UNPKG

@v4fire/core

Version:
394 lines (393 loc) 16.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _express = _interopRequireDefault(require("express")); var _async = _interopRequireDefault(require("../../../../core/async")); var _data = _interopRequireWildcard(require("../../../../core/data")); var _events = _interopRequireDefault(require("events")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } describe('core/async/modules/wrappers', () => { var _class; let server; beforeAll(() => { server = createServer(); }); afterAll(async () => { await server.close(); }); let ProviderExample = (0, _data.provider)(_class = class ProviderExample extends _data.default { baseURL = 'http://localhost:3000/ok'; }) || _class; describe('`wrapDataProvider`', () => { it('should call methods from the original instance', () => { const $a = new _async.default(), provider = new ProviderExample(), wrappedProvider = $a.wrapDataProvider(provider); jest.spyOn(provider, 'name'); wrappedProvider.name(); expect(provider.name).toHaveBeenCalled(); jest.spyOn(provider, 'base'); wrappedProvider.base('bar'); expect(provider.base).toHaveBeenCalledWith('bar'); }); it('should call replaced methods from the original instance', () => { const $a = new _async.default(), provider = new ProviderExample(), wrappedProvider = $a.wrapDataProvider(provider); jest.spyOn(provider, 'get'); wrappedProvider.get(); expect(provider.get).toHaveBeenCalled(); jest.spyOn(provider, 'upd'); wrappedProvider.upd(); expect(provider.upd).toHaveBeenCalled(); }); it('if a group is not provided should use a class name from the provider', () => { const $a = new _async.default(), provider = new ProviderExample(), wrappedProvider = $a.wrapDataProvider(provider); jest.spyOn($a, 'request'); wrappedProvider.get({ id: 1 }); expect($a.request.mock.lastCall[1]).toEqual({ group: 'ProviderExample' }); }); it('should concatenate a global group and local group', async () => { const $a = new _async.default(), provider = new ProviderExample(), wrappedProvider = $a.wrapDataProvider(provider, { group: 'example' }); jest.spyOn($a, 'request'); await wrappedProvider.get({ id: 1 }); expect($a.request.mock.lastCall[1]).toEqual({ group: 'example' }); await wrappedProvider.upd({ id: 1 }, { group: 'foo' }); expect($a.request.mock.lastCall[1]).toEqual({ group: 'example:foo' }); }); it('should provide a group into a nested event emitter wrapper and replace the original emitter with a wrapper', () => { const $a = new _async.default(), provider = new ProviderExample(), fakeWrapper = { info: 'Is a wrapped event emitter' }; jest.spyOn($a, 'wrapEventEmitter').mockReturnValue(fakeWrapper); const wrappedProvider = $a.wrapDataProvider(provider, { group: 'example' }); expect($a.wrapEventEmitter.mock.lastCall).toEqual([provider.emitter, { group: 'example' }]); expect(wrappedProvider.emitter).toEqual(fakeWrapper); }); }); describe('`wrapEventEmitter`', () => { it('should have access to event emitter properties and methods', () => { const $a = new _async.default(); const fakeEventEmitter = { foo: () => null, bar: 'bar' }; const emitter = $a.wrapEventEmitter(fakeEventEmitter); expect(emitter.foo).toEqual(fakeEventEmitter.foo); expect(emitter.bar).toEqual(fakeEventEmitter.bar); }); it('`addEventListener` and `addListener` should be aliases for `on`', () => { const $a = new _async.default(), emitter = $a.wrapEventEmitter({}); expect(emitter.addEventListener).toEqual(emitter.on); expect(emitter.addListener).toEqual(emitter.on); }); it('should throw an error if the second parameter at `on` is not a function', () => { const $a = new _async.default(), emitter = $a.wrapEventEmitter({ on: () => null }); expect(emitter.on.bind(null, 'bar', { handleEvent: () => ({}) })).toThrowError(); }); it('should concatenate a global group and local group', () => { const $a = new _async.default(), emitterWithGroup = $a.wrapEventEmitter({ on: () => null }, { group: 'example' }); jest.spyOn($a, 'on'); emitterWithGroup.on('foo', () => null, { group: 'example2' }); expect($a.on.mock.lastCall[3]).toEqual({ group: 'example:example2' }); emitterWithGroup.on('bar', () => null); expect($a.on.mock.lastCall[3]).toEqual({ group: 'example' }); const emitterWithoutGroup = $a.wrapEventEmitter({ on: () => null }); emitterWithoutGroup.on('foo', () => null, { group: 'example3' }); expect($a.on.mock.lastCall[3]).toEqual({ group: 'example3' }); emitterWithoutGroup.on('bar', () => null); expect($a.on.mock.lastCall[3]).toEqual({}); }); it('normalizes of input parameters', () => { const $a = new _async.default(), emitter = $a.wrapEventEmitter({ on: () => null }); jest.spyOn($a, 'on'); emitter.on('foo', () => null); expect($a.on.mock.lastCall.slice(3)).toEqual([{}]); emitter.on('foo', () => null, true); expect($a.on.mock.lastCall.slice(3)).toEqual([{}, true]); emitter.on('foo', () => null, { foo: 'foo', group: 'group', label: 'label' }, null, 5); expect($a.on.mock.lastCall.slice(3)).toEqual([{ group: 'group', label: 'label' }, { foo: 'foo' }, null, 5]); }); it('`off`, `once`, `promisifyOnce` should call async wrappers', () => { const $a = new _async.default(), emitter = $a.wrapEventEmitter(new _events.default()); jest.spyOn($a, 'once'); jest.spyOn($a, 'promisifyOnce'); jest.spyOn($a, 'off'); emitter.once('foo', () => null); emitter.promisifyOnce('bar', () => null); emitter.off({}); expect($a.once).toHaveBeenCalled(); expect($a.promisifyOnce).toHaveBeenCalled(); expect($a.off).toHaveBeenCalled(); }); it('`off` alias should return control to the original function if wrong parameters are provided', () => { const originalMethods = { off: false, removeEventListener: false, removeListener: false }; const $a = new _async.default(); const emitter = $a.wrapEventEmitter({ on: () => null, off: () => originalMethods.off = true, removeEventListener: () => originalMethods.removeEventListener = true, removeListener: () => originalMethods.removeListener = true }); emitter.off(null); emitter.removeEventListener('foo'); emitter.removeListener({}, () => null, 'bar', 1); expect(originalMethods).toEqual({ off: true, removeEventListener: true, removeListener: true }); }); it('`emit` should call all emit like events', () => { const results = { emit: null, fire: null, dispatch: null, dispatchEvent: null }; const $a = new _async.default(), fakeEventEmitter = {}; const events = Object.keys(results), emitter = $a.wrapEventEmitter(fakeEventEmitter); for (let i = 0; i < events.length; i += 1) { delete fakeEventEmitter[events[i - 1]]; fakeEventEmitter[events[i]] = event => results[events[i]] = event; emitter.emit(events[i]); } expect(results).toEqual({ emit: 'emit', fire: 'fire', dispatch: 'dispatch', dispatchEvent: 'dispatchEvent' }); }); }); describe('`wrapStorage`', () => { const mainMethods = ['has', 'get', 'set', 'remove', 'clear'], methodsWithNamespace = [...mainMethods, 'namespace']; let $a, mockedStorage, methodArgs, expectedResult; beforeEach(() => { $a = new _async.default(); methodArgs = [Symbol('firstArg'), Symbol('secondArg'), Symbol('thirdArg')]; expectedResult = Symbol('result'); mockedStorage = methodsWithNamespace.reduce((cur, name) => { cur[name] = jest.fn().mockResolvedValue(expectedResult); return cur; }, {}); }); mainMethods.forEach(testMethod); function testMethod(methodName) { describe(`\`${methodName}\``, () => { it('should call the original method and return its result', async () => { const wrappedStorage = $a.wrapStorage(mockedStorage), result = await wrappedStorage[methodName](...methodArgs); expect(mockedStorage[methodName]).toHaveBeenCalledWith(...methodArgs); expect(result).toBe(expectedResult); }); it('should mark a storage by the global group', async () => { const wrappedStorage = $a.wrapStorage(mockedStorage, { group: 'bla' }), spyPromise = jest.fn().mockResolvedValue(expectedResult); const promise = wrappedStorage[methodName](...methodArgs).then(() => spyPromise('resolved'), err => spyPromise(Object.select(err, ['type', 'reason']))); await $a.clearAll({ group: 'bla' }); await promise; expect(spyPromise).toHaveBeenLastCalledWith({ type: 'clearAsync', reason: 'group' }); expect(spyPromise).toHaveBeenCalledTimes(1); }); it('should consider the `group` parameter', async () => { const wrappedStorage = $a.wrapStorage(mockedStorage), spyPromise = jest.fn().mockResolvedValue(expectedResult); const promise = wrappedStorage[methodName](...methodArgs, { group: 'bla' }).then(() => spyPromise('resolved'), err => spyPromise(Object.select(err, ['type', 'reason']))); await $a.clearAll({ group: 'bla' }); await promise; expect(spyPromise).toHaveBeenLastCalledWith({ type: 'clearAsync', reason: 'group' }); expect(spyPromise).toHaveBeenCalledTimes(1); }); it('should consider the `label` parameter', async () => { const wrappedStorage = $a.wrapStorage(mockedStorage), spyPromise = jest.fn().mockResolvedValue(expectedResult); const promise = wrappedStorage[methodName](...methodArgs, { label: 'qoo' }).then(() => spyPromise('resolved'), err => spyPromise(Object.select(err, ['type', 'reason']))); await $a.clearAll({ label: 'qoo' }); await promise; expect(spyPromise).toHaveBeenLastCalledWith({ type: 'clearAsync', reason: 'label' }); expect(spyPromise).toHaveBeenCalledTimes(1); }); it('should consider the `join` parameter', async () => { const wrappedStorage = $a.wrapStorage(mockedStorage), spyPromise = jest.fn().mockResolvedValue(expectedResult), label = Symbol('label'), promise1 = wrappedStorage[methodName](...methodArgs, { label, join: true }).then(() => spyPromise()), promise2 = wrappedStorage[methodName](...methodArgs, { label, join: true }).then(() => spyPromise()); await Promise.all([promise1, promise2]); expect(spyPromise).toHaveBeenCalledTimes(2); }); it('should concatenate global and local groups', async () => { const wrappedStorage = $a.wrapStorage(mockedStorage, { group: 'bla' }), spyWithoutLocal = jest.fn().mockResolvedValue(expectedResult), spyWithLocal = jest.fn().mockResolvedValue(expectedResult); const promiseWithoutLocal = wrappedStorage[methodName](...methodArgs).then(() => spyWithoutLocal('resolved'), err => spyWithoutLocal(Object.select(err, ['type', 'reason']))); const promiseWithLocal = wrappedStorage[methodName](...methodArgs, { group: 'foo' }).then(() => spyWithLocal('resolved'), err => spyWithLocal(Object.select(err, ['type', 'reason']))); await $a.clearAll({ group: 'bla:foo' }); await Promise.all([promiseWithoutLocal, promiseWithLocal]); expect(spyWithoutLocal).toHaveBeenLastCalledWith('resolved'); expect(spyWithoutLocal).toHaveBeenCalledTimes(1); expect(spyWithLocal).toHaveBeenLastCalledWith({ type: 'clearAsync', reason: 'group' }); expect(spyWithLocal).toHaveBeenCalledTimes(1); }); it('should separate async options from additional parameters', () => { const wrappedStorage = $a.wrapStorage(mockedStorage); wrappedStorage[methodName]('firstArg', 'secondArg', { additionalArg: true }, { group: 'bla', label: 'foo', join: true, notAsyncOption: true }); expect(mockedStorage[methodName].mock.lastCall[2]).toEqual({ additionalArg: true }); expect(mockedStorage[methodName].mock.lastCall[3]).toEqual({ notAsyncOption: true }); }); }); } describe('`namespace`', () => { it('should call the original method and return the wrapped result', () => { const parentStorage = $a.wrapStorage(mockedStorage), name = Symbol('name'), storageNamespace = Symbol('storageNamespace'), wrappedStorageNamespace = Symbol('wrappedStorageNamespace'); jest.spyOn($a, 'wrapStorage'); mockedStorage.namespace.mockReturnValue(storageNamespace); $a.wrapStorage.mockReturnValue(wrappedStorageNamespace); const returnedStorage = parentStorage.namespace(name); expect(mockedStorage.namespace).toHaveBeenCalledWith(name); expect($a.wrapStorage.mock.lastCall[0]).toBe(storageNamespace); expect(returnedStorage).toBe(wrappedStorageNamespace); }); it('should concatenate global and local groups', () => { const parentStorage = $a.wrapStorage(mockedStorage, { group: 'bla' }); jest.spyOn($a, 'wrapStorage'); parentStorage.namespace('someName', { group: 'foo' }); expect($a.wrapStorage.mock.lastCall[1]).toEqual({ group: 'bla:foo' }); }); }); }); }); function createServer() { const serverApp = (0, _express.default)(); serverApp.use(_express.default.json()); serverApp.use('/ok', (req, res) => res.status(200).json({ ok: true })); return serverApp.listen(3000); }