headlamp 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +250 -211
- package/dist/cli.cjs.map +4 -4
- package/dist/index.js +252 -213
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -93,7 +93,7 @@ var init_TimeoutError = __esm({
|
|
|
93
93
|
|
|
94
94
|
// node_modules/es-toolkit/dist/promise/delay.mjs
|
|
95
95
|
function delay(ms, { signal } = {}) {
|
|
96
|
-
return new Promise((
|
|
96
|
+
return new Promise((resolve11, reject) => {
|
|
97
97
|
const abortError = () => {
|
|
98
98
|
reject(new AbortError());
|
|
99
99
|
};
|
|
@@ -106,7 +106,7 @@ function delay(ms, { signal } = {}) {
|
|
|
106
106
|
}
|
|
107
107
|
const timeoutId = setTimeout(() => {
|
|
108
108
|
signal?.removeEventListener("abort", abortHandler);
|
|
109
|
-
|
|
109
|
+
resolve11();
|
|
110
110
|
}, ms);
|
|
111
111
|
signal?.addEventListener("abort", abortHandler, { once: true });
|
|
112
112
|
});
|
|
@@ -171,11 +171,11 @@ var init_exec = __esm({
|
|
|
171
171
|
child.stderr?.on("data", (chunk) => {
|
|
172
172
|
stderr += String(chunk);
|
|
173
173
|
});
|
|
174
|
-
const exec = new Promise((
|
|
174
|
+
const exec = new Promise((resolve11, reject) => {
|
|
175
175
|
child.on("error", reject);
|
|
176
176
|
child.on(
|
|
177
177
|
"close",
|
|
178
|
-
(code) => Number(code) === 0 ?
|
|
178
|
+
(code) => Number(code) === 0 ? resolve11(stdout) : reject(new Error(stderr || `exit ${code}`))
|
|
179
179
|
);
|
|
180
180
|
});
|
|
181
181
|
try {
|
|
@@ -195,7 +195,7 @@ var init_exec = __esm({
|
|
|
195
195
|
throw caughtError;
|
|
196
196
|
}
|
|
197
197
|
};
|
|
198
|
-
runExitCode = async (cmd, args, opts = {}) => new Promise((
|
|
198
|
+
runExitCode = async (cmd, args, opts = {}) => new Promise((resolve11, reject) => {
|
|
199
199
|
const child = (0, import_node_child_process.spawn)(cmd, [...args], {
|
|
200
200
|
cwd: opts.cwd,
|
|
201
201
|
env: opts.env,
|
|
@@ -204,9 +204,9 @@ var init_exec = __esm({
|
|
|
204
204
|
windowsHide: true
|
|
205
205
|
});
|
|
206
206
|
child.on("error", reject);
|
|
207
|
-
child.on("close", (code) =>
|
|
207
|
+
child.on("close", (code) => resolve11(Number(code)));
|
|
208
208
|
});
|
|
209
|
-
runWithCapture = async (cmd, args, opts) => new Promise((
|
|
209
|
+
runWithCapture = async (cmd, args, opts) => new Promise((resolve11, reject) => {
|
|
210
210
|
const child = (0, import_node_child_process.spawn)(cmd, [...args], {
|
|
211
211
|
cwd: opts.cwd,
|
|
212
212
|
env: opts.env,
|
|
@@ -222,7 +222,7 @@ var init_exec = __esm({
|
|
|
222
222
|
buf += String(chunk);
|
|
223
223
|
});
|
|
224
224
|
child.on("error", reject);
|
|
225
|
-
child.on("close", (code) =>
|
|
225
|
+
child.on("close", (code) => resolve11({ code: Number(code), output: buf }));
|
|
226
226
|
});
|
|
227
227
|
}
|
|
228
228
|
});
|
|
@@ -736,12 +736,14 @@ __export(fast_related_exports, {
|
|
|
736
736
|
cachedRelated: () => cachedRelated,
|
|
737
737
|
findRelatedTestsFast: () => findRelatedTestsFast
|
|
738
738
|
});
|
|
739
|
-
var path2, fs, TailSegmentCount, EmptyCount, JsonIndentSpaces, DEFAULT_TEST_GLOBS, findRelatedTestsFast, cachedRelated;
|
|
739
|
+
var path2, os2, fs, import_node_crypto, TailSegmentCount, EmptyCount, JsonIndentSpaces, DEFAULT_TEST_GLOBS, findRelatedTestsFast, cachedRelated;
|
|
740
740
|
var init_fast_related = __esm({
|
|
741
741
|
"src/lib/fast-related.ts"() {
|
|
742
742
|
"use strict";
|
|
743
743
|
path2 = __toESM(require("node:path"), 1);
|
|
744
|
+
os2 = __toESM(require("node:os"), 1);
|
|
744
745
|
fs = __toESM(require("node:fs/promises"), 1);
|
|
746
|
+
import_node_crypto = require("node:crypto");
|
|
745
747
|
init_env_utils();
|
|
746
748
|
init_exec();
|
|
747
749
|
TailSegmentCount = 2;
|
|
@@ -790,9 +792,7 @@ var init_fast_related = __esm({
|
|
|
790
792
|
}
|
|
791
793
|
const args = ["-n", "-l", "-S", "-F"];
|
|
792
794
|
testGlobs.forEach((globPattern) => args.push("-g", globPattern));
|
|
793
|
-
excludeGlobs.forEach(
|
|
794
|
-
(excludeGlobPattern) => args.push("-g", `!${excludeGlobPattern}`)
|
|
795
|
-
);
|
|
795
|
+
excludeGlobs.forEach((excludeGlobPattern) => args.push("-g", `!${excludeGlobPattern}`));
|
|
796
796
|
seeds.forEach((seedToken) => args.push("-e", seedToken));
|
|
797
797
|
let raw = "";
|
|
798
798
|
try {
|
|
@@ -804,9 +804,7 @@ var init_fast_related = __esm({
|
|
|
804
804
|
}
|
|
805
805
|
const lines = raw.split(/\r?\n/).map((lineText) => lineText.trim()).filter(Boolean);
|
|
806
806
|
const looksLikeTest = (pathText) => /\.(test|spec)\.[tj]sx?$/i.test(pathText) || /(^|\/)tests?\//i.test(pathText);
|
|
807
|
-
const absolute = lines.map(
|
|
808
|
-
(relativePath) => path2.resolve(repoRoot, relativePath).replace(/\\/g, "/")
|
|
809
|
-
).filter(looksLikeTest);
|
|
807
|
+
const absolute = lines.map((relativePath) => path2.resolve(repoRoot, relativePath).replace(/\\/g, "/")).filter(looksLikeTest);
|
|
810
808
|
const uniq = Array.from(new Set(absolute));
|
|
811
809
|
const results = [];
|
|
812
810
|
await Promise.all(
|
|
@@ -821,17 +819,15 @@ var init_fast_related = __esm({
|
|
|
821
819
|
return results;
|
|
822
820
|
};
|
|
823
821
|
cachedRelated = async (opts) => {
|
|
824
|
-
const
|
|
822
|
+
const cacheRoot = process.env.HEADLAMP_CACHE_DIR || path2.join(os2.tmpdir(), "headlamp-cache");
|
|
823
|
+
const repoKey = (0, import_node_crypto.createHash)("sha1").update(path2.resolve(opts.repoRoot)).digest("hex").slice(0, 12);
|
|
824
|
+
const cacheDir = path2.join(cacheRoot, repoKey);
|
|
825
825
|
const cacheFile = path2.join(cacheDir, "relevant-tests.json");
|
|
826
826
|
let head = "nogit";
|
|
827
827
|
try {
|
|
828
|
-
const raw = await runText(
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
{
|
|
832
|
-
env: safeEnv(process.env, {})
|
|
833
|
-
}
|
|
834
|
-
);
|
|
828
|
+
const raw = await runText("git", ["-C", opts.repoRoot, "rev-parse", "--short", "HEAD"], {
|
|
829
|
+
env: safeEnv(process.env, {})
|
|
830
|
+
});
|
|
835
831
|
head = raw.trim() || "nogit";
|
|
836
832
|
} catch {
|
|
837
833
|
head = "nogit";
|
|
@@ -863,10 +859,7 @@ var init_fast_related = __esm({
|
|
|
863
859
|
try {
|
|
864
860
|
const next = { ...bag, [key]: Array.from(new Set(recomputed)) };
|
|
865
861
|
await fs.mkdir(cacheDir, { recursive: true });
|
|
866
|
-
await fs.writeFile(
|
|
867
|
-
cacheFile,
|
|
868
|
-
JSON.stringify(next, null, JsonIndentSpaces)
|
|
869
|
-
);
|
|
862
|
+
await fs.writeFile(cacheFile, JSON.stringify(next, null, JsonIndentSpaces));
|
|
870
863
|
} catch {
|
|
871
864
|
}
|
|
872
865
|
return recomputed;
|
|
@@ -1987,17 +1980,17 @@ var require_lib = __commonJS({
|
|
|
1987
1980
|
"node_modules/json5/lib/index.js"(exports2, module2) {
|
|
1988
1981
|
var parse = require_parse();
|
|
1989
1982
|
var stringify = require_stringify();
|
|
1990
|
-
var
|
|
1983
|
+
var JSON54 = {
|
|
1991
1984
|
parse,
|
|
1992
1985
|
stringify
|
|
1993
1986
|
};
|
|
1994
|
-
module2.exports =
|
|
1987
|
+
module2.exports = JSON54;
|
|
1995
1988
|
}
|
|
1996
1989
|
});
|
|
1997
1990
|
|
|
1998
1991
|
// src/lib/program.ts
|
|
1999
|
-
var
|
|
2000
|
-
var
|
|
1992
|
+
var path12 = __toESM(require("node:path"), 1);
|
|
1993
|
+
var os3 = __toESM(require("node:os"), 1);
|
|
2001
1994
|
var fsSync3 = __toESM(require("node:fs"), 1);
|
|
2002
1995
|
var fs7 = __toESM(require("node:fs/promises"), 1);
|
|
2003
1996
|
var LibReport = __toESM(require("istanbul-lib-report"), 1);
|
|
@@ -4919,15 +4912,23 @@ var buildMessageSection = (messageLines, details, _ctx, opts) => {
|
|
|
4919
4912
|
const fallbackLines = [];
|
|
4920
4913
|
if (hasOnlyBareError) {
|
|
4921
4914
|
const startFrom = hintIdx >= 0 ? hintIdx + 1 : 0;
|
|
4915
|
+
let started = false;
|
|
4922
4916
|
for (let i = startFrom; i < lines.length; i += 1) {
|
|
4923
4917
|
const candidate = lines[i];
|
|
4924
|
-
if (
|
|
4918
|
+
if (isStackLine(candidate)) {
|
|
4925
4919
|
break;
|
|
4926
4920
|
}
|
|
4927
|
-
if (
|
|
4921
|
+
if (!candidate.trim()) {
|
|
4922
|
+
if (!started) {
|
|
4923
|
+
continue;
|
|
4924
|
+
}
|
|
4928
4925
|
break;
|
|
4929
4926
|
}
|
|
4927
|
+
started = true;
|
|
4930
4928
|
fallbackLines.push(candidate);
|
|
4929
|
+
if (fallbackLines.length >= 6) {
|
|
4930
|
+
break;
|
|
4931
|
+
}
|
|
4931
4932
|
}
|
|
4932
4933
|
if (fallbackLines.length === 0 && details && details.messages && details.messages.length) {
|
|
4933
4934
|
fallbackLines.push(
|
|
@@ -4995,7 +4996,7 @@ var linesFromDetails = (details) => {
|
|
|
4995
4996
|
if (typeof obj.received === "string") {
|
|
4996
4997
|
pushMaybe(obj.received, messages);
|
|
4997
4998
|
}
|
|
4998
|
-
const arrays = ["errors", "causes", "aggregatedErrors"];
|
|
4999
|
+
const arrays = ["errors", "details", "issues", "inner", "causes", "aggregatedErrors"];
|
|
4999
5000
|
for (const key of arrays) {
|
|
5000
5001
|
const arr = obj[key];
|
|
5001
5002
|
if (Array.isArray(arr)) {
|
|
@@ -5004,7 +5005,7 @@ var linesFromDetails = (details) => {
|
|
|
5004
5005
|
}
|
|
5005
5006
|
}
|
|
5006
5007
|
}
|
|
5007
|
-
const nestedCandidates = ["error", "cause", "matcherResult"];
|
|
5008
|
+
const nestedCandidates = ["error", "cause", "matcherResult", "context", "data"];
|
|
5008
5009
|
for (const key of nestedCandidates) {
|
|
5009
5010
|
if (obj[key] && typeof obj[key] === "object") {
|
|
5010
5011
|
visitDeep(obj[key], depth + 1);
|
|
@@ -5033,9 +5034,7 @@ var linesFromDetails = (details) => {
|
|
|
5033
5034
|
pushMaybe(matcher.expected, messages);
|
|
5034
5035
|
pushMaybe(matcher.received, messages);
|
|
5035
5036
|
}
|
|
5036
|
-
|
|
5037
|
-
visitDeep(detail, 0);
|
|
5038
|
-
}
|
|
5037
|
+
visitDeep(detail, 0);
|
|
5039
5038
|
}
|
|
5040
5039
|
}
|
|
5041
5040
|
return { stacks, messages };
|
|
@@ -5099,24 +5098,31 @@ var buildConsoleSection = (maybeConsole) => {
|
|
|
5099
5098
|
var buildFallbackMessageBlock = (messageLines, details) => {
|
|
5100
5099
|
const normalize2 = (arr) => arr.map((lineText) => stripAnsiSimple(lineText)).filter((line) => line.trim().length > 0);
|
|
5101
5100
|
const normalized = normalize2(messageLines);
|
|
5102
|
-
const informative = normalized.filter(
|
|
5101
|
+
const informative = normalized.filter(
|
|
5102
|
+
(line) => !/^\s*(?:Error|AssertionError):?\s*$/i.test(line)
|
|
5103
|
+
);
|
|
5103
5104
|
if (informative.length > 0) {
|
|
5104
5105
|
return [];
|
|
5105
5106
|
}
|
|
5106
5107
|
const errorIdx = normalized.findIndex(
|
|
5107
|
-
(line) => /(TypeError|ReferenceError|SyntaxError|RangeError|AssertionError|Error)
|
|
5108
|
+
(line) => /(TypeError|ReferenceError|SyntaxError|RangeError|AssertionError|Error):?/i.test(line)
|
|
5108
5109
|
);
|
|
5109
5110
|
const collected = [];
|
|
5110
5111
|
if (errorIdx >= 0) {
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5112
|
+
let started = false;
|
|
5113
|
+
for (let i = errorIdx + 1; i < messageLines.length && collected.length < 8; i += 1) {
|
|
5114
|
+
const raw = stripAnsiSimple(messageLines[i]);
|
|
5115
|
+
if (isStackLine(raw)) {
|
|
5114
5116
|
break;
|
|
5115
5117
|
}
|
|
5116
|
-
if (
|
|
5118
|
+
if (!raw.trim()) {
|
|
5119
|
+
if (!started) {
|
|
5120
|
+
continue;
|
|
5121
|
+
}
|
|
5117
5122
|
break;
|
|
5118
5123
|
}
|
|
5119
|
-
|
|
5124
|
+
started = true;
|
|
5125
|
+
collected.push(raw);
|
|
5120
5126
|
}
|
|
5121
5127
|
}
|
|
5122
5128
|
const fromDetails = collected.length > 0 ? [] : normalize2(details.messages).slice(0, 6);
|
|
@@ -5364,39 +5370,13 @@ var makeCtx = (opts, showStacks = false) => {
|
|
|
5364
5370
|
return { cwd, width, showStacks, projectHint, editorCmd: opts?.editorCmd, readSource: readSource2 };
|
|
5365
5371
|
};
|
|
5366
5372
|
|
|
5367
|
-
// src/lib/formatter/bridge.ts
|
|
5373
|
+
// src/lib/formatter/bridge/tryBridgeFallback.ts
|
|
5368
5374
|
var fs6 = __toESM(require("node:fs"), 1);
|
|
5375
|
+
var path11 = __toESM(require("node:path"), 1);
|
|
5376
|
+
var import_json53 = __toESM(require_lib(), 1);
|
|
5377
|
+
|
|
5378
|
+
// src/lib/formatter/bridge/logic.ts
|
|
5369
5379
|
var path10 = __toESM(require("node:path"), 1);
|
|
5370
|
-
var import_json52 = __toESM(require_lib(), 1);
|
|
5371
|
-
var colorTokens2 = {
|
|
5372
|
-
pass: Colors.Success,
|
|
5373
|
-
fail: Colors.Failure,
|
|
5374
|
-
skip: Colors.Skip,
|
|
5375
|
-
todo: Colors.Todo,
|
|
5376
|
-
passPill: (text) => BackgroundColors.Success(ansi.white(` ${text} `)),
|
|
5377
|
-
failPill: (text) => BackgroundColors.Failure(ansi.white(` ${text} `))
|
|
5378
|
-
};
|
|
5379
|
-
var by = (keySelector) => (left, right) => keySelector(left) - keySelector(right);
|
|
5380
|
-
var isObject = (candidateValue) => !!candidateValue && typeof candidateValue === "object";
|
|
5381
|
-
var asHttpList = (candidateValue) => Array.isArray(candidateValue) ? candidateValue : [];
|
|
5382
|
-
var summarizeUrl = (method, url, route) => {
|
|
5383
|
-
const base = route || url || "";
|
|
5384
|
-
const qs = url && url.includes("?") ? ` ? ${url.split("?")[1]}` : "";
|
|
5385
|
-
return [method || "", base, qs].filter(Boolean).join(" ").trim();
|
|
5386
|
-
};
|
|
5387
|
-
var stripBridgeEventsFromConsole = (maybeConsole) => {
|
|
5388
|
-
if (!Array.isArray(maybeConsole)) {
|
|
5389
|
-
return maybeConsole;
|
|
5390
|
-
}
|
|
5391
|
-
return maybeConsole.filter((entry) => {
|
|
5392
|
-
try {
|
|
5393
|
-
const raw = Array.isArray(entry.message) ? entry.message.map(String).join(" ") : String(entry.message ?? "");
|
|
5394
|
-
return !raw.includes("[JEST-BRIDGE-EVENT]");
|
|
5395
|
-
} catch {
|
|
5396
|
-
return true;
|
|
5397
|
-
}
|
|
5398
|
-
});
|
|
5399
|
-
};
|
|
5400
5380
|
var extractBridgePath2 = (raw, cwd) => {
|
|
5401
5381
|
const matches = Array.from(
|
|
5402
5382
|
raw.matchAll(/Test results written to:\s+([^\n\r]+jest-bridge-[^\s'"]+\.json)/g)
|
|
@@ -5404,7 +5384,7 @@ var extractBridgePath2 = (raw, cwd) => {
|
|
|
5404
5384
|
if (!matches.length) {
|
|
5405
5385
|
return null;
|
|
5406
5386
|
}
|
|
5407
|
-
const jsonPath = (matches[matches.length - 1][1] ?? "").trim().replace(/^["
|
|
5387
|
+
const jsonPath = (matches[matches.length - 1][1] ?? "").trim().replace(/^['"`]|['"`]$/g, "");
|
|
5408
5388
|
return path10.isAbsolute(jsonPath) ? jsonPath : path10.resolve(cwd, jsonPath).replace(/\\/g, "/");
|
|
5409
5389
|
};
|
|
5410
5390
|
var isTransportError = (msg) => {
|
|
@@ -5413,25 +5393,6 @@ var isTransportError = (msg) => {
|
|
|
5413
5393
|
lowercaseMessage
|
|
5414
5394
|
);
|
|
5415
5395
|
};
|
|
5416
|
-
var envNumber = (name, fallback) => {
|
|
5417
|
-
const parsed = Number(process.env[name]);
|
|
5418
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
5419
|
-
};
|
|
5420
|
-
var HEADLAMP_HTTP_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_WINDOW_MS", 3e3);
|
|
5421
|
-
var HEADLAMP_HTTP_STRICT_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_STRICT_WINDOW_MS", 600);
|
|
5422
|
-
var HEADLAMP_HTTP_MIN_SCORE = () => envNumber("HEADLAMP_HTTP_MIN_SCORE", 1200);
|
|
5423
|
-
var HEADLAMP_HTTP_DIFF_LIMIT = () => envNumber("HEADLAMP_HTTP_DIFF_LIMIT", 6);
|
|
5424
|
-
var HEADLAMP_HTTP_SHOW_MISS = () => process.env.HEADLAMP_HTTP_MISS === "1";
|
|
5425
|
-
var eventsNear = (http, ts, testPath, windowMs = HEADLAMP_HTTP_WINDOW_MS()) => {
|
|
5426
|
-
if (typeof ts !== "number" || !Number.isFinite(ts)) {
|
|
5427
|
-
return [];
|
|
5428
|
-
}
|
|
5429
|
-
return http.filter((e) => {
|
|
5430
|
-
const timeOk = typeof e.timestampMs === "number" && Math.abs(e.timestampMs - ts) <= windowMs;
|
|
5431
|
-
const pathOk = !testPath || e.testPath === testPath;
|
|
5432
|
-
return timeOk && pathOk;
|
|
5433
|
-
});
|
|
5434
|
-
};
|
|
5435
5396
|
var parseMethodPathFromTitle = (title) => {
|
|
5436
5397
|
if (!title) {
|
|
5437
5398
|
return {};
|
|
@@ -5439,35 +5400,6 @@ var parseMethodPathFromTitle = (title) => {
|
|
|
5439
5400
|
const matchResult = title.match(/\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\s+([^\s)]+)/i);
|
|
5440
5401
|
return matchResult ? { method: matchResult[1]?.toUpperCase(), path: matchResult[2] } : {};
|
|
5441
5402
|
};
|
|
5442
|
-
var isHttpStatusNumber = (statusNumber) => typeof statusNumber === "number" && statusNumber >= 100 && statusNumber <= 599;
|
|
5443
|
-
var hasStatusSemantics = (assertionLike) => {
|
|
5444
|
-
if (!assertionLike) {
|
|
5445
|
-
return false;
|
|
5446
|
-
}
|
|
5447
|
-
if (isHttpStatusNumber(assertionLike.expectedNumber) || isHttpStatusNumber(assertionLike.receivedNumber)) {
|
|
5448
|
-
return true;
|
|
5449
|
-
}
|
|
5450
|
-
const combinedRaw = `${assertionLike.matcher ?? ""} ${assertionLike.message ?? ""}`;
|
|
5451
|
-
const combinedMessage = combinedRaw.toLowerCase();
|
|
5452
|
-
return /\bstatus(code)?\b|\btohaves(tatus|tatuscode)\b/.test(combinedMessage);
|
|
5453
|
-
};
|
|
5454
|
-
var fileSuggestsHttp = (relPath2) => /(?:^|\/)(routes?|api|controllers?|e2e|integration)(?:\/|\.test\.)/i.test(relPath2);
|
|
5455
|
-
var inferHttpNumbersFromText = (lines) => {
|
|
5456
|
-
const text = lines.join("\n");
|
|
5457
|
-
const match = text.match(/Expected:\s*(\d{3})[\s\S]*?Received:\s*(\d{3})/i);
|
|
5458
|
-
if (match) {
|
|
5459
|
-
return { expectedNumber: Number(match[1]), receivedNumber: Number(match[2]) };
|
|
5460
|
-
}
|
|
5461
|
-
return {};
|
|
5462
|
-
};
|
|
5463
|
-
var titleSuggestsHttp = (title) => {
|
|
5464
|
-
const { method, path: parsedPath } = parseMethodPathFromTitle(title);
|
|
5465
|
-
return Boolean(method || parsedPath && parsedPath.startsWith("/"));
|
|
5466
|
-
};
|
|
5467
|
-
var isHttpRelevant = (ctx) => {
|
|
5468
|
-
const assertionCtx = ctx.assertion;
|
|
5469
|
-
return ctx.hasTransportSignal || ctx.httpCountInSameTest > 0 || titleSuggestsHttp(ctx.title) || hasStatusSemantics(assertionCtx) || fileSuggestsHttp(ctx.relPath);
|
|
5470
|
-
};
|
|
5471
5403
|
var routeSimilarityScore = (hint, evt) => {
|
|
5472
5404
|
if (!hint.path && !hint.method) {
|
|
5473
5405
|
return 0;
|
|
@@ -5488,6 +5420,15 @@ var routeSimilarityScore = (hint, evt) => {
|
|
|
5488
5420
|
}
|
|
5489
5421
|
return methodOk * 10;
|
|
5490
5422
|
};
|
|
5423
|
+
var envNumber = (name, fallback) => {
|
|
5424
|
+
const parsed = Number(process.env[name]);
|
|
5425
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
5426
|
+
};
|
|
5427
|
+
var HEADLAMP_HTTP_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_WINDOW_MS", 3e3);
|
|
5428
|
+
var HEADLAMP_HTTP_STRICT_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_STRICT_WINDOW_MS", 600);
|
|
5429
|
+
var HEADLAMP_HTTP_MIN_SCORE = () => envNumber("HEADLAMP_HTTP_MIN_SCORE", 1200);
|
|
5430
|
+
var HEADLAMP_HTTP_DIFF_LIMIT = () => envNumber("HEADLAMP_HTTP_DIFF_LIMIT", 6);
|
|
5431
|
+
var HEADLAMP_HTTP_SHOW_MISS = () => process.env.HEADLAMP_HTTP_MISS === "1";
|
|
5491
5432
|
var scoreHttpForAssertion = (assertion, titleHint) => (candidateEvent) => {
|
|
5492
5433
|
const tsA = assertion.timestampMs;
|
|
5493
5434
|
const tsH = candidateEvent.timestampMs;
|
|
@@ -5508,14 +5449,20 @@ var pickRelevantHttp = (assertion, http, ctx) => {
|
|
|
5508
5449
|
const windowMs = isTransportError(assertion.message) ? HEADLAMP_HTTP_STRICT_WINDOW_MS() : HEADLAMP_HTTP_WINDOW_MS();
|
|
5509
5450
|
let pool = strictPool;
|
|
5510
5451
|
if (!pool.length) {
|
|
5511
|
-
pool = http.filter(
|
|
5512
|
-
|
|
5513
|
-
|
|
5452
|
+
pool = http.filter((event) => {
|
|
5453
|
+
const samePath = event.testPath === ctx.testPath;
|
|
5454
|
+
const tsA = assertion.timestampMs;
|
|
5455
|
+
const tsH = event.timestampMs;
|
|
5456
|
+
const inWindow = typeof tsA === "number" && typeof tsH === "number" && Math.abs(tsH - tsA) <= windowMs;
|
|
5457
|
+
return samePath && inWindow;
|
|
5458
|
+
});
|
|
5514
5459
|
}
|
|
5515
5460
|
if (!pool.length) {
|
|
5516
|
-
pool = http.filter(
|
|
5517
|
-
|
|
5518
|
-
|
|
5461
|
+
pool = http.filter((event) => {
|
|
5462
|
+
const tsA = assertion.timestampMs;
|
|
5463
|
+
const tsH = event.timestampMs;
|
|
5464
|
+
return typeof tsA === "number" && typeof tsH === "number" && Math.abs(tsH - tsA) <= windowMs;
|
|
5465
|
+
});
|
|
5519
5466
|
}
|
|
5520
5467
|
if (!pool.length) {
|
|
5521
5468
|
return void 0;
|
|
@@ -5525,9 +5472,11 @@ var pickRelevantHttp = (assertion, http, ctx) => {
|
|
|
5525
5472
|
const threshold = isTransportError(assertion.message) ? Math.max(HEADLAMP_HTTP_MIN_SCORE(), 1400) : HEADLAMP_HTTP_MIN_SCORE();
|
|
5526
5473
|
return best && best.s >= threshold ? best.h : void 0;
|
|
5527
5474
|
};
|
|
5528
|
-
|
|
5475
|
+
|
|
5476
|
+
// src/lib/formatter/bridge/utils.ts
|
|
5477
|
+
var import_json52 = __toESM(require_lib(), 1);
|
|
5529
5478
|
var coerceJestJsonToBridge = (raw) => {
|
|
5530
|
-
if (
|
|
5479
|
+
if (raw && typeof raw === "object" && "aggregated" in raw) {
|
|
5531
5480
|
return raw;
|
|
5532
5481
|
}
|
|
5533
5482
|
const j = raw;
|
|
@@ -5554,19 +5503,85 @@ var coerceJestJsonToBridge = (raw) => {
|
|
|
5554
5503
|
}))
|
|
5555
5504
|
})),
|
|
5556
5505
|
aggregated: {
|
|
5557
|
-
numTotalTestSuites:
|
|
5558
|
-
numPassedTestSuites:
|
|
5559
|
-
numFailedTestSuites:
|
|
5560
|
-
numTotalTests:
|
|
5561
|
-
numPassedTests:
|
|
5562
|
-
numFailedTests:
|
|
5563
|
-
numPendingTests:
|
|
5564
|
-
numTodoTests:
|
|
5565
|
-
startTime:
|
|
5566
|
-
success:
|
|
5506
|
+
numTotalTestSuites: raw.numTotalTestSuites,
|
|
5507
|
+
numPassedTestSuites: raw.numPassedTestSuites,
|
|
5508
|
+
numFailedTestSuites: raw.numFailedTestSuites,
|
|
5509
|
+
numTotalTests: raw.numTotalTests,
|
|
5510
|
+
numPassedTests: raw.numPassedTests,
|
|
5511
|
+
numFailedTests: raw.numFailedTests,
|
|
5512
|
+
numPendingTests: raw.numPendingTests,
|
|
5513
|
+
numTodoTests: raw.numTodoTests,
|
|
5514
|
+
startTime: raw.startTime,
|
|
5515
|
+
success: raw.success,
|
|
5516
|
+
runTimeMs: raw.aggregated?.runTimeMs
|
|
5567
5517
|
}
|
|
5568
5518
|
};
|
|
5569
5519
|
};
|
|
5520
|
+
var colorTokens2 = {
|
|
5521
|
+
pass: Colors.Success,
|
|
5522
|
+
fail: Colors.Failure,
|
|
5523
|
+
skip: Colors.Skip,
|
|
5524
|
+
todo: Colors.Todo,
|
|
5525
|
+
passPill: (text) => BackgroundColors.Success(ansi.white(` ${text} `)),
|
|
5526
|
+
failPill: (text) => BackgroundColors.Failure(ansi.white(` ${text} `))
|
|
5527
|
+
};
|
|
5528
|
+
var by = (keySelector) => (left, right) => keySelector(left) - keySelector(right);
|
|
5529
|
+
var isObject = (candidateValue) => !!candidateValue && typeof candidateValue === "object";
|
|
5530
|
+
var asHttpList = (candidateValue) => Array.isArray(candidateValue) ? candidateValue : [];
|
|
5531
|
+
var summarizeUrl = (method, url, route) => {
|
|
5532
|
+
const base = route || url || "";
|
|
5533
|
+
const qs = url && url.includes("?") ? ` ? ${url.split("?")[1]}` : "";
|
|
5534
|
+
return [method || "", base, qs].filter(Boolean).join(" ").trim();
|
|
5535
|
+
};
|
|
5536
|
+
var stripBridgeEventsFromConsole = (maybeConsole) => {
|
|
5537
|
+
if (!Array.isArray(maybeConsole)) {
|
|
5538
|
+
return maybeConsole;
|
|
5539
|
+
}
|
|
5540
|
+
return maybeConsole.filter((entry) => {
|
|
5541
|
+
try {
|
|
5542
|
+
const raw = Array.isArray(entry.message) ? entry.message.map(String).join(" ") : String(entry.message ?? "");
|
|
5543
|
+
return !raw.includes("[JEST-BRIDGE-EVENT]");
|
|
5544
|
+
} catch {
|
|
5545
|
+
return true;
|
|
5546
|
+
}
|
|
5547
|
+
});
|
|
5548
|
+
};
|
|
5549
|
+
var eventsNear = (http, ts, testPath, windowMs = HEADLAMP_HTTP_WINDOW_MS()) => {
|
|
5550
|
+
if (typeof ts !== "number" || !Number.isFinite(ts)) {
|
|
5551
|
+
return [];
|
|
5552
|
+
}
|
|
5553
|
+
return http.filter((event) => {
|
|
5554
|
+
const timeOk = typeof event.timestampMs === "number" && Math.abs(event.timestampMs - ts) <= windowMs;
|
|
5555
|
+
const pathOk = !testPath || event.testPath === testPath;
|
|
5556
|
+
return timeOk && pathOk;
|
|
5557
|
+
});
|
|
5558
|
+
};
|
|
5559
|
+
var isHttpStatusNumber = (statusNumber) => typeof statusNumber === "number" && statusNumber >= 100 && statusNumber <= 599;
|
|
5560
|
+
var inferHttpNumbersFromText = (lines) => {
|
|
5561
|
+
const text = lines.join("\n");
|
|
5562
|
+
const match = text.match(/Expected:\s*(\d{3})[\s\S]*?Received:\s*(\d{3})/i);
|
|
5563
|
+
if (match) {
|
|
5564
|
+
return { expectedNumber: Number(match[1]), receivedNumber: Number(match[2]) };
|
|
5565
|
+
}
|
|
5566
|
+
return {};
|
|
5567
|
+
};
|
|
5568
|
+
var titleSuggestsHttp = (title) => {
|
|
5569
|
+
const { method, path: parsedPath } = parseMethodPathFromTitle(title);
|
|
5570
|
+
return Boolean(method || parsedPath && parsedPath.startsWith("/"));
|
|
5571
|
+
};
|
|
5572
|
+
var hasStatusSemantics = (assertionLike) => {
|
|
5573
|
+
if (!assertionLike) {
|
|
5574
|
+
return false;
|
|
5575
|
+
}
|
|
5576
|
+
if (isHttpStatusNumber(assertionLike.expectedNumber) || isHttpStatusNumber(assertionLike.receivedNumber)) {
|
|
5577
|
+
return true;
|
|
5578
|
+
}
|
|
5579
|
+
const combinedRaw = `${assertionLike.matcher ?? ""} ${assertionLike.message ?? ""}`;
|
|
5580
|
+
const combinedMessage = combinedRaw.toLowerCase();
|
|
5581
|
+
return /\bstatus(code)?\b|\btohaves(tatus|tatuscode)\b/.test(combinedMessage);
|
|
5582
|
+
};
|
|
5583
|
+
var fileSuggestsHttp = (relPath2) => /(?:^|\/)(routes?|api|controllers?|e2e|integration)(?:\/|\.test\.)/i.test(relPath2);
|
|
5584
|
+
var isHttpRelevant = (ctx) => ctx.hasTransportSignal || ctx.httpCountInSameTest > 0 || titleSuggestsHttp(ctx.title) || hasStatusSemantics(ctx.assertion) || fileSuggestsHttp(ctx.relPath);
|
|
5570
5585
|
var vitestFooter = (agg, durationMs) => {
|
|
5571
5586
|
const files = [
|
|
5572
5587
|
agg.numFailedTestSuites ? colorTokens2.fail(`${agg.numFailedTestSuites} failed`) : "",
|
|
@@ -6043,13 +6058,21 @@ var renderVitestFromJestJSON = (data, ctx, opts) => {
|
|
|
6043
6058
|
out.push(vitestFooter(data.aggregated));
|
|
6044
6059
|
return out.join("\n");
|
|
6045
6060
|
};
|
|
6061
|
+
|
|
6062
|
+
// src/lib/formatter/bridge/tryBridgeFallback.ts
|
|
6046
6063
|
var tryBridgeFallback = (raw, ctx, opts) => {
|
|
6047
|
-
|
|
6064
|
+
let bridgeJsonPath = extractBridgePath2(raw, ctx.cwd);
|
|
6065
|
+
if (!bridgeJsonPath) {
|
|
6066
|
+
const def = path11.resolve(ctx.cwd, "coverage/jest-run.json").replace(/\\/g, "/");
|
|
6067
|
+
if (fs6.existsSync(def)) {
|
|
6068
|
+
bridgeJsonPath = def;
|
|
6069
|
+
}
|
|
6070
|
+
}
|
|
6048
6071
|
if (!bridgeJsonPath || !fs6.existsSync(bridgeJsonPath)) {
|
|
6049
6072
|
return null;
|
|
6050
6073
|
}
|
|
6051
6074
|
try {
|
|
6052
|
-
const json =
|
|
6075
|
+
const json = import_json53.default.parse(fs6.readFileSync(bridgeJsonPath, "utf8"));
|
|
6053
6076
|
const bridge = coerceJestJsonToBridge(json);
|
|
6054
6077
|
return renderVitestFromJestJSON(bridge, ctx, opts);
|
|
6055
6078
|
} catch {
|
|
@@ -6067,23 +6090,39 @@ var formatJestOutputVitest = (raw, opts) => pipe(
|
|
|
6067
6090
|
(state) => ({ ...state, chunks: parseChunks(state.raw) }),
|
|
6068
6091
|
(state) => ({
|
|
6069
6092
|
...state,
|
|
6070
|
-
|
|
6093
|
+
native: renderChunks(state.chunks, state.ctx, mkPrettyFns(), {
|
|
6071
6094
|
onlyFailures: Boolean(state.opts?.onlyFailures)
|
|
6072
|
-
})
|
|
6095
|
+
}).text
|
|
6073
6096
|
}),
|
|
6074
|
-
(state) => {
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
}
|
|
6078
|
-
const fallback = tryBridgeFallback(state.raw, state.ctx, {
|
|
6097
|
+
(state) => ({
|
|
6098
|
+
...state,
|
|
6099
|
+
bridge: tryBridgeFallback(state.raw, state.ctx, {
|
|
6079
6100
|
onlyFailures: Boolean(state.opts?.onlyFailures)
|
|
6080
|
-
})
|
|
6081
|
-
|
|
6082
|
-
|
|
6101
|
+
}) || null
|
|
6102
|
+
}),
|
|
6103
|
+
(state) => {
|
|
6104
|
+
const out = [];
|
|
6105
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6106
|
+
const pushUnique = (text) => {
|
|
6107
|
+
if (!text) {
|
|
6108
|
+
return;
|
|
6109
|
+
}
|
|
6110
|
+
for (const line of text.split(/\r?\n/)) {
|
|
6111
|
+
const key = stripAnsiSimple(line);
|
|
6112
|
+
if (!seen.has(key)) {
|
|
6113
|
+
out.push(line);
|
|
6114
|
+
seen.add(key);
|
|
6115
|
+
}
|
|
6116
|
+
}
|
|
6117
|
+
};
|
|
6118
|
+
pushUnique(state.native);
|
|
6119
|
+
if (state.bridge) {
|
|
6120
|
+
if (out.length) {
|
|
6121
|
+
out.push("");
|
|
6122
|
+
}
|
|
6123
|
+
pushUnique(state.bridge);
|
|
6083
6124
|
}
|
|
6084
|
-
|
|
6085
|
-
return prefix ? `${prefix}
|
|
6086
|
-
${fallback}` : fallback;
|
|
6125
|
+
return out.join("\n");
|
|
6087
6126
|
}
|
|
6088
6127
|
);
|
|
6089
6128
|
|
|
@@ -6130,7 +6169,7 @@ var mergeLcov = async () => {
|
|
|
6130
6169
|
try {
|
|
6131
6170
|
const entries = fsSync3.readdirSync(dir, { withFileTypes: true });
|
|
6132
6171
|
for (const entry of entries) {
|
|
6133
|
-
const full =
|
|
6172
|
+
const full = path12.join(dir, entry.name);
|
|
6134
6173
|
if (entry.isDirectory()) {
|
|
6135
6174
|
out.push(...collectLcovs(full));
|
|
6136
6175
|
} else if (entry.isFile() && entry.name === "lcov.info") {
|
|
@@ -6142,8 +6181,8 @@ var mergeLcov = async () => {
|
|
|
6142
6181
|
return out;
|
|
6143
6182
|
};
|
|
6144
6183
|
try {
|
|
6145
|
-
const jestRoot =
|
|
6146
|
-
const candidates = [
|
|
6184
|
+
const jestRoot = path12.join("coverage", "jest");
|
|
6185
|
+
const candidates = [path12.join(jestRoot, "lcov.info"), ...collectLcovs(jestRoot)].map((candidatePath) => path12.resolve(candidatePath)).filter((absolutePath, index, arr) => arr.indexOf(absolutePath) === index);
|
|
6147
6186
|
for (const filePath of candidates) {
|
|
6148
6187
|
try {
|
|
6149
6188
|
const content = await readOrEmpty(filePath);
|
|
@@ -6183,7 +6222,7 @@ var emitMergedCoverage = async (ui, opts) => {
|
|
|
6183
6222
|
try {
|
|
6184
6223
|
const entries = fsSync3.readdirSync(dir, { withFileTypes: true });
|
|
6185
6224
|
for (const entry of entries) {
|
|
6186
|
-
const full =
|
|
6225
|
+
const full = path12.join(dir, entry.name);
|
|
6187
6226
|
if (entry.isDirectory()) {
|
|
6188
6227
|
out.push(...listJsons(full));
|
|
6189
6228
|
} else if (entry.isFile() && entry.name === "coverage-final.json") {
|
|
@@ -6194,11 +6233,11 @@ var emitMergedCoverage = async (ui, opts) => {
|
|
|
6194
6233
|
}
|
|
6195
6234
|
return out;
|
|
6196
6235
|
};
|
|
6197
|
-
const coverageRoot =
|
|
6236
|
+
const coverageRoot = path12.join("coverage", "jest");
|
|
6198
6237
|
const jsonCandidates = [
|
|
6199
|
-
|
|
6238
|
+
path12.join(coverageRoot, "coverage-final.json"),
|
|
6200
6239
|
...listJsons(coverageRoot)
|
|
6201
|
-
].map((candidatePath) =>
|
|
6240
|
+
].map((candidatePath) => path12.resolve(candidatePath)).filter((absolutePath, index, arr) => {
|
|
6202
6241
|
const isFirst = arr.indexOf(absolutePath) === index;
|
|
6203
6242
|
const exists = fsSync3.existsSync(absolutePath);
|
|
6204
6243
|
return isFirst && exists;
|
|
@@ -6260,7 +6299,7 @@ var emitMergedCoverage = async (ui, opts) => {
|
|
|
6260
6299
|
executedTests: opts.executedTests ?? []
|
|
6261
6300
|
});
|
|
6262
6301
|
const context = LibReport.createContext({
|
|
6263
|
-
dir:
|
|
6302
|
+
dir: path12.resolve("coverage", "merged"),
|
|
6264
6303
|
coverageMap: filteredMap,
|
|
6265
6304
|
defaultSummarizer: "nested"
|
|
6266
6305
|
});
|
|
@@ -6328,8 +6367,8 @@ var emitMergedCoverage = async (ui, opts) => {
|
|
|
6328
6367
|
for (const reporter of reporters) {
|
|
6329
6368
|
reporter.execute(context);
|
|
6330
6369
|
}
|
|
6331
|
-
const textPath =
|
|
6332
|
-
const summaryPath =
|
|
6370
|
+
const textPath = path12.resolve("coverage", "merged", "coverage.txt");
|
|
6371
|
+
const summaryPath = path12.resolve("coverage", "merged", "coverage-summary.txt");
|
|
6333
6372
|
const filesToPrint = [];
|
|
6334
6373
|
if (fsSync3.existsSync(textPath)) {
|
|
6335
6374
|
filesToPrint.push(textPath);
|
|
@@ -6472,13 +6511,13 @@ var program = async () => {
|
|
|
6472
6511
|
const rels2 = Array.from(
|
|
6473
6512
|
/* @__PURE__ */ new Set([...branchDiff, ...stagedNow, ...unstagedNow, ...untrackedNow])
|
|
6474
6513
|
);
|
|
6475
|
-
return rels2.map((rel) =>
|
|
6514
|
+
return rels2.map((rel) => path12.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
|
|
6476
6515
|
}
|
|
6477
6516
|
const staged = mode === "staged" || mode === "all" ? await collect("git", ["diff", "--name-only", "--diff-filter=ACMRTUXB", "--cached"]) : [];
|
|
6478
6517
|
const unstagedTracked = mode === "unstaged" || mode === "all" ? await collect("git", ["diff", "--name-only", "--diff-filter=ACMRTUXB"]) : [];
|
|
6479
6518
|
const untracked = mode === "unstaged" || mode === "all" ? await collect("git", ["ls-files", "--others", "--exclude-standard"]) : [];
|
|
6480
6519
|
const rels = Array.from(/* @__PURE__ */ new Set([...staged, ...unstagedTracked, ...untracked]));
|
|
6481
|
-
return rels.map((rel) =>
|
|
6520
|
+
return rels.map((rel) => path12.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
|
|
6482
6521
|
};
|
|
6483
6522
|
const repoRootForChanged = workspaceRoot ?? await findRepoRoot();
|
|
6484
6523
|
const changedSelectionAbs = changed ? await getChangedFiles(changed, repoRootForChanged) : [];
|
|
@@ -6503,18 +6542,18 @@ var program = async () => {
|
|
|
6503
6542
|
if (!token) {
|
|
6504
6543
|
continue;
|
|
6505
6544
|
}
|
|
6506
|
-
const isAbs =
|
|
6545
|
+
const isAbs = path12.isAbsolute(token);
|
|
6507
6546
|
const looksLikeRelPath = /[\\/]/.test(token);
|
|
6508
6547
|
let candidateFromRoot;
|
|
6509
6548
|
if (token.startsWith("/")) {
|
|
6510
|
-
candidateFromRoot =
|
|
6549
|
+
candidateFromRoot = path12.join(repoRoot, token.slice(1));
|
|
6511
6550
|
} else if (looksLikeRelPath) {
|
|
6512
|
-
candidateFromRoot =
|
|
6551
|
+
candidateFromRoot = path12.join(repoRoot, token);
|
|
6513
6552
|
} else {
|
|
6514
6553
|
candidateFromRoot = void 0;
|
|
6515
6554
|
}
|
|
6516
6555
|
const tryPushIfProd = (absPath) => {
|
|
6517
|
-
const norm =
|
|
6556
|
+
const norm = path12.resolve(absPath).replace(/\\/g, "/");
|
|
6518
6557
|
const isTest = /(^|\/)tests?\//i.test(norm) || /\.(test|spec)\.[tj]sx?$/i.test(norm);
|
|
6519
6558
|
if (!isTest && fsSync3.existsSync(norm)) {
|
|
6520
6559
|
results.add(norm);
|
|
@@ -6536,7 +6575,7 @@ var program = async () => {
|
|
|
6536
6575
|
}),
|
|
6537
6576
|
timeoutMs: 4e3
|
|
6538
6577
|
});
|
|
6539
|
-
const matches = out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((rel) =>
|
|
6578
|
+
const matches = out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((rel) => path12.resolve(repoRoot, rel).replace(/\\/g, "/")).filter(
|
|
6540
6579
|
(abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/") && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
|
|
6541
6580
|
);
|
|
6542
6581
|
matches.forEach((abs) => results.add(abs));
|
|
@@ -6557,8 +6596,8 @@ var program = async () => {
|
|
|
6557
6596
|
const jestDiscoveryArgs = selectionIncludesProdPaths ? stripPathTokens(jest) : jest;
|
|
6558
6597
|
const projectConfigs = [];
|
|
6559
6598
|
try {
|
|
6560
|
-
const baseCfg =
|
|
6561
|
-
const tsCfg =
|
|
6599
|
+
const baseCfg = path12.resolve("jest.config.js");
|
|
6600
|
+
const tsCfg = path12.resolve("jest.ts.config.js");
|
|
6562
6601
|
if (fsSync3.existsSync(baseCfg)) {
|
|
6563
6602
|
projectConfigs.push(baseCfg);
|
|
6564
6603
|
}
|
|
@@ -6575,7 +6614,7 @@ var program = async () => {
|
|
|
6575
6614
|
);
|
|
6576
6615
|
const prodSelections2 = expandedProdSelections;
|
|
6577
6616
|
for (const cfg of projectConfigs) {
|
|
6578
|
-
const cfgCwd =
|
|
6617
|
+
const cfgCwd = path12.dirname(cfg);
|
|
6579
6618
|
const allTests = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
|
|
6580
6619
|
cwd: cfgCwd
|
|
6581
6620
|
});
|
|
@@ -6588,7 +6627,7 @@ var program = async () => {
|
|
|
6588
6627
|
});
|
|
6589
6628
|
} catch (err) {
|
|
6590
6629
|
if (isDebug()) {
|
|
6591
|
-
console.warn(`direct selection failed for project ${
|
|
6630
|
+
console.warn(`direct selection failed for project ${path12.basename(cfg)}: ${String(err)}`);
|
|
6592
6631
|
}
|
|
6593
6632
|
}
|
|
6594
6633
|
perProjectFiles.set(cfg, directPerProject);
|
|
@@ -6600,7 +6639,7 @@ var program = async () => {
|
|
|
6600
6639
|
)} | related=${selectionIncludesProdPaths} | cwd=${repoRootForDiscovery}`
|
|
6601
6640
|
);
|
|
6602
6641
|
for (const cfg of projectConfigs) {
|
|
6603
|
-
const cfgCwd =
|
|
6642
|
+
const cfgCwd = path12.dirname(cfg);
|
|
6604
6643
|
const files = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
|
|
6605
6644
|
cwd: cfgCwd
|
|
6606
6645
|
});
|
|
@@ -6615,13 +6654,13 @@ var program = async () => {
|
|
|
6615
6654
|
);
|
|
6616
6655
|
const candidates = selectionHasPaths && selectionLooksLikeTest ? selectionTestPaths : files;
|
|
6617
6656
|
const absFiles = candidates.map(
|
|
6618
|
-
(candidatePath) =>
|
|
6657
|
+
(candidatePath) => path12.isAbsolute(candidatePath) ? candidatePath : path12.join(repoRootForDiscovery, candidatePath)
|
|
6619
6658
|
).map((absolutePath) => absolutePath.replace(/\\/g, "/"));
|
|
6620
6659
|
const onlyOwned = await filterCandidatesForProject(
|
|
6621
6660
|
cfg,
|
|
6622
6661
|
jestDiscoveryArgs,
|
|
6623
6662
|
absFiles,
|
|
6624
|
-
|
|
6663
|
+
path12.dirname(cfg)
|
|
6625
6664
|
);
|
|
6626
6665
|
perProjectFiltered.set(cfg, onlyOwned);
|
|
6627
6666
|
}
|
|
@@ -6633,7 +6672,7 @@ var program = async () => {
|
|
|
6633
6672
|
if (selectionHasPaths && prodSelections.length > 0) {
|
|
6634
6673
|
console.info(`rg related \u2192 prodSelections=${prodSelections.length} (starting)`);
|
|
6635
6674
|
const repoRootForRefinement = workspaceRoot ?? await findRepoRoot();
|
|
6636
|
-
const selectionKey = prodSelections.map((absPath) =>
|
|
6675
|
+
const selectionKey = prodSelections.map((absPath) => path12.relative(repoRootForRefinement, absPath).replace(/\\/g, "/")).sort((firstPath, secondPath) => firstPath.localeCompare(secondPath)).join("|");
|
|
6637
6676
|
const { cachedRelated: cachedRelated2, findRelatedTestsFast: findRelatedTestsFast2, DEFAULT_TEST_GLOBS: DEFAULT_TEST_GLOBS2 } = await Promise.resolve().then(() => (init_fast_related(), fast_related_exports));
|
|
6638
6677
|
const { DEFAULT_EXCLUDE: DEFAULT_EXCLUDE2 } = await Promise.resolve().then(() => (init_args(), args_exports));
|
|
6639
6678
|
const rgMatches = await cachedRelated2({
|
|
@@ -6663,7 +6702,7 @@ var program = async () => {
|
|
|
6663
6702
|
cfg,
|
|
6664
6703
|
jestDiscoveryArgs,
|
|
6665
6704
|
rgCandidates,
|
|
6666
|
-
|
|
6705
|
+
path12.dirname(cfg)
|
|
6667
6706
|
);
|
|
6668
6707
|
perProjectFromRg.set(cfg, owned);
|
|
6669
6708
|
}
|
|
@@ -6678,9 +6717,9 @@ var program = async () => {
|
|
|
6678
6717
|
} else {
|
|
6679
6718
|
const repoRootForScan = repoRootForDiscovery;
|
|
6680
6719
|
const toSeeds = (abs) => {
|
|
6681
|
-
const rel =
|
|
6720
|
+
const rel = path12.relative(repoRootForScan, abs).replace(/\\/g, "/");
|
|
6682
6721
|
const withoutExt = rel.replace(/\.(m?[tj]sx?)$/i, "");
|
|
6683
|
-
const base =
|
|
6722
|
+
const base = path12.basename(withoutExt);
|
|
6684
6723
|
const segs = withoutExt.split("/");
|
|
6685
6724
|
const tail2 = segs.slice(-2).join("/");
|
|
6686
6725
|
return Array.from(new Set([withoutExt, base, tail2].filter(Boolean)));
|
|
@@ -6695,8 +6734,8 @@ var program = async () => {
|
|
|
6695
6734
|
}
|
|
6696
6735
|
};
|
|
6697
6736
|
const resolveLocalImport = (fromFile, spec) => {
|
|
6698
|
-
const baseDir =
|
|
6699
|
-
const cand =
|
|
6737
|
+
const baseDir = path12.dirname(fromFile);
|
|
6738
|
+
const cand = path12.resolve(baseDir, spec);
|
|
6700
6739
|
const exts = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
6701
6740
|
for (const ext of exts) {
|
|
6702
6741
|
const full = ext ? `${cand}${ext}` : cand;
|
|
@@ -6705,7 +6744,7 @@ var program = async () => {
|
|
|
6705
6744
|
}
|
|
6706
6745
|
}
|
|
6707
6746
|
for (const ext of exts) {
|
|
6708
|
-
const full =
|
|
6747
|
+
const full = path12.join(cand, `index${ext}`);
|
|
6709
6748
|
if (fsSync3.existsSync(full)) {
|
|
6710
6749
|
return full;
|
|
6711
6750
|
}
|
|
@@ -6759,7 +6798,7 @@ var program = async () => {
|
|
|
6759
6798
|
cfg,
|
|
6760
6799
|
jestDiscoveryArgs,
|
|
6761
6800
|
keptCandidates,
|
|
6762
|
-
|
|
6801
|
+
path12.dirname(cfg)
|
|
6763
6802
|
);
|
|
6764
6803
|
perProjectFromScan.set(cfg, owned);
|
|
6765
6804
|
}
|
|
@@ -6789,7 +6828,7 @@ var program = async () => {
|
|
|
6789
6828
|
try {
|
|
6790
6829
|
const allAcross = [];
|
|
6791
6830
|
for (const cfg of projectConfigs) {
|
|
6792
|
-
const cfgCwd =
|
|
6831
|
+
const cfgCwd = path12.dirname(cfg);
|
|
6793
6832
|
const listed = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
|
|
6794
6833
|
cwd: cfgCwd
|
|
6795
6834
|
});
|
|
@@ -6803,9 +6842,9 @@ var program = async () => {
|
|
|
6803
6842
|
}
|
|
6804
6843
|
}
|
|
6805
6844
|
const seeds = prodSelections.map(
|
|
6806
|
-
(abs) =>
|
|
6845
|
+
(abs) => path12.relative(repoRoot, abs).replace(/\\/g, "/").replace(/\.(m?[tj]sx?)$/i, "")
|
|
6807
6846
|
).flatMap((rel) => {
|
|
6808
|
-
const base =
|
|
6847
|
+
const base = path12.basename(rel);
|
|
6809
6848
|
const segments = rel.split("/");
|
|
6810
6849
|
return Array.from(new Set([rel, base, segments.slice(-2).join("/")].filter(Boolean)));
|
|
6811
6850
|
});
|
|
@@ -6818,8 +6857,8 @@ var program = async () => {
|
|
|
6818
6857
|
}
|
|
6819
6858
|
};
|
|
6820
6859
|
const resolveLocalImport = (fromFile, spec) => {
|
|
6821
|
-
const baseDir =
|
|
6822
|
-
const candidate =
|
|
6860
|
+
const baseDir = path12.dirname(fromFile);
|
|
6861
|
+
const candidate = path12.resolve(baseDir, spec);
|
|
6823
6862
|
const extensions = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"];
|
|
6824
6863
|
for (const ext of extensions) {
|
|
6825
6864
|
const fullPath = ext ? `${candidate}${ext}` : candidate;
|
|
@@ -6828,7 +6867,7 @@ var program = async () => {
|
|
|
6828
6867
|
}
|
|
6829
6868
|
}
|
|
6830
6869
|
for (const ext of extensions) {
|
|
6831
|
-
const fullPath =
|
|
6870
|
+
const fullPath = path12.join(candidate, `index${ext}`);
|
|
6832
6871
|
if (fsSync3.existsSync(fullPath)) {
|
|
6833
6872
|
return fullPath;
|
|
6834
6873
|
}
|
|
@@ -6985,10 +7024,10 @@ var program = async () => {
|
|
|
6985
7024
|
};
|
|
6986
7025
|
const prodSeedsForRun = (() => {
|
|
6987
7026
|
const changedAbs = (changedSelectionAbs ?? []).map(
|
|
6988
|
-
(absPath) =>
|
|
7027
|
+
(absPath) => path12.resolve(absPath).replace(/\\/g, "/")
|
|
6989
7028
|
);
|
|
6990
7029
|
const selAbs = selectionPathsAugmented.map(
|
|
6991
|
-
(pathToken) =>
|
|
7030
|
+
(pathToken) => path12.resolve(pathToken).replace(/\\/g, "/")
|
|
6992
7031
|
);
|
|
6993
7032
|
return (changedAbs.length ? changedAbs : selAbs).filter(
|
|
6994
7033
|
(abs) => /[\\/]/.test(abs) && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
|
|
@@ -7003,17 +7042,17 @@ var program = async () => {
|
|
|
7003
7042
|
const cfg = projectsToRun[projIndex];
|
|
7004
7043
|
const files = perProjectFiltered.get(cfg) ?? [];
|
|
7005
7044
|
if (files.length === 0) {
|
|
7006
|
-
console.info(`Project ${
|
|
7045
|
+
console.info(`Project ${path12.basename(cfg)}: 0 matching tests after filter; skipping.`);
|
|
7007
7046
|
continue;
|
|
7008
7047
|
}
|
|
7009
7048
|
files.forEach(
|
|
7010
|
-
(absTestPath) => executedTestFilesSet.add(
|
|
7049
|
+
(absTestPath) => executedTestFilesSet.add(path12.resolve(absTestPath).replace(/\\/g, "/"))
|
|
7011
7050
|
);
|
|
7012
|
-
const outJson =
|
|
7013
|
-
|
|
7051
|
+
const outJson = path12.join(
|
|
7052
|
+
os3.tmpdir(),
|
|
7014
7053
|
`jest-bridge-${Date.now()}-${Math.random().toString(36).slice(2)}.json`
|
|
7015
7054
|
);
|
|
7016
|
-
const reporterPath =
|
|
7055
|
+
const reporterPath = path12.resolve("scripts/jest-vitest-bridge.cjs");
|
|
7017
7056
|
try {
|
|
7018
7057
|
const needsWrite = (() => {
|
|
7019
7058
|
try {
|
|
@@ -7024,10 +7063,10 @@ var program = async () => {
|
|
|
7024
7063
|
}
|
|
7025
7064
|
})();
|
|
7026
7065
|
if (needsWrite) {
|
|
7027
|
-
fsSync3.mkdirSync(
|
|
7066
|
+
fsSync3.mkdirSync(path12.dirname(reporterPath), { recursive: true });
|
|
7028
7067
|
fsSync3.writeFileSync(reporterPath, JEST_BRIDGE_REPORTER_SOURCE, "utf8");
|
|
7029
7068
|
}
|
|
7030
|
-
const envPath =
|
|
7069
|
+
const envPath = path12.resolve("scripts/jest-bridge-env.cjs");
|
|
7031
7070
|
try {
|
|
7032
7071
|
const existingEnv = fsSync3.readFileSync(envPath, "utf8");
|
|
7033
7072
|
if (existingEnv !== JEST_BRIDGE_ENV_SOURCE) {
|
|
@@ -7035,7 +7074,7 @@ var program = async () => {
|
|
|
7035
7074
|
}
|
|
7036
7075
|
} catch {
|
|
7037
7076
|
try {
|
|
7038
|
-
fsSync3.mkdirSync(
|
|
7077
|
+
fsSync3.mkdirSync(path12.dirname(envPath), { recursive: true });
|
|
7039
7078
|
} catch {
|
|
7040
7079
|
}
|
|
7041
7080
|
fsSync3.writeFileSync(envPath, JEST_BRIDGE_ENV_SOURCE, "utf8");
|
|
@@ -7043,7 +7082,7 @@ var program = async () => {
|
|
|
7043
7082
|
} catch (ensureReporterError) {
|
|
7044
7083
|
console.warn(`Unable to ensure jest bridge reporter: ${String(ensureReporterError)}`);
|
|
7045
7084
|
}
|
|
7046
|
-
const selectedFilesForCoverage = selectionPathsAugmented.filter((pathToken) => /[\\/]/.test(pathToken)).filter((pathToken) => !looksLikeTestPath(pathToken)).map((pathToken) =>
|
|
7085
|
+
const selectedFilesForCoverage = selectionPathsAugmented.filter((pathToken) => /[\\/]/.test(pathToken)).filter((pathToken) => !looksLikeTestPath(pathToken)).map((pathToken) => path12.relative(repoRootForDiscovery, pathToken).replace(/\\\\/g, "/")).filter((rel) => rel && !/^\.+\//.test(rel)).map((rel) => rel.startsWith("./") ? rel : `./${rel}`);
|
|
7047
7086
|
const coverageFromArgs = [];
|
|
7048
7087
|
for (const relPath2 of selectedFilesForCoverage) {
|
|
7049
7088
|
coverageFromArgs.push("--collectCoverageFrom", relPath2);
|
|
@@ -7061,11 +7100,11 @@ var program = async () => {
|
|
|
7061
7100
|
`--reporters=${reporterPath}`,
|
|
7062
7101
|
"--colors",
|
|
7063
7102
|
"--env",
|
|
7064
|
-
|
|
7103
|
+
path12.resolve("scripts/jest-bridge-env.cjs"),
|
|
7065
7104
|
...sanitizedJestRunArgs,
|
|
7066
7105
|
...collectCoverage ? [
|
|
7067
7106
|
"--coverageDirectory",
|
|
7068
|
-
|
|
7107
|
+
path12.join("coverage", "jest", path12.basename(cfg).replace(/[^a-zA-Z0-9_.-]+/g, "_"))
|
|
7069
7108
|
] : [],
|
|
7070
7109
|
...coverageFromArgs,
|
|
7071
7110
|
"--passWithNoTests",
|
|
@@ -7191,10 +7230,10 @@ ${stripFooter(rawAlso)}`.trimEnd();
|
|
|
7191
7230
|
try {
|
|
7192
7231
|
const prodSeeds = (() => {
|
|
7193
7232
|
const changedAbs = (changedSelectionAbs ?? []).map(
|
|
7194
|
-
(absPath) =>
|
|
7233
|
+
(absPath) => path12.resolve(absPath).replace(/\\/g, "/")
|
|
7195
7234
|
);
|
|
7196
7235
|
const selAbs = selectionPathsAugmented.map(
|
|
7197
|
-
(pathToken) =>
|
|
7236
|
+
(pathToken) => path12.resolve(pathToken).replace(/\\/g, "/")
|
|
7198
7237
|
);
|
|
7199
7238
|
return (changedAbs.length ? changedAbs : selAbs).filter(
|
|
7200
7239
|
(abs) => /[\\/]/.test(abs) && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
|