Repository: webpack-contrib/uglifyjs-webpack-plugin
Pull request #333 (2018-07-27 12:18:35)

Refactor stuff
Briefly:
1. Move some utils to class (we don't need extract require for some stuff).
2. Merge some identical tests.
3. Add test for validation.
4. Rename all test (example `sourceMap.test.js` -> `sourceMap-option.test.js`)


evilebottnawi: Merge as is, feel free to feedback

Patch:
diff --git a/src/index.js b/src/index.js
index b16fbbc..dab8c02 100644
--- a/src/index.js
+++ b/src/index.js
@@ -10,8 +10,6 @@ import ModuleFilenameHelpers from 'webpack/lib/ModuleFilenameHelpers';
 import validateOptions from 'schema-utils';
 import schema from './options.json';
 import Runner from './uglify/Runner';
-import versions from './uglify/versions';
-import utils from './utils';
 
 const warningRegex = /\[.+:([0-9]+),([0-9]+)\]/;
 
@@ -56,8 +54,18 @@ class UglifyJsPlugin {
     };
   }
 
+  static isSourceMap(input) {
+    // All required options for `new SourceMapConsumer(...options)`
+    // https://github.com/mozilla/source-map#new-sourcemapconsumerrawsourcemap
+    return Boolean(input &&
+      input.version &&
+      input.sources &&
+      Array.isArray(input.sources) &&
+      typeof input.mappings === 'string');
+  }
+
   static buildSourceMap(inputSourceMap) {
-    if (!inputSourceMap || !utils.isSourceMap(inputSourceMap)) {
+    if (!inputSourceMap || !UglifyJsPlugin.isSourceMap(inputSourceMap)) {
       return null;
     }
 
@@ -71,6 +79,7 @@ class UglifyJsPlugin {
         line: err.line,
         column: err.col,
       });
+
       if (original && original.source) {
         return new Error(`${file} from UglifyJs\n${err.message} [${requestShortener.shorten(original.source)}:${original.line},${original.column}][${file}:${err.line},${err.col}]`);
       }
@@ -78,6 +87,7 @@ class UglifyJsPlugin {
     } else if (err.stack) {
       return new Error(`${file} from UglifyJs\n${err.stack}`);
     }
+
     return new Error(`${file} from UglifyJs\n${err.message}`);
   }
 
