UNPKG

ts-bus

Version:

<p align="center"> <img src="logo.png" width="100" height="100"/> </p>

292 lines 12.7 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); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var react_hooks_1 = require("@testing-library/react-hooks"); var eventemitter2_1 = require("eventemitter2"); var react_1 = __importDefault(require("react")); var react_test_renderer_1 = require("react-test-renderer"); var EventBus_1 = require("./EventBus"); var react_2 = require("./react"); var useBusReducer_1 = require("./useBusReducer"); var bus = new EventBus_1.EventBus(); function mockEventBus() { var _unsubscribe = jest.fn(); var subscribe = jest.fn(function () { return _unsubscribe; }); var publish = jest.fn(); var emitter = new eventemitter2_1.EventEmitter2(); return { subscribe: subscribe, emitter: emitter, publish: publish, _unsubscribe: _unsubscribe }; } var wrapper = function (_a) { var children = _a.children; return (react_1.default.createElement(react_2.BusProvider, { value: bus }, children)); }; it("should provide a bus", function () { var result = react_hooks_1.renderHook(function () { return react_2.useBus(); }, { wrapper: wrapper }).result; expect(result.current).toBe(bus); }); it("should not subscribe without unsubscribing (useBusReducer)", function () { var mockBus = mockEventBus(); // run once to subscribe to bus // type SubscribeFn = (d: any, b: any) => void; var hook = react_hooks_1.renderHook(function (subscriberFn) { var useReducer = react_2.useBusReducer.configure({ subscriber: subscriberFn }); return useReducer(function (state) { return state; }, {}, function (a) { return a; }); }, { wrapper: function (_a) { var children = _a.children; return (react_1.default.createElement(react_2.BusProvider, { value: mockBus }, children)); }, initialProps: useBusReducer_1._defaultSubscriber }); // change subscriber to different reference to invalidate useEffect hook.rerender(function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return useBusReducer_1._defaultSubscriber.apply(void 0, args); }); hook.unmount(); expect(mockBus.subscribe.mock.calls.length).toBe(2); expect(mockBus._unsubscribe.mock.calls.length).toBe(2); }); it("should not subscribe without unsubscribing (useBusState)", function () { var mockBus = mockEventBus(); var incrementEvent = EventBus_1.createEventDefinition()("increment"); // run once to subscribe to bus var hook = react_hooks_1.renderHook(function () { return react_2.useBusState(0, incrementEvent); }, { wrapper: function (_a) { var children = _a.children; return (react_1.default.createElement(react_2.BusProvider, { value: mockBus }, children)); } }); hook.unmount(); expect(mockBus.subscribe.mock.calls.length).toBe(1); expect(mockBus._unsubscribe.mock.calls.length).toBe(1); }); it("should update state (options configuration)", function () { var incrementEvent = EventBus_1.createEventDefinition()("counter.increment"); var result = react_hooks_1.renderHook(function () { return react_2.useBusState.configure({ subscriber: function (dispatch, bus) { return bus.subscribe("counter.**", function (v) { return dispatch(v.payload); }); } })(0); }, { wrapper: wrapper }).result; expect(result.current).toBe(0); react_hooks_1.act(function () { bus.publish(incrementEvent(1)); }); expect(result.current).toBe(1); }); it("should update state by subscribing to multiple events", function () { var positiveNumberEvent = EventBus_1.createEventDefinition()("positive"); var negativeNumberEvent = EventBus_1.createEventDefinition()("negative"); var result = react_hooks_1.renderHook(function () { return react_2.useBusState.configure({ subscriber: react_2.stateSubscriber("positive", "negative") })(0); }, { wrapper: wrapper }).result; expect(result.current).toBe(0); react_hooks_1.act(function () { return bus.publish(positiveNumberEvent(15)); }); expect(result.current).toBe(15); react_hooks_1.act(function () { return bus.publish(negativeNumberEvent(-5)); }); expect(result.current).toBe(-5); }); it("should update state", function () { var incrementEvent = EventBus_1.createEventDefinition()("increment"); var result = react_hooks_1.renderHook(function () { return react_2.useBusState(0, incrementEvent); }, { wrapper: wrapper }).result; expect(result.current).toBe(0); react_hooks_1.act(function () { bus.publish(incrementEvent(1)); }); expect(result.current).toBe(1); }); it("should not reduce for not subscribed event", function () { var result = react_hooks_1.renderHook(function () { var reducer = react_2.useBusReducer.configure({ subscriber: react_2.reducerSubscriber("increment", "decrement") }); return reducer(function (state, event) { switch (event.type) { case "increment": return __assign({}, state, { counter: state.counter + 1 }); case "decrement": return __assign({}, state, { counter: state.counter - 1 }); case "multiply": // Must never be called return __assign({}, state, { counter: state.counter * 100 }); } return state; }, { counter: 0 }, function (a) { return a; }); }, { wrapper: wrapper }).result; expect(result.current.counter).toBe(0); react_hooks_1.act(function () { bus.publish({ type: "increment", payload: null }); bus.publish({ type: "multiply", payload: null }); bus.publish({ type: "increment", payload: null }); bus.publish({ type: "decrement", payload: null }); }); expect(result.current.counter).toBe(1); }); it("should reduce using multiple event subscription types", function () { var minusFour = EventBus_1.createEventDefinition()("minusFour"); var result = react_hooks_1.renderHook(function () { var reducer = react_2.useBusReducer.configure({ subscriber: react_2.reducerSubscriber("increment", "decrement", minusFour, function (x) { return x.payload !== null && x.payload >= 3; }) }); return reducer(function (state, event) { switch (event.type) { case "increment": return __assign({}, state, { counter: state.counter + 1 }); case "decrement": return __assign({}, state, { counter: state.counter - 1 }); case "minusFour": return __assign({}, state, { counter: state.counter - 4 }); case "multiply": return __assign({}, state, { counter: state.counter * event.payload }); } return state; }, { counter: 0 }, function (a) { return a; }); }, { wrapper: wrapper }).result; expect(result.current.counter).toBe(0); react_hooks_1.act(function () { bus.publish({ type: "increment", payload: null }); // Reaches reducer bus.publish({ type: "increment", payload: null }); // Reaches reducer bus.publish({ type: "decrement", payload: null }); // Reaches reducer bus.publish({ type: "increment", payload: null }); // Reaches reducer bus.publish({ type: "multiply", payload: 2 }); // Does not reach reducer bus.publish({ type: "multiply", payload: 3 }); // Reaches reducer bus.publish({ type: "multiply", payload: 4 }); // Reaches reducer bus.publish({ type: "multiply", payload: 2 }); // Reaches reducer bus.publish(minusFour()); // Reaches reducer }); expect(result.current.counter).toBe(20); }); it("should reduce state", function () { var result = react_hooks_1.renderHook(function () { return react_2.useBusReducer(function (state, event) { switch (event.type) { case "increment": { return __assign({}, state, { counter: state.counter + 1 }); } case "decrement": { return __assign({}, state, { counter: state.counter - 1 }); } } return state; }, { counter: 0 }, function (a) { return a; }); }, { wrapper: wrapper }).result; expect(result.current.counter).toBe(0); react_hooks_1.act(function () { bus.publish({ type: "increment", payload: null }); bus.publish({ type: "increment", payload: null }); bus.publish({ type: "increment", payload: null }); }); expect(result.current.counter).toBe(3); }); it("should subscribe state", function () { var result = react_hooks_1.renderHook(function () { var useReducer = react_2.useBusReducer.configure({ subscriber: function (dispatch, bus) { return bus.subscribe("count.**", dispatch); } }); return useReducer(function (state, event) { switch (event.type) { case "count.increment": { return __assign({}, state, { counter: state.counter + 1 }); } case "count.decrement": { return __assign({}, state, { counter: state.counter - 1 }); } case "reset": { return __assign({}, state, { counter: 0 }); } } return state; }, { counter: 0 }); }, { wrapper: wrapper }).result; expect(result.current.counter).toBe(0); react_hooks_1.act(function () { bus.publish({ type: "count.increment", payload: null }); bus.publish({ type: "reset", payload: null }); }); // Reset should have no effect because of subscriber expect(result.current.counter).toBe(1); }); it("should use an alternate useReducer", function () { var mockUseReducer = jest.fn(function (reducer, initialState, initializer) { return react_1.default.useReducer(reducer, initialState, initializer); }); var reducer = function (state) { return state; }; var init = { counter: 0 }; var ident = function (a) { return a; }; react_hooks_1.renderHook(function () { var useReducer = react_2.useBusReducer.configure({ useReducer: mockUseReducer }); return useReducer(reducer, init, ident); }, { wrapper: wrapper }); expect(mockUseReducer).toBeCalledWith(reducer, init, ident); }); it("should not loose events during the render cycle when mounted.", function (done) { var myBus = new EventBus_1.EventBus(); var reducer = jest.fn(function (s) { return s; }); var EVENT_DELAY = { type: "myevent", payload: "DELAY" }; var EVENT_URGENT = { type: "myevent", payload: "URGENT" }; function MyContextProvider(props) { react_2.useBusReducer(reducer, {}); return props.children; } function EventPublisher() { var b = react_2.useBus(); react_1.default.useEffect(function () { setTimeout(function () { b.publish(EVENT_DELAY); }, 0); }, [b]); react_1.default.useEffect(function () { b.publish(EVENT_URGENT); }, [b]); return react_1.default.createElement("div", null); } function App() { return (react_1.default.createElement(react_2.BusProvider, { value: myBus }, react_1.default.createElement(MyContextProvider, null, react_1.default.createElement(EventPublisher, null)))); } // render the component react_hooks_1.act(function () { react_test_renderer_1.create(react_1.default.createElement(App, null)); }); setTimeout(function () { var eventList = reducer.mock.calls.map(function (_a) { var ev = _a[1]; return ev; }); expect(eventList).toEqual([EVENT_URGENT, EVENT_DELAY]); done(); }, 0); }); //# sourceMappingURL=react.test.js.map