/
githubmirror
/
webpack
Обзор
Документация
Войти
/
githubmirror
/
webpack
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
test/cssParsing-webpack.spectest.js
163 строки
5 KB
Alexander Akait
test: fail tests on unexpected deprecations (#21245)
23 июн 2026, 01:28
Не верифицирован
23 июн 2026, 01:28
743256f
Код
Авторство
О чём код?
"use strict"; // Compiles every css-parsing-tests input as a webpack CSS entry to confirm the // full pipeline (parse, AST, handle, generate) handles the corpus without // crashing, in both development and production mode. One test per input per mode // reports the result; the builds run once in beforeAll, batched into shared // in-memory compilations. @import/url() extraction is off so nothing needs to // resolve — the point is that webpack handles malformed input without crashing // or throwing an internal exception. (Mirrors html5lib.spectest.js; // only fixture loading and the entry type differ.) const fs = require("fs"); const path = require("path"); const { Volume, createFsFromVolume } = require("memfs"); const webpack = require(".."); const expectNoDeprecations = require("./helpers/expectNoDeprecations"); const casesDir = path.resolve(__dirname, "./css-parsing-tests"); const MODES = ["development", "production"]; // A graceful webpack error/warning on malformed input is fine; an internal // exception leaking through (parser/generator bug) is not. const INTERNAL = /TypeError|RangeError|Cannot read|is not a function|Maximum call stack|of undefined|of null/; const BATCH = 400; /** * @returns {{ id: string, input: string }[]} every input (handles the `stylesheet_bytes` shape) */ const loadCases = () => { const cases = []; for (const file of fs.readdirSync(casesDir)) { if (!file.endsWith(".json")) continue; const data = JSON.parse(fs.readFileSync(path.join(casesDir, file), "utf8")); let index = 0; // The suite is a flat [input, expected, …] array; inputs are even-indexed. for (const [i, value] of data.entries()) { if (i % 2 !== 0) continue; let input; if (typeof value === "string") { input = value; } else if (value && typeof value.css_bytes === "string") { input = value.css_bytes; } else { continue; } cases.push({ id: `${file} #${index}`, input }); index++; } } return cases; }; /** * Compile a batch of inputs as separate CSS entries in one compilation. * @param {string[]} inputs CSS sources * @param {string} mode webpack mode * @returns {Promise<Map<number, string[]>>} internal-error messages keyed by entry index */ const buildBatch = (inputs, mode) => new Promise((resolve) => { const mfs = createFsFromVolume(new Volume()); mfs.mkdirSync("/src", { recursive: true }); /** @type {Record<string, string>} */ const entry = {}; for (const [i, input] of inputs.entries()) { mfs.writeFileSync(`/src/c${i}.css`, input); entry[`c${i}`] = `./c${i}.css`; } const compiler = webpack({ context: "/src", mode, entry, output: { path: "/out", filename: "[name].js", cssFilename: "[name].css" }, target: "web", experiments: { css: true }, module: { parser: { css: { import: false, url: false } } } }); compiler.inputFileSystem = mfs; compiler.outputFileSystem = mfs; compiler.run((err, stats) => { /** @type {Map<number, string[]>} */ const internalByEntry = new Map(); /** * @param {number} i entry index * @param {string} line message */ const add = (i, line) => { if (!internalByEntry.has(i)) internalByEntry.set(i, []); internalByEntry.get(i).push(line); }; if (err) { // Compiler-level throw can't be attributed to one entry; mark all. const line = String(err.message).split("\n")[0].slice(0, 160); for (const i of inputs.keys()) add(i, line); resolve(internalByEntry); return; } const json = stats.toJson({ errors: true, warnings: true }); for (const item of [...json.errors, ...json.warnings]) { if (!INTERNAL.test(item.message)) continue; const line = item.message.split("\n")[0].slice(0, 160); const match = /c(\d+)\.css/.exec(item.moduleName || ""); if (match) add(Number(match[1]), line); else for (const i of inputs.keys()) add(i, line); } compiler.close(() => resolve(internalByEntry)); }); }); const cases = fs.existsSync(casesDir) && fs.readdirSync(casesDir).length > 0 ? loadCases() : []; expectNoDeprecations(); describe("css-parsing-tests webpack build", () => { /** @type {Map<string, Map<string, string[]>>} */ const internalByMode = new Map(); beforeAll(async () => { for (const mode of MODES) { /** @type {Map<string, string[]>} */ const byId = new Map(); let pending = []; const flush = async () => { const inputs = []; for (const c of pending) inputs.push(c.input); const internalByEntry = await buildBatch(inputs, mode); for (const [k, c] of pending.entries()) { byId.set(c.id, internalByEntry.get(k) || []); } pending = []; }; for (const c of cases) { pending.push(c); if (pending.length === BATCH) await flush(); } if (pending.length > 0) await flush(); internalByMode.set(mode, byId); } }, 600000); if (cases.length === 0) { it("submodule not initialized (run `git submodule update --init test/css-parsing-tests`)", () => { // No-op: the conformance data is an optional git submodule. }); return; } for (const mode of MODES) { for (const { id } of cases) { it(`${id} (${mode})`, () => { expect(internalByMode.get(mode).get(id)).toEqual([]); }); } } });