Use published jest-light-runner (#12592)
This commit is contained in:
1 parent
3cbee742a7
commit
637c00618c
12 files changed
+26
-373
No files matched your search
@@ -3,7 +3,6 @@
|
||||
/tests/format/**/*.js
|
||||
/tests/integration/cli/
|
||||
!/tests/format/**/jsfmt.spec.js
|
||||
/tests/config/jest-light-runner/**/*
|
||||
!/**/.eslintrc.js
|
||||
/test*.*
|
||||
/scripts/release/node_modules
|
||||
|
||||
@@ -7,7 +7,6 @@ coverage/
|
||||
/tests/integration/cli/
|
||||
/tests/integration/plugins/
|
||||
/tests/integration/custom-parsers/
|
||||
/tests/config/jest-light-runner/**/*
|
||||
/website/build/
|
||||
/website/static/lib/
|
||||
/website/static/playground.js
|
||||
|
||||
+2
-1
@@ -215,6 +215,7 @@
|
||||
"neoclide",
|
||||
"neoformat",
|
||||
"neovim",
|
||||
"nicolo",
|
||||
"nocheck",
|
||||
"nnoremap",
|
||||
"nonenumerable",
|
||||
@@ -276,6 +277,7 @@
|
||||
"regexes",
|
||||
"Reimplement",
|
||||
"rhengles",
|
||||
"ribaudo",
|
||||
"Roadmap",
|
||||
"Rubocop",
|
||||
"ruleset",
|
||||
@@ -391,7 +393,6 @@
|
||||
".git",
|
||||
"cspell.json",
|
||||
"*.{log,svg,snap,png}",
|
||||
"tests/config/jest-light-runner/**/*",
|
||||
"website/data/users.yml",
|
||||
"website/build/**",
|
||||
"website/playground/codeSamples.mjs",
|
||||
|
||||
@@ -2,7 +2,7 @@ import baseConfig from "./jest.config.mjs";
|
||||
|
||||
const config = {
|
||||
...baseConfig,
|
||||
runner: "./tests/config/jest-light-runner",
|
||||
runner: "jest-light-runner",
|
||||
testRegex: "tests/format/.*/jsfmt\\.spec\\.js$",
|
||||
setupFiles: ["<rootDir>/tests/config/format-test-setup.js"],
|
||||
projects: [],
|
||||
|
||||
+1
-1
@@ -99,7 +99,6 @@
|
||||
"@esbuild-plugins/node-modules-polyfill": "0.1.4",
|
||||
"@glimmer/reference": "0.84.1",
|
||||
"@jest/globals": "27.4.2",
|
||||
"@prettier/jest-light-runner": "file:./tests/config/jest-light-runner",
|
||||
"@types/estree": "0.0.51",
|
||||
"@types/jest": "27.4.1",
|
||||
"@typescript-eslint/eslint-plugin": "5.17.0",
|
||||
@@ -124,6 +123,7 @@
|
||||
"esm-utils": "3.0.0",
|
||||
"execa": "6.1.0",
|
||||
"jest": "27.5.1",
|
||||
"jest-light-runner": "nicolo-ribaudo/jest-light-runner#1c31422",
|
||||
"jest-snapshot-serializer-ansi": "1.0.0",
|
||||
"jest-snapshot-serializer-raw": "1.2.0",
|
||||
"jest-watch-typeahead": "1.0.0",
|
||||
|
||||
@@ -14,6 +14,4 @@ async function setup() {
|
||||
globalThis.run_spec = runSpec;
|
||||
}
|
||||
|
||||
// `await`ed in `./jest-light-runner/worker-runner.js`
|
||||
// Use top-level await in `./prettier-entry.js` when we drop support for Node.js 12
|
||||
export { setup };
|
||||
export default setup;
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"name": "@prettier/jest-light-runner",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./src/index.js",
|
||||
"exports": {
|
||||
".": "./src/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"expect": "^27.4.0",
|
||||
"jest-circus": "^27.4.0",
|
||||
"jest-each": "^27.4.0",
|
||||
"jest-mock": "^27.4.0",
|
||||
"jest-snapshot": "^27.4.0",
|
||||
"piscina": "^3.1.0",
|
||||
"supports-color": "^9.0.2"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
> This package is copied from https://github.com/babel/babel/tree/main/test/jest-light-runner
|
||||
|
||||
Modifications:
|
||||
|
||||
- Added `setupFiles` support
|
||||
- Added `snapshotSerializers` support
|
||||
@@ -1,27 +0,0 @@
|
||||
/* eslint-disable import/extensions */
|
||||
|
||||
import mock from "jest-mock";
|
||||
import expect from "expect";
|
||||
import snapshot from "jest-snapshot";
|
||||
import * as circus from "jest-circus";
|
||||
|
||||
expect.extend({
|
||||
toMatchInlineSnapshot: snapshot.toMatchInlineSnapshot,
|
||||
toMatchSnapshot: snapshot.toMatchSnapshot,
|
||||
toThrowErrorMatchingInlineSnapshot:
|
||||
snapshot.toThrowErrorMatchingInlineSnapshot,
|
||||
toThrowErrorMatchingSnapshot: snapshot.toThrowErrorMatchingSnapshot,
|
||||
});
|
||||
|
||||
globalThis.expect = expect;
|
||||
globalThis.test = circus.test;
|
||||
globalThis.it = circus.it;
|
||||
globalThis.describe = circus.describe;
|
||||
globalThis.beforeAll = circus.beforeAll;
|
||||
globalThis.afterAll = circus.afterAll;
|
||||
globalThis.beforeEach = circus.beforeEach;
|
||||
globalThis.afterEach = circus.afterEach;
|
||||
globalThis.jest = {
|
||||
fn: mock.fn,
|
||||
spyOn: mock.spyOn,
|
||||
};
|
||||
@@ -1,54 +0,0 @@
|
||||
import { Piscina } from "piscina";
|
||||
import supportsColor from "supports-color";
|
||||
import { MessageChannel } from "worker_threads";
|
||||
import os from "os";
|
||||
|
||||
/** @typedef {import("@jest/test-result").Test} Test */
|
||||
|
||||
const piscina = new Piscina({
|
||||
filename: new URL("./worker-runner.js", import.meta.url).href,
|
||||
maxThreads: os.cpus().length / 2,
|
||||
env: {
|
||||
// Workers don't have a tty; we whant them to inherit
|
||||
// the color support level from the main thread.
|
||||
FORCE_COLOR: supportsColor.stdout.level,
|
||||
...process.env,
|
||||
},
|
||||
});
|
||||
|
||||
export default class LightRunner {
|
||||
#config;
|
||||
|
||||
constructor(config) {
|
||||
this.#config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array<Test>} tests
|
||||
* @param {*} watcher
|
||||
* @param {*} onStart
|
||||
* @param {*} onResult
|
||||
* @param {*} onFailure
|
||||
*/
|
||||
runTests(tests, watcher, onStart, onResult, onFailure) {
|
||||
const { updateSnapshot } = this.#config;
|
||||
|
||||
return Promise.all(
|
||||
tests.map((test) => {
|
||||
const mc = new MessageChannel();
|
||||
mc.port2.onmessage = () => onStart(test);
|
||||
mc.port2.unref();
|
||||
|
||||
return piscina
|
||||
.run(
|
||||
{ test, updateSnapshot, port: mc.port1 },
|
||||
{ transferList: [mc.port1] }
|
||||
)
|
||||
.then(
|
||||
(result) => void onResult(test, result),
|
||||
(error) => void onFailure(test, error)
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,239 +0,0 @@
|
||||
import path from "path";
|
||||
import { fileURLToPath, pathToFileURL } from "url";
|
||||
import { performance } from "perf_hooks";
|
||||
import snapshot from "jest-snapshot";
|
||||
import expect from "expect";
|
||||
import * as circus from "jest-circus";
|
||||
|
||||
import "./global-setup.js";
|
||||
|
||||
/** @typedef {{ failures: number, passses: number, pending: number, start: number, end: number }} Stats */
|
||||
/** @typedef {{ ancestors: string[], title: string, errors: Error[], skipped: boolean }} InternalTestResult */
|
||||
|
||||
// Node.js workers (worker_therads) don't support
|
||||
// process.chdir, that we use multiple times in our tests.
|
||||
// We can "polyfill" it for process.cwd() usage, but it
|
||||
// won't affect path.* and fs.* functions.
|
||||
{
|
||||
const startCwd = process.cwd();
|
||||
let cwd = startCwd;
|
||||
process.cwd = () => cwd;
|
||||
process.chdir = dir => {
|
||||
cwd = path.resolve(cwd, dir);
|
||||
};
|
||||
}
|
||||
|
||||
export default async function ({ test, updateSnapshot, port }) {
|
||||
port.postMessage("start");
|
||||
|
||||
const {setupFiles, snapshotSerializers} = test.context.config;
|
||||
for (const path of setupFiles) {
|
||||
const { setup } = await import(pathToFileURL(path));
|
||||
|
||||
if (typeof setup === "function") {
|
||||
await setup();
|
||||
}
|
||||
}
|
||||
for (const path of snapshotSerializers) {
|
||||
const {default: serializer} = await import(pathToFileURL(path));
|
||||
snapshot.addSerializer(serializer);
|
||||
}
|
||||
|
||||
/** @type {Stats} */
|
||||
const stats = { passes: 0, failures: 0, pending: 0, start: 0, end: 0 };
|
||||
/** @type {Array<InternalTestResult>} */
|
||||
const results = [];
|
||||
|
||||
const { tests, hasFocusedTests } = await loadTests(test.path);
|
||||
|
||||
const snapshotState = new snapshot.SnapshotState(
|
||||
`${path.dirname(test.path)}/__snapshots__/${path.basename(test.path)}.snap`,
|
||||
{ prettierPath: "prettier", updateSnapshot }
|
||||
);
|
||||
expect.setState({ snapshotState });
|
||||
|
||||
stats.start = performance.now();
|
||||
await runTestBlock(tests, hasFocusedTests, results, stats);
|
||||
stats.end = performance.now();
|
||||
|
||||
snapshotState._inlineSnapshots.forEach(({ frame }) => {
|
||||
// When using native ESM, errors have an URL location.
|
||||
// Jest expects paths.
|
||||
frame.file = fileURLToPath(frame.file);
|
||||
});
|
||||
snapshotState.save();
|
||||
|
||||
return toTestResult(stats, results, test);
|
||||
}
|
||||
|
||||
async function loadTests(testFile) {
|
||||
circus.resetState();
|
||||
await import(pathToFileURL(testFile));
|
||||
const { rootDescribeBlock, hasFocusedTests } = circus.getState();
|
||||
return { tests: rootDescribeBlock, hasFocusedTests };
|
||||
}
|
||||
|
||||
async function runTestBlock(
|
||||
block,
|
||||
hasFocusedTests,
|
||||
results,
|
||||
stats,
|
||||
ancestors = []
|
||||
) {
|
||||
await runHooks("beforeAll", block, results, stats, ancestors);
|
||||
|
||||
for (const child of block.children) {
|
||||
const { type, mode, fn, name } = child;
|
||||
const nextAncestors = ancestors.concat(name);
|
||||
|
||||
if (
|
||||
mode === "skip" ||
|
||||
(hasFocusedTests && type === "test" && mode !== "only")
|
||||
) {
|
||||
stats.pending++;
|
||||
results.push({ ancestors, title: name, errors: [], skipped: true });
|
||||
} else if (type === "describeBlock") {
|
||||
await runTestBlock(child, hasFocusedTests, results, stats, nextAncestors);
|
||||
} else if (type === "test") {
|
||||
await runHooks("beforeEach", block, results, stats, nextAncestors, true);
|
||||
await runTest(fn, stats, results, ancestors, name);
|
||||
await runHooks("afterEach", block, results, stats, nextAncestors, true);
|
||||
}
|
||||
}
|
||||
|
||||
await runHooks("afterAll", block, results, stats, ancestors);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Function} fn
|
||||
* @param {Stats} stats
|
||||
* @param {Array<InternalTestResult>} results
|
||||
* @param {string[]} ancestors
|
||||
* @param {string} name
|
||||
*/
|
||||
async function runTest(fn, stats, results, ancestors, name) {
|
||||
expect.setState({
|
||||
suppressedErrors: [],
|
||||
currentTestName: ancestors.concat(name).join(" "),
|
||||
});
|
||||
|
||||
const errors = [];
|
||||
await callAsync(fn).catch(error => {
|
||||
errors.push(error);
|
||||
});
|
||||
|
||||
// Get suppressed errors from ``jest-matchers`` that weren't throw during
|
||||
// test execution and add them to the test result, potentially failing
|
||||
// a passing test.
|
||||
const { suppressedErrors } = expect.getState();
|
||||
expect.setState({ suppressedErrors: [] });
|
||||
if (suppressedErrors.length > 0) {
|
||||
errors.unshift(...suppressedErrors);
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
stats.failures++;
|
||||
} else {
|
||||
stats.passes++;
|
||||
}
|
||||
results.push({ ancestors, title: name, errors, skipped: false });
|
||||
}
|
||||
|
||||
async function runHooks(hook, block, results, stats, ancestors, runInParents) {
|
||||
for (const { type, fn } of block.hooks) {
|
||||
if (type === hook) {
|
||||
await callAsync(fn).catch(error => {
|
||||
stats.failures++;
|
||||
results.push({ ancestors, title: `(${hook})`, error, skipped: false });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (block.parent && runInParents) {
|
||||
await runHooks(hook, block.parent, results, stats, ancestors, true);
|
||||
}
|
||||
}
|
||||
|
||||
function callAsync(fn) {
|
||||
if (fn.length >= 1) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fn((err, result) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve().then(fn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Stats} stats
|
||||
* @param {Array<InternalTestResult>} tests
|
||||
* @param {import("@jest/test-result").Test} testInput
|
||||
* @returns {import("@jest/test-result").TestResult}
|
||||
*/
|
||||
function toTestResult(stats, tests, { path, context }) {
|
||||
const { start, end } = stats;
|
||||
const runtime = end - start;
|
||||
|
||||
return {
|
||||
coverage: globalThis.__coverage__,
|
||||
console: null,
|
||||
failureMessage: tests
|
||||
.filter(t => t.errors.length > 0)
|
||||
.map(failureToString)
|
||||
.join("\n"),
|
||||
numFailingTests: stats.failures,
|
||||
numPassingTests: stats.passes,
|
||||
numPendingTests: stats.pending,
|
||||
perfStats: {
|
||||
start,
|
||||
end,
|
||||
runtime: Math.round(runtime), // ms precision
|
||||
slow: runtime / 1000 > context.config.slowTestThreshold,
|
||||
},
|
||||
skipped: false,
|
||||
snapshot: {
|
||||
added: 0,
|
||||
fileDeleted: false,
|
||||
matched: 0,
|
||||
unchecked: 0,
|
||||
unmatched: 0,
|
||||
updated: 0,
|
||||
},
|
||||
sourceMaps: {},
|
||||
testExecError: null,
|
||||
testFilePath: path,
|
||||
testResults: tests.map(test => {
|
||||
return {
|
||||
ancestorTitles: test.ancestors,
|
||||
duration: test.duration / 1000,
|
||||
failureMessages: test.errors.length ? [failureToString(test)] : [],
|
||||
fullName: test.title,
|
||||
numPassingAsserts: test.errors.length > 0 ? 1 : 0,
|
||||
status: test.skipped
|
||||
? "pending"
|
||||
: test.errors.length > 0
|
||||
? "failed"
|
||||
: "passed",
|
||||
title: test.title,
|
||||
};
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
function failureToString(test) {
|
||||
return (
|
||||
test.ancestors.concat(test.title).join(" > ") +
|
||||
"\n" +
|
||||
test.errors.map(e => e.toString().replace(/^/gm, "\t")).join("\n") +
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
@@ -1571,17 +1571,6 @@
|
||||
"@nodelib/fs.scandir" "2.1.5"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@prettier/jest-light-runner@file:./tests/config/jest-light-runner":
|
||||
version "0.0.1"
|
||||
dependencies:
|
||||
expect "^27.4.0"
|
||||
jest-circus "^27.4.0"
|
||||
jest-each "^27.4.0"
|
||||
jest-mock "^27.4.0"
|
||||
jest-snapshot "^27.4.0"
|
||||
piscina "^3.1.0"
|
||||
supports-color "^9.0.2"
|
||||
|
||||
"@simple-dom/interface@^1.4.0":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@simple-dom/interface/-/interface-1.4.0.tgz#e8feea579232017f89b0138e2726facda6fbb71f"
|
||||
@@ -3317,7 +3306,7 @@ exit@^0.1.2:
|
||||
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
|
||||
integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=
|
||||
|
||||
expect@^27.4.0, expect@^27.4.2, expect@^27.5.1:
|
||||
expect@^27.4.2, expect@^27.5.1:
|
||||
version "27.5.1"
|
||||
resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74"
|
||||
integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==
|
||||
@@ -4096,7 +4085,7 @@ jest-changed-files@^27.5.1:
|
||||
execa "^5.0.0"
|
||||
throat "^6.0.1"
|
||||
|
||||
jest-circus@^27.4.0, jest-circus@^27.5.1:
|
||||
jest-circus@^27.5.1:
|
||||
version "27.5.1"
|
||||
resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc"
|
||||
integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==
|
||||
@@ -4196,7 +4185,7 @@ jest-docblock@27.5.1, jest-docblock@^27.5.1:
|
||||
dependencies:
|
||||
detect-newline "^3.0.0"
|
||||
|
||||
jest-each@^27.4.0, jest-each@^27.5.1:
|
||||
jest-each@^27.5.1:
|
||||
version "27.5.1"
|
||||
resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e"
|
||||
integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==
|
||||
@@ -4313,6 +4302,18 @@ jest-leak-detector@^27.5.1:
|
||||
jest-get-type "^27.5.1"
|
||||
pretty-format "^27.5.1"
|
||||
|
||||
jest-light-runner@nicolo-ribaudo/jest-light-runner#1c31422:
|
||||
version "0.1.0"
|
||||
resolved "https://codeload.github.com/nicolo-ribaudo/jest-light-runner/tar.gz/1c3142229d667fe874749ee3fb91e67ef102ab15"
|
||||
dependencies:
|
||||
expect "^27.5.1"
|
||||
jest-circus "^27.5.1"
|
||||
jest-each "^27.5.1"
|
||||
jest-mock "^27.5.1"
|
||||
jest-snapshot "^27.5.1"
|
||||
piscina "^3.1.0"
|
||||
supports-color "^9.2.1"
|
||||
|
||||
jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.0, jest-matcher-utils@^27.5.1:
|
||||
version "27.5.1"
|
||||
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab"
|
||||
@@ -4353,7 +4354,7 @@ jest-message-util@^27.5.1:
|
||||
slash "^3.0.0"
|
||||
stack-utils "^2.0.3"
|
||||
|
||||
jest-mock@^27.4.0, jest-mock@^27.5.1:
|
||||
jest-mock@^27.5.1:
|
||||
version "27.5.1"
|
||||
resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6"
|
||||
integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==
|
||||
@@ -4513,7 +4514,7 @@ jest-snapshot@^27.0.4:
|
||||
pretty-format "^27.5.0"
|
||||
semver "^7.3.2"
|
||||
|
||||
jest-snapshot@^27.4.0, jest-snapshot@^27.5.1:
|
||||
jest-snapshot@^27.5.1:
|
||||
version "27.5.1"
|
||||
resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1"
|
||||
integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==
|
||||
@@ -6289,10 +6290,10 @@ supports-color@^8.0.0:
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
supports-color@^9.0.2:
|
||||
version "9.2.1"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.2.1.tgz#599dc9d45acf74c6176e0d880bab1d7d718fe891"
|
||||
integrity sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ==
|
||||
supports-color@^9.2.1:
|
||||
version "9.2.2"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.2.2.tgz#502acaf82f2b7ee78eb7c83dcac0f89694e5a7bb"
|
||||
integrity sha512-XC6g/Kgux+rJXmwokjm9ECpD6k/smUoS5LKlUCcsYr4IY3rW0XyAympon2RmxGrlnZURMpg5T18gWDP9CsHXFA==
|
||||
|
||||
supports-hyperlinks@^2.0.0:
|
||||
version "2.2.0"
|
||||
|
||||
Reference in new issue
Block a user