UNPKG

state-synchronizers

Version:

Deterministically update state based on other state

96 lines (95 loc) 4.99 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; exports.__esModule = true; var compose_state_synchronizers_1 = require("./compose-state-synchronizers"); var create_composable_state_synchronizer_1 = require("./create-composable-state-synchronizer"); describe('composeStateSynchronizers', function () { it('should return a function', function () { expect.hasAssertions(); var synchronizer = compose_state_synchronizers_1.composeStateSynchronizers([]); expect(synchronizer).toBeInstanceOf(Function); }); it('should throw an error when there is a cycle in the dependencies', function () { expect.hasAssertions(); var synchronizers = [ { stateKey: 'a', dependenciesKeys: ['b'], synchronizer: jest.fn() }, { stateKey: 'b', dependenciesKeys: ['a'], synchronizer: jest.fn() }, ]; expect(function () { return compose_state_synchronizers_1.composeStateSynchronizers(synchronizers); }).toThrow('Cycle detected: b->a->b'); }); describe('returned state synchronizer', function () { var initialState = { pageSize: 10, recordsCount: 20, maxPage: 2, currentPage: 1 }; var maxPageUpdater = jest.fn(function (state) { return (__assign(__assign({}, state), { maxPage: Math.max(1, Math.ceil(state.recordsCount / state.pageSize)) })); }); var currentPageUpdater = jest.fn(function (state) { return (__assign(__assign({}, state), { currentPage: Math.min(state.currentPage, state.maxPage) })); }); var synchronizers = [ create_composable_state_synchronizer_1.createComposableStateSynchronizer(maxPageUpdater, 'maxPage', [ 'recordsCount', 'pageSize', ]), create_composable_state_synchronizer_1.createComposableStateSynchronizer(currentPageUpdater, 'currentPage', [ 'maxPage', ]), ]; beforeEach(function () { jest.clearAllMocks(); }); it('should run necessary synchronizers in correct order when the state changed', function () { expect.hasAssertions(); var synchronizer = compose_state_synchronizers_1.composeStateSynchronizers(synchronizers); var newState = __assign(__assign({}, initialState), { recordsCount: 17 }); var result = synchronizer(newState, initialState); expect(maxPageUpdater).toHaveBeenCalledTimes(1); expect(currentPageUpdater).not.toHaveBeenCalled(); expect(result).toStrictEqual(newState); }); it('should propagate the change made by the synchronizers', function () { expect.hasAssertions(); var synchronizer = compose_state_synchronizers_1.composeStateSynchronizers(synchronizers); var newState = __assign(__assign({}, initialState), { recordsCount: 28 }); var result = synchronizer(newState, initialState); expect(maxPageUpdater).toHaveBeenCalledTimes(1); expect(currentPageUpdater).toHaveBeenCalledTimes(1); expect(result).toStrictEqual(__assign(__assign({}, newState), { maxPage: 3 })); }); it('should propagate the change made by the synchronizers (2)', function () { expect.hasAssertions(); var synchronizer = compose_state_synchronizers_1.composeStateSynchronizers(synchronizers); var newState = __assign(__assign({}, initialState), { recordsCount: 28, currentPage: 4 }); var result = synchronizer(newState, initialState); expect(maxPageUpdater).toHaveBeenCalledTimes(1); expect(currentPageUpdater).toHaveBeenCalledTimes(1); expect(result).toStrictEqual(__assign(__assign({}, newState), { maxPage: 3, currentPage: 3 })); }); it('should pass state returned from earlier synchronizer to the later one', function () { expect.hasAssertions(); var synchronizer = compose_state_synchronizers_1.composeStateSynchronizers(synchronizers); var newState = __assign(__assign({}, initialState), { recordsCount: 28, currentPage: 4 }); synchronizer(newState, initialState); expect(maxPageUpdater).toHaveBeenCalledWith(newState); expect(currentPageUpdater).toHaveBeenCalledWith(maxPageUpdater.mock.results[0].value); }); }); });