@v4fire/core
Version:
V4Fire core library
394 lines (393 loc) • 16.2 kB
JavaScript
"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);
}