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/index.js
CHANGED
|
@@ -593,7 +593,7 @@ var init_TimeoutError = __esm({
|
|
|
593
593
|
|
|
594
594
|
// node_modules/es-toolkit/dist/promise/delay.mjs
|
|
595
595
|
function delay(ms, { signal } = {}) {
|
|
596
|
-
return new Promise((
|
|
596
|
+
return new Promise((resolve11, reject) => {
|
|
597
597
|
const abortError = () => {
|
|
598
598
|
reject(new AbortError());
|
|
599
599
|
};
|
|
@@ -606,7 +606,7 @@ function delay(ms, { signal } = {}) {
|
|
|
606
606
|
}
|
|
607
607
|
const timeoutId = setTimeout(() => {
|
|
608
608
|
signal?.removeEventListener("abort", abortHandler);
|
|
609
|
-
|
|
609
|
+
resolve11();
|
|
610
610
|
}, ms);
|
|
611
611
|
signal?.addEventListener("abort", abortHandler, { once: true });
|
|
612
612
|
});
|
|
@@ -671,11 +671,11 @@ var init_exec = __esm({
|
|
|
671
671
|
child.stderr?.on("data", (chunk) => {
|
|
672
672
|
stderr += String(chunk);
|
|
673
673
|
});
|
|
674
|
-
const exec = new Promise((
|
|
674
|
+
const exec = new Promise((resolve11, reject) => {
|
|
675
675
|
child.on("error", reject);
|
|
676
676
|
child.on(
|
|
677
677
|
"close",
|
|
678
|
-
(code) => Number(code) === 0 ?
|
|
678
|
+
(code) => Number(code) === 0 ? resolve11(stdout) : reject(new Error(stderr || `exit ${code}`))
|
|
679
679
|
);
|
|
680
680
|
});
|
|
681
681
|
try {
|
|
@@ -695,7 +695,7 @@ var init_exec = __esm({
|
|
|
695
695
|
throw caughtError;
|
|
696
696
|
}
|
|
697
697
|
};
|
|
698
|
-
runExitCode = async (cmd, args, opts = {}) => new Promise((
|
|
698
|
+
runExitCode = async (cmd, args, opts = {}) => new Promise((resolve11, reject) => {
|
|
699
699
|
const child = spawn(cmd, [...args], {
|
|
700
700
|
cwd: opts.cwd,
|
|
701
701
|
env: opts.env,
|
|
@@ -704,9 +704,9 @@ var init_exec = __esm({
|
|
|
704
704
|
windowsHide: true
|
|
705
705
|
});
|
|
706
706
|
child.on("error", reject);
|
|
707
|
-
child.on("close", (code) =>
|
|
707
|
+
child.on("close", (code) => resolve11(Number(code)));
|
|
708
708
|
});
|
|
709
|
-
runWithCapture = async (cmd, args, opts) => new Promise((
|
|
709
|
+
runWithCapture = async (cmd, args, opts) => new Promise((resolve11, reject) => {
|
|
710
710
|
const child = spawn(cmd, [...args], {
|
|
711
711
|
cwd: opts.cwd,
|
|
712
712
|
env: opts.env,
|
|
@@ -722,7 +722,7 @@ var init_exec = __esm({
|
|
|
722
722
|
buf += String(chunk);
|
|
723
723
|
});
|
|
724
724
|
child.on("error", reject);
|
|
725
|
-
child.on("close", (code) =>
|
|
725
|
+
child.on("close", (code) => resolve11({ code: Number(code), output: buf }));
|
|
726
726
|
});
|
|
727
727
|
}
|
|
728
728
|
});
|
|
@@ -735,7 +735,9 @@ __export(fast_related_exports, {
|
|
|
735
735
|
findRelatedTestsFast: () => findRelatedTestsFast
|
|
736
736
|
});
|
|
737
737
|
import * as path3 from "node:path";
|
|
738
|
+
import * as os2 from "node:os";
|
|
738
739
|
import * as fs from "node:fs/promises";
|
|
740
|
+
import { createHash } from "node:crypto";
|
|
739
741
|
var TailSegmentCount, EmptyCount, JsonIndentSpaces, DEFAULT_TEST_GLOBS, findRelatedTestsFast, cachedRelated;
|
|
740
742
|
var init_fast_related = __esm({
|
|
741
743
|
"src/lib/fast-related.ts"() {
|
|
@@ -788,9 +790,7 @@ var init_fast_related = __esm({
|
|
|
788
790
|
}
|
|
789
791
|
const args = ["-n", "-l", "-S", "-F"];
|
|
790
792
|
testGlobs.forEach((globPattern) => args.push("-g", globPattern));
|
|
791
|
-
excludeGlobs.forEach(
|
|
792
|
-
(excludeGlobPattern) => args.push("-g", `!${excludeGlobPattern}`)
|
|
793
|
-
);
|
|
793
|
+
excludeGlobs.forEach((excludeGlobPattern) => args.push("-g", `!${excludeGlobPattern}`));
|
|
794
794
|
seeds.forEach((seedToken) => args.push("-e", seedToken));
|
|
795
795
|
let raw = "";
|
|
796
796
|
try {
|
|
@@ -802,9 +802,7 @@ var init_fast_related = __esm({
|
|
|
802
802
|
}
|
|
803
803
|
const lines = raw.split(/\r?\n/).map((lineText) => lineText.trim()).filter(Boolean);
|
|
804
804
|
const looksLikeTest = (pathText) => /\.(test|spec)\.[tj]sx?$/i.test(pathText) || /(^|\/)tests?\//i.test(pathText);
|
|
805
|
-
const absolute = lines.map(
|
|
806
|
-
(relativePath) => path3.resolve(repoRoot, relativePath).replace(/\\/g, "/")
|
|
807
|
-
).filter(looksLikeTest);
|
|
805
|
+
const absolute = lines.map((relativePath) => path3.resolve(repoRoot, relativePath).replace(/\\/g, "/")).filter(looksLikeTest);
|
|
808
806
|
const uniq = Array.from(new Set(absolute));
|
|
809
807
|
const results = [];
|
|
810
808
|
await Promise.all(
|
|
@@ -819,17 +817,15 @@ var init_fast_related = __esm({
|
|
|
819
817
|
return results;
|
|
820
818
|
};
|
|
821
819
|
cachedRelated = async (opts) => {
|
|
822
|
-
const
|
|
820
|
+
const cacheRoot = process.env.HEADLAMP_CACHE_DIR || path3.join(os2.tmpdir(), "headlamp-cache");
|
|
821
|
+
const repoKey = createHash("sha1").update(path3.resolve(opts.repoRoot)).digest("hex").slice(0, 12);
|
|
822
|
+
const cacheDir = path3.join(cacheRoot, repoKey);
|
|
823
823
|
const cacheFile = path3.join(cacheDir, "relevant-tests.json");
|
|
824
824
|
let head = "nogit";
|
|
825
825
|
try {
|
|
826
|
-
const raw = await runText(
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
{
|
|
830
|
-
env: safeEnv(process.env, {})
|
|
831
|
-
}
|
|
832
|
-
);
|
|
826
|
+
const raw = await runText("git", ["-C", opts.repoRoot, "rev-parse", "--short", "HEAD"], {
|
|
827
|
+
env: safeEnv(process.env, {})
|
|
828
|
+
});
|
|
833
829
|
head = raw.trim() || "nogit";
|
|
834
830
|
} catch {
|
|
835
831
|
head = "nogit";
|
|
@@ -861,10 +857,7 @@ var init_fast_related = __esm({
|
|
|
861
857
|
try {
|
|
862
858
|
const next = { ...bag, [key]: Array.from(new Set(recomputed)) };
|
|
863
859
|
await fs.mkdir(cacheDir, { recursive: true });
|
|
864
|
-
await fs.writeFile(
|
|
865
|
-
cacheFile,
|
|
866
|
-
JSON.stringify(next, null, JsonIndentSpaces)
|
|
867
|
-
);
|
|
860
|
+
await fs.writeFile(cacheFile, JSON.stringify(next, null, JsonIndentSpaces));
|
|
868
861
|
} catch {
|
|
869
862
|
}
|
|
870
863
|
return recomputed;
|
|
@@ -1133,8 +1126,8 @@ var require_utils = __commonJS({
|
|
|
1133
1126
|
}
|
|
1134
1127
|
return output;
|
|
1135
1128
|
};
|
|
1136
|
-
exports.basename = (
|
|
1137
|
-
const segs =
|
|
1129
|
+
exports.basename = (path13, { windows } = {}) => {
|
|
1130
|
+
const segs = path13.split(windows ? /[\\/]/ : "/");
|
|
1138
1131
|
const last = segs[segs.length - 1];
|
|
1139
1132
|
if (last === "") {
|
|
1140
1133
|
return segs[segs.length - 2];
|
|
@@ -3503,11 +3496,11 @@ var require_lib = __commonJS({
|
|
|
3503
3496
|
"node_modules/json5/lib/index.js"(exports, module) {
|
|
3504
3497
|
var parse = require_parse2();
|
|
3505
3498
|
var stringify = require_stringify();
|
|
3506
|
-
var
|
|
3499
|
+
var JSON54 = {
|
|
3507
3500
|
parse,
|
|
3508
3501
|
stringify
|
|
3509
3502
|
};
|
|
3510
|
-
module.exports =
|
|
3503
|
+
module.exports = JSON54;
|
|
3511
3504
|
}
|
|
3512
3505
|
});
|
|
3513
3506
|
|
|
@@ -6133,15 +6126,23 @@ var buildMessageSection = (messageLines, details, _ctx, opts) => {
|
|
|
6133
6126
|
const fallbackLines = [];
|
|
6134
6127
|
if (hasOnlyBareError) {
|
|
6135
6128
|
const startFrom = hintIdx >= 0 ? hintIdx + 1 : 0;
|
|
6129
|
+
let started = false;
|
|
6136
6130
|
for (let i = startFrom; i < lines.length; i += 1) {
|
|
6137
6131
|
const candidate = lines[i];
|
|
6138
|
-
if (
|
|
6132
|
+
if (isStackLine(candidate)) {
|
|
6139
6133
|
break;
|
|
6140
6134
|
}
|
|
6141
|
-
if (
|
|
6135
|
+
if (!candidate.trim()) {
|
|
6136
|
+
if (!started) {
|
|
6137
|
+
continue;
|
|
6138
|
+
}
|
|
6142
6139
|
break;
|
|
6143
6140
|
}
|
|
6141
|
+
started = true;
|
|
6144
6142
|
fallbackLines.push(candidate);
|
|
6143
|
+
if (fallbackLines.length >= 6) {
|
|
6144
|
+
break;
|
|
6145
|
+
}
|
|
6145
6146
|
}
|
|
6146
6147
|
if (fallbackLines.length === 0 && details && details.messages && details.messages.length) {
|
|
6147
6148
|
fallbackLines.push(
|
|
@@ -6209,7 +6210,7 @@ var linesFromDetails = (details) => {
|
|
|
6209
6210
|
if (typeof obj.received === "string") {
|
|
6210
6211
|
pushMaybe(obj.received, messages);
|
|
6211
6212
|
}
|
|
6212
|
-
const arrays = ["errors", "causes", "aggregatedErrors"];
|
|
6213
|
+
const arrays = ["errors", "details", "issues", "inner", "causes", "aggregatedErrors"];
|
|
6213
6214
|
for (const key of arrays) {
|
|
6214
6215
|
const arr = obj[key];
|
|
6215
6216
|
if (Array.isArray(arr)) {
|
|
@@ -6218,7 +6219,7 @@ var linesFromDetails = (details) => {
|
|
|
6218
6219
|
}
|
|
6219
6220
|
}
|
|
6220
6221
|
}
|
|
6221
|
-
const nestedCandidates = ["error", "cause", "matcherResult"];
|
|
6222
|
+
const nestedCandidates = ["error", "cause", "matcherResult", "context", "data"];
|
|
6222
6223
|
for (const key of nestedCandidates) {
|
|
6223
6224
|
if (obj[key] && typeof obj[key] === "object") {
|
|
6224
6225
|
visitDeep(obj[key], depth + 1);
|
|
@@ -6247,9 +6248,7 @@ var linesFromDetails = (details) => {
|
|
|
6247
6248
|
pushMaybe(matcher.expected, messages);
|
|
6248
6249
|
pushMaybe(matcher.received, messages);
|
|
6249
6250
|
}
|
|
6250
|
-
|
|
6251
|
-
visitDeep(detail, 0);
|
|
6252
|
-
}
|
|
6251
|
+
visitDeep(detail, 0);
|
|
6253
6252
|
}
|
|
6254
6253
|
}
|
|
6255
6254
|
return { stacks, messages };
|
|
@@ -6313,24 +6312,31 @@ var buildConsoleSection = (maybeConsole) => {
|
|
|
6313
6312
|
var buildFallbackMessageBlock = (messageLines, details) => {
|
|
6314
6313
|
const normalize2 = (arr) => arr.map((lineText) => stripAnsiSimple(lineText)).filter((line) => line.trim().length > 0);
|
|
6315
6314
|
const normalized = normalize2(messageLines);
|
|
6316
|
-
const informative = normalized.filter(
|
|
6315
|
+
const informative = normalized.filter(
|
|
6316
|
+
(line) => !/^\s*(?:Error|AssertionError):?\s*$/i.test(line)
|
|
6317
|
+
);
|
|
6317
6318
|
if (informative.length > 0) {
|
|
6318
6319
|
return [];
|
|
6319
6320
|
}
|
|
6320
6321
|
const errorIdx = normalized.findIndex(
|
|
6321
|
-
(line) => /(TypeError|ReferenceError|SyntaxError|RangeError|AssertionError|Error)
|
|
6322
|
+
(line) => /(TypeError|ReferenceError|SyntaxError|RangeError|AssertionError|Error):?/i.test(line)
|
|
6322
6323
|
);
|
|
6323
6324
|
const collected = [];
|
|
6324
6325
|
if (errorIdx >= 0) {
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6326
|
+
let started = false;
|
|
6327
|
+
for (let i = errorIdx + 1; i < messageLines.length && collected.length < 8; i += 1) {
|
|
6328
|
+
const raw = stripAnsiSimple(messageLines[i]);
|
|
6329
|
+
if (isStackLine(raw)) {
|
|
6328
6330
|
break;
|
|
6329
6331
|
}
|
|
6330
|
-
if (
|
|
6332
|
+
if (!raw.trim()) {
|
|
6333
|
+
if (!started) {
|
|
6334
|
+
continue;
|
|
6335
|
+
}
|
|
6331
6336
|
break;
|
|
6332
6337
|
}
|
|
6333
|
-
|
|
6338
|
+
started = true;
|
|
6339
|
+
collected.push(raw);
|
|
6334
6340
|
}
|
|
6335
6341
|
}
|
|
6336
6342
|
const fromDetails = collected.length > 0 ? [] : normalize2(details.messages).slice(0, 6);
|
|
@@ -6578,39 +6584,13 @@ var makeCtx = (opts, showStacks = false) => {
|
|
|
6578
6584
|
return { cwd, width, showStacks, projectHint, editorCmd: opts?.editorCmd, readSource: readSource2 };
|
|
6579
6585
|
};
|
|
6580
6586
|
|
|
6581
|
-
// src/lib/formatter/bridge.ts
|
|
6582
|
-
var
|
|
6587
|
+
// src/lib/formatter/bridge/tryBridgeFallback.ts
|
|
6588
|
+
var import_json53 = __toESM(require_lib(), 1);
|
|
6583
6589
|
import * as fs6 from "node:fs";
|
|
6590
|
+
import * as path11 from "node:path";
|
|
6591
|
+
|
|
6592
|
+
// src/lib/formatter/bridge/logic.ts
|
|
6584
6593
|
import * as path10 from "node:path";
|
|
6585
|
-
var colorTokens2 = {
|
|
6586
|
-
pass: Colors.Success,
|
|
6587
|
-
fail: Colors.Failure,
|
|
6588
|
-
skip: Colors.Skip,
|
|
6589
|
-
todo: Colors.Todo,
|
|
6590
|
-
passPill: (text) => BackgroundColors.Success(ansi.white(` ${text} `)),
|
|
6591
|
-
failPill: (text) => BackgroundColors.Failure(ansi.white(` ${text} `))
|
|
6592
|
-
};
|
|
6593
|
-
var by = (keySelector) => (left, right) => keySelector(left) - keySelector(right);
|
|
6594
|
-
var isObject = (candidateValue) => !!candidateValue && typeof candidateValue === "object";
|
|
6595
|
-
var asHttpList = (candidateValue) => Array.isArray(candidateValue) ? candidateValue : [];
|
|
6596
|
-
var summarizeUrl = (method, url, route) => {
|
|
6597
|
-
const base = route || url || "";
|
|
6598
|
-
const qs = url && url.includes("?") ? ` ? ${url.split("?")[1]}` : "";
|
|
6599
|
-
return [method || "", base, qs].filter(Boolean).join(" ").trim();
|
|
6600
|
-
};
|
|
6601
|
-
var stripBridgeEventsFromConsole = (maybeConsole) => {
|
|
6602
|
-
if (!Array.isArray(maybeConsole)) {
|
|
6603
|
-
return maybeConsole;
|
|
6604
|
-
}
|
|
6605
|
-
return maybeConsole.filter((entry) => {
|
|
6606
|
-
try {
|
|
6607
|
-
const raw = Array.isArray(entry.message) ? entry.message.map(String).join(" ") : String(entry.message ?? "");
|
|
6608
|
-
return !raw.includes("[JEST-BRIDGE-EVENT]");
|
|
6609
|
-
} catch {
|
|
6610
|
-
return true;
|
|
6611
|
-
}
|
|
6612
|
-
});
|
|
6613
|
-
};
|
|
6614
6594
|
var extractBridgePath2 = (raw, cwd) => {
|
|
6615
6595
|
const matches = Array.from(
|
|
6616
6596
|
raw.matchAll(/Test results written to:\s+([^\n\r]+jest-bridge-[^\s'"]+\.json)/g)
|
|
@@ -6618,7 +6598,7 @@ var extractBridgePath2 = (raw, cwd) => {
|
|
|
6618
6598
|
if (!matches.length) {
|
|
6619
6599
|
return null;
|
|
6620
6600
|
}
|
|
6621
|
-
const jsonPath = (matches[matches.length - 1][1] ?? "").trim().replace(/^["
|
|
6601
|
+
const jsonPath = (matches[matches.length - 1][1] ?? "").trim().replace(/^['"`]|['"`]$/g, "");
|
|
6622
6602
|
return path10.isAbsolute(jsonPath) ? jsonPath : path10.resolve(cwd, jsonPath).replace(/\\/g, "/");
|
|
6623
6603
|
};
|
|
6624
6604
|
var isTransportError = (msg) => {
|
|
@@ -6627,25 +6607,6 @@ var isTransportError = (msg) => {
|
|
|
6627
6607
|
lowercaseMessage
|
|
6628
6608
|
);
|
|
6629
6609
|
};
|
|
6630
|
-
var envNumber = (name, fallback) => {
|
|
6631
|
-
const parsed = Number(process.env[name]);
|
|
6632
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
6633
|
-
};
|
|
6634
|
-
var HEADLAMP_HTTP_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_WINDOW_MS", 3e3);
|
|
6635
|
-
var HEADLAMP_HTTP_STRICT_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_STRICT_WINDOW_MS", 600);
|
|
6636
|
-
var HEADLAMP_HTTP_MIN_SCORE = () => envNumber("HEADLAMP_HTTP_MIN_SCORE", 1200);
|
|
6637
|
-
var HEADLAMP_HTTP_DIFF_LIMIT = () => envNumber("HEADLAMP_HTTP_DIFF_LIMIT", 6);
|
|
6638
|
-
var HEADLAMP_HTTP_SHOW_MISS = () => process.env.HEADLAMP_HTTP_MISS === "1";
|
|
6639
|
-
var eventsNear = (http, ts, testPath, windowMs = HEADLAMP_HTTP_WINDOW_MS()) => {
|
|
6640
|
-
if (typeof ts !== "number" || !Number.isFinite(ts)) {
|
|
6641
|
-
return [];
|
|
6642
|
-
}
|
|
6643
|
-
return http.filter((e) => {
|
|
6644
|
-
const timeOk = typeof e.timestampMs === "number" && Math.abs(e.timestampMs - ts) <= windowMs;
|
|
6645
|
-
const pathOk = !testPath || e.testPath === testPath;
|
|
6646
|
-
return timeOk && pathOk;
|
|
6647
|
-
});
|
|
6648
|
-
};
|
|
6649
6610
|
var parseMethodPathFromTitle = (title) => {
|
|
6650
6611
|
if (!title) {
|
|
6651
6612
|
return {};
|
|
@@ -6653,35 +6614,6 @@ var parseMethodPathFromTitle = (title) => {
|
|
|
6653
6614
|
const matchResult = title.match(/\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\s+([^\s)]+)/i);
|
|
6654
6615
|
return matchResult ? { method: matchResult[1]?.toUpperCase(), path: matchResult[2] } : {};
|
|
6655
6616
|
};
|
|
6656
|
-
var isHttpStatusNumber = (statusNumber) => typeof statusNumber === "number" && statusNumber >= 100 && statusNumber <= 599;
|
|
6657
|
-
var hasStatusSemantics = (assertionLike) => {
|
|
6658
|
-
if (!assertionLike) {
|
|
6659
|
-
return false;
|
|
6660
|
-
}
|
|
6661
|
-
if (isHttpStatusNumber(assertionLike.expectedNumber) || isHttpStatusNumber(assertionLike.receivedNumber)) {
|
|
6662
|
-
return true;
|
|
6663
|
-
}
|
|
6664
|
-
const combinedRaw = `${assertionLike.matcher ?? ""} ${assertionLike.message ?? ""}`;
|
|
6665
|
-
const combinedMessage = combinedRaw.toLowerCase();
|
|
6666
|
-
return /\bstatus(code)?\b|\btohaves(tatus|tatuscode)\b/.test(combinedMessage);
|
|
6667
|
-
};
|
|
6668
|
-
var fileSuggestsHttp = (relPath2) => /(?:^|\/)(routes?|api|controllers?|e2e|integration)(?:\/|\.test\.)/i.test(relPath2);
|
|
6669
|
-
var inferHttpNumbersFromText = (lines) => {
|
|
6670
|
-
const text = lines.join("\n");
|
|
6671
|
-
const match = text.match(/Expected:\s*(\d{3})[\s\S]*?Received:\s*(\d{3})/i);
|
|
6672
|
-
if (match) {
|
|
6673
|
-
return { expectedNumber: Number(match[1]), receivedNumber: Number(match[2]) };
|
|
6674
|
-
}
|
|
6675
|
-
return {};
|
|
6676
|
-
};
|
|
6677
|
-
var titleSuggestsHttp = (title) => {
|
|
6678
|
-
const { method, path: parsedPath } = parseMethodPathFromTitle(title);
|
|
6679
|
-
return Boolean(method || parsedPath && parsedPath.startsWith("/"));
|
|
6680
|
-
};
|
|
6681
|
-
var isHttpRelevant = (ctx) => {
|
|
6682
|
-
const assertionCtx = ctx.assertion;
|
|
6683
|
-
return ctx.hasTransportSignal || ctx.httpCountInSameTest > 0 || titleSuggestsHttp(ctx.title) || hasStatusSemantics(assertionCtx) || fileSuggestsHttp(ctx.relPath);
|
|
6684
|
-
};
|
|
6685
6617
|
var routeSimilarityScore = (hint, evt) => {
|
|
6686
6618
|
if (!hint.path && !hint.method) {
|
|
6687
6619
|
return 0;
|
|
@@ -6702,6 +6634,15 @@ var routeSimilarityScore = (hint, evt) => {
|
|
|
6702
6634
|
}
|
|
6703
6635
|
return methodOk * 10;
|
|
6704
6636
|
};
|
|
6637
|
+
var envNumber = (name, fallback) => {
|
|
6638
|
+
const parsed = Number(process.env[name]);
|
|
6639
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
6640
|
+
};
|
|
6641
|
+
var HEADLAMP_HTTP_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_WINDOW_MS", 3e3);
|
|
6642
|
+
var HEADLAMP_HTTP_STRICT_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_STRICT_WINDOW_MS", 600);
|
|
6643
|
+
var HEADLAMP_HTTP_MIN_SCORE = () => envNumber("HEADLAMP_HTTP_MIN_SCORE", 1200);
|
|
6644
|
+
var HEADLAMP_HTTP_DIFF_LIMIT = () => envNumber("HEADLAMP_HTTP_DIFF_LIMIT", 6);
|
|
6645
|
+
var HEADLAMP_HTTP_SHOW_MISS = () => process.env.HEADLAMP_HTTP_MISS === "1";
|
|
6705
6646
|
var scoreHttpForAssertion = (assertion, titleHint) => (candidateEvent) => {
|
|
6706
6647
|
const tsA = assertion.timestampMs;
|
|
6707
6648
|
const tsH = candidateEvent.timestampMs;
|
|
@@ -6722,14 +6663,20 @@ var pickRelevantHttp = (assertion, http, ctx) => {
|
|
|
6722
6663
|
const windowMs = isTransportError(assertion.message) ? HEADLAMP_HTTP_STRICT_WINDOW_MS() : HEADLAMP_HTTP_WINDOW_MS();
|
|
6723
6664
|
let pool = strictPool;
|
|
6724
6665
|
if (!pool.length) {
|
|
6725
|
-
pool = http.filter(
|
|
6726
|
-
|
|
6727
|
-
|
|
6666
|
+
pool = http.filter((event) => {
|
|
6667
|
+
const samePath = event.testPath === ctx.testPath;
|
|
6668
|
+
const tsA = assertion.timestampMs;
|
|
6669
|
+
const tsH = event.timestampMs;
|
|
6670
|
+
const inWindow = typeof tsA === "number" && typeof tsH === "number" && Math.abs(tsH - tsA) <= windowMs;
|
|
6671
|
+
return samePath && inWindow;
|
|
6672
|
+
});
|
|
6728
6673
|
}
|
|
6729
6674
|
if (!pool.length) {
|
|
6730
|
-
pool = http.filter(
|
|
6731
|
-
|
|
6732
|
-
|
|
6675
|
+
pool = http.filter((event) => {
|
|
6676
|
+
const tsA = assertion.timestampMs;
|
|
6677
|
+
const tsH = event.timestampMs;
|
|
6678
|
+
return typeof tsA === "number" && typeof tsH === "number" && Math.abs(tsH - tsA) <= windowMs;
|
|
6679
|
+
});
|
|
6733
6680
|
}
|
|
6734
6681
|
if (!pool.length) {
|
|
6735
6682
|
return void 0;
|
|
@@ -6739,9 +6686,11 @@ var pickRelevantHttp = (assertion, http, ctx) => {
|
|
|
6739
6686
|
const threshold = isTransportError(assertion.message) ? Math.max(HEADLAMP_HTTP_MIN_SCORE(), 1400) : HEADLAMP_HTTP_MIN_SCORE();
|
|
6740
6687
|
return best && best.s >= threshold ? best.h : void 0;
|
|
6741
6688
|
};
|
|
6742
|
-
|
|
6689
|
+
|
|
6690
|
+
// src/lib/formatter/bridge/utils.ts
|
|
6691
|
+
var import_json52 = __toESM(require_lib(), 1);
|
|
6743
6692
|
var coerceJestJsonToBridge = (raw) => {
|
|
6744
|
-
if (
|
|
6693
|
+
if (raw && typeof raw === "object" && "aggregated" in raw) {
|
|
6745
6694
|
return raw;
|
|
6746
6695
|
}
|
|
6747
6696
|
const j = raw;
|
|
@@ -6768,19 +6717,85 @@ var coerceJestJsonToBridge = (raw) => {
|
|
|
6768
6717
|
}))
|
|
6769
6718
|
})),
|
|
6770
6719
|
aggregated: {
|
|
6771
|
-
numTotalTestSuites:
|
|
6772
|
-
numPassedTestSuites:
|
|
6773
|
-
numFailedTestSuites:
|
|
6774
|
-
numTotalTests:
|
|
6775
|
-
numPassedTests:
|
|
6776
|
-
numFailedTests:
|
|
6777
|
-
numPendingTests:
|
|
6778
|
-
numTodoTests:
|
|
6779
|
-
startTime:
|
|
6780
|
-
success:
|
|
6720
|
+
numTotalTestSuites: raw.numTotalTestSuites,
|
|
6721
|
+
numPassedTestSuites: raw.numPassedTestSuites,
|
|
6722
|
+
numFailedTestSuites: raw.numFailedTestSuites,
|
|
6723
|
+
numTotalTests: raw.numTotalTests,
|
|
6724
|
+
numPassedTests: raw.numPassedTests,
|
|
6725
|
+
numFailedTests: raw.numFailedTests,
|
|
6726
|
+
numPendingTests: raw.numPendingTests,
|
|
6727
|
+
numTodoTests: raw.numTodoTests,
|
|
6728
|
+
startTime: raw.startTime,
|
|
6729
|
+
success: raw.success,
|
|
6730
|
+
runTimeMs: raw.aggregated?.runTimeMs
|
|
6781
6731
|
}
|
|
6782
6732
|
};
|
|
6783
6733
|
};
|
|
6734
|
+
var colorTokens2 = {
|
|
6735
|
+
pass: Colors.Success,
|
|
6736
|
+
fail: Colors.Failure,
|
|
6737
|
+
skip: Colors.Skip,
|
|
6738
|
+
todo: Colors.Todo,
|
|
6739
|
+
passPill: (text) => BackgroundColors.Success(ansi.white(` ${text} `)),
|
|
6740
|
+
failPill: (text) => BackgroundColors.Failure(ansi.white(` ${text} `))
|
|
6741
|
+
};
|
|
6742
|
+
var by = (keySelector) => (left, right) => keySelector(left) - keySelector(right);
|
|
6743
|
+
var isObject = (candidateValue) => !!candidateValue && typeof candidateValue === "object";
|
|
6744
|
+
var asHttpList = (candidateValue) => Array.isArray(candidateValue) ? candidateValue : [];
|
|
6745
|
+
var summarizeUrl = (method, url, route) => {
|
|
6746
|
+
const base = route || url || "";
|
|
6747
|
+
const qs = url && url.includes("?") ? ` ? ${url.split("?")[1]}` : "";
|
|
6748
|
+
return [method || "", base, qs].filter(Boolean).join(" ").trim();
|
|
6749
|
+
};
|
|
6750
|
+
var stripBridgeEventsFromConsole = (maybeConsole) => {
|
|
6751
|
+
if (!Array.isArray(maybeConsole)) {
|
|
6752
|
+
return maybeConsole;
|
|
6753
|
+
}
|
|
6754
|
+
return maybeConsole.filter((entry) => {
|
|
6755
|
+
try {
|
|
6756
|
+
const raw = Array.isArray(entry.message) ? entry.message.map(String).join(" ") : String(entry.message ?? "");
|
|
6757
|
+
return !raw.includes("[JEST-BRIDGE-EVENT]");
|
|
6758
|
+
} catch {
|
|
6759
|
+
return true;
|
|
6760
|
+
}
|
|
6761
|
+
});
|
|
6762
|
+
};
|
|
6763
|
+
var eventsNear = (http, ts, testPath, windowMs = HEADLAMP_HTTP_WINDOW_MS()) => {
|
|
6764
|
+
if (typeof ts !== "number" || !Number.isFinite(ts)) {
|
|
6765
|
+
return [];
|
|
6766
|
+
}
|
|
6767
|
+
return http.filter((event) => {
|
|
6768
|
+
const timeOk = typeof event.timestampMs === "number" && Math.abs(event.timestampMs - ts) <= windowMs;
|
|
6769
|
+
const pathOk = !testPath || event.testPath === testPath;
|
|
6770
|
+
return timeOk && pathOk;
|
|
6771
|
+
});
|
|
6772
|
+
};
|
|
6773
|
+
var isHttpStatusNumber = (statusNumber) => typeof statusNumber === "number" && statusNumber >= 100 && statusNumber <= 599;
|
|
6774
|
+
var inferHttpNumbersFromText = (lines) => {
|
|
6775
|
+
const text = lines.join("\n");
|
|
6776
|
+
const match = text.match(/Expected:\s*(\d{3})[\s\S]*?Received:\s*(\d{3})/i);
|
|
6777
|
+
if (match) {
|
|
6778
|
+
return { expectedNumber: Number(match[1]), receivedNumber: Number(match[2]) };
|
|
6779
|
+
}
|
|
6780
|
+
return {};
|
|
6781
|
+
};
|
|
6782
|
+
var titleSuggestsHttp = (title) => {
|
|
6783
|
+
const { method, path: parsedPath } = parseMethodPathFromTitle(title);
|
|
6784
|
+
return Boolean(method || parsedPath && parsedPath.startsWith("/"));
|
|
6785
|
+
};
|
|
6786
|
+
var hasStatusSemantics = (assertionLike) => {
|
|
6787
|
+
if (!assertionLike) {
|
|
6788
|
+
return false;
|
|
6789
|
+
}
|
|
6790
|
+
if (isHttpStatusNumber(assertionLike.expectedNumber) || isHttpStatusNumber(assertionLike.receivedNumber)) {
|
|
6791
|
+
return true;
|
|
6792
|
+
}
|
|
6793
|
+
const combinedRaw = `${assertionLike.matcher ?? ""} ${assertionLike.message ?? ""}`;
|
|
6794
|
+
const combinedMessage = combinedRaw.toLowerCase();
|
|
6795
|
+
return /\bstatus(code)?\b|\btohaves(tatus|tatuscode)\b/.test(combinedMessage);
|
|
6796
|
+
};
|
|
6797
|
+
var fileSuggestsHttp = (relPath2) => /(?:^|\/)(routes?|api|controllers?|e2e|integration)(?:\/|\.test\.)/i.test(relPath2);
|
|
6798
|
+
var isHttpRelevant = (ctx) => ctx.hasTransportSignal || ctx.httpCountInSameTest > 0 || titleSuggestsHttp(ctx.title) || hasStatusSemantics(ctx.assertion) || fileSuggestsHttp(ctx.relPath);
|
|
6784
6799
|
var vitestFooter = (agg, durationMs) => {
|
|
6785
6800
|
const files = [
|
|
6786
6801
|
agg.numFailedTestSuites ? colorTokens2.fail(`${agg.numFailedTestSuites} failed`) : "",
|
|
@@ -7257,13 +7272,21 @@ var renderVitestFromJestJSON = (data, ctx, opts) => {
|
|
|
7257
7272
|
out.push(vitestFooter(data.aggregated));
|
|
7258
7273
|
return out.join("\n");
|
|
7259
7274
|
};
|
|
7275
|
+
|
|
7276
|
+
// src/lib/formatter/bridge/tryBridgeFallback.ts
|
|
7260
7277
|
var tryBridgeFallback = (raw, ctx, opts) => {
|
|
7261
|
-
|
|
7278
|
+
let bridgeJsonPath = extractBridgePath2(raw, ctx.cwd);
|
|
7279
|
+
if (!bridgeJsonPath) {
|
|
7280
|
+
const def = path11.resolve(ctx.cwd, "coverage/jest-run.json").replace(/\\/g, "/");
|
|
7281
|
+
if (fs6.existsSync(def)) {
|
|
7282
|
+
bridgeJsonPath = def;
|
|
7283
|
+
}
|
|
7284
|
+
}
|
|
7262
7285
|
if (!bridgeJsonPath || !fs6.existsSync(bridgeJsonPath)) {
|
|
7263
7286
|
return null;
|
|
7264
7287
|
}
|
|
7265
7288
|
try {
|
|
7266
|
-
const json =
|
|
7289
|
+
const json = import_json53.default.parse(fs6.readFileSync(bridgeJsonPath, "utf8"));
|
|
7267
7290
|
const bridge = coerceJestJsonToBridge(json);
|
|
7268
7291
|
return renderVitestFromJestJSON(bridge, ctx, opts);
|
|
7269
7292
|
} catch {
|
|
@@ -7281,23 +7304,39 @@ var formatJestOutputVitest = (raw, opts) => pipe(
|
|
|
7281
7304
|
(state) => ({ ...state, chunks: parseChunks(state.raw) }),
|
|
7282
7305
|
(state) => ({
|
|
7283
7306
|
...state,
|
|
7284
|
-
|
|
7307
|
+
native: renderChunks(state.chunks, state.ctx, mkPrettyFns(), {
|
|
7285
7308
|
onlyFailures: Boolean(state.opts?.onlyFailures)
|
|
7286
|
-
})
|
|
7309
|
+
}).text
|
|
7287
7310
|
}),
|
|
7288
|
-
(state) => {
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
}
|
|
7292
|
-
const fallback = tryBridgeFallback(state.raw, state.ctx, {
|
|
7311
|
+
(state) => ({
|
|
7312
|
+
...state,
|
|
7313
|
+
bridge: tryBridgeFallback(state.raw, state.ctx, {
|
|
7293
7314
|
onlyFailures: Boolean(state.opts?.onlyFailures)
|
|
7294
|
-
})
|
|
7295
|
-
|
|
7296
|
-
|
|
7315
|
+
}) || null
|
|
7316
|
+
}),
|
|
7317
|
+
(state) => {
|
|
7318
|
+
const out = [];
|
|
7319
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7320
|
+
const pushUnique = (text) => {
|
|
7321
|
+
if (!text) {
|
|
7322
|
+
return;
|
|
7323
|
+
}
|
|
7324
|
+
for (const line of text.split(/\r?\n/)) {
|
|
7325
|
+
const key = stripAnsiSimple(line);
|
|
7326
|
+
if (!seen.has(key)) {
|
|
7327
|
+
out.push(line);
|
|
7328
|
+
seen.add(key);
|
|
7329
|
+
}
|
|
7330
|
+
}
|
|
7331
|
+
};
|
|
7332
|
+
pushUnique(state.native);
|
|
7333
|
+
if (state.bridge) {
|
|
7334
|
+
if (out.length) {
|
|
7335
|
+
out.push("");
|
|
7336
|
+
}
|
|
7337
|
+
pushUnique(state.bridge);
|
|
7297
7338
|
}
|
|
7298
|
-
|
|
7299
|
-
return prefix ? `${prefix}
|
|
7300
|
-
${fallback}` : fallback;
|
|
7339
|
+
return out.join("\n");
|
|
7301
7340
|
}
|
|
7302
7341
|
);
|
|
7303
7342
|
|
|
@@ -7414,8 +7453,8 @@ module.exports = BridgeReporter;`;
|
|
|
7414
7453
|
init_env_utils();
|
|
7415
7454
|
init_exec();
|
|
7416
7455
|
init_args();
|
|
7417
|
-
import * as
|
|
7418
|
-
import * as
|
|
7456
|
+
import * as path12 from "node:path";
|
|
7457
|
+
import * as os3 from "node:os";
|
|
7419
7458
|
import * as fsSync3 from "node:fs";
|
|
7420
7459
|
import * as fs7 from "node:fs/promises";
|
|
7421
7460
|
import * as LibReport from "istanbul-lib-report";
|
|
@@ -7694,7 +7733,7 @@ var mergeLcov = async () => {
|
|
|
7694
7733
|
try {
|
|
7695
7734
|
const entries = fsSync3.readdirSync(dir, { withFileTypes: true });
|
|
7696
7735
|
for (const entry of entries) {
|
|
7697
|
-
const full =
|
|
7736
|
+
const full = path12.join(dir, entry.name);
|
|
7698
7737
|
if (entry.isDirectory()) {
|
|
7699
7738
|
out.push(...collectLcovs(full));
|
|
7700
7739
|
} else if (entry.isFile() && entry.name === "lcov.info") {
|
|
@@ -7706,8 +7745,8 @@ var mergeLcov = async () => {
|
|
|
7706
7745
|
return out;
|
|
7707
7746
|
};
|
|
7708
7747
|
try {
|
|
7709
|
-
const jestRoot =
|
|
7710
|
-
const candidates = [
|
|
7748
|
+
const jestRoot = path12.join("coverage", "jest");
|
|
7749
|
+
const candidates = [path12.join(jestRoot, "lcov.info"), ...collectLcovs(jestRoot)].map((candidatePath) => path12.resolve(candidatePath)).filter((absolutePath, index, arr) => arr.indexOf(absolutePath) === index);
|
|
7711
7750
|
for (const filePath of candidates) {
|
|
7712
7751
|
try {
|
|
7713
7752
|
const content = await readOrEmpty(filePath);
|
|
@@ -7747,7 +7786,7 @@ var emitMergedCoverage = async (ui, opts) => {
|
|
|
7747
7786
|
try {
|
|
7748
7787
|
const entries = fsSync3.readdirSync(dir, { withFileTypes: true });
|
|
7749
7788
|
for (const entry of entries) {
|
|
7750
|
-
const full =
|
|
7789
|
+
const full = path12.join(dir, entry.name);
|
|
7751
7790
|
if (entry.isDirectory()) {
|
|
7752
7791
|
out.push(...listJsons(full));
|
|
7753
7792
|
} else if (entry.isFile() && entry.name === "coverage-final.json") {
|
|
@@ -7758,11 +7797,11 @@ var emitMergedCoverage = async (ui, opts) => {
|
|
|
7758
7797
|
}
|
|
7759
7798
|
return out;
|
|
7760
7799
|
};
|
|
7761
|
-
const coverageRoot =
|
|
7800
|
+
const coverageRoot = path12.join("coverage", "jest");
|
|
7762
7801
|
const jsonCandidates = [
|
|
7763
|
-
|
|
7802
|
+
path12.join(coverageRoot, "coverage-final.json"),
|
|
7764
7803
|
...listJsons(coverageRoot)
|
|
7765
|
-
].map((candidatePath) =>
|
|
7804
|
+
].map((candidatePath) => path12.resolve(candidatePath)).filter((absolutePath, index, arr) => {
|
|
7766
7805
|
const isFirst = arr.indexOf(absolutePath) === index;
|
|
7767
7806
|
const exists = fsSync3.existsSync(absolutePath);
|
|
7768
7807
|
return isFirst && exists;
|
|
@@ -7824,7 +7863,7 @@ var emitMergedCoverage = async (ui, opts) => {
|
|
|
7824
7863
|
executedTests: opts.executedTests ?? []
|
|
7825
7864
|
});
|
|
7826
7865
|
const context = LibReport.createContext({
|
|
7827
|
-
dir:
|
|
7866
|
+
dir: path12.resolve("coverage", "merged"),
|
|
7828
7867
|
coverageMap: filteredMap,
|
|
7829
7868
|
defaultSummarizer: "nested"
|
|
7830
7869
|
});
|
|
@@ -7892,8 +7931,8 @@ var emitMergedCoverage = async (ui, opts) => {
|
|
|
7892
7931
|
for (const reporter of reporters) {
|
|
7893
7932
|
reporter.execute(context);
|
|
7894
7933
|
}
|
|
7895
|
-
const textPath =
|
|
7896
|
-
const summaryPath =
|
|
7934
|
+
const textPath = path12.resolve("coverage", "merged", "coverage.txt");
|
|
7935
|
+
const summaryPath = path12.resolve("coverage", "merged", "coverage-summary.txt");
|
|
7897
7936
|
const filesToPrint = [];
|
|
7898
7937
|
if (fsSync3.existsSync(textPath)) {
|
|
7899
7938
|
filesToPrint.push(textPath);
|
|
@@ -8036,13 +8075,13 @@ var program = async () => {
|
|
|
8036
8075
|
const rels2 = Array.from(
|
|
8037
8076
|
/* @__PURE__ */ new Set([...branchDiff, ...stagedNow, ...unstagedNow, ...untrackedNow])
|
|
8038
8077
|
);
|
|
8039
|
-
return rels2.map((rel) =>
|
|
8078
|
+
return rels2.map((rel) => path12.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
|
|
8040
8079
|
}
|
|
8041
8080
|
const staged = mode === "staged" || mode === "all" ? await collect("git", ["diff", "--name-only", "--diff-filter=ACMRTUXB", "--cached"]) : [];
|
|
8042
8081
|
const unstagedTracked = mode === "unstaged" || mode === "all" ? await collect("git", ["diff", "--name-only", "--diff-filter=ACMRTUXB"]) : [];
|
|
8043
8082
|
const untracked = mode === "unstaged" || mode === "all" ? await collect("git", ["ls-files", "--others", "--exclude-standard"]) : [];
|
|
8044
8083
|
const rels = Array.from(/* @__PURE__ */ new Set([...staged, ...unstagedTracked, ...untracked]));
|
|
8045
|
-
return rels.map((rel) =>
|
|
8084
|
+
return rels.map((rel) => path12.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
|
|
8046
8085
|
};
|
|
8047
8086
|
const repoRootForChanged = workspaceRoot ?? await findRepoRoot();
|
|
8048
8087
|
const changedSelectionAbs = changed ? await getChangedFiles(changed, repoRootForChanged) : [];
|
|
@@ -8067,18 +8106,18 @@ var program = async () => {
|
|
|
8067
8106
|
if (!token) {
|
|
8068
8107
|
continue;
|
|
8069
8108
|
}
|
|
8070
|
-
const isAbs =
|
|
8109
|
+
const isAbs = path12.isAbsolute(token);
|
|
8071
8110
|
const looksLikeRelPath = /[\\/]/.test(token);
|
|
8072
8111
|
let candidateFromRoot;
|
|
8073
8112
|
if (token.startsWith("/")) {
|
|
8074
|
-
candidateFromRoot =
|
|
8113
|
+
candidateFromRoot = path12.join(repoRoot, token.slice(1));
|
|
8075
8114
|
} else if (looksLikeRelPath) {
|
|
8076
|
-
candidateFromRoot =
|
|
8115
|
+
candidateFromRoot = path12.join(repoRoot, token);
|
|
8077
8116
|
} else {
|
|
8078
8117
|
candidateFromRoot = void 0;
|
|
8079
8118
|
}
|
|
8080
8119
|
const tryPushIfProd = (absPath) => {
|
|
8081
|
-
const norm =
|
|
8120
|
+
const norm = path12.resolve(absPath).replace(/\\/g, "/");
|
|
8082
8121
|
const isTest = /(^|\/)tests?\//i.test(norm) || /\.(test|spec)\.[tj]sx?$/i.test(norm);
|
|
8083
8122
|
if (!isTest && fsSync3.existsSync(norm)) {
|
|
8084
8123
|
results.add(norm);
|
|
@@ -8100,7 +8139,7 @@ var program = async () => {
|
|
|
8100
8139
|
}),
|
|
8101
8140
|
timeoutMs: 4e3
|
|
8102
8141
|
});
|
|
8103
|
-
const matches = out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((rel) =>
|
|
8142
|
+
const matches = out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((rel) => path12.resolve(repoRoot, rel).replace(/\\/g, "/")).filter(
|
|
8104
8143
|
(abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/") && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
|
|
8105
8144
|
);
|
|
8106
8145
|
matches.forEach((abs) => results.add(abs));
|
|
@@ -8121,8 +8160,8 @@ var program = async () => {
|
|
|
8121
8160
|
const jestDiscoveryArgs = selectionIncludesProdPaths ? stripPathTokens(jest) : jest;
|
|
8122
8161
|
const projectConfigs = [];
|
|
8123
8162
|
try {
|
|
8124
|
-
const baseCfg =
|
|
8125
|
-
const tsCfg =
|
|
8163
|
+
const baseCfg = path12.resolve("jest.config.js");
|
|
8164
|
+
const tsCfg = path12.resolve("jest.ts.config.js");
|
|
8126
8165
|
if (fsSync3.existsSync(baseCfg)) {
|
|
8127
8166
|
projectConfigs.push(baseCfg);
|
|
8128
8167
|
}
|
|
@@ -8139,7 +8178,7 @@ var program = async () => {
|
|
|
8139
8178
|
);
|
|
8140
8179
|
const prodSelections2 = expandedProdSelections;
|
|
8141
8180
|
for (const cfg of projectConfigs) {
|
|
8142
|
-
const cfgCwd =
|
|
8181
|
+
const cfgCwd = path12.dirname(cfg);
|
|
8143
8182
|
const allTests = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
|
|
8144
8183
|
cwd: cfgCwd
|
|
8145
8184
|
});
|
|
@@ -8152,7 +8191,7 @@ var program = async () => {
|
|
|
8152
8191
|
});
|
|
8153
8192
|
} catch (err) {
|
|
8154
8193
|
if (isDebug()) {
|
|
8155
|
-
console.warn(`direct selection failed for project ${
|
|
8194
|
+
console.warn(`direct selection failed for project ${path12.basename(cfg)}: ${String(err)}`);
|
|
8156
8195
|
}
|
|
8157
8196
|
}
|
|
8158
8197
|
perProjectFiles.set(cfg, directPerProject);
|
|
@@ -8164,7 +8203,7 @@ var program = async () => {
|
|
|
8164
8203
|
)} | related=${selectionIncludesProdPaths} | cwd=${repoRootForDiscovery}`
|
|
8165
8204
|
);
|
|
8166
8205
|
for (const cfg of projectConfigs) {
|
|
8167
|
-
const cfgCwd =
|
|
8206
|
+
const cfgCwd = path12.dirname(cfg);
|
|
8168
8207
|
const files = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
|
|
8169
8208
|
cwd: cfgCwd
|
|
8170
8209
|
});
|
|
@@ -8179,13 +8218,13 @@ var program = async () => {
|
|
|
8179
8218
|
);
|
|
8180
8219
|
const candidates = selectionHasPaths && selectionLooksLikeTest ? selectionTestPaths : files;
|
|
8181
8220
|
const absFiles = candidates.map(
|
|
8182
|
-
(candidatePath) =>
|
|
8221
|
+
(candidatePath) => path12.isAbsolute(candidatePath) ? candidatePath : path12.join(repoRootForDiscovery, candidatePath)
|
|
8183
8222
|
).map((absolutePath) => absolutePath.replace(/\\/g, "/"));
|
|
8184
8223
|
const onlyOwned = await filterCandidatesForProject(
|
|
8185
8224
|
cfg,
|
|
8186
8225
|
jestDiscoveryArgs,
|
|
8187
8226
|
absFiles,
|
|
8188
|
-
|
|
8227
|
+
path12.dirname(cfg)
|
|
8189
8228
|
);
|
|
8190
8229
|
perProjectFiltered.set(cfg, onlyOwned);
|
|
8191
8230
|
}
|
|
@@ -8197,7 +8236,7 @@ var program = async () => {
|
|
|
8197
8236
|
if (selectionHasPaths && prodSelections.length > 0) {
|
|
8198
8237
|
console.info(`rg related \u2192 prodSelections=${prodSelections.length} (starting)`);
|
|
8199
8238
|
const repoRootForRefinement = workspaceRoot ?? await findRepoRoot();
|
|
8200
|
-
const selectionKey = prodSelections.map((absPath) =>
|
|
8239
|
+
const selectionKey = prodSelections.map((absPath) => path12.relative(repoRootForRefinement, absPath).replace(/\\/g, "/")).sort((firstPath, secondPath) => firstPath.localeCompare(secondPath)).join("|");
|
|
8201
8240
|
const { cachedRelated: cachedRelated2, findRelatedTestsFast: findRelatedTestsFast2, DEFAULT_TEST_GLOBS: DEFAULT_TEST_GLOBS2 } = await Promise.resolve().then(() => (init_fast_related(), fast_related_exports));
|
|
8202
8241
|
const { DEFAULT_EXCLUDE: DEFAULT_EXCLUDE2 } = await Promise.resolve().then(() => (init_args(), args_exports));
|
|
8203
8242
|
const rgMatches = await cachedRelated2({
|
|
@@ -8227,7 +8266,7 @@ var program = async () => {
|
|
|
8227
8266
|
cfg,
|
|
8228
8267
|
jestDiscoveryArgs,
|
|
8229
8268
|
rgCandidates,
|
|
8230
|
-
|
|
8269
|
+
path12.dirname(cfg)
|
|
8231
8270
|
);
|
|
8232
8271
|
perProjectFromRg.set(cfg, owned);
|
|
8233
8272
|
}
|
|
@@ -8242,9 +8281,9 @@ var program = async () => {
|
|
|
8242
8281
|
} else {
|
|
8243
8282
|
const repoRootForScan = repoRootForDiscovery;
|
|
8244
8283
|
const toSeeds = (abs) => {
|
|
8245
|
-
const rel =
|
|
8284
|
+
const rel = path12.relative(repoRootForScan, abs).replace(/\\/g, "/");
|
|
8246
8285
|
const withoutExt = rel.replace(/\.(m?[tj]sx?)$/i, "");
|
|
8247
|
-
const base =
|
|
8286
|
+
const base = path12.basename(withoutExt);
|
|
8248
8287
|
const segs = withoutExt.split("/");
|
|
8249
8288
|
const tail2 = segs.slice(-2).join("/");
|
|
8250
8289
|
return Array.from(new Set([withoutExt, base, tail2].filter(Boolean)));
|
|
@@ -8259,8 +8298,8 @@ var program = async () => {
|
|
|
8259
8298
|
}
|
|
8260
8299
|
};
|
|
8261
8300
|
const resolveLocalImport = (fromFile, spec) => {
|
|
8262
|
-
const baseDir =
|
|
8263
|
-
const cand =
|
|
8301
|
+
const baseDir = path12.dirname(fromFile);
|
|
8302
|
+
const cand = path12.resolve(baseDir, spec);
|
|
8264
8303
|
const exts = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
8265
8304
|
for (const ext of exts) {
|
|
8266
8305
|
const full = ext ? `${cand}${ext}` : cand;
|
|
@@ -8269,7 +8308,7 @@ var program = async () => {
|
|
|
8269
8308
|
}
|
|
8270
8309
|
}
|
|
8271
8310
|
for (const ext of exts) {
|
|
8272
|
-
const full =
|
|
8311
|
+
const full = path12.join(cand, `index${ext}`);
|
|
8273
8312
|
if (fsSync3.existsSync(full)) {
|
|
8274
8313
|
return full;
|
|
8275
8314
|
}
|
|
@@ -8323,7 +8362,7 @@ var program = async () => {
|
|
|
8323
8362
|
cfg,
|
|
8324
8363
|
jestDiscoveryArgs,
|
|
8325
8364
|
keptCandidates,
|
|
8326
|
-
|
|
8365
|
+
path12.dirname(cfg)
|
|
8327
8366
|
);
|
|
8328
8367
|
perProjectFromScan.set(cfg, owned);
|
|
8329
8368
|
}
|
|
@@ -8353,7 +8392,7 @@ var program = async () => {
|
|
|
8353
8392
|
try {
|
|
8354
8393
|
const allAcross = [];
|
|
8355
8394
|
for (const cfg of projectConfigs) {
|
|
8356
|
-
const cfgCwd =
|
|
8395
|
+
const cfgCwd = path12.dirname(cfg);
|
|
8357
8396
|
const listed = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
|
|
8358
8397
|
cwd: cfgCwd
|
|
8359
8398
|
});
|
|
@@ -8367,9 +8406,9 @@ var program = async () => {
|
|
|
8367
8406
|
}
|
|
8368
8407
|
}
|
|
8369
8408
|
const seeds = prodSelections.map(
|
|
8370
|
-
(abs) =>
|
|
8409
|
+
(abs) => path12.relative(repoRoot, abs).replace(/\\/g, "/").replace(/\.(m?[tj]sx?)$/i, "")
|
|
8371
8410
|
).flatMap((rel) => {
|
|
8372
|
-
const base =
|
|
8411
|
+
const base = path12.basename(rel);
|
|
8373
8412
|
const segments = rel.split("/");
|
|
8374
8413
|
return Array.from(new Set([rel, base, segments.slice(-2).join("/")].filter(Boolean)));
|
|
8375
8414
|
});
|
|
@@ -8382,8 +8421,8 @@ var program = async () => {
|
|
|
8382
8421
|
}
|
|
8383
8422
|
};
|
|
8384
8423
|
const resolveLocalImport = (fromFile, spec) => {
|
|
8385
|
-
const baseDir =
|
|
8386
|
-
const candidate =
|
|
8424
|
+
const baseDir = path12.dirname(fromFile);
|
|
8425
|
+
const candidate = path12.resolve(baseDir, spec);
|
|
8387
8426
|
const extensions = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"];
|
|
8388
8427
|
for (const ext of extensions) {
|
|
8389
8428
|
const fullPath = ext ? `${candidate}${ext}` : candidate;
|
|
@@ -8392,7 +8431,7 @@ var program = async () => {
|
|
|
8392
8431
|
}
|
|
8393
8432
|
}
|
|
8394
8433
|
for (const ext of extensions) {
|
|
8395
|
-
const fullPath =
|
|
8434
|
+
const fullPath = path12.join(candidate, `index${ext}`);
|
|
8396
8435
|
if (fsSync3.existsSync(fullPath)) {
|
|
8397
8436
|
return fullPath;
|
|
8398
8437
|
}
|
|
@@ -8549,10 +8588,10 @@ var program = async () => {
|
|
|
8549
8588
|
};
|
|
8550
8589
|
const prodSeedsForRun = (() => {
|
|
8551
8590
|
const changedAbs = (changedSelectionAbs ?? []).map(
|
|
8552
|
-
(absPath) =>
|
|
8591
|
+
(absPath) => path12.resolve(absPath).replace(/\\/g, "/")
|
|
8553
8592
|
);
|
|
8554
8593
|
const selAbs = selectionPathsAugmented.map(
|
|
8555
|
-
(pathToken) =>
|
|
8594
|
+
(pathToken) => path12.resolve(pathToken).replace(/\\/g, "/")
|
|
8556
8595
|
);
|
|
8557
8596
|
return (changedAbs.length ? changedAbs : selAbs).filter(
|
|
8558
8597
|
(abs) => /[\\/]/.test(abs) && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
|
|
@@ -8567,17 +8606,17 @@ var program = async () => {
|
|
|
8567
8606
|
const cfg = projectsToRun[projIndex];
|
|
8568
8607
|
const files = perProjectFiltered.get(cfg) ?? [];
|
|
8569
8608
|
if (files.length === 0) {
|
|
8570
|
-
console.info(`Project ${
|
|
8609
|
+
console.info(`Project ${path12.basename(cfg)}: 0 matching tests after filter; skipping.`);
|
|
8571
8610
|
continue;
|
|
8572
8611
|
}
|
|
8573
8612
|
files.forEach(
|
|
8574
|
-
(absTestPath) => executedTestFilesSet.add(
|
|
8613
|
+
(absTestPath) => executedTestFilesSet.add(path12.resolve(absTestPath).replace(/\\/g, "/"))
|
|
8575
8614
|
);
|
|
8576
|
-
const outJson =
|
|
8577
|
-
|
|
8615
|
+
const outJson = path12.join(
|
|
8616
|
+
os3.tmpdir(),
|
|
8578
8617
|
`jest-bridge-${Date.now()}-${Math.random().toString(36).slice(2)}.json`
|
|
8579
8618
|
);
|
|
8580
|
-
const reporterPath =
|
|
8619
|
+
const reporterPath = path12.resolve("scripts/jest-vitest-bridge.cjs");
|
|
8581
8620
|
try {
|
|
8582
8621
|
const needsWrite = (() => {
|
|
8583
8622
|
try {
|
|
@@ -8588,10 +8627,10 @@ var program = async () => {
|
|
|
8588
8627
|
}
|
|
8589
8628
|
})();
|
|
8590
8629
|
if (needsWrite) {
|
|
8591
|
-
fsSync3.mkdirSync(
|
|
8630
|
+
fsSync3.mkdirSync(path12.dirname(reporterPath), { recursive: true });
|
|
8592
8631
|
fsSync3.writeFileSync(reporterPath, JEST_BRIDGE_REPORTER_SOURCE, "utf8");
|
|
8593
8632
|
}
|
|
8594
|
-
const envPath =
|
|
8633
|
+
const envPath = path12.resolve("scripts/jest-bridge-env.cjs");
|
|
8595
8634
|
try {
|
|
8596
8635
|
const existingEnv = fsSync3.readFileSync(envPath, "utf8");
|
|
8597
8636
|
if (existingEnv !== JEST_BRIDGE_ENV_SOURCE) {
|
|
@@ -8599,7 +8638,7 @@ var program = async () => {
|
|
|
8599
8638
|
}
|
|
8600
8639
|
} catch {
|
|
8601
8640
|
try {
|
|
8602
|
-
fsSync3.mkdirSync(
|
|
8641
|
+
fsSync3.mkdirSync(path12.dirname(envPath), { recursive: true });
|
|
8603
8642
|
} catch {
|
|
8604
8643
|
}
|
|
8605
8644
|
fsSync3.writeFileSync(envPath, JEST_BRIDGE_ENV_SOURCE, "utf8");
|
|
@@ -8607,7 +8646,7 @@ var program = async () => {
|
|
|
8607
8646
|
} catch (ensureReporterError) {
|
|
8608
8647
|
console.warn(`Unable to ensure jest bridge reporter: ${String(ensureReporterError)}`);
|
|
8609
8648
|
}
|
|
8610
|
-
const selectedFilesForCoverage = selectionPathsAugmented.filter((pathToken) => /[\\/]/.test(pathToken)).filter((pathToken) => !looksLikeTestPath(pathToken)).map((pathToken) =>
|
|
8649
|
+
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}`);
|
|
8611
8650
|
const coverageFromArgs = [];
|
|
8612
8651
|
for (const relPath2 of selectedFilesForCoverage) {
|
|
8613
8652
|
coverageFromArgs.push("--collectCoverageFrom", relPath2);
|
|
@@ -8625,11 +8664,11 @@ var program = async () => {
|
|
|
8625
8664
|
`--reporters=${reporterPath}`,
|
|
8626
8665
|
"--colors",
|
|
8627
8666
|
"--env",
|
|
8628
|
-
|
|
8667
|
+
path12.resolve("scripts/jest-bridge-env.cjs"),
|
|
8629
8668
|
...sanitizedJestRunArgs,
|
|
8630
8669
|
...collectCoverage ? [
|
|
8631
8670
|
"--coverageDirectory",
|
|
8632
|
-
|
|
8671
|
+
path12.join("coverage", "jest", path12.basename(cfg).replace(/[^a-zA-Z0-9_.-]+/g, "_"))
|
|
8633
8672
|
] : [],
|
|
8634
8673
|
...coverageFromArgs,
|
|
8635
8674
|
"--passWithNoTests",
|
|
@@ -8755,10 +8794,10 @@ ${stripFooter(rawAlso)}`.trimEnd();
|
|
|
8755
8794
|
try {
|
|
8756
8795
|
const prodSeeds = (() => {
|
|
8757
8796
|
const changedAbs = (changedSelectionAbs ?? []).map(
|
|
8758
|
-
(absPath) =>
|
|
8797
|
+
(absPath) => path12.resolve(absPath).replace(/\\/g, "/")
|
|
8759
8798
|
);
|
|
8760
8799
|
const selAbs = selectionPathsAugmented.map(
|
|
8761
|
-
(pathToken) =>
|
|
8800
|
+
(pathToken) => path12.resolve(pathToken).replace(/\\/g, "/")
|
|
8762
8801
|
);
|
|
8763
8802
|
return (changedAbs.length ? changedAbs : selAbs).filter(
|
|
8764
8803
|
(abs) => /[\\/]/.test(abs) && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
|
|
@@ -8851,6 +8890,7 @@ export {
|
|
|
8851
8890
|
drawFailLine,
|
|
8852
8891
|
drawRule,
|
|
8853
8892
|
emitMergedCoverage,
|
|
8893
|
+
extractBridgePath,
|
|
8854
8894
|
filterCandidatesForProject,
|
|
8855
8895
|
filterCoverageMap,
|
|
8856
8896
|
findCodeFrameStart,
|
|
@@ -8889,7 +8929,6 @@ export {
|
|
|
8889
8929
|
routeSimilarityScore,
|
|
8890
8930
|
rule,
|
|
8891
8931
|
runJestBootstrap,
|
|
8892
|
-
scoreHttpForAssertion,
|
|
8893
8932
|
stripAnsiSimple,
|
|
8894
8933
|
supportsUnicode,
|
|
8895
8934
|
tintPct,
|