import 'reflect-metadata'; import { assert } from 'chai'; import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers'; import { IArrayStorage } from '../../../src/interfaces/storages/IArrayStorage'; import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade'; import { IOptions } from '../../../src/interfaces/options/IOptions'; import { IRandomGenerator } from '../../../src/interfaces/utils/IRandomGenerator'; import { ArrayStorage } from '../../../src/storages/ArrayStorage'; import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade'; class ConcreteStorage extends ArrayStorage { constructor () { const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade(); inversifyContainerFacade.load('', '', {}); super( inversifyContainerFacade.get(ServiceIdentifiers.IRandomGenerator), inversifyContainerFacade.get(ServiceIdentifiers.IOptions) ); } } /** * @returns {IArrayStorage} */ const getStorageInstance = (): IArrayStorage => { const storage: IArrayStorage = new ConcreteStorage (); storage.initialize(); return storage; }; describe('ArrayStorage', () => { const storageKey: number = 0; const storageValue: string = 'foo'; let storage: IArrayStorage ; describe('initialize', () => { const expectedError: ErrorConstructor = Error; let testFunc: () => void; before(() => { storage = new ConcreteStorage(); testFunc = () => storage.set(storageKey, storageValue); }); it('should throws an error when storage isn\'t initialized', () => { assert.throws(testFunc, expectedError); }); }); describe('getStorage', () => { const expectedInstanceOf: ArrayConstructor = Array; let arrayStorage: string[]; before(() => { storage = getStorageInstance(); arrayStorage = storage.getStorage(); }); it('should return storage', () => { assert.instanceOf(arrayStorage, expectedInstanceOf); }); }); describe('getStorageId', () => { const storageIdRegExp: RegExp = /^[a-zA-Z0-9]{6}$/; let storageId: string; before(() => { storage = getStorageInstance(); storage.set(storageKey, storageValue); storageId = storage.getStorageId(); }); it('should return storage id', () => { assert.match(storageId, storageIdRegExp); }); }); describe('get', () => { describe('Variant #1: value exist', () => { const expectedValue: string = storageValue; let value: string; before(() => { storage = getStorageInstance(); storage.set(storageKey, storageValue); value = storage.get(storageKey); }); it('should return value from storage by key', () => { assert.equal(value, expectedValue); }); }); describe('Variant #2: value isn\'t exist', () => { const expectedValue: undefined = undefined; let value: string; before(() => { storage = getStorageInstance(); value = storage.get(storageKey); }); it('should return undefined if value does not exist in the storage', () => { assert.equal(value, expectedValue); }); }); }); describe('getOrThrow', () => { describe('Variant #1: value exist', () => { const expectedValue: string = storageValue; let value: string; before(() => { storage = getStorageInstance(); storage.set(storageKey, storageValue); value = storage.getOrThrow(storageKey); }); it('should return value from storage by key', () => { assert.equal(value, expectedValue); }); }); describe('Variant #2: value isn\'t exist', () => { const expectedError: ErrorConstructor = Error; let testFunc: () => void; before(() => { storage = getStorageInstance(); testFunc = () => storage.getOrThrow(storageKey); }); it('should throw an error', () => { assert.throws(testFunc, expectedError); }); }); }); describe('getLength', () => { const expectedStorageLength: number = 1; let storageLength: number; before(() => { storage = getStorageInstance(); storage.set(storageKey, storageValue); storageLength = storage.getLength(); }); it('should return length of storage', () => { assert.equal(storageLength, expectedStorageLength); }); }); describe('getKeyOf', () => { let key: string | number | null; describe('Variant #1', () => { before(() => { storage = getStorageInstance(); storage.set(storageKey, storageValue); key = storage.getKeyOf(storageValue); }); it('should return key of string value', () => { assert.equal(key, storageKey); }); }); describe('Variant #2', () => { const object: Object = { foo: 'bar' }; before(() => { storage = getStorageInstance(); storage.set(storageKey, object); key = storage.getKeyOf(object); }); it('should return key of object if objects in `set` and `get` are two same objects', () => { assert.equal(key, storageKey); }); }); describe('Variant #3', () => { const expectedKey: null = null; const object: Object = { foo: 'bar' }; before(() => { storage = getStorageInstance(); storage.set(storageKey, object); key = storage.getKeyOf({...object}); }); it('should return `null` if objects in `set` and `get` are two different objects', () => { assert.equal(key, expectedKey); }); }); }); describe('set', () => { let value: string; before(() => { storage = getStorageInstance(); storage.set(storageKey, storageValue); value = storage.get(storageKey); }); it('should set value to the storage', () => { assert.equal(value, storageValue); }); }); describe('delete', () => { describe('Variant #1: value exist', () => { const expectedUpdatedStorage: string[] = [ 'foo', 'baz' ]; const expectedUpdatedStorageLength: number = 2; const expectedDeletedValue: string = 'bar'; let updatedStorage: string[]; let updatedStorageLength: number; let deletedValue: string; before(() => { storage = getStorageInstance(); storage.set(0, 'foo'); storage.set(1, 'bar'); storage.set(2, 'baz'); deletedValue = storage.delete(1); updatedStorage = storage.getStorage(); updatedStorageLength = storage.getLength(); }); it('should delete value from the storage by index', () => { assert.deepEqual(updatedStorage, expectedUpdatedStorage); }); it('should update storage length', () => { assert.deepEqual(updatedStorageLength, expectedUpdatedStorageLength); }); it('should return deleted value', () => { assert.equal(deletedValue, expectedDeletedValue); }); }); describe('Variant #2: value isn\'t exist', () => { const expectedUpdatedStorage: string[] = [ 'foo', 'bar', 'baz' ]; const expectedUpdatedStorageLength: number = 3; const expectedDeletedValue: undefined = undefined; let updatedStorage: string[]; let updatedStorageLength: number; let deletedValue: string; before(() => { storage = getStorageInstance(); storage.set(0, 'foo'); storage.set(1, 'bar'); storage.set(2, 'baz'); deletedValue = storage.delete(3); updatedStorage = storage.getStorage(); updatedStorageLength = storage.getLength(); }); it('should keep storage the same', () => { assert.deepEqual(updatedStorage, expectedUpdatedStorage); }); it('should keep storage length', () => { assert.deepEqual(updatedStorageLength, expectedUpdatedStorageLength); }); it('should return undefined', () => { assert.equal(deletedValue, expectedDeletedValue); }); }); }); describe('mergeWith', () => { describe('Base merge', () => { const secondStorageKey: number = 1; const secondStorageValue: string = 'bar'; const expectedArray: string[] = [storageValue, secondStorageValue]; let array: string[]; before(() => { storage = getStorageInstance(); storage.set(storageKey, storageValue); const secondStorage: IArrayStorage = getStorageInstance(); secondStorage.set(secondStorageKey, secondStorageValue); storage.mergeWith(secondStorage, false); array = storage.getStorage(); }); it('should merge two storages', () => { assert.deepEqual(array, expectedArray); }); }); describe('Merge with storage id', () => { const secondStorageKey: number = 1; const secondStorageValue: string = 'bar'; const expectedArray: string[] = [storageValue, secondStorageValue]; let array: string[]; let storageId: string; let expectedStorageId: string; before(() => { storage = getStorageInstance(); storage.set(storageKey, storageValue); const secondStorage: IArrayStorage = getStorageInstance(); expectedStorageId = secondStorage.getStorageId(); secondStorage.set(secondStorageKey, secondStorageValue); storage.mergeWith(secondStorage, true); storageId = storage.getStorageId(); array = storage.getStorage(); }); it('should update storage id', () => { assert.deepEqual(storageId, expectedStorageId); }); it('should merge two storages', () => { assert.deepEqual(array, expectedArray); }); }); }); });