Code coverage report for src/node-transformers/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts

# All files / src/node-transformers/node-control-flow-transformers/control-flow-replacers AbstractControlFlowReplacer.ts

96.43% Statements 27/28
88.89% Branches 8/9
100% Functions 2/2
96.3% Lines 26/27

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    1161x
    1x

    1x

    1x

    1261x

    1261x
    1261x

    1848x

    1848x
    677x

    1171x

    1848x

    1848x
    1848x

    1848x

    1848x

    341x

    1507x
    1507x

    1507x

    1507x

    1507x

    1507x
    1507x
    1507x

    1507x

     import { injectable, inject } from 'inversify';
    import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';

    import * as ESTree from 'estree';

    import { TCustomNodeFactory } from '../../../types/container/TCustomNodeFactory';

    import { IControlFlowReplacer } from '../../../interfaces/node-transformers/IControlFlowReplacer';
    import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
    import { IOptions } from '../../../interfaces/options/IOptions';
    import { IStorage } from '../../../interfaces/storages/IStorage';

    import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';

    @injectable()
    export abstract class AbstractControlFlowReplacer implements IControlFlowReplacer {
        /**
         * @type {TCustomNodeFactory}
         */
        protected readonly customNodeFactory: TCustomNodeFactory;

        /**
         * @type {IOptions}
         */
        protected readonly options: IOptions;

        /**
         * @type {Map<string, Map<string, string[]>>}
         */
        protected readonly replacerDataByControlFlowStorageId: Map <string, Map<string, string[]>> = new Map();

        /**
         * @param customNodeFactory
         * @param options
         */
        constructor (
            @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory,
            @inject(ServiceIdentifiers.IOptions) options: IOptions
        ) {
            this.customNodeFactory = customNodeFactory;
            this.options = options;
        }

        /**
         * @param identifierDataByControlFlowStorageId
         * @param controlFlowStorageId
         * @returns {Map<string, string[]>}
         */
        protected static getStorageKeysByIdForCurrentStorage (
            identifierDataByControlFlowStorageId: Map<string, Map<string, string[]>>,
            controlFlowStorageId: string
        ): Map<string, string[]> {
            let storageKeysById: Map<string, string[]>;

            if (identifierDataByControlFlowStorageId.has(controlFlowStorageId)) {
                storageKeysById = <Map<string, string[]>>identifierDataByControlFlowStorageId.get(controlFlowStorageId);
            } else {
                storageKeysById = new Map <string, string[]> ();
            }

            return storageKeysById;
        }

        /**
         * @param node
         * @param parentNode
         * @param controlFlowStorage
         * @returns {ESTree.Node}
         */
        public abstract replace (node: ESTree.Node, parentNode: ESTree.Node, controlFlowStorage: IStorage <ICustomNode>): ESTree.Node;

        /**
         * @param customNode
         * @param controlFlowStorage
         * @param replacerId
         * @param usingExistingIdentifierChance
         * @returns {string}
         */
        protected insertCustomNodeToControlFlowStorage (
            customNode: ICustomNode,
            controlFlowStorage: IStorage <ICustomNode>,
            replacerId: string,
            usingExistingIdentifierChance: number
        ): string {
            const controlFlowStorageId: string = controlFlowStorage.getStorageId();
            const storageKeysById: Map<string, string[]> = AbstractControlFlowReplacer
                .getStorageKeysByIdForCurrentStorage(this.replacerDataByControlFlowStorageId, controlFlowStorageId);
            const storageKeysForCurrentId: string[] | undefined = storageKeysById.get(replacerId);

            if (
                RandomGeneratorUtils.getRandomFloat(0, 1) > usingExistingIdentifierChance &&
                storageKeysForCurrentId &&
                storageKeysForCurrentId.length
            ) {
                return RandomGeneratorUtils.getRandomGenerator().pickone(storageKeysForCurrentId);
            }

            const generateStorageKey: (length: number) => string = (length: number) => {
                const storageKey: string = RandomGeneratorUtils.getRandomString(length);

                Iif (controlFlowStorage.getStorage().has(storageKey)) {
                    return generateStorageKey(length);
                }

                return storageKey;
            };
            const storageKey: string = generateStorageKey(3);

            storageKeysById.set(replacerId, [storageKey]);
            this.replacerDataByControlFlowStorageId.set(controlFlowStorageId, storageKeysById);
            controlFlowStorage.set(storageKey, customNode);

            return storageKey;
        }
    }