diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..c89d4ff --- /dev/null +++ b/jest.config.js @@ -0,0 +1,4 @@ +module.exports = { + testEnvironment: 'node', + snapshotResolver: './test/helpers/snapshotResolver.js', +}; diff --git a/package-lock.json b/package-lock.json index dea3f8c..7a51684 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,22 @@ "source-map": "^0.5.0" }, "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -47,6 +63,14 @@ "browserslist": "^4.12.0", "invariant": "^2.2.4", "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, "@babel/core": { @@ -88,6 +112,12 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -145,6 +175,14 @@ "invariant": "^2.2.4", "levenary": "^1.1.1", "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, "@babel/helper-create-class-features-plugin": { @@ -982,6 +1020,14 @@ "invariant": "^2.2.2", "levenary": "^1.1.1", "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, "@babel/preset-modules": { @@ -1527,15 +1573,16 @@ "dev": true }, "@jest/console": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.1.0.tgz", - "integrity": "sha512-+0lpTHMd/8pJp+Nd4lyip+/Iyf2dZJvcCqrlkeZQoQid+JlThA4M9vxHtheyrQ99jJTMQam+es4BcvZ5W5cC3A==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.2.0.tgz", + "integrity": "sha512-mXQfx3nSLwiHm1i7jbu+uvi+vvpVjNGzIQYLCfsat9rapC+MJkS4zBseNrgJE0vU921b3P67bQzhduphjY3Tig==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.1.0", - "jest-util": "^26.1.0", + "jest-message-util": "^26.2.0", + "jest-util": "^26.2.0", "slash": "^3.0.0" }, "dependencies": { @@ -1598,33 +1645,34 @@ } }, "@jest/core": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.1.0.tgz", - "integrity": "sha512-zyizYmDJOOVke4OO/De//aiv8b07OwZzL2cfsvWF3q9YssfpcKfcnZAwDY8f+A76xXSMMYe8i/f/LPocLlByfw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.2.0.tgz", + "integrity": "sha512-btXHfHuCR9BZJcXTu+iNjUSGfRYo28aVLMXL8B/gcDPypAvaQ+NXPJSLljhRIBGSzcBz3CLE/jQf2NyfwXiLNA==", "dev": true, "requires": { - "@jest/console": "^26.1.0", - "@jest/reporters": "^26.1.0", - "@jest/test-result": "^26.1.0", - "@jest/transform": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/console": "^26.2.0", + "@jest/reporters": "^26.2.0", + "@jest/test-result": "^26.2.0", + "@jest/transform": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.1.0", - "jest-config": "^26.1.0", - "jest-haste-map": "^26.1.0", - "jest-message-util": "^26.1.0", + "jest-changed-files": "^26.2.0", + "jest-config": "^26.2.0", + "jest-haste-map": "^26.2.0", + "jest-message-util": "^26.2.0", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.1.0", - "jest-resolve-dependencies": "^26.1.0", - "jest-runner": "^26.1.0", - "jest-runtime": "^26.1.0", - "jest-snapshot": "^26.1.0", - "jest-util": "^26.1.0", - "jest-validate": "^26.1.0", - "jest-watcher": "^26.1.0", + "jest-resolve": "^26.2.0", + "jest-resolve-dependencies": "^26.2.0", + "jest-runner": "^26.2.0", + "jest-runtime": "^26.2.0", + "jest-snapshot": "^26.2.0", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", + "jest-watcher": "^26.2.0", "micromatch": "^4.0.2", "p-each-series": "^2.1.0", "rimraf": "^3.0.0", @@ -1749,51 +1797,53 @@ } }, "@jest/environment": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.1.0.tgz", - "integrity": "sha512-86+DNcGongbX7ai/KE/S3/NcUVZfrwvFzOOWX/W+OOTvTds7j07LtC+MgGydH5c8Ri3uIrvdmVgd1xFD5zt/xA==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.2.0.tgz", + "integrity": "sha512-oCgp9NmEiJ5rbq9VI/v/yYLDpladAAVvFxZgNsnJxOETuzPZ0ZcKKHYjKYwCtPOP1WCrM5nmyuOhMStXFGHn+g==", "dev": true, "requires": { - "@jest/fake-timers": "^26.1.0", - "@jest/types": "^26.1.0", - "jest-mock": "^26.1.0" + "@jest/fake-timers": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "jest-mock": "^26.2.0" } }, "@jest/fake-timers": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.1.0.tgz", - "integrity": "sha512-Y5F3kBVWxhau3TJ825iuWy++BAuQzK/xEa+wD9vDH3RytW9f2DbMVodfUQC54rZDX3POqdxCgcKdgcOL0rYUpA==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.2.0.tgz", + "integrity": "sha512-45Gfe7YzYTKqTayBrEdAF0qYyAsNRBzfkV0IyVUm3cx7AsCWlnjilBM4T40w7IXT5VspOgMPikQlV0M6gHwy/g==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.1.0", - "jest-mock": "^26.1.0", - "jest-util": "^26.1.0" + "@types/node": "*", + "jest-message-util": "^26.2.0", + "jest-mock": "^26.2.0", + "jest-util": "^26.2.0" } }, "@jest/globals": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.1.0.tgz", - "integrity": "sha512-MKiHPNaT+ZoG85oMaYUmGHEqu98y3WO2yeIDJrs2sJqHhYOy3Z6F7F/luzFomRQ8SQ1wEkmahFAz2291Iv8EAw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.2.0.tgz", + "integrity": "sha512-Hoc6ScEIPaym7RNytIL2ILSUWIGKlwEv+JNFof9dGYOdvPjb2evEURSslvCMkNuNg1ECEClTE8PH7ULlMJntYA==", "dev": true, "requires": { - "@jest/environment": "^26.1.0", - "@jest/types": "^26.1.0", - "expect": "^26.1.0" + "@jest/environment": "^26.2.0", + "@jest/types": "^26.2.0", + "expect": "^26.2.0" } }, "@jest/reporters": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.1.0.tgz", - "integrity": "sha512-SVAysur9FOIojJbF4wLP0TybmqwDkdnFxHSPzHMMIYyBtldCW9gG+Q5xWjpMFyErDiwlRuPyMSJSU64A67Pazg==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.2.0.tgz", + "integrity": "sha512-WOzZLmPBXhrAaIYk+koLIhY9IJVgVW22VJKKUAaRIYMyWRnafbKO+32aPDNWpAsVzzsqGKnYpKO1Q3ZIC7TouA==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.1.0", - "@jest/test-result": "^26.1.0", - "@jest/transform": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/console": "^26.2.0", + "@jest/test-result": "^26.2.0", + "@jest/transform": "^26.2.0", + "@jest/types": "^26.2.0", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", @@ -1804,10 +1854,10 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.1.0", - "jest-resolve": "^26.1.0", - "jest-util": "^26.1.0", - "jest-worker": "^26.1.0", + "jest-haste-map": "^26.2.0", + "jest-resolve": "^26.2.0", + "jest-util": "^26.2.0", + "jest-worker": "^26.2.0", "node-notifier": "^7.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", @@ -1894,46 +1944,46 @@ } }, "@jest/test-result": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.1.0.tgz", - "integrity": "sha512-Xz44mhXph93EYMA8aYDz+75mFbarTV/d/x0yMdI3tfSRs/vh4CqSxgzVmCps1fPkHDCtn0tU8IH9iCKgGeGpfw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.2.0.tgz", + "integrity": "sha512-kgPlmcVafpmfyQEu36HClK+CWI6wIaAWDHNxfQtGuKsgoa2uQAYdlxjMDBEa3CvI40+2U3v36gQF6oZBkoKatw==", "dev": true, "requires": { - "@jest/console": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/console": "^26.2.0", + "@jest/types": "^26.2.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.1.0.tgz", - "integrity": "sha512-Z/hcK+rTq56E6sBwMoQhSRDVjqrGtj1y14e2bIgcowARaIE1SgOanwx6gvY4Q9gTKMoZQXbXvptji+q5GYxa6Q==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.2.0.tgz", + "integrity": "sha512-xix2i2B9glWgUliCnm8HApVDw8FWs/WlH4OnGvtIoxrcZLUl4mY9U2NxcGf8NDUC0LMeqW/AtIvtgX2JRRbXUQ==", "dev": true, "requires": { - "@jest/test-result": "^26.1.0", + "@jest/test-result": "^26.2.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.1.0", - "jest-runner": "^26.1.0", - "jest-runtime": "^26.1.0" + "jest-haste-map": "^26.2.0", + "jest-runner": "^26.2.0", + "jest-runtime": "^26.2.0" } }, "@jest/transform": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.1.0.tgz", - "integrity": "sha512-ICPm6sUXmZJieq45ix28k0s+d/z2E8CHDsq+WwtWI6kW8m7I8kPqarSEcUN86entHQ570ZBRci5OWaKL0wlAWw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.2.0.tgz", + "integrity": "sha512-6uh4QiC5ldGKpTCbSGHMgiFA4AzzjFvcZIYPah62gO1PxD7zAzOyjTpKi9S1Qw3p23kwQbb+zRjFBNjCdfvn3g==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", "babel-plugin-istanbul": "^6.0.0", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.1.0", + "jest-haste-map": "^26.2.0", "jest-regex-util": "^26.0.0", - "jest-util": "^26.1.0", + "jest-util": "^26.2.0", "micromatch": "^4.0.2", "pirates": "^4.0.1", "slash": "^3.0.0", @@ -2043,13 +2093,14 @@ } }, "@jest/types": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.1.0.tgz", - "integrity": "sha512-GXigDDsp6ZlNMhXQDeuy/iYCDsRIHJabWtDzvnn36+aqFfG14JmFV0e/iXxY4SP9vbXSiPNOWdehU5MeqrYHBQ==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", + "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -2138,13 +2189,6 @@ "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", "requires": { "mkdirp": "^1.0.4" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - } } }, "@sinonjs/commons": { @@ -2280,10 +2324,9 @@ "dev": true }, "@types/node": { - "version": "14.0.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.26.tgz", - "integrity": "sha512-W+fpe5s91FBGE0pEa0lnqGLL4USgpLgs4nokw16SrBBco/gQxuua7KnArSEOd5iaMqbbSHV10vUDkJYJJqpXKA==", - "dev": true + "version": "14.0.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz", + "integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==" }, "@types/normalize-package-data": { "version": "2.4.0", @@ -2633,9 +2676,9 @@ "dev": true }, "ajv-keywords": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.1.tgz", - "integrity": "sha512-KWcq3xN8fDjSB+IMoh2VaXVhRI0BBGxoYp3rx7Pkb6z0cFjYR9Q9l4yZqqals0/zsioCmocC5H6UvsGD4MoIBA==" + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" }, "alphanum-sort": { "version": "1.0.2", @@ -2954,16 +2997,16 @@ } }, "babel-jest": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.1.0.tgz", - "integrity": "sha512-Nkqgtfe7j6PxLO6TnCQQlkMm8wdTdnIF8xrdpooHCuD5hXRzVEPbPneTJKknH5Dsv3L8ip9unHDAp48YQ54Dkg==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.2.0.tgz", + "integrity": "sha512-yZE9eXX0+3aAAhE/0A7q3PgPBDz9JFLfqtoAqYj0f8trqlB45VTkvBb45TVK9MLimpyY+GBlnLShYLYY60VdCQ==", "dev": true, "requires": { - "@jest/transform": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/transform": "^26.2.0", + "@jest/types": "^26.2.0", "@types/babel__core": "^7.1.7", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.1.0", + "babel-preset-jest": "^26.2.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" @@ -3050,9 +3093,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.1.0.tgz", - "integrity": "sha512-qhqLVkkSlqmC83bdMhM8WW4Z9tB+JkjqAqlbbohS9sJLT5Ha2vfzuKqg5yenXrAjOPG2YC0WiXdH3a9PvB+YYw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.2.0.tgz", + "integrity": "sha512-B/hVMRv8Nh1sQ1a3EY8I0n4Y1Wty3NrR5ebOyVT302op+DOAau+xNEImGMsUWOC3++ZlMooCytKz+NgN8aKGbA==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -3081,12 +3124,12 @@ } }, "babel-preset-jest": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.1.0.tgz", - "integrity": "sha512-na9qCqFksknlEj5iSdw1ehMVR06LCCTkZLGKeEtxDDdhg8xpUF09m29Kvh1pRbZ07h7AQ5ttLYUwpXL4tO6w7w==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.2.0.tgz", + "integrity": "sha512-R1k8kdP3R9phYQugXeNnK/nvCGlBzG4m3EoIIukC80GXb6wCv2XiwPhK6K9MAkQcMszWBYvl2Wm+yigyXFQqXg==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^26.1.0", + "babel-plugin-jest-hoist": "^26.2.0", "babel-preset-current-node-syntax": "^0.1.2" } }, @@ -3346,12 +3389,6 @@ "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true } } }, @@ -3435,47 +3472,6 @@ "ssri": "^8.0.0", "tar": "^6.0.2", "unique-filename": "^1.1.1" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "tar": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz", - "integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==", - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.0", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } } }, "cache-base": { @@ -3553,9 +3549,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001105", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001105.tgz", - "integrity": "sha512-JupOe6+dGMr7E20siZHIZQwYqrllxotAhiaej96y6x00b/48rPt42o+SzOSCPbrpsDWvRja40Hwrj0g0q6LZJg==" + "version": "1.0.30001109", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001109.tgz", + "integrity": "sha512-4JIXRodHzdS3HdK8nSgIqXYLExOvG+D2/EenSvcub2Kp3QEADjo2v2oUn5g0n0D+UNwG9BtwKOyGcSq2qvQXvQ==" }, "capture-exit": { "version": "2.0.0", @@ -4003,6 +3999,15 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -4492,12 +4497,6 @@ "type-fest": "^0.13.1", "yargs-parser": "^18.1.3" } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true } } }, @@ -4999,6 +4998,14 @@ "dev": true, "requires": { "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } } }, "copy-concurrently": { @@ -5015,6 +5022,15 @@ "run-queue": "^1.0.0" }, "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -5032,6 +5048,47 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, + "copy-webpack-plugin": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.0.3.tgz", + "integrity": "sha512-q5m6Vz4elsuyVEIUXr7wJdIdePWTubsqVbEMvf1WQnHGv0Q+9yPRu7MtYFPt+GBOXRav9lvIINifTQ1vSCs+eA==", + "dev": true, + "requires": { + "cacache": "^15.0.4", + "fast-glob": "^3.2.4", + "find-cache-dir": "^3.3.1", + "glob-parent": "^5.1.1", + "globby": "^11.0.1", + "loader-utils": "^2.0.0", + "normalize-path": "^3.0.0", + "p-limit": "^3.0.1", + "schema-utils": "^2.7.0", + "serialize-javascript": "^4.0.0", + "webpack-sources": "^1.4.3" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + } + } + }, "core-js": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", @@ -5158,6 +5215,15 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -5174,14 +5240,11 @@ "which": "^1.2.9" }, "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true } } }, @@ -5244,12 +5307,6 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true } } }, @@ -5587,6 +5644,31 @@ "slash": "^3.0.0" }, "dependencies": { + "globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -5793,6 +5875,15 @@ "path-exists": "^3.0.0" } }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -5800,17 +5891,6 @@ "dev": true, "requires": { "p-limit": "^2.0.0" - }, - "dependencies": { - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - } } }, "path-exists": { @@ -5860,13 +5940,35 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true } } }, "electron-to-chromium": { - "version": "1.3.509", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.509.tgz", - "integrity": "sha512-cN4lkjNRuTG8rtAqTOVgwpecEC2kbKA04PG6YijcKGHK/kD0xLjiqExcAOmLUwtXZRF8cBeam2I0VZcih919Ug==" + "version": "1.3.514", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.514.tgz", + "integrity": "sha512-8vb8zKIeGlZigeDzNWWthmGeLzo5CC43Lc+CZshMs7UXFVMPNLtXJGa/txedpu3OJFrXXVheBwp9PqOJJlHQ8w==" }, "elliptic": { "version": "6.5.3", @@ -5891,6 +5993,12 @@ } } }, + "emittery": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz", + "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", + "dev": true + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -6271,6 +6379,15 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -6309,6 +6426,66 @@ "requires": { "debug": "^2.6.9", "pkg-dir": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } } }, "eslint-plugin-import": { @@ -6608,16 +6785,16 @@ } }, "expect": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.1.0.tgz", - "integrity": "sha512-QbH4LZXDsno9AACrN9eM0zfnby9G+OsdNgZUohjg/P0mLy1O+/bzTAJGT6VSIjVCe8yKM6SzEl/ckEOFBT7Vnw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.2.0.tgz", + "integrity": "sha512-8AMBQ9UVcoUXt0B7v+5/U5H6yiUR87L6eKCfjE3spx7Ya5lF+ebUo37MCFBML2OiLfkX1sxmQOZhIDonyVTkcw==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", "ansi-styles": "^4.0.0", "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.1.0", - "jest-message-util": "^26.1.0", + "jest-matcher-utils": "^26.2.0", + "jest-message-util": "^26.2.0", "jest-regex-util": "^26.0.0" }, "dependencies": { @@ -6910,29 +7087,6 @@ "commondir": "^1.0.1", "make-dir": "^3.0.2", "pkg-dir": "^4.1.0" - }, - "dependencies": { - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } } }, "find-up": { @@ -7119,6 +7273,15 @@ "rimraf": "2" }, "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -7541,12 +7704,6 @@ "type-fest": "^0.13.1", "yargs-parser": "^18.1.3" } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true } } }, @@ -7621,18 +7778,16 @@ "dev": true }, "globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", "dev": true, "requires": { - "@types/glob": "^7.1.1", "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", "slash": "^3.0.0" }, "dependencies": { @@ -7688,12 +7843,12 @@ "dev": true }, "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "dev": true, "requires": { - "ajv": "^6.5.5", + "ajv": "^6.12.3", "har-schema": "^2.0.0" } }, @@ -7789,12 +7944,6 @@ "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true } } }, @@ -7986,15 +8135,6 @@ "lines-and-columns": "^1.1.6" } }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -8071,17 +8211,6 @@ "requires": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" - }, - "dependencies": { - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - } } }, "imurmurhash": { @@ -8501,14 +8630,6 @@ "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.0.0", "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } } }, "istanbul-lib-report": { @@ -8528,21 +8649,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -8593,14 +8699,14 @@ } }, "jest": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.1.0.tgz", - "integrity": "sha512-LIti8jppw5BcQvmNJe4w2g1N/3V68HUfAv9zDVm7v+VAtQulGhH0LnmmiVkbNE4M4I43Bj2fXPiBGKt26k9tHw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.2.0.tgz", + "integrity": "sha512-597+hFlPBbSB34J4JsCViC+oHB+Ez8dKhWs7kLiTmFcVf1WaGGLY2POYMcAKtuC0b51qmWyU1/0czmS/jT1Gfg==", "dev": true, "requires": { - "@jest/core": "^26.1.0", + "@jest/core": "^26.2.0", "import-local": "^3.0.2", - "jest-cli": "^26.1.0" + "jest-cli": "^26.2.0" }, "dependencies": { "ansi-styles": { @@ -8645,22 +8751,22 @@ "dev": true }, "jest-cli": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.1.0.tgz", - "integrity": "sha512-Imumvjgi3rU7stq6SJ1JUEMaV5aAgJYXIs0jPqdUnF47N/Tk83EXfmtvNKQ+SnFVI6t6mDOvfM3aA9Sg6kQPSw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.2.0.tgz", + "integrity": "sha512-hcFTvnj1a6L4i+59rMlQggFIV0QVsUzYQRNzB+mFvulCjOkSfgsKKSkab55kmVSqVFIjMF0WF7YSDsnBe0gTtg==", "dev": true, "requires": { - "@jest/core": "^26.1.0", - "@jest/test-result": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/core": "^26.2.0", + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", "is-ci": "^2.0.0", - "jest-config": "^26.1.0", - "jest-util": "^26.1.0", - "jest-validate": "^26.1.0", + "jest-config": "^26.2.0", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", "prompts": "^2.0.1", "yargs": "^15.3.1" } @@ -8677,12 +8783,12 @@ } }, "jest-changed-files": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.1.0.tgz", - "integrity": "sha512-HS5MIJp3B8t0NRKGMCZkcDUZo36mVRvrDETl81aqljT1S9tqiHRSpyoOvWg9ZilzZG9TDisDNaN1IXm54fLRZw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.2.0.tgz", + "integrity": "sha512-+RyJb+F1K/XBLIYiL449vo5D+CvlHv29QveJUWNPXuUicyZcq+tf1wNxmmFeRvAU1+TzhwqczSjxnCCFt7+8iA==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", "execa": "^4.0.0", "throat": "^5.0.0" }, @@ -8759,33 +8865,42 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, "jest-config": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.1.0.tgz", - "integrity": "sha512-ONTGeoMbAwGCdq4WuKkMcdMoyfs5CLzHEkzFOlVvcDXufZSaIWh/OXMLa2fwKXiOaFcqEw8qFr4VOKJQfn4CVw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.2.0.tgz", + "integrity": "sha512-pYrenhZJLqkzb/3vHLOo4c0ojuYuWTun2Sbmg8PG9X067XER0pYSk7gifQjuSJO//UWjUkZrRnJDahkPswP3Bg==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.1.0", - "@jest/types": "^26.1.0", - "babel-jest": "^26.1.0", + "@jest/test-sequencer": "^26.2.0", + "@jest/types": "^26.2.0", + "babel-jest": "^26.2.0", "chalk": "^4.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.1.0", - "jest-environment-node": "^26.1.0", + "jest-environment-jsdom": "^26.2.0", + "jest-environment-node": "^26.2.0", "jest-get-type": "^26.0.0", - "jest-jasmine2": "^26.1.0", + "jest-jasmine2": "^26.2.0", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.1.0", - "jest-util": "^26.1.0", - "jest-validate": "^26.1.0", + "jest-resolve": "^26.2.0", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", "micromatch": "^4.0.2", - "pretty-format": "^26.1.0" + "pretty-format": "^26.2.0" }, "dependencies": { "ansi-styles": { @@ -8884,15 +8999,15 @@ } }, "jest-diff": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.1.0.tgz", - "integrity": "sha512-GZpIcom339y0OXznsEKjtkfKxNdg7bVbEofK8Q6MnevTIiR1jNhDWKhRX6X0SDXJlwn3dy59nZ1z55fLkAqPWg==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.2.0.tgz", + "integrity": "sha512-Wu4Aopi2nzCsHWLBlD48TgRy3Z7OsxlwvHNd1YSnHc7q1NJfrmyCPoUXrTIrydQOG5ApaYpsAsdfnMbJqV1/wQ==", "dev": true, "requires": { "chalk": "^4.0.0", "diff-sequences": "^26.0.0", "jest-get-type": "^26.0.0", - "pretty-format": "^26.1.0" + "pretty-format": "^26.2.0" }, "dependencies": { "ansi-styles": { @@ -8957,16 +9072,16 @@ } }, "jest-each": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.1.0.tgz", - "integrity": "sha512-lYiSo4Igr81q6QRsVQq9LIkJW0hZcKxkIkHzNeTMPENYYDw/W/Raq28iJ0sLlNFYz2qxxeLnc5K2gQoFYlu2bA==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.2.0.tgz", + "integrity": "sha512-gHPCaho1twWHB5bpcfnozlc6mrMi+VAewVPNgmwf81x2Gzr6XO4dl+eOrwPWxbkYlgjgrYjWK2xgKnixbzH3Ew==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", "chalk": "^4.0.0", "jest-get-type": "^26.0.0", - "jest-util": "^26.1.0", - "pretty-format": "^26.1.0" + "jest-util": "^26.2.0", + "pretty-format": "^26.2.0" }, "dependencies": { "ansi-styles": { @@ -9022,30 +9137,32 @@ } }, "jest-environment-jsdom": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.1.0.tgz", - "integrity": "sha512-dWfiJ+spunVAwzXbdVqPH1LbuJW/kDL+FyqgA5YzquisHqTi0g9hquKif9xKm7c1bKBj6wbmJuDkeMCnxZEpUw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.2.0.tgz", + "integrity": "sha512-sDG24+5M4NuIGzkI3rJW8XUlrpkvIdE9Zz4jhD8OBnVxAw+Y1jUk9X+lAOD48nlfUTlnt3lbAI3k2Ox+WF3S0g==", "dev": true, "requires": { - "@jest/environment": "^26.1.0", - "@jest/fake-timers": "^26.1.0", - "@jest/types": "^26.1.0", - "jest-mock": "^26.1.0", - "jest-util": "^26.1.0", + "@jest/environment": "^26.2.0", + "@jest/fake-timers": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "jest-mock": "^26.2.0", + "jest-util": "^26.2.0", "jsdom": "^16.2.2" } }, "jest-environment-node": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.1.0.tgz", - "integrity": "sha512-DNm5x1aQH0iRAe9UYAkZenuzuJ69VKzDCAYISFHQ5i9e+2Tbeu2ONGY7YStubCLH8a1wdKBgqScYw85+ySxqxg==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.2.0.tgz", + "integrity": "sha512-4M5ExTYkJ19efBzkiXtBi74JqKLDciEk4CEsp5tTjWGYMrlKFQFtwIVG3tW1OGE0AlXhZjuHPwubuRYY4j4uOw==", "dev": true, "requires": { - "@jest/environment": "^26.1.0", - "@jest/fake-timers": "^26.1.0", - "@jest/types": "^26.1.0", - "jest-mock": "^26.1.0", - "jest-util": "^26.1.0" + "@jest/environment": "^26.2.0", + "@jest/fake-timers": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "jest-mock": "^26.2.0", + "jest-util": "^26.2.0" } }, "jest-get-type": { @@ -9055,24 +9172,25 @@ "dev": true }, "jest-haste-map": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.1.0.tgz", - "integrity": "sha512-WeBS54xCIz9twzkEdm6+vJBXgRBQfdbbXD0dk8lJh7gLihopABlJmIQFdWSDDtuDe4PRiObsjZSUjbJ1uhWEpA==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.2.0.tgz", + "integrity": "sha512-NRAjpP8Fq/idLWGmIpyMMjpfzFOhJVhIdaxDuiZxAdL9JcJNUcSol23fOZ3gVbth5NlJqLvx46x0MNDeFjSZQw==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", "@types/graceful-fs": "^4.1.2", + "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", - "jest-serializer": "^26.1.0", - "jest-util": "^26.1.0", - "jest-worker": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.2.0", + "jest-util": "^26.2.0", + "jest-worker": "^26.2.0", "micromatch": "^4.0.2", "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" + "walker": "^1.0.7" }, "dependencies": { "anymatch": { @@ -9138,27 +9256,28 @@ } }, "jest-jasmine2": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.1.0.tgz", - "integrity": "sha512-1IPtoDKOAG+MeBrKvvuxxGPJb35MTTRSDglNdWWCndCB3TIVzbLThRBkwH9P081vXLgiJHZY8Bz3yzFS803xqQ==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.2.0.tgz", + "integrity": "sha512-JAzgeAVNhsuLyVh+3yS0Ep8iwpBrCL/5wC/YrGcGu4B3U1WUMjgvyXOar/TRjS8gTl8Qw98MeQfv9zT8tBmd+A==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.1.0", + "@jest/environment": "^26.2.0", "@jest/source-map": "^26.1.0", - "@jest/test-result": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^26.1.0", + "expect": "^26.2.0", "is-generator-fn": "^2.0.0", - "jest-each": "^26.1.0", - "jest-matcher-utils": "^26.1.0", - "jest-message-util": "^26.1.0", - "jest-runtime": "^26.1.0", - "jest-snapshot": "^26.1.0", - "jest-util": "^26.1.0", - "pretty-format": "^26.1.0", + "jest-each": "^26.2.0", + "jest-matcher-utils": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-runtime": "^26.2.0", + "jest-snapshot": "^26.2.0", + "jest-util": "^26.2.0", + "pretty-format": "^26.2.0", "throat": "^5.0.0" }, "dependencies": { @@ -9215,9 +9334,9 @@ } }, "jest-junit": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-11.0.1.tgz", - "integrity": "sha512-stgc0mBoiSg/F9qWd4KkmR3K7Nk2u+M/dc1oup7gxz9mrzGcEaU2YL9/0QscVqqg3IOaA1P5ZXtozG/XR6j6nw==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-11.1.0.tgz", + "integrity": "sha512-c2LFOyKY7+ZxL5zSu+WHmHfsJ2wqbOpeYJ4Uu26yMhFxny2J2NQj6AVS7M+Eaxji9Q/oIDDK5tQy0DGzDp9xOw==", "dev": true, "requires": { "mkdirp": "^1.0.4", @@ -9232,12 +9351,6 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -9256,25 +9369,25 @@ } }, "jest-leak-detector": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.1.0.tgz", - "integrity": "sha512-dsMnKF+4BVOZwvQDlgn3MG+Ns4JuLv8jNvXH56bgqrrboyCbI1rQg6EI5rs+8IYagVcfVP2yZFKfWNZy0rK0Hw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.2.0.tgz", + "integrity": "sha512-aQdzTX1YiufkXA1teXZu5xXOJgy7wZQw6OJ0iH5CtQlOETe6gTSocaYKUNui1SzQ91xmqEUZ/WRavg9FD82rtQ==", "dev": true, "requires": { "jest-get-type": "^26.0.0", - "pretty-format": "^26.1.0" + "pretty-format": "^26.2.0" } }, "jest-matcher-utils": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.1.0.tgz", - "integrity": "sha512-PW9JtItbYvES/xLn5mYxjMd+Rk+/kIt88EfH3N7w9KeOrHWaHrdYPnVHndGbsFGRJ2d5gKtwggCvkqbFDoouQA==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.2.0.tgz", + "integrity": "sha512-2cf/LW2VFb3ayPHrH36ZDjp9+CAeAe/pWBAwsV8t3dKcrINzXPVxq8qMWOxwt5BaeBCx4ZupVGH7VIgB8v66vQ==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.1.0", + "jest-diff": "^26.2.0", "jest-get-type": "^26.0.0", - "pretty-format": "^26.1.0" + "pretty-format": "^26.2.0" }, "dependencies": { "ansi-styles": { @@ -9330,13 +9443,13 @@ } }, "jest-message-util": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.1.0.tgz", - "integrity": "sha512-dY0+UlldiAJwNDJ08SF0HdF32g9PkbF2NRK/+2iMPU40O6q+iSn1lgog/u0UH8ksWoPv0+gNq8cjhYO2MFtT0g==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.2.0.tgz", + "integrity": "sha512-g362RhZaJuqeqG108n1sthz5vNpzTNy926eNDszo4ncRbmmcMRIUAZibnd6s5v2XSBCChAxQtCoN25gnzp7JbQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", "@types/stack-utils": "^1.0.1", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -9447,12 +9560,13 @@ } }, "jest-mock": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.1.0.tgz", - "integrity": "sha512-1Rm8EIJ3ZFA8yCIie92UbxZWj9SuVmUGcyhLHyAhY6WI3NIct38nVcfOPWhJteqSn8V8e3xOMha9Ojfazfpovw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.2.0.tgz", + "integrity": "sha512-XeC7yWtWmWByoyVOHSsE7NYsbXJLtJNgmhD7z4MKumKm6ET0si81bsSLbQ64L5saK3TgsHo2B/UqG5KNZ1Sp/Q==", "dev": true, "requires": { - "@jest/types": "^26.1.0" + "@jest/types": "^26.2.0", + "@types/node": "*" } }, "jest-pnp-resolver": { @@ -9468,16 +9582,16 @@ "dev": true }, "jest-resolve": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.1.0.tgz", - "integrity": "sha512-KsY1JV9FeVgEmwIISbZZN83RNGJ1CC+XUCikf/ZWJBX/tO4a4NvA21YixokhdR9UnmPKKAC4LafVixJBrwlmfg==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.2.0.tgz", + "integrity": "sha512-8X+pHe7MepZG9D2R4VGvkqVL7S1KuWmIQVkQD7X+wAoTGfchJxADF08VAaQQpSgsoJLKglF5rkkwZRxuhhUYfA==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.1.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.2.0", "read-pkg-up": "^7.0.1", "resolve": "^1.17.0", "slash": "^3.0.0" @@ -9542,39 +9656,40 @@ } }, "jest-resolve-dependencies": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.1.0.tgz", - "integrity": "sha512-fQVEPHHQ1JjHRDxzlLU/buuQ9om+hqW6Vo928aa4b4yvq4ZHBtRSDsLdKQLuCqn5CkTVpYZ7ARh2fbA8WkRE6g==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.2.0.tgz", + "integrity": "sha512-aOLJo+RzlmvNZE0QUySMxKPtHa4+2tHluq92TvXgL9ZHYcPui2C8RKy6ApGrtNsIjk96MoADigNn57SYKEoNyw==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.1.0" + "jest-snapshot": "^26.2.0" } }, "jest-runner": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.1.0.tgz", - "integrity": "sha512-elvP7y0fVDREnfqit0zAxiXkDRSw6dgCkzPCf1XvIMnSDZ8yogmSKJf192dpOgnUVykmQXwYYJnCx641uLTgcw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.2.0.tgz", + "integrity": "sha512-OtX7vV6OjcQ+JLEpPiHmkfeIHXeHfV9LOLDRFanup82n0QbHmU5bK6smtvvNoMYL1ZSzmhagyDiG8Lzx2ZK+bA==", "dev": true, "requires": { - "@jest/console": "^26.1.0", - "@jest/environment": "^26.1.0", - "@jest/test-result": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/console": "^26.2.0", + "@jest/environment": "^26.2.0", + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", "chalk": "^4.0.0", + "emittery": "^0.7.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-config": "^26.1.0", + "jest-config": "^26.2.0", "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.1.0", - "jest-jasmine2": "^26.1.0", - "jest-leak-detector": "^26.1.0", - "jest-message-util": "^26.1.0", - "jest-resolve": "^26.1.0", - "jest-runtime": "^26.1.0", - "jest-util": "^26.1.0", - "jest-worker": "^26.1.0", + "jest-haste-map": "^26.2.0", + "jest-leak-detector": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-resolve": "^26.2.0", + "jest-runtime": "^26.2.0", + "jest-util": "^26.2.0", + "jest-worker": "^26.2.0", "source-map-support": "^0.5.6", "throat": "^5.0.0" }, @@ -9632,34 +9747,34 @@ } }, "jest-runtime": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.1.0.tgz", - "integrity": "sha512-1qiYN+EZLmG1QV2wdEBRf+Ci8i3VSfIYLF02U18PiUDrMbhfpN/EAMMkJtT02jgJUoaEOpHAIXG6zS3QRMzRmA==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.2.0.tgz", + "integrity": "sha512-PwTpmtxnUQU1k+nNlj/sbUtkH4NX5i+Rts/fMz1zBSW0OB8D/tx5nvabFiqQYEKP0Pn7tmyDLmXuueQz4V6qtQ==", "dev": true, "requires": { - "@jest/console": "^26.1.0", - "@jest/environment": "^26.1.0", - "@jest/fake-timers": "^26.1.0", - "@jest/globals": "^26.1.0", + "@jest/console": "^26.2.0", + "@jest/environment": "^26.2.0", + "@jest/fake-timers": "^26.2.0", + "@jest/globals": "^26.2.0", "@jest/source-map": "^26.1.0", - "@jest/test-result": "^26.1.0", - "@jest/transform": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/test-result": "^26.2.0", + "@jest/transform": "^26.2.0", + "@jest/types": "^26.2.0", "@types/yargs": "^15.0.0", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-config": "^26.1.0", - "jest-haste-map": "^26.1.0", - "jest-message-util": "^26.1.0", - "jest-mock": "^26.1.0", + "jest-config": "^26.2.0", + "jest-haste-map": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-mock": "^26.2.0", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.1.0", - "jest-snapshot": "^26.1.0", - "jest-util": "^26.1.0", - "jest-validate": "^26.1.0", + "jest-resolve": "^26.2.0", + "jest-snapshot": "^26.2.0", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^15.3.1" @@ -9730,34 +9845,35 @@ } }, "jest-serializer": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.1.0.tgz", - "integrity": "sha512-eqZOQG/0+MHmr25b2Z86g7+Kzd5dG9dhCiUoyUNJPgiqi38DqbDEOlHcNijyfZoj74soGBohKBZuJFS18YTJ5w==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.2.0.tgz", + "integrity": "sha512-V7snZI9IVmyJEu0Qy0inmuXgnMWDtrsbV2p9CRAcmlmPVwpC2ZM8wXyYpiugDQnwLHx0V4+Pnog9Exb3UO8M6Q==", "dev": true, "requires": { + "@types/node": "*", "graceful-fs": "^4.2.4" } }, "jest-snapshot": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.1.0.tgz", - "integrity": "sha512-YhSbU7eMTVQO/iRbNs8j0mKRxGp4plo7sJ3GzOQ0IYjvsBiwg0T1o0zGQAYepza7lYHuPTrG5J2yDd0CE2YxSw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.2.0.tgz", + "integrity": "sha512-VREFCukUjvSOSiwS9JIuwVwBjv0gBFT2Mwr2Yl8w7P6PLQ7T/Qkhh1BE5VUT5l/KBMaUKyKlnM1lozEL3H80pQ==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.1.0", + "expect": "^26.2.0", "graceful-fs": "^4.2.4", - "jest-diff": "^26.1.0", + "jest-diff": "^26.2.0", "jest-get-type": "^26.0.0", - "jest-haste-map": "^26.1.0", - "jest-matcher-utils": "^26.1.0", - "jest-message-util": "^26.1.0", - "jest-resolve": "^26.1.0", + "jest-haste-map": "^26.2.0", + "jest-matcher-utils": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-resolve": "^26.2.0", "natural-compare": "^1.4.0", - "pretty-format": "^26.1.0", + "pretty-format": "^26.2.0", "semver": "^7.3.2" }, "dependencies": { @@ -9820,12 +9936,13 @@ } }, "jest-util": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.1.0.tgz", - "integrity": "sha512-rNMOwFQevljfNGvbzNQAxdmXQ+NawW/J72dmddsK0E8vgxXCMtwQ/EH0BiWEIxh0hhMcTsxwAxINt7Lh46Uzbg==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.2.0.tgz", + "integrity": "sha512-YmDwJxLZ1kFxpxPfhSJ0rIkiZOM0PQbRcfH0TzJOhqCisCAsI1WcmoQqO83My9xeVA2k4n+rzg2UuexVKzPpig==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", @@ -9928,17 +10045,17 @@ } }, "jest-validate": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.1.0.tgz", - "integrity": "sha512-WPApOOnXsiwhZtmkDsxnpye+XLb/tUISP+H6cHjfUIXvlG+eKwP+isnivsxlHCPaO9Q5wvbhloIBkdF3qUn+Nw==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.2.0.tgz", + "integrity": "sha512-8XKn3hM6VIVmLNuyzYLCPsRCT83o8jMZYhbieh4dAyKLc4Ypr36rVKC+c8WMpWkfHHpGnEkvWUjjIAyobEIY/Q==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", "camelcase": "^6.0.0", "chalk": "^4.0.0", "jest-get-type": "^26.0.0", "leven": "^3.1.0", - "pretty-format": "^26.1.0" + "pretty-format": "^26.2.0" }, "dependencies": { "ansi-styles": { @@ -9994,16 +10111,17 @@ } }, "jest-watcher": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.1.0.tgz", - "integrity": "sha512-ffEOhJl2EvAIki613oPsSG11usqnGUzIiK7MMX6hE4422aXOcVEG3ySCTDFLn1+LZNXGPE8tuJxhp8OBJ1pgzQ==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.2.0.tgz", + "integrity": "sha512-674Boco4Joe0CzgKPL6K4Z9LgyLx+ZvW2GilbpYb8rFEUkmDGgsZdv1Hv5rxsRpb1HLgKUOL/JfbttRCuFdZXQ==", "dev": true, "requires": { - "@jest/test-result": "^26.1.0", - "@jest/types": "^26.1.0", + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.1.0", + "jest-util": "^26.2.0", "string-length": "^4.0.1" }, "dependencies": { @@ -10060,10 +10178,11 @@ } }, "jest-worker": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.1.0.tgz", - "integrity": "sha512-Z9P5pZ6UC+kakMbNJn+tA2RdVdNX5WH1x+5UCBZ9MxIK24pjYtFt96fK+UwBTrjLYm232g1xz0L3eTh51OW+yQ==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.2.0.tgz", + "integrity": "sha512-c5IzzcepylKWHBQYq6ASy96n1wSEjruid8H2eo5kWyXjJgAxxPU7bVeG9/kXqyD6lcT5R/iSW59pbeDChbCULw==", "requires": { + "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^7.0.0" }, @@ -10530,6 +10649,15 @@ "requires": { "is-number": "^7.0.0" } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -10540,18 +10668,18 @@ "dev": true }, "listr2": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-2.3.3.tgz", - "integrity": "sha512-vU2eiFEzUEaDjgwRJ/n8RB79K2cBcaTw1DigIGHnXGp/BEeQqxGwiM8R17Itit5l2ykrrST11kw2l9vSpCbqUQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-2.4.1.tgz", + "integrity": "sha512-8pYsCZCztr5+KAjReLyBeGhLV0vaQ2Du/eMe/ux9QAfQl7efiWejM1IWjALh0zHIRYuIbhQ8N2KztZ4ci56pnQ==", "dev": true, "requires": { - "chalk": "^4.0.0", + "chalk": "^4.1.0", "cli-truncate": "^2.1.0", "figures": "^3.2.0", "indent-string": "^4.0.0", "log-update": "^4.0.0", "p-map": "^4.0.0", - "rxjs": "^6.5.5", + "rxjs": "^6.6.0", "through": "^2.3.8" }, "dependencies": { @@ -10596,15 +10724,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -10868,23 +10987,19 @@ } }, "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "yallist": "^4.0.0" } }, "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "semver": "^6.0.0" } }, "makeerror": { @@ -11308,13 +11423,6 @@ "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", "requires": { "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } } }, "minipass-collect": { @@ -11334,9 +11442,9 @@ } }, "minipass-pipeline": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.3.tgz", - "integrity": "sha512-cFOknTvng5vqnwOpDsZTWhNll6Jf8o2x+/diplafmxpuIymAjzoOolZG0VvQf3V2HgqzJNhnuKHYp2BqDgz8IQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "requires": { "minipass": "^3.0.0" } @@ -11348,13 +11456,6 @@ "requires": { "minipass": "^3.0.0", "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } } }, "mississippi": { @@ -11421,12 +11522,9 @@ } }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "modify-values": { "version": "1.0.1", @@ -11448,6 +11546,15 @@ "run-queue": "^1.0.3" }, "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -11515,6 +11622,15 @@ "path-exists": "^3.0.0" } }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -11522,17 +11638,6 @@ "dev": true, "requires": { "p-limit": "^2.0.0" - }, - "dependencies": { - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - } } }, "path-exists": { @@ -11540,6 +11645,12 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true } } }, @@ -11612,6 +11723,15 @@ "which": "1" }, "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -11627,13 +11747,15 @@ "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { - "isexe": "^2.0.0" + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" } } } @@ -11710,6 +11832,16 @@ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true, "optional": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "optional": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -11826,6 +11958,16 @@ "strip-bom": "^2.0.0" } }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", @@ -11850,6 +11992,15 @@ "trim-newlines": "^1.0.0" } }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -11946,14 +12097,11 @@ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "dev": true }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true } } }, @@ -11976,6 +12124,14 @@ "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, "normalize-path": { @@ -12287,10 +12443,9 @@ } }, "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "requires": { "aggregate-error": "^3.0.0" } @@ -12513,63 +12668,11 @@ } }, "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "requires": { - "find-up": "^2.1.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } + "find-up": "^4.0.0" } }, "please-upgrade-node": { @@ -13089,12 +13192,12 @@ "dev": true }, "pretty-format": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.1.0.tgz", - "integrity": "sha512-GmeO1PEYdM+non4BKCj+XsPJjFOJIPnsLewqhDVoqY1xo0yNmDas7tC2XwpMrRAHR3MaE2hPo37deX5OisJ2Wg==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.2.0.tgz", + "integrity": "sha512-qi/8IuBu2clY9G7qCXgCdD1Bf9w+sXakdHTRToknzMtVy0g7c4MBWaZy7MfB7ndKZovRO6XRwJiAYqq+MC7SDA==", "dev": true, "requires": { - "@jest/types": "^26.1.0", + "@jest/types": "^26.2.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -13400,6 +13503,14 @@ "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } } }, "readdirp": { @@ -13778,9 +13889,9 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safe-regex": { "version": "1.1.0", @@ -13868,6 +13979,15 @@ "path-exists": "^3.0.0" } }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -13875,17 +13995,6 @@ "dev": true, "requires": { "p-limit": "^2.0.0" - }, - "dependencies": { - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - } } }, "path-exists": { @@ -14022,10 +14131,9 @@ } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "semver-compare": { "version": "1.0.0", @@ -14694,6 +14802,14 @@ "dev": true, "requires": { "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } } }, "stringify-object": { @@ -14838,6 +14954,16 @@ "stable": "^0.1.8", "unquote": "~1.1.1", "util.promisify": "~1.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + } } }, "symbol-tree": { @@ -14865,14 +14991,16 @@ "dev": true }, "tar": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", - "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", - "dev": true, + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz", + "integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==", "requires": { - "block-stream": "*", - "fstream": "^1.0.12", - "inherits": "2" + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.0", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" } }, "terminal-link": { @@ -14995,6 +15123,25 @@ "yallist": "^3.0.2" } }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -15048,6 +15195,12 @@ "ajv-keywords": "^3.1.0" } }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, "serialize-javascript": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", @@ -15533,9 +15686,9 @@ } }, "uuid": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz", - "integrity": "sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", "dev": true, "optional": true }, @@ -15763,9 +15916,9 @@ "dev": true }, "webpack": { - "version": "4.44.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.0.tgz", - "integrity": "sha512-wAuJxK123sqAw31SpkPiPW3iKHgFUiKvO7E7UZjtdExcsRe3fgav4mvoMM7vvpjLHVoJ6a0Mtp2fzkoA13e0Zw==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz", + "integrity": "sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ==", "dev": true, "requires": { "@webassemblyjs/ast": "1.9.0", @@ -15809,6 +15962,15 @@ "estraverse": "^4.1.1" } }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", @@ -15875,9 +16037,9 @@ } }, "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -16040,6 +16202,17 @@ "dev": true, "requires": { "mkdirp": "^0.5.1" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + } } }, "write-file-atomic": { @@ -16091,10 +16264,9 @@ "dev": true }, "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yaml": { "version": "1.10.0", diff --git a/package.json b/package.json index 3b1ac92..0e2e0dc 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "cacache": "^15.0.5", "cssnano": "^4.1.10", "find-cache-dir": "^3.3.1", - "jest-worker": "^26.1.0", + "jest-worker": "^26.2.0", "p-limit": "^3.0.2", "schema-utils": "^2.7.0", "serialize-javascript": "^4.0.0", @@ -59,8 +59,9 @@ "@commitlint/config-conventional": "^9.1.1", "@webpack-contrib/defaults": "^6.3.0", "@webpack-contrib/eslint-config-webpack": "^3.0.0", - "babel-jest": "^26.1.0", + "babel-jest": "^26.2.0", "commitlint-azure-pipelines-cli": "^1.0.3", + "copy-webpack-plugin": "^6.0.3", "cross-env": "^7.0.2", "css-loader": "^3.6.0", "del": "^5.1.0", @@ -69,17 +70,18 @@ "eslint-config-prettier": "^6.11.0", "eslint-plugin-import": "^2.22.0", "husky": "^4.2.5", - "jest": "^26.1.0", + "jest": "^26.2.0", "jest-junit": "^11.0.1", "lint-staged": "^10.2.11", "memfs": "^3.2.0", "mini-css-extract-plugin": "^0.9.0", "node-sass": "^4.14.1", "npm-run-all": "^4.1.5", + "postcss": "^7.0.32", "prettier": "^2.0.5", "sass-loader": "^9.0.2", "standard-version": "^8.0.2", - "webpack": "^4.44.0" + "webpack": "^4.44.1" }, "keywords": [ "cssnano", diff --git a/src/index.js b/src/index.js index 139cf21..928df40 100644 --- a/src/index.js +++ b/src/index.js @@ -41,6 +41,7 @@ class CssnanoPlugin { parallel = true, include, exclude, + minify, } = options; this.options = { @@ -53,6 +54,7 @@ class CssnanoPlugin { parallel, include, exclude, + minify, }; if (this.options.sourceMap === true) { @@ -86,7 +88,7 @@ class CssnanoPlugin { sourceMap && sourceMap.originalPositionFor({ line: error.line, - column: error.col, + column: error.column, }); if (original && original.source && requestShortener) { @@ -95,7 +97,7 @@ class CssnanoPlugin { error.message } [${requestShortener.shorten(original.source)}:${original.line},${ original.column - }][${file}:${error.line},${error.col}]${ + }][${file}:${error.line},${error.column}]${ error.stack ? `\n${error.stack.split('\n').slice(1).join('\n')}` : '' @@ -106,7 +108,7 @@ class CssnanoPlugin { return new Error( `${file} from Cssnano Webpack Plugin\n${error.message} [${file}:${ error.line - },${error.col}]${ + },${error.column}]${ error.stack ? `\n${error.stack.split('\n').slice(1).join('\n')}` : '' }` ); @@ -273,19 +275,13 @@ class CssnanoPlugin { const postcssOptions = { to: file, from: file, map: false }; - if (inputSourceMap) { - postcssOptions.map = Object.assign( - { prev: inputSourceMap }, - this.options.sourceMap - ); - } - const task = { - file, input, inputSourceMap, postcssOptions, + map: this.options.sourceMap, cssnanoOptions: this.options.cssnanoOptions, + minify: this.options.minify, callback, }; @@ -377,7 +373,7 @@ class CssnanoPlugin { if (worker) { taskResult = await worker.transform(serialize(task)); } else { - taskResult = minifyFn(task); + taskResult = await minifyFn(task); } } catch (error) { taskResult = { error }; @@ -452,23 +448,9 @@ class CssnanoPlugin { ); const optimizeFn = async (compilation, chunksOrAssets) => { - let assetNames; - - if (CssnanoPlugin.isWebpack4()) { - assetNames = [] - .concat(Array.from(compilation.additionalChunkAssets || [])) - .concat( - Array.from(chunksOrAssets).reduce( - (acc, chunk) => acc.concat(Array.from(chunk.files || [])), - [] - ) - ) - .filter((file) => matchObject(file)); - } else { - assetNames = [] - .concat(Object.keys(chunksOrAssets)) - .filter((file) => matchObject(file)); - } + const assetNames = Object.keys( + CssnanoPlugin.isWebpack4() ? compilation.assets : chunksOrAssets + ).filter((file) => matchObject(file)); if (assetNames.length === 0) { return Promise.resolve(); @@ -545,4 +527,4 @@ class CssnanoPlugin { } } -module.exports = CssnanoPlugin; +export default CssnanoPlugin; diff --git a/src/minify.js b/src/minify.js index c09f6a0..9cafb58 100644 --- a/src/minify.js +++ b/src/minify.js @@ -1,12 +1,34 @@ const cssnano = require('cssnano'); -const minify = (options) => { - const { input, postcssOptions, cssnanoOptions } = options; +const minify = async (options) => { + const { + input, + postcssOptions, + cssnanoOptions, + map, + inputSourceMap, + minify: minifyFn, + } = options; - return cssnano.process(input, postcssOptions, cssnanoOptions); + if (minifyFn) { + return minifyFn({ input, postcssOptions, cssnanoOptions }, inputSourceMap); + } + + if (inputSourceMap) { + postcssOptions.map = { prev: inputSourceMap, ...map }; + } + + const result = await cssnano.process(input, postcssOptions, cssnanoOptions); + + return { + css: result.css, + map: result.map, + error: result.error, + warnings: result.warnings(), + }; }; -function transform(options) { +async function transform(options) { // 'use strict' => this === undefined (Clean Scope) // Safer for possible security issues, albeit not critical at all here // eslint-disable-next-line no-new-func, no-param-reassign @@ -19,13 +41,9 @@ function transform(options) { `'use strict'\nreturn ${options}` )(exports, require, module, __filename, __dirname); - const result = minify(options); + const result = await minify(options); - if (result.error) { - throw result.error; - } else { - return result; - } + return result; } module.exports.minify = minify; diff --git a/src/options.json b/src/options.json index d55c583..7216f60 100644 --- a/src/options.json +++ b/src/options.json @@ -107,6 +107,10 @@ "warningsFilter": { "description": "Allow to filter `cssnano` warnings.", "instanceof": "Function" + }, + "minify": { + "description": "Allows you to override default minify function.", + "instanceof": "Function" } }, "additionalProperties": false diff --git a/test/CssNano.test.js b/test/CssNano.test.js deleted file mode 100644 index 014fea5..0000000 --- a/test/CssNano.test.js +++ /dev/null @@ -1,55 +0,0 @@ -import MiniCssExtractPlugin from 'mini-css-extract-plugin'; - -import CssnanoPlugin from '../src/index'; - -import { createCompiler, compile } from './compiler'; - -import { readAsset, normalizedSourceMap, removeCache } from './helpers'; - -describe('CssnanoPlugin', () => { - jest.setTimeout(30000); - - beforeEach(() => Promise.all([removeCache()])); - - afterEach(() => Promise.all([removeCache()])); - - it('should work with assets using querystring', () => { - const config = { - devtool: 'source-map', - entry: { - entry: `${__dirname}/fixtures/foo.css`, - }, - plugins: [ - new MiniCssExtractPlugin({ - filename: '[name].css?v=test', - chunkFilename: '[id].[name].css?v=test', - }), - ], - }; - - const compiler = createCompiler(config); - new CssnanoPlugin({ - sourceMap: true, - }).apply(compiler); - - return compile(compiler).then((stats) => { - expect(stats.compilation.errors).toEqual([]); - expect(stats.compilation.warnings).toEqual([]); - - // eslint-disable-next-line guard-for-in - for (const file in stats.compilation.assets) { - // eslint-disable-next-line no-continue - - if (/\.css\?/.test(file)) { - expect(readAsset(file, compiler, stats)).toMatchSnapshot(file); - } - - // eslint-disable-next-line no-continue - if (!/\.css.map/.test(file)) continue; - expect( - normalizedSourceMap(readAsset(file, compiler, stats)) - ).toMatchSnapshot(file); - } - }); - }); -}); diff --git a/test/CssnanoPlugin.test.js b/test/CssnanoPlugin.test.js new file mode 100644 index 0000000..5891394 --- /dev/null +++ b/test/CssnanoPlugin.test.js @@ -0,0 +1,344 @@ +import path from 'path'; + +import postcss from 'postcss'; +import MiniCssExtractPlugin from 'mini-css-extract-plugin'; +import CopyPlugin from 'copy-webpack-plugin'; +import RequestShortener from 'webpack/lib/RequestShortener'; + +import CssnanoPlugin from '../src/index'; + +import { + getCompiler, + getErrors, + getWarnings, + compile, + readAssets, + readAsset, + removeCache, + normalizedSourceMap, +} from './helpers'; + +jest.setTimeout(30000); + +describe('CssnanoPlugin', () => { + const rawSourceMap = { + version: 3, + file: 'test.css', + names: ['bar', 'baz', 'n'], + sources: ['one.css', 'two.css'], + sourceRoot: 'http://example.com/www/js/', + mappings: + 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA', + }; + + const emptyRawSourceMap = { + version: 3, + sources: [], + mappings: '', + }; + + beforeEach(() => Promise.all([removeCache()])); + + afterEach(() => Promise.all([removeCache()])); + + it('should respect the hash options #1', () => { + const compiler = getCompiler({ + output: { + pathinfo: false, + path: path.resolve(__dirname, 'dist'), + filename: '[name].js', + chunkFilename: '[id].[name].js', + hashDigest: 'hex', + hashDigestLength: 20, + hashFunction: 'sha256', + hashSalt: 'salt', + }, + entry: { + entry: `${__dirname}/fixtures/test/foo.css`, + }, + }); + new CssnanoPlugin({ + cssnanoOptions: { + preset: ['default', { discardEmpty: false }], + }, + }).apply(compiler); + + return compile(compiler).then((stats) => { + expect(stats.compilation.errors).toEqual([]); + expect(stats.compilation.warnings).toEqual([]); + + for (const file in stats.compilation.assets) { + // eslint-disable-next-line no-continue + if (/\.js$/.test(file)) continue; + expect(readAsset(file, compiler, stats)).toMatchSnapshot(file); + } + }); + }); + + it('should write stdout and stderr of workers to stdout and stderr of main process in parallel mode', async () => { + const { write: stdoutWrite } = process.stdout; + const { write: stderrWrite } = process.stderr; + + let stdoutOutput = ''; + let stderrOutput = ''; + + process.stdout.write = (str) => { + stdoutOutput += str; + }; + + process.stderr.write = (str) => { + stderrOutput += str; + }; + + const compiler = getCompiler({ + entry: { + one: `${__dirname}/fixtures/entry.js`, + two: `${__dirname}/fixtures/entry.js`, + }, + }); + + new CssnanoPlugin({ + parallel: true, + minify: () => { + // eslint-disable-next-line no-console + process.stdout.write('stdout\n'); + // eslint-disable-next-line no-console + process.stderr.write('stderr\n'); + + return { css: '.minify {};' }; + }, + }).apply(compiler); + + const stats = await compile(compiler); + + expect(stdoutOutput).toMatchSnapshot('process stdout output'); + expect(stderrOutput).toMatchSnapshot('process stderr output'); + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + process.stdout.write = stdoutWrite; + process.stderr.write = stderrWrite; + }); + + it('isSourceMap method', () => { + expect(CssnanoPlugin.isSourceMap(null)).toBe(false); + expect(CssnanoPlugin.isSourceMap()).toBe(false); + expect(CssnanoPlugin.isSourceMap({})).toBe(false); + expect(CssnanoPlugin.isSourceMap([])).toBe(false); + expect(CssnanoPlugin.isSourceMap('foo')).toBe(false); + expect(CssnanoPlugin.isSourceMap({ version: 3 })).toBe(false); + expect(CssnanoPlugin.isSourceMap({ sources: '' })).toBe(false); + expect(CssnanoPlugin.isSourceMap({ mappings: [] })).toBe(false); + expect(CssnanoPlugin.isSourceMap({ version: 3, sources: '' })).toBe(false); + expect(CssnanoPlugin.isSourceMap({ version: 3, mappings: [] })).toBe(false); + expect(CssnanoPlugin.isSourceMap({ sources: '', mappings: [] })).toBe( + false + ); + expect( + CssnanoPlugin.isSourceMap({ version: 3, sources: '', mappings: [] }) + ).toBe(false); + expect(CssnanoPlugin.isSourceMap(rawSourceMap)).toBe(true); + expect(CssnanoPlugin.isSourceMap(emptyRawSourceMap)).toBe(true); + }); + + it('buildSourceMap method', () => { + expect(CssnanoPlugin.buildSourceMap()).toBe(null); + expect(CssnanoPlugin.buildSourceMap('invalid')).toBe(null); + expect(CssnanoPlugin.buildSourceMap({})).toBe(null); + expect(CssnanoPlugin.buildSourceMap(rawSourceMap)).toMatchSnapshot(); + }); + + it('buildError method', () => { + const error = new Error('Message'); + + error.stack = null; + + expect(CssnanoPlugin.buildError(error, 'test.css')).toMatchSnapshot(); + + const errorWithLineAndCol = new Error('Message'); + + errorWithLineAndCol.stack = null; + errorWithLineAndCol.line = 1; + errorWithLineAndCol.column = 1; + + expect( + CssnanoPlugin.buildError( + errorWithLineAndCol, + 'test.css', + CssnanoPlugin.buildSourceMap(rawSourceMap) + ) + ).toMatchSnapshot(); + + const otherErrorWithLineAndCol = new Error('Message'); + + otherErrorWithLineAndCol.stack = null; + otherErrorWithLineAndCol.line = 1; + otherErrorWithLineAndCol.column = 1; + + expect( + CssnanoPlugin.buildError( + otherErrorWithLineAndCol, + 'test.css', + CssnanoPlugin.buildSourceMap(rawSourceMap), + new RequestShortener('/example.com/www/js/') + ) + ).toMatchSnapshot(); + + const errorWithStack = new Error('Message'); + + errorWithStack.stack = 'Stack'; + + expect( + CssnanoPlugin.buildError(errorWithStack, 'test.css') + ).toMatchSnapshot(); + }); + + it('buildWarning method', () => { + expect( + CssnanoPlugin.buildWarning('Warning [test.css:1,1]') + ).toMatchSnapshot(); + expect( + CssnanoPlugin.buildWarning('Warning [test.css:1,1]', 'test.css') + ).toMatchSnapshot(); + expect( + CssnanoPlugin.buildWarning( + 'Warning [test.css:1,1]', + 'test.css', + CssnanoPlugin.buildSourceMap(rawSourceMap) + ) + ).toMatchSnapshot(); + expect( + CssnanoPlugin.buildWarning( + 'Warning [test.css:1,1]', + 'test.css', + CssnanoPlugin.buildSourceMap(rawSourceMap), + new RequestShortener('/example.com/www/js/') + ) + ).toMatchSnapshot(); + expect( + CssnanoPlugin.buildWarning( + 'Warning [test.css:1,1]', + 'test.css', + CssnanoPlugin.buildSourceMap(rawSourceMap), + new RequestShortener('/example.com/www/js/'), + () => true + ) + ).toMatchSnapshot(); + expect( + CssnanoPlugin.buildWarning( + 'Warning [test.css:1,1]', + 'test.css', + CssnanoPlugin.buildSourceMap(rawSourceMap), + new RequestShortener('/example.com/www/js/'), + () => false + ) + ).toMatchSnapshot(); + }); + + it('should build error', () => { + const compiler = getCompiler({ + entry: { + foo: `${__dirname}/fixtures/test/foo.css`, + }, + plugins: [ + new CopyPlugin({ + patterns: [ + { + context: `${__dirname}/fixtures/test`, + from: `error.css`, + }, + ], + }), + new MiniCssExtractPlugin({ + filename: '[name].css', + chunkFilename: '[id].[name].css', + }), + ], + }); + + new CssnanoPlugin().apply(compiler); + + return compile(compiler).then((stats) => { + expect(getErrors(stats)).toMatchSnapshot('error'); + expect(getWarnings(stats)).toMatchSnapshot('warning'); + }); + }); + + it('should build warning', () => { + const compiler = getCompiler({ + entry: { + foo: `${__dirname}/fixtures/test/foo.css`, + }, + }); + + const plugin = postcss.plugin('warning-plugin', () => (css, result) => { + result.warn('Warning', { + word: 'warning_word', + index: 2, + plugin: 'warning-plugin', + }); + }); + + new CssnanoPlugin({ + parallel: false, + minify: (data) => { + return postcss([plugin]) + .process(data.input, data.postcssOptions) + .then((result) => { + return { + css: result.css, + map: result.map, + error: result.error, + warnings: result.warnings(), + }; + }); + }, + }).apply(compiler); + + return compile(compiler).then((stats) => { + expect(getErrors(stats)).toMatchSnapshot('error'); + expect(getWarnings(stats)).toMatchSnapshot('warning'); + }); + }); + + it('should work with assets using querystring', () => { + const config = { + devtool: 'source-map', + entry: { + entry: `${__dirname}/fixtures/foo.css`, + }, + plugins: [ + new MiniCssExtractPlugin({ + filename: '[name].css?v=test', + chunkFilename: '[id].[name].css?v=test', + }), + ], + }; + + const compiler = getCompiler(config); + new CssnanoPlugin({ + sourceMap: true, + }).apply(compiler); + + return compile(compiler).then((stats) => { + expect(stats.compilation.errors).toEqual([]); + expect(stats.compilation.warnings).toEqual([]); + + // eslint-disable-next-line guard-for-in + for (const file in stats.compilation.assets) { + // eslint-disable-next-line no-continue + + if (/\.css\?/.test(file)) { + expect(readAsset(file, compiler, stats)).toMatchSnapshot(file); + } + + // eslint-disable-next-line no-continue + if (!/\.css.map/.test(file)) continue; + expect( + normalizedSourceMap(readAsset(file, compiler, stats)) + ).toMatchSnapshot(file); + } + }); + }); +}); diff --git a/test/__snapshots__/CssNano.test.js.snap b/test/__snapshots__/CssNano.test.js.snap.webpack4 similarity index 100% rename from test/__snapshots__/CssNano.test.js.snap rename to test/__snapshots__/CssNano.test.js.snap.webpack4 diff --git a/test/__snapshots__/CssnanoPlugin.test.js.snap.webpack4 b/test/__snapshots__/CssnanoPlugin.test.js.snap.webpack4 new file mode 100644 index 0000000..516b3c8 --- /dev/null +++ b/test/__snapshots__/CssnanoPlugin.test.js.snap.webpack4 @@ -0,0 +1,118 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`CssnanoPlugin buildError method 1`] = ` +[Error: test.css from Cssnano Webpack Plugin +Message] +`; + +exports[`CssnanoPlugin buildError method 2`] = ` +[Error: test.css from Cssnano Webpack Plugin +Message [test.css:1,1]] +`; + +exports[`CssnanoPlugin buildError method 3`] = ` +[Error: test.css from Cssnano Webpack Plugin +Message [http://example.com/www/js/one.css:1,1][test.css:1,1]] +`; + +exports[`CssnanoPlugin buildError method 4`] = ` +[Error: test.css from Cssnano Webpack Plugin +Stack] +`; + +exports[`CssnanoPlugin buildSourceMap method 1`] = ` +SourceMapConsumer { + "_absoluteSources": Array [ + "http://example.com/www/js/one.css", + "http://example.com/www/js/two.css", + ], + "_mappings": "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA", + "_names": ArraySet { + "_array": Array [ + "bar", + "baz", + "n", + ], + "_set": Map { + "bar" => 0, + "baz" => 1, + "n" => 2, + }, + }, + "_sourceMapURL": undefined, + "_sources": ArraySet { + "_array": Array [ + "one.css", + "two.css", + ], + "_set": Map { + "one.css" => 0, + "two.css" => 1, + }, + }, + "file": "test.css", + "sourceRoot": "http://example.com/www/js/", + "sourcesContent": null, +} +`; + +exports[`CssnanoPlugin buildWarning method 1`] = `"Cssnano Webpack Plugin: Warning [test.css:1,1]"`; + +exports[`CssnanoPlugin buildWarning method 2`] = `"Cssnano Webpack Plugin: Warning [test.css:1,1]"`; + +exports[`CssnanoPlugin buildWarning method 3`] = `"Cssnano Webpack Plugin: Warning [test.css:1,1]"`; + +exports[`CssnanoPlugin buildWarning method 4`] = `"Cssnano Webpack Plugin: Warning [http://example.com/www/js/one.css:1,1]"`; + +exports[`CssnanoPlugin buildWarning method 5`] = `"Cssnano Webpack Plugin: Warning [http://example.com/www/js/one.css:1,1]"`; + +exports[`CssnanoPlugin buildWarning method 6`] = `null`; + +exports[`CssnanoPlugin should build error: error 1`] = ` +Array [ + "Error: error.css from Cssnano Webpack Plugin +/error.css:1:1: Unknown word [error.css:1,1]", +] +`; + +exports[`CssnanoPlugin should build error: warning 1`] = `Array []`; + +exports[`CssnanoPlugin should build warning: error 1`] = `Array []`; + +exports[`CssnanoPlugin should build warning: warning 1`] = ` +Array [ + "Cssnano Webpack Plugin: warning-plugin: Warning", +] +`; + +exports[`CssnanoPlugin should respect the hash options #1: entry.css 1`] = `"a{text-align:center}"`; + +exports[`CssnanoPlugin should work with assets using querystring: entry.css.map?v=test 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACA,SACA,CACA,EACA,UACA\\",\\"file\\":\\"entry.css?v=test\\",\\"sourcesContent\\":[\\"body {\\\\n color: red;\\\\n}\\\\na {\\\\n color: blue;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; + +exports[`CssnanoPlugin should work with assets using querystring: entry.css?v=test 1`] = ` +"body{color:red}a{color:#00f} +/*# sourceMappingURL=entry.css.map?v=test*/" +`; + +exports[`CssnanoPlugin should write stdout and stderr of workers to stdout and stderr of main process in parallel mode: assets 1`] = ` +Object { + "one.css": ".minify {};", + "two.css": ".minify {};", +} +`; + +exports[`CssnanoPlugin should write stdout and stderr of workers to stdout and stderr of main process in parallel mode: errors 1`] = `Array []`; + +exports[`CssnanoPlugin should write stdout and stderr of workers to stdout and stderr of main process in parallel mode: process stderr output 1`] = ` +"stderr +stderr +" +`; + +exports[`CssnanoPlugin should write stdout and stderr of workers to stdout and stderr of main process in parallel mode: process stdout output 1`] = ` +"stdout +stdout +" +`; + +exports[`CssnanoPlugin should write stdout and stderr of workers to stdout and stderr of main process in parallel mode: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/CssnanoPlugin.test.js.snap.webpack5 b/test/__snapshots__/CssnanoPlugin.test.js.snap.webpack5 new file mode 100644 index 0000000..516b3c8 --- /dev/null +++ b/test/__snapshots__/CssnanoPlugin.test.js.snap.webpack5 @@ -0,0 +1,118 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`CssnanoPlugin buildError method 1`] = ` +[Error: test.css from Cssnano Webpack Plugin +Message] +`; + +exports[`CssnanoPlugin buildError method 2`] = ` +[Error: test.css from Cssnano Webpack Plugin +Message [test.css:1,1]] +`; + +exports[`CssnanoPlugin buildError method 3`] = ` +[Error: test.css from Cssnano Webpack Plugin +Message [http://example.com/www/js/one.css:1,1][test.css:1,1]] +`; + +exports[`CssnanoPlugin buildError method 4`] = ` +[Error: test.css from Cssnano Webpack Plugin +Stack] +`; + +exports[`CssnanoPlugin buildSourceMap method 1`] = ` +SourceMapConsumer { + "_absoluteSources": Array [ + "http://example.com/www/js/one.css", + "http://example.com/www/js/two.css", + ], + "_mappings": "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA", + "_names": ArraySet { + "_array": Array [ + "bar", + "baz", + "n", + ], + "_set": Map { + "bar" => 0, + "baz" => 1, + "n" => 2, + }, + }, + "_sourceMapURL": undefined, + "_sources": ArraySet { + "_array": Array [ + "one.css", + "two.css", + ], + "_set": Map { + "one.css" => 0, + "two.css" => 1, + }, + }, + "file": "test.css", + "sourceRoot": "http://example.com/www/js/", + "sourcesContent": null, +} +`; + +exports[`CssnanoPlugin buildWarning method 1`] = `"Cssnano Webpack Plugin: Warning [test.css:1,1]"`; + +exports[`CssnanoPlugin buildWarning method 2`] = `"Cssnano Webpack Plugin: Warning [test.css:1,1]"`; + +exports[`CssnanoPlugin buildWarning method 3`] = `"Cssnano Webpack Plugin: Warning [test.css:1,1]"`; + +exports[`CssnanoPlugin buildWarning method 4`] = `"Cssnano Webpack Plugin: Warning [http://example.com/www/js/one.css:1,1]"`; + +exports[`CssnanoPlugin buildWarning method 5`] = `"Cssnano Webpack Plugin: Warning [http://example.com/www/js/one.css:1,1]"`; + +exports[`CssnanoPlugin buildWarning method 6`] = `null`; + +exports[`CssnanoPlugin should build error: error 1`] = ` +Array [ + "Error: error.css from Cssnano Webpack Plugin +/error.css:1:1: Unknown word [error.css:1,1]", +] +`; + +exports[`CssnanoPlugin should build error: warning 1`] = `Array []`; + +exports[`CssnanoPlugin should build warning: error 1`] = `Array []`; + +exports[`CssnanoPlugin should build warning: warning 1`] = ` +Array [ + "Cssnano Webpack Plugin: warning-plugin: Warning", +] +`; + +exports[`CssnanoPlugin should respect the hash options #1: entry.css 1`] = `"a{text-align:center}"`; + +exports[`CssnanoPlugin should work with assets using querystring: entry.css.map?v=test 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACA,SACA,CACA,EACA,UACA\\",\\"file\\":\\"entry.css?v=test\\",\\"sourcesContent\\":[\\"body {\\\\n color: red;\\\\n}\\\\na {\\\\n color: blue;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; + +exports[`CssnanoPlugin should work with assets using querystring: entry.css?v=test 1`] = ` +"body{color:red}a{color:#00f} +/*# sourceMappingURL=entry.css.map?v=test*/" +`; + +exports[`CssnanoPlugin should write stdout and stderr of workers to stdout and stderr of main process in parallel mode: assets 1`] = ` +Object { + "one.css": ".minify {};", + "two.css": ".minify {};", +} +`; + +exports[`CssnanoPlugin should write stdout and stderr of workers to stdout and stderr of main process in parallel mode: errors 1`] = `Array []`; + +exports[`CssnanoPlugin should write stdout and stderr of workers to stdout and stderr of main process in parallel mode: process stderr output 1`] = ` +"stderr +stderr +" +`; + +exports[`CssnanoPlugin should write stdout and stderr of workers to stdout and stderr of main process in parallel mode: process stdout output 1`] = ` +"stdout +stdout +" +`; + +exports[`CssnanoPlugin should write stdout and stderr of workers to stdout and stderr of main process in parallel mode: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/cache-option.test.js.snap.webpack4 b/test/__snapshots__/cache-option.test.js.snap.webpack4 new file mode 100644 index 0000000..ce5ae8c --- /dev/null +++ b/test/__snapshots__/cache-option.test.js.snap.webpack4 @@ -0,0 +1,155 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`cache option should match snapshot and invalid cache when entry point was renamed: assets 1`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`cache option should match snapshot and invalid cache when entry point was renamed: assets 2`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "onne.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`cache option should match snapshot and invalid cache when entry point was renamed: errors 1`] = `Array []`; + +exports[`cache option should match snapshot and invalid cache when entry point was renamed: errors 2`] = `Array []`; + +exports[`cache option should match snapshot and invalid cache when entry point was renamed: warnings 1`] = `Array []`; + +exports[`cache option should match snapshot and invalid cache when entry point was renamed: warnings 2`] = `Array []`; + +exports[`cache option should match snapshot for the "false" value: assets 1`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`cache option should match snapshot for the "false" value: errors 1`] = `Array []`; + +exports[`cache option should match snapshot for the "false" value: warnings 1`] = `Array []`; + +exports[`cache option should match snapshot for the "other-cache-directory" value: assets 1`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`cache option should match snapshot for the "other-cache-directory" value: assets 2`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`cache option should match snapshot for the "other-cache-directory" value: errors 1`] = `Array []`; + +exports[`cache option should match snapshot for the "other-cache-directory" value: errors 2`] = `Array []`; + +exports[`cache option should match snapshot for the "other-cache-directory" value: warnings 1`] = `Array []`; + +exports[`cache option should match snapshot for the "other-cache-directory" value: warnings 2`] = `Array []`; + +exports[`cache option should match snapshot for the "true" value: assets 1`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`cache option should match snapshot for the "true" value: assets 2`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`cache option should match snapshot for the "true" value: errors 1`] = `Array []`; + +exports[`cache option should match snapshot for the "true" value: errors 2`] = `Array []`; + +exports[`cache option should match snapshot for the "true" value: warnings 1`] = `Array []`; + +exports[`cache option should match snapshot for the "true" value: warnings 2`] = `Array []`; + +exports[`cache option should match snapshot when "cacheKey" is custom "function": assets 1`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`cache option should match snapshot when "cacheKey" is custom "function": assets 2`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`cache option should match snapshot when "cacheKey" is custom "function": errors 1`] = `Array []`; + +exports[`cache option should match snapshot when "cacheKey" is custom "function": errors 2`] = `Array []`; + +exports[`cache option should match snapshot when "cacheKey" is custom "function": warnings 1`] = `Array []`; + +exports[`cache option should match snapshot when "cacheKey" is custom "function": warnings 2`] = `Array []`; + +exports[`cache option should match snapshot when a value is not specify: assets 1`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`cache option should match snapshot when a value is not specify: assets 2`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`cache option should match snapshot when a value is not specify: errors 1`] = `Array []`; + +exports[`cache option should match snapshot when a value is not specify: errors 2`] = `Array []`; + +exports[`cache option should match snapshot when a value is not specify: warnings 1`] = `Array []`; + +exports[`cache option should match snapshot when a value is not specify: warnings 2`] = `Array []`; diff --git a/test/__snapshots__/cssnanoOptions-option.test.js.snap b/test/__snapshots__/cssnanoOptions-option.test.js.snap.webpack4 similarity index 100% rename from test/__snapshots__/cssnanoOptions-option.test.js.snap rename to test/__snapshots__/cssnanoOptions-option.test.js.snap.webpack4 diff --git a/test/__snapshots__/cssnanoOptions-option.test.js.snap.webpack5 b/test/__snapshots__/cssnanoOptions-option.test.js.snap.webpack5 new file mode 100644 index 0000000..1442488 --- /dev/null +++ b/test/__snapshots__/cssnanoOptions-option.test.js.snap.webpack5 @@ -0,0 +1,22 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`when applied with "cssnanoOptions" option matches snapshot for "discardComments" option (disable): entry.css 1`] = ` +"body{ + /* this is a comment */ + /*! this is a comment with exclamation mark */color:red}" +`; + +exports[`when applied with "cssnanoOptions" option matches snapshot for "discardComments" option (enable [default]): entry.css 1`] = ` +"body{ + /*! this is a comment with exclamation mark */color:red}" +`; + +exports[`when applied with "cssnanoOptions" option matches snapshot for "discardComments" option (enable, with "removeAll" option): entry.css 1`] = `"body{color:red}"`; + +exports[`when applied with "cssnanoOptions" option matches snapshot for "discardEmpty" option (disable): entry.css 1`] = `"body{color:red}a{}"`; + +exports[`when applied with "cssnanoOptions" option matches snapshot for "discardEmpty" option (enable [default]): entry.css 1`] = `"body{color:red}"`; + +exports[`when applied with "cssnanoOptions" option matches snapshot for "mergeRules" option (disable): entry.css 1`] = `"body{color:red}body{font-weight:700}"`; + +exports[`when applied with "cssnanoOptions" option matches snapshot for "mergeRules" option (enable [default]): entry.css 1`] = `"body{color:red;font-weight:700}"`; diff --git a/test/__snapshots__/exclude-option.test.js.snap.webpack4 b/test/__snapshots__/exclude-option.test.js.snap.webpack4 new file mode 100644 index 0000000..1621707 --- /dev/null +++ b/test/__snapshots__/exclude-option.test.js.snap.webpack4 @@ -0,0 +1,87 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`exclude option should match snapshot for a single RegExp value excluded1: assets 1`] = ` +Object { + "entry.css": "body{color:red}a{color:#00f}", + "excluded1.css": "a { + text-align: center; +} + +", + "excluded2.css": "body{color:red;font-size:20px}a{color:#00f}", +} +`; + +exports[`exclude option should match snapshot for a single RegExp value excluded1: errors 1`] = `Array []`; + +exports[`exclude option should match snapshot for a single RegExp value excluded1: warnings 1`] = `Array []`; + +exports[`exclude option should match snapshot for a single String value excluded1: assets 1`] = ` +Object { + "entry.css": "body{color:red}a{color:#00f}", + "excluded1.css": "a { + text-align: center; +} + +", + "excluded2.css": "body{color:red;font-size:20px}a{color:#00f}", +} +`; + +exports[`exclude option should match snapshot for a single String value excluded1: errors 1`] = `Array []`; + +exports[`exclude option should match snapshot for a single String value excluded1: warnings 1`] = `Array []`; + +exports[`exclude option should match snapshot for multiple RegExp values excluded1 and excluded2: assets 1`] = ` +Object { + "entry.css": "body{color:red}a{color:#00f}", + "excluded1.css": "a { + text-align: center; +} + +", + "excluded2.css": "body { + color: red; +} +body { + color: red; + font-size: 20px; +} +a { + color: blue; +} + +", +} +`; + +exports[`exclude option should match snapshot for multiple RegExp values excluded1 and excluded2: errors 1`] = `Array []`; + +exports[`exclude option should match snapshot for multiple RegExp values excluded1 and excluded2: warnings 1`] = `Array []`; + +exports[`exclude option should match snapshot for multiple String values excluded1 and excluded2: assets 1`] = ` +Object { + "entry.css": "body{color:red}a{color:#00f}", + "excluded1.css": "a { + text-align: center; +} + +", + "excluded2.css": "body { + color: red; +} +body { + color: red; + font-size: 20px; +} +a { + color: blue; +} + +", +} +`; + +exports[`exclude option should match snapshot for multiple String values excluded1 and excluded2: errors 1`] = `Array []`; + +exports[`exclude option should match snapshot for multiple String values excluded1 and excluded2: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/exclude-option.test.js.snap.webpack5 b/test/__snapshots__/exclude-option.test.js.snap.webpack5 new file mode 100644 index 0000000..1621707 --- /dev/null +++ b/test/__snapshots__/exclude-option.test.js.snap.webpack5 @@ -0,0 +1,87 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`exclude option should match snapshot for a single RegExp value excluded1: assets 1`] = ` +Object { + "entry.css": "body{color:red}a{color:#00f}", + "excluded1.css": "a { + text-align: center; +} + +", + "excluded2.css": "body{color:red;font-size:20px}a{color:#00f}", +} +`; + +exports[`exclude option should match snapshot for a single RegExp value excluded1: errors 1`] = `Array []`; + +exports[`exclude option should match snapshot for a single RegExp value excluded1: warnings 1`] = `Array []`; + +exports[`exclude option should match snapshot for a single String value excluded1: assets 1`] = ` +Object { + "entry.css": "body{color:red}a{color:#00f}", + "excluded1.css": "a { + text-align: center; +} + +", + "excluded2.css": "body{color:red;font-size:20px}a{color:#00f}", +} +`; + +exports[`exclude option should match snapshot for a single String value excluded1: errors 1`] = `Array []`; + +exports[`exclude option should match snapshot for a single String value excluded1: warnings 1`] = `Array []`; + +exports[`exclude option should match snapshot for multiple RegExp values excluded1 and excluded2: assets 1`] = ` +Object { + "entry.css": "body{color:red}a{color:#00f}", + "excluded1.css": "a { + text-align: center; +} + +", + "excluded2.css": "body { + color: red; +} +body { + color: red; + font-size: 20px; +} +a { + color: blue; +} + +", +} +`; + +exports[`exclude option should match snapshot for multiple RegExp values excluded1 and excluded2: errors 1`] = `Array []`; + +exports[`exclude option should match snapshot for multiple RegExp values excluded1 and excluded2: warnings 1`] = `Array []`; + +exports[`exclude option should match snapshot for multiple String values excluded1 and excluded2: assets 1`] = ` +Object { + "entry.css": "body{color:red}a{color:#00f}", + "excluded1.css": "a { + text-align: center; +} + +", + "excluded2.css": "body { + color: red; +} +body { + color: red; + font-size: 20px; +} +a { + color: blue; +} + +", +} +`; + +exports[`exclude option should match snapshot for multiple String values excluded1 and excluded2: errors 1`] = `Array []`; + +exports[`exclude option should match snapshot for multiple String values excluded1 and excluded2: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/include-option.test.js.snap.webpack4 b/test/__snapshots__/include-option.test.js.snap.webpack4 new file mode 100644 index 0000000..268d8b5 --- /dev/null +++ b/test/__snapshots__/include-option.test.js.snap.webpack4 @@ -0,0 +1,95 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`include option should match snapshot for a single RegExp value included1: assets 1`] = ` +Object { + "entry.css": "body { + color: red; +} +a { + color: blue; +} +", + "included1.css": "a{text-align:center}", + "included2.css": "body { + color: red; +} +body { + color: red; + font-size: 20px; +} +a { + color: blue; +} + +", +} +`; + +exports[`include option should match snapshot for a single RegExp value included1: errors 1`] = `Array []`; + +exports[`include option should match snapshot for a single RegExp value included1: warnings 1`] = `Array []`; + +exports[`include option should match snapshot for a single String value included1: assets 1`] = ` +Object { + "entry.css": "body { + color: red; +} +a { + color: blue; +} +", + "included1.css": "a{text-align:center}", + "included2.css": "body { + color: red; +} +body { + color: red; + font-size: 20px; +} +a { + color: blue; +} + +", +} +`; + +exports[`include option should match snapshot for a single String value included1: errors 1`] = `Array []`; + +exports[`include option should match snapshot for a single String value included1: warnings 1`] = `Array []`; + +exports[`include option should match snapshot for multiple RegExp values included1 and included2: assets 1`] = ` +Object { + "entry.css": "body { + color: red; +} +a { + color: blue; +} +", + "included1.css": "a{text-align:center}", + "included2.css": "body{color:red;font-size:20px}a{color:#00f}", +} +`; + +exports[`include option should match snapshot for multiple RegExp values included1 and included2: errors 1`] = `Array []`; + +exports[`include option should match snapshot for multiple RegExp values included1 and included2: warnings 1`] = `Array []`; + +exports[`include option should match snapshot for multiple String values included1 and included2: assets 1`] = ` +Object { + "entry.css": "body { + color: red; +} +a { + color: blue; +} +", + "included1.css": "a{text-align:center}", + "included2.css": "body{color:red;font-size:20px}a{color:#00f}", +} +`; + +exports[`include option should match snapshot for multiple String values included1 and included2: errors 1`] = `Array []`; + +exports[`include option should match snapshot for multiple String values included1 and included2: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/include-option.test.js.snap.webpack5 b/test/__snapshots__/include-option.test.js.snap.webpack5 new file mode 100644 index 0000000..268d8b5 --- /dev/null +++ b/test/__snapshots__/include-option.test.js.snap.webpack5 @@ -0,0 +1,95 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`include option should match snapshot for a single RegExp value included1: assets 1`] = ` +Object { + "entry.css": "body { + color: red; +} +a { + color: blue; +} +", + "included1.css": "a{text-align:center}", + "included2.css": "body { + color: red; +} +body { + color: red; + font-size: 20px; +} +a { + color: blue; +} + +", +} +`; + +exports[`include option should match snapshot for a single RegExp value included1: errors 1`] = `Array []`; + +exports[`include option should match snapshot for a single RegExp value included1: warnings 1`] = `Array []`; + +exports[`include option should match snapshot for a single String value included1: assets 1`] = ` +Object { + "entry.css": "body { + color: red; +} +a { + color: blue; +} +", + "included1.css": "a{text-align:center}", + "included2.css": "body { + color: red; +} +body { + color: red; + font-size: 20px; +} +a { + color: blue; +} + +", +} +`; + +exports[`include option should match snapshot for a single String value included1: errors 1`] = `Array []`; + +exports[`include option should match snapshot for a single String value included1: warnings 1`] = `Array []`; + +exports[`include option should match snapshot for multiple RegExp values included1 and included2: assets 1`] = ` +Object { + "entry.css": "body { + color: red; +} +a { + color: blue; +} +", + "included1.css": "a{text-align:center}", + "included2.css": "body{color:red;font-size:20px}a{color:#00f}", +} +`; + +exports[`include option should match snapshot for multiple RegExp values included1 and included2: errors 1`] = `Array []`; + +exports[`include option should match snapshot for multiple RegExp values included1 and included2: warnings 1`] = `Array []`; + +exports[`include option should match snapshot for multiple String values included1 and included2: assets 1`] = ` +Object { + "entry.css": "body { + color: red; +} +a { + color: blue; +} +", + "included1.css": "a{text-align:center}", + "included2.css": "body{color:red;font-size:20px}a{color:#00f}", +} +`; + +exports[`include option should match snapshot for multiple String values included1 and included2: errors 1`] = `Array []`; + +exports[`include option should match snapshot for multiple String values included1 and included2: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/parallel-option.test.js.snap.webpack4 b/test/__snapshots__/parallel-option.test.js.snap.webpack4 new file mode 100644 index 0000000..2ac1c2b --- /dev/null +++ b/test/__snapshots__/parallel-option.test.js.snap.webpack4 @@ -0,0 +1,104 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`parallel option should match snapshot for the "2" value: assets 1`] = ` +Object { + "four.css": "body{color:red}a{color:#00f}", + "one.css": "body{color:red}a{color:#00f}", + "three.css": "body{color:red}a{color:#00f}", + "two.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "2" value: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "2" value: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "false" value: assets 1`] = ` +Object { + "four.css": "body{color:red}a{color:#00f}", + "one.css": "body{color:red}a{color:#00f}", + "three.css": "body{color:red}a{color:#00f}", + "two.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "false" value: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "false" value: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is less than the number of cores: assets 1`] = ` +Object { + "entry-0.css": "body{color:red}a{color:#00f}", + "entry-1.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is less than the number of cores: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is less than the number of cores: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is more than the number of cores: assets 1`] = ` +Object { + "eight.css": "body{color:red}a{color:#00f}", + "five.css": "body{color:red}a{color:#00f}", + "four.css": "body{color:red}a{color:#00f}", + "one.css": "body{color:red}a{color:#00f}", + "seven.css": "body{color:red}a{color:#00f}", + "six.css": "body{color:red}a{color:#00f}", + "three.css": "body{color:red}a{color:#00f}", + "two.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is more than the number of cores: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is more than the number of cores: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is same than the number of cores: assets 1`] = ` +Object { + "entry-0.css": "body{color:red}a{color:#00f}", + "entry-1.css": "body{color:red}a{color:#00f}", + "entry-2.css": "body{color:red}a{color:#00f}", + "entry-3.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is same than the number of cores: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is same than the number of cores: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value when only one file passed: assets 1`] = ` +Object { + "main.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "true" value when only one file passed: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value when only one file passed: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value: assets 1`] = ` +Object { + "four.css": "body{color:red}a{color:#00f}", + "one.css": "body{color:red}a{color:#00f}", + "three.css": "body{color:red}a{color:#00f}", + "two.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "true" value: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot when a value is not specify: assets 1`] = ` +Object { + "four.css": "body{color:red}a{color:#00f}", + "one.css": "body{color:red}a{color:#00f}", + "three.css": "body{color:red}a{color:#00f}", + "two.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot when a value is not specify: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot when a value is not specify: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/parallel-option.test.js.snap.webpack5 b/test/__snapshots__/parallel-option.test.js.snap.webpack5 new file mode 100644 index 0000000..2ac1c2b --- /dev/null +++ b/test/__snapshots__/parallel-option.test.js.snap.webpack5 @@ -0,0 +1,104 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`parallel option should match snapshot for the "2" value: assets 1`] = ` +Object { + "four.css": "body{color:red}a{color:#00f}", + "one.css": "body{color:red}a{color:#00f}", + "three.css": "body{color:red}a{color:#00f}", + "two.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "2" value: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "2" value: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "false" value: assets 1`] = ` +Object { + "four.css": "body{color:red}a{color:#00f}", + "one.css": "body{color:red}a{color:#00f}", + "three.css": "body{color:red}a{color:#00f}", + "two.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "false" value: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "false" value: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is less than the number of cores: assets 1`] = ` +Object { + "entry-0.css": "body{color:red}a{color:#00f}", + "entry-1.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is less than the number of cores: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is less than the number of cores: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is more than the number of cores: assets 1`] = ` +Object { + "eight.css": "body{color:red}a{color:#00f}", + "five.css": "body{color:red}a{color:#00f}", + "four.css": "body{color:red}a{color:#00f}", + "one.css": "body{color:red}a{color:#00f}", + "seven.css": "body{color:red}a{color:#00f}", + "six.css": "body{color:red}a{color:#00f}", + "three.css": "body{color:red}a{color:#00f}", + "two.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is more than the number of cores: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is more than the number of cores: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is same than the number of cores: assets 1`] = ` +Object { + "entry-0.css": "body{color:red}a{color:#00f}", + "entry-1.css": "body{color:red}a{color:#00f}", + "entry-2.css": "body{color:red}a{color:#00f}", + "entry-3.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is same than the number of cores: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value and the number of files is same than the number of cores: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value when only one file passed: assets 1`] = ` +Object { + "main.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "true" value when only one file passed: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value when only one file passed: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value: assets 1`] = ` +Object { + "four.css": "body{color:red}a{color:#00f}", + "one.css": "body{color:red}a{color:#00f}", + "three.css": "body{color:red}a{color:#00f}", + "two.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot for the "true" value: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot for the "true" value: warnings 1`] = `Array []`; + +exports[`parallel option should match snapshot when a value is not specify: assets 1`] = ` +Object { + "four.css": "body{color:red}a{color:#00f}", + "one.css": "body{color:red}a{color:#00f}", + "three.css": "body{color:red}a{color:#00f}", + "two.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`parallel option should match snapshot when a value is not specify: errors 1`] = `Array []`; + +exports[`parallel option should match snapshot when a value is not specify: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/sourceMap-option.test.js.snap b/test/__snapshots__/sourceMap-option.test.js.snap.webpack4 similarity index 90% rename from test/__snapshots__/sourceMap-option.test.js.snap rename to test/__snapshots__/sourceMap-option.test.js.snap.webpack4 index bbd0656..1f94713 100644 --- a/test/__snapshots__/sourceMap-option.test.js.snap +++ b/test/__snapshots__/sourceMap-option.test.js.snap.webpack4 @@ -49,3 +49,18 @@ exports[`when applied with "sourceMap" option matches snapshot when using Source exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): sourcemaps/entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"webpack:///./test/fixtures/sourcemap/bar.scss\\",\\"webpack:///./test/fixtures/sourcemap/foo.scss\\"],\\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"dist/entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): sourcemaps/entry2.css.map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"webpack:///./test/fixtures/sourcemap/bar.scss\\",\\"webpack:///./test/fixtures/sourcemap/foo.css\\"],\\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCGlB,OAGC,iBAAkB\\",\\"file\\":\\"dist/entry2.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n}\\\\n\\\\nbody a {\\\\n text-align: center;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; + +exports[`when applied with "sourceMap" option should emit warning when broken sourcemap: error 1`] = ` +Array [ + "Error: broken-source-map.css from Cssnano Webpack Plugin +Error: \\"version\\" is a required argument.", + "ModuleBuildError: Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js): +Error: broken-source-map.css from Cssnano Webpack Plugin", +] +`; + +exports[`when applied with "sourceMap" option should emit warning when broken sourcemap: warning 1`] = ` +Array [ + "Error: broken-source-map.css contains invalid source map", +] +`; diff --git a/test/__snapshots__/sourceMap-option.test.js.snap.webpack5 b/test/__snapshots__/sourceMap-option.test.js.snap.webpack5 new file mode 100644 index 0000000..1f94713 --- /dev/null +++ b/test/__snapshots__/sourceMap-option.test.js.snap.webpack5 @@ -0,0 +1,66 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`when applied with "sourceMap" option matches snapshot for "false" value, using previous sourcemap: entry.css 1`] = `"body{font-weight:700;color:red}body a{text-align:center}"`; + +exports[`when applied with "sourceMap" option matches snapshot for "false" value, using previous sourcemap: entry2.css 1`] = `"body{font-weight:700;color:red}body a{text-align:center}"`; + +exports[`when applied with "sourceMap" option matches snapshot for "false" value, without previous sourcemap: entry.css 1`] = `"body{font-weight:700;color:red}body a{text-align:center}"`; + +exports[`when applied with "sourceMap" option matches snapshot for "false" value, without previous sourcemap: entry2.css 1`] = `"body{font-weight:700;color:red}body a{text-align:center}"`; + +exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry.css 1`] = ` +"body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=entry.css.map*/" +`; + +exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; + +exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry2.css 1`] = ` +"body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=entry2.css.map*/" +`; + +exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry2.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCGlB,OAGC,iBAAkB\\",\\"file\\":\\"entry2.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n}\\\\n\\\\nbody a {\\\\n text-align: center;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; + +exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry.css 1`] = ` +"body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=entry.css.map*/" +`; + +exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KAAK,gBAAsB,SAAtB,CAAgC,OAAO\\",\\"file\\":\\"entry.css\\",\\"sourcesContent\\":[\\"body{font-weight:bold}body{color:red}body a{text-align:center}\\\\n\\"],\\"sourceRoot\\":\\"\\"}"`; + +exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry2.css 1`] = ` +"body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=entry2.css.map*/" +`; + +exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry2.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KAAK,gBAAsB,SAAtB,CAAgC,OAAO\\",\\"file\\":\\"entry2.css\\",\\"sourcesContent\\":[\\"body{font-weight:bold}body{color:red}body a{text-align:center}\\\\n\\"],\\"sourceRoot\\":\\"\\"}"`; + +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): dist/entry.css 1`] = ` +"body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=https://example.com/project/sourcemaps/entry.css.map*/" +`; + +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): dist/entry2.css 1`] = ` +"body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=https://example.com/project/sourcemaps/entry2.css.map*/" +`; + +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): sourcemaps/entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"webpack:///./test/fixtures/sourcemap/bar.scss\\",\\"webpack:///./test/fixtures/sourcemap/foo.scss\\"],\\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"dist/entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; + +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): sourcemaps/entry2.css.map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"webpack:///./test/fixtures/sourcemap/bar.scss\\",\\"webpack:///./test/fixtures/sourcemap/foo.css\\"],\\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCGlB,OAGC,iBAAkB\\",\\"file\\":\\"dist/entry2.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n}\\\\n\\\\nbody a {\\\\n text-align: center;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; + +exports[`when applied with "sourceMap" option should emit warning when broken sourcemap: error 1`] = ` +Array [ + "Error: broken-source-map.css from Cssnano Webpack Plugin +Error: \\"version\\" is a required argument.", + "ModuleBuildError: Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js): +Error: broken-source-map.css from Cssnano Webpack Plugin", +] +`; + +exports[`when applied with "sourceMap" option should emit warning when broken sourcemap: warning 1`] = ` +Array [ + "Error: broken-source-map.css contains invalid source map", +] +`; diff --git a/test/__snapshots__/test-option.test.js.snap b/test/__snapshots__/test-option.test.js.snap.webpack4 similarity index 100% rename from test/__snapshots__/test-option.test.js.snap rename to test/__snapshots__/test-option.test.js.snap.webpack4 diff --git a/test/__snapshots__/test-option.test.js.snap.webpack5 b/test/__snapshots__/test-option.test.js.snap.webpack5 new file mode 100644 index 0000000..6de26e2 --- /dev/null +++ b/test/__snapshots__/test-option.test.js.snap.webpack5 @@ -0,0 +1,31 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): bar1.css 1`] = `"body{color:red;font-size:20px}a{color:#00f}"`; + +exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): bar2.css 1`] = `"h1{color:green}h2{color:#ff0}"`; + +exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): foo.css 1`] = ` +"a { + text-align: center; +} + +" +`; + +exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): bar1.css 1`] = `"body{color:red;font-size:20px}a{color:#00f}"`; + +exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): bar2.css 1`] = `"h1{color:green}h2{color:#ff0}"`; + +exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): foo.css 1`] = ` +"a { + text-align: center; +} + +" +`; + +exports[`when applied with "test" option matches snapshot with empty value: bar1.css 1`] = `"body{color:red;font-size:20px}a{color:#00f}"`; + +exports[`when applied with "test" option matches snapshot with empty value: bar2.css 1`] = `"h1{color:green}h2{color:#ff0}"`; + +exports[`when applied with "test" option matches snapshot with empty value: foo.css 1`] = `"a{text-align:center}"`; diff --git a/test/__snapshots__/validate-options.test.js.snap b/test/__snapshots__/validate-options.test.js.snap.webpack4 similarity index 94% rename from test/__snapshots__/validate-options.test.js.snap rename to test/__snapshots__/validate-options.test.js.snap.webpack4 index a403fdf..188c90b 100644 --- a/test/__snapshots__/validate-options.test.js.snap +++ b/test/__snapshots__/validate-options.test.js.snap.webpack4 @@ -146,7 +146,13 @@ exports[`validation 12`] = ` `; exports[`validation 13`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.minify should be an instance of function. + -> Allows you to override default minify function." +`; + +exports[`validation 14`] = ` "Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. - options has an unknown property 'unknown'. These properties are valid: - object { test?, include?, exclude?, sourceMap?, cssnanoOptions?, cache?, cacheKeys?, parallel?, warningsFilter? }" + object { test?, include?, exclude?, sourceMap?, cssnanoOptions?, cache?, cacheKeys?, parallel?, warningsFilter?, minify? }" `; diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack5 b/test/__snapshots__/validate-options.test.js.snap.webpack5 new file mode 100644 index 0000000..188c90b --- /dev/null +++ b/test/__snapshots__/validate-options.test.js.snap.webpack5 @@ -0,0 +1,158 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`validation 1`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.test should be one of these: + [RegExp | non-empty string, ...] | RegExp | non-empty string + -> Filtering rules. + Details: + * options.test should be an array: + [RegExp | non-empty string, ...] + * options.test should be one of these: + RegExp | non-empty string + -> Filtering rule as regex or string. + Details: + * options.test should be an instance of RegExp. + * options.test should be a non-empty string." +`; + +exports[`validation 2`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.test should be one of these: + [RegExp | non-empty string, ...] | RegExp | non-empty string + -> Filtering rules. + Details: + * options.test[0] should be one of these: + RegExp | non-empty string + -> Filtering rule as regex or string. + Details: + * options.test[0] should be an instance of RegExp. + * options.test[0] should be a non-empty string." +`; + +exports[`validation 3`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.include should be one of these: + [RegExp | non-empty string, ...] | RegExp | non-empty string + -> Filtering rules. + Details: + * options.include should be an array: + [RegExp | non-empty string, ...] + * options.include should be one of these: + RegExp | non-empty string + -> Filtering rule as regex or string. + Details: + * options.include should be an instance of RegExp. + * options.include should be a non-empty string." +`; + +exports[`validation 4`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.include should be one of these: + [RegExp | non-empty string, ...] | RegExp | non-empty string + -> Filtering rules. + Details: + * options.include[0] should be one of these: + RegExp | non-empty string + -> Filtering rule as regex or string. + Details: + * options.include[0] should be an instance of RegExp. + * options.include[0] should be a non-empty string." +`; + +exports[`validation 5`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.exclude should be one of these: + [RegExp | non-empty string, ...] | RegExp | non-empty string + -> Filtering rules. + Details: + * options.exclude should be an array: + [RegExp | non-empty string, ...] + * options.exclude should be one of these: + RegExp | non-empty string + -> Filtering rule as regex or string. + Details: + * options.exclude should be an instance of RegExp. + * options.exclude should be a non-empty string." +`; + +exports[`validation 6`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.exclude should be one of these: + [RegExp | non-empty string, ...] | RegExp | non-empty string + -> Filtering rules. + Details: + * options.exclude[0] should be one of these: + RegExp | non-empty string + -> Filtering rule as regex or string. + Details: + * options.exclude[0] should be an instance of RegExp. + * options.exclude[0] should be a non-empty string." +`; + +exports[`validation 7`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.sourceMap should be one of these: + object { … } | boolean + -> Enables/Disables generation of source maps. + Details: + * options.sourceMap should be an object: + object { … } + -> Options for source map. + * options.sourceMap should be a boolean." +`; + +exports[`validation 8`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.cssnanoOptions should be an object: + object { … } + -> Options for \`cssnanoOptions\`." +`; + +exports[`validation 9`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.cache should be one of these: + boolean | string + -> Enable file caching. Ignored in webpack 5, for webpack 5 please use https://webpack.js.org/configuration/other-options/#cache. + Details: + * options.cache should be a boolean. + * options.cache should be a string." +`; + +exports[`validation 10`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.cacheKeys should be an instance of function. + -> Allows you to override default cache keys. Ignored in webpack 5, for webpack 5 please use https://webpack.js.org/configuration/other-options/#cache." +`; + +exports[`validation 11`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.parallel should be one of these: + boolean | integer + -> Use multi-process parallel running to improve the build speed. + Details: + * options.parallel should be a boolean. + * options.parallel should be a integer." +`; + +exports[`validation 12`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.parallel should be one of these: + boolean | integer + -> Use multi-process parallel running to improve the build speed. + Details: + * options.parallel should be a boolean. + * options.parallel should be a integer." +`; + +exports[`validation 13`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options.minify should be an instance of function. + -> Allows you to override default minify function." +`; + +exports[`validation 14`] = ` +"Invalid options object. Cssnano webpack plugin has been initialized using an options object that does not match the API schema. + - options has an unknown property 'unknown'. These properties are valid: + object { test?, include?, exclude?, sourceMap?, cssnanoOptions?, cache?, cacheKeys?, parallel?, warningsFilter?, minify? }" +`; diff --git a/test/__snapshots__/warningsFilter-option.test.js.snap.webpack4 b/test/__snapshots__/warningsFilter-option.test.js.snap.webpack4 new file mode 100644 index 0000000..e0a2d45 --- /dev/null +++ b/test/__snapshots__/warningsFilter-option.test.js.snap.webpack4 @@ -0,0 +1,42 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`warningsFilter option should match snapshot for a "function" value: assets 1`] = ` +Object { + "bar1.css": "body { + color: red; +} +body { + color: red; + font-size: 20px; +} +a { + color: blue; +} + +", + "bar2.css": "h1 { + color: green; +} +h2 { + color: yellow; +} +h3 { +} + +", + "foo.css": "a { + text-align: center; +} + +", +} +`; + +exports[`warningsFilter option should match snapshot for a "function" value: errors 1`] = `Array []`; + +exports[`warningsFilter option should match snapshot for a "function" value: warnings 1`] = ` +Array [ + "Cssnano Webpack Plugin: warning-plugin: Warning from bar1.css", + "Cssnano Webpack Plugin: warning-plugin: Warning from bar2.css", +] +`; diff --git a/test/__snapshots__/warningsFilter-option.test.js.snap.webpack5 b/test/__snapshots__/warningsFilter-option.test.js.snap.webpack5 new file mode 100644 index 0000000..e0a2d45 --- /dev/null +++ b/test/__snapshots__/warningsFilter-option.test.js.snap.webpack5 @@ -0,0 +1,42 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`warningsFilter option should match snapshot for a "function" value: assets 1`] = ` +Object { + "bar1.css": "body { + color: red; +} +body { + color: red; + font-size: 20px; +} +a { + color: blue; +} + +", + "bar2.css": "h1 { + color: green; +} +h2 { + color: yellow; +} +h3 { +} + +", + "foo.css": "a { + text-align: center; +} + +", +} +`; + +exports[`warningsFilter option should match snapshot for a "function" value: errors 1`] = `Array []`; + +exports[`warningsFilter option should match snapshot for a "function" value: warnings 1`] = ` +Array [ + "Cssnano Webpack Plugin: warning-plugin: Warning from bar1.css", + "Cssnano Webpack Plugin: warning-plugin: Warning from bar2.css", +] +`; diff --git a/test/__snapshots__/worker.test.js.snap.webpack4 b/test/__snapshots__/worker.test.js.snap.webpack4 new file mode 100644 index 0000000..24006ff --- /dev/null +++ b/test/__snapshots__/worker.test.js.snap.webpack4 @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`worker should emit error: error 1`] = ` +Array [ + "/entry.css:1:1: Unknown word", +] +`; + +exports[`worker should minify css: css 1`] = `".foo{color:red}.bar{color:coral}"`; + +exports[`worker should minify css: map 1`] = ` +Object { + "file": "entry.css", + "mappings": "AAAA,KAAK,SAAA,CCCL,KAAK,WAAY", + "names": Array [], + "sources": Array [ + "foo.css", + "entry.css", + ], + "sourcesContent": Array [ + ".foo{color:red;}", + ".foo{color:red;} +.bar{color:coral;}", + ], + "version": 3, +} +`; + +exports[`worker should work inputSourceMap as prev: css 1`] = `".foo{color:red}.bar{color:coral}"`; + +exports[`worker should work inputSourceMap as prev: map 1`] = ` +Object { + "file": "entry.css", + "mappings": "AAAA,KAAK,SAAA,CCCL,KAAK,WAAY", + "names": Array [], + "sources": Array [ + "foo.css", + "entry.css", + ], + "sourcesContent": Array [ + ".foo{color:red;}", + ".foo{color:red;} +.bar{color:coral;}", + ], + "version": 3, +} +`; + +exports[`worker should work options.minify function: css 1`] = `".minify {};"`; + +exports[`worker should work options.minify function: map 1`] = `undefined`; diff --git a/test/__snapshots__/worker.test.js.snap.webpack5 b/test/__snapshots__/worker.test.js.snap.webpack5 new file mode 100644 index 0000000..24006ff --- /dev/null +++ b/test/__snapshots__/worker.test.js.snap.webpack5 @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`worker should emit error: error 1`] = ` +Array [ + "/entry.css:1:1: Unknown word", +] +`; + +exports[`worker should minify css: css 1`] = `".foo{color:red}.bar{color:coral}"`; + +exports[`worker should minify css: map 1`] = ` +Object { + "file": "entry.css", + "mappings": "AAAA,KAAK,SAAA,CCCL,KAAK,WAAY", + "names": Array [], + "sources": Array [ + "foo.css", + "entry.css", + ], + "sourcesContent": Array [ + ".foo{color:red;}", + ".foo{color:red;} +.bar{color:coral;}", + ], + "version": 3, +} +`; + +exports[`worker should work inputSourceMap as prev: css 1`] = `".foo{color:red}.bar{color:coral}"`; + +exports[`worker should work inputSourceMap as prev: map 1`] = ` +Object { + "file": "entry.css", + "mappings": "AAAA,KAAK,SAAA,CCCL,KAAK,WAAY", + "names": Array [], + "sources": Array [ + "foo.css", + "entry.css", + ], + "sourcesContent": Array [ + ".foo{color:red;}", + ".foo{color:red;} +.bar{color:coral;}", + ], + "version": 3, +} +`; + +exports[`worker should work options.minify function: css 1`] = `".minify {};"`; + +exports[`worker should work options.minify function: map 1`] = `undefined`; diff --git a/test/cache-option.test.js b/test/cache-option.test.js new file mode 100644 index 0000000..17d45c4 --- /dev/null +++ b/test/cache-option.test.js @@ -0,0 +1,329 @@ +import cacache from 'cacache'; +import findCacheDir from 'find-cache-dir'; + +import Webpack4Cache from '../src/Webpack4Cache'; +import CssnanoPlugin from '../src/index'; + +import { + compile, + getCompiler, + getErrors, + getWarnings, + readAssets, + removeCache, +} from './helpers'; + +const uniqueCacheDirectory = findCacheDir({ name: 'unique-cache-directory' }); +const uniqueOtherDirectory = findCacheDir({ + name: 'unique-other-cache-directory', +}); +const otherCacheDir = findCacheDir({ name: 'other-cache-directory' }); +const otherOtherCacheDir = findCacheDir({ + name: 'other-other-cache-directory', +}); +const otherOtherOtherCacheDir = findCacheDir({ + name: 'other-other-other-cache-directory', +}); + +jest.setTimeout(30000); + +if (getCompiler.isWebpack4()) { + describe('cache option', () => { + let compiler; + + beforeEach(() => { + compiler = getCompiler({ + entry: { + one: `${__dirname}/fixtures/cache.js`, + two: `${__dirname}/fixtures/cache-1.js`, + three: `${__dirname}/fixtures/cache-2.js`, + four: `${__dirname}/fixtures/cache-3.js`, + five: `${__dirname}/fixtures/cache-4.js`, + }, + }); + + return Promise.all([ + removeCache(), + removeCache(uniqueCacheDirectory), + removeCache(uniqueOtherDirectory), + removeCache(otherCacheDir), + removeCache(otherOtherCacheDir), + removeCache(otherOtherOtherCacheDir), + ]); + }); + + afterEach(() => { + return Promise.all([ + removeCache(), + removeCache(uniqueCacheDirectory), + removeCache(uniqueOtherDirectory), + removeCache(otherCacheDir), + removeCache(otherOtherCacheDir), + removeCache(otherOtherOtherCacheDir), + ]); + }); + + it('should match snapshot when a value is not specify', async () => { + const cacacheGetSpy = jest.spyOn(cacache, 'get'); + const cacachePutSpy = jest.spyOn(cacache, 'put'); + + const getCacheDirectorySpy = jest + .spyOn(Webpack4Cache, 'getCacheDirectory') + .mockImplementation(() => uniqueCacheDirectory); + + new CssnanoPlugin().apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + const countAssets = Object.keys(readAssets(compiler, stats, '.css')) + .length; + + // Try to found cached files, but we don't have their in cache + expect(cacacheGetSpy).toHaveBeenCalledTimes(countAssets); + // Put files in cache + expect(cacachePutSpy).toHaveBeenCalledTimes(countAssets); + + cacache.get.mockClear(); + cacache.put.mockClear(); + + const newStats = await compile(compiler); + + expect(readAssets(compiler, newStats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + const newCountAssets = Object.keys(readAssets(compiler, newStats, '.css')) + .length; + + // Now we have cached files so we get them and don't put new + expect(cacacheGetSpy).toHaveBeenCalledTimes(newCountAssets); + expect(cacachePutSpy).toHaveBeenCalledTimes(0); + + cacacheGetSpy.mockRestore(); + cacachePutSpy.mockRestore(); + getCacheDirectorySpy.mockRestore(); + }); + + it('should match snapshot for the "false" value', async () => { + const cacacheGetSpy = jest.spyOn(cacache, 'get'); + const cacachePutSpy = jest.spyOn(cacache, 'put'); + + new CssnanoPlugin({ cache: false }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + // Cache disabled so we don't run `get` or `put` + expect(cacacheGetSpy).toHaveBeenCalledTimes(0); + expect(cacachePutSpy).toHaveBeenCalledTimes(0); + + cacacheGetSpy.mockRestore(); + cacachePutSpy.mockRestore(); + }); + + it('should match snapshot for the "true" value', async () => { + const cacacheGetSpy = jest.spyOn(cacache, 'get'); + const cacachePutSpy = jest.spyOn(cacache, 'put'); + + const getCacheDirectorySpy = jest + .spyOn(Webpack4Cache, 'getCacheDirectory') + .mockImplementation(() => { + return uniqueOtherDirectory; + }); + + new CssnanoPlugin({ cache: true }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + const countAssets = Object.keys(readAssets(compiler, stats, '.css')) + .length; + + // Try to found cached files, but we don't have their in cache + expect(cacacheGetSpy).toHaveBeenCalledTimes(countAssets); + // Put files in cache + expect(cacachePutSpy).toHaveBeenCalledTimes(countAssets); + + cacache.get.mockClear(); + cacache.put.mockClear(); + + const newStats = await compile(compiler); + + expect(readAssets(compiler, newStats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + const newCountAssets = Object.keys(readAssets(compiler, newStats, '.css')) + .length; + + // Now we have cached files so we get them and don't put new + expect(cacacheGetSpy).toHaveBeenCalledTimes(newCountAssets); + expect(cacachePutSpy).toHaveBeenCalledTimes(0); + + cacacheGetSpy.mockRestore(); + cacachePutSpy.mockRestore(); + getCacheDirectorySpy.mockRestore(); + }); + + it('should match snapshot for the "other-cache-directory" value', async () => { + const cacacheGetSpy = jest.spyOn(cacache, 'get'); + const cacachePutSpy = jest.spyOn(cacache, 'put'); + + new CssnanoPlugin({ cache: otherCacheDir }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + const countAssets = Object.keys(readAssets(compiler, stats, '.css')) + .length; + + // Try to found cached files, but we don't have their in cache + expect(cacacheGetSpy).toHaveBeenCalledTimes(countAssets); + // Put files in cache + expect(cacachePutSpy).toHaveBeenCalledTimes(countAssets); + + cacache.get.mockClear(); + cacache.put.mockClear(); + + const newStats = await compile(compiler); + + expect(readAssets(compiler, newStats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + const newCountAssets = Object.keys(readAssets(compiler, newStats, '.css')) + .length; + + // Now we have cached files so we get them and don't put new + expect(cacacheGetSpy).toHaveBeenCalledTimes(newCountAssets); + expect(cacachePutSpy).toHaveBeenCalledTimes(0); + + cacacheGetSpy.mockRestore(); + cacachePutSpy.mockRestore(); + }); + + it('should match snapshot when "cacheKey" is custom "function"', async () => { + const cacacheGetSpy = jest.spyOn(cacache, 'get'); + const cacachePutSpy = jest.spyOn(cacache, 'put'); + + new CssnanoPlugin({ + cache: otherOtherCacheDir, + cacheKeys: (defaultCacheKeys, file) => { + // eslint-disable-next-line no-param-reassign + defaultCacheKeys.myCacheKey = 1; + // eslint-disable-next-line no-param-reassign + defaultCacheKeys.myCacheKeyBasedOnFile = `file-${file}`; + + return defaultCacheKeys; + }, + }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + const countAssets = Object.keys(readAssets(compiler, stats, '.css')) + .length; + + // Try to found cached files, but we don't have their in cache + expect(cacacheGetSpy).toHaveBeenCalledTimes(countAssets); + // Put files in cache + expect(cacachePutSpy).toHaveBeenCalledTimes(countAssets); + + cacache.get.mockClear(); + cacache.put.mockClear(); + + const newStats = await compile(compiler); + + expect(readAssets(compiler, newStats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + const newCountAssets = Object.keys(readAssets(compiler, newStats, '.css')) + .length; + + // Now we have cached files so we get them and don't put new + expect(cacacheGetSpy).toHaveBeenCalledTimes(newCountAssets); + expect(cacachePutSpy).toHaveBeenCalledTimes(0); + + cacacheGetSpy.mockRestore(); + cacachePutSpy.mockRestore(); + }); + + it('should match snapshot and invalid cache when entry point was renamed', async () => { + const cacacheGetSpy = jest.spyOn(cacache, 'get'); + const cacachePutSpy = jest.spyOn(cacache, 'put'); + + const getCacheDirectorySpy = jest + .spyOn(Webpack4Cache, 'getCacheDirectory') + .mockImplementation(() => { + return otherOtherOtherCacheDir; + }); + + new CssnanoPlugin({ cache: true }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + const countAssets = Object.keys(readAssets(compiler, stats, '.css')) + .length; + + // Try to found cached files, but we don't have their in cache + expect(cacacheGetSpy).toHaveBeenCalledTimes(countAssets); + // Put files in cache + expect(cacachePutSpy).toHaveBeenCalledTimes(countAssets); + + cacache.get.mockClear(); + cacache.put.mockClear(); + + compiler = getCompiler({ + entry: { + onne: `${__dirname}/fixtures/cache.js`, + two: `${__dirname}/fixtures/cache-1.js`, + three: `${__dirname}/fixtures/cache-2.js`, + four: `${__dirname}/fixtures/cache-3.js`, + five: `${__dirname}/fixtures/cache-4.js`, + }, + }); + + new CssnanoPlugin({ cache: true }).apply(compiler); + + const newStats = await compile(compiler); + + expect(readAssets(compiler, newStats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + const newCountAssets = Object.keys(readAssets(compiler, newStats, '.css')) + .length; + + // Now we have cached files so we get them and don't put new + expect(cacacheGetSpy).toHaveBeenCalledTimes(newCountAssets); + expect(cacachePutSpy).toHaveBeenCalledTimes(1); + + cacacheGetSpy.mockRestore(); + cacachePutSpy.mockRestore(); + getCacheDirectorySpy.mockRestore(); + }); + }); +} else { + test.skip('skip it', () => {}); +} diff --git a/test/cjs.test.js b/test/cjs.test.js new file mode 100644 index 0000000..3893b51 --- /dev/null +++ b/test/cjs.test.js @@ -0,0 +1,8 @@ +import src from '../src'; +import cjs from '../src/cjs'; + +describe('CJS', () => { + it('should export loader', () => { + expect(cjs).toEqual(src); + }); +}); diff --git a/test/cssnanoOptions-option.test.js b/test/cssnanoOptions-option.test.js index 97f22ad..8300c7c 100644 --- a/test/cssnanoOptions-option.test.js +++ b/test/cssnanoOptions-option.test.js @@ -1,18 +1,16 @@ import CssnanoPlugin from '../src/index'; -import { createCompiler, compile } from './compiler'; +import { getCompiler, compile, readAsset, removeCache } from './helpers'; -import { readAsset, removeCache } from './helpers'; +jest.setTimeout(30000); describe('when applied with "cssnanoOptions" option', () => { - jest.setTimeout(30000); - beforeEach(() => Promise.all([removeCache()])); afterEach(() => Promise.all([removeCache()])); it('matches snapshot for "discardComments" option (enable [default])', () => { - const compiler = createCompiler({ + const compiler = getCompiler({ entry: { entry: `${__dirname}/fixtures/cssnanooptions/discardComments.css`, }, @@ -32,7 +30,7 @@ describe('when applied with "cssnanoOptions" option', () => { }); it('matches snapshot for "discardComments" option (disable)', () => { - const compiler = createCompiler({ + const compiler = getCompiler({ entry: { entry: `${__dirname}/fixtures/cssnanooptions/discardComments.css`, }, @@ -56,7 +54,7 @@ describe('when applied with "cssnanoOptions" option', () => { }); it('matches snapshot for "discardComments" option (enable, with "removeAll" option)', () => { - const compiler = createCompiler({ + const compiler = getCompiler({ entry: { entry: `${__dirname}/fixtures/cssnanooptions/discardComments.css`, }, @@ -80,7 +78,7 @@ describe('when applied with "cssnanoOptions" option', () => { }); it('matches snapshot for "mergeRules" option (enable [default])', () => { - const compiler = createCompiler({ + const compiler = getCompiler({ entry: { entry: `${__dirname}/fixtures/cssnanooptions/mergeRules.css`, }, @@ -100,7 +98,7 @@ describe('when applied with "cssnanoOptions" option', () => { }); it('matches snapshot for "mergeRules" option (disable)', () => { - const compiler = createCompiler({ + const compiler = getCompiler({ entry: { entry: `${__dirname}/fixtures/cssnanooptions/mergeRules.css`, }, @@ -124,7 +122,7 @@ describe('when applied with "cssnanoOptions" option', () => { }); it('matches snapshot for "discardEmpty" option (enable [default])', () => { - const compiler = createCompiler({ + const compiler = getCompiler({ entry: { entry: `${__dirname}/fixtures/cssnanooptions/discardEmpty.css`, }, @@ -144,7 +142,7 @@ describe('when applied with "cssnanoOptions" option', () => { }); it('matches snapshot for "discardEmpty" option (disable)', () => { - const compiler = createCompiler({ + const compiler = getCompiler({ entry: { entry: `${__dirname}/fixtures/cssnanooptions/discardEmpty.css`, }, diff --git a/test/exclude-option.test.js b/test/exclude-option.test.js new file mode 100644 index 0000000..7fc8a98 --- /dev/null +++ b/test/exclude-option.test.js @@ -0,0 +1,76 @@ +import CssnanoPlugin from '../src/index'; + +import { + compile, + getCompiler, + getErrors, + getWarnings, + readAssets, + removeCache, +} from './helpers'; + +describe('exclude option', () => { + let compiler; + + beforeEach(() => { + compiler = getCompiler({ + entry: { + excluded1: `${__dirname}/fixtures/excluded1.js`, + excluded2: `${__dirname}/fixtures/excluded2.js`, + entry: `${__dirname}/fixtures/entry.js`, + }, + }); + + return Promise.all([removeCache()]); + }); + + afterEach(() => Promise.all([removeCache()])); + + it('should match snapshot for a single RegExp value excluded1', async () => { + new CssnanoPlugin({ + exclude: /excluded1/i, + }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); + + it('should match snapshot for a single String value excluded1', async () => { + new CssnanoPlugin({ + exclude: 'excluded1', + }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); + + it('should match snapshot for multiple RegExp values excluded1 and excluded2', async () => { + new CssnanoPlugin({ + exclude: [/excluded1/i, /excluded2/i], + }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); + + it('should match snapshot for multiple String values excluded1 and excluded2', async () => { + new CssnanoPlugin({ + exclude: ['excluded1', 'excluded2'], + }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); +}); diff --git a/test/fixtures/cache-1.js b/test/fixtures/cache-1.js new file mode 100644 index 0000000..4d630e8 --- /dev/null +++ b/test/fixtures/cache-1.js @@ -0,0 +1,3 @@ +import css from './test/foo.css'; + +module.exports = css; diff --git a/test/fixtures/cache-2.js b/test/fixtures/cache-2.js new file mode 100644 index 0000000..d116312 --- /dev/null +++ b/test/fixtures/cache-2.js @@ -0,0 +1,3 @@ +import css from './test/bar1.css'; + +module.exports = css; diff --git a/test/fixtures/cache-3.js b/test/fixtures/cache-3.js new file mode 100644 index 0000000..4d4f1fe --- /dev/null +++ b/test/fixtures/cache-3.js @@ -0,0 +1,3 @@ +import css from './test/bar2.css'; + +module.exports = css; diff --git a/test/fixtures/cache-4.js b/test/fixtures/cache-4.js new file mode 100644 index 0000000..d116312 --- /dev/null +++ b/test/fixtures/cache-4.js @@ -0,0 +1,3 @@ +import css from './test/bar1.css'; + +module.exports = css; diff --git a/test/fixtures/cache.js b/test/fixtures/cache.js new file mode 100644 index 0000000..4d630e8 --- /dev/null +++ b/test/fixtures/cache.js @@ -0,0 +1,3 @@ +import css from './test/foo.css'; + +module.exports = css; diff --git a/test/fixtures/entry.js b/test/fixtures/entry.js new file mode 100644 index 0000000..b73ef60 --- /dev/null +++ b/test/fixtures/entry.js @@ -0,0 +1,3 @@ +import css from './foo.css'; + +module.exports = css; diff --git a/test/fixtures/excluded1.js b/test/fixtures/excluded1.js new file mode 100644 index 0000000..4d630e8 --- /dev/null +++ b/test/fixtures/excluded1.js @@ -0,0 +1,3 @@ +import css from './test/foo.css'; + +module.exports = css; diff --git a/test/fixtures/excluded2.js b/test/fixtures/excluded2.js new file mode 100644 index 0000000..d116312 --- /dev/null +++ b/test/fixtures/excluded2.js @@ -0,0 +1,3 @@ +import css from './test/bar1.css'; + +module.exports = css; diff --git a/test/fixtures/included1.js b/test/fixtures/included1.js new file mode 100644 index 0000000..4d630e8 --- /dev/null +++ b/test/fixtures/included1.js @@ -0,0 +1,3 @@ +import css from './test/foo.css'; + +module.exports = css; diff --git a/test/fixtures/included2.js b/test/fixtures/included2.js new file mode 100644 index 0000000..d116312 --- /dev/null +++ b/test/fixtures/included2.js @@ -0,0 +1,3 @@ +import css from './test/bar1.css'; + +module.exports = css; diff --git a/test/fixtures/test/error.css b/test/fixtures/test/error.css new file mode 100644 index 0000000..19765bd --- /dev/null +++ b/test/fixtures/test/error.css @@ -0,0 +1 @@ +null diff --git a/test/helpers/compile.js b/test/helpers/compile.js new file mode 100644 index 0000000..a7fb43b --- /dev/null +++ b/test/helpers/compile.js @@ -0,0 +1,8 @@ +export default function compile(compiler) { + return new Promise((resolve, reject) => { + compiler.run((err, stats) => { + if (err) return reject(err); + return resolve(stats); + }); + }); +} diff --git a/test/compiler.js b/test/helpers/getCompiler.js similarity index 75% rename from test/compiler.js rename to test/helpers/getCompiler.js index 834ffc8..f27d59f 100644 --- a/test/compiler.js +++ b/test/helpers/getCompiler.js @@ -4,26 +4,18 @@ import webpack from 'webpack'; import MiniCssExtractPlugin from 'mini-css-extract-plugin'; import { createFsFromVolume, Volume } from 'memfs'; -module.exports.compile = (compiler) => { - return new Promise((resolve, reject) => { - compiler.run((err, stats) => { - if (err) return reject(err); - return resolve(stats); - }); - }); -}; - -module.exports.createCompiler = (options) => { +export default function getCompiler(options) { const compiler = webpack({ mode: 'production', bail: true, - cache: false, + cache: getCompiler.isWebpack4() ? false : { type: 'memory' }, optimization: { minimize: false, + noEmitOnErrors: false, }, output: { pathinfo: false, - path: `${__dirname}/dist`, + path: path.resolve(__dirname, 'dist'), filename: '[name].js', chunkFilename: '[id].[name].js', }, @@ -51,4 +43,6 @@ module.exports.createCompiler = (options) => { compiler.outputFileSystem = outputFileSystem; return compiler; -}; +} + +getCompiler.isWebpack4 = () => webpack.version[0] === '4'; diff --git a/test/helpers/getErrors.js b/test/helpers/getErrors.js new file mode 100644 index 0000000..085bae5 --- /dev/null +++ b/test/helpers/getErrors.js @@ -0,0 +1,5 @@ +import normalizeErrors from './normalizeErrors'; + +export default (stats) => { + return normalizeErrors(stats.compilation.errors).sort(); +}; diff --git a/test/helpers/getWarnings.js b/test/helpers/getWarnings.js new file mode 100644 index 0000000..9e09c82 --- /dev/null +++ b/test/helpers/getWarnings.js @@ -0,0 +1,5 @@ +import normalizeErrors from './normalizeErrors'; + +export default (stats) => { + return normalizeErrors(stats.compilation.warnings).sort(); +}; diff --git a/test/helpers/index.js b/test/helpers/index.js index 1ea198f..31e9ac1 100644 --- a/test/helpers/index.js +++ b/test/helpers/index.js @@ -1,5 +1,21 @@ +import compile from './compile'; +import getCompiler from './getCompiler'; import readAsset from './readAsset'; +import readAssets from './readAssets'; import normalizedSourceMap from './normalizedSourceMap'; import removeCache from './removeCache'; +import getErrors from './getErrors'; +import getWarnings from './getWarnings'; +import normalizeErrors from './normalizeErrors'; -export { readAsset, normalizedSourceMap, removeCache }; +export { + compile, + getCompiler, + readAsset, + readAssets, + normalizedSourceMap, + removeCache, + getErrors, + getWarnings, + normalizeErrors, +}; diff --git a/test/helpers/normalizeErrors.js b/test/helpers/normalizeErrors.js new file mode 100644 index 0000000..c6d0f16 --- /dev/null +++ b/test/helpers/normalizeErrors.js @@ -0,0 +1,19 @@ +function removeCWD(str) { + const isWin = process.platform === 'win32'; + let cwd = process.cwd(); + + if (isWin) { + // eslint-disable-next-line no-param-reassign + str = str.replace(/\\/g, '/'); + // eslint-disable-next-line no-param-reassign + cwd = cwd.replace(/\\/g, '/'); + } + + return str.replace(new RegExp(cwd, 'g'), ''); +} + +export default (errors) => { + return errors.map((error) => + removeCWD(error.toString().split('\n').slice(0, 2).join('\n')) + ); +}; diff --git a/test/helpers/readAssets.js b/test/helpers/readAssets.js new file mode 100644 index 0000000..e625d84 --- /dev/null +++ b/test/helpers/readAssets.js @@ -0,0 +1,15 @@ +import readAsset from './readAsset'; + +export default function readAssets(compiler, stats, extension) { + const assets = {}; + + Object.keys(stats.compilation.assets).forEach((asset) => { + if (typeof extension === 'undefined') { + assets[asset] = readAsset(asset, compiler, stats); + } else if (asset.endsWith(extension)) { + assets[asset] = readAsset(asset, compiler, stats); + } + }); + + return assets; +} diff --git a/test/helpers/snapshotResolver.js b/test/helpers/snapshotResolver.js new file mode 100644 index 0000000..742ee5b --- /dev/null +++ b/test/helpers/snapshotResolver.js @@ -0,0 +1,28 @@ +const path = require('path'); + +const webpack = require('webpack'); + +// eslint-disable-next-line global-require +const [webpackVersion] = webpack.version; +const snapshotExtension = `.snap.webpack${webpackVersion}`; + +// eslint-disable-next-line no-console +console.log('Current webpack version:', webpackVersion); + +module.exports = { + resolveSnapshotPath: (testPath) => + path.join( + path.dirname(testPath), + '__snapshots__', + `${path.basename(testPath)}${snapshotExtension}` + ), + resolveTestPath: (snapshotPath) => + snapshotPath + .replace(`${path.sep}__snapshots__`, '') + .slice(0, -snapshotExtension.length), + testPathForConsistencyCheck: path.join( + 'consistency_check', + '__tests__', + 'example.test.js' + ), +}; diff --git a/test/include-option.test.js b/test/include-option.test.js new file mode 100644 index 0000000..c762476 --- /dev/null +++ b/test/include-option.test.js @@ -0,0 +1,76 @@ +import CssnanoPlugin from '../src/index'; + +import { + compile, + getCompiler, + getErrors, + getWarnings, + readAssets, + removeCache, +} from './helpers'; + +describe('include option', () => { + let compiler; + + beforeEach(() => { + compiler = getCompiler({ + entry: { + included1: `${__dirname}/fixtures/included1.js`, + included2: `${__dirname}/fixtures/included2.js`, + entry: `${__dirname}/fixtures/entry.js`, + }, + }); + + return Promise.all([removeCache()]); + }); + + afterEach(() => Promise.all([removeCache()])); + + it('should match snapshot for a single RegExp value included1', async () => { + new CssnanoPlugin({ + include: /included1/i, + }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); + + it('should match snapshot for a single String value included1', async () => { + new CssnanoPlugin({ + include: 'included1', + }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); + + it('should match snapshot for multiple RegExp values included1 and included2', async () => { + new CssnanoPlugin({ + include: [/included1/i, /included2/i], + }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); + + it('should match snapshot for multiple String values included1 and included2', async () => { + new CssnanoPlugin({ + include: ['included1', 'included2'], + }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); +}); diff --git a/test/parallel-option.test.js b/test/parallel-option.test.js new file mode 100644 index 0000000..ca9984b --- /dev/null +++ b/test/parallel-option.test.js @@ -0,0 +1,252 @@ +import os from 'os'; + +import Worker from 'jest-worker'; + +import CssnanoPlugin from '../src/index'; + +import { + compile, + getCompiler, + getErrors, + getWarnings, + readAssets, + removeCache, +} from './helpers'; + +jest.mock('os', () => { + const actualOs = jest.requireActual('os'); + + actualOs.cpus = jest.fn(() => { + return { length: 4 }; + }); + + return actualOs; +}); + +// Based on https://github.com/facebook/jest/blob/edde20f75665c2b1e3c8937f758902b5cf28a7b4/packages/jest-runner/src/__tests__/test_runner.test.js +let workerTransform; +let workerEnd; + +jest.mock('jest-worker', () => { + return jest.fn().mockImplementation((workerPath) => { + return { + // eslint-disable-next-line global-require, import/no-dynamic-require + transform: (workerTransform = jest.fn((data) => + // eslint-disable-next-line global-require, import/no-dynamic-require + require(workerPath).transform(data) + )), + end: (workerEnd = jest.fn()), + getStderr: jest.fn(), + getStdout: jest.fn(), + }; + }); +}); + +const workerPath = require.resolve('../src/minify'); + +jest.setTimeout(30000); + +describe('parallel option', () => { + let compiler; + + beforeEach(() => { + jest.clearAllMocks(); + + compiler = getCompiler({ + entry: { + one: `${__dirname}/fixtures/entry.js`, + two: `${__dirname}/fixtures/entry.js`, + three: `${__dirname}/fixtures/entry.js`, + four: `${__dirname}/fixtures/entry.js`, + }, + }); + + return Promise.all([removeCache()]); + }); + + afterEach(() => Promise.all([removeCache()])); + + it('should match snapshot when a value is not specify', async () => { + new CssnanoPlugin().apply(compiler); + + const stats = await compile(compiler); + + expect(Worker).toHaveBeenCalledTimes(1); + expect(Worker).toHaveBeenLastCalledWith(workerPath, { + numWorkers: os.cpus().length - 1, + }); + expect(workerTransform).toHaveBeenCalledTimes( + Object.keys(readAssets(compiler, stats, '.css')).length + ); + expect(workerEnd).toHaveBeenCalledTimes(1); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); + + it('should match snapshot for the "false" value', async () => { + new CssnanoPlugin({ parallel: false }).apply(compiler); + + const stats = await compile(compiler); + + expect(Worker).toHaveBeenCalledTimes(0); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); + + it('should match snapshot for the "true" value', async () => { + new CssnanoPlugin({ parallel: true }).apply(compiler); + + const stats = await compile(compiler); + + expect(Worker).toHaveBeenCalledTimes(1); + expect(Worker).toHaveBeenLastCalledWith(workerPath, { + numWorkers: Math.min(4, os.cpus().length - 1), + }); + expect(workerTransform).toHaveBeenCalledTimes( + Object.keys(readAssets(compiler, stats, '.css')).length + ); + expect(workerEnd).toHaveBeenCalledTimes(1); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); + + it('should match snapshot for the "2" value', async () => { + new CssnanoPlugin({ parallel: 2 }).apply(compiler); + + const stats = await compile(compiler); + + expect(Worker).toHaveBeenCalledTimes(1); + expect(Worker).toHaveBeenLastCalledWith(workerPath, { + numWorkers: 2, + }); + expect(workerTransform).toHaveBeenCalledTimes( + Object.keys(readAssets(compiler, stats, '.css')).length + ); + expect(workerEnd).toHaveBeenCalledTimes(1); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); + + it('should match snapshot for the "true" value when only one file passed', async () => { + compiler = getCompiler({ + entry: `${__dirname}/fixtures/entry.js`, + }); + + new CssnanoPlugin({ parallel: true }).apply(compiler); + + const stats = await compile(compiler); + + expect(Worker).toHaveBeenCalledTimes(1); + expect(Worker).toHaveBeenLastCalledWith(workerPath, { + numWorkers: Math.min(1, os.cpus().length - 1), + }); + expect(workerTransform).toHaveBeenCalledTimes( + Object.keys(readAssets(compiler, stats, '.css')).length + ); + expect(workerEnd).toHaveBeenCalledTimes(1); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); + + it('should match snapshot for the "true" value and the number of files is less than the number of cores', async () => { + const entries = {}; + + for (let i = 0; i < os.cpus().length / 2; i++) { + entries[`entry-${i}`] = `${__dirname}/fixtures/entry.js`; + } + + compiler = getCompiler({ entry: entries }); + + new CssnanoPlugin({ parallel: true }).apply(compiler); + + const stats = await compile(compiler); + + expect(Worker).toHaveBeenCalledTimes(1); + expect(Worker).toHaveBeenLastCalledWith(workerPath, { + numWorkers: Math.min(Object.keys(entries).length, os.cpus().length - 1), + }); + expect(workerTransform).toHaveBeenCalledTimes( + Object.keys(readAssets(compiler, stats, '.css')).length + ); + expect(workerEnd).toHaveBeenCalledTimes(1); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); + + it('should match snapshot for the "true" value and the number of files is same than the number of cores', async () => { + const entries = {}; + + for (let i = 0; i < os.cpus().length; i++) { + entries[`entry-${i}`] = `${__dirname}/fixtures/entry.js`; + } + + compiler = getCompiler({ entry: entries }); + + new CssnanoPlugin({ parallel: true }).apply(compiler); + + const stats = await compile(compiler); + + expect(Worker).toHaveBeenCalledTimes(1); + expect(Worker).toHaveBeenLastCalledWith(workerPath, { + numWorkers: Math.min(Object.keys(entries).length, os.cpus().length - 1), + }); + expect(workerTransform).toHaveBeenCalledTimes( + Object.keys(readAssets(compiler, stats, '.css')).length + ); + expect(workerEnd).toHaveBeenCalledTimes(1); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); + + it('should match snapshot for the "true" value and the number of files is more than the number of cores', async () => { + const entries = {}; + + for (let i = 0; i < os.cpus().length * 2; i++) { + entries[`entry-${i}`] = `${__dirname}/fixtures/entry.js`; + } + + compiler = getCompiler({ + entry: { + one: `${__dirname}/fixtures/entry.js`, + two: `${__dirname}/fixtures/entry.js`, + three: `${__dirname}/fixtures/entry.js`, + four: `${__dirname}/fixtures/entry.js`, + five: `${__dirname}/fixtures/entry.js`, + six: `${__dirname}/fixtures/entry.js`, + seven: `${__dirname}/fixtures/entry.js`, + eight: `${__dirname}/fixtures/entry.js`, + }, + }); + + new CssnanoPlugin({ parallel: true }).apply(compiler); + + const stats = await compile(compiler); + + expect(Worker).toHaveBeenCalledTimes(1); + expect(Worker).toHaveBeenLastCalledWith(workerPath, { + numWorkers: Math.min(Object.keys(entries).length, os.cpus().length - 1), + }); + expect(workerTransform).toHaveBeenCalledTimes( + Object.keys(readAssets(compiler, stats, '.css')).length + ); + expect(workerEnd).toHaveBeenCalledTimes(1); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); +}); diff --git a/test/sourceMap-option.test.js b/test/sourceMap-option.test.js index 33cf124..a06529b 100644 --- a/test/sourceMap-option.test.js +++ b/test/sourceMap-option.test.js @@ -1,15 +1,21 @@ -import MiniCssExtractPlugin from 'mini-css-extract-plugin'; - import webpack from 'webpack'; +import MiniCssExtractPlugin from 'mini-css-extract-plugin'; import CssnanoPlugin from '../src/index'; -import { createCompiler, compile } from './compiler'; +import { + getCompiler, + compile, + readAsset, + normalizedSourceMap, + removeCache, + getErrors, + getWarnings, +} from './helpers'; -import { readAsset, normalizedSourceMap, removeCache } from './helpers'; +jest.setTimeout(30000); describe('when applied with "sourceMap" option', () => { - jest.setTimeout(30000); const baseConfig = { devtool: 'source-map', entry: { @@ -37,7 +43,7 @@ describe('when applied with "sourceMap" option', () => { afterEach(() => Promise.all([removeCache()])); it('matches snapshot for "false" value, without previous sourcemap', () => { - const compiler = createCompiler(baseConfig); + const compiler = getCompiler(baseConfig); new CssnanoPlugin().apply(compiler); return compile(compiler).then((stats) => { @@ -53,7 +59,7 @@ describe('when applied with "sourceMap" option', () => { }); it('matches snapshot for "true" value, without previous sourcemap', () => { - const compiler = createCompiler(baseConfig); + const compiler = getCompiler(baseConfig); new CssnanoPlugin({ sourceMap: true, }).apply(compiler); @@ -93,7 +99,7 @@ describe('when applied with "sourceMap" option', () => { }, }); - const compiler = createCompiler(config); + const compiler = getCompiler(config); new CssnanoPlugin({ sourceMap: false, }).apply(compiler); @@ -126,7 +132,7 @@ describe('when applied with "sourceMap" option', () => { }, }); - const compiler = createCompiler(config); + const compiler = getCompiler(config); new CssnanoPlugin({ sourceMap: true, }).apply(compiler); @@ -151,7 +157,7 @@ describe('when applied with "sourceMap" option', () => { }); it('matches snapshot for "inline" value', () => { - const compiler = createCompiler(baseConfig); + const compiler = getCompiler(baseConfig); new CssnanoPlugin({ sourceMap: { inline: true }, }).apply(compiler); @@ -202,7 +208,7 @@ describe('when applied with "sourceMap" option', () => { ], }); - const compiler = createCompiler(config); + const compiler = getCompiler(config); new CssnanoPlugin({ sourceMap: true, }).apply(compiler); @@ -218,4 +224,69 @@ describe('when applied with "sourceMap" option', () => { } }); }); + + it('should emit warning when broken sourcemap', () => { + const emitBrokenSourceMapPlugin = new (class EmitBrokenSourceMapPlugin { + apply(pluginCompiler) { + pluginCompiler.hooks.compilation.tap( + { name: this.constructor.name }, + (compilation) => { + compilation.hooks.additionalChunkAssets.tap( + { name: this.constructor.name }, + () => { + compilation.additionalChunkAssets.push('broken-source-map.css'); + + const assetContent = '.bar {color: red};'; + + // eslint-disable-next-line no-param-reassign + compilation.assets['broken-source-map.css'] = { + size() { + return assetContent.length; + }, + source() { + return assetContent; + }, + sourceAndMap() { + return { + source: this.source(), + map: { + sources: [], + names: [], + mappings: 'AAAA,KAAK,iBAAiB,KAAK,UAAU,OAAO', + file: 'x', + sourcesContent: [], + }, + }; + }, + }; + } + ); + } + ); + } + })(); + + const config = Object.assign(baseConfig, { + entry: { + entry2: `${__dirname}/fixtures/sourcemap/foo.css`, + }, + plugins: [ + emitBrokenSourceMapPlugin, + new MiniCssExtractPlugin({ + filename: 'dist/[name].css', + chunkFilename: 'dist/[id].[name].css', + }), + ], + }); + + const compiler = getCompiler(config); + new CssnanoPlugin({ + sourceMap: true, + }).apply(compiler); + + return compile(compiler).then((stats) => { + expect(getErrors(stats)).toMatchSnapshot('error'); + expect(getWarnings(stats)).toMatchSnapshot('warning'); + }); + }); }); diff --git a/test/test-option.test.js b/test/test-option.test.js index 7afa5f2..2a647fd 100644 --- a/test/test-option.test.js +++ b/test/test-option.test.js @@ -1,17 +1,16 @@ import CssnanoPlugin from '../src/index'; -import { createCompiler, compile } from './compiler'; +import { getCompiler, compile, readAsset, removeCache } from './helpers'; -import { readAsset, removeCache } from './helpers'; +jest.setTimeout(30000); describe('when applied with "test" option', () => { - jest.setTimeout(30000); let compiler; beforeEach(() => { Promise.all([removeCache()]); - compiler = createCompiler({ + compiler = getCompiler({ entry: { bar1: `${__dirname}/fixtures/test/bar1.css`, bar2: `${__dirname}/fixtures/test/bar2.css`, diff --git a/test/validate-options.test.js b/test/validate-options.test.js index f80ed74..f88dbf8 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -172,6 +172,14 @@ it('validation', () => { new CssnanoWebpackPlugin({ parallel: {} }); }).toThrowErrorMatchingSnapshot(); + expect(() => { + new CssnanoWebpackPlugin({ minify() {} }); + }).not.toThrow(); + + expect(() => { + new CssnanoWebpackPlugin({ minify: true }); + }).toThrowErrorMatchingSnapshot(); + expect(() => { new CssnanoWebpackPlugin({ unknown: true }); }).toThrowErrorMatchingSnapshot(); diff --git a/test/warningsFilter-option.test.js b/test/warningsFilter-option.test.js new file mode 100644 index 0000000..9dfb1cb --- /dev/null +++ b/test/warningsFilter-option.test.js @@ -0,0 +1,63 @@ +import postcss from 'postcss'; + +import CssnanoPlugin from '../src/index'; + +import { + compile, + getCompiler, + getErrors, + getWarnings, + readAssets, + removeCache, +} from './helpers'; + +describe('warningsFilter option', () => { + beforeEach(() => Promise.all([removeCache()])); + + afterEach(() => Promise.all([removeCache()])); + + it('should match snapshot for a "function" value', async () => { + const plugin = postcss.plugin('warning-plugin', () => (css, result) => { + result.warn(`Warning from ${result.opts.from}`, { + plugin: 'warning-plugin', + }); + }); + + const compiler = getCompiler({ + entry: { + foo: `${__dirname}/fixtures/test/foo.css`, + bar1: `${__dirname}/fixtures/test/bar1.css`, + bar2: `${__dirname}/fixtures/test/bar2.css`, + }, + }); + + new CssnanoPlugin({ + parallel: false, + minify: (data) => { + return postcss([plugin]) + .process(data.input, data.postcssOptions) + .then((result) => { + return { + css: result.css, + map: result.map, + error: result.error, + warnings: result.warnings(), + }; + }); + }, + warningsFilter(warning) { + if (/foo/.test(warning.text)) { + return false; + } + + return true; + }, + }).apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); +}); diff --git a/test/worker.test.js b/test/worker.test.js new file mode 100644 index 0000000..30aa6ab --- /dev/null +++ b/test/worker.test.js @@ -0,0 +1,105 @@ +import serialize from 'serialize-javascript'; + +import { transform } from '../src/minify'; + +import { normalizeErrors } from './helpers'; + +describe('worker', () => { + it('should minify css', async () => { + const options = { + input: '.foo{color:red;}\n.bar{color:coral;}', + postcssOptions: { + from: 'entry.css', + to: 'entry.css', + map: { + prev: { + version: 3, + sources: ['foo.css', 'bar.css'], + names: [], + mappings: 'AAAA,KAAK,iBAAiB,KAAK,UAAU,OAAO', + file: 'x', + sourcesContent: ['.foo{color:red;}', '.bar{color:coral;}'], + }, + inline: false, + }, + }, + cssnanoOptions: { discardComments: false }, + }; + const { css, map } = await transform(serialize(options)); + + expect(css).toMatchSnapshot('css'); + expect(map).toMatchSnapshot('map'); + }); + + it('should work inputSourceMap as prev', async () => { + const options = { + input: '.foo{color:red;}\n.bar{color:coral;}', + postcssOptions: { + from: 'entry.css', + to: 'entry.css', + map: { + prev: { + version: 3, + sources: ['foo.css', 'bar.css'], + names: [], + mappings: 'AAAA,KAAK,iBAAiB,KAAK,UAAU,OAAO', + file: 'x', + sourcesContent: ['.foo{color:red;}', '.bar{color:coral;}'], + }, + inline: false, + }, + }, + cssnanoOptions: { discardComments: false }, + inputSourceMap: { + version: 3, + sources: ['foo.css', 'bar.css'], + names: [], + mappings: 'AAAA,KAAK,iBAAiB,KAAK,UAAU,OAAO', + file: 'x', + sourcesContent: ['.foo{color:red;}', '.bar{color:coral;}'], + }, + }; + const { css, map } = await transform(serialize(options)); + + expect(css).toMatchSnapshot('css'); + expect(map).toMatchSnapshot('map'); + }); + + it('should work options.minify function', async () => { + const options = { + input: '.foo{color:red;}\n.bar{color:coral;}', + postcssOptions: { + from: 'entry.css', + to: 'entry.css', + }, + cssnanoOptions: { discardComments: false }, + minify: () => { + return { css: '.minify {};' }; + }, + }; + const { css, map } = await transform(serialize(options)); + + expect(css).toMatchSnapshot('css'); + expect(map).toMatchSnapshot('map'); + }); + + it('should emit error', async () => { + const options = { + input: false, + postcssOptions: { + from: 'entry.css', + to: 'entry.css', + }, + }; + + try { + await transform(serialize(options)); + } catch (error) { + const normalizeError = { ...error }; + + normalizeError.message = [error.message.split('\n')]; + + expect(normalizeErrors(normalizeError.message)).toMatchSnapshot('error'); + } + }); +});