All files / xstate/test invoke.test.ts

100% Statements 17/17
100% Branches 0/0
100% Functions 5/5
100% Lines 17/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 761x 1x 1x 1x   1x                                     1x                 4x 3x                             1x 1x 1x             1x   1x     1x 1x   1x           1x      
import { Machine, actions } from '../src/index';
import { interpret } from '../src/interpreter';
import { assign, invoke } from '../src/actions';
import { assert } from 'chai';
 
const childMachine = Machine({
  id: 'child',
  initial: 'init',
  states: {
    init: {
      onEntry: [actions.sendParent('INC'), actions.sendParent('INC')],
      on: {
        FORWARD_DEC: {
          actions: [
            actions.sendParent('DEC'),
            actions.sendParent('DEC'),
            actions.sendParent('DEC')
          ]
        }
      }
    }
  }
});
 
const parentMachine = Machine(
  {
    id: 'parent',
    context: { count: 0 },
    initial: 'start',
    states: {
      start: {
        activities: [invoke('child', { id: 'someService', forward: true })],
        on: {
          INC: { actions: assign({ count: ctx => ctx.count + 1 }) },
          DEC: { actions: assign({ count: ctx => ctx.count - 1 }) },
          FORWARD_DEC: undefined,
          STOP: 'stop'
        }
      },
      stop: {}
    }
  },
  {
    services: {
      child: childMachine.definition
    }
  }
);
 
describe('invoke', () => {
  it('should start services (external machines)', () => {
    const interpreter = interpret(parentMachine).start();
    // 1. The 'parent' machine will enter 'start' state
    // 2. The 'child' service will be run with ID 'someService'
    // 3. The 'child' machine will enter 'init' state
    // 4. The 'onEntry' action will be executed, which sends 'INC' to 'parent' machine twice
    // 5. The context will be updated to increment count to 2
 
    assert.deepEqual(interpreter.state.context, { count: 2 });
 
    interpreter.send('STOP');
  });
 
  it('should forward events to services if forward: true', () => {
    const interpreter = interpret(parentMachine).start();
 
    interpreter.send('FORWARD_DEC');
    // 1. The 'parent' machine will not do anything (inert transition)
    // 2. The 'FORWARD_DEC' event will be forwarded to the 'child' machine (forward: true)
    // 3. On the 'child' machine, the 'FORWARD_DEC' event sends the 'DEC' action to the 'parent' thrice
    // 4. The context of the 'parent' machine will be updated from 2 to -1
 
    assert.deepEqual(interpreter.state.context, { count: -1 });
  });
});