Splitted IStorage into two separate interfaces for map and array storages

This commit is contained in:
sanex3339
2018-03-20 00:17:20 +03:00
parent 1149ee4be0
commit d08a1e4075
17 changed files with 155 additions and 97 deletions
+1 -1
View File
@@ -22,7 +22,7 @@
"@babel/runtime": "7.0.0-beta.42",
"chalk": "2.3.2",
"chance": "1.0.13",
"class-validator": "0.8.1",
"class-validator": "0.8.4",
"commander": "2.15.0",
"escodegen-wallaby": "1.6.18",
"esprima": "4.0.0",
@@ -1,17 +1,17 @@
import { IInitializable } from '../IInitializable';
export interface IStorage <T> extends IInitializable {
export interface IArrayStorage <V> extends IInitializable {
/**
* @param key
* @returns T
* @param {number} key
* @returns {V}
*/
get (key: string | number): T;
get (key: number): V;
/**
* @param value
* @returns string | number | null
* @returns number | null
*/
getKeyOf (value: T): string | number | null;
getKeyOf (value: V): number | null;
/**
* @returns number
@@ -19,9 +19,9 @@ export interface IStorage <T> extends IInitializable {
getLength (): number;
/**
* @returns any
* @returns {V[]}
*/
getStorage (): any;
getStorage (): V[];
/**
* @returns string
@@ -40,10 +40,10 @@ export interface IStorage <T> extends IInitializable {
mergeWith (storage: this, mergeId: boolean): void;
/**
* @param key
* @param value
* @param {number} key
* @param {V} value
*/
set (key: string | number, value: T): void;
set (key: number, value: V): void;
/**
* @returns string
+52
View File
@@ -0,0 +1,52 @@
import { IInitializable } from '../IInitializable';
export interface IMapStorage <K, V> extends IInitializable {
/**
* @param {K} key
* @returns {V}
*/
get (key: K): V;
/**
* @param {V} value
* @returns {K | null}
*/
getKeyOf (value: V): K | null;
/**
* @returns number
*/
getLength (): number;
/**
* @returns {Map<K, V>}
*/
getStorage (): Map <K, V>;
/**
* @returns string
*/
getStorageId (): string;
/**
* @param args
*/
initialize (...args: any[]): void;
/**
* @param storage
* @param mergeId
*/
mergeWith (storage: this, mergeId: boolean): void;
/**
* @param {K} key
* @param {V} value
*/
set (key: K, value: V): void;
/**
* @returns string
*/
toString (): string;
}
+13 -13
View File
@@ -1,14 +1,14 @@
import { inject, injectable, postConstruct } from 'inversify';
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
import { IArrayStorage } from '../interfaces/storages/IArrayStorage';
import { IOptions } from '../interfaces/options/IOptions';
import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';
import { IStorage } from '../interfaces/storages/IStorage';
import { initializable } from '../decorators/Initializable';
@injectable()
export abstract class ArrayStorage <T> implements IStorage <T> {
export abstract class ArrayStorage <V> implements IArrayStorage <V> {
/**
* @type {IRandomGenerator}
*/
@@ -20,10 +20,10 @@ export abstract class ArrayStorage <T> implements IStorage <T> {
protected readonly options: IOptions;
/**
* @type {T[]}
* @type {V[]}
*/
@initializable()
protected storage!: T[];
protected storage!: V[];
/**
* @type {string}
@@ -56,10 +56,10 @@ export abstract class ArrayStorage <T> implements IStorage <T> {
/**
* @param {number} key
* @returns {T}
* @returns {V}
*/
public get (key: number): T {
const value: T | undefined = this.storage[key];
public get (key: number): V {
const value: V | undefined = this.storage[key];
if (!value) {
throw new Error(`No value found in array storage with key \`${key}\``);
@@ -69,10 +69,10 @@ export abstract class ArrayStorage <T> implements IStorage <T> {
}
/**
* @param {T} value
* @param {V} value
* @returns {number}
*/
public getKeyOf (value: T): number | null {
public getKeyOf (value: V): number | null {
const key: number = this.storage.indexOf(value);
return key >= 0 ? key : null;
@@ -86,9 +86,9 @@ export abstract class ArrayStorage <T> implements IStorage <T> {
}
/**
* @returns {T[]}
* @returns {V[]}
*/
public getStorage (): T[] {
public getStorage (): V[] {
return this.storage;
}
@@ -113,9 +113,9 @@ export abstract class ArrayStorage <T> implements IStorage <T> {
/**
* @param {number} key
* @param {T} value
* @param {V} value
*/
public set (key: number, value: T): void {
public set (key: number, value: V): void {
if (key === this.storageLength) {
this.storage.push(value);
} else {
+18 -18
View File
@@ -1,14 +1,14 @@
import { inject, injectable, postConstruct } from 'inversify';
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
import { IMapStorage } from '../interfaces/storages/IMapStorage';
import { IOptions } from '../interfaces/options/IOptions';
import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';
import { IStorage } from '../interfaces/storages/IStorage';
import { initializable } from '../decorators/Initializable';
@injectable()
export abstract class MapStorage <T> implements IStorage <T> {
export abstract class MapStorage <K, V> implements IMapStorage <K, V> {
/**
* @type {IOptions}
*/
@@ -26,10 +26,10 @@ export abstract class MapStorage <T> implements IStorage <T> {
protected storageId!: string;
/**
* @type {Map <string | number, T>}
* @type {Map <K, V>}
*/
@initializable()
protected storage!: Map <string | number, T>;
protected storage!: Map <K, V>;
/**
* @param {IRandomGenerator} randomGenerator
@@ -45,16 +45,16 @@ export abstract class MapStorage <T> implements IStorage <T> {
@postConstruct()
public initialize (): void {
this.storage = new Map <string | number, T>();
this.storage = new Map <K, V>();
this.storageId = this.randomGenerator.getRandomString(6);
}
/**
* @param {string | number} key
* @returns {T}
* @param {K} key
* @returns {V}
*/
public get (key: string | number): T {
const value: T | undefined = this.storage.get(key);
public get (key: K): V {
const value: V | undefined = this.storage.get(key);
if (!value) {
throw new Error(`No value found in map storage with key \`${key}\``);
@@ -64,10 +64,10 @@ export abstract class MapStorage <T> implements IStorage <T> {
}
/**
* @param {T} value
* @returns {string | number | null}
* @param {V} value
* @returns {K | null}
*/
public getKeyOf (value: T): string | number | null {
public getKeyOf (value: V): K | null {
for (const [key, storageValue] of this.storage) {
if (value === storageValue) {
return key;
@@ -85,9 +85,9 @@ export abstract class MapStorage <T> implements IStorage <T> {
}
/**
* @returns {Map <string | number, T>}
* @returns {Map<K, V>}
*/
public getStorage (): Map <string | number, T> {
public getStorage (): Map <K, V> {
return this.storage;
}
@@ -103,7 +103,7 @@ export abstract class MapStorage <T> implements IStorage <T> {
* @param {boolean} mergeId
*/
public mergeWith (storage: this, mergeId: boolean = false): void {
this.storage = new Map <string | number, T>([...this.storage, ...storage.getStorage()]);
this.storage = new Map <K, V>([...this.storage, ...storage.getStorage()]);
if (mergeId) {
this.storageId = storage.getStorageId();
@@ -111,10 +111,10 @@ export abstract class MapStorage <T> implements IStorage <T> {
}
/**
* @param {string | number} key
* @param {T} value
* @param {K} key
* @param {V} value
*/
public set (key: string | number, value: T): void {
public set (key: K, value: V): void {
this.storage.set(key, value);
}
}
@@ -8,7 +8,7 @@ import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { MapStorage } from '../MapStorage';
@injectable()
export class ControlFlowStorage extends MapStorage <ICustomNode> {
export class ControlFlowStorage extends MapStorage <string, ICustomNode> {
/**
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
@@ -12,7 +12,7 @@ import { CustomNodeGroup } from '../../enums/custom-nodes/CustomNodeGroup';
import { MapStorage } from '../MapStorage';
@injectable()
export class CustomNodeGroupStorage extends MapStorage <ICustomNodeGroup> {
export class CustomNodeGroupStorage extends MapStorage <string, ICustomNodeGroup> {
/**
* @type {CustomNodeGroup[]}
*/
+2 -2
View File
@@ -1,4 +1,4 @@
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
import { IStorage } from '../../interfaces/storages/IStorage';
import { IMapStorage } from '../../interfaces/storages/IMapStorage';
export type TControlFlowStorage = IStorage <ICustomNode>;
export type TControlFlowStorage = IMapStorage <string, ICustomNode>;
+2 -2
View File
@@ -1,4 +1,4 @@
import { ICustomNodeGroup } from '../../interfaces/custom-nodes/ICustomNodeGroup';
import { IStorage } from '../../interfaces/storages/IStorage';
import { IMapStorage } from '../../interfaces/storages/IMapStorage';
export type TCustomNodeGroupStorage = IStorage <ICustomNodeGroup>;
export type TCustomNodeGroupStorage = IMapStorage <string, ICustomNodeGroup>;
+2 -2
View File
@@ -1,3 +1,3 @@
import { IStorage } from '../../interfaces/storages/IStorage';
import { IArrayStorage } from '../../interfaces/storages/IArrayStorage';
export type TStringArrayStorage = IStorage <string>;
export type TStringArrayStorage = IArrayStorage <string>;
@@ -11,7 +11,7 @@ import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscator
describe('BinaryExpressionControlFlowReplacer', function () {
this.timeout(100000);
describe('replace (binaryExpressionNode: ESTree.BinaryExpression,parentNode: ESTree.Node,controlFlowStorage: IStorage <ICustomNode>)', () => {
describe('replace (binaryExpressionNode, parentNode, controlFlowStorage)', () => {
describe('Variant #1 - single binary expression', () => {
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\w{5}'\]\(0x1, *0x2\);/;
@@ -11,7 +11,7 @@ import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscator
describe('CallExpressionControlFlowReplacer', function () {
this.timeout(100000);
describe('replace (callExpressionNode: ESTree.CallExpression,parentNode: ESTree.Node,controlFlowStorage: IStorage <ICustomNode>)', () => {
describe('replace (callExpressionNode, parentNode, controlFlowStorage)', () => {
describe('Variant #1 - single call expression', () => {
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\w{5}'\]\(_0x([a-f0-9]){4,6}, *0x1, *0x2\);/;
@@ -11,7 +11,7 @@ import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscator
describe('LogicalExpressionControlFlowReplacer', function () {
this.timeout(100000);
describe('replace (logicalExpressionNode: ESTree.LogicalExpression,parentNode: ESTree.Node,controlFlowStorage: IStorage <ICustomNode>)', () => {
describe('replace (logicalExpressionNode, parentNode, controlFlowStorage)', () => {
describe('Variant #1 - single logical expression', () => {
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\w{5}'\]\(!!\[\], *!\[\]\);/;
@@ -9,7 +9,7 @@ import { readFileAsString } from '../../../../../helpers/readFileAsString';
import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscatorFacade';
describe('StringLiteralControlFlowReplacer', () => {
describe('replace (literalNode: ESTree.Literal,parentNode: ESTree.Node,controlFlowStorage: IStorage <ICustomNode>)', () => {
describe('replace (literalNode, parentNode, controlFlowStorage)', () => {
const controlFlowStorageStringLiteralRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *\{'\w{5}' *: *'test'\};/;
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\w{5}'\];/;
+18 -17
View File
@@ -2,15 +2,16 @@ 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 { IStorage } from '../../../src/interfaces/storages/IStorage';
import { ArrayStorage } from '../../../src/storages/ArrayStorage';
import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade';
class ConcreteStorage extends ArrayStorage <string> {
class ConcreteStorage <V> extends ArrayStorage <V> {
constructor () {
const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
@@ -24,10 +25,10 @@ class ConcreteStorage extends ArrayStorage <string> {
}
/**
* @type {IStorage<any>}
* @returns {IArrayStorage<V>}
*/
const getStorageInstance = (): IStorage <any> => {
const storage: IStorage<any> = new ConcreteStorage();
const getStorageInstance = <V> (): IArrayStorage <V> => {
const storage: IArrayStorage <V> = new ConcreteStorage <V> ();
storage.initialize();
@@ -38,7 +39,7 @@ describe('ArrayStorage', () => {
const storageKey: number = 0;
const storageValue: string = 'foo';
let storage: IStorage <any>;
let storage: IArrayStorage <any>;
describe('initialize (...args: any[]): void', () => {
const expectedError: ErrorConstructor = Error;
@@ -46,7 +47,7 @@ describe('ArrayStorage', () => {
let testFunc: () => void;
before(() => {
storage = new ConcreteStorage();
storage = new ConcreteStorage<string>();
testFunc = () => storage.set(storageKey, storageValue);
});
@@ -61,7 +62,7 @@ describe('ArrayStorage', () => {
let arrayStorage: string[];
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
arrayStorage = storage.getStorage();
});
@@ -78,7 +79,7 @@ describe('ArrayStorage', () => {
let value: string;
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, storageValue);
value = storage.get(storageKey);
@@ -95,7 +96,7 @@ describe('ArrayStorage', () => {
let testFunc: () => void;
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
testFunc = () => storage.get(storageKey);
});
@@ -112,7 +113,7 @@ describe('ArrayStorage', () => {
let storageLength: number;
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, storageValue);
storageLength = storage.getLength();
@@ -128,7 +129,7 @@ describe('ArrayStorage', () => {
describe('Variant #1', () => {
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, storageValue);
key = storage.getKeyOf(storageValue);
@@ -145,7 +146,7 @@ describe('ArrayStorage', () => {
};
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, object);
key = storage.getKeyOf(object);
@@ -163,7 +164,7 @@ describe('ArrayStorage', () => {
};
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, object);
key = storage.getKeyOf({...object});
@@ -179,7 +180,7 @@ describe('ArrayStorage', () => {
let value: string;
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, storageValue);
value = storage.get(storageKey);
@@ -199,10 +200,10 @@ describe('ArrayStorage', () => {
let array: string[];
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, storageValue);
const secondStorage: IStorage <string> = getStorageInstance();
const secondStorage: IArrayStorage <string> = getStorageInstance<string>();
secondStorage.set(secondStorageKey, secondStorageValue);
storage.mergeWith(secondStorage, false);
+22 -22
View File
@@ -3,14 +3,14 @@ import { assert } from 'chai';
import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers';
import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade';
import { IMapStorage } from '../../../src/interfaces/storages/IMapStorage';
import { IOptions } from '../../../src/interfaces/options/IOptions';
import { IRandomGenerator } from '../../../src/interfaces/utils/IRandomGenerator';
import { IStorage } from '../../../src/interfaces/storages/IStorage';
import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade';
import { MapStorage } from '../../../src/storages/MapStorage';
class ConcreteStorage extends MapStorage <string> {
class ConcreteStorage <V> extends MapStorage <string, V> {
constructor () {
const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
@@ -24,10 +24,10 @@ class ConcreteStorage extends MapStorage <string> {
}
/**
* @type {IStorage<any>}
* @returns {IMapStorage<string, V>}
*/
const getStorageInstance = (): IStorage <any> => {
const storage: IStorage<any> = new ConcreteStorage();
const getStorageInstance = <V>(): IMapStorage <string, V> => {
const storage: IMapStorage <string, V> = new ConcreteStorage <V> ();
storage.initialize();
@@ -38,7 +38,7 @@ describe('MapStorage', () => {
const storageKey: string = 'foo';
const storageValue: string = 'bar';
let storage: IStorage <any>;
let storage: IMapStorage <string, any>;
describe('initialize (...args: any[]): void', () => {
const expectedError: ErrorConstructor = Error;
@@ -55,13 +55,13 @@ describe('MapStorage', () => {
});
});
describe('getStorage (): Map <string | number, T>', () => {
describe('getStorage (): Map <K, V>', () => {
const expectedInstanceOf: MapConstructor = Map;
let mapStorage: string[];
let mapStorage: Map <string, string>;
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
mapStorage = storage.getStorage();
});
@@ -71,14 +71,14 @@ describe('MapStorage', () => {
});
});
describe('get (key: string | number): T', () => {
describe('get (key: K): V', () => {
describe('Variant #1: value exist', () => {
const expectedValue: string = storageValue;
let value: string;
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, storageValue);
value = storage.get(storageKey);
@@ -95,7 +95,7 @@ describe('MapStorage', () => {
let testFunc: () => void;
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
testFunc = () => storage.get(storageKey);
});
@@ -112,7 +112,7 @@ describe('MapStorage', () => {
let storageLength: number;
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, storageValue);
storageLength = storage.getLength();
@@ -123,12 +123,12 @@ describe('MapStorage', () => {
});
});
describe('getKeyOf (value: T): string | number | null', () => {
describe('getKeyOf (value: V): K | null', () => {
let key: string | number | null;
describe('Variant #1', () => {
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, storageValue);
key = storage.getKeyOf(storageValue);
@@ -145,7 +145,7 @@ describe('MapStorage', () => {
};
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, object);
key = storage.getKeyOf(object);
@@ -163,7 +163,7 @@ describe('MapStorage', () => {
};
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, object);
key = storage.getKeyOf({...object});
@@ -175,11 +175,11 @@ describe('MapStorage', () => {
});
});
describe('set (key: string | number, value: T): void', () => {
describe('set (key: K, value: V): void', () => {
let value: string;
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, storageValue);
value = storage.get(storageKey);
@@ -202,15 +202,15 @@ describe('MapStorage', () => {
let array: string[][];
before(() => {
storage = getStorageInstance();
storage = getStorageInstance<string>();
storage.set(storageKey, storageValue);
const secondStorage: IStorage <string> = getStorageInstance();
const secondStorage: IMapStorage <string, string> = getStorageInstance<string>();
secondStorage.set(secondStorageKey, secondStorageValue);
storage.mergeWith(secondStorage, false);
array = <any>Array.from(storage.getStorage());
array = Array.from(storage.getStorage());
});
it('should merge two storages', () => {
+8 -3
View File
@@ -709,6 +709,10 @@ ansi-styles@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178"
ansicolor@1.1.71:
version "1.1.71"
resolved "https://registry.yarnpkg.com/ansicolor/-/ansicolor-1.1.71.tgz#38bbf97db282edb1462dcb23400112407a9486e3"
any-observable@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242"
@@ -1892,10 +1896,11 @@ class-utils@^0.3.5:
lazy-cache "^2.0.2"
static-extend "^0.1.1"
class-validator@0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.8.1.tgz#f5efd5c613927e3c2f68692e8f14d53a2644fb2f"
class-validator@0.8.4:
version "0.8.4"
resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.8.4.tgz#f78d31f5aeabd27e05394be07e93f42e2041a0bb"
dependencies:
ansicolor "1.1.71"
validator "9.2.0"
cli-cursor@^1.0.2: