stateworks
Version:
Composable stateful objects
140 lines (121 loc) • 3.33 kB
JavaScript
//////////////////////////////////////////////////////////////////////
// Node Stateworks UTs
// -----
// Copyright (c) Kiruse 2018 - 2021. Licensed under MIT License.
const {assert} = require('chai');
const Stateful = require('../index');
describe('stateworks', () => {
it('should transition', () => {
const stateful = Stateful((proxy, common, enter, me) => {
const stateFoo = {
foo() {
assert.strictEqual(me(), stateFoo);
enter(stateBar);
return 'foo.foo';
},
};
const stateBar = {
foo() {
assert.strictEqual(me(), stateBar);
enter(stateBaz);
return 'bar.foo';
},
};
const stateBaz = {
foo() {
assert.strictEqual(me(), stateBaz);
enter({});
return 'baz.foo';
}
};
return stateFoo;
});
assert.strictEqual(stateful.foo(), 'foo.foo');
assert.strictEqual(stateful.foo(), 'bar.foo');
assert.strictEqual(stateful.foo(), 'baz.foo');
assert.strictEqual(stateful.foo, undefined);
});
it('should retain common props', () => {
const stateful = Stateful((proxy, common, enter) => {
Object.assign(common, {
hello: 42,
shared: 33,
});
const state1 = {
foo() {
this.hello = 'world';
enter(state2);
}
};
const state2 = {
foo() {
this.hello = 'bye';
enter({});
}
}
return state1;
});
assert.strictEqual(stateful.hello, 42);
assert.strictEqual(stateful.shared, 33);
stateful.foo();
assert.strictEqual(stateful.hello, 'world');
assert.strictEqual(stateful.shared, 33);
stateful.foo();
assert.strictEqual(stateful.hello, 'bye');
assert.strictEqual(stateful.shared, 33);
});
it('should call transition handlers', () => {
const checks = ['state1Enter', 'state1Leave', 'state2Enter', 'state2Leave'];
const stateful = Stateful((proxy, common, enter) => {
for (let key of checks) {
common[key] = false;
}
const state1 = {
onStateEnter(oldState, newState) {
this.state1Enter = true;
assert.isTrue(typeof(oldState) === 'object' && Object.keys(oldState).length === 0);
assert.strictEqual(newState, state1);
},
onStateLeave(oldState, newState) {
this.state1Leave = true;
assert.strictEqual(oldState, state1);
assert.strictEqual(newState, state2);
},
foo() {
enter(state2);
},
};
const state2 = {
onStateEnter(oldState, newState) {
this.state2Enter = true;
assert.strictEqual(oldState, state1);
assert.strictEqual(newState, state2);
},
onStateLeave(oldState, newState) {
this.state2Leave = true;
assert.strictEqual(oldState, state2);
assert.strictEqual(newState, state3);
},
foo() {
enter(state3);
},
};
const state3 = {};
return state1;
});
assert.isTrue(stateful.state1Enter);
assert.isFalse(stateful.state1Leave);
assert.isFalse(stateful.state2Enter);
assert.isFalse(stateful.state2Leave);
stateful.foo();
assert.isTrue(stateful.state1Enter);
assert.isTrue(stateful.state1Leave);
assert.isTrue(stateful.state2Enter);
assert.isFalse(stateful.state2Leave);
stateful.foo();
assert.isTrue(stateful.state1Enter);
assert.isTrue(stateful.state1Leave);
assert.isTrue(stateful.state2Enter);
assert.isTrue(stateful.state2Leave);
});
});