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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 1x 1x 1x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import { Machine } from '../src/index';
import { assert } from 'chai';
const wordMachine = Machine({
key: 'word',
parallel: true,
states: {
direction: {
initial: 'left',
onEntry: 'ENTER_DIRECTION',
onExit: 'EXIT_DIRECTION',
states: {
left: {},
right: {},
center: {},
justify: {}
},
on: {
// internal transitions
LEFT_CLICK: '.left',
RIGHT_CLICK: '.right',
CENTER_CLICK: '.center',
JUSTIFY_CLICK: '.justify',
RESET: 'direction', // explicit self-transition
RESET_TO_CENTER: 'direction.center'
}
}
}
});
const topLevelMachine = Machine({
initial: 'Hidden',
on: {
CLICKED_CLOSE: '.Hidden',
TARGETLESS_ARRAY: [{ actions: ['doSomethingParent'] }],
TARGETLESS_OBJECT: { actions: ['doSomethingParent'] },
PARENT_EVENT: { actions: ['handleParentEvent'] }
},
states: {
Hidden: {
on: {
PUBLISH_FAILURE: 'Failure',
TARGETLESS_ARRAY: [{ actions: ['doSomething'] }],
TARGETLESS_OBJECT: { actions: ['doSomething'] }
}
},
Failure: {}
}
});
describe('internal transitions', () => {
it('parent state should enter child state without re-entering self', () => {
const nextState = wordMachine.transition(
wordMachine.initialState,
'RIGHT_CLICK'
);
assert.deepEqual(nextState.value, { direction: 'right' });
assert.lengthOf(
nextState.actions.map(a => a.type),
0,
'should not have onEntry or onExit actions'
);
});
it('parent state should only exit/reenter if there is an explicit self-transition', () => {
const resetState = wordMachine.transition('direction.center', 'RESET');
assert.deepEqual(resetState.value, { direction: 'left' });
assert.deepEqual(resetState.actions.map(a => a.type), [
'EXIT_DIRECTION',
'ENTER_DIRECTION'
]);
});
it('parent state should only exit/reenter if there is an explicit self-transition (to child)', () => {
const resetState = wordMachine.transition(
'direction.right',
'RESET_TO_CENTER'
);
assert.deepEqual(resetState.value, { direction: 'center' });
assert.deepEqual(resetState.actions.map(a => a.type), [
'EXIT_DIRECTION',
'ENTER_DIRECTION'
]);
});
it('should listen to events declared at top state', () => {
const actualState = topLevelMachine.transition('Failure', 'CLICKED_CLOSE');
assert.deepEqual(actualState.value, 'Hidden');
});
it('should work with targetless transitions (in conditional array)', () => {
const sameState = topLevelMachine.transition('Hidden', 'TARGETLESS_ARRAY');
assert.deepEqual(sameState.actions.map(a => a.type), ['doSomething']);
});
it('should work with targetless transitions (in object)', () => {
const sameState = topLevelMachine.transition('Hidden', 'TARGETLESS_OBJECT');
assert.deepEqual(sameState.actions.map(a => a.type), ['doSomething']);
});
it('should work on parent with targetless transitions (in conditional array)', () => {
const sameState = topLevelMachine.transition('Failure', 'TARGETLESS_ARRAY');
assert.deepEqual(sameState.actions.map(a => a.type), ['doSomethingParent']);
});
it('should work with targetless transitions (in object)', () => {
const sameState = topLevelMachine.transition(
'Failure',
'TARGETLESS_OBJECT'
);
assert.deepEqual(sameState.actions.map(a => a.type), ['doSomethingParent']);
});
it('should maintain the child state when targetless transition is handled by parent', () => {
const hiddenState = topLevelMachine.transition('Hidden', 'PARENT_EVENT');
assert.deepEqual(hiddenState.value, 'Hidden');
});
});
|