|
5 | 5 | /**
|
6 | 6 | * Functional tests.
|
7 | 7 | *
|
| 8 | + * ## Builds |
| 9 | + * |
8 | 10 | * Build webpack1-4 to actual files, read those in, and then assert against
|
9 | 11 | * "expected" fixtures in `test/expected`.
|
| 12 | + * |
| 13 | + * ## Failures |
| 14 | + * |
| 15 | + * Use `builder` to do multi-process executions and assert against the logged |
| 16 | + * error output. |
10 | 17 | */
|
11 | 18 | const path = require("path");
|
12 | 19 | const pify = require("pify");
|
13 | 20 | const fs = pify(require("fs"));
|
14 | 21 | const expect = require("chai").expect;
|
| 22 | +const cp = require("child_process"); |
| 23 | +const builderCli = require.resolve("builder/bin/builder"); |
15 | 24 |
|
16 | 25 | const BUILD_DIRS = ["build", "build2"];
|
17 | 26 | const WEBPACKS = [1, 2, 3, 4].map((n) => `webpack${n}`); // eslint-disable-line no-magic-numbers
|
18 | 27 |
|
| 28 | +// Detect if node4 + webpack4 so we can skip. |
| 29 | +const isSkipped = (webpack) => webpack === "webpack4" && |
| 30 | + process.version.match(/(v|)([0-9]+)/)[2] === "4"; // eslint-disable-line no-magic-numbers |
| 31 | + |
19 | 32 | // Specific hash regex to abstract.
|
20 | 33 | const HASH_RE = /[0-9a-f]{20}/gm;
|
21 | 34 |
|
@@ -55,31 +68,106 @@ const readBuild = (buildDir) => {
|
55 | 68 | );
|
56 | 69 | };
|
57 | 70 |
|
58 |
| -let expecteds; |
59 |
| -const actuals = {}; |
| 71 | +// Promise-friendly spawn. |
| 72 | +const spawn = function () { |
| 73 | + const stdout = []; |
| 74 | + const stderr = []; |
| 75 | + |
| 76 | + return new Promise((resolve) => { |
| 77 | + const proc = cp.spawn.apply(cp, arguments); // eslint-disable-line prefer-spread |
| 78 | + proc.stdout.on("data", (data) => { |
| 79 | + stdout.push(data.toString()); |
| 80 | + }); |
| 81 | + proc.stderr.on("data", (data) => { |
| 82 | + stderr.push(data.toString()); |
| 83 | + }); |
| 84 | + proc.on("close", (code, signal) => resolve({ |
| 85 | + code, |
| 86 | + signal, |
| 87 | + stdout: stdout.length ? stdout.join("") : null, |
| 88 | + stderr: stderr.length ? stderr.join("") : null |
| 89 | + })); |
| 90 | + }); |
| 91 | +}; |
| 92 | + |
| 93 | +describe("builds", () => { |
| 94 | + let expecteds; |
| 95 | + const actuals = {}; |
60 | 96 |
|
61 |
| -// Read in expected fixtures. |
62 |
| -before(() => readBuild("expected").then((data) => { expecteds = data; })); |
| 97 | + // Read in expected fixtures. |
| 98 | + before(() => readBuild("expected").then((data) => { expecteds = data; })); |
63 | 99 |
|
64 |
| -// Dynamically create suites and tests. |
65 |
| -WEBPACKS.forEach((webpack) => { |
66 |
| - before(() => readBuild(webpack).then((data) => { actuals[webpack] = data; })); |
| 100 | + // Dynamically create suites and tests. |
| 101 | + WEBPACKS.forEach((webpack) => { |
| 102 | + before(() => readBuild(webpack).then((data) => { actuals[webpack] = data; })); |
67 | 103 |
|
68 |
| - describe(webpack, () => { |
69 |
| - it("matches expected files", function () { |
70 |
| - const actual = actuals[webpack]; |
| 104 | + describe(webpack, () => { |
| 105 | + it("matches expected files", function () { |
| 106 | + const actual = actuals[webpack]; |
71 | 107 |
|
72 |
| - // Allow webpack4 to have no files if all other webpacks have the right |
73 |
| - // number of files to account for node4 not being supported. |
74 |
| - if (webpack === "webpack4" && !actual && |
75 |
| - actuals.webpack1 && actuals.webpack2 && actuals.webpack3) { |
76 |
| - // Dynamically skip. |
77 |
| - return void this.skip(); // eslint-disable-line no-invalid-this |
78 |
| - } |
| 108 | + // Allow webpack4 to have no files if all other webpacks have the right |
| 109 | + // number of files to account for node4 not being supported. |
| 110 | + if (isSkipped(webpack)) { |
| 111 | + // Dynamically skip. |
| 112 | + return void this.skip(); // eslint-disable-line no-invalid-this |
| 113 | + } |
79 | 114 |
|
80 |
| - Object.keys(expecteds).forEach((fileKey) => { |
81 |
| - expect(actual[fileKey], fileKey).to.equal(expecteds[fileKey]); |
| 115 | + Object.keys(expecteds).forEach((fileKey) => { |
| 116 | + expect(actual[fileKey], fileKey).to.equal(expecteds[fileKey]); |
| 117 | + }); |
82 | 118 | });
|
83 | 119 | });
|
84 | 120 | });
|
85 | 121 | });
|
| 122 | + |
| 123 | +describe("failures", () => { |
| 124 | + // Dynamically figure out if doing webpack4. |
| 125 | + const VERSIONS = [].concat( |
| 126 | + [{ VERS: 1 }, { VERS: 2 }, { VERS: 3 }], |
| 127 | + isSkipped("webpack4") ? [] : [{ VERS: 4 }] |
| 128 | + ); |
| 129 | + const NUM_ERRS = VERSIONS.length; |
| 130 | + |
| 131 | + it("fails with synchronous error", () => { |
| 132 | + // Use builder to concurrently run: |
| 133 | + // `webpack<VERS> --config test/webpack<VERS>/webpack.config.fail-sync.js` |
| 134 | + return spawn(builderCli, |
| 135 | + [ |
| 136 | + "envs", "test:build:single", |
| 137 | + JSON.stringify(VERSIONS), |
| 138 | + "--env", JSON.stringify({ WP_EXTRA: ".fail-sync" }), |
| 139 | + "--buffer", "--bail=false" |
| 140 | + ] |
| 141 | + ) |
| 142 | + .then((obj) => { |
| 143 | + expect(obj.code).to.equal(1); |
| 144 | + expect(obj.stderr).to.contain(`Hit ${NUM_ERRS} errors`); |
| 145 | + |
| 146 | + const exps = Array(NUM_ERRS).fill("Error: SYNC"); |
| 147 | + const errs = obj.stderr.match(/(Error\: SYNC)/gm); |
| 148 | + expect(errs).to.eql(exps); |
| 149 | + }); |
| 150 | + }); |
| 151 | + |
| 152 | + it("fails with promise rejection", () => { |
| 153 | + // Use builder to concurrently run: |
| 154 | + // `webpack<VERS> --config test/webpack<VERS>/webpack.config.fail-promise.js` |
| 155 | + return spawn(builderCli, |
| 156 | + [ |
| 157 | + "envs", "test:build:single", |
| 158 | + JSON.stringify(VERSIONS), |
| 159 | + "--env", JSON.stringify({ WP_EXTRA: ".fail-promise" }), |
| 160 | + "--buffer", "--bail=false" |
| 161 | + ] |
| 162 | + ) |
| 163 | + .then((obj) => { |
| 164 | + expect(obj.code).to.equal(1); |
| 165 | + expect(obj.stderr).to.contain(`Hit ${NUM_ERRS} errors`); |
| 166 | + |
| 167 | + const exps = Array(NUM_ERRS).fill("Error: PROMISE"); |
| 168 | + const errs = obj.stderr.match(/(Error\: PROMISE)/gm); |
| 169 | + expect(errs).to.eql(exps); |
| 170 | + }); |
| 171 | + }); |
| 172 | + |
| 173 | +}); |
0 commit comments