diff --git a/package-lock.json b/package-lock.json index d5c8d661..bb60876d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,16 +5,17 @@ "requires": true, "dependencies": { "@commitlint/cli": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-5.2.5.tgz", - "integrity": "sha512-UoWLCBuLHpZ6yMq1WUQhOD4YGAx3vakxe98kAiv5ekKCWN2PNJpXAyjyYjqS5P4IMKE0fU37FL1f9LqjsiS5+w==", + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-5.2.8.tgz", + "integrity": "sha512-XSej+/Pvl3gMOahEZpbsE5F1hPzMVPMXuK6MWZxsou3fyPUeAzHK9F2C76WCDVLIBVte/lxow7QQtUtMQEyiOg==", "dev": true, "requires": { - "@commitlint/core": "5.2.5", + "@commitlint/core": "5.2.8", "babel-polyfill": "6.26.0", "chalk": "2.3.0", "get-stdin": "5.0.1", - "lodash": "4.17.4", + "lodash.merge": "4.6.0", + "lodash.pick": "4.4.0", "meow": "3.7.0" } }, @@ -34,24 +35,115 @@ "dev": true }, "@commitlint/core": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/@commitlint/core/-/core-5.2.5.tgz", - "integrity": "sha512-YWyxMQT8x2VJ9xkXLYbruq272A9TfjLGZTClNl/C4EX2o0bdBce6Kk/2PdyPWpA2++1bTZ0T4zUAE1wqh1Y75g==", + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@commitlint/core/-/core-5.2.8.tgz", + "integrity": "sha512-E/2gJ6BpO43E3OeT1z99oPzVu9SHOprdjiBZ8ZwgmW8NynzhfSsSqrP+fHcro0ig8FcynRI/tYnpGeBGFC8DXg==", "dev": true, "requires": { + "@commitlint/execute-rule": "5.2.8", + "@commitlint/is-ignored": "5.2.8", + "@commitlint/parse": "5.2.8", + "@commitlint/resolve-extends": "5.2.8", + "@commitlint/rules": "5.2.8", + "@commitlint/top-level": "5.2.8", "@marionebl/sander": "0.6.1", "babel-runtime": "6.26.0", "chalk": "2.3.0", - "conventional-changelog-angular": "1.6.0", - "conventional-commits-parser": "2.1.0", "cosmiconfig": "3.1.0", - "find-up": "2.1.0", "git-raw-commits": "1.3.0", - "lodash": "4.17.4", + "lodash.merge": "4.6.0", + "lodash.mergewith": "4.6.0", + "lodash.pick": "4.4.0", + "lodash.topairs": "4.3.0", + "resolve-from": "4.0.0" + } + }, + "@commitlint/ensure": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-5.2.8.tgz", + "integrity": "sha512-SWclCuYUmzTUDw0RL/ktO6qzkX2uo3PwGz+4nEyZK00ZCnZk9V99A4AX1fW3VyhB3J1C40QIztNGpafk3iCvkg==", + "dev": true, + "requires": { + "lodash.camelcase": "4.3.0", + "lodash.kebabcase": "4.1.1", + "lodash.snakecase": "4.1.1", + "lodash.startcase": "4.4.0", + "lodash.upperfirst": "4.3.1" + } + }, + "@commitlint/execute-rule": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-5.2.8.tgz", + "integrity": "sha512-0ShMDkTXdGnb21U2MfTtpnhySVZJ8FuEH4F9S9c0zoRlbVrphIfX8m+2T4p4ge3AGM0E/QDi8bZqLrD/E8edHQ==", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "@commitlint/is-ignored": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-5.2.8.tgz", + "integrity": "sha512-AGViKcJ2/F2HXJNM+vBHxGrAMxJ3ZXGqQYZXC9hjF5d1x3tLFe5uYkI2WBdX6YiAsZbKk5a+Cchr2qojkckqRA==", + "dev": true, + "requires": { + "semver": "5.4.1" + } + }, + "@commitlint/message": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-5.2.8.tgz", + "integrity": "sha512-5k4pOPX5hwS34xAYzSZZFxsW0MCaJbbcjCTiqbyf8WEPep0ru2dsZg6EsBqLTe9IG1YjQM/Z5/udkfIwBXOYpw==", + "dev": true + }, + "@commitlint/parse": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-5.2.8.tgz", + "integrity": "sha512-XSBuLXuyOJ7u4aOM4XdGUvcfaLZ8By4abFF9VzF6tbek+R3jylSlrULqeX8oNnzkSn2PWtf9sYDb2dt5z9XWjw==", + "dev": true, + "requires": { + "conventional-changelog-angular": "1.6.0", + "conventional-commits-parser": "2.1.0" + } + }, + "@commitlint/resolve-extends": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-5.2.8.tgz", + "integrity": "sha512-3d4Qk5/IQiX95nGn5pmtPAkoueKZLgz8VCdOxf1fNegudyl2EaRxKLIoaZ9DmZz6RE1CpRCinvsFFdESq3tvTw==", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "lodash.merge": "4.6.0", + "lodash.omit": "4.5.0", "require-uncached": "1.0.3", "resolve-from": "4.0.0", - "resolve-global": "0.1.0", - "semver": "5.4.1" + "resolve-global": "0.1.0" + } + }, + "@commitlint/rules": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-5.2.8.tgz", + "integrity": "sha512-R2shsQJk2q0Wd+zBKbeKDVJszEpiTNL7OnPavXr9wdseHPtpXNUTn3YiWtipgNOW3Rfb9t2A5mxgn0uF0ce3iQ==", + "dev": true, + "requires": { + "@commitlint/ensure": "5.2.8", + "@commitlint/message": "5.2.8", + "@commitlint/to-lines": "5.2.8", + "babel-runtime": "6.26.0" + } + }, + "@commitlint/to-lines": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-5.2.8.tgz", + "integrity": "sha512-BI0wuimKkV/DrEHf7Ze2DIY9tY9E1MWz3/Ox3hheyQeTjDD3MSNdEs4KmXtIXfoAAPifOMmRUccbcEIR6vW3UQ==", + "dev": true + }, + "@commitlint/top-level": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-5.2.8.tgz", + "integrity": "sha512-0WdwHKLUXVCr2CYtAIZWdYLo4kSIlEs+q24/rt55SNl7/QRT6/UKMiyHN/gLeK7Q0CzEOebXD8Jjrl3BCUTyYg==", + "dev": true, + "requires": { + "find-up": "2.1.0" } }, "@marionebl/sander": { @@ -2138,9 +2230,9 @@ } }, "cross-env": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.1.1.tgz", - "integrity": "sha512-Wtvr+z0Z06KO1JxjfRRsPC+df7biIOiuV4iZ73cThjFGkH+ULBZq1MkBdywEcJC4cTDbO6c8IjgRjfswx3YTBA==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.1.3.tgz", + "integrity": "sha512-UOokgwvDzCT0mqRSLEkJzUhYXB1vK3E5UgDrD41QiXsm9UetcW2rCGHYz/O3p873lMJ1VZbFCF9Izkwh7nYR5A==", "dev": true, "requires": { "cross-spawn": "5.1.0", @@ -2575,9 +2667,9 @@ } }, "eslint": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.13.1.tgz", - "integrity": "sha512-UCJVV50RtLHYzBp1DZ8CMPtRSg4iVZvjgO9IJHIKyWU/AnJVjtdRikoUPLB29n5pzMB7TnsLQWf0V6VUJfoPfw==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.14.0.tgz", + "integrity": "sha512-Ul6CSGRjKscEyg0X/EeNs7o2XdnbTEOD1OM8cTjmx85RPcBJQrEhZLevhuJZNAE/vS2iVl5Uhgiqf3h5uLMCJQ==", "dev": true, "requires": { "ajv": "5.5.2", @@ -2588,9 +2680,9 @@ "debug": "3.1.0", "doctrine": "2.0.2", "eslint-scope": "3.7.1", + "eslint-visitor-keys": "1.0.0", "espree": "3.5.2", "esquery": "1.0.0", - "estraverse": "4.2.0", "esutils": "2.0.2", "file-entry-cache": "2.0.0", "functional-red-black-tree": "1.0.1", @@ -2805,6 +2897,12 @@ "estraverse": "4.2.0" } }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, "espree": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", @@ -6233,18 +6331,60 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, "lodash.cond": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", "dev": true }, + "lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", + "dev": true + }, "lodash.merge": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz", "integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU=", "dev": true }, + "lodash.mergewith": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz", + "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=", + "dev": true + }, + "lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=", + "dev": true + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "dev": true + }, + "lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=", + "dev": true + }, + "lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha1-lDbjTtJgk+1/+uGTYUQ1CRXZrdg=", + "dev": true + }, "lodash.template": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", @@ -6264,6 +6404,18 @@ "lodash._reinterpolate": "3.0.0" } }, + "lodash.topairs": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.topairs/-/lodash.topairs-4.3.0.tgz", + "integrity": "sha1-O23qo31g+xFnE8RsXxfqGQ7EjWQ=", + "dev": true + }, + "lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=", + "dev": true + }, "log-symbols": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.1.0.tgz", @@ -8791,9 +8943,9 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "uglify-es": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.2.2.tgz", - "integrity": "sha512-l+s5VLzFwGJfS+fbqaGf/Dfwo1MF13jLOF2ekL0PytzqEqQ6cVppvHf4jquqFok+35USMpKjqkYxy6pQyUcuug==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.2.tgz", + "integrity": "sha512-g7rGvx7YiFROLXKUtFMTw+YpTVV/XXPNvDUQfzwDTcB3vINwLUr3qXnkcPCu8VCIVjxI2EqaZ+sHoAxcYE/98w==", "requires": { "commander": "2.12.2", "source-map": "0.6.1" @@ -8807,9 +8959,9 @@ "optional": true }, "uglifyjs-webpack-plugin": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.1.4.tgz", - "integrity": "sha512-fRrOJ5tv6YCsJIhP9mPRnfgyo4DVNSIfNOa7Gs9aT1NNpeJc85W7GcbVxQgc+9rU3No6tnkbMqZ4xsgRBU+HGQ==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.1.5.tgz", + "integrity": "sha512-YBGc9G7dv12Vjx8vUQs54DZgAXVf04LlG6dNNiEbTZjL3PbUqiY4uPB9Kv+fUJaqRskEGva/lS7sh08yJr7jnA==", "dev": true, "requires": { "cacache": "10.0.1", @@ -8820,6 +8972,18 @@ "uglify-es": "3.2.2", "webpack-sources": "1.1.0", "worker-farm": "1.5.2" + }, + "dependencies": { + "uglify-es": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.2.2.tgz", + "integrity": "sha512-l+s5VLzFwGJfS+fbqaGf/Dfwo1MF13jLOF2ekL0PytzqEqQ6cVppvHf4jquqFok+35USMpKjqkYxy6pQyUcuug==", + "dev": true, + "requires": { + "commander": "2.12.2", + "source-map": "0.6.1" + } + } } }, "unique-filename": { @@ -9047,9 +9211,9 @@ "dev": true }, "webpack": { - "version": "4.0.0-alpha.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.0.0-alpha.1.tgz", - "integrity": "sha512-4jcDzG58oRcuvTKofcbMRPAKFXP9ZDkvVNupFaT0YKz45EseMt4P3YC/YiBs02gldEtcN6GLqMWZ20CmeXjl4w==", + "version": "4.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.0.0-alpha.2.tgz", + "integrity": "sha512-ReJ5RZhxvZgmWqL4Z3t0MCKHMnqHFBVuBdQGbuhZpWrUJDBkLEaRExb5KgpmPDh8kXF4fKYOCzQZmddZSRyYYA==", "dev": true, "requires": { "acorn": "5.2.1", @@ -9065,9 +9229,8 @@ "mkdirp": "0.5.1", "node-libs-browser": "2.1.0", "schema-utils": "0.4.3", - "source-map": "0.5.7", "tapable": "1.0.0-beta.5", - "uglifyjs-webpack-plugin": "1.1.4", + "uglifyjs-webpack-plugin": "1.1.5", "watchpack": "1.4.0", "webpack-sources": "1.1.0" }, @@ -9090,19 +9253,13 @@ "ajv": "5.5.2", "ajv-keywords": "2.1.1" } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true } } }, "webpack-defaults": { - "version": "2.0.0-rc.2", - "resolved": "https://registry.npmjs.org/webpack-defaults/-/webpack-defaults-2.0.0-rc.2.tgz", - "integrity": "sha512-Dj9xONQOSFKQjP0uHR6YSCu05DcQPgCL+KCvFAxG1FRKrjXnWeHp5myxDPEK6eLfbitHLY6vq8VANdlFjVl7Pg==", + "version": "2.0.0-rc.4", + "resolved": "https://registry.npmjs.org/webpack-defaults/-/webpack-defaults-2.0.0-rc.4.tgz", + "integrity": "sha512-SIFdup+DceQx6/SiV4r4Gn2bOpM3QZOfVLTbyI+cIUUZVAR64pih1if80jK8dtClUMBHYtHXQgX2MUN2XndXPA==", "dev": true, "requires": { "chalk": "2.3.0", diff --git a/package.json b/package.json index 4be2a3e2..26e4c5cf 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,7 @@ "ci:lint": "npm run lint && npm run security", "ci:test": "npm run test -- --runInBand", "ci:coverage": "npm run test:coverage -- --runInBand", - "defaults": "webpack-defaults", - "webpack-defaults": "webpack-defaults" + "defaults": "webpack-defaults" }, "dependencies": { "cacache": "^10.0.0", @@ -39,12 +38,12 @@ "schema-utils": "^0.3.0", "serialize-javascript": "^1.4.0", "source-map": "^0.6.1", - "uglify-es": "^3.2.1", + "uglify-es": "^3.3.2", "webpack-sources": "^1.0.1", "worker-farm": "^1.4.1" }, "devDependencies": { - "@commitlint/cli": "^5.2.5", + "@commitlint/cli": "^5.2.8", "@commitlint/config-angular": "^5.1.1", "@webpack-contrib/eslint-config-webpack": "^2.0.2", "babel-cli": "^6.26.0", @@ -53,10 +52,10 @@ "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.6.1", "conventional-github-releaser": "^2.0.0", - "cross-env": "^5.1.1", + "cross-env": "^5.1.3", "del": "^3.0.0", "del-cli": "^1.1.0", - "eslint": "^4.13.1", + "eslint": "^4.14.0", "eslint-plugin-import": "^2.8.0", "eslint-plugin-prettier": "^2.4.0", "husky": "^0.14.3", @@ -67,8 +66,8 @@ "pre-commit": "^1.2.2", "prettier": "^1.9.2", "standard-version": "^4.2.0", - "webpack": "^4.0.0-alpha.1", - "webpack-defaults": "^2.0.0-rc.2" + "webpack": "^4.0.0-alpha.2", + "webpack-defaults": "^2.0.0-rc.4" }, "engines": { "node": ">= 6.9.0 || >= 8.9.0" diff --git a/src/index.js b/src/index.js index 969195b7..d1571807 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,6 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ - +/* eslint-disable + no-param-reassign, + */ import { SourceMapConsumer } from 'source-map'; import { SourceMapSource, RawSource, ConcatSource } from 'webpack-sources'; import RequestShortener from 'webpack/lib/RequestShortener'; diff --git a/src/uglify/versions.js b/src/uglify/versions.js index 42ef081b..90572135 100644 --- a/src/uglify/versions.js +++ b/src/uglify/versions.js @@ -1,4 +1,7 @@ +const uglify = require('uglify-es/package.json').version; +const plugin = require('../../package.json').version; + export default { - uglify: require('uglify-es/package.json').version, - plugin: require('../../package.json').version, + uglify, + plugin, }; diff --git a/test/Errors.test.js b/test/Errors.test.js new file mode 100644 index 00000000..69712d94 --- /dev/null +++ b/test/Errors.test.js @@ -0,0 +1,52 @@ +/* eslint-disable + import/order + */ +import webpack from './helpers/compiler'; +import { cleanErrorStack } from './helpers'; +import UglifyJsPlugin from '../src/index'; + +describe('Errors', () => { + test('ValidationError', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + uglifyOptions: { + output: { + invalid: true, + }, + }, + }), + ], + }; + + const stats = await webpack('entry.js', config); + const { assets } = stats.compilation; + + const errors = stats.compilation.errors.map(cleanErrorStack); + const warnings = stats.compilation.warnings.map(cleanErrorStack); + + expect(errors).toMatchSnapshot(); + expect(warnings).toMatchSnapshot(); + + expect(assets['main.bundle.js'].source()).toMatchSnapshot(); + }); + + test('Uglify Errors', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + uglifyOptions: { + output: { + invalid: true, + }, + }, + }), + ], + }; + + const stats = await webpack('entry.js', config); + const { errors } = stats.compilation; + + expect(errors[0].message).toEqual(expect.stringContaining('from UglifyJs')); + }); +}); diff --git a/test/Plugin.test.js b/test/Plugin.test.js new file mode 100644 index 00000000..aa2a2c78 --- /dev/null +++ b/test/Plugin.test.js @@ -0,0 +1,21 @@ +/* eslint-disable + import/order + */ + +import webpack from './helpers/compiler'; +import UglifyJsPlugin from '../src/index'; + +describe('Plugin', () => { + test('Defaults', async () => { + const config = { + plugins: [new UglifyJsPlugin()], + }; + + const stats = await webpack('entry.js', config); + const { assets } = stats.compilation; + + const main = assets['main.bundle.js'].source(); + + expect(main).toMatchSnapshot(); + }); +}); diff --git a/test/UglifyJsPlugin.test.js b/test/UglifyJsPlugin.test.js deleted file mode 100644 index 75d6a527..00000000 --- a/test/UglifyJsPlugin.test.js +++ /dev/null @@ -1,7 +0,0 @@ -import UglifyJsPlugin from '../src/index'; - -describe('UglifyJsPlugin', () => { - it('has apply function', () => { - expect(typeof new UglifyJsPlugin().apply).toBe('function'); - }); -}); diff --git a/test/__snapshots__/Errors.test.js.snap b/test/__snapshots__/Errors.test.js.snap new file mode 100644 index 00000000..87d6ded5 --- /dev/null +++ b/test/__snapshots__/Errors.test.js.snap @@ -0,0 +1,38 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Errors ValidationError 1`] = ` +Array [ + "Error: main.bundle.js from UglifyJs +DefaultsError: \`invalid\` is not a supported option", + "Error: runtime.bundle.js from UglifyJs +DefaultsError: \`invalid\` is not a supported option", +] +`; + +exports[`Errors ValidationError 2`] = ` +Array [ + "NoModeWarning: configuration +The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this enviroment. ", +] +`; + +exports[`Errors ValidationError 3`] = ` +"(window[\\"webpackJsonp\\"] = window[\\"webpackJsonp\\"] || []).push([[0],[ +/* 0 */ +/***/ (function(module, exports) { + +// foo +/* @preserve*/ +// bar +const a = 2 + 2; + +module.exports = function Foo() { + const b = 2 + 2; + console.log(b + 1 + 2); +}; + + +/***/ }) +],[[0,1,0]]]); +//# sourceMappingURL=main.bundle.js.map" +`; diff --git a/test/__snapshots__/Plugin.test.js.snap b/test/__snapshots__/Plugin.test.js.snap new file mode 100644 index 00000000..e2a47fdd --- /dev/null +++ b/test/__snapshots__/Plugin.test.js.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Plugin Defaults 1`] = `"(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[function(o,n){o.exports=function(){console.log(7)}}],[[0,1,0]]]);"`; diff --git a/test/__snapshots__/all-options.test.js.snap b/test/__snapshots__/all-options.test.js.snap deleted file mode 100644 index 54d5fbb8..00000000 --- a/test/__snapshots__/all-options.test.js.snap +++ /dev/null @@ -1,105 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`errors 1`] = `Array []`; - -exports[`main.6c966be0e6148d71540d.js 1`] = ` -"(window.webpackJsonp = window.webpackJsonp || []).push([ [ \\"main\\" ], { - \\"./test/fixtures/entry.js\\": function(module, exports) { - eval(\\"// foo\\\\n/* @preserve*/\\\\n// bar\\\\nconst a = 2 + 2;\\\\n\\\\nmodule.exports = function Foo() {\\\\n const b = 2 + 2;\\\\n console.log(b + 1 + 2);\\\\n};\\\\n\\\\n\\\\n//////////////////\\\\n// WEBPACK FOOTER\\\\n// ./test/fixtures/entry.js\\\\n// module id = ./test/fixtures/entry.js\\\\n// module chunks = main\\\\n\\\\n//# sourceURL=webpack:///./test/fixtures/entry.js?\\"); - } -}, [ [ \\"./test/fixtures/entry.js\\", \\"manifest\\", \\"main\\" ] ] ]);" -`; - -exports[`manifest.ae205c79cb278d0fd374.js 1`] = ` -"!function(modules) { - function webpackJsonpCallback(data) { - for (var moduleId, chunkId, result, chunkIds = data[0], moreModules = data[1], executeModules = data[2], i = 0, resolves = []; i < chunkIds.length; i++) chunkId = chunkIds[i], - installedChunks[chunkId] && resolves.push(installedChunks[chunkId][0]), installedChunks[chunkId] = 0; - for (moduleId in moreModules) Object.prototype.hasOwnProperty.call(moreModules, moduleId) && (modules[moduleId] = moreModules[moduleId]); - for (parentJsonpFunction && parentJsonpFunction(data); resolves.length; ) resolves.shift()(); - for (scheduledModules.push.apply(scheduledModules, executeModules || []), i = 0; i < scheduledModules.length; i++) { - for (var scheduledModule = scheduledModules[i], fullfilled = !0, j = 1; j < scheduledModule.length; j++) { - var depId = scheduledModule[j]; - 0 !== installedChunks[depId] && (fullfilled = !1); - } - fullfilled && (scheduledModules.splice(i--, 1), result = __webpack_require__(__webpack_require__.s = scheduledModule[0])); - } - return result; - } - function __webpack_require__(moduleId) { - if (installedModules[moduleId]) return installedModules[moduleId].exports; - var module = installedModules[moduleId] = { - i: moduleId, - l: !1, - exports: {} - }; - return modules[moduleId].call(module.exports, module, module.exports, __webpack_require__), - module.l = !0, module.exports; - } - var installedModules = {}, installedChunks = { - manifest: 0 - }, scheduledModules = []; - __webpack_require__.e = function(chunkId) { - var promises = [], installedChunkData = installedChunks[chunkId]; - if (0 !== installedChunkData) if (installedChunkData) promises.push(installedChunkData[2]); else { - var promise = new Promise(function(resolve, reject) { - installedChunkData = installedChunks[chunkId] = [ resolve, reject ]; - }); - promises.push(installedChunkData[2] = promise); - var head = document.getElementsByTagName(\\"head\\")[0], script = document.createElement(\\"script\\"); - script.charset = \\"utf-8\\", script.timeout = 12e4, __webpack_require__.nc && script.setAttribute(\\"nonce\\", __webpack_require__.nc), - script.src = __webpack_require__.p + \\"\\" + chunkId + \\".\\" + ({ - main: \\"main\\" - }[chunkId] || chunkId) + \\".\\" + { - main: \\"6c966be0e6148d71540d\\" - }[chunkId] + \\".js\\"; - var timeout = setTimeout(function() { - onScriptComplete({ - type: \\"timeout\\", - target: script - }); - }, 12e4); - script.onerror = script.onload = onScriptComplete; - function onScriptComplete(event) { - script.onerror = script.onload = null, clearTimeout(timeout); - var chunk = installedChunks[chunkId]; - if (0 !== chunk) { - if (chunk) { - var errorType = event && (\\"load\\" === event.type ? \\"missing\\" : event.type), realSrc = event && event.target && event.target.src, error = new Error(\\"Loading chunk \\" + chunkId + \\" failed.\\\\n(\\" + errorType + \\": \\" + realSrc + \\")\\"); - error.type = errorType, error.request = realSrc, chunk[1](error); - } - installedChunks[chunkId] = void 0; - } - } - head.appendChild(script); - } - return Promise.all(promises); - }, __webpack_require__.m = modules, __webpack_require__.c = installedModules, __webpack_require__.d = function(exports, name, getter) { - __webpack_require__.o(exports, name) || Object.defineProperty(exports, name, { - configurable: !1, - enumerable: !0, - get: getter - }); - }, __webpack_require__.r = function(exports) { - Object.defineProperty(exports, \\"__esModule\\", { - value: !0 - }); - }, __webpack_require__.n = function(module) { - var getter = module && module.__esModule ? function() { - return module.default; - } : function() { - return module; - }; - return __webpack_require__.d(getter, \\"a\\", getter), getter; - }, __webpack_require__.o = function(object, property) { - return Object.prototype.hasOwnProperty.call(object, property); - }, __webpack_require__.p = \\"\\", __webpack_require__.oe = function(err) { - throw console.error(err), err; - }; - var jsonpArray = window.webpackJsonp = window.webpackJsonp || [], parentJsonpFunction = jsonpArray.push.bind(jsonpArray); - jsonpArray.push = webpackJsonpCallback, jsonpArray = jsonpArray.slice(); - for (var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); -}([]);" -`; - -exports[`warnings 1`] = `Array []`; diff --git a/test/__snapshots__/cache-options.test.js.snap b/test/__snapshots__/cache-options.test.js.snap deleted file mode 100644 index 29adedc0..00000000 --- a/test/__snapshots__/cache-options.test.js.snap +++ /dev/null @@ -1,81 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`cache \`false\`: asset main.6c966be0e6148d71540d.js 1`] = `"(window.webpackJsonp=window.webpackJsonp||[]).push([[\\"main\\"],{\\"./test/fixtures/entry.js\\":function(module,exports){eval(\\"// foo\\\\n/* @preserve*/\\\\n// bar\\\\nconst a = 2 + 2;\\\\n\\\\nmodule.exports = function Foo() {\\\\n const b = 2 + 2;\\\\n console.log(b + 1 + 2);\\\\n};\\\\n\\\\n\\\\n//////////////////\\\\n// WEBPACK FOOTER\\\\n// ./test/fixtures/entry.js\\\\n// module id = ./test/fixtures/entry.js\\\\n// module chunks = main\\\\n\\\\n//# sourceURL=webpack:///./test/fixtures/entry.js?\\")}},[[\\"./test/fixtures/entry.js\\",\\"manifest\\",\\"main\\"]]]);"`; - -exports[`cache \`false\`: asset manifest.ae205c79cb278d0fd374.js 1`] = `"!function(e){function r(r){for(var n,a,c,s=r[0],l=r[1],p=r[2],f=0,d=[];f {\\\\n return {\\\\n a: b + _dep__WEBPACK_IMPORTED_MODULE_0__[\\"bar\\"] + baz,\\\\n b,\\\\n baz,\\\\n };\\\\n };\\\\n}\\\\n\\\\n/* harmony default export */ __webpack_exports__[\\"default\\"] = (Foo);\\\\n\\\\n\\\\n//////////////////\\\\n// WEBPACK FOOTER\\\\n// ./test/fixtures/import-export/entry.js\\\\n// module id = ./test/fixtures/import-export/entry.js\\\\n// module chunks = main\\\\n\\\\n//# sourceURL=webpack:///./test/fixtures/import-export/entry.js?'); - } -}, [ [ \\"./test/fixtures/import-export/entry.js\\", \\"manifest\\", \\"main\\" ] ] ]);" -`; - -exports[`import-export: manifest.js 1`] = ` -"!function(modules) { - function webpackJsonpCallback(data) { - for (var moduleId, chunkId, result, chunkIds = data[0], moreModules = data[1], executeModules = data[2], i = 0, resolves = []; i < chunkIds.length; i++) chunkId = chunkIds[i], - installedChunks[chunkId] && resolves.push(installedChunks[chunkId][0]), installedChunks[chunkId] = 0; - for (moduleId in moreModules) Object.prototype.hasOwnProperty.call(moreModules, moduleId) && (modules[moduleId] = moreModules[moduleId]); - for (parentJsonpFunction && parentJsonpFunction(data); resolves.length; ) resolves.shift()(); - for (scheduledModules.push.apply(scheduledModules, executeModules || []), i = 0; i < scheduledModules.length; i++) { - for (var scheduledModule = scheduledModules[i], fullfilled = !0, j = 1; j < scheduledModule.length; j++) { - var depId = scheduledModule[j]; - 0 !== installedChunks[depId] && (fullfilled = !1); - } - fullfilled && (scheduledModules.splice(i--, 1), result = __webpack_require__(__webpack_require__.s = scheduledModule[0])); - } - return result; - } - function __webpack_require__(moduleId) { - if (installedModules[moduleId]) return installedModules[moduleId].exports; - var module = installedModules[moduleId] = { - i: moduleId, - l: !1, - exports: {} - }; - return modules[moduleId].call(module.exports, module, module.exports, __webpack_require__), - module.l = !0, module.exports; - } - var installedModules = {}, installedChunks = { - manifest: 0 - }, scheduledModules = []; - __webpack_require__.e = function(chunkId) { - var promises = [], installedChunkData = installedChunks[chunkId]; - if (0 !== installedChunkData) if (installedChunkData) promises.push(installedChunkData[2]); else { - var promise = new Promise(function(resolve, reject) { - installedChunkData = installedChunks[chunkId] = [ resolve, reject ]; - }); - promises.push(installedChunkData[2] = promise); - var head = document.getElementsByTagName(\\"head\\")[0], script = document.createElement(\\"script\\"); - script.charset = \\"utf-8\\", script.timeout = 12e4, __webpack_require__.nc && script.setAttribute(\\"nonce\\", __webpack_require__.nc), - script.src = __webpack_require__.p + \\"\\" + chunkId + \\".\\" + ({ - main: \\"main\\" - }[chunkId] || chunkId) + \\".js\\"; - var timeout = setTimeout(function() { - onScriptComplete({ - type: \\"timeout\\", - target: script - }); - }, 12e4); - script.onerror = script.onload = onScriptComplete; - function onScriptComplete(event) { - script.onerror = script.onload = null, clearTimeout(timeout); - var chunk = installedChunks[chunkId]; - if (0 !== chunk) { - if (chunk) { - var errorType = event && (\\"load\\" === event.type ? \\"missing\\" : event.type), realSrc = event && event.target && event.target.src, error = new Error(\\"Loading chunk \\" + chunkId + \\" failed.\\\\n(\\" + errorType + \\": \\" + realSrc + \\")\\"); - error.type = errorType, error.request = realSrc, chunk[1](error); - } - installedChunks[chunkId] = void 0; - } - } - head.appendChild(script); - } - return Promise.all(promises); - }, __webpack_require__.m = modules, __webpack_require__.c = installedModules, __webpack_require__.d = function(exports, name, getter) { - __webpack_require__.o(exports, name) || Object.defineProperty(exports, name, { - configurable: !1, - enumerable: !0, - get: getter - }); - }, __webpack_require__.r = function(exports) { - Object.defineProperty(exports, \\"__esModule\\", { - value: !0 - }); - }, __webpack_require__.n = function(module) { - var getter = module && module.__esModule ? function() { - return module.default; - } : function() { - return module; - }; - return __webpack_require__.d(getter, \\"a\\", getter), getter; - }, __webpack_require__.o = function(object, property) { - return Object.prototype.hasOwnProperty.call(object, property); - }, __webpack_require__.p = \\"\\", __webpack_require__.oe = function(err) { - throw console.error(err), err; - }; - var jsonpArray = window.webpackJsonp = window.webpackJsonp || [], parentJsonpFunction = jsonpArray.push.bind(jsonpArray); - jsonpArray.push = webpackJsonpCallback, jsonpArray = jsonpArray.slice(); - for (var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); -}([]);" -`; - -exports[`import-export: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/empty-options.test.js.snap b/test/__snapshots__/empty-options.test.js.snap deleted file mode 100644 index 65e5887f..00000000 --- a/test/__snapshots__/empty-options.test.js.snap +++ /dev/null @@ -1,9 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`errors 1`] = `Array []`; - -exports[`main.6c966be0e6148d71540d.js 1`] = `"(window.webpackJsonp=window.webpackJsonp||[]).push([[\\"main\\"],{\\"./test/fixtures/entry.js\\":function(module,exports){eval(\\"// foo\\\\n/* @preserve*/\\\\n// bar\\\\nconst a = 2 + 2;\\\\n\\\\nmodule.exports = function Foo() {\\\\n const b = 2 + 2;\\\\n console.log(b + 1 + 2);\\\\n};\\\\n\\\\n\\\\n//////////////////\\\\n// WEBPACK FOOTER\\\\n// ./test/fixtures/entry.js\\\\n// module id = ./test/fixtures/entry.js\\\\n// module chunks = main\\\\n\\\\n//# sourceURL=webpack:///./test/fixtures/entry.js?\\")}},[[\\"./test/fixtures/entry.js\\",\\"manifest\\",\\"main\\"]]]);"`; - -exports[`manifest.ae205c79cb278d0fd374.js 1`] = `"!function(e){function r(r){for(var n,a,c,s=r[0],l=r[1],p=r[2],f=0,d=[];f { - let eventBindings; - let eventBinding; - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - sourceMap: true, - extractComments: { - condition: 'should be extracted', - filename(file) { - return file.replace(/(\.\w+)$/, '.license$1'); - }, - banner(licenseFile) { - return `License information can be found in ${licenseFile}`; - }, - }, - uglifyOptions: { - warnings: true, - mangle: false, - output: { - beautify: true, - }, - }, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('matches snapshot', () => { - const compiler = createCompiler(); - new UglifyJsPlugin({ - sourceMap: true, - uglifyOptions: { - mangle: false, - output: { - beautify: true, - }, - warnings: true, - }, - extractComments: { - condition: 'should be extracted', - filename(file) { - return file.replace(/(\.\w+)$/, '.license$1'); - }, - banner(licenseFile) { - return `License information can be found in ${licenseFile}`; - }, - }, - }).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('binds one event handler', () => { - expect(eventBindings.length).toBe(1); - }); - - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test.js': { - source: () => - '/** @preserve Foo Bar */ function foo(longVariableName) { longVariableName = 1; }', - map: () => { - return { - version: 3, - sources: ['test.js'], - names: ['foo', 'longVariableName'], - mappings: 'AAAA,QAASA,KAAIC,kBACTA,iBAAmB', - }; - }, - }, - 'test1.js': { - source: () => 'invalid javascript', - map: () => { - return { - version: 3, - sources: ['test1.js'], - names: [''], - mappings: 'AAAA', - }; - }, - }, - 'test2.js': { - source: () => - 'function foo(x) { if (x) { return bar(); not_called1(); } }', - map: () => { - return { - version: 3, - sources: ['test1.js'], - names: ['foo', 'x', 'bar', 'not_called1'], - mappings: 'AAAA,QAASA,KAAIC,GACT,GAAIA,EAAG,CACH,MAAOC,MACPC', - }; - }, - }, - 'test3.js': { - sourceAndMap: () => { - return { - source: - '/** @preserve Foo Bar */ function foo(longVariableName) { longVariableName = 1; }', - map: { - version: 3, - sources: ['test.js'], - names: ['foo', 'longVariableName'], - mappings: 'AAAA,QAASA,KAAIC,kBACTA,iBAAmB', - }, - }; - }, - }, - 'test4.js': { - source: () => - '/*! this comment should be extracted */ function foo(longVariableName) { /* this will not be extracted */ longVariableName = 1; } // another comment that should be extracted to a separate file\n function foo2(bar) { return bar; }', - map: () => { - return { - version: 3, - sources: ['test.js'], - names: ['foo', 'longVariableName'], - mappings: 'AAAA,QAASA,KAAIC,kBACTA,iBAAmB', - }; - }, - }, - }; - compilation.errors = []; - compilation.warnings = []; - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds two event handler', () => { - expect(compilationEventBindings.length).toBe(2); - }); - - describe('build-module handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to build-module event', () => { - expect(compilationEventBinding.name).toBe('build-module'); - }); - - it('sets the useSourceMap flag', () => { - const obj = {}; - compilationEventBinding.handler(obj); - expect(obj.useSourceMap).toBeTruthy(); - }); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBindings[1].name).toBe( - 'optimize-chunk-assets' - ); - }); - - it('outputs no errors for valid javascript', () => { - compilationEventBinding.handler( - [ - { - files: ['test.js'], - }, - ], - () => { - expect(compilation.errors.length).toBe(0); - } - ); - }); - - it('outputs SourceMapSource for valid javascript', () => { - compilationEventBinding.handler( - [ - { - files: ['test.js'], - }, - ], - () => { - expect(compilation.assets['test.js']).toBeInstanceOf( - SourceMapSource - ); - } - ); - }); - - it('does not output mangled javascript', () => { - compilationEventBinding.handler( - [ - { - files: ['test.js'], - }, - ], - () => { - // eslint-disable-next-line no-underscore-dangle - expect(compilation.assets['test.js']._value).toEqual( - expect.stringContaining('longVariableName') - ); - } - ); - }); - - it('outputs beautified javascript', () => { - compilationEventBinding.handler( - [ - { - files: ['test.js'], - }, - ], - () => { - // eslint-disable-next-line no-underscore-dangle - expect(compilation.assets['test.js']._value).toEqual( - expect.stringContaining('\n') - ); - } - ); - }); - - it('does not preserve comments', () => { - compilationEventBinding.handler( - [ - { - files: ['test.js'], - }, - ], - () => { - // eslint-disable-next-line no-underscore-dangle - expect(compilation.assets['test.js']._value).not.toBe( - expect.stringContaining('/**') - ); - } - ); - }); - - it('outputs parsing errors', () => { - compilationEventBinding.handler( - [ - { - files: ['test1.js'], - }, - ], - () => { - expect(compilation.errors.length).toBe(1); - expect(compilation.errors[0]).toBeInstanceOf(Error); - expect(compilation.errors[0].message).toEqual( - expect.stringContaining('[test1.js:1,0][test1.js:1,8]') - ); - } - ); - }); - - it('outputs warnings for unreachable code', () => { - compilationEventBinding.handler( - [ - { - files: ['test2.js'], - }, - ], - () => { - expect(compilation.warnings.length).toBe(1); - expect(compilation.warnings[0]).toBeInstanceOf(Error); - expect(compilation.warnings[0].message).toEqual( - expect.stringContaining('Dropping unreachable code') - ); - } - ); - }); - - it('works with sourceAndMap assets as well', () => { - compilationEventBinding.handler( - [ - { - files: ['test3.js'], - }, - ], - () => { - expect(compilation.errors.length).toBe(0); - expect(compilation.assets['test3.js']).toBeInstanceOf( - SourceMapSource - ); - } - ); - }); - - it('extracts license information to separate file', () => { - compilationEventBinding.handler( - [ - { - files: ['test4.js'], - }, - ], - () => { - expect(compilation.errors.length).toBe(0); - /* eslint-disable no-underscore-dangle */ - expect(compilation.assets['test4.license.js'].source()).toContain( - '/*! this comment should be extracted */' - ); - expect(compilation.assets['test4.license.js'].source()).toContain( - '// another comment that should be extracted to a separate file' - ); - expect( - compilation.assets['test4.license.js'].source() - ).not.toEqual( - expect.stringContaining('/* this will not be extracted */') - ); - /* eslint-enable no-underscore-dangle */ - } - ); - }); - - describe('with warningsFilter set', () => { - describe('and the filter returns true', () => { - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - warningsFilter: () => true, - sourceMap: true, - uglifyOptions: { - warnings: true, - mangle: false, - output: { - beautify: true, - }, - }, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test2.js': { - source: () => - 'function foo(x) { if (x) { return bar(); not_called1(); } }', - map: () => { - return { - version: 3, - sources: ['test1.js'], - names: ['foo', 'x', 'bar', 'not_called1'], - mappings: - 'AAAA,QAASA,KAAIC,GACT,GAAIA,EAAG,CACH,MAAOC,MACPC', - }; - }, - }, - }; - compilation.errors = []; - compilation.warnings = []; - - eventBindings[0].handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('should get all warnings', () => { - compilationEventBindings[1].handler( - [ - { - files: ['test2.js'], - }, - ], - () => { - expect(compilation.warnings.length).toBe(1); - expect(compilation.warnings[0]).toBeInstanceOf(Error); - expect(compilation.warnings[0].message).toEqual( - expect.stringContaining('Dropping unreachable code') - ); - } - ); - }); - }); - - describe('and the filter returns false', () => { - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - warningsFilter: () => false, - sourceMap: true, - uglifyOptions: { - warnings: true, - mangle: false, - output: { - beautify: true, - }, - }, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test2.js': { - source: () => - 'function foo(x) { if (x) { return bar(); not_called1(); } }', - map: () => { - return { - version: 3, - sources: ['test1.js'], - names: ['foo', 'x', 'bar', 'not_called1'], - mappings: - 'AAAA,QAASA,KAAIC,GACT,GAAIA,EAAG,CACH,MAAOC,MACPC', - }; - }, - }, - }; - compilation.errors = []; - compilation.warnings = []; - - eventBindings[0].handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('should get no warnings', () => { - compilationEventBindings[1].handler( - [ - { - files: ['test2.js'], - }, - ], - () => { - expect(compilation.warnings.length).toBe(0); - } - ); - }); - }); - }); - }); - }); - }); -}); diff --git a/test/cache-options.test.js b/test/cache-options.test.js deleted file mode 100644 index 2f241108..00000000 --- a/test/cache-options.test.js +++ /dev/null @@ -1,485 +0,0 @@ -import cacache from 'cacache'; -import findCacheDir from 'find-cache-dir'; -import UglifyJsPlugin from '../src/index'; -import { - PluginEnvironment, - createCompiler, - compile, - cleanErrorStack, -} from './helpers'; - -const cacheDir = findCacheDir({ name: 'uglifyjs-webpack-plugin' }); - -describe('when options.cache', () => { - const assets = { - 'test.js': { - source: () => 'function test(foo) { foo = 1; }', - }, - 'test1.js': { - source: () => 'function test1(foo) { foo = 1; }', - }, - 'test2.js': { - source: () => 'function test2(foo) { foo = 1; }', - }, - 'test3.js': { - source: () => 'function test3(foo) { foo = 1; }', - }, - }; - - describe('false', () => { - let eventBindings; - let eventBinding; - - beforeAll(() => cacache.rm.all(cacheDir)); - - afterAll(() => cacache.rm.all(cacheDir)); - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - cache: false, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(eventBindings.length).toBe(1); - }); - - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - let callback; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = Object.assign({}, assets); - compilation.errors = []; - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(compilationEventBindings.length).toBe(1); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual( - 'optimize-chunk-assets' - ); - }); - - it('only calls callback once', (done) => { - callback = jest.fn(); - compilationEventBinding.handler([''], () => { - callback(); - expect(callback.mock.calls.length).toBe(1); - done(); - }); - }); - - it('cache files', (done) => { - const files = ['test.js', 'test1.js', 'test2.js', 'test3.js']; - - cacache.get = jest.fn(cacache.get); - cacache.put = jest.fn(cacache.put); - - compilationEventBinding.handler( - [ - { - files, - }, - ], - () => { - // Cache disabled so we don't run `get` or `put` - expect(cacache.get.mock.calls.length).toBe(0); - expect(cacache.put.mock.calls.length).toBe(0); - - cacache.ls(cacheDir).then((cacheEntriesList) => { - const cacheKeys = Object.keys(cacheEntriesList); - - expect(cacheKeys.length).toBe(0); - done(); - }); - } - ); - }); - }); - }); - }); - - it('matches snapshot', () => { - const compiler = createCompiler(); - new UglifyJsPlugin({ cache: 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('cache `false`: errors'); - expect(warnings).toMatchSnapshot('cache `false`: warnings'); - - for (const file in stats.compilation.assets) { - if ( - Object.prototype.hasOwnProperty.call(stats.compilation.assets, file) - ) { - expect(stats.compilation.assets[file].source()).toMatchSnapshot( - `cache \`false\`: asset ${file}` - ); - } - } - }); - }); - }); - - describe('true', () => { - let eventBindings; - let eventBinding; - - beforeAll(() => cacache.rm.all(cacheDir)); - - afterAll(() => cacache.rm.all(cacheDir)); - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - cache: true, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(eventBindings.length).toBe(1); - }); - - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - let callback; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = Object.assign({}, assets); - compilation.errors = []; - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(compilationEventBindings.length).toBe(1); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual( - 'optimize-chunk-assets' - ); - }); - - it('only calls callback once', (done) => { - callback = jest.fn(); - compilationEventBinding.handler([''], () => { - callback(); - expect(callback.mock.calls.length).toBe(1); - done(); - }); - }); - - it('cache files', (done) => { - const files = ['test.js', 'test1.js', 'test2.js', 'test3.js']; - - cacache.get = jest.fn(cacache.get); - cacache.put = jest.fn(cacache.put); - - compilationEventBinding.handler( - [ - { - files, - }, - ], - () => { - // Try to found cached files, but we don't have their in cache - expect(cacache.get.mock.calls.length).toBe(4); - // Put files in cache - expect(cacache.put.mock.calls.length).toBe(4); - - cacache.ls(cacheDir).then((cacheEntriesList) => { - const cacheKeys = Object.keys(cacheEntriesList); - - // Make sure that we cached files - expect(cacheKeys.length).toBe(files.length); - cacheKeys.forEach((cacheEntry) => { - // eslint-disable-next-line no-new-func - const cacheEntryOptions = new Function( - `'use strict'\nreturn ${cacheEntry}` - )(); - - expect([ - cacheEntryOptions.path, - cacheEntryOptions.input, - ]).toMatchSnapshot( - `cache \`true\`: cached entry ${cacheEntryOptions.path}` - ); - }); - - // Reset compilation assets and mocks - compilation.assets = Object.assign({}, assets); - compilation.errors = []; - - cacache.get.mockClear(); - cacache.put.mockClear(); - - compilationEventBinding.handler( - [ - { - files, - }, - ], - () => { - // Now we have cached files so we get their and don't put - expect(cacache.get.mock.calls.length).toBe(4); - expect(cacache.put.mock.calls.length).toBe(0); - - done(); - } - ); - }); - } - ); - }); - }); - }); - }); - - it('matches snapshot', () => { - const compiler = createCompiler(); - new UglifyJsPlugin({ cache: 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('cache `true`: errors'); - expect(warnings).toMatchSnapshot('cache `true`: warnings'); - - for (const file in stats.compilation.assets) { - if ( - Object.prototype.hasOwnProperty.call(stats.compilation.assets, file) - ) { - expect(stats.compilation.assets[file].source()).toMatchSnapshot( - `cache \`true\`: asset ${file}` - ); - } - } - }); - }); - }); - - describe('string', () => { - const othercacheDir = findCacheDir({ name: 'other-cache-directory' }); - let eventBindings; - let eventBinding; - - beforeAll(() => cacache.rm.all(othercacheDir)); - - afterAll(() => cacache.rm.all(othercacheDir)); - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - cache: othercacheDir, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(eventBindings.length).toBe(1); - }); - - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - let callback; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = Object.assign({}, assets); - compilation.errors = []; - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(compilationEventBindings.length).toBe(1); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual( - 'optimize-chunk-assets' - ); - }); - - it('only calls callback once', (done) => { - callback = jest.fn(); - compilationEventBinding.handler([''], () => { - callback(); - expect(callback.mock.calls.length).toBe(1); - done(); - }); - }); - - it('cache files', (done) => { - const files = ['test.js', 'test1.js', 'test2.js', 'test3.js']; - - cacache.get = jest.fn(cacache.get); - cacache.put = jest.fn(cacache.put); - - compilationEventBinding.handler( - [ - { - files, - }, - ], - () => { - // Try to found cached files, but we don't have their in cache - expect(cacache.get.mock.calls.length).toBe(4); - // Put files in cache - expect(cacache.put.mock.calls.length).toBe(4); - - cacache.ls(othercacheDir).then((cacheEntriesList) => { - const cacheKeys = Object.keys(cacheEntriesList); - - // Make sure that we cached files - expect(cacheKeys.length).toBe(files.length); - cacheKeys.forEach((cacheEntry) => { - // eslint-disable-next-line no-new-func - const cacheEntryOptions = new Function( - `'use strict'\nreturn ${cacheEntry}` - )(); - - expect([ - cacheEntryOptions.path, - cacheEntryOptions.input, - ]).toMatchSnapshot( - `cache \`true\`: cached entry ${cacheEntryOptions.path}` - ); - }); - - // Reset compilation assets and mocks - compilation.assets = Object.assign({}, assets); - compilation.errors = []; - - cacache.get.mockClear(); - cacache.put.mockClear(); - - compilationEventBinding.handler( - [ - { - files, - }, - ], - () => { - // Now we have cached files so we get their and don't put - expect(cacache.get.mock.calls.length).toBe(4); - expect(cacache.put.mock.calls.length).toBe(0); - - done(); - } - ); - }); - } - ); - }); - }); - }); - }); - - it('matches snapshot', () => { - const compiler = createCompiler(); - new UglifyJsPlugin({ cache: othercacheDir }).apply(compiler); - - return compile(compiler).then((stats) => { - const errors = stats.compilation.errors.map(cleanErrorStack); - const warnings = stats.compilation.warnings.map(cleanErrorStack); - - expect(errors).toMatchSnapshot('cache `string`: errors'); - expect(warnings).toMatchSnapshot('cache `string`: warnings'); - - for (const file in stats.compilation.assets) { - if ( - Object.prototype.hasOwnProperty.call(stats.compilation.assets, file) - ) { - expect(stats.compilation.assets[file].source()).toMatchSnapshot( - `cache \`string\`: asset ${file}` - ); - } - } - }); - }); - }); -}); diff --git a/test/ecma.test.js b/test/ecma.test.js deleted file mode 100644 index fab7aded..00000000 --- a/test/ecma.test.js +++ /dev/null @@ -1,203 +0,0 @@ -import UglifyJsPlugin from '../src/index'; -import { cleanErrorStack, createCompiler, compile } from './helpers'; - -describe('when applied with uglifyOptions.ecma', () => { - it('matches snapshot for import and export', () => { - const compiler = createCompiler({ - entry: `${__dirname}/fixtures/import-export/entry.js`, - output: { - path: `${__dirname}/dist-import-export`, - filename: '[name].js', - chunkFilename: '[id].[name].js', - }, - }); - - new UglifyJsPlugin({ - uglifyOptions: { - ecma: 5, - mangle: false, - warnings: true, - output: { - beautify: 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('import-export: errors'); - expect(warnings).toMatchSnapshot('import-export: warnings'); - - for (const file in stats.compilation.assets) { - if ( - Object.prototype.hasOwnProperty.call(stats.compilation.assets, file) - ) { - expect(stats.compilation.assets[file].source()).toMatchSnapshot( - `import-export: ${file}` - ); - } - } - }); - }); - - it('matches snapshot for ecma 5', () => { - const compiler = createCompiler({ - entry: `${__dirname}/fixtures/ecma-5/entry.js`, - output: { - path: `${__dirname}/dist-ecma-5`, - filename: '[name].js', - chunkFilename: '[id].[name].js', - }, - }); - - new UglifyJsPlugin({ - uglifyOptions: { - ecma: 5, - mangle: false, - warnings: true, - output: { - beautify: 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('ecma 5: errors'); - expect(warnings).toMatchSnapshot('ecma 5: warnings'); - - for (const file in stats.compilation.assets) { - if ( - Object.prototype.hasOwnProperty.call(stats.compilation.assets, file) - ) { - expect(stats.compilation.assets[file].source()).toMatchSnapshot( - `ecma 5: ${file}` - ); - } - } - }); - }); - - it('matches snapshot for ecma 6', () => { - const compiler = createCompiler({ - entry: `${__dirname}/fixtures/ecma-6/entry.js`, - output: { - path: `${__dirname}/dist-ecma-6`, - filename: '[name].js', - chunkFilename: '[id].[name].js', - }, - }); - - new UglifyJsPlugin({ - uglifyOptions: { - ecma: 6, - mangle: false, - warnings: true, - output: { - beautify: 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('ecma 6: errors'); - expect(warnings).toMatchSnapshot('ecma 6: warnings'); - - for (const file in stats.compilation.assets) { - if ( - Object.prototype.hasOwnProperty.call(stats.compilation.assets, file) - ) { - expect(stats.compilation.assets[file].source()).toMatchSnapshot( - `ecma 6: ${file}` - ); - } - } - }); - }); - - it('matches snapshot for ecma 7', () => { - const compiler = createCompiler({ - entry: `${__dirname}/fixtures/ecma-7/entry.js`, - output: { - path: `${__dirname}/dist-ecma-7`, - filename: '[name].js', - chunkFilename: '[id].[name].js', - }, - }); - new UglifyJsPlugin({ - uglifyOptions: { - ecma: 7, - mangle: false, - warnings: true, - output: { - beautify: 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('ecma 7: errors'); - expect(warnings).toMatchSnapshot('ecma 7: warnings'); - - for (const file in stats.compilation.assets) { - if ( - Object.prototype.hasOwnProperty.call(stats.compilation.assets, file) - ) { - expect(stats.compilation.assets[file].source()).toMatchSnapshot( - `ecma 7: ${file}` - ); - } - } - }); - }); - - it('matches snapshot for ecma 8', () => { - const compiler = createCompiler({ - entry: `${__dirname}/fixtures/ecma-8/entry.js`, - output: { - path: `${__dirname}/dist-ecma-8`, - filename: '[name].js', - chunkFilename: '[id].[name].js', - }, - }); - - new UglifyJsPlugin({ - uglifyOptions: { - ecma: 8, - mangle: false, - warnings: true, - output: { - beautify: 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('ecma 8: errors'); - expect(warnings).toMatchSnapshot('ecma 8: warnings'); - - for (const file in stats.compilation.assets) { - if ( - Object.prototype.hasOwnProperty.call(stats.compilation.assets, file) - ) { - expect(stats.compilation.assets[file].source()).toMatchSnapshot( - `ecma 8: ${file}` - ); - } - } - }); - }); -}); diff --git a/test/empty-options.test.js b/test/empty-options.test.js deleted file mode 100644 index e6130192..00000000 --- a/test/empty-options.test.js +++ /dev/null @@ -1,245 +0,0 @@ -import { RawSource } from 'webpack-sources'; -import UglifyJsPlugin from '../src/index'; -import { - PluginEnvironment, - cleanErrorStack, - createCompiler, - compile, -} from './helpers'; - -describe('when applied with no options', () => { - let eventBindings; - let eventBinding; - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin(); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('matches snapshot', () => { - const compiler = createCompiler(); - new UglifyJsPlugin().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('binds one event handler', () => { - expect(eventBindings.length).toBe(1); - }); - - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - let callback; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test.js': {}, - 'test1.js': '', - 'test2.js': { - source: () => 'invalid javascript', - }, - 'test3.js': { - source: () => - '/** @preserve Foo Bar */ function foo(longVariableName) { longVariableName = 1; }', - }, - }; - compilation.errors = []; - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(compilationEventBindings.length).toBe(1); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual('optimize-chunk-assets'); - }); - - it('only calls callback once', () => { - callback = jest.fn(); - compilationEventBinding.handler([''], () => { - callback(); - expect(callback.mock.calls.length).toBe(1); - }); - }); - - it('default only parses filenames ending with .js', () => { - compilationEventBinding.handler( - [ - { - files: ['test', 'test.js'], - }, - ], - () => { - expect(Object.keys(compilation.assets).length).toBe(4); - } - ); - }); - - it('early returns if private property is already set', () => { - compilationEventBinding.handler( - [ - { - files: ['test.js'], - }, - ], - () => { - expect(compilation.assets['test.js']).toEqual({}); - } - ); - }); - - it('outputs stack trace errors for invalid asset', () => { - compilationEventBinding.handler( - [ - { - files: ['test1.js'], - }, - ], - () => { - expect(compilation.errors.length).toBe(1); - expect(compilation.errors[0]).toBeInstanceOf(Error); - expect(compilation.errors[0].message).toEqual( - expect.stringContaining('asset.source is not a function') - ); - } - ); - }); - - it('outputs parsing errors for invalid javascript', () => { - compilationEventBinding.handler( - [ - { - files: ['test2.js'], - }, - ], - () => { - expect(compilation.errors.length).toBe(1); - expect(compilation.errors[0]).toBeInstanceOf(Error); - expect(compilation.errors[0].message).toEqual( - expect.stringContaining('Unexpected token') - ); - expect(compilation.errors[0].message).toEqual( - expect.stringContaining('[test2.js:1,8]') - ); - } - ); - }); - - it('outputs no errors for valid javascript', () => { - compilationEventBinding.handler( - [ - { - files: ['test3.js'], - }, - ], - () => { - expect(compilation.errors.length).toBe(0); - } - ); - }); - - it('outputs RawSource for valid javascript', () => { - compilationEventBinding.handler( - [ - { - files: ['test3.js'], - }, - ], - () => { - expect(compilation.assets['test3.js']).toBeInstanceOf(RawSource); - } - ); - }); - - it('outputs mangled javascript', () => { - compilationEventBinding.handler( - [ - { - files: ['test3.js'], - }, - ], - () => { - // eslint-disable-next-line no-underscore-dangle - expect(compilation.assets['test3.js']._value).not.toEqual( - expect.stringContaining('longVariableName') - ); - } - ); - }); - - it('compresses and does not output beautified javascript', () => { - compilationEventBinding.handler( - [ - { - files: ['test3.js'], - }, - ], - () => { - // eslint-disable-next-line no-underscore-dangle - expect(compilation.assets['test3.js']._value).not.toEqual( - expect.stringContaining('\n') - ); - } - ); - }); - - it('preserves comments', () => { - compilationEventBinding.handler( - [ - { - files: ['test3.js'], - }, - ], - () => { - // eslint-disable-next-line no-underscore-dangle - expect(compilation.assets['test3.js']._value).toEqual( - expect.stringContaining('/**') - ); - } - ); - }); - }); - }); - }); -}); diff --git a/test/exclude-option.test.js b/test/exclude-option.test.js deleted file mode 100644 index 2da16488..00000000 --- a/test/exclude-option.test.js +++ /dev/null @@ -1,59 +0,0 @@ -import UglifyJsPlugin from '../src/index'; -import { cleanErrorStack, createCompiler, compile } from './helpers'; - -describe('when applied with exclude option', () => { - let compiler; - beforeEach(() => { - compiler = createCompiler({ - entry: { - excluded1: `${__dirname}/fixtures/excluded1.js`, - excluded2: `${__dirname}/fixtures/excluded2.js`, - entry: `${__dirname}/fixtures/entry.js`, - }, - }); - }); - - it('matches snapshot for a single exclude', () => { - new UglifyJsPlugin({ - exclude: /excluded1/, - }).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('matches snapshot for multiple excludes', () => { - new UglifyJsPlugin({ - exclude: [/excluded1/, /excluded2/], - }).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); - } - } - }); - }); -}); diff --git a/test/extract-comments-options.test.js b/test/extract-comments-options.test.js deleted file mode 100644 index 3300ad23..00000000 --- a/test/extract-comments-options.test.js +++ /dev/null @@ -1,331 +0,0 @@ -import UglifyJsPlugin from '../src/index'; -import { PluginEnvironment } from './helpers'; - -describe('when options.extractComments', () => { - let compilation; - let compilationEventBinding; - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - uglifyOptions: { - warnings: true, - mangle: { - properties: { - builtins: true, - }, - }, - }, - extractComments: true, - }); - plugin.apply(compilerEnv); - - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); - - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test.js': { - source: () => 'var foo = 1;', - }, - 'test1.js': { - source: () => - 'function foo(x) { if (x) { return bar(); not_called1(); } }', - map: () => { - return { - version: 3, - sources: ['test1.js'], - names: ['foo', 'x', 'bar', 'not_called1'], - mappings: 'AAAA,QAASA,KAAIC,GACT,GAAIA,EAAG,CACH,MAAOC,MACPC', - }; - }, - }, - }; - compilation.warnings = []; - compilation.errors = []; - - eventBinding.handler(compilation); - [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); - }); - - it('normalizes extractConmments', () => { - compilationEventBinding.handler( - [ - { - files: ['test.js'], - }, - ], - () => { - expect(compilation.errors.length).toBe(0); - } - ); - }); - - it('outputs warnings for unreachable code', () => { - compilationEventBinding.handler( - [ - { - files: ['test.js', 'test1.js'], - }, - ], - () => { - expect(compilation.warnings.length).toBe(1); - expect(compilation.warnings[0]).toBeInstanceOf(Error); - expect(compilation.warnings[0].message).toEqual( - expect.stringContaining('Dropping unreachable code') - ); - } - ); - }); - - it('normalizes when options.extractComments is boolean', () => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - extractComments: true, - }); - plugin.apply(compilerEnv); - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); - const compilation2 = chunkPluginEnvironment.getEnvironmentStub(); - compilation2.assets = { - 'test.js': { - source: () => '// Comment\nvar foo = 1;', - }, - 'test1.js': { - source: () => '/* Comment */\nvar foo = 1;', - }, - }; - compilation2.warnings = []; - compilation2.errors = []; - - eventBinding.handler(compilation2); - [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); - - compilationEventBinding.handler( - [ - { - files: ['test.js', 'test1.js'], - }, - ], - () => { - expect(compilation2.assets['test.js'].source()).toMatchSnapshot( - 'test.js' - ); - expect(compilation2.assets['test1.js'].source()).toMatchSnapshot( - 'test1.js' - ); - expect( - compilation2.assets['test1.js.LICENSE'].source() - ).toMatchSnapshot('test1.js.LICENSE'); - expect(compilation2.errors).toMatchSnapshot('errors'); - expect(compilation2.warnings).toMatchSnapshot('warnings'); - } - ); - }); - - it('normalizes when options.extractComments is regex', () => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - extractComments: /foo/, - }); - plugin.apply(compilerEnv); - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); - const compilation2 = chunkPluginEnvironment.getEnvironmentStub(); - compilation2.assets = { - 'test.js': { - source: () => '// Comment\nvar foo = 1;', - }, - 'test1.js': { - source: () => '// foo\nvar foo = 1;', - }, - }; - compilation2.warnings = []; - compilation2.errors = []; - - eventBinding.handler(compilation2); - [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); - - compilationEventBinding.handler( - [ - { - files: ['test.js', 'test1.js'], - }, - ], - () => { - expect(compilation2.assets['test.js'].source()).toMatchSnapshot( - 'test.js' - ); - expect(compilation2.assets['test1.js'].source()).toMatchSnapshot( - 'test1.js' - ); - expect( - compilation2.assets['test1.js.LICENSE'].source() - ).toMatchSnapshot('test1.js.LICENSE'); - expect(compilation2.errors).toMatchSnapshot('errors'); - expect(compilation2.warnings).toMatchSnapshot('warnings'); - } - ); - }); - - it('normalizes when options.extractComments is string', () => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - extractComments: 'all', - }); - plugin.apply(compilerEnv); - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); - const compilation2 = chunkPluginEnvironment.getEnvironmentStub(); - compilation2.assets = { - 'test.js': { - source: () => '// Comment\nvar foo = 1;', - }, - 'test1.js': { - source: () => '/* Comment */\nvar foo = 1;', - }, - }; - compilation2.warnings = []; - compilation2.errors = []; - - eventBinding.handler(compilation2); - [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); - - compilationEventBinding.handler( - [ - { - files: ['test.js', 'test1.js'], - }, - ], - () => { - expect(compilation2.assets['test.js'].source()).toMatchSnapshot( - 'test.js' - ); - expect(compilation2.assets['test.js.LICENSE'].source()).toMatchSnapshot( - 'test.js.LICENSE' - ); - expect(compilation2.assets['test1.js'].source()).toMatchSnapshot( - 'test1.js' - ); - expect( - compilation2.assets['test1.js.LICENSE'].source() - ).toMatchSnapshot('test1.js.LICENSE'); - expect(compilation2.errors).toMatchSnapshot('errors'); - expect(compilation2.warnings).toMatchSnapshot('warnings'); - } - ); - }); - - it('normalizes when options.extractComments is function', () => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - extractComments: () => true, - }); - plugin.apply(compilerEnv); - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); - const compilation2 = chunkPluginEnvironment.getEnvironmentStub(); - compilation2.assets = { - 'test.js': { - source: () => '// Comment\nvar foo = 1;', - }, - 'test1.js': { - source: () => '/* Comment */\nvar foo = 1;', - }, - }; - compilation2.warnings = []; - compilation2.errors = []; - - eventBinding.handler(compilation2); - [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); - - compilationEventBinding.handler( - [ - { - files: ['test.js', 'test1.js'], - }, - ], - () => { - expect(compilation2.assets['test.js'].source()).toMatchSnapshot( - 'test.js' - ); - expect(compilation2.assets['test1.js'].source()).toMatchSnapshot( - 'test.js' - ); - expect(compilation2.assets['test.js.LICENSE'].source()).toMatchSnapshot( - 'test.js.LICENSE' - ); - expect( - compilation2.assets['test1.js.LICENSE'].source() - ).toMatchSnapshot('test1.js.LICENSE'); - expect(compilation2.errors).toMatchSnapshot('errors'); - expect(compilation2.warnings).toMatchSnapshot('warnings'); - } - ); - }); - - it('normalizes when options.extractComments is object', () => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - extractComments: { - condition: true, - filename(file) { - return file.replace(/(\.\w+)$/, '.license$1'); - }, - banner(licenseFile) { - return `License information can be found in ${licenseFile}`; - }, - }, - }); - plugin.apply(compilerEnv); - const [eventBinding] = pluginEnvironment.getEventBindings(); - const chunkPluginEnvironment = new PluginEnvironment(); - const compilation2 = chunkPluginEnvironment.getEnvironmentStub(); - compilation2.assets = { - 'test.js': { - source: () => '// Comment\nvar foo = 1;', - }, - }; - compilation2.warnings = []; - compilation2.errors = []; - - eventBinding.handler(compilation2); - [compilationEventBinding] = chunkPluginEnvironment.getEventBindings(); - - compilationEventBinding.handler( - [ - { - files: ['test.js'], - }, - ], - () => { - expect(compilation2.assets['test.js'].source()).toMatchSnapshot( - 'test.js' - ); - expect(compilation2.assets['test.license.js'].source()).toMatchSnapshot( - 'test.license.js' - ); - expect(compilation2.errors).toMatchSnapshot('errors'); - expect(compilation2.warnings).toMatchSnapshot('warnings'); - } - ); - }); -}); diff --git a/test/extract-option-set-to-a-single-file.test.js b/test/extract-option-set-to-a-single-file.test.js deleted file mode 100644 index 02fb2508..00000000 --- a/test/extract-option-set-to-a-single-file.test.js +++ /dev/null @@ -1,148 +0,0 @@ -import UglifyJsPlugin from '../src/index'; -import { PluginEnvironment } from './helpers'; - -describe('when applied with extract option set to a single file', () => { - let eventBindings; - let eventBinding; - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - uglifyOptions: { - output: { - comments: 'all', - }, - }, - extractComments: { - condition: /.*/, - filename: 'extracted-comments.js', - }, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(eventBindings.length).toBe(1); - }); - - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = { - 'test.js': { - source: () => - '/* This is a comment from test.js */ function foo(bar) { return bar; }', - }, - 'test2.js': { - source: () => - '// This is a comment from test2.js\nfunction foo2(bar) { return bar; }', - }, - 'test3.js': { - source: () => - '/* This is a comment from test3.js */ function foo3(bar) { return bar; }\n// This is another comment from test3.js\nfunction foobar3(baz) { return baz; }', - }, - }; - compilation.errors = []; - compilation.warnings = []; - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(compilationEventBindings.length).toBe(1); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual('optimize-chunk-assets'); - }); - - it('preserves comments', () => { - compilationEventBinding.handler( - [ - { - files: ['test.js', 'test2.js', 'test3.js'], - }, - ], - () => { - expect(compilation.assets['test.js'].source()).toEqual( - expect.stringContaining('/*') - ); - expect(compilation.assets['test2.js'].source()).toEqual( - expect.stringContaining('//') - ); - expect(compilation.assets['test3.js'].source()).toEqual( - expect.stringContaining('/*') - ); - expect(compilation.assets['test3.js'].source()).toEqual( - expect.stringContaining('//') - ); - } - ); - }); - - it('extracts comments to specified file', () => { - compilationEventBinding.handler( - [ - { - files: ['test.js', 'test2.js', 'test3.js'], - }, - ], - () => { - expect(compilation.errors.length).toBe(0); - expect( - compilation.assets['extracted-comments.js'].source() - ).toEqual( - expect.stringContaining('/* This is a comment from test.js */') - ); - expect( - compilation.assets['extracted-comments.js'].source() - ).toEqual( - expect.stringContaining('// This is a comment from test2.js') - ); - expect( - compilation.assets['extracted-comments.js'].source() - ).toEqual( - expect.stringContaining('/* This is a comment from test3.js */') - ); - expect( - compilation.assets['extracted-comments.js'].source() - ).toEqual( - expect.stringContaining( - '// This is another comment from test3.js' - ) - ); - expect( - compilation.assets['extracted-comments.js'].source() - ).not.toEqual(expect.stringContaining('function')); - } - ); - }); - }); - }); - }); -}); diff --git a/test/fixtures/ecma-6/entry.js b/test/fixtures/es2015/entry.js similarity index 100% rename from test/fixtures/ecma-6/entry.js rename to test/fixtures/es2015/entry.js diff --git a/test/fixtures/ecma-7/entry.js b/test/fixtures/es2016/entry.js similarity index 100% rename from test/fixtures/ecma-7/entry.js rename to test/fixtures/es2016/entry.js diff --git a/test/fixtures/ecma-8/entry.js b/test/fixtures/es2017/entry.js similarity index 100% rename from test/fixtures/ecma-8/entry.js rename to test/fixtures/es2017/entry.js diff --git a/test/fixtures/ecma-5/entry.js b/test/fixtures/es5/entry.js similarity index 100% rename from test/fixtures/ecma-5/entry.js rename to test/fixtures/es5/entry.js diff --git a/test/fixtures/excluded1.js b/test/fixtures/exclude/1.js similarity index 100% rename from test/fixtures/excluded1.js rename to test/fixtures/exclude/1.js diff --git a/test/fixtures/excluded2.js b/test/fixtures/exclude/2.js similarity index 100% rename from test/fixtures/excluded2.js rename to test/fixtures/exclude/2.js diff --git a/test/fixtures/extract/1.js b/test/fixtures/extract/1.js new file mode 100644 index 00000000..3f9a04aa --- /dev/null +++ b/test/fixtures/extract/1.js @@ -0,0 +1,4 @@ +/* This is a comment from 1.js */ +function foo (bar) { + return bar; +} \ No newline at end of file diff --git a/test/fixtures/extract/2.js b/test/fixtures/extract/2.js new file mode 100644 index 00000000..59a2ace9 --- /dev/null +++ b/test/fixtures/extract/2.js @@ -0,0 +1,4 @@ +// This is a comment from 2.js +function foo2 (bar) { + return bar; +} \ No newline at end of file diff --git a/test/fixtures/extract/3.js b/test/fixtures/extract/3.js new file mode 100644 index 00000000..b2c444e0 --- /dev/null +++ b/test/fixtures/extract/3.js @@ -0,0 +1,4 @@ +/* This is a comment from 3.js */ +function foo3 (bar) { + return bar; +} \ No newline at end of file diff --git a/test/fixtures/extract/4.js b/test/fixtures/extract/4.js new file mode 100644 index 00000000..683b8597 --- /dev/null +++ b/test/fixtures/extract/4.js @@ -0,0 +1,4 @@ +// This is another comment from 4.js +function foo4 (bar) { + return baz; +} \ No newline at end of file diff --git a/test/fixtures/extract/entry.js b/test/fixtures/extract/entry.js new file mode 100644 index 00000000..66fb9078 --- /dev/null +++ b/test/fixtures/extract/entry.js @@ -0,0 +1,19 @@ +/* This is a comment 1 */ +function foo (bar) { + return bar; +} + +// This is a comment 2 +function foo2 (bar) { + return bar; +} + +/* This is a comment 3 */ +function foo3 (bar) { + return bar; +} + +// This is another comment 4 +function foo4 (bar) { + return baz; +} \ No newline at end of file diff --git a/test/fixtures/extract/entry2.js b/test/fixtures/extract/entry2.js new file mode 100644 index 00000000..fce840ec --- /dev/null +++ b/test/fixtures/extract/entry2.js @@ -0,0 +1,3 @@ +// This is comment 1 +var foo = 1; +/** @preserve This is comment 2 */ \ No newline at end of file diff --git a/test/fixtures/import-export/dep.js b/test/fixtures/import-export/dep.js deleted file mode 100644 index 6d24cac9..00000000 --- a/test/fixtures/import-export/dep.js +++ /dev/null @@ -1,2 +0,0 @@ -export const bar = 'bar'; -export default 'foo'; diff --git a/test/fixtures/import-export/entry.js b/test/fixtures/import-export/entry.js deleted file mode 100644 index a700e397..00000000 --- a/test/fixtures/import-export/entry.js +++ /dev/null @@ -1,15 +0,0 @@ -import foo, { bar } from './dep'; - -function Foo() { - const b = foo; - const baz = `baz${Math.random()}`; - return () => { - return { - a: b + bar + baz, - b, - baz, - }; - }; -} - -export default Foo; diff --git a/test/fixtures/included1.js b/test/fixtures/include/1.js similarity index 100% rename from test/fixtures/included1.js rename to test/fixtures/include/1.js diff --git a/test/fixtures/included2.js b/test/fixtures/include/2.js similarity index 100% rename from test/fixtures/included2.js rename to test/fixtures/include/2.js diff --git a/test/fixtures/parallel/1.js b/test/fixtures/parallel/1.js new file mode 100644 index 00000000..3f9a04aa --- /dev/null +++ b/test/fixtures/parallel/1.js @@ -0,0 +1,4 @@ +/* This is a comment from 1.js */ +function foo (bar) { + return bar; +} \ No newline at end of file diff --git a/test/fixtures/parallel/2.js b/test/fixtures/parallel/2.js new file mode 100644 index 00000000..59a2ace9 --- /dev/null +++ b/test/fixtures/parallel/2.js @@ -0,0 +1,4 @@ +// This is a comment from 2.js +function foo2 (bar) { + return bar; +} \ No newline at end of file diff --git a/test/fixtures/parallel/3.js b/test/fixtures/parallel/3.js new file mode 100644 index 00000000..b2c444e0 --- /dev/null +++ b/test/fixtures/parallel/3.js @@ -0,0 +1,4 @@ +/* This is a comment from 3.js */ +function foo3 (bar) { + return bar; +} \ No newline at end of file diff --git a/test/fixtures/parallel/4.js b/test/fixtures/parallel/4.js new file mode 100644 index 00000000..683b8597 --- /dev/null +++ b/test/fixtures/parallel/4.js @@ -0,0 +1,4 @@ +// This is another comment from 4.js +function foo4 (bar) { + return baz; +} \ No newline at end of file diff --git a/test/fixtures/parallel/entry.js b/test/fixtures/parallel/entry.js new file mode 100644 index 00000000..a389c87a --- /dev/null +++ b/test/fixtures/parallel/entry.js @@ -0,0 +1,19 @@ +/* This is a comment 1 */ +export function foo (bar) { + return bar; +} + +// This is a comment 2 +export function foo2 (bar) { + return bar; +} + +/* This is a comment 3 */ +export function foo3 (bar) { + return bar; +} + +// This is another comment 4 +export function foo4 (bar) { + return baz; +} \ No newline at end of file diff --git a/test/helpers.js b/test/helpers.js deleted file mode 100644 index 28cf8b32..00000000 --- a/test/helpers.js +++ /dev/null @@ -1,83 +0,0 @@ -/* eslint-disable consistent-return, import/no-extraneous-dependencies, import/order */ -import MemoryFileSystem from 'memory-fs'; -import webpack from 'webpack'; - -const majorVersion = require('webpack/package.json').version.split('.')[0]; - -export class PluginEnvironment { - constructor() { - this.events = []; - } - - getEnvironmentStub() { - return { - plugin: (name, handler) => { - this.events.push({ - name, - handler, - }); - }, - }; - } - - getEventBindings() { - return this.events; - } -} - -export function compile(compiler) { - return new Promise((resolve, reject) => { - compiler.run((err, stats) => { - if (err) return reject(err); - resolve(stats); - }); - }); -} - -export function createCompiler(options = {}) { - if (Number(majorVersion) >= 4) { - options.mode = 'development'; - } - const compiler = webpack( - Array.isArray(options) - ? options - : { - bail: true, - cache: false, - entry: `${__dirname}/fixtures/entry.js`, - output: { - path: `${__dirname}/dist`, - filename: '[name].[chunkhash].js', - chunkFilename: '[id].[name].[chunkhash].js', - }, - plugins: [ - new webpack.optimize.CommonsChunkPlugin({ - name: 'manifest', - }), - ], - ...options, - } - ); - compiler.outputFileSystem = new MemoryFileSystem(); - return compiler; -} - -export function countPlugins({ _plugins }) { - return Object.keys(_plugins).reduce((aggregate, name) => { - // eslint-disable-next-line no-param-reassign - aggregate[name] = Array.isArray(_plugins[name]) ? _plugins[name].length : 0; - return aggregate; - }, {}); -} - -export function removeCWD(str) { - return str.split(`${process.cwd()}/`).join(''); -} - -export function cleanErrorStack(error) { - return exports - .removeCWD(error.toString()) - .split('\n') - .slice(0, 2) - .join('\n'); -} diff --git a/test/helpers/compiler.js b/test/helpers/compiler.js new file mode 100644 index 00000000..534b9959 --- /dev/null +++ b/test/helpers/compiler.js @@ -0,0 +1,83 @@ +/* eslint-disable + import/order, + global-require, + multiline-ternary, + no-param-reassign +*/ +import del from 'del'; +import path from 'path'; +import webpack from 'webpack'; +import MemoryFS from 'memory-fs'; + +const mode = (config) => { + const { version } = require('webpack/package.json'); + + if (version >= '4.0.0') { + config.mode = config.mode || 'development'; + } +}; + +const module = (config) => { + return { + rules: + config.rules || config.loader + ? [ + { + test: config.loader.test || /\.txt$/, + use: { + loader: path.resolve(__dirname, '../../src'), + options: config.loader.options || {}, + }, + }, + ] + : [], + }; +}; + +const plugins = (config) => + [ + new webpack.optimize.CommonsChunkPlugin({ + names: ['runtime'], + minChunks: Infinity, + }), + ].concat(config.plugins || []); + +const output = (config) => { + return { + path: path.resolve( + __dirname, + `../outputs/${config.output ? config.output : ''}` + ), + filename: '[name].bundle.js', + }; +}; + +export default function(fixture, config, options) { + // Compiler Mode + mode(config); + // Compiler Config + config = { + devtool: config.devtool || 'sourcemap', + context: path.resolve(__dirname, '..', 'fixtures'), + entry: config.entry || `./${fixture}`, + output: output(config), + module: module(config), + plugins: plugins(config), + }; + // Compiler Options + options = Object.assign({ output: false }, options); + + if (options.output) del.sync(config.output.path); + + const compiler = webpack(config); + + if (!options.output) compiler.outputFileSystem = new MemoryFS(); + + return new Promise((resolve, reject) => + compiler.run((err, stats) => { + if (err) reject(err); + + resolve(stats); + }) + ); +} diff --git a/test/helpers/index.js b/test/helpers/index.js new file mode 100644 index 00000000..e74aa5c2 --- /dev/null +++ b/test/helpers/index.js @@ -0,0 +1,16 @@ +/* eslint-disable + * import/order, + * import/no-extraneous-dependencies, + * consistent-return, + */ +export function removeCWD(path) { + return path.split(`${process.cwd()}/`).join(''); +} + +export function cleanErrorStack(err) { + return exports + .removeCWD(err.toString()) + .split('\n') + .slice(0, 2) + .join('\n'); +} diff --git a/test/include-options.test.js b/test/include-options.test.js deleted file mode 100644 index 9b4a7107..00000000 --- a/test/include-options.test.js +++ /dev/null @@ -1,59 +0,0 @@ -import UglifyJsPlugin from '../src/index'; -import { cleanErrorStack, createCompiler, compile } from './helpers'; - -describe('when applied with include option', () => { - let compiler; - beforeEach(() => { - compiler = createCompiler({ - entry: { - included1: `${__dirname}/fixtures/included1.js`, - included2: `${__dirname}/fixtures/included2.js`, - entry: `${__dirname}/fixtures/entry.js`, - }, - }); - }); - - it('matches snapshot for a single include', () => { - new UglifyJsPlugin({ - include: /included1/, - }).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('matches snapshot for multiple includes', () => { - new UglifyJsPlugin({ - include: [/included1/, /included2/], - }).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); - } - } - }); - }); -}); diff --git a/test/invalid-options.test.js b/test/invalid-options.test.js deleted file mode 100644 index 9f4a1d73..00000000 --- a/test/invalid-options.test.js +++ /dev/null @@ -1,170 +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 }); - }).toThrow('Validation Error'); - - 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: {} }); - }).toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ parallel: true }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ parallel: 2 }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ parallel: '2' }); - }).toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ parallel: {} }); - }).toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ sourceMap: true }); - }).not.toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ sourceMap: 'true' }); - }).toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: null }); - }).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' } }); - }).toThrow('Validation Error'); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { emca: 5 } }); - }).not.toThrow(); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { emca: 8 } }); - }).not.toThrow(); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { ecma: 7.5 } }); - }).toThrow('should be integer'); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { ecma: true } }); - }).toThrow('should be integer'); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { ecma: '5' } }); - }).toThrow('should be integer'); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { ecma: 3 } }); - }).toThrow('should be >= 5'); - - expect(() => { - new UglifyJsPlugin({ uglifyOptions: { ecma: 10 } }); - }).toThrow('should be <= 8'); - }); - - 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/options/__snapshots__/.cache/uglifyjs-webpack-plugin/content-v2/sha512/97/23/484be479ab94dcfe7b8658b503d461971d6ac8f2164a1e26b6c589078c9154e7981943cd4be3585524191d304d4e89cbf046a9c594d0b5dad09302bca4ba b/test/options/__snapshots__/.cache/uglifyjs-webpack-plugin/content-v2/sha512/97/23/484be479ab94dcfe7b8658b503d461971d6ac8f2164a1e26b6c589078c9154e7981943cd4be3585524191d304d4e89cbf046a9c594d0b5dad09302bca4ba new file mode 100644 index 00000000..9a89ae62 --- /dev/null +++ b/test/options/__snapshots__/.cache/uglifyjs-webpack-plugin/content-v2/sha512/97/23/484be479ab94dcfe7b8658b503d461971d6ac8f2164a1e26b6c589078c9154e7981943cd4be3585524191d304d4e89cbf046a9c594d0b5dad09302bca4ba @@ -0,0 +1 @@ +{"code":"!function(e){function r(r){for(var t,i,c,l=r[0],s=r[1],p=r[2],f=0,d=[];f} 1`] = ` +"(window[\\"webpackJsonp\\"] = window[\\"webpackJsonp\\"] || []).push([[0],[ +/* 0 */ +/***/ (function(module, exports) { + +module.exports = function Bar1() { + const b = 2 + 2; + console.log(b + 1 + 2); +}; + +/***/ }) +],[[0,3,0]]]); +//# sourceMappingURL=1.bundle.js.map" +`; + +exports[`Options exclude {Array<{RegExp}>} 2`] = ` +"(window[\\"webpackJsonp\\"] = window[\\"webpackJsonp\\"] || []).push([[1],[ +/* 0 */, +/* 1 */ +/***/ (function(module, exports) { + +module.exports = function Bar2() { + const b = 2 + 2; + console.log(b + 1 + 2); +}; + +/***/ }) +],[[1,3,1]]]); +//# sourceMappingURL=2.bundle.js.map" +`; + +exports[`Options exclude {RegExp} 1`] = ` +"(window[\\"webpackJsonp\\"] = window[\\"webpackJsonp\\"] || []).push([[0],[ +/* 0 */ +/***/ (function(module, exports) { + +module.exports = function Bar1() { + const b = 2 + 2; + console.log(b + 1 + 2); +}; + +/***/ }) +],[[0,3,0]]]); +//# sourceMappingURL=1.bundle.js.map" +`; + +exports[`Options exclude {RegExp} 2`] = `"(window.webpackJsonp=window.webpackJsonp||[]).push([[1],[,function(o,n){o.exports=function(){console.log(7)}}],[[1,3,1]]]);"`; diff --git a/test/options/__snapshots__/extractComments.test.js.snap b/test/options/__snapshots__/extractComments.test.js.snap new file mode 100644 index 00000000..6e1dff2a --- /dev/null +++ b/test/options/__snapshots__/extractComments.test.js.snap @@ -0,0 +1,186 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`1.bundle.js 1`] = ` +"/*! For license information please see extracted.js */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[ +/* 0 */ +/***/function(n,w){}],[[0,5,0]]]); +//# sourceMappingURL=1.bundle.js.map" +`; + +exports[`2.bundle.js 1`] = ` +"/*! For license information please see extracted.js */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[1],[ +/* 0 */ +/* 1 */ +/***/, +/* 1 */ +/***/function(n,w){}],[[1,5,1]]]); +//# sourceMappingURL=2.bundle.js.map" +`; + +exports[`3.bundle.js 1`] = ` +"/*! For license information please see extracted.js */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{ +/***/2: +/***/function(n,w){}},[[2,5,2]]]); +//# sourceMappingURL=3.bundle.js.map" +`; + +exports[`4.bundle.js 1`] = ` +"/*! For license information please see extracted.js */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{ +/***/3: +/***/function(n,w){}},[[3,5,3]]]); +//# sourceMappingURL=4.bundle.js.map" +`; + +exports[`Options extract {Function} 1`] = ` +"/*! For license information please see 1.bundle.js.LICENSE */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[function(n,w){}],[[0,2,0]]]); +//# sourceMappingURL=1.bundle.js.map" +`; + +exports[`Options extract {Function} 2`] = ` +"/* 0 */ + +/***/ +" +`; + +exports[`Options extract {Function} 3`] = ` +"/*! For license information please see main.bundle.js.LICENSE */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[1],[,function(o,n){o.exports=function(){console.log(7)}}],[[1,2,1]]]); +//# sourceMappingURL=main.bundle.js.map" +`; + +exports[`Options extract {Function} 4`] = ` +"/* 0 */ + +/* 1 */ + +/***/ + +/* 1 */ + +/***/ +" +`; + +exports[`Options extract {Object<{Function}>} 1`] = ` +"/*! License information can be found in main.bundle.license.js */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[function(n,w){}],[[0,1,0]]]); +//# sourceMappingURL=main.bundle.js.map" +`; + +exports[`Options extract {Object<{Function}>} 2`] = ` +"/* 0 */ + +/***/ + +/** @preserve This is comment 2 */ + +/***/ +" +`; + +exports[`Options extract {Regex} 1`] = ` +"/*! For license information please see 1.bundle.js.LICENSE */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[function(n,w){}],[[0,2,0]]]); +//# sourceMappingURL=1.bundle.js.map" +`; + +exports[`Options extract {Regex} 2`] = ` +"/* 0 */ + +/***/ +" +`; + +exports[`Options extract {Regex} 3`] = ` +"/*! For license information please see main.bundle.js.LICENSE */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[1],[,function(o,n){o.exports=function(){console.log(7)}}],[[1,2,1]]]); +//# sourceMappingURL=main.bundle.js.map" +`; + +exports[`Options extract {Regex} 4`] = ` +"/* 0 */ + +/* 1 */ + +/***/ + +/* 1 */ + +/***/ +" +`; + +exports[`Options extract {String} 1`] = ` +"/*! For license information please see 1.bundle.js.LICENSE */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[function(n,w){}],[[0,2,0]]]); +//# sourceMappingURL=1.bundle.js.map" +`; + +exports[`Options extract {String} 2`] = ` +"/* 0 */ + +/***/ +" +`; + +exports[`Options extract {String} 3`] = ` +"/*! For license information please see main.bundle.js.LICENSE */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[1],[,function(o,n){o.exports=function(){console.log(7)}}],[[1,2,1]]]); +//# sourceMappingURL=main.bundle.js.map" +`; + +exports[`Options extract {String} 4`] = ` +"/* 0 */ + +/* 1 */ + +/***/ + +/* 1 */ + +/***/ +" +`; + +exports[`extracted.js 1`] = ` +"/* 0 */ + +/***/ + +/* 0 */ + +/* 1 */ + +/***/ + +/* 1 */ + +/***/ + +/***/ + +/***/ + +/***/ + +/***/ + +/***/ + +/***/ +" +`; + +exports[`main.bundle.js 1`] = ` +"/*! For license information please see extracted.js */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{ +/***/4: +/***/function(n,w){}},[[4,5,4]]]); +//# sourceMappingURL=main.bundle.js.map" +`; diff --git a/test/options/__snapshots__/include.test.js.snap b/test/options/__snapshots__/include.test.js.snap new file mode 100644 index 00000000..a091ebf7 --- /dev/null +++ b/test/options/__snapshots__/include.test.js.snap @@ -0,0 +1,24 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Options include {Array<{RegExp}>} 1`] = `"(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[function(o,n){o.exports=function(){console.log(7)}}],[[0,3,0]]]);"`; + +exports[`Options include {Array<{RegExp}>} 2`] = `"(window.webpackJsonp=window.webpackJsonp||[]).push([[1],[,function(o,n){o.exports=function(){console.log(7)}}],[[1,3,1]]]);"`; + +exports[`Options include {RegExp} 1`] = `"(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[function(o,n){o.exports=function(){console.log(7)}}],[[0,3,0]]]);"`; + +exports[`Options include {RegExp} 2`] = ` +"(window[\\"webpackJsonp\\"] = window[\\"webpackJsonp\\"] || []).push([[1],[ +/* 0 */, +/* 1 */ +/***/ (function(module, exports) { + +module.exports = function Bar2() { + const b = 2 + 2; + console.log(b + 1 + 2); +}; + + +/***/ }) +],[[1,3,1]]]); +//# sourceMappingURL=2.bundle.js.map" +`; diff --git a/test/options/__snapshots__/parallel.test.js.snap b/test/options/__snapshots__/parallel.test.js.snap new file mode 100644 index 00000000..0bd047f9 --- /dev/null +++ b/test/options/__snapshots__/parallel.test.js.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Options parallel {Boolean} - false 1`] = `"(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[function(n,o,t){\\"use strict\\";t.r(o),t.d(o,\\"foo\\",function(){return u}),t.d(o,\\"foo2\\",function(){return r}),t.d(o,\\"foo3\\",function(){return f}),t.d(o,\\"foo4\\",function(){return c});function u(n){return n}function r(n){return n}function f(n){return n}function c(n){return baz}}],[[0,1,0]]]);"`; + +exports[`Options parallel {Boolean} - false 2`] = `"!function(e){function r(r){for(var t,i,c,l=r[0],s=r[1],p=r[2],f=0,d=[];f (!/\.map/.test(file) ? file : false); + +beforeEach(() => del.sync(cacheDir)); + +describe('Options', () => { + describe('cache', () => { + test('{Boolean} - false', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + parallel: false, + }), + ], + }; + + const stats = await webpack('parallel/entry.js', config); + const { assets } = stats.compilation; + + Object.keys(assets) + .filter(filter) + .forEach((asset) => { + expect(assets[asset].source()).toMatchSnapshot(); + }); + + expect(existsSync(cacheDir)).toBe(false); + }); + + test('{Boolean} - true', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + cache: true, + }), + ], + }; + + const stats = await webpack('parallel/entry.js', config); + const { assets } = stats.compilation; + + Object.keys(assets) + .filter(filter) + .forEach((asset) => { + expect(assets[asset].source()).toMatchSnapshot(); + }); + + expect(existsSync(cacheDir)).toBe(true); + }); + + test('{String}', async () => { + const cacheDir = + 'test/options/__snapshots__/.cache/uglifyjs-webpack-plugin'; + + const config = { + plugins: [ + new UglifyJsPlugin({ + cache: cacheDir, + }), + ], + }; + + const stats = await webpack('parallel/entry.js', config); + const { assets } = stats.compilation; + + Object.keys(assets) + .filter(filter) + .forEach((asset) => { + expect(assets[asset].source()).toMatchSnapshot(); + }); + + expect(existsSync(cacheDir)).toBe(true); + }); + }); +}); diff --git a/test/options/ecma.test.js b/test/options/ecma.test.js new file mode 100644 index 00000000..d71455b9 --- /dev/null +++ b/test/options/ecma.test.js @@ -0,0 +1,100 @@ +import webpack from '../helpers/compiler'; +import UglifyJsPlugin from '../../src/index'; + +describe('ECMAScript', () => { + test('ES5', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + uglifyOptions: { + ecma: 5, + mangle: false, + warnings: true, + output: { + beautify: true, + }, + }, + }), + ], + }; + + const stats = await webpack('es5/entry.js', config); + const { assets } = stats.compilation; + + const source = assets['main.bundle.js'].source(); + + expect(source).toMatchSnapshot(); + }); + + test('ES2015', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + uglifyOptions: { + ecma: 6, + mangle: false, + warnings: true, + output: { + beautify: true, + }, + }, + }), + ], + }; + + const stats = await webpack('es2015/entry.js', config); + const { assets } = stats.compilation; + + const source = assets['main.bundle.js'].source(); + + expect(source).toMatchSnapshot(); + }); + + test('ES2016', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + uglifyOptions: { + ecma: 7, + mangle: false, + warnings: true, + output: { + beautify: true, + }, + }, + }), + ], + }; + + const stats = await webpack('es2016/entry.js', config); + const { assets } = stats.compilation; + + const source = assets['main.bundle.js'].source(); + + expect(source).toMatchSnapshot(); + }); + + test('ES2017', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + uglifyOptions: { + ecma: 8, + mangle: false, + warnings: true, + output: { + beautify: true, + }, + }, + }), + ], + }; + + const stats = await webpack('es2017/entry.js', config); + const { assets } = stats.compilation; + + const source = assets['main.bundle.js'].source(); + + expect(source).toMatchSnapshot(); + }); +}); diff --git a/test/options/exclude.test.js b/test/options/exclude.test.js new file mode 100644 index 00000000..2bedc2be --- /dev/null +++ b/test/options/exclude.test.js @@ -0,0 +1,48 @@ +import webpack from '../helpers/compiler'; +import UglifyJsPlugin from '../../src/index'; + +describe('Options', () => { + describe('exclude', () => { + test('{RegExp}', async () => { + const config = { + entry: { + 1: `./exclude/1.js`, + 2: `./exclude/2.js`, + entry: `./entry.js`, + }, + plugins: [ + new UglifyJsPlugin({ + exclude: /1/, + }), + ], + }; + + const stats = await webpack(false, config); + const { assets } = stats.compilation; + + expect(assets['1.bundle.js'].source()).toMatchSnapshot(); + expect(assets['2.bundle.js'].source()).toMatchSnapshot(); + }); + + test('{Array<{RegExp}>}', async () => { + const config = { + entry: { + 1: `./exclude/1.js`, + 2: `./exclude/2.js`, + entry: `./entry.js`, + }, + plugins: [ + new UglifyJsPlugin({ + exclude: [/1/, /2/], + }), + ], + }; + + const stats = await webpack(false, config); + const { assets } = stats.compilation; + + expect(assets['1.bundle.js'].source()).toMatchSnapshot(); + expect(assets['2.bundle.js'].source()).toMatchSnapshot(); + }); + }); +}); diff --git a/test/options/extractComments.test.js b/test/options/extractComments.test.js new file mode 100644 index 00000000..3ee60ca4 --- /dev/null +++ b/test/options/extractComments.test.js @@ -0,0 +1,137 @@ +import webpack from '../helpers/compiler'; +import UglifyJsPlugin from '../../src/index'; + +describe('Options', () => { + describe('extract', () => { + test('{String}', async () => { + const config = { + entry: { + 1: './extract/1.js', + main: './entry.js', + }, + plugins: [ + new UglifyJsPlugin({ + extractComments: 'all', + }), + ], + }; + + const stats = await webpack('extract/entry2.js', config); + const { assets } = stats.compilation; + + expect(assets['1.bundle.js'].source()).toMatchSnapshot(); + expect(assets['1.bundle.js.LICENSE'].source()).toMatchSnapshot(); + + expect(assets['main.bundle.js'].source()).toMatchSnapshot(); + expect(assets['main.bundle.js.LICENSE'].source()).toMatchSnapshot(); + }); + + test('{Regex}', async () => { + const config = { + entry: { + 1: './extract/1.js', + main: './entry.js', + }, + plugins: [ + new UglifyJsPlugin({ + extractComments: /.*/, + }), + ], + }; + + const stats = await webpack('extract/entry2.js', config); + const { assets } = stats.compilation; + + expect(assets['1.bundle.js'].source()).toMatchSnapshot(); + expect(assets['1.bundle.js.LICENSE'].source()).toMatchSnapshot(); + + expect(assets['main.bundle.js'].source()).toMatchSnapshot(); + expect(assets['main.bundle.js.LICENSE'].source()).toMatchSnapshot(); + }); + + test('{Object}', async () => { + const config = { + entry: { + 1: './extract/1.js', + 2: './extract/2.js', + 3: './extract/3.js', + 4: './extract/4.js', + main: './extract/entry.js', + }, + plugins: [ + new UglifyJsPlugin({ + exclude: /runtime/, + uglifyOptions: { + output: { + comments: 'all', + }, + }, + extractComments: { + condition: /.*/, + filename: 'extracted.js', + }, + }), + ], + }; + + const stats = await webpack('extract/entry.js', config); + const { assets } = stats.compilation; + + expect(assets['1.bundle.js'].source()).toMatchSnapshot('1.bundle.js'); + expect(assets['2.bundle.js'].source()).toMatchSnapshot('2.bundle.js'); + expect(assets['3.bundle.js'].source()).toMatchSnapshot('3.bundle.js'); + expect(assets['4.bundle.js'].source()).toMatchSnapshot('4.bundle.js'); + expect(assets['main.bundle.js'].source()).toMatchSnapshot( + 'main.bundle.js' + ); + + expect(assets['extracted.js'].source()).toMatchSnapshot('extracted.js'); + }); + + test('{Object<{Function}>}', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + extractComments: { + condition: true, + filename(file) { + return file.replace(/(\.\w+)$/, '.license$1'); + }, + banner(file) { + return `License information can be found in ${file}`; + }, + }, + }), + ], + }; + + const stats = await webpack('extract/entry2.js', config); + const { assets } = stats.compilation; + + expect(assets['main.bundle.js'].source()).toMatchSnapshot(); + expect(assets['main.bundle.license.js'].source()).toMatchSnapshot(); + }); + + test('{Function}', async () => { + const config = { + entry: { + 1: './extract/1.js', + main: './entry.js', + }, + plugins: [ + new UglifyJsPlugin({ + extractComments: () => true, + }), + ], + }; + + const stats = await webpack('extract/entry2.js', config); + const { assets } = stats.compilation; + + expect(assets['1.bundle.js'].source()).toMatchSnapshot(); + expect(assets['1.bundle.js.LICENSE'].source()).toMatchSnapshot(); + expect(assets['main.bundle.js'].source()).toMatchSnapshot(); + expect(assets['main.bundle.js.LICENSE'].source()).toMatchSnapshot(); + }); + }); +}); diff --git a/test/options/include.test.js b/test/options/include.test.js new file mode 100644 index 00000000..e9c0543d --- /dev/null +++ b/test/options/include.test.js @@ -0,0 +1,48 @@ +import webpack from '../helpers/compiler'; +import UglifyJsPlugin from '../../src/index'; + +describe('Options', () => { + describe('include', () => { + test('{RegExp}', async () => { + const config = { + entry: { + 1: `./include/1.js`, + 2: `./include/2.js`, + entry: `./entry.js`, + }, + plugins: [ + new UglifyJsPlugin({ + include: /1/, + }), + ], + }; + + const stats = await webpack(false, config); + const { assets } = stats.compilation; + + expect(assets['1.bundle.js'].source()).toMatchSnapshot(); + expect(assets['2.bundle.js'].source()).toMatchSnapshot(); + }); + + test('{Array<{RegExp}>}', async () => { + const config = { + entry: { + 1: `./include/1.js`, + 2: `./include/2.js`, + entry: `./entry.js`, + }, + plugins: [ + new UglifyJsPlugin({ + include: [/1/, /2/], + }), + ], + }; + + const stats = await webpack(false, config); + const { assets } = stats.compilation; + + expect(assets['1.bundle.js'].source()).toMatchSnapshot(); + expect(assets['2.bundle.js'].source()).toMatchSnapshot(); + }); + }); +}); diff --git a/test/options/parallel.test.js b/test/options/parallel.test.js new file mode 100644 index 00000000..d4d92aae --- /dev/null +++ b/test/options/parallel.test.js @@ -0,0 +1,65 @@ +import webpack from '../helpers/compiler'; +import UglifyJsPlugin from '../../src/index'; + +const filter = (file) => (!/\.map/.test(file) ? file : false); + +describe('Options', () => { + describe('parallel', () => { + test('{Boolean} - false', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + parallel: false, + }), + ], + }; + + const stats = await webpack('parallel/entry.js', config); + const { assets } = stats.compilation; + + Object.keys(assets) + .filter(filter) + .forEach((asset) => { + expect(assets[asset].source()).toMatchSnapshot(); + }); + }); + + test('{Boolean} - true', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + parallel: true, + }), + ], + }; + + const stats = await webpack('parallel/entry.js', config); + const { assets } = stats.compilation; + + Object.keys(assets) + .filter(filter) + .forEach((asset) => { + expect(assets[asset].source()).toMatchSnapshot(); + }); + }); + + test('{Number}', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + parallel: 2, + }), + ], + }; + + const stats = await webpack('parallel/entry.js', config); + const { assets } = stats.compilation; + + Object.keys(assets) + .filter(filter) + .forEach((asset) => { + expect(assets[asset].source()).toMatchSnapshot(); + }); + }); + }); +}); diff --git a/test/options/sourceMap.test.js b/test/options/sourceMap.test.js new file mode 100644 index 00000000..30f172e1 --- /dev/null +++ b/test/options/sourceMap.test.js @@ -0,0 +1,43 @@ +import webpack from '../helpers/compiler'; +import UglifyJsPlugin from '../../src/index'; + +describe('Options', () => { + describe('sourceMap', () => { + test('{Boolean} - true', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + sourceMap: true, + }), + ], + }; + + const stats = await webpack('entry.js', config); + const { assets } = stats.compilation; + + const { source, map } = assets['main.bundle.js'].sourceAndMap(); + + expect(source).toMatchSnapshot(); + expect(map).toMatchSnapshot(); + }); + }); + + test('{Boolean} - true (parallel)', async () => { + const config = { + plugins: [ + new UglifyJsPlugin({ + parallel: true, + sourceMap: true, + }), + ], + }; + + const stats = await webpack('entry.js', config); + const { assets } = stats.compilation; + + const { source, map } = assets['main.bundle.js'].sourceAndMap(); + + expect(source).toMatchSnapshot(); + expect(map).toMatchSnapshot(); + }); +}); diff --git a/test/parallel-options.test.js b/test/parallel-options.test.js deleted file mode 100644 index f9b7a5f0..00000000 --- a/test/parallel-options.test.js +++ /dev/null @@ -1,398 +0,0 @@ -import os from 'os'; -import workerFarm from 'worker-farm'; -import UglifyJsPlugin from '../src/index'; -import { - PluginEnvironment, - createCompiler, - compile, - cleanErrorStack, -} from './helpers'; - -// Based on https://github.com/facebook/jest/blob/edde20f75665c2b1e3c8937f758902b5cf28a7b4/packages/jest-runner/src/__tests__/test_runner.test.js -let workerFarmMock; - -jest.mock('worker-farm', () => { - const mock = jest.fn( - (options, worker) => - (workerFarmMock = jest.fn((data, callback) => - // eslint-disable-next-line global-require, import/no-dynamic-require - require(worker)(data, callback) - )) - ); - mock.end = jest.fn(); - return mock; -}); - -describe('when options.parallel', () => { - const assets = { - 'test.js': { - source: () => 'function test(foo) { foo = 1; }', - }, - 'test1.js': { - source: () => 'function test1(foo) { foo = 1; }', - }, - 'test2.js': { - source: () => 'function test2(foo) { foo = 1; }', - }, - 'test3.js': { - source: () => 'function test3(foo) { foo = 1; }', - }, - }; - - describe('false', () => { - let eventBindings; - let eventBinding; - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - parallel: false, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(eventBindings.length).toBe(1); - }); - - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - let callback; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = assets; - compilation.errors = []; - - workerFarm.mockClear(); - workerFarm.end.mockClear(); - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(compilationEventBindings.length).toBe(1); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual( - 'optimize-chunk-assets' - ); - }); - - it('only calls callback once', (done) => { - callback = jest.fn(); - compilationEventBinding.handler([''], () => { - callback(); - expect(callback.mock.calls.length).toBe(1); - done(); - }); - }); - - it('parallelization', (done) => { - compilationEventBinding.handler( - [ - { - files: ['test.js', 'test1.js', 'test2.js', 'test3.js'], - }, - ], - () => { - expect(workerFarm.mock.calls.length).toBe(0); - expect(workerFarm.end.mock.calls.length).toBe(0); - - done(); - } - ); - }); - }); - }); - }); - - it('matches snapshot', () => { - const compiler = createCompiler(); - new UglifyJsPlugin({ parallel: false }).apply(compiler); - - return compile(compiler).then((stats) => { - const errors = stats.compilation.errors.map(cleanErrorStack); - const warnings = stats.compilation.warnings.map(cleanErrorStack); - - expect(errors).toMatchSnapshot('parallel `false`: errors'); - expect(warnings).toMatchSnapshot('parallel `false`: warnings'); - - for (const file in stats.compilation.assets) { - if ( - Object.prototype.hasOwnProperty.call(stats.compilation.assets, file) - ) { - expect(stats.compilation.assets[file].source()).toMatchSnapshot( - `parallel \`false\`: asset ${file}` - ); - } - } - }); - }); - }); - - describe('true', () => { - let eventBindings; - let eventBinding; - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - parallel: true, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(eventBindings.length).toBe(1); - }); - - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - let callback; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = assets; - compilation.errors = []; - - workerFarm.mockClear(); - workerFarm.end.mockClear(); - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(compilationEventBindings.length).toBe(1); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual( - 'optimize-chunk-assets' - ); - }); - - it('only calls callback once', (done) => { - callback = jest.fn(); - compilationEventBinding.handler([''], () => { - callback(); - expect(callback.mock.calls.length).toBe(1); - done(); - }); - }); - - it('parallelization', (done) => { - compilationEventBinding.handler( - [ - { - files: ['test.js', 'test1.js', 'test2.js', 'test3.js'], - }, - ], - () => { - expect(workerFarm.mock.calls.length).toBe(1); - expect(workerFarm.mock.calls[0][0].maxConcurrentWorkers).toBe( - os.cpus().length - 1 - ); - expect(workerFarmMock.mock.calls.length).toBe(4); - expect(workerFarm.end.mock.calls.length).toBe(1); - - done(); - } - ); - }); - }); - }); - }); - - it('matches snapshot', () => { - const compiler = createCompiler(); - new UglifyJsPlugin({ parallel: 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('parallel `true`: errors'); - expect(warnings).toMatchSnapshot('parallel `true`: warnings'); - - for (const file in stats.compilation.assets) { - if ( - Object.prototype.hasOwnProperty.call(stats.compilation.assets, file) - ) { - expect(stats.compilation.assets[file].source()).toMatchSnapshot( - `parallel \`true\`: asset ${file}` - ); - } - } - }); - }); - }); - - describe('number', () => { - let eventBindings; - let eventBinding; - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - parallel: 2, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(eventBindings.length).toBe(1); - }); - - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - let callback; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = assets; - compilation.errors = []; - - workerFarm.mockClear(); - workerFarm.end.mockClear(); - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(compilationEventBindings.length).toBe(1); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual( - 'optimize-chunk-assets' - ); - }); - - it('only calls callback once', (done) => { - callback = jest.fn(); - compilationEventBinding.handler([''], () => { - callback(); - expect(callback.mock.calls.length).toBe(1); - done(); - }); - }); - - it('parallelization', (done) => { - compilationEventBinding.handler( - [ - { - files: ['test.js', 'test1.js', 'test2.js', 'test3.js'], - }, - ], - () => { - expect(workerFarm.mock.calls.length).toBe(1); - // Appveyor give only one core - expect(workerFarm.mock.calls[0][0].maxConcurrentWorkers).toBe( - Math.min(Number(2) || 0, os.cpus().length - 1) - ); - expect(workerFarmMock.mock.calls.length).toBe(4); - expect(workerFarm.end.mock.calls.length).toBe(1); - - done(); - } - ); - }); - }); - }); - }); - - it('matches snapshot', () => { - const compiler = createCompiler(); - new UglifyJsPlugin({ parallel: 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('parallel `number`: errors'); - expect(warnings).toMatchSnapshot('parallel `number`: warnings'); - - for (const file in stats.compilation.assets) { - if ( - Object.prototype.hasOwnProperty.call(stats.compilation.assets, file) - ) { - expect(stats.compilation.assets[file].source()).toMatchSnapshot( - `parallel \`number\`: asset ${file}` - ); - } - } - }); - }); - }); -}); diff --git a/test/source-map-options.test.js b/test/source-map-options.test.js deleted file mode 100644 index 8815bf95..00000000 --- a/test/source-map-options.test.js +++ /dev/null @@ -1,296 +0,0 @@ -import UglifyJsPlugin from '../src/index'; -import { - PluginEnvironment, - createCompiler, - compile, - cleanErrorStack, -} from './helpers'; - -describe('when options.sourceMap', () => { - const assets = { - 'test.js': { - source: () => 'function test(foo) { foo = 1; }', - }, - 'test1.js': { - source: () => 'function test1(foo) { foo = 1; }', - }, - 'test2.js': { - source: () => 'function test2(foo) { foo = 1; }', - }, - 'test3.js': { - source: () => 'function test3(foo) { foo = 1; }', - }, - }; - - describe('true', () => { - let eventBindings; - let eventBinding; - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - compilerEnv.devtool = 'source-map'; - - const plugin = new UglifyJsPlugin({ - sourceMap: true, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(eventBindings.length).toBe(1); - }); - - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - let callback; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = assets; - compilation.errors = []; - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds two event handler', () => { - expect(compilationEventBindings[0].name).toBe('build-module'); - expect(compilationEventBindings[1].name).toBe( - 'optimize-chunk-assets' - ); - }); - - describe('build-module handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to build-module event', () => { - expect(compilationEventBinding.name).toEqual('build-module'); - }); - - it('build-module handler', (done) => { - const moduleArgs = { useSourceMap: false }; - const mockBuildModuleEvent = jest.fn(() => - compilationEventBinding.handler(moduleArgs) - ); - - mockBuildModuleEvent(); - - expect(mockBuildModuleEvent.mock.calls.length).toBe(1); - expect(moduleArgs.useSourceMap).toBe(true); - done(); - }); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [, compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual( - 'optimize-chunk-assets' - ); - }); - - it('only calls callback once', (done) => { - callback = jest.fn(); - compilationEventBinding.handler( - [ - { - files: ['test.js', 'test1.js', 'test2.js', 'test3.js'], - }, - ], - () => { - callback(); - expect(callback.mock.calls.length).toBe(1); - done(); - } - ); - }); - }); - }); - }); - - it('matches snapshot', () => { - const compiler = createCompiler(); - new UglifyJsPlugin({ sourceMap: 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('source map: errors'); - expect(warnings).toMatchSnapshot('source map: warnings'); - - for (const file in stats.compilation.assets) { - if ( - Object.prototype.hasOwnProperty.call(stats.compilation.assets, file) - ) { - const asset = stats.compilation.assets[file].sourceAndMap(); - - asset.map.sources = []; - - expect(asset.source).toMatchSnapshot(`source: asset ${file}`); - expect(asset.map).toMatchSnapshot(`source map: asset ${file}`); - } - } - }); - }); - }); - - describe('true and options.parallel true', () => { - let eventBindings; - let eventBinding; - - beforeEach(() => { - const pluginEnvironment = new PluginEnvironment(); - const compilerEnv = pluginEnvironment.getEnvironmentStub(); - compilerEnv.context = ''; - - const plugin = new UglifyJsPlugin({ - parallel: true, - sourceMap: true, - }); - plugin.apply(compilerEnv); - eventBindings = pluginEnvironment.getEventBindings(); - }); - - it('binds one event handler', () => { - expect(eventBindings.length).toBe(1); - }); - - describe('compilation handler', () => { - beforeEach(() => { - [eventBinding] = eventBindings; - }); - - it('binds to compilation event', () => { - expect(eventBinding.name).toBe('compilation'); - }); - - describe('when called', () => { - let chunkPluginEnvironment; - let compilationEventBindings; - let compilationEventBinding; - let compilation; - let callback; - - beforeEach(() => { - chunkPluginEnvironment = new PluginEnvironment(); - compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = assets; - compilation.errors = []; - - eventBinding.handler(compilation); - compilationEventBindings = chunkPluginEnvironment.getEventBindings(); - }); - - it('binds two event handler', () => { - expect(compilationEventBindings[0].name).toBe('build-module'); - expect(compilationEventBindings[1].name).toBe( - 'optimize-chunk-assets' - ); - }); - - describe('build-module handler', () => { - beforeEach(() => { - [compilationEventBinding] = compilationEventBindings; - }); - - it('binds to build-module event', () => { - expect(compilationEventBinding.name).toEqual('build-module'); - }); - - it('build-module handler', (done) => { - const moduleArgs = { useSourceMap: false }; - const mockBuildModuleEvent = jest.fn(() => - compilationEventBinding.handler(moduleArgs) - ); - - mockBuildModuleEvent(); - - expect(mockBuildModuleEvent.mock.calls.length).toBe(1); - expect(moduleArgs.useSourceMap).toBe(true); - done(); - }); - }); - - describe('optimize-chunk-assets handler', () => { - beforeEach(() => { - [, compilationEventBinding] = compilationEventBindings; - }); - - it('binds to optimize-chunk-assets event', () => { - expect(compilationEventBinding.name).toEqual( - 'optimize-chunk-assets' - ); - }); - - it('only calls callback once', (done) => { - callback = jest.fn(); - compilationEventBinding.handler( - [ - { - files: ['test.js', 'test1.js', 'test2.js', 'test3.js'], - }, - ], - () => { - callback(); - expect(callback.mock.calls.length).toBe(1); - done(); - } - ); - }); - }); - }); - }); - - it('matches snapshot', () => { - const compiler = createCompiler(); - new UglifyJsPlugin({ parallel: true, sourceMap: 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('source map and parallel: errors'); - expect(warnings).toMatchSnapshot('source map and parallel: warnings'); - - for (const file in stats.compilation.assets) { - if ( - Object.prototype.hasOwnProperty.call(stats.compilation.assets, file) - ) { - const asset = stats.compilation.assets[file].sourceAndMap(); - - asset.map.sources = []; - - expect(asset.source).toMatchSnapshot( - `source and parallel: asset ${file}` - ); - expect(asset.map).toMatchSnapshot( - `source map and parallel: asset ${file}` - ); - } - } - }); - }); - }); -}); diff --git a/test/supports-multicompiler.test.js b/test/supports-multicompiler.test.js deleted file mode 100644 index 5be3a1b4..00000000 --- a/test/supports-multicompiler.test.js +++ /dev/null @@ -1,88 +0,0 @@ -import MultiCompiler from 'webpack/lib/MultiCompiler'; -import MultiStats from 'webpack/lib/MultiStats'; -import UglifyJsPlugin from '../src/index'; -import { - cleanErrorStack, - createCompiler, - countPlugins, - compile, -} from './helpers'; - -describe('when using MultiCompiler with empty options', () => { - it('matches snapshot', () => { - const multiCompiler = createCompiler([ - { - bail: true, - cache: false, - entry: `${__dirname}/fixtures/entry.js`, - output: { - path: `${__dirname}/dist`, - filename: '[name].[chunkhash].js', - chunkFilename: '[id].[name].[chunkhash].js', - }, - }, - { - bail: true, - cache: false, - entry: `${__dirname}/fixtures/entry.js`, - output: { - path: `${__dirname}/dist`, - filename: '[name].[chunkhash].js', - chunkFilename: '[id].[name].[chunkhash].js', - }, - plugins: [new UglifyJsPlugin()], - }, - { - bail: true, - cache: false, - entry: `${__dirname}/fixtures/import-export/entry.js`, - output: { - path: `${__dirname}/dist-MultiCompiler`, - filename: '[name].[chunkhash].js', - chunkFilename: '[id].[name].[chunkhash].js', - }, - plugins: [new UglifyJsPlugin()], - }, - ]); - - const emptyPluginCount = countPlugins(multiCompiler.compilers[0]); - const expectedPluginCount = countPlugins(multiCompiler.compilers[1]); - - expect(emptyPluginCount).not.toEqual(expectedPluginCount); - expect(multiCompiler).toBeInstanceOf(MultiCompiler); - - multiCompiler.compilers.slice(2).forEach((compiler) => { - const pluginCount = countPlugins(compiler); - expect(pluginCount).not.toEqual(emptyPluginCount); - expect(pluginCount).toEqual(expectedPluginCount); - expect(pluginCount).toMatchSnapshot('compiler plugin count'); - }); - - expect(multiCompiler).toBeInstanceOf(MultiCompiler); - - return compile(multiCompiler).then((multiStats) => { - expect(multiStats).toBeInstanceOf(MultiStats); - - multiStats.stats.forEach((stats) => { - const errors = stats.compilation.errors.map(cleanErrorStack); - const warnings = stats.compilation.warnings.map(cleanErrorStack); - - expect(errors.length).toEqual(0); - expect(warnings.length).toEqual(0); - - 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 - ); - } - } - }); - }); - }); -}); diff --git a/test/uglify/__snapshots__/worker.test.js.snap b/test/workers/__snapshots__/worker.test.js.snap similarity index 97% rename from test/uglify/__snapshots__/worker.test.js.snap rename to test/workers/__snapshots__/worker.test.js.snap index 6f064f11..7a786abb 100644 --- a/test/uglify/__snapshots__/worker.test.js.snap +++ b/test/workers/__snapshots__/worker.test.js.snap @@ -12,7 +12,7 @@ Object { exports[`test2.js 1`] = ` Object { - "code": "var foo=1;", + "code": "var foo=1;/* hello */", "error": undefined, "extractedComments": Array [], "map": undefined, diff --git a/test/uglify/worker.test.js b/test/workers/worker.test.js similarity index 87% rename from test/uglify/worker.test.js rename to test/workers/worker.test.js index 4aa341e2..6da48064 100644 --- a/test/uglify/worker.test.js +++ b/test/workers/worker.test.js @@ -1,22 +1,24 @@ import serialize from 'serialize-javascript'; import worker from '../../src/uglify/worker'; -describe('matches snapshot', () => { - it('normalizes when options.extractComments is regex', () => { +describe('Worker', () => { + test('normalizes when options.extractComments is regex', () => { const options = { file: 'test1.js', input: 'var foo = 1;/* hello */', extractComments: /foo/, }; + worker(serialize(options), (error, data) => { if (error) { throw error; } + expect(data).toMatchSnapshot(options.file); }); }); - it('normalizes when uglifyOptions.output.comments is string: all', () => { + test('normalizes when uglifyOptions.output.comments is string: all', () => { const options = { file: 'test2.js', input: 'var foo = 1;/* hello */', @@ -26,15 +28,17 @@ describe('matches snapshot', () => { }, }, }; + worker(serialize(options), (error, data) => { if (error) { throw error; } + expect(data).toMatchSnapshot(options.file); }); }); - it('normalizes when uglifyOptions.output.comments is string: some', () => { + test('normalizes when uglifyOptions.output.comments is string: some', () => { const options = { file: 'test3.js', input: 'var foo = 1;/* hello */', @@ -52,7 +56,7 @@ describe('matches snapshot', () => { }); }); - it('normalizes when uglifyOptions.extractComments is number', () => { + test('normalizes when uglifyOptions.extractComments is number', () => { const options = { file: 'test4.js', input: 'var foo = 1;/* hello */', @@ -63,10 +67,12 @@ describe('matches snapshot', () => { }, extractComments: 1, }; + worker(serialize(options), (error, data) => { if (error) { throw error; } + expect(data).toMatchSnapshot(options.file); }); }); @@ -90,15 +96,17 @@ describe('matches snapshot', () => { }, }, }; + worker(serialize(options), (error, data) => { if (error) { throw error; } + expect(data).toMatchSnapshot(options.file); }); }); - it('when options.inputSourceMap', () => { + test('when options.inputSourceMap', () => { const options = { file: 'test6.js', input: 'function foo(x) { if (x) { return bar(); not_called1(); } }', @@ -109,10 +117,12 @@ describe('matches snapshot', () => { mappings: 'AAAA,QAASA,KAAIC,GACT,GAAIA,EAAG,CACH,MAAOC,MACPC', }, }; + worker(serialize(options), (error, data) => { if (error) { throw error; } + expect(data).toMatchSnapshot(options.file); }); });