overmind
Version:
Frictionless state management
246 lines • 7.6 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const proxy_state_tree_1 = require("proxy-state-tree");
const _1 = require("./");
describe('Derived', () => {
test('should instantiate app with derived state', () => {
const state = {
foo: 'bar',
upperFoo: (0, _1.derived)((state) => state.foo.toUpperCase()),
};
const config = {
state,
};
const app = new _1.Overmind(config);
expect(app.state.upperFoo).toEqual('BAR');
});
test('should dynamically remove derived', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
let dirtyCount = 0;
const removeDerived = ({ state }) => {
state.upperFoo = null;
};
const changeFoo = ({ state }, count) => {
state.foo = 'bar' + count;
};
const state = {
foo: 'bar',
upperFoo: (0, _1.derived)((state) => state.foo.toUpperCase()),
};
const actions = {
changeFoo,
removeDerived,
};
const config = {
state,
actions,
};
const app = new _1.Overmind(config);
const trackStateTree = app.getTrackStateTree();
const onTrack = () => { };
function render() {
trackStateTree.track(onTrack);
app.state.upperFoo;
}
app.eventHub.on(_1.EventType.DERIVED_DIRTY, () => {
dirtyCount++;
});
render();
expect(app.state.upperFoo).toBe('BAR');
app.actions.changeFoo(2);
expect(app.state.upperFoo).toBe('BAR2');
app.actions.removeDerived();
app.actions.changeFoo(3);
// The dirty event is async
yield new Promise((resolve) => setTimeout(resolve, 0));
expect(dirtyCount).toBe(1);
}));
test('should dynamically add derived', () => {
const addDerived = ({ state }) => {
state.upperFoo = (0, _1.derived)((state) => state.foo.toUpperCase());
};
const changeFoo = ({ state }) => {
state.foo = 'bar2';
};
const state = {
foo: 'bar',
upperFoo: null,
};
const actions = {
changeFoo,
addDerived,
};
const config = {
state,
actions,
};
const app = new _1.Overmind(config);
const trackStateTree = app.getTrackStateTree();
const onTrack = () => { };
function render() {
trackStateTree.track(onTrack);
app.state.upperFoo;
}
render();
app.actions.addDerived();
expect(app.state.upperFoo).toBe('BAR');
app.actions.changeFoo();
expect(app.state.upperFoo).toBe('BAR2');
});
test('should allow access to proxy state tree to continue tracking with derived function', () => {
let renderCount = 0;
const changeFoo = ({ state }) => {
state.foo = 'bar2';
};
const state = {
foo: 'bar',
upperFoo: (0, _1.derived)(() => function () {
const state = this[proxy_state_tree_1.PROXY_TREE].state;
return state.foo.toUpperCase();
}),
};
const actions = {
changeFoo,
};
const config = {
state,
actions,
};
const app = new _1.Overmind(config);
const trackStateTree = app.getTrackStateTree();
const onTrack = () => {
renderCount++;
};
function render() {
trackStateTree.track(onTrack);
app.state.upperFoo();
}
render();
app.actions.changeFoo();
expect(renderCount).toBe(1);
});
test('should track derived state', () => {
let renderCount = 0;
const changeFoo = ({ state }) => {
state.foo = 'bar2';
};
const state = {
foo: 'bar',
upperFoo: (0, _1.derived)((state) => state.foo.toUpperCase()),
};
const actions = {
changeFoo,
};
const config = {
state,
actions,
};
const app = new _1.Overmind(config);
const trackStateTree = app.getTrackStateTree();
const onTrack = () => {
renderCount++;
};
function render() {
trackStateTree.track(onTrack);
app.state.upperFoo;
}
render();
app.actions.changeFoo();
expect(app.state.upperFoo).toBe('BAR2');
expect(renderCount).toBe(1);
});
test('should not require flush to flag as dirty', () => {
expect.assertions(1);
const state = {
foo: 'bar',
upperFoo: (0, _1.derived)((state) => state.foo.toUpperCase()),
};
const changeFoo = ({ state }) => {
state.foo = 'bar2';
expect(state.upperFoo).toBe('BAR2');
};
const actions = {
changeFoo,
};
const config = {
state,
actions,
};
const app = new _1.Overmind(config);
app.actions.changeFoo();
});
test('should pass parent as second argument', () => {
expect.assertions(1);
const changeFoo = ({ state }) => {
state.foo = 'bar2';
expect(state.upperFoo).toBe('BAR2');
};
const state = {
foo: 'bar',
upperFoo: (0, _1.derived)((_, parent) => parent.foo.toUpperCase()),
};
const actions = {
changeFoo,
};
const config = {
state,
actions,
};
const app = new _1.Overmind(config);
app.actions.changeFoo();
});
test('should track nested derived correctly', () => {
expect.assertions(4);
let runCount = 0;
const changeFoo = ({ state }) => {
state.nestedDerived.foo = 'bar2';
expect(state.nestedDerived.upperFoo).toBe('BAR2');
};
const state = {
nestedDerived: {
foo: 'bar',
upperFoo: (0, _1.derived)((parent) => parent.foo.toUpperCase()),
},
};
const actions = {
changeFoo,
};
const config = {
state,
actions,
};
const app = new _1.Overmind(config);
const trackStateTree = app.getTrackStateTree();
function render() {
runCount++;
if (runCount === 1) {
expect(trackStateTree.state.nestedDerived.upperFoo).toBe('BAR');
}
else {
expect(trackStateTree.state.nestedDerived.upperFoo).toBe('BAR2');
}
trackStateTree.stopTracking();
}
trackStateTree.track(render);
render();
app.actions.changeFoo();
expect(runCount).toBe(2);
});
test('should be able to add derived to class instances', () => {
class SomeClass {
constructor() {
this.foo = (0, _1.derived)((state) => state.bar + '!');
this.bar = 'foo';
}
}
const state = {
class: new SomeClass(),
};
const config = {
state,
};
const app = new _1.Overmind(config);
expect(app.state.class.foo).toEqual('foo!');
});
});
//# sourceMappingURL=derived.test.js.map
;