@@ -129,7 +139,9 @@ class UglifyJsPlugin {
         .filter(ModuleFilenameHelpers.matchObject.bind(null, this.options))
         .forEach((file) => {
           let inputSourceMap;
+
           const asset = compilation.assets[file];
+
           if (uglifiedAssets.has(asset)) {
             return;
           }
@@ -142,7 +154,7 @@ class UglifyJsPlugin {
 
               input = source;
 
-              if (utils.isSourceMap(map)) {
+              if (UglifyJsPlugin.isSourceMap(map)) {
                 inputSourceMap = map;
               } else {
                 inputSourceMap = map;
@@ -157,8 +169,10 @@ class UglifyJsPlugin {
 
             // Handling comment extraction
             let commentsFile = false;
+
             if (this.options.extractComments) {
               commentsFile = this.options.extractComments.filename || `${file}.LICENSE`;
+
               if (typeof commentsFile === 'function') {
                 commentsFile = commentsFile(file);
               }
@@ -176,8 +190,10 @@ class UglifyJsPlugin {
 
             if (this.options.cache) {
               const defaultCacheKeys = {
-                'uglify-es': versions.uglify,
-                'uglifyjs-webpack-plugin': versions.plugin,
+                // eslint-disable-next-line global-require
+                'uglify-es': require('uglify-es/package.json').version,
+                // eslint-disable-next-line global-require
+                'uglifyjs-webpack-plugin': require('../package.json').version,
                 'uglifyjs-webpack-plugin-options': this.options,
                 path: compiler.outputPath ? `${compiler.outputPath}/${file}` : file,
                 hash: crypto.createHash('md4').update(input).digest('hex'),
@@ -202,6 +218,7 @@ class UglifyJsPlugin {
       runner.runTasks(tasks, (tasksError, results) => {
         if (tasksError) {
           compilation.errors.push(tasksError);
+
           return;
         }
 
@@ -231,6 +248,7 @@ class UglifyJsPlugin {
           }
 
           let outputSource;
+
           if (map) {
             outputSource = new SourceMapSource(
               code,
diff --git a/src/options.json b/src/options.json
index 76a09d2..f9ee386 100644
--- a/src/options.json
+++ b/src/options.json
@@ -19,8 +19,6 @@
         { "type": "integer" }
       ]
     },
-    "warningsFilter": {},
-    "extractComments": {},
     "sourceMap": {
       "type": "boolean"
     },
@@ -67,7 +65,9 @@
           "type": ["object", "null"]
         }
       }
-    }
+    },
+    "extractComments": {},
+    "warningsFilter": {}
   },
   "additionalProperties": false
 }
diff --git a/src/uglify/versions.js b/src/uglify/versions.js
deleted file mode 100644
index d398e95..0000000
--- a/src/uglify/versions.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export default {
-  uglify: require('uglify-es/package.json').version, // eslint-disable-line global-require
-  plugin: require('../../package.json').version, // eslint-disable-line global-require
-};
-
diff --git a/src/utils/index.js b/src/utils/index.js
deleted file mode 100644
index 68ff51e..0000000
--- a/src/utils/index.js
+++ /dev/null
@@ -1,13 +0,0 @@
-function isSourceMap(input) {
-  // All required options for `new SourceMapConsumer(...options)`
-  // https://github.com/mozilla/source-map#new-sourcemapconsumerrawsourcemap
-  return Boolean(input &&
-    input.version &&
-    input.sources &&
-    Array.isArray(input.sources) &&
-    typeof input.mappings === 'string');
-}
-
-export default {
-  isSourceMap,
-};


Test patch:
diff --git a/test/UglifyJsPlugin.test.js b/test/UglifyJsPlugin.test.js
index 75d6a52..bae86b0 100644
--- a/test/UglifyJsPlugin.test.js
+++ b/test/UglifyJsPlugin.test.js
@@ -1,7 +1,238 @@
 import UglifyJsPlugin from '../src/index';
+import { cleanErrorStack, compile, createCompiler } from './helpers';
 
 describe('UglifyJsPlugin', () => {
-  it('has apply function', () => {
+  it('export as function', () => {
     expect(typeof new UglifyJsPlugin().apply).toBe('function');
   });
+
+  it('validation errors', () => {
+    /* eslint-disable no-new */
+    expect(() => {
+      new UglifyJsPlugin({ test: /foo/ });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ test: [/foo/] });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ include: /foo/ });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ include: [/foo/] });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ exclude: /foo/ });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ exclude: [/foo/] });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ doesntExist: true });
+    }).toThrowErrorMatchingSnapshot();
+
+    expect(() => {
+      new UglifyJsPlugin({ cache: true });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ cache: false });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ cache: 'path/to/cache/directory' });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ cache: {} });
+    }).toThrowErrorMatchingSnapshot();
+
+    expect(() => {
+      new UglifyJsPlugin({ cacheKeys() {} });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ parallel: true });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ parallel: false });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ parallel: 2 });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ parallel: '2' });
+    }).toThrowErrorMatchingSnapshot();
+
+    expect(() => {
+      new UglifyJsPlugin({ parallel: {} });
+    }).toThrowErrorMatchingSnapshot();
+
+    expect(() => {
+      new UglifyJsPlugin({ sourceMap: true });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ sourceMap: false });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ sourceMap: 'true' });
+    }).toThrowErrorMatchingSnapshot();
+
+    expect(() => {
+      new UglifyJsPlugin({ minify() {} });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ uglifyOptions: null });
+    }).toThrowErrorMatchingSnapshot();
+
+    expect(() => {
+      new UglifyJsPlugin({ uglifyOptions: {} });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({
+        uglifyOptions: {
+          ecma: 5,
+          warnings: false,
+          parse: {},
+          compress: true,
+          mangle: { inline: false },
+          output: { comments: /^\**!|@preserve|@license|@cc_on/ },
+          toplevel: false,
+          nameCache: {},
+          ie8: false,
+          keep_classnames: false,
+          keep_fnames: false,
+          safari10: false,
+        },
+      });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ uglifyOptions: { ie8: false } });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ uglifyOptions: { ie8: true } });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ uglifyOptions: { ie8: 'false' } });
+    }).toThrowErrorMatchingSnapshot();
+
+    expect(() => {
+      new UglifyJsPlugin({ uglifyOptions: { emca: 5 } });
+    }).not.toThrow();
+
+    expect(() => {
+      new UglifyJsPlugin({ uglifyOptions: { emca: 8 } });
+    }).not.toThrow();
+
+    expect(() => {
+      new UglifyJsPlugin({ uglifyOptions: { ecma: 7.5 } });
+    }).toThrowErrorMatchingSnapshot();
+
+    expect(() => {
+      new UglifyJsPlugin({ uglifyOptions: { ecma: true } });
+    }).toThrowErrorMatchingSnapshot();
+
+    expect(() => {
+      new UglifyJsPlugin({ uglifyOptions: { ecma: '5' } });
+    }).toThrowErrorMatchingSnapshot();
+
+    expect(() => {
+      new UglifyJsPlugin({ uglifyOptions: { ecma: 3 } });
+    }).toThrowErrorMatchingSnapshot();
+
+    expect(() => {
+      new UglifyJsPlugin({ uglifyOptions: { ecma: 10 } });
+    }).toThrowErrorMatchingSnapshot();
+
+    expect(() => {
+      new UglifyJsPlugin({ extractComments: true });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ extractComments: false });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ extractComments: /comment/ });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ extractComments() {} });
+    }).not.toThrow('Validation Error');
+
+    expect(() => {
+      new UglifyJsPlugin({ warningsFilter() {} });
+    }).not.toThrow('Validation Error');
+  });
+
+  it('contain errors when uglify has unknown option', () => {
+    const compiler = createCompiler();
+    new UglifyJsPlugin({
+      uglifyOptions: {
+        output: {
+          unknown: true,
+        },
+      },
+    }).apply(compiler);
+
+    return compile(compiler).then((stats) => {
+      const errors = stats.compilation.errors.map(cleanErrorStack);
+      const warnings = stats.compilation.warnings.map(cleanErrorStack);
+
+      expect(errors).toMatchSnapshot('errors');
+      expect(warnings).toMatchSnapshot('warnings');
+
+      for (const file in stats.compilation.assets) {
+        if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) {
+          expect(stats.compilation.assets[file].source()).toMatchSnapshot(file);
+        }
+      }
+    });
+  });
+
+  it('isSourceMap method', () => {
+    const rawSourceMap = {
+      version: 3,
+      file: 'min.js',
+      names: ['bar', 'baz', 'n'],
+      sources: ['one.js', 'two.js'],
+      sourceRoot: 'http://example.com/www/js/',
+      mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA',
+    };
+    const emptyRawSourceMap = {
+      version: 3,
+      sources: [],
+      mappings: '',
+    };
+
+    expect(UglifyJsPlugin.isSourceMap(null)).toBe(false);
+    expect(UglifyJsPlugin.isSourceMap()).toBe(false);
+    expect(UglifyJsPlugin.isSourceMap({})).toBe(false);
+    expect(UglifyJsPlugin.isSourceMap([])).toBe(false);
+    expect(UglifyJsPlugin.isSourceMap('foo')).toBe(false);
+    expect(UglifyJsPlugin.isSourceMap({ version: 3 })).toBe(false);
+    expect(UglifyJsPlugin.isSourceMap({ sources: '' })).toBe(false);
+    expect(UglifyJsPlugin.isSourceMap({ mappings: [] })).toBe(false);
+    expect(UglifyJsPlugin.isSourceMap({ version: 3, sources: '' })).toBe(false);
+    expect(UglifyJsPlugin.isSourceMap({ version: 3, mappings: [] })).toBe(false);
+    expect(UglifyJsPlugin.isSourceMap({ sources: '', mappings: [] })).toBe(false);
+    expect(UglifyJsPlugin.isSourceMap({ version: 3, sources: '', mappings: [] })).toBe(false);
+    expect(UglifyJsPlugin.isSourceMap(rawSourceMap)).toBe(true);
+    expect(UglifyJsPlugin.isSourceMap(emptyRawSourceMap)).toBe(true);
+  });
 });
