Skip to content
This repository has been archived by the owner on Dec 5, 2019. It is now read-only.

Commit

Permalink
refactor: code and tests (#333)
Browse files Browse the repository at this point in the history
* refactor: stuff

* refactor: equal name convention for tests

* refactor: move test from `invalid` option to `UglifyJsPlugin` test

* refactor: more tests

* refactor: sort validate option as in docs
  • Loading branch information
evilebottnawi committed Jul 30, 2018
1 parent 24fe22b commit 726874b
Show file tree
Hide file tree
Showing 25 changed files with 277 additions and 241 deletions.
30 changes: 24 additions & 6 deletions src/index.js
Expand Up @@ -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]+)\]/;

Expand Down Expand Up @@ -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;
}

Expand All @@ -71,13 +79,15 @@ 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}]`);
}
return new Error(`${file} from UglifyJs\n${err.message} [${file}:${err.line},${err.col}]`);
} else if (err.stack) {
return new Error(`${file} from UglifyJs\n${err.stack}`);
}

return new Error(`${file} from UglifyJs\n${err.message}`);
}

Expand Down Expand Up @@ -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;
}
Expand All @@ -142,7 +154,7 @@ class UglifyJsPlugin {

input = source;

if (utils.isSourceMap(map)) {
if (UglifyJsPlugin.isSourceMap(map)) {
inputSourceMap = map;
} else {
inputSourceMap = map;
Expand All @@ -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);
}
Expand All @@ -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'),
Expand All @@ -202,6 +218,7 @@ class UglifyJsPlugin {
runner.runTasks(tasks, (tasksError, results) => {
if (tasksError) {
compilation.errors.push(tasksError);

return;
}

Expand Down Expand Up @@ -231,6 +248,7 @@ class UglifyJsPlugin {
}

let outputSource;

if (map) {
outputSource = new SourceMapSource(
code,
Expand Down
6 changes: 3 additions & 3 deletions src/options.json
Expand Up @@ -19,8 +19,6 @@
{ "type": "integer" }
]
},
"warningsFilter": {},
"extractComments": {},
"sourceMap": {
"type": "boolean"
},
Expand Down Expand Up @@ -67,7 +65,9 @@
"type": ["object", "null"]
}
}
}
},
"extractComments": {},
"warningsFilter": {}
},
"additionalProperties": false
}
Expand Down
5 changes: 0 additions & 5 deletions src/uglify/versions.js

This file was deleted.

13 changes: 0 additions & 13 deletions src/utils/index.js

This file was deleted.

233 changes: 232 additions & 1 deletion 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);
});
});

0 comments on commit 726874b

Please sign in to comment.