Browse Source

New CLI option: `exclude`

sanex3339 7 years ago
parent
commit
e5778b4fa4
59 changed files with 1096 additions and 508 deletions
  1. 4 0
      CHANGELOG.md
  2. 6 0
      README.md
  3. 0 0
      dist/index.js
  4. 4 2
      package.json
  5. 7 8
      src/cli/JavaScriptObfuscatorCLI.ts
  6. 82 33
      src/cli/utils/SourceCodeReader.ts
  7. 1 0
      src/interfaces/options/ICLIOptions.d.ts
  8. 1 0
      src/options/presets/Default.ts
  9. 1 0
      src/options/presets/NoCustomNodes.ts
  10. 10 10
      test/functional-tests/analyzers/stack-trace-analyzer/StackTraceAnalyzer.spec.ts
  11. 341 162
      test/functional-tests/cli/JavaScriptObfuscatorCLI.spec.ts
  12. 8 8
      test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts
  13. 15 15
      test/functional-tests/node-transformers/control-flow-transformers/block-statement-control-flow-transformer/BlockStatementControlFlowTransformer.spec.ts
  14. 2 2
      test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer/BinaryExpressionControlFlowReplacer.spec.ts
  15. 3 3
      test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/call-expression-control-flow-replacer/CallExpressionControlFlowReplacer.spec.ts
  16. 4 4
      test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/logical-expression-control-flow-replacer/LogicalExpressionControlFlowReplacer.spec.ts
  17. 8 8
      test/functional-tests/node-transformers/control-flow-transformers/function-control-flow-transformer/FunctionControlFlowTransformer.spec.ts
  18. 2 2
      test/functional-tests/node-transformers/converting-transformers/member-expression-transformer/MemberExpressionTransformer.spec.ts
  19. 3 3
      test/functional-tests/node-transformers/converting-transformers/method-definition-transformer/MethodDefinitionTransformer.spec.ts
  20. 10 10
      test/functional-tests/node-transformers/converting-transformers/object-expression-keys-transformer/ObjectExpressionKeysTransformer.spec.ts
  21. 10 10
      test/functional-tests/node-transformers/converting-transformers/template-literal-transformer/TemplateLiteralTransformer.spec.ts
  22. 18 18
      test/functional-tests/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.spec.ts
  23. 4 4
      test/functional-tests/node-transformers/obfuscating-transformers/class-declaration-transformer/ClassDeclarationTransformer.spec.ts
  24. 6 6
      test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/FunctionDeclarationTransformer.spec.ts
  25. 5 5
      test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/FunctionTransformer.spec.ts
  26. 13 13
      test/functional-tests/node-transformers/obfuscating-transformers/literal-transformer/LiteralTransformer.spec.ts
  27. 16 16
      test/functional-tests/node-transformers/obfuscating-transformers/variable-declaration-transformer/VariableDeclarationTransformer.spec.ts
  28. 6 6
      test/functional-tests/node-transformers/preparing-transformers/comments-transformer/CommentsTransformer.spec.ts
  29. 9 9
      test/functional-tests/node-transformers/preparing-transformers/eval-call-expression-transformer/EvalCallExpressionTransformer.spec.ts
  30. 5 5
      test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/ConditionalCommentObfuscatingGuard.spec.ts
  31. 2 2
      test/functional-tests/options/OptionsNormalizer.spec.ts
  32. 3 3
      test/functional-tests/templates/GlobalVariableNoEvalTemplate.spec.ts
  33. 5 5
      test/functional-tests/templates/debug-protection-nodes/DebugProtectionFunctionCallTemplate.spec.ts
  34. 3 3
      test/functional-tests/templates/domain-lock-nodes/DomainLockNodeTemplate.spec.ts
  35. 2 2
      test/functional-tests/templates/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec.ts
  36. 1 1
      test/runtime-tests/JavaScriptObfuscatorRuntime.spec.ts
  37. 4 4
      test/unit-tests/analyzers/stack-trace-analyzer/StackTraceAnalyzer.spec.ts
  38. 3 3
      test/unit-tests/cli/sanitizers/ArraySanitizer.spec.ts
  39. 4 4
      test/unit-tests/cli/sanitizers/BooleanSanitizer.spec.ts
  40. 2 2
      test/unit-tests/cli/sanitizers/IdentifierNamesGeneratorSanitizer.spec.ts
  41. 2 2
      test/unit-tests/cli/sanitizers/ObfuscationTargetSanitizer.spec.ts
  42. 2 2
      test/unit-tests/cli/sanitizers/SourceMapModeSanitizer.spec.ts
  43. 5 5
      test/unit-tests/cli/sanitizers/StringArrayEncodingSanitizer.spec.ts
  44. 6 6
      test/unit-tests/cli/utils/CLIUtils.spec.ts
  45. 335 16
      test/unit-tests/cli/utils/SourceCodeReader.spec.ts
  46. 9 9
      test/unit-tests/decorators/initializable/Initializable.spec.ts
  47. 8 8
      test/unit-tests/generators/identifier-names-generators/MangledlIdentifierNamesGenerator.spec.ts
  48. 2 2
      test/unit-tests/javascript-obfuscator/EsprimaFacade.spec.ts
  49. 2 2
      test/unit-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts
  50. 2 2
      test/unit-tests/node-transformers/preparing-transformers/ObfuscatingGuardsTransformer.spec.ts
  51. 5 5
      test/unit-tests/node/node-appender/NodeAppender.spec.ts
  52. 20 20
      test/unit-tests/node/node-guards/NodeGuards.spec.ts
  53. 10 10
      test/unit-tests/node/node-utils/NodeUtils.spec.ts
  54. 3 3
      test/unit-tests/options/ValidationErrorsFormatter.spec.ts
  55. 5 5
      test/unit-tests/storages/ArrayStorage.spec.ts
  56. 5 5
      test/unit-tests/storages/MapStorage.spec.ts
  57. 2 2
      test/unit-tests/utils/EscapeSequenceEncoder.spec.ts
  58. 9 9
      test/unit-tests/utils/Utils.spec.ts
  59. 31 4
      yarn.lock

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 Change Log
 Change Log
 ===
 ===
+v0.15.0
+---
+* **New CLI option:** `exclude` allows to exclude specific files or directories from obfuscation.
+
 v0.14.3
 v0.14.3
 ---
 ---
 * Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/195
 * Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/195

+ 6 - 0
README.md

@@ -315,6 +315,7 @@ Following options are available for the JS Obfuscator:
     --debug-protection-interval <boolean>
     --debug-protection-interval <boolean>
     --disable-console-output <boolean>
     --disable-console-output <boolean>
     --domain-lock '<list>' (comma separated)
     --domain-lock '<list>' (comma separated)
+    --exclude '<list>' (comma separated)
     --identifier-names-generator <string> [hexadecimal, mangled]
     --identifier-names-generator <string> [hexadecimal, mangled]
     --identifiers-prefix <string>
     --identifiers-prefix <string>
     --log <boolean>
     --log <boolean>
@@ -564,6 +565,11 @@ Locks the obfuscated source code so it only runs on specific domains and/or sub-
 ##### Multiple domains and sub-domains
 ##### Multiple domains and sub-domains
 It's possible to lock your code to more than one domain or sub-domain. For instance, to lock it so the code only runs on **www.example.com** add `www.example.com`, to make it work on any sub-domain from example.com, use `.example.com`.
 It's possible to lock your code to more than one domain or sub-domain. For instance, to lock it so the code only runs on **www.example.com** add `www.example.com`, to make it work on any sub-domain from example.com, use `.example.com`.
 
 
+### `exclude`
+Type: `string[]` Default: `[]`
+
+A file names or globs which indicates files to exclude from obfuscation. 
+
 ### `identifierNamesGenerator`
 ### `identifierNamesGenerator`
 Type: `string` Default: `hexadecimal`
 Type: `string` Default: `hexadecimal`
 
 

File diff suppressed because it is too large
+ 0 - 0
dist/index.js


+ 4 - 2
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "javascript-obfuscator",
   "name": "javascript-obfuscator",
-  "version": "0.14.3",
+  "version": "0.15.0-dev.0",
   "description": "JavaScript obfuscator",
   "description": "JavaScript obfuscator",
   "keywords": [
   "keywords": [
     "obfuscator",
     "obfuscator",
@@ -30,6 +30,7 @@
     "js-string-escape": "1.0.1",
     "js-string-escape": "1.0.1",
     "md5": "2.2.1",
     "md5": "2.2.1",
     "mkdirp": "0.5.1",
     "mkdirp": "0.5.1",
+    "multimatch": "2.1.0",
     "opencollective": "1.0.3",
     "opencollective": "1.0.3",
     "pjson": "1.0.9",
     "pjson": "1.0.9",
     "reflect-metadata": "0.1.12",
     "reflect-metadata": "0.1.12",
@@ -47,6 +48,7 @@
     "@types/md5": "2.1.32",
     "@types/md5": "2.1.32",
     "@types/mkdirp": "0.5.2",
     "@types/mkdirp": "0.5.2",
     "@types/mocha": "2.2.48",
     "@types/mocha": "2.2.48",
+    "@types/multimatch": "2.1.2",
     "@types/node": "9.4.6",
     "@types/node": "9.4.6",
     "@types/rimraf": "2.0.2",
     "@types/rimraf": "2.0.2",
     "@types/sinon": "4.1.3",
     "@types/sinon": "4.1.3",
@@ -63,7 +65,7 @@
     "mocha": "5.0.1",
     "mocha": "5.0.1",
     "pre-commit": "1.2.2",
     "pre-commit": "1.2.2",
     "rimraf": "2.6.2",
     "rimraf": "2.6.2",
-    "sinon": "4.3.0",
+    "sinon": "4.4.1",
     "threads": "0.10.1",
     "threads": "0.10.1",
     "ts-node": "5.0.0",
     "ts-node": "5.0.0",
     "tslint": "5.9.1",
     "tslint": "5.9.1",

+ 7 - 8
src/cli/JavaScriptObfuscatorCLI.ts

@@ -26,13 +26,6 @@ import { JavaScriptObfuscator } from '../JavaScriptObfuscatorFacade';
 import { SourceCodeReader } from './utils/SourceCodeReader';
 import { SourceCodeReader } from './utils/SourceCodeReader';
 
 
 export class JavaScriptObfuscatorCLI implements IInitializable {
 export class JavaScriptObfuscatorCLI implements IInitializable {
-    /**
-     * @type {string[]}
-     */
-    public static readonly availableInputExtensions: string[] = [
-        '.js'
-    ];
-
     /**
     /**
      * @type {BufferEncoding}
      * @type {BufferEncoding}
      */
      */
@@ -163,7 +156,8 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
             return this.commands.outputHelp();
             return this.commands.outputHelp();
         }
         }
 
 
-        const sourceCodeData: TSourceCodeData = SourceCodeReader.readSourceCode(this.inputPath);
+        const sourceCodeData: TSourceCodeData = new SourceCodeReader(this.inputCLIOptions)
+            .readSourceCode(this.inputPath, this.inputCLIOptions.exclude);
 
 
         this.processSourceCodeData(sourceCodeData);
         this.processSourceCodeData(sourceCodeData);
     }
     }
@@ -244,6 +238,11 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
                 'Blocks the execution of the code in domains that do not match the passed RegExp patterns (comma separated)',
                 'Blocks the execution of the code in domains that do not match the passed RegExp patterns (comma separated)',
                 ArraySanitizer
                 ArraySanitizer
             )
             )