diff --git a/test/__snapshots__/invalid-options.test.js.snap b/test/__snapshots__/UglifyJsPlugin.test.js.snap
similarity index 79%
rename from test/__snapshots__/invalid-options.test.js.snap
rename to test/__snapshots__/UglifyJsPlugin.test.js.snap
index 4ca3b51..7f05267 100644
--- a/test/__snapshots__/invalid-options.test.js.snap
+++ b/test/__snapshots__/UglifyJsPlugin.test.js.snap
@@ -1,15 +1,15 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`when applied with invalid options matches snapshot: errors 1`] = `
+exports[`UglifyJsPlugin contain errors when uglify has unknown option: errors 1`] = `
 Array [
   "Error: main.0c220ec66316af2c1b24.js from UglifyJs
-DefaultsError: \`invalid-option\` is not a supported option",
+DefaultsError: \`unknown\` is not a supported option",
   "Error: manifest.d6857f782c13a99b5917.js from UglifyJs
-DefaultsError: \`invalid-option\` is not a supported option",
+DefaultsError: \`unknown\` is not a supported option",
 ]
 `;
 
-exports[`when applied with invalid options matches snapshot: main.0c220ec66316af2c1b24.js 1`] = `
+exports[`UglifyJsPlugin contain errors when uglify has unknown option: main.0c220ec66316af2c1b24.js 1`] = `
 "webpackJsonp([0],[
 /* 0 */
 /***/ (function(module, exports) {
@@ -29,7 +29,7 @@ module.exports = function Foo() {
 ],[0]);"
 `;
 
-exports[`when applied with invalid options matches snapshot: manifest.d6857f782c13a99b5917.js 1`] = `
+exports[`UglifyJsPlugin contain errors when uglify has unknown option: manifest.d6857f782c13a99b5917.js 1`] = `
 "/******/ (function(modules) { // webpackBootstrap
 /******/ 	// install a JSONP callback for chunk loading
 /******/ 	var parentJsonpFunction = window[\\"webpackJsonp\\"];
@@ -133,16 +133,16 @@ exports[`when applied with invalid options matches snapshot: manifest.d6857f782c
 /******/ ([]);"
 `;
 
-exports[`when applied with invalid options matches snapshot: warnings 1`] = `Array []`;
+exports[`UglifyJsPlugin contain errors when uglify has unknown option: warnings 1`] = `Array []`;
 
-exports[`when applied with invalid options throws validation errors 1`] = `
+exports[`UglifyJsPlugin validation errors 1`] = `
 "UglifyJs Plugin Invalid Options
 
 options['doesntExist'] is an invalid additional property
 "
 `;
 
-exports[`when applied with invalid options throws validation errors 2`] = `
+exports[`UglifyJsPlugin validation errors 2`] = `
 "UglifyJs Plugin Invalid Options
 
 options.cache should be boolean
@@ -151,7 +151,7 @@ options.cache should match exactly one schema in oneOf
 "
 `;
 
-exports[`when applied with invalid options throws validation errors 3`] = `
+exports[`UglifyJsPlugin validation errors 3`] = `
 "UglifyJs Plugin Invalid Options
 
 options.parallel should be boolean
@@ -160,7 +160,7 @@ options.parallel should match exactly one schema in oneOf
 "
 `;
 
-exports[`when applied with invalid options throws validation errors 4`] = `
+exports[`UglifyJsPlugin validation errors 4`] = `
 "UglifyJs Plugin Invalid Options
 
 options.parallel should be boolean
@@ -169,56 +169,56 @@ options.parallel should match exactly one schema in oneOf
 "
 `;
 
-exports[`when applied with invalid options throws validation errors 5`] = `
+exports[`UglifyJsPlugin validation errors 5`] = `
 "UglifyJs Plugin Invalid Options
 
 options.sourceMap should be boolean
 "
 `;
 
-exports[`when applied with invalid options throws validation errors 6`] = `
+exports[`UglifyJsPlugin validation errors 6`] = `
 "UglifyJs Plugin Invalid Options
 
 options.uglifyOptions should be object
 "
 `;
 
-exports[`when applied with invalid options throws validation errors 7`] = `
+exports[`UglifyJsPlugin validation errors 7`] = `
 "UglifyJs Plugin Invalid Options
 
 options.uglifyOptions.ie8 should be boolean
 "
 `;
 
-exports[`when applied with invalid options throws validation errors 8`] = `
+exports[`UglifyJsPlugin validation errors 8`] = `
 "UglifyJs Plugin Invalid Options
 
 options.uglifyOptions.ecma should be integer
 "
 `;
 
-exports[`when applied with invalid options throws validation errors 9`] = `
+exports[`UglifyJsPlugin validation errors 9`] = `
 "UglifyJs Plugin Invalid Options
 
 options.uglifyOptions.ecma should be integer
 "
 `;
 
-exports[`when applied with invalid options throws validation errors 10`] = `
+exports[`UglifyJsPlugin validation errors 10`] = `
 "UglifyJs Plugin Invalid Options
 
 options.uglifyOptions.ecma should be integer
 "
 `;
 
-exports[`when applied with invalid options throws validation errors 11`] = `
+exports[`UglifyJsPlugin validation errors 11`] = `
 "UglifyJs Plugin Invalid Options
 
 options.uglifyOptions.ecma should be >= 5
 "
 `;
 
-exports[`when applied with invalid options throws validation errors 12`] = `
+exports[`UglifyJsPlugin validation errors 12`] = `
 "UglifyJs Plugin Invalid Options
 
 options.uglifyOptions.ecma should be <= 8
diff --git a/test/__snapshots__/cache-options.test.js.snap b/test/__snapshots__/cache-option.test.js.snap
similarity index 100%
rename from test/__snapshots__/cache-options.test.js.snap
rename to test/__snapshots__/cache-option.test.js.snap
diff --git a/test/__snapshots__/extract-comments-options.test.js.snap b/test/__snapshots__/extractComments-option.test.js.snap
similarity index 100%
rename from test/__snapshots__/extract-comments-options.test.js.snap
rename to test/__snapshots__/extractComments-option.test.js.snap
diff --git a/test/__snapshots__/include-options.test.js.snap b/test/__snapshots__/include-option.test.js.snap
similarity index 100%
rename from test/__snapshots__/include-options.test.js.snap
rename to test/__snapshots__/include-option.test.js.snap
diff --git a/test/__snapshots__/minify.test.js.snap b/test/__snapshots__/minify-option.test.js.snap
similarity index 100%
rename from test/__snapshots__/minify.test.js.snap
rename to test/__snapshots__/minify-option.test.js.snap
diff --git a/test/__snapshots__/parallel-options.test.js.snap b/test/__snapshots__/parallel-option.test.js.snap
similarity index 100%
rename from test/__snapshots__/parallel-options.test.js.snap
rename to test/__snapshots__/parallel-option.test.js.snap
diff --git a/test/__snapshots__/source-map-options.test.js.snap b/test/__snapshots__/sourceMap-option.test.js.snap
similarity index 100%
rename from test/__snapshots__/source-map-options.test.js.snap
rename to test/__snapshots__/sourceMap-option.test.js.snap
diff --git a/test/__snapshots__/test.test.js.snap b/test/__snapshots__/test-option.test.js.snap
similarity index 100%
rename from test/__snapshots__/test.test.js.snap
rename to test/__snapshots__/test-option.test.js.snap
diff --git a/test/__snapshots__/uglify-options.test.js.snap b/test/__snapshots__/uglifyOptions-option.test.js.snap
similarity index 100%
rename from test/__snapshots__/uglify-options.test.js.snap
rename to test/__snapshots__/uglifyOptions-option.test.js.snap
diff --git a/test/cache-options.test.js b/test/cache-option.test.js
similarity index 100%
rename from test/cache-options.test.js
rename to test/cache-option.test.js
diff --git a/test/extract-option-set-to-a-single-file.test.js b/test/extractComments-option-set-to-a-single-file.test.js
similarity index 100%
rename from test/extract-option-set-to-a-single-file.test.js
rename to test/extractComments-option-set-to-a-single-file.test.js
diff --git a/test/extract-comments-options.test.js b/test/extractComments-option.test.js
similarity index 100%
rename from test/extract-comments-options.test.js
rename to test/extractComments-option.test.js
diff --git a/test/include-options.test.js b/test/include-option.test.js
similarity index 100%
rename from test/include-options.test.js
rename to test/include-option.test.js
diff --git a/test/invalid-options.test.js b/test/invalid-options.test.js
deleted file mode 100644
index 7cb092c..0000000
--- a/test/invalid-options.test.js
+++ /dev/null
@@ -1,161 +0,0 @@
-import UglifyJsPlugin from '../src/index';
-import {
-  PluginEnvironment,
-  cleanErrorStack,
-  createCompiler,
-  compile,
-} from './helpers';
-
-describe('when applied with invalid options', () => {
-  it('matches snapshot', () => {
-    const compiler = createCompiler();
-    new UglifyJsPlugin({
-      uglifyOptions: {
-        output: {
-          'invalid-option': true,
-        },
-      },
-    }).apply(compiler);
-
-    return compile(compiler).then((stats) => {
-      const errors = stats.compilation.errors.map(cleanErrorStack);
-      const warnings = stats.compilation.warnings.map(cleanErrorStack);
-
-      expect(errors).toMatchSnapshot('errors');
-      expect(warnings).toMatchSnapshot('warnings');
-
-      for (const file in stats.compilation.assets) {
-        if (Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)) {
-          expect(stats.compilation.assets[file].source()).toMatchSnapshot(file);
-        }
-      }
-    });
-  });
-
-  it('throws validation errors', () => {
-    /* eslint-disable no-new */
-    expect(() => {
-      new UglifyJsPlugin({ test: /foo/ });
-    }).not.toThrow('Validation Error');
-
-    expect(() => {
-      new UglifyJsPlugin({ doesntExist: true });
-    }).toThrowErrorMatchingSnapshot();
-
-    expect(() => {
-      new UglifyJsPlugin({ cache: true });
-    }).not.toThrow('Validation Error');
-
-    expect(() => {
-      new UglifyJsPlugin({ cache: 'path/to/cache/directory' });
-    }).not.toThrow('Validation Error');
-
-    expect(() => {
-      new UglifyJsPlugin({ cache: {} });
-    }).toThrowErrorMatchingSnapshot();
-
-    expect(() => {
-      new UglifyJsPlugin({ parallel: true });
-    }).not.toThrow('Validation Error');
-
-    expect(() => {
-      new UglifyJsPlugin({ parallel: 2 });
-    }).not.toThrow('Validation Error');
-
-    expect(() => {
-      new UglifyJsPlugin({ parallel: '2' });
-    }).toThrowErrorMatchingSnapshot();
-
-    expect(() => {
-      new UglifyJsPlugin({ parallel: {} });
-    }).toThrowErrorMatchingSnapshot();
-
-    expect(() => {
-      new UglifyJsPlugin({ sourceMap: true });
-    }).not.toThrow('Validation Error');
-
-    expect(() => {
-      new UglifyJsPlugin({ sourceMap: 'true' });
-    }).toThrowErrorMatchingSnapshot();
-
-    expect(() => {
-      new UglifyJsPlugin({ uglifyOptions: null });
-    }).toThrowErrorMatchingSnapshot();
-
-    expect(() => {
-      new UglifyJsPlugin({ uglifyOptions: { ie8: false } });
-    }).not.toThrow('Validation Error');
-
-    expect(() => {
-      new UglifyJsPlugin({ uglifyOptions: { ie8: true } });
-    }).not.toThrow('Validation Error');
-
-    expect(() => {
-      new UglifyJsPlugin({ uglifyOptions: { ie8: 'false' } });
-    }).toThrowErrorMatchingSnapshot();
-
-    expect(() => {
-      new UglifyJsPlugin({ uglifyOptions: { emca: 5 } });
-    }).not.toThrow();
-
-    expect(() => {
-      new UglifyJsPlugin({ uglifyOptions: { emca: 8 } });
-    }).not.toThrow();
-
-    expect(() => {
-      new UglifyJsPlugin({ uglifyOptions: { ecma: 7.5 } });
-    }).toThrowErrorMatchingSnapshot();
-
-    expect(() => {
-      new UglifyJsPlugin({ uglifyOptions: { ecma: true } });
-    }).toThrowErrorMatchingSnapshot();
-
-    expect(() => {
-      new UglifyJsPlugin({ uglifyOptions: { ecma: '5' } });
-    }).toThrowErrorMatchingSnapshot();
-
-    expect(() => {
-      new UglifyJsPlugin({ uglifyOptions: { ecma: 3 } });
-    }).toThrowErrorMatchingSnapshot();
-
-    expect(() => {
-      new UglifyJsPlugin({ uglifyOptions: { ecma: 10 } });
-    }).toThrowErrorMatchingSnapshot();
-  });
-
-  it('outputs uglify errors', () => {
-    const pluginEnvironment = new PluginEnvironment();
-    const compilerEnv = pluginEnvironment.getEnvironmentStub();
-    compilerEnv.context = '';
-
-    const plugin = new UglifyJsPlugin({
-      uglifyOptions: {
-        output: {
-          'invalid-option': true,
-        },
-      },
-    });
-    plugin.apply(compilerEnv);
-    const [eventBinding] = pluginEnvironment.getEventBindings();
-
-    const chunkPluginEnvironment = new PluginEnvironment();
-    const compilation = chunkPluginEnvironment.getEnvironmentStub();
-    compilation.assets = {
-      'test.js': {
-        source: () => 'var foo = 1;',
-      },
-    };
-    compilation.errors = [];
-
-    eventBinding.handler(compilation);
-    const [compilationEventBinding] = chunkPluginEnvironment.getEventBindings();
-
-    compilationEventBinding.handler([{
-      files: ['test.js'],
-    }], () => {
-      expect(compilation.errors.length).toBe(1);
-      expect(compilation.errors[0]).toBeInstanceOf(Error);
-      expect(compilation.errors[0].message).toEqual(expect.stringContaining('from UglifyJs'));
-    });
-  });
-});
diff --git a/test/minify.test.js b/test/minify-option.test.js
similarity index 100%
rename from test/minify.test.js
rename to test/minify-option.test.js
diff --git a/test/parallel-options.test.js b/test/parallel-option.test.js
similarity index 100%
rename from test/parallel-options.test.js
rename to test/parallel-option.test.js
diff --git a/test/source-map-options.test.js b/test/sourceMap-option.test.js
similarity index 100%
rename from test/source-map-options.test.js
rename to test/sourceMap-option.test.js
diff --git a/test/test.test.js b/test/test-option.test.js
similarity index 100%
rename from test/test.test.js
rename to test/test-option.test.js
diff --git a/test/uglify-options.test.js b/test/uglifyOptions-option.test.js
similarity index 100%
rename from test/uglify-options.test.js
rename to test/uglifyOptions-option.test.js
diff --git a/test/utils/index.test.js b/test/utils/index.test.js
deleted file mode 100644
index 3a27a19..0000000
--- a/test/utils/index.test.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import utils from '../../src/utils';
-
-describe('utils', () => {
-  it('isSourceMap', () => {
-    const rawSourceMap = {
-      version: 3,
-      file: 'min.js',
-      names: ['bar', 'baz', 'n'],
-      sources: ['one.js', 'two.js'],
-      sourceRoot: 'http://example.com/www/js/',
-      mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA',
-    };
-    const emptyRawSourceMap = {
-      version: 3,
-      sources: [],
-      mappings: '',
-    };
-
-    expect(utils.isSourceMap(null)).toBe(false);
-    expect(utils.isSourceMap()).toBe(false);
-    expect(utils.isSourceMap({})).toBe(false);
-    expect(utils.isSourceMap([])).toBe(false);
-    expect(utils.isSourceMap('foo')).toBe(false);
-    expect(utils.isSourceMap({ version: 3 })).toBe(false);
-    expect(utils.isSourceMap({ sources: '' })).toBe(false);
-    expect(utils.isSourceMap({ mappings: [] })).toBe(false);
-    expect(utils.isSourceMap({ version: 3, sources: '' })).toBe(false);
-    expect(utils.isSourceMap({ version: 3, mappings: [] })).toBe(false);
-    expect(utils.isSourceMap({ sources: '', mappings: [] })).toBe(false);
-    expect(utils.isSourceMap({ version: 3, sources: '', mappings: [] })).toBe(false);
-    expect(utils.isSourceMap(rawSourceMap)).toBe(true);
-    expect(utils.isSourceMap(emptyRawSourceMap)).toBe(true);
-  });
-});