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
 ===
+v0.15.0
+---
+* **New CLI option:** `exclude` allows to exclude specific files or directories from obfuscation.
+
 v0.14.3
 ---
 * 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>
     --disable-console-output <boolean>
     --domain-lock '<list>' (comma separated)
+    --exclude '<list>' (comma separated)
     --identifier-names-generator <string> [hexadecimal, mangled]
     --identifiers-prefix <string>
     --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
 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`
 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",
-  "version": "0.14.3",
+  "version": "0.15.0-dev.0",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",
@@ -30,6 +30,7 @@
     "js-string-escape": "1.0.1",
     "md5": "2.2.1",
     "mkdirp": "0.5.1",
+    "multimatch": "2.1.0",
     "opencollective": "1.0.3",
     "pjson": "1.0.9",
     "reflect-metadata": "0.1.12",
@@ -47,6 +48,7 @@
     "@types/md5": "2.1.32",
     "@types/mkdirp": "0.5.2",
     "@types/mocha": "2.2.48",
+    "@types/multimatch": "2.1.2",
     "@types/node": "9.4.6",
     "@types/rimraf": "2.0.2",
     "@types/sinon": "4.1.3",
@@ -63,7 +65,7 @@
     "mocha": "5.0.1",
     "pre-commit": "1.2.2",
     "rimraf": "2.6.2",
-    "sinon": "4.3.0",
+    "sinon": "4.4.1",
     "threads": "0.10.1",
     "ts-node": "5.0.0",
     "tslint": "5.9.1",

+ 7 - 8
src/cli/JavaScriptObfuscatorCLI.ts

@@ -26,13 +26,6 @@ import { JavaScriptObfuscator } from '../JavaScriptObfuscatorFacade';
 import { SourceCodeReader } from './utils/SourceCodeReader';
 
 export class JavaScriptObfuscatorCLI implements IInitializable {
-    /**
-     * @type {string[]}
-     */
-    public static readonly availableInputExtensions: string[] = [
-        '.js'
-    ];
-
     /**
      * @type {BufferEncoding}
      */
@@ -163,7 +156,8 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
             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);
     }
@@ -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)',
                 ArraySanitizer
             )
+            .option(
+                '--exclude <list> (comma separated, without whitespaces)',
+                'A filename or glob which indicates files to exclude from obfuscation',
+                ArraySanitizer
+            )
             .option(
                 '--identifier-names-generator <string> [hexadecimal, mangled]', 'Sets identifier names generator (Default: hexadecimal)',
                 IdentifierNamesGeneratorSanitizer

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

@@ -1,6 +1,8 @@
 import * as fs from 'fs';
 import * as path from 'path';
+import multimatch from 'multimatch';
 
+import { TInputCLIOptions } from '../../types/options/TInputCLIOptions';
 import { TSourceCodeData } from '../../types/cli/TSourceCodeData';
 
 import { IFileData } from '../../interfaces/cli/IFileData';
@@ -12,19 +14,41 @@ import { Logger } from '../../logger/Logger';
 
 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 {IFileData[]} fileData
      * @returns {IFileData[]}
      */
-    private static readDirectoryRecursive (directoryPath: string, fileData: IFileData[] = []): IFileData[] {
+    private readDirectoryRecursive (directoryPath: string, fileData: IFileData[] = []): IFileData[] {
         fs.readdirSync(directoryPath, JavaScriptObfuscatorCLI.encoding)
             .forEach((fileName: string) => {
                 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 });
                 }
@@ -79,35 +136,27 @@ export class SourceCodeReader {
      * @param {string} filePath
      * @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);
 
         return fs.readFileSync(filePath, JavaScriptObfuscatorCLI.encoding);
     }
 
     /**
-     * @param {string} filePath
+     * @param {string} directoryPath
      * @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
+     * @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 {
     readonly config: string;
+    readonly exclude: string[];
     readonly output: string;
     readonly version: string;
 }

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

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

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

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

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

@@ -162,7 +162,7 @@ describe('StackTraceAnalyzer', () => {
                 .get<IStackTraceAnalyzer>(ServiceIdentifiers.IStackTraceAnalyzer);
         });
 
-        describe('variant #1: basic-1', () => {
+        describe('Variant #1: basic-1', () => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/basic-1.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -212,7 +212,7 @@ describe('StackTraceAnalyzer', () => {
             });
         });
 
-        describe('variant #2: basic-2', () => {
+        describe('Variant #2: basic-2', () => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/basic-2.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -251,7 +251,7 @@ describe('StackTraceAnalyzer', () => {
             });
         });
 
-        describe('variant #3: deep conditions nesting', () => {
+        describe('Variant #3: deep conditions nesting', () => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/deep-conditions-nesting.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -290,7 +290,7 @@ describe('StackTraceAnalyzer', () => {
             });
         });
 
-        describe('variant #4: call before declaration', () => {
+        describe('Variant #4: call before declaration', () => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/call-before-declaration.js');
                 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(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/call-expression-of-object-member-1.js');
                 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(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/call-expression-of-object-member-2.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -400,7 +400,7 @@ describe('StackTraceAnalyzer', () => {
             });
         });
 
-        describe('variant #6: no call expressions', () => {
+        describe('Variant #6: no call expressions', () => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/no-call-expressions.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -417,7 +417,7 @@ describe('StackTraceAnalyzer', () => {
             });
         });
 
-        describe('variant #7: only call expression', () => {
+        describe('Variant #7: only call expression', () => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/only-call-expression.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -434,7 +434,7 @@ describe('StackTraceAnalyzer', () => {
             });
         });
 
-        describe('variant #8: self-invoking functions', () => {
+        describe('Variant #8: self-invoking functions', () => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/self-invoking-functions.js');
                 const astTree: TNodeWithBlockScope = Nodes.getProgramNode(
@@ -469,7 +469,7 @@ describe('StackTraceAnalyzer', () => {
             });
         });
 
-        describe('variant #9: no recursion', () => {
+        describe('Variant #9: no recursion', () => {
             before(() => {
                 const code: string = readFileAsString(__dirname + '/fixtures/no-recursion.js');
                 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 {
     this.timeout(100000);
 
+    const expectedError: RegExp = /Given input path must be a valid/;
+
     const fixturesDirName: string = 'test/fixtures';
     const fixtureFileName: string = 'sample.js';
     const fixtureFilePath: string = `${fixturesDirName}/${fixtureFileName}`;
@@ -58,7 +60,7 @@ describe('JavaScriptObfuscatorCLI', function (): void {
             });
 
             describe('`--output` option isn\'t set', () => {
-                describe('variant #1: default behaviour', () => {
+                describe('Variant #1: default behaviour', () => {
                     let outputFixturesFilePath: string,
                         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;
 
                     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 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', () => {
-            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', () => {
             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,
                         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,
                         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 sourceMapFilePath: string = `${sourceMapFileName}.js.map`;
                     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;
 
                 before(() => {

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

@@ -186,7 +186,7 @@ describe('JavaScriptObfuscator', () => {
         });
 
         describe('variable inside global scope', () => {
-            describe('variant #1: without `renameGlobals` option', () => {
+            describe('Variant #1: without `renameGlobals` option', () => {
                 const regExp: RegExp = /^var *test *= *0x\d+;$/;
 
                 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+;$/;
 
                 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+;$/;
 
                 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 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('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 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}/;
@@ -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');
 
                 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');
 
                 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 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);
 
     describe('transformNode (blockStatementNode: ESTree.BlockStatement): ESTree.Node', () => {
-        describe('variant #1: 5 simple statements', () => {
+        describe('Variant #1: 5 simple statements', () => {
             let obfuscatedCode: string;
 
             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;
 
             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\); *\} *\( *\) *\);$/;
 
             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\);/;
 
             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\);/;
 
             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\);/;
 
             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\);/;
 
             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 switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
             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\);/;
 
             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\);/;
 
             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 switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
             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\);/
 
             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} *{.*?} *}/;
 
             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 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 switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
             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);
 
     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\);/;
 
             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 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);
 
     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\);/;
 
             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 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\);/;
 
             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);
 
     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}'\]\(!!\[\], *!\[\]\);/;
 
             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 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}\);/;
 
             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}\] *&& *!\[\];/;
 
             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('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);
 
             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 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(
                 `var *${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;$/;
 
             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 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 controlFlowStorageRegExp: RegExp = new RegExp(rootControlFlowStorageNodeMatch);
 
@@ -230,7 +230,7 @@ describe('FunctionControlFlowTransformer', function () {
         });
 
         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);
 
                 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;`);
 
                 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('variant #1: square brackets literal ', () => {
+        describe('Variant #1: square brackets literal ', () => {
             const stringArrayRegExp: RegExp = /var *_0x([a-f0-9]){4} *= *\['log'\];/;
             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\];/;
 
             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';
 
 describe('MethodDefinitionTransformer', () => {
-    describe('variant #1: default behaviour', () => {
+    describe('Variant #1: default behaviour', () => {
         const regExp: RegExp = /\['bar'\]\(\)\{\}/;
 
         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 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\(\)\{\}/;
 
         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}';
 
     describe('transformation of object keys', () => {
-        describe('variant #1: simple', () => {
+        describe('Variant #1: simple', () => {
             const match: string = `` +
                 `var *${variableMatch} *= *{};` +
                 `${variableMatch}\\['foo'] *= *'bar';` +
@@ -40,7 +40,7 @@ describe('ObjectExpressionKeysTransformer', () => {
             });
         });
 
-        describe('variant #2: nested objects #1', () => {
+        describe('Variant #2: nested objects #1', () => {
             const match: string = `` +
                 `var *${variableMatch} *= *{};` +
                 `${variableMatch}\\['foo'] *= *'bar';` +
@@ -70,7 +70,7 @@ describe('ObjectExpressionKeysTransformer', () => {
             });
         });
 
-        describe('variant #3: nested objects #2', () => {
+        describe('Variant #3: nested objects #2', () => {
             const match: string = `` +
                 `var *${variableMatch} *= *{};` +
                 `${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 = `` +
                 `var *${variableMatch} *= *{};` +
                 `${variableMatch}\\['\\w{5}'] *= *function *\\(${variableMatch}, *${variableMatch}\\) *{` +
@@ -137,7 +137,7 @@ describe('ObjectExpressionKeysTransformer', () => {
     });
 
     describe('correct placement of expression statements', () => {
-        describe('variant #1: if statement', () => {
+        describe('Variant #1: if statement', () => {
             const match: string = `` +
                 `if *\\(!!\\[]\\) *{` +
                     `var *${variableMatch} *= *{};` +
@@ -166,7 +166,7 @@ describe('ObjectExpressionKeysTransformer', () => {
             });
         });
 
-        describe('variant #2: try statement', () => {
+        describe('Variant #2: try statement', () => {
             const match: string = `` +
                 `try *{` +
                     `var *${variableMatch} *= *{};` +
@@ -196,7 +196,7 @@ describe('ObjectExpressionKeysTransformer', () => {
             });
         });
 
-        describe('variant #3: catch clause statement', () => {
+        describe('Variant #3: catch clause statement', () => {
             const match: string = `` +
                 `try *{` +
                 `} *catch *\\(${variableMatch}\\) *{` +
@@ -226,7 +226,7 @@ describe('ObjectExpressionKeysTransformer', () => {
             });
         });
 
-        describe('variant #4: switch catch statement', () => {
+        describe('Variant #4: switch catch statement', () => {
             const match: string = `` +
                 `switch *\\(!!\\[]\\) *{` +
                     `case *!!\\[]:` +
@@ -258,7 +258,7 @@ describe('ObjectExpressionKeysTransformer', () => {
     });
 
     describe('Ignore transformation', () => {
-        describe('variant #1: disabled option', () => {
+        describe('Variant #1: disabled option', () => {
             const match: string = `` +
                 `var *${variableMatch} *= *{` +
                     `'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 = `` +
                 `var *${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';
 
 describe('TemplateLiteralTransformer', () => {
-    describe('variant #1: simple template literal', () => {
+    describe('Variant #1: simple template literal', () => {
         it('should transform es6 template literal to es5', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
             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 obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 code,
@@ -38,7 +38,7 @@ describe('TemplateLiteralTransformer', () => {
             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 obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 code,
@@ -51,7 +51,7 @@ describe('TemplateLiteralTransformer', () => {
             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 obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 code,
@@ -64,7 +64,7 @@ describe('TemplateLiteralTransformer', () => {
             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 obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 code,
@@ -77,7 +77,7 @@ describe('TemplateLiteralTransformer', () => {
             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 obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                 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', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/expression-only.js');
             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', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/literal-inside-expression.js');
             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', () => {
             const code: string = readFileAsString(__dirname + '/fixtures/multiple-expressions.js');
             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 () {
         this.timeout(100000);
 
-        describe('variant #1 - 5 simple block statements', () => {
+        describe('Variant #1 - 5 simple block statements', () => {
             const regExp: RegExp = new RegExp(
                 `if *\\(${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(
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                     `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(
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                     `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(
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                     `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(
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                     `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(
                 `var *${variableMatch} *= *function *\\(\\) *\\{` +
                     `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 delta: number = 0.1;
             const expectedDistribution: number = 0.25;
@@ -368,24 +368,24 @@ describe('DeadCodeInjectionTransformer', () => {
                 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);
             });
 
-            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);
             });
 
-            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);
             });
 
-            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);
             });
         });
 
-        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(
                 `if *\\(!!\\[\\]\\) *{` +
                     `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';
 
             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 = `` +
                 `if *\\(.*?\\) *{` +
                     `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(
                 `function *${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(
                     `${variableMatch} *\\(\\); *` +
                     `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(
                     `function *${variableMatch} *\\(\\) *{ *` +
                         `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('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 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 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 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('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 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 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 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 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 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('variant #1: simple', () => {
+        describe('Variant #1: simple', () => {
             const functionParameterRegExp: RegExp = /function *\(\{ *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 callbackBodyRegExp: RegExp = /console\['log']\(data\)/;
 
@@ -105,7 +105,7 @@ describe('FunctionTransformer', () => {
     });
 
     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 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 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});/;
@@ -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 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});/;

+ 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('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 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';/;
 
             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;
 
             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 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';$/;
 
             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 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';/;
 
             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 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}'\);/;
 
             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 stringArrayThreshold: number = 0.5;
             const delta: number = 0.1;
@@ -282,16 +282,16 @@ describe('LiteralTransformer', () => {
                 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);
             });
 
-            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);
             });
         });
 
-        describe('variant #11: string array calls wrapper name', () => {
+        describe('Variant #11: string array calls wrapper name', () => {
             const regExp: RegExp = /console\[b\('0x0'\)]\('a'\);/;
 
             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';
 
 describe('VariableDeclarationTransformer', () => {
-    describe('variant #1: default behaviour', () => {
+    describe('Variant #1: default behaviour', () => {
         const variableDeclarationRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *'abc';/;
         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 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 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}\);/;
 
         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\);/;
 
         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 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 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})\)/;
@@ -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 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})\)/;
@@ -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/;
 
             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'\]/;
 
             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 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 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\};/;
 
         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'] *\(\) *{}/;
 
         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';
 
 describe('CommentsTransformer', () => {
-    describe('variant #1: simple comment without preserved words', () => {
+    describe('Variant #1: simple comment without preserved words', () => {
         const regExp: RegExp = /^var *test *= *0x1;$/;
 
         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;$/;
 
         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;$/;
 
         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(``+
             `^\\/\\*\\* *\\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;
 
         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$/;
 
         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';
 
 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 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 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};'\);/;
 
         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 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 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 evalExpressionMatch: string = `` +
             `eval *\\('` +
@@ -233,7 +233,7 @@ describe('EvalCallExpressionTransformer', () => {
         });
     });
 
-    describe('variant #7: wrong eval string', () => {
+    describe('Variant #7: wrong eval string', () => {
         const evalExpressionRegExp: RegExp = /eval *\('~'\);/;
 
         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 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 controlFlowStorageNodeMatch: string = `` +
             `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('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 ignoredVariableDeclarationRegExp: RegExp = /var *bar *= *2;/;
             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 obfuscatedVariableDeclaration2RegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x3;/;
             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 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 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 ignoredVariableDeclarationRegExp: RegExp = /var *bar *= *'bar';/;
 

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

@@ -197,7 +197,7 @@ describe('OptionsNormalizer', () => {
         });
 
         describe('sourceMapBaseUrlRule', () => {
-            describe('variant #1: only source map base url', () => {
+            describe('Variant #1: only source map base url', () => {
                 before(() => {
                     optionsPreset = getNormalizedOptions({
                         ...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(() => {
                     optionsPreset = getNormalizedOptions({
                         ...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';
 
 describe('GlobalVariableNoEvalTemplate (): string', () => {
-    describe('variant #1: simple', () => {
+    describe('Variant #1: simple', () => {
         const expectedGlobalObject: NodeJS.Global = 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;
 
         let globalObject: NodeJS.Global;
@@ -49,7 +49,7 @@ describe('GlobalVariableNoEvalTemplate (): string', () => {
         });
     });
 
-    describe('variant #3: return `window`', () => {
+    describe('Variant #3: return `window`', () => {
         const expectedGlobalObject: {} = {
             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('variant #1: correctly obfuscated code`', () => {
+    describe('Variant #1: correctly obfuscated code`', () => {
         const expectedEvaluationResult: number = 1;
 
         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;
 
         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;
 
         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;
 
         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;
 
         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);
     });
 
-    describe('variant #1: current domain matches with `domainsString`', () => {
+    describe('Variant #1: current domain matches with `domainsString`', () => {
         const domainsString: string = ['www.example.com'].join(';');
         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 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 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);
     });
 
-    describe('variant #1: `base64` encoding', () => {
+    describe('Variant #1: `base64` encoding', () => {
         const index: string = '0x0';
         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 key: string = 'key';
         const expectedDecodedValue: string = 'test1';

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

@@ -30,7 +30,7 @@ describe('JavaScriptObfuscator runtime eval', function () {
         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(
             eval(`${obfuscatedCode} sha256('test');`),
             '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'

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

@@ -6,7 +6,7 @@ describe('StackTraceAnalyzer', () => {
     describe('getLimitIndex (blockScopeBodyLength: number): number', () => {
         let limitIndex: number;
 
-        describe('variant #1: length - 10000', () => {
+        describe('Variant #1: length - 10000', () => {
             const blockScopeBodyLength: number = 10000;
             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 expectedLimitIndex: number = 26;
 
@@ -32,7 +32,7 @@ describe('StackTraceAnalyzer', () => {
             });
         });
 
-        describe('variant #3: length - 25', () => {
+        describe('Variant #3: length - 25', () => {
             const blockScopeBodyLength: number = 25;
             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 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: TCLISanitizer = (value: string): string[]', () => {
-        describe('variant #1: input value `foo`', () => {
+        describe('Variant #1: input value `foo`', () => {
             const inputValue: 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 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 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: TCLISanitizer = (value: string): boolean', () => {
-        describe('variant #1: input value `true`', () => {
+        describe('Variant #1: input value `true`', () => {
             const inputValue: string = '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 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 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 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: TCLISanitizer = (value: string): string', () => {
-        describe('variant #1: valid identifier names generator', () => {
+        describe('Variant #1: valid identifier names generator', () => {
             const inputValue: string = 'mangled';
             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';
 
             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: TCLISanitizer = (value: string): string', () => {
-        describe('variant #1: valid obfuscation target', () => {
+        describe('Variant #1: valid obfuscation target', () => {
             const inputValue: string = 'browser';
             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';
 
             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: TCLISanitizer = (value: string): string', () => {
-        describe('variant #1: valid source map mode', () => {
+        describe('Variant #1: valid source map mode', () => {
             const inputValue: string = 'inline';
             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';
 
             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: TCLISanitizer = (value: string): TStringArrayEncoding', () => {
-        describe('variant #1: string array encoding `base64`', () => {
+        describe('Variant #1: string array encoding `base64`', () => {
             const inputValue: string = 'base64';
             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 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 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 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 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('getOutputCodePath (inputPath: string): string', () => {
-        describe('variant #1: base input path', () => {
+        describe('Variant #1: base input path', () => {
             let expectedOutputPath: string = 'test/input/test-obfuscated.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',
                 inputPath: string = './input.js';
 
@@ -35,8 +35,8 @@ describe('CLIUtils', () => {
     });
 
     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 configFileName: string = 'config.js';
                 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 configFileName: string = 'config.json';
                 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 configFileName: string = 'configs.js';
             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';
 
 describe('SourceCodeReader', () => {
+    const expectedError: RegExp = /Given input path must be a valid/;
     const fileContent: string = 'test';
     const tmpDirectoryPath: string = 'test/tmp';
 
@@ -19,7 +20,7 @@ describe('SourceCodeReader', () => {
 
     describe('readSourceCode (inputPath: string): void', () => {
         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 inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;
 
@@ -27,7 +28,7 @@ describe('SourceCodeReader', () => {
 
                 before(() => {
                     fs.writeFileSync(inputPath, fileContent);
-                    result = SourceCodeReader.readSourceCode(inputPath);
+                    result = new SourceCodeReader({}).readSourceCode(inputPath);
                 });
 
                 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 inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;
 
                 let testFunc: () => void;
 
                 before(() => {
-                    testFunc = () => SourceCodeReader.readSourceCode(inputPath);
+                    testFunc = () => new SourceCodeReader({}).readSourceCode(inputPath);
                 });
 
                 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 inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;
 
@@ -62,21 +63,112 @@ describe('SourceCodeReader', () => {
 
                 before(() => {
                     fs.writeFileSync(inputPath, fileContent);
-                    testFunc = () => SourceCodeReader.readSourceCode(inputPath);
+                    testFunc = () => new SourceCodeReader({}).readSourceCode(inputPath);
                 });
 
                 it('should throw an error if `inputPath` has invalid extension', () => {
-                    assert.throws(testFunc, ReferenceError);
+                    assert.throws(testFunc, expectedError);
                 });
 
                 after(() => {
                     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('`inputPath` is a valid path', () => {
+            describe('Variant #1: `inputPath` is a valid path', () => {
                 const tmpFileName1: string = 'foo.js';
                 const tmpFileName2: string = 'bar.js';
                 const tmpFileName3: string = 'baz.png';
@@ -104,7 +196,7 @@ describe('SourceCodeReader', () => {
                     fs.writeFileSync(filePath2, fileContent);
                     fs.writeFileSync(filePath3, fileContent);
                     fs.writeFileSync(filePath4, fileContent);
-                    result = SourceCodeReader.readSourceCode(tmpDirectoryPath);
+                    result = new SourceCodeReader({}).readSourceCode(tmpDirectoryPath);
                 });
 
                 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';
 
                 let testFunc: () => void;
 
                 before(() => {
-                    testFunc = () => SourceCodeReader.readSourceCode(inputPath);
+                    testFunc = () => new SourceCodeReader({}).readSourceCode(inputPath);
                 });
 
                 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 parentDirectoryName2: string = 'parent';
                 const parentDirectoryPath1: string = `${tmpDirectoryPath}/${parentDirectoryName1}`;
@@ -175,7 +267,7 @@ describe('SourceCodeReader', () => {
                     fs.writeFileSync(filePath2, fileContent);
                     fs.writeFileSync(filePath3, fileContent);
                     fs.writeFileSync(filePath4, fileContent);
-                    result = SourceCodeReader.readSourceCode(tmpDirectoryPath);
+                    result = new SourceCodeReader({}).readSourceCode(tmpDirectoryPath);
                 });
 
                 it('should return files data', () => {
@@ -191,6 +283,233 @@ describe('SourceCodeReader', () => {
                     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', () => {
@@ -207,7 +526,7 @@ describe('SourceCodeReader', () => {
                 consoleLogSpy = sinon.spy(console, 'log');
 
                 fs.writeFileSync(inputPath, fileContent);
-                SourceCodeReader.readSourceCode(inputPath);
+                new SourceCodeReader({}).readSourceCode(inputPath);
 
                 consoleLogCallResult = consoleLogSpy.called;
                 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 (initializeMethodKey: string): any', () => {
-        describe('variant #1: property was initialized', () => {
+        describe('Variant #1: property was initialized', () => {
             const testFunc: () => void = () => {
                 class Foo implements IInitializable {
                     @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 = () => {
                     class Foo {
                         @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 = () => {
                     class Foo {
                         @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 = () => {
                     class Foo {
                         @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 = () => {
                     class Foo {
                         @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 = () => {
                     class Foo {
                         @initializable()
@@ -152,7 +152,7 @@ describe('@initializable', () => {
             });
         });
 
-        describe('variant #3: property didn\'t initialized', () => {
+        describe('Variant #3: property didn\'t initialized', () => {
             const testFunc: () => void = () => {
                 class Foo implements IInitializable {
                     @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 = () => {
                 class Foo {
                     @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';
 
             beforeEach(() => {
@@ -38,7 +38,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             });
         });
 
-        describe('variant #2: second mangled name', () => {
+        describe('Variant #2: second mangled name', () => {
             const expectedMangledIdentifierName: string = 'b';
             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 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 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 expectedMangledIdentifierPosition: number = 62;
 
@@ -98,7 +98,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             });
         });
 
-        describe('variant #6: reserved names', () => {
+        describe('Variant #6: reserved names', () => {
             const expectedMangledIdentifierName1: string = 'dn';
             const expectedMangledIdentifierName2: string = 'dp';
             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';
 
             beforeEach(() => {
@@ -157,7 +157,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             });
         });
 
-        describe('variant #2: second mangled name', () => {
+        describe('Variant #2: second mangled name', () => {
             const expectedMangledIdentifierName: string = 'foo_b';
 
             beforeEach(() => {

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

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

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

@@ -18,7 +18,7 @@ describe('JavaScriptObfuscator', () => {
 
             let javaScriptObfuscator: IJavaScriptObfuscator;
 
-            describe('variant #1: default behaviour', () => {
+            describe('Variant #1: default behaviour', () => {
                 const regExp: RegExp = new RegExp(`sourceMappingURL=${sourceMapUrl}`);
 
                 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 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);
         });
 
-        describe('variant #1: valid node', () => {
+        describe('Variant #1: valid node', () => {
             const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
 
             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(
                 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');
         });
 
-        describe('variant #1: nested function calls', () => {
+        describe('Variant #1: nested function calls', () => {
             beforeEach(() => {
                 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');
@@ -92,7 +92,7 @@ describe('NodeAppender', () => {
             });
         });
 
-        describe('variant #2: nested function calls', () => {
+        describe('Variant #2: nested function calls', () => {
             beforeEach(() => {
                 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');
@@ -114,7 +114,7 @@ describe('NodeAppender', () => {
                 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(() => {
                     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(() => {
                     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(() => {
                     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');

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

@@ -9,7 +9,7 @@ import { NodeUtils } from '../../../../src/node/NodeUtils';
 describe('NodeGuards', () => {
     describe('isNodeHasBlockScope (node: ESTree.Node): node is TNodeWithBlockScope', () => {
         describe('truthful checks', () => {
-            describe('variant #1: block statement of function declaration', () => {
+            describe('Variant #1: block statement of function declaration', () => {
                 const expectedResult: boolean = true;
                 const node: ESTree.Node = Nodes.getBlockStatementNode();
                 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 node: ESTree.Node = Nodes.getBlockStatementNode();
                 const parentNode: ESTree.FunctionExpression = Nodes.getFunctionExpressionNode(
@@ -52,7 +52,7 @@ describe('NodeGuards', () => {
         });
 
         describe('false checks', () => {
-            describe('variant #1: switch-case node', () => {
+            describe('Variant #1: switch-case node', () => {
                 const expectedResult: boolean = false;
                 const node: ESTree.Node = Nodes.getSwitchCaseNode(
                     Nodes.getLiteralNode(1),
@@ -88,7 +88,7 @@ describe('NodeGuards', () => {
                 });
             });
 
-            describe('variant #2: literal node', () => {
+            describe('Variant #2: literal node', () => {
                 const expectedResult: boolean = false;
                 const node: ESTree.Node = Nodes.getLiteralNode(1);
                 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 node: ESTree.Node = Nodes.getBlockStatementNode();
                 const parentNode: ESTree.IfStatement = Nodes.getIfStatementNode(
@@ -140,7 +140,7 @@ describe('NodeGuards', () => {
 
     describe('isNodeHasScope (node: ESTree.Node): node is TNodeWithScope', () => {
         describe('truthful checks', () => {
-            describe('variant #1: program node', () => {
+            describe('Variant #1: program node', () => {
                 const expectedResult: boolean = true;
                 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 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 node: ESTree.Node = Nodes.getSwitchCaseNode(
                     Nodes.getLiteralNode(1),
@@ -190,7 +190,7 @@ describe('NodeGuards', () => {
         });
 
         describe('false checks', () => {
-            describe('variant #1: literal node', () => {
+            describe('Variant #1: literal node', () => {
                 const expectedResult: boolean = false;
                 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 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 node: ESTree.Node = Nodes.getIfStatementNode(
                     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 node: ESTree.Node = Nodes.getSwitchStatementNode(
                     Nodes.getIdentifierNode('foo'),
@@ -260,7 +260,7 @@ describe('NodeGuards', () => {
 
     describe('isReplaceableIdentifierNode (node: ESTree.Node, parentNode: ESTree.Node): node is ESTree.Identifier', () => {
         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 identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 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 identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 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 identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 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 identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 const parentNode: ESTree.Node = Nodes.getMethodDefinitionNode(
@@ -347,7 +347,7 @@ describe('NodeGuards', () => {
         });
 
         describe('false checks', () => {
-            describe('variant #1: node isn\'t an identifier', () => {
+            describe('Variant #1: node isn\'t an identifier', () => {
                 const expectedResult: boolean = false;
                 const literal: ESTree.Literal = Nodes.getLiteralNode(1);
                 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 identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 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 identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 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 identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
                 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('variant #1: simple AST-tree', () => {
+        describe('Variant #1: simple AST-tree', () => {
             let programNode: 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,
                 expectedProgramNode: ESTree.Program;
 
@@ -295,7 +295,7 @@ describe('NodeUtils', () => {
     });
 
     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,
                 statementNode2: 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,
                 statementNode2: ESTree.Statement,
                 statementNode3: ESTree.Statement;
@@ -380,7 +380,7 @@ describe('NodeUtils', () => {
     });
 
     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,
                 statementNode2: 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,
                 statementNode2: 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(() => {
                 programNode = Nodes.getProgramNode([
                     ifStatementNode
@@ -685,7 +685,7 @@ describe('NodeUtils', () => {
             });
         });
 
-        describe('variant #2: parentize AST-tree', () => {
+        describe('Variant #2: parentize AST-tree', () => {
             beforeEach(() => {
                 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('variant #1: node with parent node', () => {
+        describe('Variant #1: node with parent node', () => {
             const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
             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 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('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 constraintRegExp: RegExp = /(?: *-)+ *constraint *text/;
             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 constraintRegExp1: RegExp = /(?: *-)+ constraint *text *#1/;
             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 = `` +
                 `\`foo\` *errors:\\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('variant #1: value exist', () => {
+        describe('Variant #1: value exist', () => {
             const expectedValue: string = storageValue;
 
             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;
 
             let testFunc: () => void;
@@ -126,7 +126,7 @@ describe('ArrayStorage', () => {
     describe('getKeyOf (value: T): number | null', () => {
         let key: string | number | null;
 
-        describe('variant #1', () => {
+        describe('Variant #1', () => {
             before(() => {
                 storage = getStorageInstance();
                 storage.set(storageKey, storageValue);
@@ -139,7 +139,7 @@ describe('ArrayStorage', () => {
             });
         });
 
-        describe('variant #2', () => {
+        describe('Variant #2', () => {
             const object: Object = {
                 foo: 'bar'
             };
@@ -156,7 +156,7 @@ describe('ArrayStorage', () => {
             });
         });
 
-        describe('variant #3', () => {
+        describe('Variant #3', () => {
             const expectedKey: null = null;
             const object: Object = {
                 foo: 'bar'

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

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

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

@@ -19,7 +19,7 @@ describe('EscapeSequenceEncoder', () => {
                 .get<IEscapeSequenceEncoder>(ServiceIdentifiers.IEscapeSequenceEncoder);
         });
 
-        describe('variant #1: default', () => {
+        describe('Variant #1: default', () => {
             const string: string = 'string';
             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 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('decToHex (dec: number): string', () => {
-        describe('variant #1: number `0`', () => {
+        describe('Variant #1: number `0`', () => {
             const number: number = 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 expectedHexString = 'a';
 
@@ -36,7 +36,7 @@ describe('Utils', () => {
             });
         });
 
-        describe('variant #3: number `17`', () => {
+        describe('Variant #3: number `17`', () => {
             const number: number = 17;
             const expectedHexString = '11';
 
@@ -51,7 +51,7 @@ describe('Utils', () => {
             });
         });
 
-        describe('variant #4: number `536870912`', () => {
+        describe('Variant #4: number `536870912`', () => {
             const number: number = 536870912;
             const expectedHexString = '20000000';
 
@@ -68,7 +68,7 @@ describe('Utils', () => {
     });
 
     describe('extractDomainFromUrl (url: string): string', () => {
-        describe('variant #1: simple url', () => {
+        describe('Variant #1: simple url', () => {
             const url: string = 'http://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 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 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 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 expectedDomain: string = 'localhost';
 

+ 31 - 4
yarn.lock

@@ -68,6 +68,10 @@
   version "2.2.48"
   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@*":
   version "8.0.53"
   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"
   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:
   version "0.2.1"
   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"
     regenerator-runtime "^0.10.5"
 
-babel-preset-env@^1.6.1:
[email protected]:
   version "1.6.1"
   resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48"
   dependencies:
@@ -2667,6 +2685,15 @@ [email protected]:
   version "2.0.0"
   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]:
   version "0.0.7"
   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"
   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:
     "@sinonjs/formatio" "^2.0.0"
     diff "^3.1.0"

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