+            .option(
+                '--exclude <list> (comma separated, without whitespaces)',
+                'A filename or glob which indicates files to exclude from obfuscation',
+                ArraySanitizer
+            )
             .option(
             .option(
                 '--identifier-names-generator <string> [hexadecimal, mangled]', 'Sets identifier names generator (Default: hexadecimal)',
                 '--identifier-names-generator <string> [hexadecimal, mangled]', 'Sets identifier names generator (Default: hexadecimal)',
                 IdentifierNamesGeneratorSanitizer
                 IdentifierNamesGeneratorSanitizer

+ 82 - 33
src/cli/utils/SourceCodeReader.ts

@@ -1,6 +1,8 @@
 import * as fs from 'fs';
 import * as fs from 'fs';
 import * as path from 'path';
 import * as path from 'path';
+import multimatch from 'multimatch';
 
 
+import { TInputCLIOptions } from '../../types/options/TInputCLIOptions';
 import { TSourceCodeData } from '../../types/cli/TSourceCodeData';
 import { TSourceCodeData } from '../../types/cli/TSourceCodeData';
 
 
 import { IFileData } from '../../interfaces/cli/IFileData';
 import { IFileData } from '../../interfaces/cli/IFileData';
@@ -12,19 +14,41 @@ import { Logger } from '../../logger/Logger';
 
 
 export class SourceCodeReader {
 export class SourceCodeReader {
     /**
     /**
-     * @param {string} inputPath
-     * @returns {TSourceCodeData}
+     * @type {string[]}
      */
      */
-    public static readSourceCode (inputPath: string): TSourceCodeData {
-        if (SourceCodeReader.isFilePath(inputPath)) {
-            return SourceCodeReader.readFile(inputPath);
-        }
+    public static readonly availableInputExtensions: string[] = [
+        '.js'
+    ];
+
+    /**
+     * @type {TInputCLIOptions}
+     */
+    private readonly options: TInputCLIOptions;
+
+    /**
+     * @param {TInputCLIOptions} options
+     */
+    constructor (options: TInputCLIOptions) {
+        this.options = options;
+    }
 
 
-        if (SourceCodeReader.isDirectoryPath(inputPath)) {
-            return SourceCodeReader.readDirectoryRecursive(inputPath);
+    /**
+     * @param {string} filePath
+     * @param {string[]} excludePatterns
+     * @returns {boolean}
+     */
+    private static isExcludedPath (filePath: string, excludePatterns: string[] = []): boolean {
+        if (!excludePatterns.length) {
+            return false;
         }
         }
 
 
-        throw new ReferenceError(`Given input path must be a valid source code file or directory path`);
+        const fileName: string = path.basename(filePath);
+        const isExcludedFilePathByGlobPattern: boolean = !!multimatch([filePath], excludePatterns).length;
+        const isExcludedFilePathByInclusion: boolean = excludePatterns.some((excludePattern: string) =>
+            filePath.includes(excludePattern) || fileName.includes(excludePattern)
+        );
+
+        return isExcludedFilePathByInclusion || isExcludedFilePathByGlobPattern;
     }
     }
 
 
     /**
     /**
@@ -51,22 +75,55 @@ export class SourceCodeReader {
         }
         }
     }
     }
 
 
+    /**
+     * @param {string} filePath
+     */
+    private static logFilePath (filePath: string): void {
+        const normalizedFilePath: string = path.normalize(filePath);
+
+        Logger.log(
+            Logger.colorInfo,
+            LoggingPrefix.CLI,
+            `Obfuscating file: ${normalizedFilePath}...`
+        );
+    }
+
+    /**
+     * @param {string} inputPath
+     * @param {string[]} excludePatterns
+     * @returns {TSourceCodeData}
+     */
+    public readSourceCode (inputPath: string, excludePatterns: string[] = []): TSourceCodeData {
+        if (SourceCodeReader.isFilePath(inputPath) && this.isValidFile(inputPath)) {
+            return this.readFile(inputPath);
+        }
+
+        if (SourceCodeReader.isDirectoryPath(inputPath) && this.isValidDirectory(inputPath)) {
+            return this.readDirectoryRecursive(inputPath);
+        }
+
+        const availableFilePaths: string = SourceCodeReader
+            .availableInputExtensions
+            .map((extension: string) => `\`${extension}\``)
+            .join(', ');
+
+        throw new ReferenceError(`Given input path must be a valid ${availableFilePaths} file or directory path`);
+    }
+
     /**
     /**
      * @param {string} directoryPath
      * @param {string} directoryPath
      * @param {IFileData[]} fileData
      * @param {IFileData[]} fileData
      * @returns {IFileData[]}
      * @returns {IFileData[]}
      */
      */
-    private static readDirectoryRecursive (directoryPath: string, fileData: IFileData[] = []): IFileData[] {
+    private readDirectoryRecursive (directoryPath: string, fileData: IFileData[] = []): IFileData[] {
         fs.readdirSync(directoryPath, JavaScriptObfuscatorCLI.encoding)
         fs.readdirSync(directoryPath, JavaScriptObfuscatorCLI.encoding)
             .forEach((fileName: string) => {
             .forEach((fileName: string) => {
                 const filePath: string = `${directoryPath}/${fileName}`;
                 const filePath: string = `${directoryPath}/${fileName}`;
 
 
-                if (SourceCodeReader.isDirectoryPath(filePath)) {
-                    fileData.push(
-                        ...SourceCodeReader.readDirectoryRecursive(filePath)
-                    );
-                } else if (SourceCodeReader.isFilePath(filePath) && SourceCodeReader.isValidFile(fileName)) {
-                    const content: string = SourceCodeReader.readFile(filePath);
+                if (SourceCodeReader.isDirectoryPath(filePath) && this.isValidDirectory(filePath)) {
+                    fileData.push(...this.readDirectoryRecursive(filePath));
+                } else if (SourceCodeReader.isFilePath(filePath) && this.isValidFile(filePath)) {
+                    const content: string = this.readFile(filePath);
 
 
                     fileData.push({ filePath, content });
                     fileData.push({ filePath, content });
                 }
                 }
@@ -79,35 +136,27 @@ export class SourceCodeReader {
      * @param {string} filePath
      * @param {string} filePath
      * @returns {string}
      * @returns {string}
      */
      */
-    private static readFile (filePath: string): string {
-        if (!SourceCodeReader.isValidFile(filePath)) {
-            throw new ReferenceError(`Input file must have .js extension`);
-        }
-
+    private readFile (filePath: string): string {
         SourceCodeReader.logFilePath(filePath);
         SourceCodeReader.logFilePath(filePath);
 
 
         return fs.readFileSync(filePath, JavaScriptObfuscatorCLI.encoding);
         return fs.readFileSync(filePath, JavaScriptObfuscatorCLI.encoding);
     }
     }
 
 
     /**
     /**
-     * @param {string} filePath
+     * @param {string} directoryPath
      * @returns {boolean}
      * @returns {boolean}
      */
      */
-    private static isValidFile (filePath: string): boolean {
-        return JavaScriptObfuscatorCLI.availableInputExtensions.includes(path.extname(filePath))
-            && !filePath.includes(JavaScriptObfuscatorCLI.obfuscatedFilePrefix);
+    private isValidDirectory (directoryPath: string): boolean {
+        return !SourceCodeReader.isExcludedPath(directoryPath, this.options.exclude);
     }
     }
 
 
     /**
     /**
      * @param {string} filePath
      * @param {string} filePath
+     * @returns {boolean}
      */
      */
-    private static logFilePath (filePath: string): void {
-        const normalizedFilePath: string = path.normalize(filePath);
-
-        Logger.log(
-            Logger.colorInfo,
-            LoggingPrefix.CLI,
-            `Obfuscating file: ${normalizedFilePath}...`
-        );
+    private isValidFile (filePath: string): boolean {
+        return SourceCodeReader.availableInputExtensions.includes(path.extname(filePath))
+            && !filePath.includes(JavaScriptObfuscatorCLI.obfuscatedFilePrefix)
+            && !SourceCodeReader.isExcludedPath(filePath, this.options.exclude);
     }
     }
 }
 }

+ 1 - 0
src/interfaces/options/ICLIOptions.d.ts

@@ -2,6 +2,7 @@ import { IOptions } from './IOptions';
 
 
 export interface ICLIOptions extends IOptions {
 export interface ICLIOptions extends IOptions {
     readonly config: string;
     readonly config: string;
+    readonly exclude: string[];
     readonly output: string;
     readonly output: string;
     readonly version: string;
     readonly version: string;
 }
 }

+ 1 - 0
src/options/presets/Default.ts

@@ -15,6 +15,7 @@ export const DEFAULT_PRESET: TInputOptions = Object.freeze({
     debugProtectionInterval: false,
     debugProtectionInterval: false,
     disableConsoleOutput: false,
     disableConsoleOutput: false,
     domainLock: [],
     domainLock: [],
+    exclude: [],
     identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
     identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
     identifiersPrefix: '',
     identifiersPrefix: '',
     log: false,
     log: false,

+ 1 - 0
src/options/presets/NoCustomNodes.ts

@@ -14,6 +14,7 @@ export const NO_ADDITIONAL_NODES_PRESET: TInputOptions = Object.freeze({
     debugProtectionInterval: false,
     debugProtectionInterval: false,
     disableConsoleOutput: false,
     disableConsoleOutput: false,
     domainLock: [],
     domainLock: [],
+    exclude: [],
     identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
     identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
     identifiersPrefix: '',
     identifiersPrefix: '',
     log: false,
     log: false,

+ 10 - 10
test/functional-tests/analyzers/stack-trace-analyzer/StackTraceAnalyzer.spec.ts

@@ -162,7 +162,7 @@ describe('StackTraceAnalyzer', () => {
                 .get<IStackTraceAnalyzer>(ServiceIdentifiers.IStackTraceAnalyzer);
                 .get<IStackTraceAnalyzer>(ServiceIdentifiers.IStackTraceAnalyzer);
         });
         });
 
 
-        describe('variant #1: basic-1', () => {
+        describe('Variant #1: basic-1', () => {
             before(() => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/basic-1.js');
                 const code: string = readFileAsString(__dirname + '/fixtures/basic-1.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -212,7 +212,7 @@ describe('StackTraceAnalyzer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: basic-2', () => {
+        describe('Variant #2: basic-2', () => {
             before(() => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/basic-2.js');
                 const code: string = readFileAsString(__dirname + '/fixtures/basic-2.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -251,7 +251,7 @@ describe('StackTraceAnalyzer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: deep conditions nesting', () => {
+        describe('Variant #3: deep conditions nesting', () => {
             before(() => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/deep-conditions-nesting.js');
                 const code: string = readFileAsString(__dirname + '/fixtures/deep-conditions-nesting.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -290,7 +290,7 @@ describe('StackTraceAnalyzer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4: call before declaration', () => {
+        describe('Variant #4: call before declaration', () => {
             before(() => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/call-before-declaration.js');
                 const code: string = readFileAsString(__dirname + '/fixtures/call-before-declaration.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -313,7 +313,7 @@ describe('StackTraceAnalyzer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #5: call expression of object member #1', () => {
+        describe('Variant #5: call expression of object member #1', () => {
             before(() => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/call-expression-of-object-member-1.js');
                 const code: string = readFileAsString(__dirname + '/fixtures/call-expression-of-object-member-1.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -372,7 +372,7 @@ describe('StackTraceAnalyzer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #5: call expression of object member #2', () => {
+        describe('Variant #5: call expression of object member #2', () => {
             before(() => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/call-expression-of-object-member-2.js');
                 const code: string = readFileAsString(__dirname + '/fixtures/call-expression-of-object-member-2.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -400,7 +400,7 @@ describe('StackTraceAnalyzer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #6: no call expressions', () => {
+        describe('Variant #6: no call expressions', () => {
             before(() => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/no-call-expressions.js');
                 const code: string = readFileAsString(__dirname + '/fixtures/no-call-expressions.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -417,7 +417,7 @@ describe('StackTraceAnalyzer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #7: only call expression', () => {
+        describe('Variant #7: only call expression', () => {
             before(() => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/only-call-expression.js');
                 const code: string = readFileAsString(__dirname + '/fixtures/only-call-expression.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -434,7 +434,7 @@ describe('StackTraceAnalyzer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #8: self-invoking functions', () => {
+        describe('Variant #8: self-invoking functions', () => {
             before(() => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/self-invoking-functions.js');
                 const code: string = readFileAsString(__dirname + '/fixtures/self-invoking-functions.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -469,7 +469,7 @@ describe('StackTraceAnalyzer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #9: no recursion', () => {
+        describe('Variant #9: no recursion', () => {
             before(() => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/no-recursion.js');
                 const code: string = readFileAsString(__dirname + '/fixtures/no-recursion.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(

+ 341 - 162
test/functional-tests/cli/JavaScriptObfuscatorCLI.spec.ts

@@ -12,6 +12,8 @@ import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscatorFacade';
 describe('JavaScriptObfuscatorCLI', function (): void {
 describe('JavaScriptObfuscatorCLI', function (): void {
     this.timeout(100000);
     this.timeout(100000);
 
 
+    const expectedError: RegExp = /Given input path must be a valid/;
+
     const fixturesDirName: string = 'test/fixtures';
     const fixturesDirName: string = 'test/fixtures';
     const fixtureFileName: string = 'sample.js';
     const fixtureFileName: string = 'sample.js';
     const fixtureFilePath: string = `${fixturesDirName}/${fixtureFileName}`;
     const fixtureFilePath: string = `${fixturesDirName}/${fixtureFileName}`;
@@ -58,7 +60,7 @@ describe('JavaScriptObfuscatorCLI', function (): void {
             });
             });
 
 
             describe('`--output` option isn\'t set', () => {
             describe('`--output` option isn\'t set', () => {
-                describe('variant #1: default behaviour', () => {
+                describe('Variant #1: default behaviour', () => {
                     let outputFixturesFilePath: string,
                     let outputFixturesFilePath: string,
                         isFileExist: boolean;
                         isFileExist: boolean;
 
 
@@ -83,9 +85,7 @@ describe('JavaScriptObfuscatorCLI', function (): void {
                     });
                     });
                 });
                 });
 
 
-                describe('variant #2: invalid input file path', () => {
-                    const expectedError: ReferenceErrorConstructor = ReferenceError;
-
+                describe('Variant #2: invalid input file path', () => {
                     let testFunc: () => void;
                     let testFunc: () => void;
 
 
                     before(() => {
                     before(() => {
@@ -101,8 +101,8 @@ describe('JavaScriptObfuscatorCLI', function (): void {
                     });
                     });
                 });
                 });
 
 
-                describe('variant #3: input file extension isn\'t `.js`', () => {
-                    const expectedError: ReferenceErrorConstructor = ReferenceError;
+                describe('Variant #3: input file extension isn\'t `.js`', () => {
+                    const expectedError: RegExp = /Given input path must be a valid/;
                     const outputFileName: string = 'sample-obfuscated.ts';
                     const outputFileName: string = 'sample-obfuscated.ts';
                     const outputFilePath: string = `${outputDirName}/${outputFileName}`;
                     const outputFilePath: string = `${outputDirName}/${outputFileName}`;
 
 
@@ -127,199 +127,378 @@ describe('JavaScriptObfuscatorCLI', function (): void {
                     });
                     });
                 });
                 });
             });
             });
+
+            describe('--exclude option', () => {
+                describe('Variant #1: --exclude option is pointed on different file', () => {
+                    let isFileExist: boolean;
+
+                    before(() => {
+                        JavaScriptObfuscator.runCLI([
+                            'node',
+                            'javascript-obfuscator',
+                            fixtureFilePath,
+                            '--output',
+                            outputFilePath,
+                            '--exclude',
+                            '**/foo.js'
+                        ]);
+
+                        isFileExist = fs.existsSync(outputFilePath);
+                    });
+
+                    it('should create file with obfuscated code in `--output` directory', () => {
+                        assert.equal(isFileExist, true);
+                    });
+                });
+
+                describe('Variant #2: --exclude option is pointed on input file', () => {
+                    let testFunc: () => void;
+
+                    before(() => {
+                        testFunc = () => JavaScriptObfuscator.runCLI([
+                            'node',
+                            'javascript-obfuscator',
+                            fixtureFilePath,
+                            '--output',
+                            outputFilePath,
+                            '--exclude',
+                            '**/sample.js'
+                        ]);
+                    });
+
+                    it('should throw an error', () => {
+                        assert.throws(testFunc, expectedError);
+                    });
+
+                    after(() => {
+                        fs.unlinkSync(outputFilePath);
+                    });
+                });
+            });
         });
         });
 
 
         describe('Variant #2: obfuscation of directory', () => {
         describe('Variant #2: obfuscation of directory', () => {
-            const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
-            const outputFileName1: string = 'foo-obfuscated.js';
-            const outputFileName2: string = 'bar-obfuscated.js';
-            const outputFileName3: string = 'baz-obfuscated.js';
-            const readFileEncoding: string = 'utf8';
-            const regExp1: RegExp = /^var *a1_0x(\w){4,6} *= *0x1;$/;
-            const regExp2: RegExp = /^var *a0_0x(\w){4,6} *= *0x2;$/;
-
-            let outputFixturesFilePath1: string,
-                outputFixturesFilePath2: string,
-                outputFixturesFilePath3: string,
-                isFileExist1: boolean,
-                isFileExist2: boolean,
-                isFileExist3: boolean,
-                fileContent1: string,
-                fileContent2: string;
+            describe(`Variant #1: default behaviour`, () => {
+                const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
+                const outputFileName1: string = 'foo-obfuscated.js';
+                const outputFileName2: string = 'bar-obfuscated.js';
+                const outputFileName3: string = 'baz-obfuscated.js';
+                const readFileEncoding: string = 'utf8';
+                const regExp1: RegExp = /^var *a1_0x(\w){4,6} *= *0x1;$/;
+                const regExp2: RegExp = /^var *a0_0x(\w){4,6} *= *0x2;$/;
+
+                let outputFixturesFilePath1: string,
+                    outputFixturesFilePath2: string,
+                    outputFixturesFilePath3: string,
+                    isFileExist1: boolean,
+                    isFileExist2: boolean,
+                    isFileExist3: boolean,
+                    fileContent1: string,
+                    fileContent2: string;
 
 
-            before(() => {
-                outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
-                outputFixturesFilePath2 = `${directoryPath}/${outputFileName2}`;
-                outputFixturesFilePath3 = `${directoryPath}/${outputFileName3}`;
+                before(() => {
+                    outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
+                    outputFixturesFilePath2 = `${directoryPath}/${outputFileName2}`;
+                    outputFixturesFilePath3 = `${directoryPath}/${outputFileName3}`;
 
 
-                JavaScriptObfuscator.runCLI([
-                    'node',
-                    'javascript-obfuscator',
-                    directoryPath,
-                    '--rename-globals',
-                    'true'
-                ]);
+                    JavaScriptObfuscator.runCLI([
+                        'node',
+                        'javascript-obfuscator',
+                        directoryPath,
+                        '--rename-globals',
+                        'true'
+                    ]);
 
 
-                isFileExist1 = fs.existsSync(outputFixturesFilePath1);
-                isFileExist2 = fs.existsSync(outputFixturesFilePath2);
-                isFileExist3 = fs.existsSync(outputFixturesFilePath3);
+                    isFileExist1 = fs.existsSync(outputFixturesFilePath1);
+                    isFileExist2 = fs.existsSync(outputFixturesFilePath2);
+                    isFileExist3 = fs.existsSync(outputFixturesFilePath3);
 
 
-                fileContent1 = fs.readFileSync(outputFixturesFilePath1, readFileEncoding);
-                fileContent2 = fs.readFileSync(outputFixturesFilePath2, readFileEncoding);
-            });
+                    fileContent1 = fs.readFileSync(outputFixturesFilePath1, readFileEncoding);
+                    fileContent2 = fs.readFileSync(outputFixturesFilePath2, readFileEncoding);
+                });
 
 
-            it(`should create file \`${outputFileName1}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
-                assert.equal(isFileExist1, true);
-            });
+                it(`should create file \`${outputFileName1}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
+                    assert.equal(isFileExist1, true);
+                });
 
 
-            it(`should create file \`${outputFileName2}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
-                assert.equal(isFileExist2, true);
-            });
+                it(`should create file \`${outputFileName2}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
+                    assert.equal(isFileExist2, true);
+                });
 
 
-            it(`shouldn't create file \`${outputFileName3}\` in \`${fixturesDirName}\` directory`, () => {
-                assert.equal(isFileExist3, false);
-            });
+                it(`shouldn't create file \`${outputFileName3}\` in \`${fixturesDirName}\` directory`, () => {
+                    assert.equal(isFileExist3, false);
+                });
 
 
-            it(`match #1: should create file with obfuscated code with prefixed identifier`, () => {
-                assert.match(fileContent1, regExp1);
-            });
+                it(`match #1: should create file with obfuscated code with prefixed identifier`, () => {
+                    assert.match(fileContent1, regExp1);
+                });
 
 
-            it(`match #2: should create file with obfuscated code with prefixed identifier`, () => {
-                assert.match(fileContent2, regExp2);
-            });
+                it(`match #2: should create file with obfuscated code with prefixed identifier`, () => {
+                    assert.match(fileContent2, regExp2);
+                });
 
 
-            after(() => {
-                rimraf.sync(outputFixturesFilePath1);
-                rimraf.sync(outputFixturesFilePath2);
+                after(() => {
+                    rimraf.sync(outputFixturesFilePath1);
+                    rimraf.sync(outputFixturesFilePath2);
+                });
             });
             });
-        });
 
 
-        describe('Variant #3: obfuscation of directory with `identifiersPrefix` option value', () => {
-            const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
-            const identifiersPrefix: string = 'foo';
-            const outputFileName1: string = 'foo-obfuscated.js';
-            const outputFileName2: string = 'bar-obfuscated.js';
-            const readFileEncoding: string = 'utf8';
-            const regExp1: RegExp = /^var *foo1_0x(\w){4,6} *= *0x1;$/;
-            const regExp2: RegExp = /^var *foo0_0x(\w){4,6} *= *0x2;$/;
-
-            let outputFixturesFilePath1: string,
-                outputFixturesFilePath2: string,
-                isFileExist1: boolean,
-                isFileExist2: boolean,
-                fileContent1: string,
-                fileContent2: string;
+            describe('Variant #2: obfuscation of directory with `identifiersPrefix` option value', () => {
+                const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
+                const identifiersPrefix: string = 'foo';
+                const outputFileName1: string = 'foo-obfuscated.js';
+                const outputFileName2: string = 'bar-obfuscated.js';
+                const readFileEncoding: string = 'utf8';
+                const regExp1: RegExp = /^var *foo1_0x(\w){4,6} *= *0x1;$/;
+                const regExp2: RegExp = /^var *foo0_0x(\w){4,6} *= *0x2;$/;
 
 
-            before(() => {
-                outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
-                outputFixturesFilePath2 = `${directoryPath}/${outputFileName2}`;
+                let outputFixturesFilePath1: string,
+                    outputFixturesFilePath2: string,
+                    isFileExist1: boolean,
+                    isFileExist2: boolean,
+                    fileContent1: string,
+                    fileContent2: string;
 
 
-                JavaScriptObfuscator.runCLI([
-                    'node',
-                    'javascript-obfuscator',
-                    directoryPath,
-                    '--identifiers-prefix',
-                    identifiersPrefix,
-                    '--rename-globals',
-                    'true'
-                ]);
+                before(() => {
+                    outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
+                    outputFixturesFilePath2 = `${directoryPath}/${outputFileName2}`;
 
 
-                isFileExist1 = fs.existsSync(outputFixturesFilePath1);
-                isFileExist2 = fs.existsSync(outputFixturesFilePath2);
+                    JavaScriptObfuscator.runCLI([
+                        'node',
+                        'javascript-obfuscator',
+                        directoryPath,
+                        '--identifiers-prefix',
+                        identifiersPrefix,
+                        '--rename-globals',
+                        'true'
+                    ]);
 
 
-                fileContent1 = fs.readFileSync(outputFixturesFilePath1, readFileEncoding);
-                fileContent2 = fs.readFileSync(outputFixturesFilePath2, readFileEncoding);
-            });
+                    isFileExist1 = fs.existsSync(outputFixturesFilePath1);
+                    isFileExist2 = fs.existsSync(outputFixturesFilePath2);
 
 
-            it(`should create file \`${outputFileName1}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
-                assert.equal(isFileExist1, true);
-            });
+                    fileContent1 = fs.readFileSync(outputFixturesFilePath1, readFileEncoding);
+                    fileContent2 = fs.readFileSync(outputFixturesFilePath2, readFileEncoding);
+                });
 
 
-            it(`should create file \`${outputFileName2}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
-                assert.equal(isFileExist2, true);
-            });
+                it(`should create file \`${outputFileName1}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
+                    assert.equal(isFileExist1, true);
+                });
 
 
-            it(`match #1: should create file with obfuscated code with prefixed identifier`, () => {
-                assert.match(fileContent1, regExp1);
-            });
+                it(`should create file \`${outputFileName2}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
+                    assert.equal(isFileExist2, true);
+                });
 
 
-            it(`match #2: should create file with obfuscated code with prefixed identifier`, () => {
-                assert.match(fileContent2, regExp2);
-            });
+                it(`match #1: should create file with obfuscated code with prefixed identifier`, () => {
+                    assert.match(fileContent1, regExp1);
+                });
 
 
-            after(() => {
-                rimraf.sync(outputFixturesFilePath1);
-                rimraf.sync(outputFixturesFilePath2);
+                it(`match #2: should create file with obfuscated code with prefixed identifier`, () => {
+                    assert.match(fileContent2, regExp2);
+                });
+
+                after(() => {
+                    rimraf.sync(outputFixturesFilePath1);
+                    rimraf.sync(outputFixturesFilePath2);
+                });
             });
             });
-        });
 
 
-        describe('Variant #4: obfuscation of directory with `output` option', () => {
-            const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
-            const outputDirectoryName: string = 'obfuscated';
-            const outputDirectoryPath: string = `${directoryPath}/${outputDirectoryName}`;
-            const outputFileName1: string = 'foo.js';
-            const outputFileName2: string = 'bar.js';
-            const outputFileName3: string = 'baz.js';
-
-            let outputFixturesFilePath1: string,
-                outputFixturesFilePath2: string,
-                outputFixturesFilePath3: string,
-                isFileExist1: boolean,
-                isFileExist2: boolean,
-                isFileExist3: boolean;
+            describe('Variant #3: obfuscation of directory with `output` option', () => {
+                const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
+                const outputDirectoryName: string = 'obfuscated';
+                const outputDirectoryPath: string = `${directoryPath}/${outputDirectoryName}`;
+                const outputFileName1: string = 'foo.js';
+                const outputFileName2: string = 'bar.js';
+                const outputFileName3: string = 'baz.js';
 
 
-            before(() => {
-                outputFixturesFilePath1 = `${outputDirectoryPath}/${directoryPath}/${outputFileName1}`;
-                outputFixturesFilePath2 = `${outputDirectoryPath}/${directoryPath}/${outputFileName2}`;
-                outputFixturesFilePath3 = `${outputDirectoryPath}/${directoryPath}/${outputFileName3}`;
+                let outputFixturesFilePath1: string,
+                    outputFixturesFilePath2: string,
+                    outputFixturesFilePath3: string,
+                    isFileExist1: boolean,
+                    isFileExist2: boolean,
+                    isFileExist3: boolean;
 
 
-                JavaScriptObfuscator.runCLI([
-                    'node',
-                    'javascript-obfuscator',
-                    directoryPath,
-                    '--output',
-                    outputDirectoryPath
-                ]);
+                before(() => {
+                    outputFixturesFilePath1 = `${outputDirectoryPath}/${directoryPath}/${outputFileName1}`;
+                    outputFixturesFilePath2 = `${outputDirectoryPath}/${directoryPath}/${outputFileName2}`;
+                    outputFixturesFilePath3 = `${outputDirectoryPath}/${directoryPath}/${outputFileName3}`;
+
+                    JavaScriptObfuscator.runCLI([
+                        'node',
+                        'javascript-obfuscator',
+                        directoryPath,
+                        '--output',
+                        outputDirectoryPath
+                    ]);
+
+                    isFileExist1 = fs.existsSync(outputFixturesFilePath1);
+                    isFileExist2 = fs.existsSync(outputFixturesFilePath2);
+                    isFileExist3 = fs.existsSync(outputFixturesFilePath3);
+                });
 
 
-                isFileExist1 = fs.existsSync(outputFixturesFilePath1);
-                isFileExist2 = fs.existsSync(outputFixturesFilePath2);
-                isFileExist3 = fs.existsSync(outputFixturesFilePath3);
+                it(
+                    `should create file \`${outputFileName1}\` with obfuscated code in ` +
+                    `\`${fixturesDirName}/${outputDirectoryName}\` directory`,
+                    () => {
+                        assert.equal(isFileExist1, true);
+                    }
+                );
+
+                it(
+                    `should create file \`${outputFileName2}\` with obfuscated code in ` +
+                    `\`${fixturesDirName}/${outputDirectoryName}\` directory`,
+                    () => {
+                        assert.equal(isFileExist2, true);
+                    }
+                );
+
+                it(
+                    `shouldn't create file \`${outputFileName3}\` in ` +
+                    `\`${fixturesDirName}/${outputDirectoryName}\` directory`,
+                    () => {
+                        assert.equal(isFileExist3, false);
+                    }
+                );
+
+                after(() => {
+                    rimraf.sync(outputDirectoryPath);
+                });
             });
             });
 
 
-            it(
-                `should create file \`${outputFileName1}\` with obfuscated code in ` +
-                `\`${fixturesDirName}/${outputDirectoryName}\` directory`,
-                () => {
-                    assert.equal(isFileExist1, true);
-                }
-            );
+            describe('Variant #4: --exclude option', () => {
+                describe('Variant #1: --exclude option is pointed on different file', () => {
+                    const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
+                    const outputFileName1: string = 'foo-obfuscated.js';
+                    const outputFileName2: string = 'bar-obfuscated.js';
+                    const outputFileName3: string = 'baz-obfuscated.js';
+                    const readFileEncoding: string = 'utf8';
+                    const regExp1: RegExp = /^var *a1_0x(\w){4,6} *= *0x1;$/;
+                    const regExp2: RegExp = /^var *a0_0x(\w){4,6} *= *0x2;$/;
+
+                    let outputFixturesFilePath1: string,
+                        outputFixturesFilePath2: string,
+                        outputFixturesFilePath3: string,
+                        isFileExist1: boolean,
+                        isFileExist2: boolean,
+                        isFileExist3: boolean,
+                        fileContent1: string,
+                        fileContent2: string;
 
 
-            it(
-                `should create file \`${outputFileName2}\` with obfuscated code in ` +
-                `\`${fixturesDirName}/${outputDirectoryName}\` directory`,
-                () => {
-                    assert.equal(isFileExist2, true);
-                }
-            );
+                    before(() => {
+                        outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
+                        outputFixturesFilePath2 = `${directoryPath}/${outputFileName2}`;
+                        outputFixturesFilePath3 = `${directoryPath}/${outputFileName3}`;
 
 
-            it(
-                `shouldn't create file \`${outputFileName3}\` in ` +
-                `\`${fixturesDirName}/${outputDirectoryName}\` directory`,
-                () => {
-                    assert.equal(isFileExist3, false);
-                }
-            );
+                        JavaScriptObfuscator.runCLI([
+                            'node',
+                            'javascript-obfuscator',
+                            directoryPath,
+                            '--exclude',
+                            '**/bark.js',
+                            '--rename-globals',
+                            'true'
+                        ]);
 
 
-            after(() => {
-                rimraf.sync(outputDirectoryPath);
+                        isFileExist1 = fs.existsSync(outputFixturesFilePath1);
+                        isFileExist2 = fs.existsSync(outputFixturesFilePath2);
+                        isFileExist3 = fs.existsSync(outputFixturesFilePath3);
+
+                        fileContent1 = fs.readFileSync(outputFixturesFilePath1, readFileEncoding);
+                        fileContent2 = fs.readFileSync(outputFixturesFilePath2, readFileEncoding);
+                    });
+
+                    it(`should create file \`${outputFileName1}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
+                        assert.equal(isFileExist1, true);
+                    });
+
+                    it(`should create file \`${outputFileName2}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
+                        assert.equal(isFileExist2, true);
+                    });
+
+                    it(`shouldn't create file \`${outputFileName3}\` in \`${fixturesDirName}\` directory`, () => {
+                        assert.equal(isFileExist3, false);
+                    });
+
+                    it(`match #1: should create file with obfuscated code with prefixed identifier`, () => {
+                        assert.match(fileContent1, regExp1);
+                    });
+
+                    it(`match #2: should create file with obfuscated code with prefixed identifier`, () => {
+                        assert.match(fileContent2, regExp2);
+                    });
+
+                    after(() => {
+                        rimraf.sync(outputFixturesFilePath1);
+                        rimraf.sync(outputFixturesFilePath2);
+                    });
+                });
+
+                describe('Variant #2: --exclude option is pointed on file under obfuscating directory', () => {
+                    const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
+                    const outputFileName1: string = 'foo-obfuscated.js';
+                    const outputFileName2: string = 'bar-obfuscated.js';
+                    const outputFileName3: string = 'baz-obfuscated.js';
+                    const readFileEncoding: string = 'utf8';
+                    const regExp1: RegExp = /^var *a0_0x(\w){4,6} *= *0x2;$/;
+
+                    let outputFixturesFilePath1: string,
+                        outputFixturesFilePath2: string,
+                        outputFixturesFilePath3: string,
+                        isFileExist1: boolean,
+                        isFileExist2: boolean,
+                        isFileExist3: boolean,
+                        fileContent1: string;
+
+                    before(() => {
+                        outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
+                        outputFixturesFilePath2 = `${directoryPath}/${outputFileName2}`;
+                        outputFixturesFilePath3 = `${directoryPath}/${outputFileName3}`;
+
+                        JavaScriptObfuscator.runCLI([
+                            'node',
+                            'javascript-obfuscator',
+                            directoryPath,
+                            '--exclude',
+                            '**/foo.js',
+                            '--rename-globals',
+                            'true'
+                        ]);
+
+                        isFileExist1 = fs.existsSync(outputFixturesFilePath1);
+                        isFileExist2 = fs.existsSync(outputFixturesFilePath2);
+                        isFileExist3 = fs.existsSync(outputFixturesFilePath3);
+
+                        fileContent1 = fs.readFileSync(outputFixturesFilePath2, readFileEncoding);
+                    });
+
+                    it(`shouldn't create file \`${outputFileName1}\` in \`${fixturesDirName}\` directory`, () => {
+                        assert.equal(isFileExist1, false);
+                    });
+
+                    it(`should create file \`${outputFileName2}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
+                        assert.equal(isFileExist2, true);
+                    });
+
+                    it(`shouldn't create file \`${outputFileName3}\` in \`${fixturesDirName}\` directory`, () => {
+                        assert.equal(isFileExist3, false);
+                    });
+
+                    it(`match #1: should create file with obfuscated code with prefixed identifier`, () => {
+                        assert.match(fileContent1, regExp1);
+                    });
+
+                    after(() => {
+                        rimraf.sync(outputFixturesFilePath1);
+                        rimraf.sync(outputFixturesFilePath2);
+                    });
+                });
             });
             });
         });
         });
 
 
         describe('`--sourceMap` option is set', () => {
         describe('`--sourceMap` option is set', () => {
             const outputSourceMapPath: string = `${outputFilePath}.map`;
             const outputSourceMapPath: string = `${outputFilePath}.map`;
 
 
-            describe('variant #1: `--sourceMapMode` option value is `separate`', () => {
-                describe('variant #1: default behaviour', () => {
+            describe('Variant #1: `--sourceMapMode` option value is `separate`', () => {
+                describe('Variant #1: default behaviour', () => {
                     let isFileExist: boolean,
                     let isFileExist: boolean,
                         sourceMapObject: any;
                         sourceMapObject: any;
 
 
@@ -370,7 +549,7 @@ describe('JavaScriptObfuscatorCLI', function (): void {
                     });
                     });
                 });
                 });
 
 
-                describe('variant #2: `sourceMapBaseUrl` option is set', () => {
+                describe('Variant #2: `sourceMapBaseUrl` option is set', () => {
                     let isFileExist: boolean,
                     let isFileExist: boolean,
                         sourceMapObject: any;
                         sourceMapObject: any;
 
 
@@ -423,7 +602,7 @@ describe('JavaScriptObfuscatorCLI', function (): void {
                     });
                     });
                 });
                 });
 
 
-                describe('variant #3: `--sourceMapFileName` option is set', () => {
+                describe('Variant #3: `--sourceMapFileName` option is set', () => {
                     const sourceMapFileName: string = 'test';
                     const sourceMapFileName: string = 'test';
                     const sourceMapFilePath: string = `${sourceMapFileName}.js.map`;
                     const sourceMapFilePath: string = `${sourceMapFileName}.js.map`;
                     const outputSourceMapFilePath: string = `${outputDirName}/${sourceMapFilePath}`;
                     const outputSourceMapFilePath: string = `${outputDirName}/${sourceMapFilePath}`;
@@ -481,7 +660,7 @@ describe('JavaScriptObfuscatorCLI', function (): void {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: `--sourceMapMode` option is `inline`', () => {
+            describe('Variant #2: `--sourceMapMode` option is `inline`', () => {
                 let isFileExist: boolean;
                 let isFileExist: boolean;
 
 
                 before(() => {
                 before(() => {

+ 8 - 8
test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts

@@ -186,7 +186,7 @@ describe('JavaScriptObfuscator', () => {
         });
         });
 
 
         describe('variable inside global scope', () => {
         describe('variable inside global scope', () => {
-            describe('variant #1: without `renameGlobals` option', () => {
+            describe('Variant #1: without `renameGlobals` option', () => {
                 const regExp: RegExp = /^var *test *= *0x\d+;$/;
                 const regExp: RegExp = /^var *test *= *0x\d+;$/;
 
 
                 let obfuscatedCode: string;
                 let obfuscatedCode: string;
@@ -208,7 +208,7 @@ describe('JavaScriptObfuscator', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: with `renameGlobals` option', () => {
+            describe('Variant #2: with `renameGlobals` option', () => {
                 const regExp: RegExp = /^var *_0x(\w){4,6} *= *0x\d+;$/;
                 const regExp: RegExp = /^var *_0x(\w){4,6} *= *0x\d+;$/;
 
 
                 let obfuscatedCode: string;
                 let obfuscatedCode: string;
@@ -231,7 +231,7 @@ describe('JavaScriptObfuscator', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #3: with `renameGlobals` and `identifiersPrefix` options', () => {
+            describe('Variant #3: with `renameGlobals` and `identifiersPrefix` options', () => {
                 const regExp: RegExp = /^var *foo_0x(\w){4,6} *= *0x\d+;$/;
                 const regExp: RegExp = /^var *foo_0x(\w){4,6} *= *0x\d+;$/;
 
 
                 let obfuscatedCode: string;
                 let obfuscatedCode: string;
@@ -255,7 +255,7 @@ describe('JavaScriptObfuscator', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #4: with `stringArray`, `renameGlobals` and `identifiersPrefix` options', () => {
+            describe('Variant #4: with `stringArray`, `renameGlobals` and `identifiersPrefix` options', () => {
                 const stringArrayRegExp: RegExp = /^var foo_0x(\w){4} *= *\['abc'\];/;
                 const stringArrayRegExp: RegExp = /^var foo_0x(\w){4} *= *\['abc'\];/;
                 const stringArrayCallRegExp: RegExp = /var *foo_0x(\w){4,6} *= *foo_0x(\w){4}\('0x0'\);$/;
                 const stringArrayCallRegExp: RegExp = /var *foo_0x(\w){4,6} *= *foo_0x(\w){4}\('0x0'\);$/;
 
 
@@ -310,7 +310,7 @@ describe('JavaScriptObfuscator', () => {
         });
         });
 
 
         describe('variables inside global and block scopes', () => {
         describe('variables inside global and block scopes', () => {
-            describe('variant #1: with `renameGlobals` and `identifiersPrefix` options', () => {
+            describe('Variant #1: with `renameGlobals` and `identifiersPrefix` options', () => {
                 const variableDeclaration1: RegExp = /var foo_0x(\w){4,6} *= *0x1;/;
                 const variableDeclaration1: RegExp = /var foo_0x(\w){4,6} *= *0x1;/;
                 const variableDeclaration2: RegExp = /var foo_0x(\w){4,6} *= *0x2;/;
                 const variableDeclaration2: RegExp = /var foo_0x(\w){4,6} *= *0x2;/;
                 const variableDeclaration3: RegExp = /var _0x(\w){4,6} *= *foo_0x(\w){4,6} *\+ *foo_0x(\w){4,6}/;
                 const variableDeclaration3: RegExp = /var _0x(\w){4,6} *= *foo_0x(\w){4,6} *\+ *foo_0x(\w){4,6}/;
@@ -453,7 +453,7 @@ describe('JavaScriptObfuscator', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #1: different seed on each run', () => {
+            describe('Variant #1: different seed on each run', () => {
                 const code: string = readFileAsString('./test/fixtures/sample.js');
                 const code: string = readFileAsString('./test/fixtures/sample.js');
 
 
                 let obfuscatedCode1: string,
                 let obfuscatedCode1: string,
@@ -482,7 +482,7 @@ describe('JavaScriptObfuscator', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: different seed on each run', () => {
+            describe('Variant #2: different seed on each run', () => {
                 const code: string = readFileAsString('./test/fixtures/sample.js');
                 const code: string = readFileAsString('./test/fixtures/sample.js');
 
 
                 let obfuscatedCode1: string,
                 let obfuscatedCode1: string,
@@ -511,7 +511,7 @@ describe('JavaScriptObfuscator', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #3: same seed for different source code', () => {
+            describe('Variant #3: same seed for different source code', () => {
                 const code1: string = readFileAsString(__dirname + '/fixtures/simple-input-cyrillic.js');
                 const code1: string = readFileAsString(__dirname + '/fixtures/simple-input-cyrillic.js');
                 const code2: string = readFileAsString(__dirname + '/fixtures/simple-input-2.js');
                 const code2: string = readFileAsString(__dirname + '/fixtures/simple-input-2.js');
 
 

+ 15 - 15
test/functional-tests/node-transformers/control-flow-transformers/block-statement-control-flow-transformer/BlockStatementControlFlowTransformer.spec.ts

@@ -21,7 +21,7 @@ describe('BlockStatementControlFlowTransformer', function () {
     this.timeout(100000);
     this.timeout(100000);
 
 
     describe('transformNode (blockStatementNode: ESTree.BlockStatement): ESTree.Node', () => {
     describe('transformNode (blockStatementNode: ESTree.BlockStatement): ESTree.Node', () => {
-        describe('variant #1: 5 simple statements', () => {
+        describe('Variant #1: 5 simple statements', () => {
             let obfuscatedCode: string;
             let obfuscatedCode: string;
 
 
             before(() => {
             before(() => {
@@ -109,7 +109,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #2: 5 simple statements inside while loop without break or continue statement', () => {
+        describe('Variant #2: 5 simple statements inside while loop without break or continue statement', () => {
             let obfuscatedCode: string;
             let obfuscatedCode: string;
 
 
             before(() => {
             before(() => {
@@ -198,7 +198,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #3: statements length less then 5 statements', () => {
+        describe('Variant #3: statements length less then 5 statements', () => {
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *console\['log'\]\(0x1\); *\} *\( *\) *\);$/;
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *console\['log'\]\(0x1\); *\} *\( *\) *\);$/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -222,7 +222,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #4: block statement contain variable declaration with `const` kind', () => {
+        describe('Variant #4: block statement contain variable declaration with `const` kind', () => {
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *const *_0x([a-f0-9]){4,6} *= *0x1; *console\['log'\]\(0x1\);/;
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *const *_0x([a-f0-9]){4,6} *= *0x1; *console\['log'\]\(0x1\);/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -246,7 +246,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #5: block statement contain variable declaration with `let` kind', () => {
+        describe('Variant #5: block statement contain variable declaration with `let` kind', () => {
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *let *_0x([a-f0-9]){4,6} *= *0x1; *console\['log'\]\(0x1\);/;
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *let *_0x([a-f0-9]){4,6} *= *0x1; *console\['log'\]\(0x1\);/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -270,7 +270,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #6: block statement contain break statement #1', () => {
+        describe('Variant #6: block statement contain break statement #1', () => {
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *break; *console\['log'\]\(0x1\);/;
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *break; *console\['log'\]\(0x1\);/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -294,7 +294,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #7: block statement contain break statement #2', () => {
+        describe('Variant #7: block statement contain break statement #2', () => {
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *if *\(!!\[\]\) *\{ *break; *\} *console\['log'\]\(0x1\);/;
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *if *\(!!\[\]\) *\{ *break; *\} *console\['log'\]\(0x1\);/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -318,7 +318,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #8: block statement contain while statement with break statement', () => {
+        describe('Variant #8: block statement contain while statement with break statement', () => {
             const switchCaseRegExp: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/;
             const switchCaseRegExp: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/;
             const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
             const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
             const expectedSwitchCaseLength: number = 5;
             const expectedSwitchCaseLength: number = 5;
@@ -350,7 +350,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #9: block statement contain continue statement #1', () => {
+        describe('Variant #9: block statement contain continue statement #1', () => {
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *continue; *console\['log'\]\(0x1\);/;
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *continue; *console\['log'\]\(0x1\);/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -374,7 +374,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #10: block statement contain continue statement #2', () => {
+        describe('Variant #10: block statement contain continue statement #2', () => {
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *if *\(!!\[\]\) *\{ *continue; *\} *console\['log'\]\(0x1\);/;
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *while *\(!!\[\]\) *\{ *if *\(!!\[\]\) *\{ *continue; *\} *console\['log'\]\(0x1\);/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -398,7 +398,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #11: block statement contain while statement with continue statement', () => {
+        describe('Variant #11: block statement contain while statement with continue statement', () => {
             const switchCaseRegExp: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/;
             const switchCaseRegExp: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/;
             const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
             const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
             const expectedSwitchCaseLength: number = 5;
             const expectedSwitchCaseLength: number = 5;
@@ -430,7 +430,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #12: block statement contain function declaration', () => {
+        describe('Variant #12: block statement contain function declaration', () => {
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *function *_0x([a-f0-9]){4,6} *\( *\) *\{ *\} *console\['log'\]\(0x1\);/
             const statementRegExp: RegExp = /^\(function *\( *\) *\{ *function *_0x([a-f0-9]){4,6} *\( *\) *\{ *\} *console\['log'\]\(0x1\);/
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -454,7 +454,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #13: block statement contain class declaration', () => {
+        describe('Variant #13: block statement contain class declaration', () => {
             const statementRegExp: RegExp = /^\(function *\( *\) *{ * *class *_0x([a-f0-9]){4,6} *{.*?} *}.*class *_0x([a-f0-9]){4,6} *{.*?} *}.*class *_0x([a-f0-9]){4,6} *{.*?} *}/;
             const statementRegExp: RegExp = /^\(function *\( *\) *{ * *class *_0x([a-f0-9]){4,6} *{.*?} *}.*class *_0x([a-f0-9]){4,6} *{.*?} *}.*class *_0x([a-f0-9]){4,6} *{.*?} *}/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -478,7 +478,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #14: `controlFlowFlatteningThreshold` chance', () => {
+        describe('Variant #14: `controlFlowFlatteningThreshold` chance', () => {
             const samples: number = 1000;
             const samples: number = 1000;
             const delta: number = 0.1;
             const delta: number = 0.1;
 
 
@@ -523,7 +523,7 @@ describe('BlockStatementControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #15: No `unreachable code after return statement` warning', () => {
+        describe('Variant #15: No `unreachable code after return statement` warning', () => {
             const switchCaseRegExp: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/;
             const switchCaseRegExp: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/;
             const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
             const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
             const returnStatementRegExp: RegExp = /case *'[0-5]': *return; *(case|})/;
             const returnStatementRegExp: RegExp = /case *'[0-5]': *return; *(case|})/;

+ 2 - 2
test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer/BinaryExpressionControlFlowReplacer.spec.ts

@@ -12,7 +12,7 @@ describe('BinaryExpressionControlFlowReplacer', function () {
     this.timeout(100000);
     this.timeout(100000);
 
 
     describe('replace (binaryExpressionNode: ESTree.BinaryExpression,parentNode: ESTree.Node,controlFlowStorage: IStorage <ICustomNode>)', () => {
     describe('replace (binaryExpressionNode: ESTree.BinaryExpression,parentNode: ESTree.Node,controlFlowStorage: IStorage <ICustomNode>)', () => {
-        describe('variant #1 - single binary expression', () => {
+        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\);/;
             const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\w{5}'\]\(0x1, *0x2\);/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -36,7 +36,7 @@ describe('BinaryExpressionControlFlowReplacer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #2 - multiple binary expressions with threshold = 1', () => {
+        describe('Variant #2 - multiple binary expressions with threshold = 1', () => {
             const expectedMatchErrorsCount: number = 0;
             const expectedMatchErrorsCount: number = 0;
             const expectedChance: number = 0.5;
             const expectedChance: number = 0.5;
 
 

+ 3 - 3
test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/call-expression-control-flow-replacer/CallExpressionControlFlowReplacer.spec.ts

@@ -12,7 +12,7 @@ describe('CallExpressionControlFlowReplacer', function () {
     this.timeout(100000);
     this.timeout(100000);
 
 
     describe('replace (callExpressionNode: ESTree.CallExpression,parentNode: ESTree.Node,controlFlowStorage: IStorage <ICustomNode>)', () => {
     describe('replace (callExpressionNode: ESTree.CallExpression,parentNode: ESTree.Node,controlFlowStorage: IStorage <ICustomNode>)', () => {
-        describe('variant #1 - single call expression', () => {
+        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\);/;
             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\);/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -36,7 +36,7 @@ describe('CallExpressionControlFlowReplacer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #2 - multiple call expressions with threshold = 1', () => {
+        describe('Variant #2 - multiple call expressions with threshold = 1', () => {
             const expectedMatchErrorsCount: number = 0;
             const expectedMatchErrorsCount: number = 0;
             const expectedChance: number = 0.5;
             const expectedChance: number = 0.5;
 
 
@@ -101,7 +101,7 @@ describe('CallExpressionControlFlowReplacer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #3 - call expression callee is member expression node', () => {
+        describe('Variant #3 - call expression callee is member expression node', () => {
             const regExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['sum'\]\(0x1, *0x2\);/;
             const regExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['sum'\]\(0x1, *0x2\);/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;

+ 4 - 4
test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/logical-expression-control-flow-replacer/LogicalExpressionControlFlowReplacer.spec.ts

@@ -12,7 +12,7 @@ describe('LogicalExpressionControlFlowReplacer', function () {
     this.timeout(100000);
     this.timeout(100000);
 
 
     describe('replace (logicalExpressionNode: ESTree.LogicalExpression,parentNode: ESTree.Node,controlFlowStorage: IStorage <ICustomNode>)', () => {
     describe('replace (logicalExpressionNode: ESTree.LogicalExpression,parentNode: ESTree.Node,controlFlowStorage: IStorage <ICustomNode>)', () => {
-        describe('variant #1 - single logical expression', () => {
+        describe('Variant #1 - single logical expression', () => {
             const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\w{5}'\]\(!!\[\], *!\[\]\);/;
             const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\w{5}'\]\(!!\[\], *!\[\]\);/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -36,7 +36,7 @@ describe('LogicalExpressionControlFlowReplacer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #2 - multiple logical expressions with threshold = 1', () => {
+        describe('Variant #2 - multiple logical expressions with threshold = 1', () => {
             const expectedMatchErrorsCount: number = 0;
             const expectedMatchErrorsCount: number = 0;
             const expectedChance: number = 0.5;
             const expectedChance: number = 0.5;
 
 
@@ -101,7 +101,7 @@ describe('LogicalExpressionControlFlowReplacer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #3 - single logical expression with unary expression', () => {
+        describe('Variant #3 - single logical expression with unary 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}, *!_0x([a-f0-9]){4,6}\);/;
             const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\w{5}'\]\(!_0x([a-f0-9]){4,6}, *!_0x([a-f0-9]){4,6}\);/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -125,7 +125,7 @@ describe('LogicalExpressionControlFlowReplacer', function () {
             });
             });
         });
         });
 
 
-        describe('prohibited nodes variant #1', () => {
+        describe('prohibited nodes Variant #1', () => {
             const regExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\] *&& *!\[\];/;
             const regExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\] *&& *!\[\];/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;

+ 8 - 8
test/functional-tests/node-transformers/control-flow-transformers/function-control-flow-transformer/FunctionControlFlowTransformer.spec.ts

@@ -28,7 +28,7 @@ describe('FunctionControlFlowTransformer', function () {
     ``;
     ``;
 
 
     describe('transformNode (functionNode: ESTree.Function): ESTree.Node', () => {
     describe('transformNode (functionNode: ESTree.Function): ESTree.Node', () => {
-        describe('variant #1 - single `control flow storage` node with single item', () => {
+        describe('Variant #1 - single `control flow storage` node with single item', () => {
             const regexp: RegExp = new RegExp(rootControlFlowStorageNodeMatch);
             const regexp: RegExp = new RegExp(rootControlFlowStorageNodeMatch);
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -52,7 +52,7 @@ describe('FunctionControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #2 - two `control flow storage` nodes: root and inner', () => {
+        describe('Variant #2 - two `control flow storage` nodes: root and inner', () => {
             const expectedAppendToScopeThreshold: number = 0.5;
             const expectedAppendToScopeThreshold: number = 0.5;
 
 
             const samplesCount: number = 1000;
             const samplesCount: number = 1000;
@@ -104,7 +104,7 @@ describe('FunctionControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #3 - single `control flow storage` node with multiple items', () => {
+        describe('Variant #3 - single `control flow storage` node with multiple items', () => {
             const regexp: RegExp = new RegExp(
             const regexp: RegExp = new RegExp(
                 `var *${variableMatch} *= *\\{` +
                 `var *${variableMatch} *= *\\{` +
                     `'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
                     `'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
@@ -137,7 +137,7 @@ describe('FunctionControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #4 - transformed node in the root block scope', () => {
+        describe('Variant #4 - transformed node in the root block scope', () => {
             const regExp: RegExp = /^var *test *= *0x1 *\+ *0x2;$/;
             const regExp: RegExp = /^var *test *= *0x1 *\+ *0x2;$/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -161,7 +161,7 @@ describe('FunctionControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #5 - transformed nodes not in the root block scope', () => {
+        describe('Variant #5 - transformed nodes not in the root block scope', () => {
             const expectedValue: number = 0;
             const expectedValue: number = 0;
             const samplesCount: number = 20;
             const samplesCount: number = 20;
 
 
@@ -200,7 +200,7 @@ describe('FunctionControlFlowTransformer', function () {
             });
             });
         });
         });
 
 
-        describe('variant #6 - threshold is `0`', () => {
+        describe('Variant #6 - threshold is `0`', () => {
             const regexp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x1 *\+ *0x2;/;
             const regexp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x1 *\+ *0x2;/;
             const controlFlowStorageRegExp: RegExp = new RegExp(rootControlFlowStorageNodeMatch);
             const controlFlowStorageRegExp: RegExp = new RegExp(rootControlFlowStorageNodeMatch);
 
 
@@ -230,7 +230,7 @@ describe('FunctionControlFlowTransformer', function () {
         });
         });
 
 
         describe('arrow function expression', () => {
         describe('arrow function expression', () => {
-            describe('variant #1 - arrow function expression with body', () => {
+            describe('Variant #1 - arrow function expression with body', () => {
                 const regexp: RegExp = new RegExp(rootControlFlowStorageNodeMatch);
                 const regexp: RegExp = new RegExp(rootControlFlowStorageNodeMatch);
 
 
                 let obfuscatedCode: string;
                 let obfuscatedCode: string;
@@ -254,7 +254,7 @@ describe('FunctionControlFlowTransformer', function () {
                 });
                 });
             });
             });
 
 
-            describe('variant #2 - arrow function expression without body', () => {
+            describe('Variant #2 - arrow function expression without body', () => {
                 const regexp: RegExp = new RegExp(`var *${variableMatch} *= *\\(\\) *=> *0x1 *\\+ *0x2;`);
                 const regexp: RegExp = new RegExp(`var *${variableMatch} *= *\\(\\) *=> *0x1 *\\+ *0x2;`);
 
 
                 let obfuscatedCode: string;
                 let obfuscatedCode: string;

+ 2 - 2
test/functional-tests/node-transformers/converting-transformers/member-expression-transformer/MemberExpressionTransformer.spec.ts

@@ -63,7 +63,7 @@ describe('MemberExpressionTransformer', () => {
     });
     });
 
 
     describe('transformation of member expression node with square brackets', () => {
     describe('transformation of member expression node with square brackets', () => {
-        describe('variant #1: square brackets literal ', () => {
+        describe('Variant #1: square brackets literal ', () => {
             const stringArrayRegExp: RegExp = /var *_0x([a-f0-9]){4} *= *\['log'\];/;
             const stringArrayRegExp: RegExp = /var *_0x([a-f0-9]){4} *= *\['log'\];/;
             const stringArrayCallRegExp: RegExp = /var *test *= *console\[_0x([a-f0-9]){4}\('0x0'\)\];/;
             const stringArrayCallRegExp: RegExp = /var *test *= *console\[_0x([a-f0-9]){4}\('0x0'\)\];/;
 
 
@@ -92,7 +92,7 @@ describe('MemberExpressionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: square brackets identifier', () => {
+        describe('Variant #2: square brackets identifier', () => {
             const regExp: RegExp = /var *test *= *console\[identifier\];/;
             const regExp: RegExp = /var *test *= *console\[identifier\];/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;

+ 3 - 3
test/functional-tests/node-transformers/converting-transformers/method-definition-transformer/MethodDefinitionTransformer.spec.ts

@@ -9,7 +9,7 @@ import { readFileAsString } from '../../../../helpers/readFileAsString';
 import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 
 describe('MethodDefinitionTransformer', () => {
 describe('MethodDefinitionTransformer', () => {
-    describe('variant #1: default behaviour', () => {
+    describe('Variant #1: default behaviour', () => {
         const regExp: RegExp = /\['bar'\]\(\)\{\}/;
         const regExp: RegExp = /\['bar'\]\(\)\{\}/;
 
 
         let obfuscatedCode: string;
         let obfuscatedCode: string;
@@ -31,7 +31,7 @@ describe('MethodDefinitionTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #2: `stringArray` option is enabled', () => {
+    describe('Variant #2: `stringArray` option is enabled', () => {
         const stringArrayRegExp: RegExp = /var *_0x([a-f0-9]){4} *= *\['bar'\];/;
         const stringArrayRegExp: RegExp = /var *_0x([a-f0-9]){4} *= *\['bar'\];/;
         const stringArrayCallRegExp: RegExp = /\[_0x([a-f0-9]){4}\('0x0'\)\]\(\)\{\}/;
         const stringArrayCallRegExp: RegExp = /\[_0x([a-f0-9]){4}\('0x0'\)\]\(\)\{\}/;
 
 
@@ -60,7 +60,7 @@ describe('MethodDefinitionTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #3: `constructor` key', () => {
+    describe('Variant #3: `constructor` key', () => {
         const regExp: RegExp = /constructor\(\)\{\}/;
         const regExp: RegExp = /constructor\(\)\{\}/;
 
 
         let obfuscatedCode: string;
         let obfuscatedCode: string;

+ 10 - 10
test/functional-tests/node-transformers/converting-transformers/object-expression-keys-transformer/ObjectExpressionKeysTransformer.spec.ts

@@ -12,7 +12,7 @@ describe('ObjectExpressionKeysTransformer', () => {
     const variableMatch: string = '_0x([a-f0-9]){4,6}';
     const variableMatch: string = '_0x([a-f0-9]){4,6}';
 
 
     describe('transformation of object keys', () => {
     describe('transformation of object keys', () => {
-        describe('variant #1: simple', () => {
+        describe('Variant #1: simple', () => {
             const match: string = `` +
             const match: string = `` +
                 `var *${variableMatch} *= *{};` +
                 `var *${variableMatch} *= *{};` +
                 `${variableMatch}\\['foo'] *= *'bar';` +
                 `${variableMatch}\\['foo'] *= *'bar';` +
@@ -40,7 +40,7 @@ describe('ObjectExpressionKeysTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: nested objects #1', () => {
+        describe('Variant #2: nested objects #1', () => {
             const match: string = `` +
             const match: string = `` +
                 `var *${variableMatch} *= *{};` +
                 `var *${variableMatch} *= *{};` +
                 `${variableMatch}\\['foo'] *= *'bar';` +
                 `${variableMatch}\\['foo'] *= *'bar';` +
@@ -70,7 +70,7 @@ describe('ObjectExpressionKeysTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: nested objects #2', () => {
+        describe('Variant #3: nested objects #2', () => {
             const match: string = `` +
             const match: string = `` +
                 `var *${variableMatch} *= *{};` +
                 `var *${variableMatch} *= *{};` +
                 `${variableMatch}\\['foo'] *= *'bar';` +
                 `${variableMatch}\\['foo'] *= *'bar';` +
@@ -103,7 +103,7 @@ describe('ObjectExpressionKeysTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4: correct integration with control flow flattening object', () => {
+        describe('Variant #4: correct integration with control flow flattening object', () => {
             const match: string = `` +
             const match: string = `` +
                 `var *${variableMatch} *= *{};` +
                 `var *${variableMatch} *= *{};` +
                 `${variableMatch}\\['\\w{5}'] *= *function *\\(${variableMatch}, *${variableMatch}\\) *{` +
                 `${variableMatch}\\['\\w{5}'] *= *function *\\(${variableMatch}, *${variableMatch}\\) *{` +
@@ -137,7 +137,7 @@ describe('ObjectExpressionKeysTransformer', () => {
     });
     });
 
 
     describe('correct placement of expression statements', () => {
     describe('correct placement of expression statements', () => {
-        describe('variant #1: if statement', () => {
+        describe('Variant #1: if statement', () => {
             const match: string = `` +
             const match: string = `` +
                 `if *\\(!!\\[]\\) *{` +
                 `if *\\(!!\\[]\\) *{` +
                     `var *${variableMatch} *= *{};` +
                     `var *${variableMatch} *= *{};` +
@@ -166,7 +166,7 @@ describe('ObjectExpressionKeysTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: try statement', () => {
+        describe('Variant #2: try statement', () => {
             const match: string = `` +
             const match: string = `` +
                 `try *{` +
                 `try *{` +
                     `var *${variableMatch} *= *{};` +
                     `var *${variableMatch} *= *{};` +
@@ -196,7 +196,7 @@ describe('ObjectExpressionKeysTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: catch clause statement', () => {
+        describe('Variant #3: catch clause statement', () => {
             const match: string = `` +
             const match: string = `` +
                 `try *{` +
                 `try *{` +
                 `} *catch *\\(${variableMatch}\\) *{` +
                 `} *catch *\\(${variableMatch}\\) *{` +
@@ -226,7 +226,7 @@ describe('ObjectExpressionKeysTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4: switch catch statement', () => {
+        describe('Variant #4: switch catch statement', () => {
             const match: string = `` +
             const match: string = `` +
                 `switch *\\(!!\\[]\\) *{` +
                 `switch *\\(!!\\[]\\) *{` +
                     `case *!!\\[]:` +
                     `case *!!\\[]:` +
@@ -258,7 +258,7 @@ describe('ObjectExpressionKeysTransformer', () => {
     });
     });
 
 
     describe('Ignore transformation', () => {
     describe('Ignore transformation', () => {
-        describe('variant #1: disabled option', () => {
+        describe('Variant #1: disabled option', () => {
             const match: string = `` +
             const match: string = `` +
                 `var *${variableMatch} *= *{` +
                 `var *${variableMatch} *= *{` +
                     `'foo': *'bar',` +
                     `'foo': *'bar',` +
@@ -286,7 +286,7 @@ describe('ObjectExpressionKeysTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: variable declaration without initialization', () => {
+        describe('Variant #2: variable declaration without initialization', () => {
             const match: string = `` +
             const match: string = `` +
                 `var *${variableMatch};` +
                 `var *${variableMatch};` +
                 `${variableMatch} *= *{` +
                 `${variableMatch} *= *{` +

+ 10 - 10
test/functional-tests/node-transformers/converting-transformers/template-literal-transformer/TemplateLiteralTransformer.spec.ts

@@ -9,7 +9,7 @@ import { readFileAsString } from '../../../../helpers/readFileAsString';
 import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 
 describe('TemplateLiteralTransformer', () => {
 describe('TemplateLiteralTransformer', () => {
-    describe('variant #1: simple template literal', () => {
+    describe('Variant #1: simple template literal', () => {
         it('should transform es6 template literal to es5', () => {
         it('should transform es6 template literal to es5', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
             const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
@@ -24,8 +24,8 @@ describe('TemplateLiteralTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #2: multiline template literals', () => {
-        it('variant #1: should transform es6 multiline template literal to es5', () => {
+    describe('Variant #2: multiline template literals', () => {
+        it('Variant #1: should transform es6 multiline template literal to es5', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/multiline-template-literal.js');
             const code: string = readFileAsString(__dirname + '/fixtures/multiline-template-literal.js');
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 code,
                 code,
@@ -38,7 +38,7 @@ describe('TemplateLiteralTransformer', () => {
             assert.match(obfuscationResult.getObfuscatedCode(),  /^var *test *= *'foo\\x0abar';$/);
             assert.match(obfuscationResult.getObfuscatedCode(),  /^var *test *= *'foo\\x0abar';$/);
         });
         });
 
 
-        it('variant #2: should transform es6 multiline template literal inside return statement', () => {
+        it('Variant #2: should transform es6 multiline template literal inside return statement', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/multiline-template-literal-return-statement-1.js');
             const code: string = readFileAsString(__dirname + '/fixtures/multiline-template-literal-return-statement-1.js');
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 code,
                 code,
@@ -51,7 +51,7 @@ describe('TemplateLiteralTransformer', () => {
             assert.match(obfuscationResult.getObfuscatedCode(),  /{ *return *'foo\\x0abar'; *}$/);
             assert.match(obfuscationResult.getObfuscatedCode(),  /{ *return *'foo\\x0abar'; *}$/);
         });
         });
 
 
-        it('variant #3: should transform es6 multiline template literal inside return statement', () => {
+        it('Variant #3: should transform es6 multiline template literal inside return statement', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/multiline-template-literal-return-statement-2.js');
             const code: string = readFileAsString(__dirname + '/fixtures/multiline-template-literal-return-statement-2.js');
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 code,
                 code,
@@ -64,7 +64,7 @@ describe('TemplateLiteralTransformer', () => {
             assert.match(obfuscationResult.getObfuscatedCode(),  /case *!!\[] *: *return *'foo\\x0abar'; *} *}$/);
             assert.match(obfuscationResult.getObfuscatedCode(),  /case *!!\[] *: *return *'foo\\x0abar'; *} *}$/);
         });
         });
 
 
-        it('variant #4: should transform es6 multiline template literal inside binary expression inside return statement', () => {
+        it('Variant #4: should transform es6 multiline template literal inside binary expression inside return statement', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/multiline-template-literal-binary-expression-return-statement-1.js');
             const code: string = readFileAsString(__dirname + '/fixtures/multiline-template-literal-binary-expression-return-statement-1.js');
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 code,
                 code,
@@ -77,7 +77,7 @@ describe('TemplateLiteralTransformer', () => {
             assert.match(obfuscationResult.getObfuscatedCode(),  /{ *return *'foo\\x0abar' *\+ *0x1; *}$/);
             assert.match(obfuscationResult.getObfuscatedCode(),  /{ *return *'foo\\x0abar' *\+ *0x1; *}$/);
         });
         });
 
 
-        it('variant #5: should transform es6 multiline template literal inside binary expression inside return statement', () => {
+        it('Variant #5: should transform es6 multiline template literal inside binary expression inside return statement', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/multiline-template-literal-binary-expression-return-statement-2.js');
             const code: string = readFileAsString(__dirname + '/fixtures/multiline-template-literal-binary-expression-return-statement-2.js');
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 code,
                 code,
@@ -91,7 +91,7 @@ describe('TemplateLiteralTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #3: simple template literal with expression only', () => {
+    describe('Variant #3: simple template literal with expression only', () => {
         it('should transform es6 template literal to es5 and add empty literal node before expression node', () => {
         it('should transform es6 template literal to es5 and add empty literal node before expression node', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/expression-only.js');
             const code: string = readFileAsString(__dirname + '/fixtures/expression-only.js');
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
@@ -106,7 +106,7 @@ describe('TemplateLiteralTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #4: literal node inside expression', () => {
+    describe('Variant #4: literal node inside expression', () => {
         it('should transform es6 template literal to es5', () => {
         it('should transform es6 template literal to es5', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/literal-inside-expression.js');
             const code: string = readFileAsString(__dirname + '/fixtures/literal-inside-expression.js');
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
@@ -121,7 +121,7 @@ describe('TemplateLiteralTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #5: multiple expressions', () => {
+    describe('Variant #5: multiple expressions', () => {
         it('should transform es6 template literal to es5', () => {
         it('should transform es6 template literal to es5', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/multiple-expressions.js');
             const code: string = readFileAsString(__dirname + '/fixtures/multiple-expressions.js');
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
             const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(

+ 18 - 18
test/functional-tests/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.spec.ts

@@ -18,7 +18,7 @@ describe('DeadCodeInjectionTransformer', () => {
     describe('transformNode (programNode: ESTree.Program, parentNode: ESTree.Node): ESTree.Node', function () {
     describe('transformNode (programNode: ESTree.Program, parentNode: ESTree.Node): ESTree.Node', function () {
         this.timeout(100000);
         this.timeout(100000);
 
 
-        describe('variant #1 - 5 simple block statements', () => {
+        describe('Variant #1 - 5 simple block statements', () => {
             const regExp: RegExp = new RegExp(
             const regExp: RegExp = new RegExp(
                 `if *\\(${variableMatch}\\('${hexMatch}'\\) *[=|!]== *${variableMatch}\\('${hexMatch}'\\)\\) *\\{`+
                 `if *\\(${variableMatch}\\('${hexMatch}'\\) *[=|!]== *${variableMatch}\\('${hexMatch}'\\)\\) *\\{`+
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
@@ -56,7 +56,7 @@ describe('DeadCodeInjectionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2 - block statements count is less than `5`', () => {
+        describe('Variant #2 - block statements count is less than `5`', () => {
             const regexp: RegExp = new RegExp(
             const regexp: RegExp = new RegExp(
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
@@ -92,7 +92,7 @@ describe('DeadCodeInjectionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3 - deadCodeInjectionThreshold: 0', () => {
+        describe('Variant #3 - deadCodeInjectionThreshold: 0', () => {
             const regexp: RegExp = new RegExp(
             const regexp: RegExp = new RegExp(
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
@@ -128,7 +128,7 @@ describe('DeadCodeInjectionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4 - break or continue statement in block statement', () => {
+        describe('Variant #4 - break or continue statement in block statement', () => {
             const functionRegExp: RegExp = new RegExp(
             const functionRegExp: RegExp = new RegExp(
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
@@ -181,7 +181,7 @@ describe('DeadCodeInjectionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #5 - await expression in block statement', () => {
+        describe('Variant #5 - await expression in block statement', () => {
             const functionRegExp: RegExp = new RegExp(
             const functionRegExp: RegExp = new RegExp(
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
@@ -232,7 +232,7 @@ describe('DeadCodeInjectionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #6 - super expression in block statement', () => {
+        describe('Variant #6 - super expression in block statement', () => {
             const functionRegExp: RegExp = new RegExp(
             const functionRegExp: RegExp = new RegExp(
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
@@ -283,7 +283,7 @@ describe('DeadCodeInjectionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #7 - chance of `IfStatement` variant', () => {
+        describe('Variant #7 - chance of `IfStatement` variant', () => {
             const samplesCount: number = 1000;
             const samplesCount: number = 1000;
             const delta: number = 0.1;
             const delta: number = 0.1;
             const expectedDistribution: number = 0.25;
             const expectedDistribution: number = 0.25;
@@ -368,24 +368,24 @@ describe('DeadCodeInjectionTransformer', () => {
                 distribution4 = count4 / samplesCount;
                 distribution4 = count4 / samplesCount;
             });
             });
 
 
-            it('variant #1: `IfStatement` variant should have distribution close to `0.25`', () => {
+            it('Variant #1: `IfStatement` variant should have distribution close to `0.25`', () => {
                 assert.closeTo(distribution1, expectedDistribution, delta);
                 assert.closeTo(distribution1, expectedDistribution, delta);
             });
             });
 
 
-            it('variant #2: `IfStatement` variant should have distribution close to `0.25`', () => {
+            it('Variant #2: `IfStatement` variant should have distribution close to `0.25`', () => {
                 assert.closeTo(distribution2, expectedDistribution, delta);
                 assert.closeTo(distribution2, expectedDistribution, delta);
             });
             });
 
 
-            it('variant #3: `IfStatement` variant should have distribution close to `0.25`', () => {
+            it('Variant #3: `IfStatement` variant should have distribution close to `0.25`', () => {
                 assert.closeTo(distribution3, expectedDistribution, delta);
                 assert.closeTo(distribution3, expectedDistribution, delta);
             });
             });
 
 
-            it('variant #4: `IfStatement` variant should have distribution close to `0.25`', () => {
+            it('Variant #4: `IfStatement` variant should have distribution close to `0.25`', () => {
                 assert.closeTo(distribution4, expectedDistribution, delta);
                 assert.closeTo(distribution4, expectedDistribution, delta);
             });
             });
         });
         });
 
 
-        describe('variant #8 - block scope of block statement is `ProgramNode`', () => {
+        describe('Variant #8 - block scope of block statement is `ProgramNode`', () => {
             const regExp: RegExp = new RegExp(
             const regExp: RegExp = new RegExp(
                 `if *\\(!!\\[\\]\\) *{` +
                 `if *\\(!!\\[\\]\\) *{` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
@@ -415,7 +415,7 @@ describe('DeadCodeInjectionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #9 - correct obfuscation of dead-code block statements', () => {
+        describe('Variant #9 - correct obfuscation of dead-code block statements', () => {
             const variableName: string = 'importantVariableName';
             const variableName: string = 'importantVariableName';
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -440,7 +440,7 @@ describe('DeadCodeInjectionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #10 - unique names for dead code identifiers', () => {
+        describe('Variant #10 - unique names for dead code identifiers', () => {
             const deadCodeMatch: string = `` +
             const deadCodeMatch: string = `` +
                 `if *\\(.*?\\) *{` +
                 `if *\\(.*?\\) *{` +
                     `var *(\\w).*?;` +
                     `var *(\\w).*?;` +
@@ -482,7 +482,7 @@ describe('DeadCodeInjectionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #11 - block statements with empty body', () => {
+        describe('Variant #11 - block statements with empty body', () => {
             const regExp: RegExp = new RegExp(
             const regExp: RegExp = new RegExp(
                 `function *${variableMatch} *\\(\\) *{ *} *` +
                 `function *${variableMatch} *\\(\\) *{ *} *` +
                 `${variableMatch} *\\(\\); *`,
                 `${variableMatch} *\\(\\); *`,
@@ -518,8 +518,8 @@ describe('DeadCodeInjectionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #12 - block statement with scope-hoisting', () => {
-            describe('variant #1: collecting of block statements', () => {
+        describe('Variant #12 - block statement with scope-hoisting', () => {
+            describe('Variant #1: collecting of block statements', () => {
                 const regExp: RegExp = new RegExp(
                 const regExp: RegExp = new RegExp(
                     `${variableMatch} *\\(\\); *` +
                     `${variableMatch} *\\(\\); *` +
                     `var *${variableMatch} *= *0x2; *` +
                     `var *${variableMatch} *= *0x2; *` +
@@ -556,7 +556,7 @@ describe('DeadCodeInjectionTransformer', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: wrapping of block statements in dead code conditions', () => {
+            describe('Variant #2: wrapping of block statements in dead code conditions', () => {
                 const regExp: RegExp = new RegExp(
                 const regExp: RegExp = new RegExp(
                     `function *${variableMatch} *\\(\\) *{ *` +
                     `function *${variableMatch} *\\(\\) *{ *` +
                         `var *${variableMatch} *= *0x1; *` +
                         `var *${variableMatch} *= *0x1; *` +

+ 4 - 4
test/functional-tests/node-transformers/obfuscating-transformers/class-declaration-transformer/ClassDeclarationTransformer.spec.ts

@@ -11,7 +11,7 @@ import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFac
 
 
 describe('ClassDeclarationTransformer', () => {
 describe('ClassDeclarationTransformer', () => {
     describe('transformation of `classDeclaration` node names', () => {
     describe('transformation of `classDeclaration` node names', () => {
-        describe('variant #1: `classDeclaration` parent block scope is not a `ProgramNode`', () => {
+        describe('Variant #1: `classDeclaration` parent block scope is not a `ProgramNode`', () => {
             const classNameIdentifierRegExp: RegExp = /class *(_0x[a-f0-9]{4,6}) *\{/;
             const classNameIdentifierRegExp: RegExp = /class *(_0x[a-f0-9]{4,6}) *\{/;
             const classCallIdentifierRegExp: RegExp = /new *(_0x[a-f0-9]{4,6}) *\( *\);/;
             const classCallIdentifierRegExp: RegExp = /new *(_0x[a-f0-9]{4,6}) *\( *\);/;
 
 
@@ -38,8 +38,8 @@ describe('ClassDeclarationTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: `classDeclaration` parent block scope is a `ProgramNode`', () => {
-            describe('variant #1: `renameGlobals` option is disabled', () => {
+        describe('Variant #2: `classDeclaration` parent block scope is a `ProgramNode`', () => {
+            describe('Variant #1: `renameGlobals` option is disabled', () => {
                 const classNameIdentifierRegExp: RegExp = /class *Foo *\{/;
                 const classNameIdentifierRegExp: RegExp = /class *Foo *\{/;
                 const classCallIdentifierRegExp: RegExp = /new *Foo *\( *\);/;
                 const classCallIdentifierRegExp: RegExp = /new *Foo *\( *\);/;
 
 
@@ -66,7 +66,7 @@ describe('ClassDeclarationTransformer', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: `renameGlobals` option is enabled', () => {
+            describe('Variant #2: `renameGlobals` option is enabled', () => {
                 const classNameIdentifierRegExp: RegExp = /class *(_0x[a-f0-9]{4,6}) *\{/;
                 const classNameIdentifierRegExp: RegExp = /class *(_0x[a-f0-9]{4,6}) *\{/;
                 const classCallIdentifierRegExp: RegExp = /new *(_0x[a-f0-9]{4,6}) *\( *\);/;
                 const classCallIdentifierRegExp: RegExp = /new *(_0x[a-f0-9]{4,6}) *\( *\);/;
 
 

+ 6 - 6
test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/FunctionDeclarationTransformer.spec.ts

@@ -11,7 +11,7 @@ import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFac
 
 
 describe('FunctionDeclarationTransformer', () => {
 describe('FunctionDeclarationTransformer', () => {
     describe('transformation of `functionDeclaration` node names', () => {
     describe('transformation of `functionDeclaration` node names', () => {
-        describe('variant #1: `functionDeclaration` parent block scope is not a `ProgramNode`', () => {
+        describe('Variant #1: `functionDeclaration` parent block scope is not a `ProgramNode`', () => {
             const functionNameIdentifierRegExp: RegExp = /function *(_0x[a-f0-9]{4,6}) *\(\) *\{/;
             const functionNameIdentifierRegExp: RegExp = /function *(_0x[a-f0-9]{4,6}) *\(\) *\{/;
             const functionCallIdentifierRegExp: RegExp = /(_0x[a-f0-9]{4,6}) *\( *\);/;
             const functionCallIdentifierRegExp: RegExp = /(_0x[a-f0-9]{4,6}) *\( *\);/;
 
 
@@ -38,8 +38,8 @@ describe('FunctionDeclarationTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: `functionDeclaration` parent block scope is a `ProgramNode`', () => {
-            describe('variant #1: `renameGlobals` option is disabled', () => {
+        describe('Variant #2: `functionDeclaration` parent block scope is a `ProgramNode`', () => {
+            describe('Variant #1: `renameGlobals` option is disabled', () => {
                 const functionNameIdentifierRegExp: RegExp = /function *foo *\(\) *\{/;
                 const functionNameIdentifierRegExp: RegExp = /function *foo *\(\) *\{/;
                 const functionCallIdentifierRegExp: RegExp = /foo *\( *\);/;
                 const functionCallIdentifierRegExp: RegExp = /foo *\( *\);/;
 
 
@@ -66,7 +66,7 @@ describe('FunctionDeclarationTransformer', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: `renameGlobals` option is enabled', () => {
+            describe('Variant #2: `renameGlobals` option is enabled', () => {
                 const functionNameIdentifierRegExp: RegExp = /function *(_0x[a-f0-9]{4,6}) *\(\) *\{/;
                 const functionNameIdentifierRegExp: RegExp = /function *(_0x[a-f0-9]{4,6}) *\(\) *\{/;
                 const functionCallIdentifierRegExp: RegExp = /(_0x[a-f0-9]{4,6}) *\( *\);/;
                 const functionCallIdentifierRegExp: RegExp = /(_0x[a-f0-9]{4,6}) *\( *\);/;
 
 
@@ -95,7 +95,7 @@ describe('FunctionDeclarationTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: generator `functionDeclaration`', () => {
+        describe('Variant #3: generator `functionDeclaration`', () => {
             const functionNameIdentifierRegExp: RegExp = /function *\* *(_0x[a-f0-9]{4,6}) *\(\) *\{/;
             const functionNameIdentifierRegExp: RegExp = /function *\* *(_0x[a-f0-9]{4,6}) *\(\) *\{/;
             const functionCallIdentifierRegExp: RegExp = /let *_0x[a-f0-9]{4,6} *= *(_0x[a-f0-9]{4,6}) *\( *\);/;
             const functionCallIdentifierRegExp: RegExp = /let *_0x[a-f0-9]{4,6} *= *(_0x[a-f0-9]{4,6}) *\( *\);/;
 
 
@@ -122,7 +122,7 @@ describe('FunctionDeclarationTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4: async `functionDeclaration`', () => {
+        describe('Variant #4: async `functionDeclaration`', () => {
             const functionNameIdentifierRegExp: RegExp = /async *function *(_0x[a-f0-9]{4,6}) *\(\) *\{/;
             const functionNameIdentifierRegExp: RegExp = /async *function *(_0x[a-f0-9]{4,6}) *\(\) *\{/;
             const functionCallIdentifierRegExp: RegExp = /await *(_0x[a-f0-9]{4,6}) *\( *\);/;
             const functionCallIdentifierRegExp: RegExp = /await *(_0x[a-f0-9]{4,6}) *\( *\);/;
 
 

+ 5 - 5
test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/FunctionTransformer.spec.ts

@@ -49,7 +49,7 @@ describe('FunctionTransformer', () => {
     });
     });
 
 
     describe('object pattern as parameter', () => {
     describe('object pattern as parameter', () => {
-        describe('variant #1: simple', () => {
+        describe('Variant #1: simple', () => {
             const functionParameterRegExp: RegExp = /function *\(\{ *bar *\}\) *\{/;
             const functionParameterRegExp: RegExp = /function *\(\{ *bar *\}\) *\{/;
             const functionBodyRegExp: RegExp = /return *bar;/;
             const functionBodyRegExp: RegExp = /return *bar;/;
 
 
@@ -76,7 +76,7 @@ describe('FunctionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: correct transformation when identifier with same name in parent scope exist', () => {
+        describe('Variant #2: correct transformation when identifier with same name in parent scope exist', () => {
             const callbackParameterRegExp: RegExp = /\['then'] *\(\({ *data *}\)/;
             const callbackParameterRegExp: RegExp = /\['then'] *\(\({ *data *}\)/;
             const callbackBodyRegExp: RegExp = /console\['log']\(data\)/;
             const callbackBodyRegExp: RegExp = /console\['log']\(data\)/;
 
 
@@ -105,7 +105,7 @@ describe('FunctionTransformer', () => {
     });
     });
 
 
     describe('assignment pattern as parameter', () => {
     describe('assignment pattern as parameter', () => {
-        describe('variant #1: literal as right value', () => {
+        describe('Variant #1: literal as right value', () => {
             const functionParameterRegExp: RegExp = /function *\(_0x[a-f0-9]{4,6} *= *0x1\) *\{/;
             const functionParameterRegExp: RegExp = /function *\(_0x[a-f0-9]{4,6} *= *0x1\) *\{/;
             const functionBodyRegExp: RegExp = /return *_0x[a-f0-9]{4,6};/;
             const functionBodyRegExp: RegExp = /return *_0x[a-f0-9]{4,6};/;
 
 
@@ -132,7 +132,7 @@ describe('FunctionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: identifier as right value', () => {
+        describe('Variant #2: identifier as right value', () => {
             const variableDeclarationRegExp: RegExp = /var *(_0x[a-f0-9]{4,6}) *= *0x1;/;
             const variableDeclarationRegExp: RegExp = /var *(_0x[a-f0-9]{4,6}) *= *0x1;/;
             const functionParameterRegExp: RegExp = /function *\((_0x[a-f0-9]{4,6}) *= *(_0x[a-f0-9]{4,6})\) *\{/;
             const functionParameterRegExp: RegExp = /function *\((_0x[a-f0-9]{4,6}) *= *(_0x[a-f0-9]{4,6})\) *\{/;
             const functionBodyRegExp: RegExp = /return *(_0x[a-f0-9]{4,6});/;
             const functionBodyRegExp: RegExp = /return *(_0x[a-f0-9]{4,6});/;
@@ -180,7 +180,7 @@ describe('FunctionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: identifier as right value', () => {
+        describe('Variant #3: identifier as right value', () => {
             const variableDeclarationRegExp: RegExp = /var *(_0x[a-f0-9]{4,6}) *= *0x1;/;
             const variableDeclarationRegExp: RegExp = /var *(_0x[a-f0-9]{4,6}) *= *0x1;/;
             const functionParameterRegExp: RegExp = /function *\((_0x[a-f0-9]{4,6}), *(_0x[a-f0-9]{4,6}) *= *(_0x[a-f0-9]{4,6})\) *\{/;
             const functionParameterRegExp: RegExp = /function *\((_0x[a-f0-9]{4,6}), *(_0x[a-f0-9]{4,6}) *= *(_0x[a-f0-9]{4,6})\) *\{/;
             const functionBodyRegExp: RegExp = /return *(_0x[a-f0-9]{4,6}) *\+ *(_0x[a-f0-9]{4,6});/;
             const functionBodyRegExp: RegExp = /return *(_0x[a-f0-9]{4,6}) *\+ *(_0x[a-f0-9]{4,6});/;

+ 13 - 13
test/functional-tests/node-transformers/obfuscating-transformers/literal-transformer/LiteralTransformer.spec.ts

@@ -13,7 +13,7 @@ import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFac
 
 
 describe('LiteralTransformer', () => {
 describe('LiteralTransformer', () => {
     describe('transformation of literal node with string value', () => {
     describe('transformation of literal node with string value', () => {
-        describe('variant #1: default behaviour', () => {
+        describe('Variant #1: default behaviour', () => {
             const stringArrayRegExp: RegExp = /^var *_0x([a-f0-9]){4} *= *\['test'\];/;
             const stringArrayRegExp: RegExp = /^var *_0x([a-f0-9]){4} *= *\['test'\];/;
             const stringArrayCallRegExp: RegExp = /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/;
             const stringArrayCallRegExp: RegExp = /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/;
 
 
@@ -42,7 +42,7 @@ describe('LiteralTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: `stringArray` option is disabled', () => {
+        describe('Variant #2: `stringArray` option is disabled', () => {
             const regExp: RegExp = /^var *test *= *'test';/;
             const regExp: RegExp = /^var *test *= *'test';/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -64,7 +64,7 @@ describe('LiteralTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: string contains non-latin and non-digit characters and `unicodeEscapeSequence` is disabled', () => {
+        describe('Variant #3: string contains non-latin and non-digit characters and `unicodeEscapeSequence` is disabled', () => {
             let testFunc: () => void;
             let testFunc: () => void;
 
 
             before(() => {
             before(() => {
@@ -85,7 +85,7 @@ describe('LiteralTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4: same literal node values', () => {
+        describe('Variant #4: same literal node values', () => {
             const stringArrayRegExp: RegExp = /^var *_0x([a-f0-9]){4} *= *\['test'\];/;
             const stringArrayRegExp: RegExp = /^var *_0x([a-f0-9]){4} *= *\['test'\];/;
             const stringArrayCallRegExp: RegExp = /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/;
             const stringArrayCallRegExp: RegExp = /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/;
 
 
@@ -114,7 +114,7 @@ describe('LiteralTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #5: `unicodeEscapeSequence` option is enabled', () => {
+        describe('Variant #5: `unicodeEscapeSequence` option is enabled', () => {
             const regExp: RegExp = /^var *test *= *'\\x74\\x65\\x73\\x74';$/;
             const regExp: RegExp = /^var *test *= *'\\x74\\x65\\x73\\x74';$/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -138,7 +138,7 @@ describe('LiteralTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #6: `unicodeEscapeSequence` and `stringArray` options are enabled', () => {
+        describe('Variant #6: `unicodeEscapeSequence` and `stringArray` options are enabled', () => {
             const stringArrayRegExp: RegExp = /^var *_0x([a-f0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/;
             const stringArrayRegExp: RegExp = /^var *_0x([a-f0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/;
             const stringArrayCallRegExp: RegExp = /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/;
             const stringArrayCallRegExp: RegExp = /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/;
 
 
@@ -168,7 +168,7 @@ describe('LiteralTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #7: short literal node value', () => {
+        describe('Variant #7: short literal node value', () => {
             const regExp: RegExp = /var *test *= *'te';/;
             const regExp: RegExp = /var *test *= *'te';/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -192,7 +192,7 @@ describe('LiteralTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #8: base64 encoding', () => {
+        describe('Variant #8: base64 encoding', () => {
             const stringArrayRegExp: RegExp = /^var *_0x([a-f0-9]){4} *= *\['dGVzdA=='\];/;
             const stringArrayRegExp: RegExp = /^var *_0x([a-f0-9]){4} *= *\['dGVzdA=='\];/;
             const stringArrayCallRegExp: RegExp = /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/;
             const stringArrayCallRegExp: RegExp = /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/;
 
 
@@ -222,7 +222,7 @@ describe('LiteralTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #9: rc4 encoding', () => {
+        describe('Variant #9: rc4 encoding', () => {
             const regExp: RegExp = /var *test *= *_0x([a-f0-9]){4}\('0x0', *'.{4}'\);/;
             const regExp: RegExp = /var *test *= *_0x([a-f0-9]){4}\('0x0', *'.{4}'\);/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -247,7 +247,7 @@ describe('LiteralTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #10: `stringArrayThreshold` option value', () => {
+        describe('Variant #10: `stringArrayThreshold` option value', () => {
             const samples: number = 1000;
             const samples: number = 1000;
             const stringArrayThreshold: number = 0.5;
             const stringArrayThreshold: number = 0.5;
             const delta: number = 0.1;
             const delta: number = 0.1;
@@ -282,16 +282,16 @@ describe('LiteralTransformer', () => {
                 noStringArrayProbability = noStringArrayMatchesLength / samples;
                 noStringArrayProbability = noStringArrayMatchesLength / samples;
             });
             });
 
 
-            it('variant #1: should replace literal node value with value from string array with `stringArrayThreshold` chance', () => {
+            it('Variant #1: should replace literal node value with value from string array with `stringArrayThreshold` chance', () => {
                 assert.closeTo(stringArrayProbability, stringArrayThreshold, delta);
                 assert.closeTo(stringArrayProbability, stringArrayThreshold, delta);
             });
             });
 
 
-            it('variant #2: shouldn\'t replace literal node value with value from string array with `(1 - stringArrayThreshold)` chance', () => {
+            it('Variant #2: shouldn\'t replace literal node value with value from string array with `(1 - stringArrayThreshold)` chance', () => {
                 assert.closeTo(noStringArrayProbability, stringArrayThreshold, delta);
                 assert.closeTo(noStringArrayProbability, stringArrayThreshold, delta);
             });
             });
         });
         });
 
 
-        describe('variant #11: string array calls wrapper name', () => {
+        describe('Variant #11: string array calls wrapper name', () => {
             const regExp: RegExp = /console\[b\('0x0'\)]\('a'\);/;
             const regExp: RegExp = /console\[b\('0x0'\)]\('a'\);/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;

+ 16 - 16
test/functional-tests/node-transformers/obfuscating-transformers/variable-declaration-transformer/VariableDeclarationTransformer.spec.ts

@@ -10,7 +10,7 @@ import { readFileAsString } from '../../../../helpers/readFileAsString';
 import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 
 describe('VariableDeclarationTransformer', () => {
 describe('VariableDeclarationTransformer', () => {
-    describe('variant #1: default behaviour', () => {
+    describe('Variant #1: default behaviour', () => {
         const variableDeclarationRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *'abc';/;
         const variableDeclarationRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *'abc';/;
         const variableCallRegExp: RegExp = /console\['log'\]\(_0x([a-f0-9]){4,6}\);/;
         const variableCallRegExp: RegExp = /console\['log'\]\(_0x([a-f0-9]){4,6}\);/;
 
 
@@ -37,8 +37,8 @@ describe('VariableDeclarationTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #2: parent block scope node is `Program` node', () => {
-        describe('variant #1: `renameGlobals` option is disabled', () => {
+    describe('Variant #2: parent block scope node is `Program` node', () => {
+        describe('Variant #1: `renameGlobals` option is disabled', () => {
             const variableDeclarationRegExp: RegExp = /var *test *= *0xa;/;
             const variableDeclarationRegExp: RegExp = /var *test *= *0xa;/;
             const variableCallRegExp: RegExp = /console\['log'\]\(test\);/;
             const variableCallRegExp: RegExp = /console\['log'\]\(test\);/;
 
 
@@ -65,7 +65,7 @@ describe('VariableDeclarationTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: `renameGlobals` option is enabled', () => {
+        describe('Variant #2: `renameGlobals` option is enabled', () => {
             const variableDeclarationRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0xa;/;
             const variableDeclarationRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0xa;/;
             const variableCallRegExp: RegExp = /console\['log'\]\(_0x([a-f0-9]){4,6}\);/;
             const variableCallRegExp: RegExp = /console\['log'\]\(_0x([a-f0-9]){4,6}\);/;
 
 
@@ -94,7 +94,7 @@ describe('VariableDeclarationTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #3: scope of `var` kind', () => {
+    describe('Variant #3: scope of `var` kind', () => {
         const regExp: RegExp = /console\['log'\]\(_0x([a-f0-9]){4,6}\);/;
         const regExp: RegExp = /console\['log'\]\(_0x([a-f0-9]){4,6}\);/;
 
 
         let obfuscatedCode: string;
         let obfuscatedCode: string;
@@ -116,7 +116,7 @@ describe('VariableDeclarationTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #4: scope of `let` kind', () => {
+    describe('Variant #4: scope of `let` kind', () => {
         const regExp: RegExp = /console\['log'\]\(test\);/;
         const regExp: RegExp = /console\['log'\]\(test\);/;
 
 
         let obfuscatedCode: string;
         let obfuscatedCode: string;
@@ -138,7 +138,7 @@ describe('VariableDeclarationTransformer', () => {
         });
         });
     });
     });
 
 
-    describe(`variant #5: variable calls before variable declaration`, () => {
+    describe(`Variant #5: variable calls before variable declaration`, () => {
         const functionBodyVariableCallRegExp: RegExp = /console\['log'\]\(_0x([a-f0-9]){4,6}\['item'\]\);/;
         const functionBodyVariableCallRegExp: RegExp = /console\['log'\]\(_0x([a-f0-9]){4,6}\['item'\]\);/;
         const variableCallBeforeDeclarationRegExp: RegExp = /console\['log'\]\(_0x([a-f0-9]){4,6}\);/;
         const variableCallBeforeDeclarationRegExp: RegExp = /console\['log'\]\(_0x([a-f0-9]){4,6}\);/;
 
 
@@ -165,7 +165,7 @@ describe('VariableDeclarationTransformer', () => {
         });
         });
     });
     });
 
 
-    describe(`variant #6: variable calls before variable declaration when function param has the same name as variables name`, () => {
+    describe(`Variant #6: variable calls before variable declaration when function param has the same name as variables name`, () => {
         const functionParamIdentifierRegExp: RegExp = /function *_0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\,(_0x[a-f0-9]{4,6})\) *\{/;
         const functionParamIdentifierRegExp: RegExp = /function *_0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\,(_0x[a-f0-9]{4,6})\) *\{/;
         const innerFunctionParamIdentifierRegExp: RegExp = /function _0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\) *\{/;
         const innerFunctionParamIdentifierRegExp: RegExp = /function _0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\) *\{/;
         const constructorIdentifierRegExp: RegExp = /console\['log'\]\((_0x[a-f0-9]{4,6})\)/;
         const constructorIdentifierRegExp: RegExp = /console\['log'\]\((_0x[a-f0-9]{4,6})\)/;
@@ -220,7 +220,7 @@ describe('VariableDeclarationTransformer', () => {
         });
         });
     });
     });
 
 
-    describe(`variant #7: variable calls before variable declaration when catch clause param has the same name as variables name`, () => {
+    describe(`Variant #7: variable calls before variable declaration when catch clause param has the same name as variables name`, () => {
         const catchClauseParamIdentifierRegExp: RegExp = /catch *\((_0x[a-f0-9]{4,6})\) *\{/;
         const catchClauseParamIdentifierRegExp: RegExp = /catch *\((_0x[a-f0-9]{4,6})\) *\{/;
         const innerFunctionParamIdentifierRegExp: RegExp = /function _0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\) *\{/;
         const innerFunctionParamIdentifierRegExp: RegExp = /function _0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\) *\{/;
         const constructorIdentifierRegExp: RegExp = /console\['log'\]\((_0x[a-f0-9]{4,6})\)/;
         const constructorIdentifierRegExp: RegExp = /console\['log'\]\((_0x[a-f0-9]{4,6})\)/;
@@ -275,8 +275,8 @@ describe('VariableDeclarationTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #8: wrong replacement', () => {
-        describe('variant #1: property node identifier', () => {
+    describe('Variant #8: wrong replacement', () => {
+        describe('Variant #1: property node identifier', () => {
             const regExp: RegExp = /var _0x([a-f0-9]){4,6} *= *\{'test/;
             const regExp: RegExp = /var _0x([a-f0-9]){4,6} *= *\{'test/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -298,7 +298,7 @@ describe('VariableDeclarationTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: computed member expression identifier', () => {
+        describe('Variant #2: computed member expression identifier', () => {
             const regExp: RegExp = /_0x([a-f0-9]){4,6}\['test'\]/;
             const regExp: RegExp = /_0x([a-f0-9]){4,6}\['test'\]/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -321,7 +321,7 @@ describe('VariableDeclarationTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #9: object pattern as variable declarator', () => {
+    describe('Variant #9: object pattern as variable declarator', () => {
         const objectPatternVariableDeclaratorRegExp: RegExp = /var *\{ *bar *\} *= *\{ *'bar' *: *'foo' *\};/;
         const objectPatternVariableDeclaratorRegExp: RegExp = /var *\{ *bar *\} *= *\{ *'bar' *: *'foo' *\};/;
         const variableUsageRegExp: RegExp = /console\['log'\]\(bar\);/;
         const variableUsageRegExp: RegExp = /console\['log'\]\(bar\);/;
 
 
@@ -348,7 +348,7 @@ describe('VariableDeclarationTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #10: array pattern as variable declarator', () => {
+    describe('Variant #10: array pattern as variable declarator', () => {
         const objectPatternVariableDeclaratorRegExp: RegExp = /var *\[ *(_0x([a-f0-9]){4,6}), *(_0x([a-f0-9]){4,6}) *\] *= *\[0x1, *0x2\];/;
         const objectPatternVariableDeclaratorRegExp: RegExp = /var *\[ *(_0x([a-f0-9]){4,6}), *(_0x([a-f0-9]){4,6}) *\] *= *\[0x1, *0x2\];/;
         const variableUsageRegExp: RegExp = /console\['log'\]\((_0x([a-f0-9]){4,6}), *(_0x([a-f0-9]){4,6})\);/;
         const variableUsageRegExp: RegExp = /console\['log'\]\((_0x([a-f0-9]){4,6}), *(_0x([a-f0-9]){4,6})\);/;
 
 
@@ -392,7 +392,7 @@ describe('VariableDeclarationTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #11: computed object expression identifier', () => {
+    describe('Variant #11: computed object expression identifier', () => {
         const computedObjectExpressionRegExp: RegExp = /var *_0x[a-f0-9]{4,6} *= *\{\[_0x[a-f0-9]{4,6}\]: *0x1\};/;
         const computedObjectExpressionRegExp: RegExp = /var *_0x[a-f0-9]{4,6} *= *\{\[_0x[a-f0-9]{4,6}\]: *0x1\};/;
 
 
         let obfuscatedCode: string;
         let obfuscatedCode: string;
@@ -414,7 +414,7 @@ describe('VariableDeclarationTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #12: method definition key identifier', () => {
+    describe('Variant #12: method definition key identifier', () => {
         const regExp: RegExp = /\['bar'] *\(\) *{}/;
         const regExp: RegExp = /\['bar'] *\(\) *{}/;
 
 
         let obfuscatedCode: string;
         let obfuscatedCode: string;

+ 6 - 6
test/functional-tests/node-transformers/preparing-transformers/comments-transformer/CommentsTransformer.spec.ts

@@ -9,7 +9,7 @@ import { readFileAsString } from '../../../../helpers/readFileAsString';
 import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 
 describe('CommentsTransformer', () => {
 describe('CommentsTransformer', () => {
-    describe('variant #1: simple comment without preserved words', () => {
+    describe('Variant #1: simple comment without preserved words', () => {
         const regExp: RegExp = /^var *test *= *0x1;$/;
         const regExp: RegExp = /^var *test *= *0x1;$/;
 
 
         let obfuscatedCode: string;
         let obfuscatedCode: string;
@@ -31,7 +31,7 @@ describe('CommentsTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #2: simple comment with preserved words', () => {
+    describe('Variant #2: simple comment with preserved words', () => {
         const regExp: RegExp = /^\/\/ *@license *test *comment *\n*var *test *= *0x1;$/;
         const regExp: RegExp = /^\/\/ *@license *test *comment *\n*var *test *= *0x1;$/;
 
 
         let obfuscatedCode: string;
         let obfuscatedCode: string;
@@ -53,7 +53,7 @@ describe('CommentsTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #3: comment with preserved and non-preserved words', () => {
+    describe('Variant #3: comment with preserved and non-preserved words', () => {
         const regExp: RegExp = /^\/\/ *@license *test *comment *\n*var *test *= *0x1;$/;
         const regExp: RegExp = /^\/\/ *@license *test *comment *\n*var *test *= *0x1;$/;
 
 
         let obfuscatedCode: string;
         let obfuscatedCode: string;
@@ -75,7 +75,7 @@ describe('CommentsTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #4: comment with preserved and non-preserved words', () => {
+    describe('Variant #4: comment with preserved and non-preserved words', () => {
         const regExp: RegExp = new RegExp(``+
         const regExp: RegExp = new RegExp(``+
             `^\\/\\*\\* *\\n` +
             `^\\/\\*\\* *\\n` +
             ` *\\* *@license *\\n` +
             ` *\\* *@license *\\n` +
@@ -104,7 +104,7 @@ describe('CommentsTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #5: only comment without preserved words', () => {
+    describe('Variant #5: only comment without preserved words', () => {
         let obfuscatedCode: string;
         let obfuscatedCode: string;
 
 
         before(() => {
         before(() => {
@@ -124,7 +124,7 @@ describe('CommentsTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #5: only comment with preserved words', () => {
+    describe('Variant #5: only comment with preserved words', () => {
         const regExp: RegExp = /^\/\/ *@license$/;
         const regExp: RegExp = /^\/\/ *@license$/;
 
 
         let obfuscatedCode: string;
         let obfuscatedCode: string;

+ 9 - 9
test/functional-tests/node-transformers/preparing-transformers/eval-call-expression-transformer/EvalCallExpressionTransformer.spec.ts

@@ -10,7 +10,7 @@ import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFac
 import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
 import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
 
 
 describe('EvalCallExpressionTransformer', () => {
 describe('EvalCallExpressionTransformer', () => {
-    describe('variant #1: identifier reference', () => {
+    describe('Variant #1: identifier reference', () => {
         const functionIdentifierRegExp: RegExp = /function *_0x(?:[a-f0-9]){4,6} *\((_0x(?:[a-f0-9]){4,6})\)/;
         const functionIdentifierRegExp: RegExp = /function *_0x(?:[a-f0-9]){4,6} *\((_0x(?:[a-f0-9]){4,6})\)/;
         const evalExpressionRegExp: RegExp = /eval *\('(_0x(?:[a-f0-9]){4,6});'\);/;
         const evalExpressionRegExp: RegExp = /eval *\('(_0x(?:[a-f0-9]){4,6});'\);/;
 
 
@@ -42,7 +42,7 @@ describe('EvalCallExpressionTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #2: call expression with identifier reference', () => {
+    describe('Variant #2: call expression with identifier reference', () => {
         const functionIdentifierRegExp: RegExp = /function *_0x(?:[a-f0-9]){4,6} *\((_0x(?:[a-f0-9]){4,6})\)/;
         const functionIdentifierRegExp: RegExp = /function *_0x(?:[a-f0-9]){4,6} *\((_0x(?:[a-f0-9]){4,6})\)/;
         const evalExpressionRegExp: RegExp = /eval *\('console\[\\'log\\']\((_0x(?:[a-f0-9]){4,6})\);'\);/;
         const evalExpressionRegExp: RegExp = /eval *\('console\[\\'log\\']\((_0x(?:[a-f0-9]){4,6})\);'\);/;
 
 
@@ -74,7 +74,7 @@ describe('EvalCallExpressionTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #3: multiple statements in eval', () => {
+    describe('Variant #3: multiple statements in eval', () => {
         const regExp: RegExp = /eval *\('_0x([a-f0-9]){4,6}; *_0x([a-f0-9]){4,6};'\);/;
         const regExp: RegExp = /eval *\('_0x([a-f0-9]){4,6}; *_0x([a-f0-9]){4,6};'\);/;
 
 
         let obfuscatedCode: string;
         let obfuscatedCode: string;
@@ -96,7 +96,7 @@ describe('EvalCallExpressionTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #4: string array calls wrapper call', () => {
+    describe('Variant #4: string array calls wrapper call', () => {
         const stringArrayRegExp: RegExp = /var *_0x([a-f0-9]){4} *= *\['log', *'bar'];/;
         const stringArrayRegExp: RegExp = /var *_0x([a-f0-9]){4} *= *\['log', *'bar'];/;
         const stringArrayCallsWrapperRegExp: RegExp = /eval *\('console\[_0x([a-f0-9]){4,6}\(\\'0x0\\'\)]\(_0x([a-f0-9]){4,6}\(\\'0x1\\'\)\);'\);/;
         const stringArrayCallsWrapperRegExp: RegExp = /eval *\('console\[_0x([a-f0-9]){4,6}\(\\'0x0\\'\)]\(_0x([a-f0-9]){4,6}\(\\'0x1\\'\)\);'\);/;
 
 
@@ -125,7 +125,7 @@ describe('EvalCallExpressionTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #5: eval expression as argument', () => {
+    describe('Variant #5: eval expression as argument', () => {
         const functionIdentifierRegExp: RegExp = /function *_0x(?:[a-f0-9]){4,6} *\((_0x(?:[a-f0-9]){4,6})\)/;
         const functionIdentifierRegExp: RegExp = /function *_0x(?:[a-f0-9]){4,6} *\((_0x(?:[a-f0-9]){4,6})\)/;
         const evalExpressionRegExp: RegExp = /console\['log']\(eval *\('(_0x(?:[a-f0-9]){4,6});'\)\);/;
         const evalExpressionRegExp: RegExp = /console\['log']\(eval *\('(_0x(?:[a-f0-9]){4,6});'\)\);/;
 
 
@@ -157,7 +157,7 @@ describe('EvalCallExpressionTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #6: nested eval expressions', () => {
+    describe('Variant #6: nested eval expressions', () => {
         const functionIdentifierRegExp: RegExp = /function *_0x(?:[a-f0-9]){4,6} *\((_0x(?:[a-f0-9]){4,6}), *(_0x(?:[a-f0-9]){4,6})\)/;
         const functionIdentifierRegExp: RegExp = /function *_0x(?:[a-f0-9]){4,6} *\((_0x(?:[a-f0-9]){4,6}), *(_0x(?:[a-f0-9]){4,6})\)/;
         const evalExpressionMatch: string = `` +
         const evalExpressionMatch: string = `` +
             `eval *\\('` +
             `eval *\\('` +
@@ -233,7 +233,7 @@ describe('EvalCallExpressionTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #7: wrong eval string', () => {
+    describe('Variant #7: wrong eval string', () => {
         const evalExpressionRegExp: RegExp = /eval *\('~'\);/;
         const evalExpressionRegExp: RegExp = /eval *\('~'\);/;
 
 
         let obfuscatedCode: string
         let obfuscatedCode: string
@@ -255,7 +255,7 @@ describe('EvalCallExpressionTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #8: template literal inside eval expression', () => {
+    describe('Variant #8: template literal inside eval expression', () => {
         const functionIdentifierRegExp: RegExp = /function *_0x(?:[a-f0-9]){4,6} *\((_0x(?:[a-f0-9]){4,6})\)/;
         const functionIdentifierRegExp: RegExp = /function *_0x(?:[a-f0-9]){4,6} *\((_0x(?:[a-f0-9]){4,6})\)/;
         const evalExpressionRegExp: RegExp = /eval *\('(_0x(?:[a-f0-9]){4,6});'\);/;
         const evalExpressionRegExp: RegExp = /eval *\('(_0x(?:[a-f0-9]){4,6});'\);/;
 
 
@@ -287,7 +287,7 @@ describe('EvalCallExpressionTransformer', () => {
         });
         });
     });
     });
 
 
-    describe('variant #9: integration with control flow flattening', () => {
+    describe('Variant #9: integration with control flow flattening', () => {
         const variableMatch: string = '_0x([a-f0-9]){4,6}';
         const variableMatch: string = '_0x([a-f0-9]){4,6}';
         const controlFlowStorageNodeMatch: string = `` +
         const controlFlowStorageNodeMatch: string = `` +
             `var *${variableMatch} *= *\\{` +
             `var *${variableMatch} *= *\\{` +

+ 5 - 5
test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/ConditionalCommentObfuscatingGuard.spec.ts

@@ -10,7 +10,7 @@ import { readFileAsString } from '../../../../../helpers/readFileAsString';
 
 
 describe('ConditionalCommentObfuscatingGuard', () => {
 describe('ConditionalCommentObfuscatingGuard', () => {
     describe('check (node: ESTree.Node): boolean', () => {
     describe('check (node: ESTree.Node): boolean', () => {
-        describe('variant #1: `disable` conditional comment', () => {
+        describe('Variant #1: `disable` conditional comment', () => {
             const obfuscatedVariableDeclarationRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x1;/;
             const obfuscatedVariableDeclarationRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x1;/;
             const ignoredVariableDeclarationRegExp: RegExp = /var *bar *= *2;/;
             const ignoredVariableDeclarationRegExp: RegExp = /var *bar *= *2;/;
             const consoleLogRegExp: RegExp = /console.log\(_0x([a-f0-9]){4,6}\);/;
             const consoleLogRegExp: RegExp = /console.log\(_0x([a-f0-9]){4,6}\);/;
@@ -42,7 +42,7 @@ describe('ConditionalCommentObfuscatingGuard', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: `disable` and `enable` conditional comments', () => {
+        describe('Variant #2: `disable` and `enable` conditional comments', () => {
             const obfuscatedVariableDeclaration1RegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x1;/;
             const obfuscatedVariableDeclaration1RegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x1;/;
             const obfuscatedVariableDeclaration2RegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x3;/;
             const obfuscatedVariableDeclaration2RegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x3;/;
             const ignoredVariableDeclarationRegExp: RegExp = /var *bar *= *2;/;
             const ignoredVariableDeclarationRegExp: RegExp = /var *bar *= *2;/;
@@ -74,7 +74,7 @@ describe('ConditionalCommentObfuscatingGuard', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: `disable` conditional comment from beginning of the code', () => {
+        describe('Variant #3: `disable` conditional comment from beginning of the code', () => {
             const ignoredVariableDeclaration1RegExp: RegExp = /var *foo *= *1;/;
             const ignoredVariableDeclaration1RegExp: RegExp = /var *foo *= *1;/;
             const ignoredVariableDeclaration2RegExp: RegExp = /var *bar *= *2;/;
             const ignoredVariableDeclaration2RegExp: RegExp = /var *bar *= *2;/;
 
 
@@ -101,7 +101,7 @@ describe('ConditionalCommentObfuscatingGuard', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4: `disable` and `enable` conditional comments with dead code injection', () => {
+        describe('Variant #4: `disable` and `enable` conditional comments with dead code injection', () => {
             const obfuscatedFunctionExpressionRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *function *\(_0x([a-f0-9]){4,6}, *_0x([a-f0-9]){4,6}, *_0x([a-f0-9]){4,6}\) *{/g;
             const obfuscatedFunctionExpressionRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *function *\(_0x([a-f0-9]){4,6}, *_0x([a-f0-9]){4,6}, *_0x([a-f0-9]){4,6}\) *{/g;
             const expectedObfuscatedFunctionExpressionLength: number = 3;
             const expectedObfuscatedFunctionExpressionLength: number = 3;
 
 
@@ -172,7 +172,7 @@ describe('ConditionalCommentObfuscatingGuard', () => {
             });
             });
         });
         });
 
 
-        describe('variant #5: `disable` and `enable` conditional comments with control flow flattening', () => {
+        describe('Variant #5: `disable` and `enable` conditional comments with control flow flattening', () => {
             const obfuscatedVariableDeclarationRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['[a-zA-Z0-9]{1,5}'];/;
             const obfuscatedVariableDeclarationRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['[a-zA-Z0-9]{1,5}'];/;
             const ignoredVariableDeclarationRegExp: RegExp = /var *bar *= *'bar';/;
             const ignoredVariableDeclarationRegExp: RegExp = /var *bar *= *'bar';/;
 
 

+ 2 - 2
test/functional-tests/options/OptionsNormalizer.spec.ts

@@ -197,7 +197,7 @@ describe('OptionsNormalizer', () => {
         });
         });
 
 
         describe('sourceMapBaseUrlRule', () => {
         describe('sourceMapBaseUrlRule', () => {
-            describe('variant #1: only source map base url', () => {
+            describe('Variant #1: only source map base url', () => {
                 before(() => {
                 before(() => {
                     optionsPreset = getNormalizedOptions({
                     optionsPreset = getNormalizedOptions({
                         ...DEFAULT_PRESET,
                         ...DEFAULT_PRESET,
@@ -215,7 +215,7 @@ describe('OptionsNormalizer', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: source map base url with source map file name', () => {
+            describe('Variant #2: source map base url with source map file name', () => {
                 before(() => {
                 before(() => {
                     optionsPreset = getNormalizedOptions({
                     optionsPreset = getNormalizedOptions({
                         ...DEFAULT_PRESET,
                         ...DEFAULT_PRESET,

+ 3 - 3
test/functional-tests/templates/GlobalVariableNoEvalTemplate.spec.ts

@@ -7,7 +7,7 @@ import { assert } from 'chai';
 import { GlobalVariableNoEvalTemplate } from '../../../src/templates/GlobalVariableNoEvalTemplate';
 import { GlobalVariableNoEvalTemplate } from '../../../src/templates/GlobalVariableNoEvalTemplate';
 
 
 describe('GlobalVariableNoEvalTemplate (): string', () => {
 describe('GlobalVariableNoEvalTemplate (): string', () => {
-    describe('variant #1: simple', () => {
+    describe('Variant #1: simple', () => {
         const expectedGlobalObject: NodeJS.Global = global;
         const expectedGlobalObject: NodeJS.Global = global;
 
 
         let globalObject: NodeJS.Global;
         let globalObject: NodeJS.Global;
@@ -27,7 +27,7 @@ describe('GlobalVariableNoEvalTemplate (): string', () => {
         });
         });
     });
     });
 
 
-    describe('variant #2: call inside function', () => {
+    describe('Variant #2: call inside function', () => {
         const expectedGlobalObject: NodeJS.Global = global;
         const expectedGlobalObject: NodeJS.Global = global;
 
 
         let globalObject: NodeJS.Global;
         let globalObject: NodeJS.Global;
@@ -49,7 +49,7 @@ describe('GlobalVariableNoEvalTemplate (): string', () => {
         });
         });
     });
     });
 
 
-    describe('variant #3: return `window`', () => {
+    describe('Variant #3: return `window`', () => {
         const expectedGlobalObject: {} = {
         const expectedGlobalObject: {} = {
             document: {}
             document: {}
         };
         };

+ 5 - 5
test/functional-tests/templates/debug-protection-nodes/DebugProtectionFunctionCallTemplate.spec.ts

@@ -31,7 +31,7 @@ function spawnThread(inputCallback: Function, threadCallback: Function, timeoutC
 }
 }
 
 
 describe('DebugProtectionFunctionCallTemplate (): string', () => {
 describe('DebugProtectionFunctionCallTemplate (): string', () => {
-    describe('variant #1: correctly obfuscated code`', () => {
+    describe('Variant #1: correctly obfuscated code`', () => {
         const expectedEvaluationResult: number = 1;
         const expectedEvaluationResult: number = 1;
 
 
         let obfuscatedCode: string,
         let obfuscatedCode: string,
@@ -66,7 +66,7 @@ describe('DebugProtectionFunctionCallTemplate (): string', () => {
         });
         });
     });
     });
 
 
-    describe('variant #2: correctly obfuscated code with enabled `mangle` option', () => {
+    describe('Variant #2: correctly obfuscated code with enabled `mangle` option', () => {
         const expectedEvaluationResult: number = 1;
         const expectedEvaluationResult: number = 1;
 
 
         let obfuscatedCode: string,
         let obfuscatedCode: string,
@@ -102,7 +102,7 @@ describe('DebugProtectionFunctionCallTemplate (): string', () => {
         });
         });
     });
     });
 
 
-    describe('variant #3: correctly obfuscated code with target `extension`', () => {
+    describe('Variant #3: correctly obfuscated code with target `extension`', () => {
         const expectedEvaluationResult: number = 1;
         const expectedEvaluationResult: number = 1;
 
 
         let obfuscatedCode: string,
         let obfuscatedCode: string,
@@ -138,7 +138,7 @@ describe('DebugProtectionFunctionCallTemplate (): string', () => {
         });
         });
     });
     });
 
 
-    describe('variant #4: obfuscated code with removed debug protection code', () => {
+    describe('Variant #4: obfuscated code with removed debug protection code', () => {
         const expectedEvaluationResult: number = 0;
         const expectedEvaluationResult: number = 0;
 
 
         let obfuscatedCode: string,
         let obfuscatedCode: string,
@@ -174,7 +174,7 @@ describe('DebugProtectionFunctionCallTemplate (): string', () => {
         });
         });
     });
     });
 
 
-    describe('variant #5: single call of debug protection code', () => {
+    describe('Variant #5: single call of debug protection code', () => {
         const expectedEvaluationResult: number = 1;
         const expectedEvaluationResult: number = 1;
 
 
         let obfuscatedCode: string,
         let obfuscatedCode: string,

+ 3 - 3
test/functional-tests/templates/domain-lock-nodes/DomainLockNodeTemplate.spec.ts

@@ -50,7 +50,7 @@ describe('DomainLockNodeTemplate (): string', () => {
         cryptUtils = inversifyContainerFacade.get<ICryptUtils>(ServiceIdentifiers.ICryptUtils);
         cryptUtils = inversifyContainerFacade.get<ICryptUtils>(ServiceIdentifiers.ICryptUtils);
     });
     });
 
 
-    describe('variant #1: current domain matches with `domainsString`', () => {
+    describe('Variant #1: current domain matches with `domainsString`', () => {
         const domainsString: string = ['www.example.com'].join(';');
         const domainsString: string = ['www.example.com'].join(';');
         const currentDomain: string = 'www.example.com';
         const currentDomain: string = 'www.example.com';
 
 
@@ -76,7 +76,7 @@ describe('DomainLockNodeTemplate (): string', () => {
         });
         });
     });
     });
 
 
-    describe('variant #2: urrent domain matches with base domain of `domainsString` item', () => {
+    describe('Variant #2: urrent domain matches with base domain of `domainsString` item', () => {
         const domainsString: string = ['www.test.com', '.example.com'].join(';');
         const domainsString: string = ['www.test.com', '.example.com'].join(';');
         const currentDomain: string = 'subdomain.example.com';
         const currentDomain: string = 'subdomain.example.com';
 
 
@@ -102,7 +102,7 @@ describe('DomainLockNodeTemplate (): string', () => {
         });
         });
     });
     });
 
 
-    describe('variant #3: current domain doesn\'t match with `domainsString`', () => {
+    describe('Variant #3: current domain doesn\'t match with `domainsString`', () => {
         const domainsString: string = ['www.example.com'].join(';');
         const domainsString: string = ['www.example.com'].join(';');
         const currentDomain: string = 'www.test.com';
         const currentDomain: string = 'www.test.com';
 
 

+ 2 - 2
test/functional-tests/templates/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec.ts

@@ -34,7 +34,7 @@ describe('StringArrayCallsWrapperNodeTemplate (): string', () => {
         randomGenerator = inversifyContainerFacade.get<IRandomGenerator>(ServiceIdentifiers.IRandomGenerator);
         randomGenerator = inversifyContainerFacade.get<IRandomGenerator>(ServiceIdentifiers.IRandomGenerator);
     });
     });
 
 
-    describe('variant #1: `base64` encoding', () => {
+    describe('Variant #1: `base64` encoding', () => {
         const index: string = '0x0';
         const index: string = '0x0';
         const expectedDecodedValue: string = 'test1';
         const expectedDecodedValue: string = 'test1';
 
 
@@ -72,7 +72,7 @@ describe('StringArrayCallsWrapperNodeTemplate (): string', () => {
         });
         });
     });
     });
 
 
-    describe('variant #2: `rc4` encoding', () => {
+    describe('Variant #2: `rc4` encoding', () => {
         const index: string = '0x0';
         const index: string = '0x0';
         const key: string = 'key';
         const key: string = 'key';
         const expectedDecodedValue: string = 'test1';
         const expectedDecodedValue: string = 'test1';

+ 1 - 1
test/runtime-tests/JavaScriptObfuscatorRuntime.spec.ts

@@ -30,7 +30,7 @@ describe('JavaScriptObfuscator runtime eval', function () {
         obfuscatedCode = obfuscationResult.getObfuscatedCode();
         obfuscatedCode = obfuscationResult.getObfuscatedCode();
     });
     });
 
 
-    it('should obfuscate code without any runtime errors after obfuscation: variant #1 sha256', () => {
+    it('should obfuscate code without any runtime errors after obfuscation: Variant #1 sha256', () => {
         assert.equal(
         assert.equal(
             eval(`${obfuscatedCode} sha256('test');`),
             eval(`${obfuscatedCode} sha256('test');`),
             '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'
             '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'

+ 4 - 4
test/unit-tests/analyzers/stack-trace-analyzer/StackTraceAnalyzer.spec.ts

@@ -6,7 +6,7 @@ describe('StackTraceAnalyzer', () => {
     describe('getLimitIndex (blockScopeBodyLength: number): number', () => {
     describe('getLimitIndex (blockScopeBodyLength: number): number', () => {
         let limitIndex: number;
         let limitIndex: number;
 
 
-        describe('variant #1: length - 10000', () => {
+        describe('Variant #1: length - 10000', () => {
             const blockScopeBodyLength: number = 10000;
             const blockScopeBodyLength: number = 10000;
             const expectedLimitIndex: number = 44;
             const expectedLimitIndex: number = 44;
 
 
@@ -19,7 +19,7 @@ describe('StackTraceAnalyzer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: length - 1000', () => {
+        describe('Variant #2: length - 1000', () => {
             const blockScopeBodyLength: number = 1000;
             const blockScopeBodyLength: number = 1000;
             const expectedLimitIndex: number = 26;
             const expectedLimitIndex: number = 26;
 
 
@@ -32,7 +32,7 @@ describe('StackTraceAnalyzer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: length - 25', () => {
+        describe('Variant #3: length - 25', () => {
             const blockScopeBodyLength: number = 25;
             const blockScopeBodyLength: number = 25;
             const expectedLimitIndex: number = 24;
             const expectedLimitIndex: number = 24;
 
 
@@ -45,7 +45,7 @@ describe('StackTraceAnalyzer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4: length - 5', () => {
+        describe('Variant #4: length - 5', () => {
             const blockScopeBodyLength: number = 5;
             const blockScopeBodyLength: number = 5;
             const expectedLimitIndex: number = 4;
             const expectedLimitIndex: number = 4;
 
 

+ 3 - 3
test/unit-tests/cli/sanitizers/ArraySanitizer.spec.ts

@@ -4,7 +4,7 @@ import { ArraySanitizer } from '../../../../src/cli/sanitizers/ArraySanitizer';
 
 
 describe('ArraySanitizer', () => {
 describe('ArraySanitizer', () => {
     describe('ArraySanitizer: TCLISanitizer = (value: string): string[]', () => {
     describe('ArraySanitizer: TCLISanitizer = (value: string): string[]', () => {
-        describe('variant #1: input value `foo`', () => {
+        describe('Variant #1: input value `foo`', () => {
             const inputValue: string = 'foo';
             const inputValue: string = 'foo';
             const expectedValue: string[] = ['foo'];
             const expectedValue: string[] = ['foo'];
 
 
@@ -19,7 +19,7 @@ describe('ArraySanitizer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: input value `foo, bar`', () => {
+        describe('Variant #2: input value `foo, bar`', () => {
             const inputValue: string = 'foo, bar';
             const inputValue: string = 'foo, bar';
             const expectedValue: string[] = ['foo', 'bar'];
             const expectedValue: string[] = ['foo', 'bar'];
 
 
@@ -34,7 +34,7 @@ describe('ArraySanitizer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: input value `foo,`', () => {
+        describe('Variant #3: input value `foo,`', () => {
             const inputValue: string = 'foo,';
             const inputValue: string = 'foo,';
 
 
             const testFunc: () => void = () => {
             const testFunc: () => void = () => {

+ 4 - 4
test/unit-tests/cli/sanitizers/BooleanSanitizer.spec.ts

@@ -5,7 +5,7 @@ import { BooleanSanitizer } from '../../../../src/cli/sanitizers/BooleanSanitize
 
 
 describe('BooleanSanitizer', () => {
 describe('BooleanSanitizer', () => {
     describe('BooleanSanitizer: TCLISanitizer = (value: string): boolean', () => {
     describe('BooleanSanitizer: TCLISanitizer = (value: string): boolean', () => {
-        describe('variant #1: input value `true`', () => {
+        describe('Variant #1: input value `true`', () => {
             const inputValue: string = 'true';
             const inputValue: string = 'true';
             const expectedValue: boolean = true;
             const expectedValue: boolean = true;
 
 
@@ -20,7 +20,7 @@ describe('BooleanSanitizer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: input value `1`', () => {
+        describe('Variant #2: input value `1`', () => {
             const inputValue: string = '1';
             const inputValue: string = '1';
             const expectedValue: boolean = true;
             const expectedValue: boolean = true;
 
 
@@ -35,7 +35,7 @@ describe('BooleanSanitizer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: input value `false`', () => {
+        describe('Variant #3: input value `false`', () => {
             const inputValue: string = 'false';
             const inputValue: string = 'false';
             const expectedValue: boolean = false;
             const expectedValue: boolean = false;
 
 
@@ -50,7 +50,7 @@ describe('BooleanSanitizer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4: input value `foo`', () => {
+        describe('Variant #4: input value `foo`', () => {
             const inputValue: string = 'foo';
             const inputValue: string = 'foo';
             const expectedValue: boolean = false;
             const expectedValue: boolean = false;
 
 

+ 2 - 2
test/unit-tests/cli/sanitizers/IdentifierNamesGeneratorSanitizer.spec.ts

@@ -4,7 +4,7 @@ import { IdentifierNamesGeneratorSanitizer } from '../../../../src/cli/sanitizer
 
 
 describe('IdentifierNamesGeneratorSanitizer', () => {
 describe('IdentifierNamesGeneratorSanitizer', () => {
     describe('IdentifierNamesGeneratorSanitizer: TCLISanitizer = (value: string): string', () => {
     describe('IdentifierNamesGeneratorSanitizer: TCLISanitizer = (value: string): string', () => {
-        describe('variant #1: valid identifier names generator', () => {
+        describe('Variant #1: valid identifier names generator', () => {
             const inputValue: string = 'mangled';
             const inputValue: string = 'mangled';
             const expectedValue: string = inputValue;
             const expectedValue: string = inputValue;
 
 
@@ -19,7 +19,7 @@ describe('IdentifierNamesGeneratorSanitizer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: invalid identifier names generator', () => {
+        describe('Variant #2: invalid identifier names generator', () => {
             const inputValue: string = 'foo';
             const inputValue: string = 'foo';
 
 
             let testFunc: () => void;
             let testFunc: () => void;

+ 2 - 2
test/unit-tests/cli/sanitizers/ObfuscationTargetSanitizer.spec.ts

@@ -4,7 +4,7 @@ import { ObfuscationTargetSanitizer } from '../../../../src/cli/sanitizers/Obfus
 
 
 describe('ObfuscationTargetSanitizer', () => {
 describe('ObfuscationTargetSanitizer', () => {
     describe('ObfuscationTargetSanitizer: TCLISanitizer = (value: string): string', () => {
     describe('ObfuscationTargetSanitizer: TCLISanitizer = (value: string): string', () => {
-        describe('variant #1: valid obfuscation target', () => {
+        describe('Variant #1: valid obfuscation target', () => {
             const inputValue: string = 'browser';
             const inputValue: string = 'browser';
             const expectedValue: string = inputValue;
             const expectedValue: string = inputValue;
 
 
@@ -19,7 +19,7 @@ describe('ObfuscationTargetSanitizer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: invalid obfuscation target', () => {
+        describe('Variant #2: invalid obfuscation target', () => {
             const inputValue: string = 'foo';
             const inputValue: string = 'foo';
 
 
             let testFunc: () => void;
             let testFunc: () => void;

+ 2 - 2
test/unit-tests/cli/sanitizers/SourceMapModeSanitizer.spec.ts

@@ -4,7 +4,7 @@ import { SourceMapModeSanitizer } from '../../../../src/cli/sanitizers/SourceMap
 
 
 describe('SourceMapModeSanitizer', () => {
 describe('SourceMapModeSanitizer', () => {
     describe('SourceMapModeSanitizer: TCLISanitizer = (value: string): string', () => {
     describe('SourceMapModeSanitizer: TCLISanitizer = (value: string): string', () => {
-        describe('variant #1: valid source map mode', () => {
+        describe('Variant #1: valid source map mode', () => {
             const inputValue: string = 'inline';
             const inputValue: string = 'inline';
             const expectedValue: string = inputValue;
             const expectedValue: string = inputValue;
 
 
@@ -19,7 +19,7 @@ describe('SourceMapModeSanitizer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: invalid source map mode', () => {
+        describe('Variant #2: invalid source map mode', () => {
             const inputValue: string = 'foo';
             const inputValue: string = 'foo';
 
 
             let testFunc: () => void;
             let testFunc: () => void;

+ 5 - 5
test/unit-tests/cli/sanitizers/StringArrayEncodingSanitizer.spec.ts

@@ -8,7 +8,7 @@ import { StringArrayEncodingSanitizer } from '../../../../src/cli/sanitizers/Str
 
 
 describe('StringArrayEncodingSanitizer', () => {
 describe('StringArrayEncodingSanitizer', () => {
     describe('StringArrayEncodingSanitizer: TCLISanitizer = (value: string): TStringArrayEncoding', () => {
     describe('StringArrayEncodingSanitizer: TCLISanitizer = (value: string): TStringArrayEncoding', () => {
-        describe('variant #1: string array encoding `base64`', () => {
+        describe('Variant #1: string array encoding `base64`', () => {
             const inputValue: string = 'base64';
             const inputValue: string = 'base64';
             const expectedValue: TStringArrayEncoding = true;
             const expectedValue: TStringArrayEncoding = true;
 
 
@@ -23,7 +23,7 @@ describe('StringArrayEncodingSanitizer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: string array encoding `true`', () => {
+        describe('Variant #2: string array encoding `true`', () => {
             const inputValue: string = 'true';
             const inputValue: string = 'true';
             const expectedValue: TStringArrayEncoding = true;
             const expectedValue: TStringArrayEncoding = true;
 
 
@@ -38,7 +38,7 @@ describe('StringArrayEncodingSanitizer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: string array encoding `1`', () => {
+        describe('Variant #3: string array encoding `1`', () => {
             const inputValue: string = '1';
             const inputValue: string = '1';
             const expectedValue: TStringArrayEncoding = true;
             const expectedValue: TStringArrayEncoding = true;
 
 
@@ -53,7 +53,7 @@ describe('StringArrayEncodingSanitizer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4: string array encoding `rc4`', () => {
+        describe('Variant #4: string array encoding `rc4`', () => {
             const inputValue: string = 'rc4';
             const inputValue: string = 'rc4';
             const expectedValue: TStringArrayEncoding = StringArrayEncoding.Rc4;
             const expectedValue: TStringArrayEncoding = StringArrayEncoding.Rc4;
 
 
@@ -68,7 +68,7 @@ describe('StringArrayEncodingSanitizer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #5: string array encoding `foo`', () => {
+        describe('Variant #5: string array encoding `foo`', () => {
             const inputValue: string = 'foo';
             const inputValue: string = 'foo';
             const expectedValue: TStringArrayEncoding = false;
             const expectedValue: TStringArrayEncoding = false;
 
 

+ 6 - 6
test/unit-tests/cli/utils/CLIUtils.spec.ts

@@ -6,7 +6,7 @@ import { CLIUtils } from '../../../../src/cli/utils/CLIUtils';
 
 
 describe('CLIUtils', () => {
 describe('CLIUtils', () => {
     describe('getOutputCodePath (inputPath: string): string', () => {
     describe('getOutputCodePath (inputPath: string): string', () => {
-        describe('variant #1: base input path', () => {
+        describe('Variant #1: base input path', () => {
             let expectedOutputPath: string = 'test/input/test-obfuscated.js',
             let expectedOutputPath: string = 'test/input/test-obfuscated.js',
                 inputPath: string = 'test/input/test.js';
                 inputPath: string = 'test/input/test.js';
 
 
@@ -15,7 +15,7 @@ describe('CLIUtils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: relative input path with dot', () => {
+        describe('Variant #2: relative input path with dot', () => {
             let expectedOutputPath: string = 'input-obfuscated.js',
             let expectedOutputPath: string = 'input-obfuscated.js',
                 inputPath: string = './input.js';
                 inputPath: string = './input.js';
 
 
@@ -35,8 +35,8 @@ describe('CLIUtils', () => {
     });
     });
 
 
     describe('getUserConfig (configPath: string): Object', () => {
     describe('getUserConfig (configPath: string): Object', () => {
-        describe('variant #1: valid config file path', () => {
-            describe('variant #1: js file with config', () => {
+        describe('Variant #1: valid config file path', () => {
+            describe('Variant #1: js file with config', () => {
                 const configDirName: string = 'test/fixtures';
                 const configDirName: string = 'test/fixtures';
                 const configFileName: string = 'config.js';
                 const configFileName: string = 'config.js';
                 const configFilePath: string = `../../../${configDirName}/${configFileName}`;
                 const configFilePath: string = `../../../${configDirName}/${configFileName}`;
@@ -57,7 +57,7 @@ describe('CLIUtils', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: json file with config', () => {
+            describe('Variant #2: json file with config', () => {
                 const configDirName: string = 'test/fixtures';
                 const configDirName: string = 'test/fixtures';
                 const configFileName: string = 'config.json';
                 const configFileName: string = 'config.json';
                 const configFilePath: string = `../../../${configDirName}/${configFileName}`;
                 const configFilePath: string = `../../../${configDirName}/${configFileName}`;
@@ -79,7 +79,7 @@ describe('CLIUtils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: invalid config file path', () => {
+        describe('Variant #2: invalid config file path', () => {
             const configDirName: string = 'test/fixtures';
             const configDirName: string = 'test/fixtures';
             const configFileName: string = 'configs.js';
             const configFileName: string = 'configs.js';
             const configFilePath: string = `../../../${configDirName}/${configFileName}`;
             const configFilePath: string = `../../../${configDirName}/${configFileName}`;

+ 335 - 16
test/unit-tests/cli/utils/SourceCodeReader.spec.ts

@@ -10,6 +10,7 @@ import { IFileData } from '../../../../src/interfaces/cli/IFileData';
 import { SourceCodeReader } from '../../../../src/cli/utils/SourceCodeReader';
 import { SourceCodeReader } from '../../../../src/cli/utils/SourceCodeReader';
 
 
 describe('SourceCodeReader', () => {
 describe('SourceCodeReader', () => {
+    const expectedError: RegExp = /Given input path must be a valid/;
     const fileContent: string = 'test';
     const fileContent: string = 'test';
     const tmpDirectoryPath: string = 'test/tmp';
     const tmpDirectoryPath: string = 'test/tmp';
 
 
@@ -19,7 +20,7 @@ describe('SourceCodeReader', () => {
 
 
     describe('readSourceCode (inputPath: string): void', () => {
     describe('readSourceCode (inputPath: string): void', () => {
         describe('Variant #1: input path is a file path', () => {
         describe('Variant #1: input path is a file path', () => {
-            describe('`inputPath` is a valid path', () => {
+            describe('Variant #1: `inputPath` is a valid path', () => {
                 const tmpFileName: string = 'test.js';
                 const tmpFileName: string = 'test.js';
                 const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;
                 const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;
 
 
@@ -27,7 +28,7 @@ describe('SourceCodeReader', () => {
 
 
                 before(() => {
                 before(() => {
                     fs.writeFileSync(inputPath, fileContent);
                     fs.writeFileSync(inputPath, fileContent);
-                    result = SourceCodeReader.readSourceCode(inputPath);
+                    result = new SourceCodeReader({}).readSourceCode(inputPath);
                 });
                 });
 
 
                 it('should return content of file', () => {
                 it('should return content of file', () => {
@@ -39,22 +40,22 @@ describe('SourceCodeReader', () => {
                 });
                 });
             });
             });
 
 
-            describe('`inputPath` is not a valid path', () => {
+            describe('Variant #2: `inputPath` is not a valid path', () => {
                 const tmpFileName: string = 'test.js';
                 const tmpFileName: string = 'test.js';
                 const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;
                 const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;
 
 
                 let testFunc: () => void;
                 let testFunc: () => void;
 
 
                 before(() => {
                 before(() => {
-                    testFunc = () => SourceCodeReader.readSourceCode(inputPath);
+                    testFunc = () => new SourceCodeReader({}).readSourceCode(inputPath);
                 });
                 });
 
 
                 it('should throw an error if `inputPath` is not a valid path', () => {
                 it('should throw an error if `inputPath` is not a valid path', () => {
-                    assert.throws(testFunc, ReferenceError);
+                    assert.throws(testFunc, expectedError);
                 });
                 });
             });
             });
 
 
-            describe('`inputPath` has invalid extension', () => {
+            describe('Variant #3: `inputPath` has invalid extension', () => {
                 const tmpFileName: string = 'test.ts';
                 const tmpFileName: string = 'test.ts';
                 const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;
                 const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;
 
 
@@ -62,21 +63,112 @@ describe('SourceCodeReader', () => {
 
 
                 before(() => {
                 before(() => {
                     fs.writeFileSync(inputPath, fileContent);
                     fs.writeFileSync(inputPath, fileContent);
-                    testFunc = () => SourceCodeReader.readSourceCode(inputPath);
+                    testFunc = () => new SourceCodeReader({}).readSourceCode(inputPath);
                 });
                 });
 
 
                 it('should throw an error if `inputPath` has invalid extension', () => {
                 it('should throw an error if `inputPath` has invalid extension', () => {
-                    assert.throws(testFunc, ReferenceError);
+                    assert.throws(testFunc, expectedError);
                 });
                 });
 
 
                 after(() => {
                 after(() => {
                     fs.unlinkSync(inputPath);
                     fs.unlinkSync(inputPath);
                 });
                 });
             });
             });
+
+            describe('Variant #4: `exclude` option', () => {
+                describe('Variant #1: `inputPath` isn\'t excluded path', () => {
+                    const tmpFileName: string = 'test.js';
+                    const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;
+
+                    let result: string | IFileData[];
+
+                    before(() => {
+                        fs.writeFileSync(inputPath, fileContent);
+                        result = new SourceCodeReader({
+                            exclude: ['**/foo.js']
+                        }).readSourceCode(inputPath);                });
+
+                    it('should return content of file', () => {
+                        assert.equal(result, fileContent);
+                    });
+
+                    after(() => {
+                        fs.unlinkSync(inputPath);
+                    });
+                });
+
+                describe('Variant #2: `inputPath` is excluded path', () => {
+                    describe('Variant #1: exclude by `glob` pattern', () => {
+                        const tmpFileName: string = 'test.js';
+                        const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;
+
+                        let testFunc: () => void;
+
+                        before(() => {
+                            fs.writeFileSync(inputPath, fileContent);
+                            testFunc = () => new SourceCodeReader({
+                                exclude: [`**/${tmpFileName}`]
+                            }).readSourceCode(inputPath);
+                        });
+
+                        it('should throw an error if `inputPath` is the excluded file path', () => {
+                            assert.throws(testFunc, expectedError);
+                        });
+
+                        after(() => {
+                            fs.unlinkSync(inputPath);
+                        });
+                    });
+
+                    describe('Variant #2: exclude by file name', () => {
+                        const tmpFileName: string = 'test.js';
+                        const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;
+
+                        let testFunc: () => void;
+
+                        before(() => {
+                            fs.writeFileSync(inputPath, fileContent);
+                            testFunc = () => new SourceCodeReader({
+                                exclude: [tmpFileName]
+                            }).readSourceCode(inputPath);
+                        });
+
+                        it('should throw an error if `inputPath` is the excluded file path', () => {
+                            assert.throws(testFunc, expectedError);
+                        });
+
+                        after(() => {
+                            fs.unlinkSync(inputPath);
+                        });
+                    });
+
+                    describe('Variant #3: exclude by file path', () => {
+                        const tmpFileName: string = 'test.js';
+                        const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;
+
+                        let testFunc: () => void;
+
+                        before(() => {
+                            fs.writeFileSync(inputPath, fileContent);
+                            testFunc = () => new SourceCodeReader({
+                                exclude: [inputPath]
+                            }).readSourceCode(inputPath);
+                        });
+
+                        it('should throw an error if `inputPath` is the excluded file path', () => {
+                            assert.throws(testFunc, expectedError);
+                        });
+
+                        after(() => {
+                            fs.unlinkSync(inputPath);
+                        });
+                    });
+                });
+            });
         });
         });
 
 
         describe('Variant #2: input path is a directory path', () => {
         describe('Variant #2: input path is a directory path', () => {
-            describe('`inputPath` is a valid path', () => {
+            describe('Variant #1: `inputPath` is a valid path', () => {
                 const tmpFileName1: string = 'foo.js';
                 const tmpFileName1: string = 'foo.js';
                 const tmpFileName2: string = 'bar.js';
                 const tmpFileName2: string = 'bar.js';
                 const tmpFileName3: string = 'baz.png';
                 const tmpFileName3: string = 'baz.png';
@@ -104,7 +196,7 @@ describe('SourceCodeReader', () => {
                     fs.writeFileSync(filePath2, fileContent);
                     fs.writeFileSync(filePath2, fileContent);
                     fs.writeFileSync(filePath3, fileContent);
                     fs.writeFileSync(filePath3, fileContent);
                     fs.writeFileSync(filePath4, fileContent);
                     fs.writeFileSync(filePath4, fileContent);
-                    result = SourceCodeReader.readSourceCode(tmpDirectoryPath);
+                    result = new SourceCodeReader({}).readSourceCode(tmpDirectoryPath);
                 });
                 });
 
 
                 it('should return files data', () => {
                 it('should return files data', () => {
@@ -119,21 +211,21 @@ describe('SourceCodeReader', () => {
                 });
                 });
             });
             });
 
 
-            describe('`inputPath` is not a valid path', () => {
+            describe('Variant #2: `inputPath` is not a valid path', () => {
                 const inputPath: string = 'abc';
                 const inputPath: string = 'abc';
 
 
                 let testFunc: () => void;
                 let testFunc: () => void;
 
 
                 before(() => {
                 before(() => {
-                    testFunc = () => SourceCodeReader.readSourceCode(inputPath);
+                    testFunc = () => new SourceCodeReader({}).readSourceCode(inputPath);
                 });
                 });
 
 
                 it('should throw an error if `inputPath` is not a valid path', () => {
                 it('should throw an error if `inputPath` is not a valid path', () => {
-                    assert.throws(testFunc, ReferenceError);
+                    assert.throws(testFunc, expectedError);
                 });
                 });
             });
             });
 
 
-            describe('`inputPath` is a directory with sub-directories', () => {
+            describe('Variant #3: `inputPath` is a directory with sub-directories', () => {
                 const parentDirectoryName1: string = 'parent1';
                 const parentDirectoryName1: string = 'parent1';
                 const parentDirectoryName2: string = 'parent';
                 const parentDirectoryName2: string = 'parent';
                 const parentDirectoryPath1: string = `${tmpDirectoryPath}/${parentDirectoryName1}`;
                 const parentDirectoryPath1: string = `${tmpDirectoryPath}/${parentDirectoryName1}`;
@@ -175,7 +267,7 @@ describe('SourceCodeReader', () => {
                     fs.writeFileSync(filePath2, fileContent);
                     fs.writeFileSync(filePath2, fileContent);
                     fs.writeFileSync(filePath3, fileContent);
                     fs.writeFileSync(filePath3, fileContent);
                     fs.writeFileSync(filePath4, fileContent);
                     fs.writeFileSync(filePath4, fileContent);
-                    result = SourceCodeReader.readSourceCode(tmpDirectoryPath);
+                    result = new SourceCodeReader({}).readSourceCode(tmpDirectoryPath);
                 });
                 });
 
 
                 it('should return files data', () => {
                 it('should return files data', () => {
@@ -191,6 +283,233 @@ describe('SourceCodeReader', () => {
                     rimraf.sync(parentDirectoryPath2);
                     rimraf.sync(parentDirectoryPath2);
                 });
                 });
             });
             });
+
+            describe('Variant #4: `exclude` option', () => {
+                describe('Variant #1: `inputPath` isn\'t excluded path', () => {
+                    const tmpFileName1: string = 'foo.js';
+                    const tmpFileName2: string = 'bar.js';
+                    const tmpFileName3: string = 'baz.png';
+                    const tmpFileName4: string = 'bark-obfuscated.js';
+                    const filePath1: string = `${tmpDirectoryPath}/${tmpFileName1}`;
+                    const filePath2: string = `${tmpDirectoryPath}/${tmpFileName2}`;
+                    const filePath3: string = `${tmpDirectoryPath}/${tmpFileName3}`;
+                    const filePath4: string = `${tmpDirectoryPath}/${tmpFileName4}`;
+
+                    const expectedResult: IFileData[] = [
+                        {
+                            filePath: filePath2,
+                            content: fileContent
+                        },
+                        {
+                            filePath: filePath1,
+                            content: fileContent
+                        }
+                    ];
+
+                    let result: string | IFileData[];
+
+                    before(() => {
+                        fs.writeFileSync(filePath1, fileContent);
+                        fs.writeFileSync(filePath2, fileContent);
+                        fs.writeFileSync(filePath3, fileContent);
+                        fs.writeFileSync(filePath4, fileContent);
+                        result = new SourceCodeReader({
+                            exclude: ['**/hawk.js']
+                        }).readSourceCode(tmpDirectoryPath);
+                    });
+
+                    it('should return files data', () => {
+                        assert.deepEqual(result, expectedResult);
+                    });
+
+                    after(() => {
+                        fs.unlinkSync(filePath1);
+                        fs.unlinkSync(filePath2);
+                        fs.unlinkSync(filePath3);
+                        fs.unlinkSync(filePath4);
+                    });
+                });
+
+                describe('Variant #2: `inputPath` is excluded path', () => {
+                    describe('Variant #1: exclude by `glob` pattern', () => {
+                        const tmpFileName1: string = 'foo.js';
+                        const tmpFileName2: string = 'bar.js';
+                        const tmpFileName3: string = 'baz.js';
+                        const tmpFileName4: string = 'bark.js';
+                        const filePath1: string = `${tmpDirectoryPath}/${tmpFileName1}`;
+                        const filePath2: string = `${tmpDirectoryPath}/${tmpFileName2}`;
+                        const filePath3: string = `${tmpDirectoryPath}/${tmpFileName3}`;
+                        const filePath4: string = `${tmpDirectoryPath}/${tmpFileName4}`;
+
+                        const expectedResult: IFileData[] = [
+                            {
+                                filePath: filePath3,
+                                content: fileContent
+                            },
+                            {
+                                filePath: filePath1,
+                                content: fileContent
+                            }
+                        ];
+
+                        let result: string | IFileData[];
+
+                        before(() => {
+                            fs.writeFileSync(filePath1, fileContent);
+                            fs.writeFileSync(filePath2, fileContent);
+                            fs.writeFileSync(filePath3, fileContent);
+                            fs.writeFileSync(filePath4, fileContent);
+                            result = new SourceCodeReader({
+                                exclude: [
+                                    `**/${tmpFileName2}`,
+                                    `**/${tmpFileName4}`
+                                ]
+                            }).readSourceCode(tmpDirectoryPath);
+                        });
+
+                        it('should return files data', () => {
+                            assert.deepEqual(result, expectedResult);
+                        });
+
+                        after(() => {
+                            fs.unlinkSync(filePath1);
+                            fs.unlinkSync(filePath2);
+                            fs.unlinkSync(filePath3);
+                            fs.unlinkSync(filePath4);
+                        });
+                    });
+
+                    describe('Variant #2: exclude by file name', () => {
+                        const tmpFileName1: string = 'foo.js';
+                        const tmpFileName2: string = 'bar.js';
+                        const tmpFileName3: string = 'baz.js';
+                        const tmpFileName4: string = 'bark.js';
+                        const filePath1: string = `${tmpDirectoryPath}/${tmpFileName1}`;
+                        const filePath2: string = `${tmpDirectoryPath}/${tmpFileName2}`;
+                        const filePath3: string = `${tmpDirectoryPath}/${tmpFileName3}`;
+                        const filePath4: string = `${tmpDirectoryPath}/${tmpFileName4}`;
+
+                        const expectedResult: IFileData[] = [
+                            {
+                                filePath: filePath3,
+                                content: fileContent
+                            },
+                            {
+                                filePath: filePath1,
+                                content: fileContent
+                            }
+                        ];
+
+                        let result: string | IFileData[];
+
+                        before(() => {
+                            fs.writeFileSync(filePath1, fileContent);
+                            fs.writeFileSync(filePath2, fileContent);
+                            fs.writeFileSync(filePath3, fileContent);
+                            fs.writeFileSync(filePath4, fileContent);
+                            result = new SourceCodeReader({
+                                exclude: [
+                                    tmpFileName2,
+                                    tmpFileName4
+                                ]
+                            }).readSourceCode(tmpDirectoryPath);
+                        });
+
+                        it('should return files data', () => {
+                            assert.deepEqual(result, expectedResult);
+                        });
+
+                        after(() => {
+                            fs.unlinkSync(filePath1);
+                            fs.unlinkSync(filePath2);
+                            fs.unlinkSync(filePath3);
+                            fs.unlinkSync(filePath4);
+                        });
+                    });
+
+                    describe('Variant #3: exclude by file path', () => {
+                        const tmpFileName1: string = 'foo.js';
+                        const tmpFileName2: string = 'bar.js';
+                        const tmpFileName3: string = 'baz.js';
+                        const tmpFileName4: string = 'bark.js';
+                        const filePath1: string = `${tmpDirectoryPath}/${tmpFileName1}`;
+                        const filePath2: string = `${tmpDirectoryPath}/${tmpFileName2}`;
+                        const filePath3: string = `${tmpDirectoryPath}/${tmpFileName3}`;
+                        const filePath4: string = `${tmpDirectoryPath}/${tmpFileName4}`;
+
+                        const expectedResult: IFileData[] = [
+                            {
+                                filePath: filePath3,
+                                content: fileContent
+                            },
+                            {
+                                filePath: filePath1,
+                                content: fileContent
+                            }
+                        ];
+
+                        let result: string | IFileData[];
+
+                        before(() => {
+                            fs.writeFileSync(filePath1, fileContent);
+                            fs.writeFileSync(filePath2, fileContent);
+                            fs.writeFileSync(filePath3, fileContent);
+                            fs.writeFileSync(filePath4, fileContent);
+                            result = new SourceCodeReader({
+                                exclude: [
+                                    filePath2,
+                                    filePath4
+                                ]
+                            }).readSourceCode(tmpDirectoryPath);
+                        });
+
+                        it('should return files data', () => {
+                            assert.deepEqual(result, expectedResult);
+                        });
+
+                        after(() => {
+                            fs.unlinkSync(filePath1);
+                            fs.unlinkSync(filePath2);
+                            fs.unlinkSync(filePath3);
+                            fs.unlinkSync(filePath4);
+                        });
+                    });
+
+                    describe('Variant #4: exclude whole directory', () => {
+                        const tmpFileName1: string = 'foo.js';
+                        const tmpFileName2: string = 'bar.js';
+                        const tmpFileName3: string = 'baz.js';
+                        const tmpFileName4: string = 'bark.js';
+                        const filePath1: string = `${tmpDirectoryPath}/${tmpFileName1}`;
+                        const filePath2: string = `${tmpDirectoryPath}/${tmpFileName2}`;
+                        const filePath3: string = `${tmpDirectoryPath}/${tmpFileName3}`;
+                        const filePath4: string = `${tmpDirectoryPath}/${tmpFileName4}`;
+
+                        let testFunc: () => void;
+
+                        before(() => {
+                            fs.writeFileSync(filePath1, fileContent);
+                            fs.writeFileSync(filePath2, fileContent);
+                            fs.writeFileSync(filePath3, fileContent);
+                            fs.writeFileSync(filePath4, fileContent);
+                            testFunc = () => new SourceCodeReader({
+                                exclude: [tmpDirectoryPath]
+                            }).readSourceCode(tmpDirectoryPath);
+                        });
+
+                        it('should return files data', () => {
+                            assert.throws(testFunc, expectedError);
+                        });
+
+                        after(() => {
+                            fs.unlinkSync(filePath1);
+                            fs.unlinkSync(filePath2);
+                            fs.unlinkSync(filePath3);
+                            fs.unlinkSync(filePath4);
+                        });
+                    });
+                });
+            });
         });
         });
 
 
         describe('Variant #3: logging', () => {
         describe('Variant #3: logging', () => {
@@ -207,7 +526,7 @@ describe('SourceCodeReader', () => {
                 consoleLogSpy = sinon.spy(console, 'log');
                 consoleLogSpy = sinon.spy(console, 'log');
 
 
                 fs.writeFileSync(inputPath, fileContent);
                 fs.writeFileSync(inputPath, fileContent);
-                SourceCodeReader.readSourceCode(inputPath);
+                new SourceCodeReader({}).readSourceCode(inputPath);
 
 
                 consoleLogCallResult = consoleLogSpy.called;
                 consoleLogCallResult = consoleLogSpy.called;
                 loggingMessageResult = consoleLogSpy.getCall(0).args[0];
                 loggingMessageResult = consoleLogSpy.getCall(0).args[0];

+ 9 - 9
test/unit-tests/decorators/initializable/Initializable.spec.ts

@@ -7,7 +7,7 @@ import { IInitializable } from '../../../../src/interfaces/IInitializable';
 
 
 describe('@initializable', () => {
 describe('@initializable', () => {
     describe('initializable (initializeMethodKey: string): any', () => {
     describe('initializable (initializeMethodKey: string): any', () => {
-        describe('variant #1: property was initialized', () => {
+        describe('Variant #1: property was initialized', () => {
             const testFunc: () => void = () => {
             const testFunc: () => void = () => {
                 class Foo implements IInitializable {
                 class Foo implements IInitializable {
                     @initializable()
                     @initializable()
@@ -30,8 +30,8 @@ describe('@initializable', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: `initialize` method should be called first', () => {
-            describe('variant #1: `initialize` method was called first', () => {
+        describe('Variant #2: `initialize` method should be called first', () => {
+            describe('Variant #1: `initialize` method was called first', () => {
                 const testFunc: () => void = () => {
                 const testFunc: () => void = () => {
                     class Foo {
                     class Foo {
                         @initializable()
                         @initializable()
@@ -55,7 +55,7 @@ describe('@initializable', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: other method was called inside `initialize` method with initialization of the property', () => {
+            describe('Variant #2: other method was called inside `initialize` method with initialization of the property', () => {
                 const testFunc: () => void = () => {
                 const testFunc: () => void = () => {
                     class Foo {
                     class Foo {
                         @initializable()
                         @initializable()
@@ -80,7 +80,7 @@ describe('@initializable', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #3: other method was called inside `initialize` method without initialization of the property', () => {
+            describe('Variant #3: other method was called inside `initialize` method without initialization of the property', () => {
                 const testFunc: () => void = () => {
                 const testFunc: () => void = () => {
                     class Foo {
                     class Foo {
                         @initializable()
                         @initializable()
@@ -104,7 +104,7 @@ describe('@initializable', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #4: `initialize` method wasn\'t called first', () => {
+            describe('Variant #4: `initialize` method wasn\'t called first', () => {
                 const testFunc: () => void = () => {
                 const testFunc: () => void = () => {
                     class Foo {
                     class Foo {
                         @initializable()
                         @initializable()
@@ -128,7 +128,7 @@ describe('@initializable', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #5: `initialize` method wasn\'t called', () => {
+            describe('Variant #5: `initialize` method wasn\'t called', () => {
                 const testFunc: () => void = () => {
                 const testFunc: () => void = () => {
                     class Foo {
                     class Foo {
                         @initializable()
                         @initializable()
@@ -152,7 +152,7 @@ describe('@initializable', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: property didn\'t initialized', () => {
+        describe('Variant #3: property didn\'t initialized', () => {
             const testFunc: () => void = () => {
             const testFunc: () => void = () => {
                 class Foo implements IInitializable {
                 class Foo implements IInitializable {
                     @initializable()
                     @initializable()
@@ -174,7 +174,7 @@ describe('@initializable', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4: `initialize` method with custom name', () => {
+        describe('Variant #4: `initialize` method with custom name', () => {
             const testFunc: () => void = () => {
             const testFunc: () => void = () => {
                 class Foo {
                 class Foo {
                     @initializable('bar')
                     @initializable('bar')

+ 8 - 8
test/unit-tests/generators/identifier-names-generators/MangledlIdentifierNamesGenerator.spec.ts

@@ -26,7 +26,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             );
             );
         });
         });
 
 
-        describe('variant #1: initial mangled name', () => {
+        describe('Variant #1: initial mangled name', () => {
             const expectedMangledIdentifierName: string = 'a';
             const expectedMangledIdentifierName: string = 'a';
 
 
             beforeEach(() => {
             beforeEach(() => {
@@ -38,7 +38,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: second mangled name', () => {
+        describe('Variant #2: second mangled name', () => {
             const expectedMangledIdentifierName: string = 'b';
             const expectedMangledIdentifierName: string = 'b';
             const expectedMangledIdentifierPosition: number = 1;
             const expectedMangledIdentifierPosition: number = 1;
 
 
@@ -53,7 +53,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: last mangled name with single character', () => {
+        describe('Variant #3: last mangled name with single character', () => {
             const expectedMangledIdentifierName: string = 'Z';
             const expectedMangledIdentifierName: string = 'Z';
             const expectedMangledIdentifierPosition: number = 51;
             const expectedMangledIdentifierPosition: number = 51;
 
 
@@ -68,7 +68,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4: correct increase of mangled name length', () => {
+        describe('Variant #4: correct increase of mangled name length', () => {
             const expectedMangledIdentifierName: string = 'a0';
             const expectedMangledIdentifierName: string = 'a0';
             const expectedMangledIdentifierPosition: number = 52;
             const expectedMangledIdentifierPosition: number = 52;
 
 
@@ -83,7 +83,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             });
             });
         });
         });
 
 
-        describe('variant #5: correct increase of mangled name length #2', () => {
+        describe('Variant #5: correct increase of mangled name length #2', () => {
             const expectedMangledIdentifierName: string = 'aa';
             const expectedMangledIdentifierName: string = 'aa';
             const expectedMangledIdentifierPosition: number = 62;
             const expectedMangledIdentifierPosition: number = 62;
 
 
@@ -98,7 +98,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             });
             });
         });
         });
 
 
-        describe('variant #6: reserved names', () => {
+        describe('Variant #6: reserved names', () => {
             const expectedMangledIdentifierName1: string = 'dn';
             const expectedMangledIdentifierName1: string = 'dn';
             const expectedMangledIdentifierName2: string = 'dp';
             const expectedMangledIdentifierName2: string = 'dp';
             const expectedMangledIdentifierPosition1: number = 261;
             const expectedMangledIdentifierPosition1: number = 261;
@@ -145,7 +145,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             );
             );
         });
         });
 
 
-        describe('variant #1: initial mangled name', () => {
+        describe('Variant #1: initial mangled name', () => {
             const expectedMangledIdentifierName: string = 'foo_a';
             const expectedMangledIdentifierName: string = 'foo_a';
 
 
             beforeEach(() => {
             beforeEach(() => {
@@ -157,7 +157,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: second mangled name', () => {
+        describe('Variant #2: second mangled name', () => {
             const expectedMangledIdentifierName: string = 'foo_b';
             const expectedMangledIdentifierName: string = 'foo_b';
 
 
             beforeEach(() => {
             beforeEach(() => {

+ 2 - 2
test/unit-tests/javascript-obfuscator/EsprimaFacade.spec.ts

@@ -5,7 +5,7 @@ import { EsprimaFacade } from '../../../src/EsprimaFacade';
 describe('EsprimaFacade', () => {
 describe('EsprimaFacade', () => {
     describe(`parseScript (input: string, config: esprima.ParseOptions): ESTree.Program`, () => {
     describe(`parseScript (input: string, config: esprima.ParseOptions): ESTree.Program`, () => {
         describe(`\`Unexpected token\` error code preview`, () => {
         describe(`\`Unexpected token\` error code preview`, () => {
-            describe('variant #1: 5 lines of code', () => {
+            describe('Variant #1: 5 lines of code', () => {
                 const sourceCode: string = `` +
                 const sourceCode: string = `` +
                 `var foo = 1;
                 `var foo = 1;
                 var bar = 2;
                 var bar = 2;
@@ -24,7 +24,7 @@ describe('EsprimaFacade', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: 15 lines of code', () => {
+            describe('Variant #2: 15 lines of code', () => {
                 const sourceCode: string = `` +
                 const sourceCode: string = `` +
                 `var var1 = 1;
                 `var var1 = 1;
                 var var2 = 2;
                 var var2 = 2;

+ 2 - 2
test/unit-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts

@@ -18,7 +18,7 @@ describe('JavaScriptObfuscator', () => {
 
 
             let javaScriptObfuscator: IJavaScriptObfuscator;
             let javaScriptObfuscator: IJavaScriptObfuscator;
 
 
-            describe('variant #1: default behaviour', () => {
+            describe('Variant #1: default behaviour', () => {
                 const regExp: RegExp = new RegExp(`sourceMappingURL=${sourceMapUrl}`);
                 const regExp: RegExp = new RegExp(`sourceMappingURL=${sourceMapUrl}`);
 
 
                 let obfuscatedCode: string,
                 let obfuscatedCode: string,
@@ -53,7 +53,7 @@ describe('JavaScriptObfuscator', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: `sourceMapBaseUrl` is set', () => {
+            describe('Variant #2: `sourceMapBaseUrl` is set', () => {
                 const sourceMapBaseUrl: string = 'http://localhost:9000';
                 const sourceMapBaseUrl: string = 'http://localhost:9000';
                 const regExp: RegExp = new RegExp(`sourceMappingURL=${sourceMapBaseUrl}/${sourceMapUrl}$`);
                 const regExp: RegExp = new RegExp(`sourceMappingURL=${sourceMapBaseUrl}/${sourceMapUrl}$`);
 
 

+ 2 - 2
test/unit-tests/node-transformers/preparing-transformers/ObfuscatingGuardsTransformer.spec.ts

@@ -27,7 +27,7 @@ describe('ObfuscatingGuardsTransformer', () => {
                 .getNamed(ServiceIdentifiers.INodeTransformer, NodeTransformer.ObfuscatingGuardsTransformer);
                 .getNamed(ServiceIdentifiers.INodeTransformer, NodeTransformer.ObfuscatingGuardsTransformer);
         });
         });
 
 
-        describe('variant #1: valid node', () => {
+        describe('Variant #1: valid node', () => {
             const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
             const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
 
 
             const expectedResult: ESTree.Identifier = NodeUtils.clone(identifier);
             const expectedResult: ESTree.Identifier = NodeUtils.clone(identifier);
@@ -47,7 +47,7 @@ describe('ObfuscatingGuardsTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: invalid node', () => {
+        describe('Variant #2: invalid node', () => {
             const expressionStatement: ESTree.ExpressionStatement = Nodes.getExpressionStatementNode(
             const expressionStatement: ESTree.ExpressionStatement = Nodes.getExpressionStatementNode(
                 Nodes.getIdentifierNode('foo')
                 Nodes.getIdentifierNode('foo')
             );
             );

+ 5 - 5
test/unit-tests/node/node-appender/NodeAppender.spec.ts

@@ -78,7 +78,7 @@ describe('NodeAppender', () => {
             node = convertCodeToStructure('/fixtures/simple-input.js');
             node = convertCodeToStructure('/fixtures/simple-input.js');
         });
         });
 
 
-        describe('variant #1: nested function calls', () => {
+        describe('Variant #1: nested function calls', () => {
             beforeEach(() => {
             beforeEach(() => {
                 astTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/variant-1.js');
                 astTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/variant-1.js');
                 expectedAstTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/variant-1-expected.js');
                 expectedAstTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/variant-1-expected.js');
@@ -92,7 +92,7 @@ describe('NodeAppender', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: nested function calls', () => {
+        describe('Variant #2: nested function calls', () => {
             beforeEach(() => {
             beforeEach(() => {
                 astTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/variant-2.js');
                 astTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/variant-2.js');
                 expectedAstTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/variant-2-expected.js');
                 expectedAstTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/variant-2-expected.js');
@@ -114,7 +114,7 @@ describe('NodeAppender', () => {
                 astTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/by-index.js');
                 astTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/by-index.js');
             });
             });
 
 
-            describe('variant #1: append by specific index in nested function calls', () => {
+            describe('Variant #1: append by specific index in nested function calls', () => {
                 beforeEach(() => {
                 beforeEach(() => {
                     expectedAstTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/by-index-variant-1-expected.js');
                     expectedAstTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/by-index-variant-1-expected.js');
 
 
@@ -128,7 +128,7 @@ describe('NodeAppender', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: append by specific index in nested function calls', () => {
+            describe('Variant #2: append by specific index in nested function calls', () => {
                 beforeEach(() => {
                 beforeEach(() => {
                     expectedAstTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/by-index-variant-2-expected.js');
                     expectedAstTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/by-index-variant-2-expected.js');
 
 
@@ -142,7 +142,7 @@ describe('NodeAppender', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #3: append by specific index in nested function calls', () => {
+            describe('Variant #3: append by specific index in nested function calls', () => {
                 beforeEach(() => {
                 beforeEach(() => {
                     astTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/by-index-variant-3.js');
                     astTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/by-index-variant-3.js');
                     expectedAstTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/by-index-variant-3-expected.js');
                     expectedAstTree = convertCodeToAst('/fixtures/append-node-to-optimal-block-scope/by-index-variant-3-expected.js');

+ 20 - 20
test/unit-tests/node/node-guards/NodeGuards.spec.ts

@@ -9,7 +9,7 @@ import { NodeUtils } from '../../../../src/node/NodeUtils';
 describe('NodeGuards', () => {
 describe('NodeGuards', () => {
     describe('isNodeHasBlockScope (node: ESTree.Node): node is TNodeWithBlockScope', () => {
     describe('isNodeHasBlockScope (node: ESTree.Node): node is TNodeWithBlockScope', () => {
         describe('truthful checks', () => {
         describe('truthful checks', () => {
-            describe('variant #1: block statement of function declaration', () => {
+            describe('Variant #1: block statement of function declaration', () => {
                 const expectedResult: boolean = true;
                 const expectedResult: boolean = true;
                 const node: ESTree.Node = Nodes.getBlockStatementNode();
                 const node: ESTree.Node = Nodes.getBlockStatementNode();
                 const parentNode: ESTree.FunctionDeclaration = Nodes.getFunctionDeclarationNode(
                 const parentNode: ESTree.FunctionDeclaration = Nodes.getFunctionDeclarationNode(
@@ -30,7 +30,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: block statement of function expression', () => {
+            describe('Variant #2: block statement of function expression', () => {
                 const expectedResult: boolean = true;
                 const expectedResult: boolean = true;
                 const node: ESTree.Node = Nodes.getBlockStatementNode();
                 const node: ESTree.Node = Nodes.getBlockStatementNode();
                 const parentNode: ESTree.FunctionExpression = Nodes.getFunctionExpressionNode(
                 const parentNode: ESTree.FunctionExpression = Nodes.getFunctionExpressionNode(
@@ -52,7 +52,7 @@ describe('NodeGuards', () => {
         });
         });
 
 
         describe('false checks', () => {
         describe('false checks', () => {
-            describe('variant #1: switch-case node', () => {
+            describe('Variant #1: switch-case node', () => {
                 const expectedResult: boolean = false;
                 const expectedResult: boolean = false;
                 const node: ESTree.Node = Nodes.getSwitchCaseNode(
                 const node: ESTree.Node = Nodes.getSwitchCaseNode(
                     Nodes.getLiteralNode(1),
                     Nodes.getLiteralNode(1),
@@ -88,7 +88,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: literal node', () => {
+            describe('Variant #2: literal node', () => {
                 const expectedResult: boolean = false;
                 const expectedResult: boolean = false;
                 const node: ESTree.Node = Nodes.getLiteralNode(1);
                 const node: ESTree.Node = Nodes.getLiteralNode(1);
                 const parentNode: ESTree.FunctionDeclaration = Nodes.getFunctionDeclarationNode(
                 const parentNode: ESTree.FunctionDeclaration = Nodes.getFunctionDeclarationNode(
@@ -116,7 +116,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #3: block statement of if statement', () => {
+            describe('Variant #3: block statement of if statement', () => {
                 const expectedResult: boolean = false;
                 const expectedResult: boolean = false;
                 const node: ESTree.Node = Nodes.getBlockStatementNode();
                 const node: ESTree.Node = Nodes.getBlockStatementNode();
                 const parentNode: ESTree.IfStatement = Nodes.getIfStatementNode(
                 const parentNode: ESTree.IfStatement = Nodes.getIfStatementNode(
@@ -140,7 +140,7 @@ describe('NodeGuards', () => {
 
 
     describe('isNodeHasScope (node: ESTree.Node): node is TNodeWithScope', () => {
     describe('isNodeHasScope (node: ESTree.Node): node is TNodeWithScope', () => {
         describe('truthful checks', () => {
         describe('truthful checks', () => {
-            describe('variant #1: program node', () => {
+            describe('Variant #1: program node', () => {
                 const expectedResult: boolean = true;
                 const expectedResult: boolean = true;
                 const node: ESTree.Node = Nodes.getProgramNode();
                 const node: ESTree.Node = Nodes.getProgramNode();
 
 
@@ -155,7 +155,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: block statement node', () => {
+            describe('Variant #2: block statement node', () => {
                 const expectedResult: boolean = true;
                 const expectedResult: boolean = true;
                 const node: ESTree.Node = Nodes.getBlockStatementNode();
                 const node: ESTree.Node = Nodes.getBlockStatementNode();
 
 
@@ -170,7 +170,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #3: switch case node', () => {
+            describe('Variant #3: switch case node', () => {
                 const expectedResult: boolean = true;
                 const expectedResult: boolean = true;
                 const node: ESTree.Node = Nodes.getSwitchCaseNode(
                 const node: ESTree.Node = Nodes.getSwitchCaseNode(
                     Nodes.getLiteralNode(1),
                     Nodes.getLiteralNode(1),
@@ -190,7 +190,7 @@ describe('NodeGuards', () => {
         });
         });
 
 
         describe('false checks', () => {
         describe('false checks', () => {
-            describe('variant #1: literal node', () => {
+            describe('Variant #1: literal node', () => {
                 const expectedResult: boolean = false;
                 const expectedResult: boolean = false;
                 const node: ESTree.Node = Nodes.getLiteralNode(1);
                 const node: ESTree.Node = Nodes.getLiteralNode(1);
 
 
@@ -205,7 +205,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: identifier node', () => {
+            describe('Variant #2: identifier node', () => {
                 const expectedResult: boolean = false;
                 const expectedResult: boolean = false;
                 const node: ESTree.Node = Nodes.getIdentifierNode('foo');
                 const node: ESTree.Node = Nodes.getIdentifierNode('foo');
 
 
@@ -220,7 +220,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #3: if-statement node', () => {
+            describe('Variant #3: if-statement node', () => {
                 const expectedResult: boolean = false;
                 const expectedResult: boolean = false;
                 const node: ESTree.Node = Nodes.getIfStatementNode(
                 const node: ESTree.Node = Nodes.getIfStatementNode(
                     Nodes.getIdentifierNode('foo'),
                     Nodes.getIdentifierNode('foo'),
@@ -238,7 +238,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #4: switch-statement node', () => {
+            describe('Variant #4: switch-statement node', () => {
                 const expectedResult: boolean = false;
                 const expectedResult: boolean = false;
                 const node: ESTree.Node = Nodes.getSwitchStatementNode(
                 const node: ESTree.Node = Nodes.getSwitchStatementNode(
                     Nodes.getIdentifierNode('foo'),
                     Nodes.getIdentifierNode('foo'),
@@ -260,7 +260,7 @@ describe('NodeGuards', () => {
 
 
     describe('isReplaceableIdentifierNode (node: ESTree.Node, parentNode: ESTree.Node): node is ESTree.Identifier', () => {
     describe('isReplaceableIdentifierNode (node: ESTree.Node, parentNode: ESTree.Node): node is ESTree.Identifier', () => {
         describe('truthful checks', () => {
         describe('truthful checks', () => {
-            describe('variant #1: parent node is function declaration node', () => {
+            describe('Variant #1: parent node is function declaration node', () => {
                 const expectedResult: boolean = true;
                 const expectedResult: boolean = true;
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const parentNode: ESTree.Node = Nodes.getFunctionDeclarationNode(
                 const parentNode: ESTree.Node = Nodes.getFunctionDeclarationNode(
@@ -281,7 +281,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: parent node is computed property node', () => {
+            describe('Variant #2: parent node is computed property node', () => {
                 const expectedResult: boolean = true;
                 const expectedResult: boolean = true;
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const parentNode: ESTree.Node = Nodes.getPropertyNode(
                 const parentNode: ESTree.Node = Nodes.getPropertyNode(
@@ -302,7 +302,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #4: parent node is computed member expression node', () => {
+            describe('Variant #4: parent node is computed member expression node', () => {
                 const expectedResult: boolean = true;
                 const expectedResult: boolean = true;
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const parentNode: ESTree.Node = Nodes.getMemberExpressionNode(
                 const parentNode: ESTree.Node = Nodes.getMemberExpressionNode(
@@ -323,7 +323,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #4: parent node is computed method definition node', () => {
+            describe('Variant #4: parent node is computed method definition node', () => {
                 const expectedResult: boolean = true;
                 const expectedResult: boolean = true;
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const parentNode: ESTree.Node = Nodes.getMethodDefinitionNode(
                 const parentNode: ESTree.Node = Nodes.getMethodDefinitionNode(
@@ -347,7 +347,7 @@ describe('NodeGuards', () => {
         });
         });
 
 
         describe('false checks', () => {
         describe('false checks', () => {
-            describe('variant #1: node isn\'t an identifier', () => {
+            describe('Variant #1: node isn\'t an identifier', () => {
                 const expectedResult: boolean = false;
                 const expectedResult: boolean = false;
                 const literal: ESTree.Literal = Nodes.getLiteralNode(1);
                 const literal: ESTree.Literal = Nodes.getLiteralNode(1);
                 const parentNode: ESTree.Node = Nodes.getExpressionStatementNode(
                 const parentNode: ESTree.Node = Nodes.getExpressionStatementNode(
@@ -369,7 +369,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #2: parent node isn\'t computed property node', () => {
+            describe('Variant #2: parent node isn\'t computed property node', () => {
                 const expectedResult: boolean = false;
                 const expectedResult: boolean = false;
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const parentNode: ESTree.Node = Nodes.getPropertyNode(
                 const parentNode: ESTree.Node = Nodes.getPropertyNode(
@@ -390,7 +390,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #3: parent node isn\'t computed member expression node', () => {
+            describe('Variant #3: parent node isn\'t computed member expression node', () => {
                 const expectedResult: boolean = false;
                 const expectedResult: boolean = false;
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const parentNode: ESTree.Node = Nodes.getMemberExpressionNode(
                 const parentNode: ESTree.Node = Nodes.getMemberExpressionNode(
@@ -411,7 +411,7 @@ describe('NodeGuards', () => {
                 });
                 });
             });
             });
 
 
-            describe('variant #4: parent node isn\'t computed method definition node', () => {
+            describe('Variant #4: parent node isn\'t computed method definition node', () => {
                 const expectedResult: boolean = false;
                 const expectedResult: boolean = false;
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const parentNode: ESTree.Node = Nodes.getMethodDefinitionNode(
                 const parentNode: ESTree.Node = Nodes.getMethodDefinitionNode(

+ 10 - 10
test/unit-tests/node/node-utils/NodeUtils.spec.ts

@@ -27,7 +27,7 @@ describe('NodeUtils', () => {
     });
     });
 
 
     describe('clone <T extends ESTree.Node> (astTree: T): T', () => {
     describe('clone <T extends ESTree.Node> (astTree: T): T', () => {
-        describe('variant #1: simple AST-tree', () => {
+        describe('Variant #1: simple AST-tree', () => {
             let programNode: ESTree.Program,
             let programNode: ESTree.Program,
                 expectedProgramNode: ESTree.Program;
                 expectedProgramNode: ESTree.Program;
 
 
@@ -77,7 +77,7 @@ describe('NodeUtils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: array expression with `null` element', () => {
+        describe('Variant #2: array expression with `null` element', () => {
             let programNode: ESTree.Program,
             let programNode: ESTree.Program,
                 expectedProgramNode: ESTree.Program;
                 expectedProgramNode: ESTree.Program;
 
 
@@ -295,7 +295,7 @@ describe('NodeUtils', () => {
     });
     });
 
 
     describe('getNextSiblingStatementNode (node: ESTree.Statement): TStatement | null', () => {
     describe('getNextSiblingStatementNode (node: ESTree.Statement): TStatement | null', () => {
-        describe('variant #1: block statement node as scope node', () => {
+        describe('Variant #1: block statement node as scope node', () => {
                 let statementNode1: ESTree.Statement,
                 let statementNode1: ESTree.Statement,
                 statementNode2: ESTree.Statement,
                 statementNode2: ESTree.Statement,
                 statementNode3: ESTree.Statement;
                 statementNode3: ESTree.Statement;
@@ -335,7 +335,7 @@ describe('NodeUtils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: switch case node as scope node', () => {
+        describe('Variant #2: switch case node as scope node', () => {
             let statementNode1: ESTree.Statement,
             let statementNode1: ESTree.Statement,
                 statementNode2: ESTree.Statement,
                 statementNode2: ESTree.Statement,
                 statementNode3: ESTree.Statement;
                 statementNode3: ESTree.Statement;
@@ -380,7 +380,7 @@ describe('NodeUtils', () => {
     });
     });
 
 
     describe('getPreviousSiblingStatementNode (node: ESTree.Statement): TStatement | null', () => {
     describe('getPreviousSiblingStatementNode (node: ESTree.Statement): TStatement | null', () => {
-        describe('variant #1: block statement node as scope node', () => {
+        describe('Variant #1: block statement node as scope node', () => {
             let statementNode1: ESTree.Statement,
             let statementNode1: ESTree.Statement,
                 statementNode2: ESTree.Statement,
                 statementNode2: ESTree.Statement,
                 statementNode3: ESTree.Statement;
                 statementNode3: ESTree.Statement;
@@ -420,7 +420,7 @@ describe('NodeUtils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: switch case node as scope node', () => {
+        describe('Variant #2: switch case node as scope node', () => {
             let statementNode1: ESTree.Statement,
             let statementNode1: ESTree.Statement,
                 statementNode2: ESTree.Statement,
                 statementNode2: ESTree.Statement,
                 statementNode3: ESTree.Statement;
                 statementNode3: ESTree.Statement;
@@ -655,7 +655,7 @@ describe('NodeUtils', () => {
             );
             );
         });
         });
 
 
-        describe('variant #1: parentize AST-tree with `ProgramNode` as root node', () => {
+        describe('Variant #1: parentize AST-tree with `ProgramNode` as root node', () => {
             beforeEach(() => {
             beforeEach(() => {
                 programNode = Nodes.getProgramNode([
                 programNode = Nodes.getProgramNode([
                     ifStatementNode
                     ifStatementNode
@@ -685,7 +685,7 @@ describe('NodeUtils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: parentize AST-tree', () => {
+        describe('Variant #2: parentize AST-tree', () => {
             beforeEach(() => {
             beforeEach(() => {
                 ifStatementNode = NodeUtils.parentize(ifStatementNode);
                 ifStatementNode = NodeUtils.parentize(ifStatementNode);
             });
             });
@@ -709,7 +709,7 @@ describe('NodeUtils', () => {
     });
     });
 
 
     describe('parentizeNode <T extends ESTree.Node = ESTree.Program> (node: T, parentNode: ESTree.Node): T', () => {
     describe('parentizeNode <T extends ESTree.Node = ESTree.Program> (node: T, parentNode: ESTree.Node): T', () => {
-        describe('variant #1: node with parent node', () => {
+        describe('Variant #1: node with parent node', () => {
             const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
             const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
             const breakStatement: ESTree.BreakStatement = Nodes.getBreakStatement(identifier);
             const breakStatement: ESTree.BreakStatement = Nodes.getBreakStatement(identifier);
 
 
@@ -728,7 +728,7 @@ describe('NodeUtils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: node without parent node', () => {
+        describe('Variant #2: node without parent node', () => {
             const identifier: ESTree.Identifier = Nodes.getIdentifierNode('Foo');
             const identifier: ESTree.Identifier = Nodes.getIdentifierNode('Foo');
             const expectedResult: ESTree.Identifier = NodeUtils.clone(identifier);
             const expectedResult: ESTree.Identifier = NodeUtils.clone(identifier);
 
 

+ 3 - 3
test/unit-tests/options/ValidationErrorsFormatter.spec.ts

@@ -6,7 +6,7 @@ import { ValidationErrorsFormatter } from '../../../src/options/ValidationErrors
 
 
 describe('ValidationErrorsFormatter', () => {
 describe('ValidationErrorsFormatter', () => {
     describe('format (validationErrors: ValidationError[]): string', () => {
     describe('format (validationErrors: ValidationError[]): string', () => {
-        describe('variant #1: one constraint group with one constraint', () => {
+        describe('Variant #1: one constraint group with one constraint', () => {
             const constraintGroupRegExp: RegExp = /`foo` *errors:/;
             const constraintGroupRegExp: RegExp = /`foo` *errors:/;
             const constraintRegExp: RegExp = /(?: *-)+ *constraint *text/;
             const constraintRegExp: RegExp = /(?: *-)+ *constraint *text/;
             const validationErrors: ValidationError[] = [{
             const validationErrors: ValidationError[] = [{
@@ -34,7 +34,7 @@ describe('ValidationErrorsFormatter', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: one constraint group with two constraint', () => {
+        describe('Variant #2: one constraint group with two constraint', () => {
             const constraintGroupRegExp: RegExp = /`foo` *errors:/;
             const constraintGroupRegExp: RegExp = /`foo` *errors:/;
             const constraintRegExp1: RegExp = /(?: *-)+ constraint *text *#1/;
             const constraintRegExp1: RegExp = /(?: *-)+ constraint *text *#1/;
             const constraintRegExp2: RegExp = /(?: *-)+ constraint *text *#2/;
             const constraintRegExp2: RegExp = /(?: *-)+ constraint *text *#2/;
@@ -68,7 +68,7 @@ describe('ValidationErrorsFormatter', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: two constraint groups', () => {
+        describe('Variant #3: two constraint groups', () => {
             const regExpMatch: string = `` +
             const regExpMatch: string = `` +
                 `\`foo\` *errors:\\n` +
                 `\`foo\` *errors:\\n` +
                     `(?: *-)+ *constraint *group *#1 *text\\n+` +
                     `(?: *-)+ *constraint *group *#1 *text\\n+` +

+ 5 - 5
test/unit-tests/storages/ArrayStorage.spec.ts

@@ -72,7 +72,7 @@ describe('ArrayStorage', () => {
     });
     });
 
 
     describe('get (key: number): T', () => {
     describe('get (key: number): T', () => {
-        describe('variant #1: value exist', () => {
+        describe('Variant #1: value exist', () => {
             const expectedValue: string = storageValue;
             const expectedValue: string = storageValue;
 
 
             let value: string;
             let value: string;
@@ -89,7 +89,7 @@ describe('ArrayStorage', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: value isn\'t exist', () => {
+        describe('Variant #2: value isn\'t exist', () => {
             const expectedError: ErrorConstructor = Error;
             const expectedError: ErrorConstructor = Error;
 
 
             let testFunc: () => void;
             let testFunc: () => void;
@@ -126,7 +126,7 @@ describe('ArrayStorage', () => {
     describe('getKeyOf (value: T): number | null', () => {
     describe('getKeyOf (value: T): number | null', () => {
         let key: string | number | null;
         let key: string | number | null;
 
 
-        describe('variant #1', () => {
+        describe('Variant #1', () => {
             before(() => {
             before(() => {
                 storage = getStorageInstance();
                 storage = getStorageInstance();
                 storage.set(storageKey, storageValue);
                 storage.set(storageKey, storageValue);
@@ -139,7 +139,7 @@ describe('ArrayStorage', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2', () => {
+        describe('Variant #2', () => {
             const object: Object = {
             const object: Object = {
                 foo: 'bar'
                 foo: 'bar'
             };
             };
@@ -156,7 +156,7 @@ describe('ArrayStorage', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3', () => {
+        describe('Variant #3', () => {
             const expectedKey: null = null;
             const expectedKey: null = null;
             const object: Object = {
             const object: Object = {
                 foo: 'bar'
                 foo: 'bar'

+ 5 - 5
test/unit-tests/storages/MapStorage.spec.ts

@@ -72,7 +72,7 @@ describe('MapStorage', () => {
     });
     });
 
 
     describe('get (key: string | number): T', () => {
     describe('get (key: string | number): T', () => {
-        describe('variant #1: value exist', () => {
+        describe('Variant #1: value exist', () => {
             const expectedValue: string = storageValue;
             const expectedValue: string = storageValue;
 
 
             let value: string;
             let value: string;
@@ -89,7 +89,7 @@ describe('MapStorage', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: value isn\'t exist', () => {
+        describe('Variant #2: value isn\'t exist', () => {
             const expectedError: ErrorConstructor = Error;
             const expectedError: ErrorConstructor = Error;
 
 
             let testFunc: () => void;
             let testFunc: () => void;
@@ -126,7 +126,7 @@ describe('MapStorage', () => {
     describe('getKeyOf (value: T): string | number | null', () => {
     describe('getKeyOf (value: T): string | number | null', () => {
         let key: string | number | null;
         let key: string | number | null;
 
 
-        describe('variant #1', () => {
+        describe('Variant #1', () => {
             before(() => {
             before(() => {
                 storage = getStorageInstance();
                 storage = getStorageInstance();
                 storage.set(storageKey, storageValue);
                 storage.set(storageKey, storageValue);
@@ -139,7 +139,7 @@ describe('MapStorage', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2', () => {
+        describe('Variant #2', () => {
             const object: Object = {
             const object: Object = {
                 bar: 'baz'
                 bar: 'baz'
             };
             };
@@ -156,7 +156,7 @@ describe('MapStorage', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3', () => {
+        describe('Variant #3', () => {
             const expectedKey: null = null;
             const expectedKey: null = null;
             const object: Object = {
             const object: Object = {
                 bar: 'baz'
                 bar: 'baz'

+ 2 - 2
test/unit-tests/utils/EscapeSequenceEncoder.spec.ts

@@ -19,7 +19,7 @@ describe('EscapeSequenceEncoder', () => {
                 .get<IEscapeSequenceEncoder>(ServiceIdentifiers.IEscapeSequenceEncoder);
                 .get<IEscapeSequenceEncoder>(ServiceIdentifiers.IEscapeSequenceEncoder);
         });
         });
 
 
-        describe('variant #1: default', () => {
+        describe('Variant #1: default', () => {
             const string: string = 'string';
             const string: string = 'string';
             const expectedString: string = '\\x73\\x74\\x72\\x69\\x6e\\x67';
             const expectedString: string = '\\x73\\x74\\x72\\x69\\x6e\\x67';
 
 
@@ -34,7 +34,7 @@ describe('EscapeSequenceEncoder', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: escape `escape sequences`', () => {
+        describe('Variant #2: escape `escape sequences`', () => {
             const string: string = 'abc\'\\r\\n';
             const string: string = 'abc\'\\r\\n';
             const expectedString: string = 'abc\\x27\\x5cr\\x5cn';
             const expectedString: string = 'abc\\x27\\x5cr\\x5cn';
 
 

+ 9 - 9
test/unit-tests/utils/Utils.spec.ts

@@ -6,7 +6,7 @@ import { Utils } from '../../../src/utils/Utils';
 
 
 describe('Utils', () => {
 describe('Utils', () => {
     describe('decToHex (dec: number): string', () => {
     describe('decToHex (dec: number): string', () => {
-        describe('variant #1: number `0`', () => {
+        describe('Variant #1: number `0`', () => {
             const number: number = 0;
             const number: number = 0;
             const expectedHexString = '0';
             const expectedHexString = '0';
 
 
@@ -21,7 +21,7 @@ describe('Utils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: number `10`', () => {
+        describe('Variant #2: number `10`', () => {
             const number: number = 10;
             const number: number = 10;
             const expectedHexString = 'a';
             const expectedHexString = 'a';
 
 
@@ -36,7 +36,7 @@ describe('Utils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: number `17`', () => {
+        describe('Variant #3: number `17`', () => {
             const number: number = 17;
             const number: number = 17;
             const expectedHexString = '11';
             const expectedHexString = '11';
 
 
@@ -51,7 +51,7 @@ describe('Utils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4: number `536870912`', () => {
+        describe('Variant #4: number `536870912`', () => {
             const number: number = 536870912;
             const number: number = 536870912;
             const expectedHexString = '20000000';
             const expectedHexString = '20000000';
 
 
@@ -68,7 +68,7 @@ describe('Utils', () => {
     });
     });
 
 
     describe('extractDomainFromUrl (url: string): string', () => {
     describe('extractDomainFromUrl (url: string): string', () => {
-        describe('variant #1: simple url', () => {
+        describe('Variant #1: simple url', () => {
             const url: string = 'http://google.ru';
             const url: string = 'http://google.ru';
             const expectedDomain: string = 'google.ru';
             const expectedDomain: string = 'google.ru';
 
 
@@ -83,7 +83,7 @@ describe('Utils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #2: url with `www` part', () => {
+        describe('Variant #2: url with `www` part', () => {
             const url: string = 'http://www.google.ru';
             const url: string = 'http://www.google.ru';
             const expectedDomain: string = 'www.google.ru';
             const expectedDomain: string = 'www.google.ru';
 
 
@@ -98,7 +98,7 @@ describe('Utils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #3: url with `https` protocol and port', () => {
+        describe('Variant #3: url with `https` protocol and port', () => {
             const url: string = 'https://www.google.ru:9000';
             const url: string = 'https://www.google.ru:9000';
             const expectedDomain: string = 'www.google.ru';
             const expectedDomain: string = 'www.google.ru';
 
 
@@ -113,7 +113,7 @@ describe('Utils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #4: protocol-wide url and route', () => {
+        describe('Variant #4: protocol-wide url and route', () => {
             const url: string = '//google.ru/abc';
             const url: string = '//google.ru/abc';
             const expectedDomain: string = 'google.ru';
             const expectedDomain: string = 'google.ru';
 
 
@@ -128,7 +128,7 @@ describe('Utils', () => {
             });
             });
         });
         });
 
 
-        describe('variant #5: protocol-wide url, `localhost` and port', () => {
+        describe('Variant #5: protocol-wide url, `localhost` and port', () => {
             const url: string = '//localhost:9000';
             const url: string = '//localhost:9000';
             const expectedDomain: string = 'localhost';
             const expectedDomain: string = 'localhost';
 
 

+ 31 - 4
yarn.lock

@@ -68,6 +68,10 @@
   version "2.2.48"
   version "2.2.48"
   resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.48.tgz#3523b126a0b049482e1c3c11877460f76622ffab"
   resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.48.tgz#3523b126a0b049482e1c3c11877460f76622ffab"
 
 
+"@types/[email protected]":
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/@types/multimatch/-/multimatch-2.1.2.tgz#7d705c35b6ec6ae94f2dbfc384adb05f0974e6d7"
+
 "@types/node@*":
 "@types/node@*":
   version "8.0.53"
   version "8.0.53"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8"
@@ -214,6 +218,20 @@ arr-union@^3.1.0:
   version "3.1.0"
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
   resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
 
 
+array-differ@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031"
+
+array-union@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
+  dependencies:
+    array-uniq "^1.0.1"
+
+array-uniq@^1.0.1:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
+
 array-unique@^0.2.1:
 array-unique@^0.2.1:
   version "0.2.1"
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
   resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
@@ -715,7 +733,7 @@ babel-polyfill@^6.26.0:
     core-js "^2.5.0"
     core-js "^2.5.0"
     regenerator-runtime "^0.10.5"
     regenerator-runtime "^0.10.5"
 
 
-babel-preset-env@^1.6.1:
[email protected]:
   version "1.6.1"
   version "1.6.1"
   resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48"
   resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48"
   dependencies:
   dependencies:
@@ -2667,6 +2685,15 @@ [email protected]:
   version "2.0.0"
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
 
 
[email protected]:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b"
+  dependencies:
+    array-differ "^1.0.0"
+    array-union "^1.0.1"
+    arrify "^1.0.0"
+    minimatch "^3.0.0"
+
 [email protected]:
 [email protected]:
   version "0.0.7"
   version "0.0.7"
   resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
   resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
@@ -3407,9 +3434,9 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
   version "3.0.2"
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
   resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
 
 
-sinon@4.3.0:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.3.0.tgz#cec9b27d5f4e2c63c1a79c9dc1c05d34bb088234"
+sinon@4.4.1:
+  version "4.4.1"
+  resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.4.1.tgz#68819f18be164078d03d4fc40ce0691d1f666eb5"
   dependencies:
   dependencies:
     "@sinonjs/formatio" "^2.0.0"
     "@sinonjs/formatio" "^2.0.0"
     diff "^3.1.0"
     diff "^3.1.0"

Some files were not shown because too many files changed in this diff