@vitest-agent/plugin 5.4.5 → 5.4.7
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/package.json +13 -13
- package/reporter.js +260 -258
- package/version.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest-agent/plugin",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Vitest plugin for the vitest-agent ecosystem: owns persistence, classification, baselines, trends, and dispatches rendering to a configurable reporter.",
|
|
6
6
|
"keywords": [
|
|
@@ -43,18 +43,18 @@
|
|
|
43
43
|
"vitest-agent-mcp": "bin/vitest-agent-mcp.js"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@effect/platform-node": "^4.0.
|
|
47
|
-
"@effected/cli": "^0.
|
|
48
|
-
"@effected/env": "^0.
|
|
49
|
-
"@effected/glob": "^0.
|
|
50
|
-
"@effected/walker": "^0.
|
|
51
|
-
"@effected/workspaces": "^0.
|
|
52
|
-
"@vitest-agent/cli": "4.0.
|
|
53
|
-
"@vitest-agent/engine": "1.0
|
|
54
|
-
"@vitest-agent/mcp": "5.2.
|
|
55
|
-
"@vitest-agent/reporter": "5.0.
|
|
56
|
-
"@vitest-agent/sdk": "7.0.
|
|
57
|
-
"effect": "^4.0.
|
|
46
|
+
"@effect/platform-node": "^4.0.5",
|
|
47
|
+
"@effected/cli": "^0.19.0",
|
|
48
|
+
"@effected/env": "^0.4.0",
|
|
49
|
+
"@effected/glob": "^0.13.0",
|
|
50
|
+
"@effected/walker": "^0.18.0",
|
|
51
|
+
"@effected/workspaces": "^0.35.0",
|
|
52
|
+
"@vitest-agent/cli": "4.0.11",
|
|
53
|
+
"@vitest-agent/engine": "1.1.0",
|
|
54
|
+
"@vitest-agent/mcp": "5.2.7",
|
|
55
|
+
"@vitest-agent/reporter": "5.0.6",
|
|
56
|
+
"@vitest-agent/sdk": "7.0.4",
|
|
57
|
+
"effect": "^4.0.5",
|
|
58
58
|
"magic-string": "^1.4.3"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
package/reporter.js
CHANGED
|
@@ -13,7 +13,7 @@ import { strayOutputCaptureOf } from "./utils/stray-output-capture.js";
|
|
|
13
13
|
import { stringifyFailureValue } from "./utils/stringify-failure-value.js";
|
|
14
14
|
import { mkdirSync, statSync } from "node:fs";
|
|
15
15
|
import { dirname } from "node:path";
|
|
16
|
-
import { DataReader, DataStore, DetailResolver, EnvironmentDetector, ExecutorResolver, HistoryTracker, OutputPipelineLive, PathResolutionLive, ensureMigrated, historyKey, resolveDataPath, resolveLogFile, resolveLogLevel } from "@vitest-agent/engine";
|
|
16
|
+
import { DataReader, DataStore, DetailResolver, EnvironmentDetector, ExecutorResolver, HistoryTracker, OutputPipelineLive, PathResolutionLive, ensureMigrated, historyKey, resolveDataPath, resolveLogFile, resolveLogLevel, withPersistTransaction } from "@vitest-agent/engine";
|
|
17
17
|
import { buildAgentReport, coerceErrorField, computeTrend, formatFatalError, isTimeoutError, probeHostMetadataFromEnv } from "@vitest-agent/sdk";
|
|
18
18
|
import { Effect, Option, PubSub } from "effect";
|
|
19
19
|
import { randomUUID } from "node:crypto";
|
|
@@ -1279,7 +1279,6 @@ var AgentReporter = class {
|
|
|
1279
1279
|
const settings = captureSettings(vitestConfig, vitestVersion);
|
|
1280
1280
|
const settingsHash = hashSettings(settings);
|
|
1281
1281
|
const envVars = captureEnvVars(process.env);
|
|
1282
|
-
yield* store.writeSettings(settingsHash, settings, envVars);
|
|
1283
1282
|
const projectGroups = /* @__PURE__ */ new Map();
|
|
1284
1283
|
for (const mod of filteredModules) {
|
|
1285
1284
|
const key = mod.project.name || "default";
|
|
@@ -1341,113 +1340,155 @@ var AgentReporter = class {
|
|
|
1341
1340
|
}
|
|
1342
1341
|
const reports = [];
|
|
1343
1342
|
const isMultiProject = projectGroups.size > 1 || !!opts.projectFilter;
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
const
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
const
|
|
1388
|
-
fileId
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
const
|
|
1398
|
-
const
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
const
|
|
1416
|
-
const
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
const
|
|
1444
|
-
|
|
1343
|
+
yield* withPersistTransaction(Effect.gen(function* () {
|
|
1344
|
+
yield* store.writeSettings(settingsHash, settings, envVars);
|
|
1345
|
+
for (const [projectName, projectModules] of projectGroups) {
|
|
1346
|
+
const project = projectName === "default" ? "default" : projectName;
|
|
1347
|
+
const baseReport = buildAgentReport(projectModules, errors, reason, { omitPassingTests: opts.omitPassingTests }, isMultiProject ? projectName : void 0);
|
|
1348
|
+
let totalDuration = 0;
|
|
1349
|
+
for (const mod of projectModules) totalDuration += mod.diagnostic()?.duration ?? 0;
|
|
1350
|
+
const envAgentId = process.env.VITEST_AGENT_AGENT_ID;
|
|
1351
|
+
const envConversationId = process.env.VITEST_AGENT_CONVERSATION_ID;
|
|
1352
|
+
const attribution = envAgentId !== void 0 && envAgentId.length > 0 ? {
|
|
1353
|
+
actorType: "agent",
|
|
1354
|
+
agentId: envAgentId,
|
|
1355
|
+
conversationId: envConversationId ?? null
|
|
1356
|
+
} : {
|
|
1357
|
+
actorType: "system",
|
|
1358
|
+
agentId: null,
|
|
1359
|
+
conversationId: null
|
|
1360
|
+
};
|
|
1361
|
+
const hostProbe = probeHostMetadataFromEnv(process.env);
|
|
1362
|
+
const projectReason = reason === "interrupted" ? "interrupted" : baseReport.summary.failed > 0 || baseReport.failedFiles.length > 0 ? "failed" : "passed";
|
|
1363
|
+
const runId = yield* store.writeRun({
|
|
1364
|
+
invocationId,
|
|
1365
|
+
project,
|
|
1366
|
+
settingsHash,
|
|
1367
|
+
timestamp: baseReport.timestamp,
|
|
1368
|
+
commitSha: process.env.GITHUB_SHA ?? null,
|
|
1369
|
+
branch: process.env.GITHUB_REF_NAME ?? null,
|
|
1370
|
+
reason: projectReason,
|
|
1371
|
+
duration: totalDuration,
|
|
1372
|
+
total: baseReport.summary.total,
|
|
1373
|
+
passed: baseReport.summary.passed,
|
|
1374
|
+
failed: baseReport.summary.failed,
|
|
1375
|
+
skipped: baseReport.summary.skipped,
|
|
1376
|
+
scoped: isPartial,
|
|
1377
|
+
actorType: attribution.actorType,
|
|
1378
|
+
agentId: attribution.agentId,
|
|
1379
|
+
conversationId: attribution.conversationId,
|
|
1380
|
+
gitBranch: process.env.GITHUB_REF_NAME ?? null,
|
|
1381
|
+
gitCommitSha: process.env.GITHUB_SHA ?? null,
|
|
1382
|
+
hostSource: hostProbe.source,
|
|
1383
|
+
hostValue: hostProbe.value,
|
|
1384
|
+
hostMetadata: hostProbe.metadata
|
|
1385
|
+
});
|
|
1386
|
+
for (const mod of projectModules) {
|
|
1387
|
+
const fileId = yield* store.ensureFile(mod.relativeModuleId);
|
|
1388
|
+
const moduleId = (yield* store.writeModules(runId, [{
|
|
1389
|
+
fileId,
|
|
1390
|
+
relativeModuleId: mod.relativeModuleId,
|
|
1391
|
+
state: mod.state(),
|
|
1392
|
+
duration: mod.diagnostic()?.duration ?? 0
|
|
1393
|
+
}]))[0];
|
|
1394
|
+
const sourceFile = mod.relativeModuleId.replace(/\.test\.([^.]+)$/, ".$1").replace(/\.spec\.([^.]+)$/, ".$1");
|
|
1395
|
+
if (sourceFile !== mod.relativeModuleId) yield* store.writeSourceMap(sourceFile, moduleId, "convention");
|
|
1396
|
+
const suiteIdMap = /* @__PURE__ */ new Map();
|
|
1397
|
+
for (const suite of mod.children.allSuites()) {
|
|
1398
|
+
const parentSuiteId = suite.parent && suite.parent.type === "suite" ? suiteIdMap.get(suite.parent.fullName) : void 0;
|
|
1399
|
+
const suiteIds = yield* store.writeSuites(moduleId, [{
|
|
1400
|
+
name: suite.name,
|
|
1401
|
+
fullName: suite.fullName,
|
|
1402
|
+
state: suite.state(),
|
|
1403
|
+
...parentSuiteId !== void 0 && { parentSuiteId },
|
|
1404
|
+
...suite.options?.mode !== void 0 && { mode: suite.options.mode },
|
|
1405
|
+
...suite.options?.concurrent !== void 0 && { concurrent: suite.options.concurrent },
|
|
1406
|
+
...suite.options?.shuffle !== void 0 && { shuffle: suite.options.shuffle },
|
|
1407
|
+
...suite.options?.retry !== void 0 && { retry: suite.options.retry },
|
|
1408
|
+
...suite.options?.repeats !== void 0 && { repeats: suite.options.repeats },
|
|
1409
|
+
...suite.location?.line !== void 0 && { locationLine: suite.location.line },
|
|
1410
|
+
...suite.location?.column !== void 0 && { locationColumn: suite.location.column }
|
|
1411
|
+
}]);
|
|
1412
|
+
suiteIdMap.set(suite.fullName, suiteIds[0]);
|
|
1413
|
+
}
|
|
1414
|
+
const testCases = [];
|
|
1415
|
+
for (const testCase of mod.children.allTests()) {
|
|
1416
|
+
const result = testCase.result();
|
|
1417
|
+
const diag = testCase.diagnostic();
|
|
1418
|
+
const parent = testCase.parent;
|
|
1419
|
+
const parentSuiteId = parent && parent.type === "suite" ? suiteIdMap.get(parent.fullName) : void 0;
|
|
1420
|
+
testCases.push({
|
|
1421
|
+
name: testCase.name,
|
|
1422
|
+
fullName: testCase.fullName,
|
|
1423
|
+
state: result?.state ?? "pending",
|
|
1424
|
+
...diag?.duration !== void 0 && { duration: diag.duration },
|
|
1425
|
+
...diag?.flaky !== void 0 && { flaky: diag.flaky },
|
|
1426
|
+
...diag?.slow !== void 0 && { slow: diag.slow },
|
|
1427
|
+
...testCase.tags.length > 0 && { tags: testCase.tags },
|
|
1428
|
+
...parentSuiteId !== void 0 && { suiteId: parentSuiteId }
|
|
1429
|
+
});
|
|
1430
|
+
}
|
|
1431
|
+
const testCaseIds = yield* store.writeTestCases(moduleId, testCases.map((tc) => ({
|
|
1432
|
+
name: tc.name,
|
|
1433
|
+
fullName: tc.fullName,
|
|
1434
|
+
state: tc.state,
|
|
1435
|
+
...tc.duration !== void 0 && { duration: tc.duration },
|
|
1436
|
+
...tc.flaky !== void 0 && { flaky: tc.flaky },
|
|
1437
|
+
...tc.slow !== void 0 && { slow: tc.slow },
|
|
1438
|
+
...tc.tags !== void 0 && { tags: tc.tags },
|
|
1439
|
+
...tc.suiteId !== void 0 && { suiteId: tc.suiteId }
|
|
1440
|
+
})));
|
|
1441
|
+
let testIdx = 0;
|
|
1442
|
+
for (const testCase of mod.children.allTests()) {
|
|
1443
|
+
const result = testCase.result();
|
|
1444
|
+
const testCaseId = testCaseIds[testIdx];
|
|
1445
|
+
if (result?.errors && result.errors.length > 0) {
|
|
1446
|
+
const inputs = [];
|
|
1447
|
+
for (let ordinal = 0; ordinal < result.errors.length; ordinal++) {
|
|
1448
|
+
const e = result.errors[ordinal];
|
|
1449
|
+
const messageText = coerceErrorField(e, "message") ?? "<missing message>";
|
|
1450
|
+
const nameText = coerceErrorField(e, "name");
|
|
1451
|
+
const diffText = coerceErrorField(e, "diff");
|
|
1452
|
+
const stackText = coerceErrorField(e, "stack");
|
|
1453
|
+
const stacksValue = readErrorStacks(e);
|
|
1454
|
+
const { frames, signatureHash } = processFailure({
|
|
1455
|
+
message: messageText,
|
|
1456
|
+
...nameText !== void 0 && { name: nameText },
|
|
1457
|
+
...stackText !== void 0 && { stack: stackText },
|
|
1458
|
+
...stacksValue !== void 0 && { stacks: stacksValue }
|
|
1459
|
+
});
|
|
1460
|
+
if (signatureHash !== null) yield* store.writeFailureSignature({
|
|
1461
|
+
signatureHash,
|
|
1462
|
+
runId,
|
|
1463
|
+
seenAt: baseReport.timestamp
|
|
1464
|
+
});
|
|
1465
|
+
inputs.push({
|
|
1466
|
+
testCaseId,
|
|
1467
|
+
scope: "test",
|
|
1468
|
+
message: messageText,
|
|
1469
|
+
...nameText !== void 0 && { name: nameText },
|
|
1470
|
+
...diffText !== void 0 && { diff: diffText },
|
|
1471
|
+
...stackText !== void 0 && { stack: stackText },
|
|
1472
|
+
...signatureHash !== null && { signatureHash },
|
|
1473
|
+
...frames.length > 0 && { frames },
|
|
1474
|
+
ordinal
|
|
1475
|
+
});
|
|
1476
|
+
}
|
|
1477
|
+
yield* store.writeErrors(runId, inputs);
|
|
1478
|
+
}
|
|
1479
|
+
const annotationInputs = toAnnotationInputs(testCaseId, testCase.annotations?.() ?? []);
|
|
1480
|
+
if (annotationInputs.length > 0) yield* store.writeAnnotations(runId, annotationInputs);
|
|
1481
|
+
const artifactInputs = toArtifactInputs(testCaseId, testCase.artifacts?.() ?? []);
|
|
1482
|
+
if (artifactInputs.length > 0) yield* store.writeArtifacts(runId, artifactInputs);
|
|
1483
|
+
testIdx++;
|
|
1484
|
+
}
|
|
1485
|
+
const modErrors = mod.errors();
|
|
1486
|
+
if (modErrors.length > 0) {
|
|
1445
1487
|
const inputs = [];
|
|
1446
|
-
for (let ordinal = 0; ordinal <
|
|
1447
|
-
const e =
|
|
1488
|
+
for (let ordinal = 0; ordinal < modErrors.length; ordinal++) {
|
|
1489
|
+
const e = modErrors[ordinal];
|
|
1448
1490
|
const messageText = coerceErrorField(e, "message") ?? "<missing message>";
|
|
1449
1491
|
const nameText = coerceErrorField(e, "name");
|
|
1450
|
-
const diffText = coerceErrorField(e, "diff");
|
|
1451
1492
|
const stackText = coerceErrorField(e, "stack");
|
|
1452
1493
|
const stacksValue = readErrorStacks(e);
|
|
1453
1494
|
const { frames, signatureHash } = processFailure({
|
|
@@ -1462,11 +1503,10 @@ var AgentReporter = class {
|
|
|
1462
1503
|
seenAt: baseReport.timestamp
|
|
1463
1504
|
});
|
|
1464
1505
|
inputs.push({
|
|
1465
|
-
|
|
1466
|
-
scope: "
|
|
1506
|
+
moduleId,
|
|
1507
|
+
scope: "module",
|
|
1467
1508
|
message: messageText,
|
|
1468
1509
|
...nameText !== void 0 && { name: nameText },
|
|
1469
|
-
...diffText !== void 0 && { diff: diffText },
|
|
1470
1510
|
...stackText !== void 0 && { stack: stackText },
|
|
1471
1511
|
...signatureHash !== null && { signatureHash },
|
|
1472
1512
|
...frames.length > 0 && { frames },
|
|
@@ -1475,17 +1515,11 @@ var AgentReporter = class {
|
|
|
1475
1515
|
}
|
|
1476
1516
|
yield* store.writeErrors(runId, inputs);
|
|
1477
1517
|
}
|
|
1478
|
-
const annotationInputs = toAnnotationInputs(testCaseId, testCase.annotations?.() ?? []);
|
|
1479
|
-
if (annotationInputs.length > 0) yield* store.writeAnnotations(runId, annotationInputs);
|
|
1480
|
-
const artifactInputs = toArtifactInputs(testCaseId, testCase.artifacts?.() ?? []);
|
|
1481
|
-
if (artifactInputs.length > 0) yield* store.writeArtifacts(runId, artifactInputs);
|
|
1482
|
-
testIdx++;
|
|
1483
1518
|
}
|
|
1484
|
-
|
|
1485
|
-
if (modErrors.length > 0) {
|
|
1519
|
+
if (errors.length > 0) {
|
|
1486
1520
|
const inputs = [];
|
|
1487
|
-
for (let ordinal = 0; ordinal <
|
|
1488
|
-
const e =
|
|
1521
|
+
for (let ordinal = 0; ordinal < errors.length; ordinal++) {
|
|
1522
|
+
const e = errors[ordinal];
|
|
1489
1523
|
const messageText = coerceErrorField(e, "message") ?? "<missing message>";
|
|
1490
1524
|
const nameText = coerceErrorField(e, "name");
|
|
1491
1525
|
const stackText = coerceErrorField(e, "stack");
|
|
@@ -1502,8 +1536,7 @@ var AgentReporter = class {
|
|
|
1502
1536
|
seenAt: baseReport.timestamp
|
|
1503
1537
|
});
|
|
1504
1538
|
inputs.push({
|
|
1505
|
-
|
|
1506
|
-
scope: "module",
|
|
1539
|
+
scope: "unhandled",
|
|
1507
1540
|
message: messageText,
|
|
1508
1541
|
...nameText !== void 0 && { name: nameText },
|
|
1509
1542
|
...stackText !== void 0 && { stack: stackText },
|
|
@@ -1514,154 +1547,123 @@ var AgentReporter = class {
|
|
|
1514
1547
|
}
|
|
1515
1548
|
yield* store.writeErrors(runId, inputs);
|
|
1516
1549
|
}
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
message: messageText,
|
|
1528
|
-
...nameText !== void 0 && { name: nameText },
|
|
1529
|
-
...stackText !== void 0 && { stack: stackText },
|
|
1530
|
-
...stacksValue !== void 0 && { stacks: stacksValue }
|
|
1531
|
-
});
|
|
1532
|
-
if (signatureHash !== null) yield* store.writeFailureSignature({
|
|
1533
|
-
signatureHash,
|
|
1534
|
-
runId,
|
|
1535
|
-
seenAt: baseReport.timestamp
|
|
1536
|
-
});
|
|
1537
|
-
inputs.push({
|
|
1538
|
-
scope: "unhandled",
|
|
1539
|
-
message: messageText,
|
|
1540
|
-
...nameText !== void 0 && { name: nameText },
|
|
1541
|
-
...stackText !== void 0 && { stack: stackText },
|
|
1542
|
-
...signatureHash !== null && { signatureHash },
|
|
1543
|
-
...frames.length > 0 && { frames },
|
|
1544
|
-
ordinal
|
|
1545
|
-
});
|
|
1546
|
-
}
|
|
1547
|
-
yield* store.writeErrors(runId, inputs);
|
|
1548
|
-
}
|
|
1549
|
-
const testOutcomes = [];
|
|
1550
|
-
for (const mod of projectModules) {
|
|
1551
|
-
const modulePath = mod.relativeModuleId ?? "";
|
|
1552
|
-
for (const testCase of mod.children.allTests()) {
|
|
1553
|
-
const state = testCase.result()?.state;
|
|
1554
|
-
if (state === "passed" || state === "failed") testOutcomes.push({
|
|
1555
|
-
modulePath,
|
|
1556
|
-
fullName: testCase.fullName,
|
|
1557
|
-
state
|
|
1558
|
-
});
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
const { classifications } = yield* tracker.classify(project, testOutcomes, baseReport.timestamp);
|
|
1562
|
-
const diagMap = /* @__PURE__ */ new Map();
|
|
1563
|
-
const errorMap = /* @__PURE__ */ new Map();
|
|
1564
|
-
for (const mod of projectModules) {
|
|
1565
|
-
const modulePath = mod.relativeModuleId ?? "";
|
|
1566
|
-
for (const tc of mod.children.allTests()) {
|
|
1567
|
-
const key = historyKey(modulePath, tc.fullName);
|
|
1568
|
-
diagMap.set(key, tc.diagnostic() ?? {});
|
|
1569
|
-
const tcResult = tc.result();
|
|
1570
|
-
if (tcResult?.state === "failed") {
|
|
1571
|
-
const errors = tcResult.errors;
|
|
1572
|
-
errorMap.set(key, coerceErrorField(errors?.[0], "message") ?? null);
|
|
1550
|
+
const testOutcomes = [];
|
|
1551
|
+
for (const mod of projectModules) {
|
|
1552
|
+
const modulePath = mod.relativeModuleId ?? "";
|
|
1553
|
+
for (const testCase of mod.children.allTests()) {
|
|
1554
|
+
const state = testCase.result()?.state;
|
|
1555
|
+
if (state === "passed" || state === "failed") testOutcomes.push({
|
|
1556
|
+
modulePath,
|
|
1557
|
+
fullName: testCase.fullName,
|
|
1558
|
+
state
|
|
1559
|
+
});
|
|
1573
1560
|
}
|
|
1574
1561
|
}
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
const
|
|
1578
|
-
const
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
} : test;
|
|
1590
|
-
})
|
|
1591
|
-
}));
|
|
1592
|
-
const classifiedReport = {
|
|
1593
|
-
...baseReport,
|
|
1594
|
-
failed: failedWithClassifications
|
|
1595
|
-
};
|
|
1596
|
-
const tagCounts = {};
|
|
1597
|
-
for (const mod of projectModules) for (const tc of mod.children.allTests()) {
|
|
1598
|
-
const state = tc.result()?.state ?? "pending";
|
|
1599
|
-
const tags = tc.tags ?? [];
|
|
1600
|
-
for (const tag of tags) {
|
|
1601
|
-
tagCounts[tag] ??= {
|
|
1602
|
-
passed: 0,
|
|
1603
|
-
failed: 0,
|
|
1604
|
-
skipped: 0
|
|
1605
|
-
};
|
|
1606
|
-
if (state === "passed") tagCounts[tag].passed++;
|
|
1607
|
-
else if (state === "failed") tagCounts[tag].failed++;
|
|
1608
|
-
else if (state === "skipped") tagCounts[tag].skipped++;
|
|
1562
|
+
const { classifications } = yield* tracker.classify(project, testOutcomes, baseReport.timestamp);
|
|
1563
|
+
const diagMap = /* @__PURE__ */ new Map();
|
|
1564
|
+
const errorMap = /* @__PURE__ */ new Map();
|
|
1565
|
+
for (const mod of projectModules) {
|
|
1566
|
+
const modulePath = mod.relativeModuleId ?? "";
|
|
1567
|
+
for (const tc of mod.children.allTests()) {
|
|
1568
|
+
const key = historyKey(modulePath, tc.fullName);
|
|
1569
|
+
diagMap.set(key, tc.diagnostic() ?? {});
|
|
1570
|
+
const tcResult = tc.result();
|
|
1571
|
+
if (tcResult?.state === "failed") {
|
|
1572
|
+
const errors = tcResult.errors;
|
|
1573
|
+
errorMap.set(key, coerceErrorField(errors?.[0], "message") ?? null);
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1609
1576
|
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
const report = coverageReport ? {
|
|
1616
|
-
...reportWithTags,
|
|
1617
|
-
coverage: coverageReport
|
|
1618
|
-
} : reportWithTags;
|
|
1619
|
-
reports.push(report);
|
|
1620
|
-
if (coverageReport) {
|
|
1621
|
-
const tierByFile = /* @__PURE__ */ new Map();
|
|
1622
|
-
const sourceByFile = /* @__PURE__ */ new Map();
|
|
1623
|
-
for (const fc of coverageReport.belowTarget ?? []) {
|
|
1624
|
-
tierByFile.set(fc.file, "below_target");
|
|
1625
|
-
sourceByFile.set(fc.file, fc);
|
|
1577
|
+
for (const outcome of testOutcomes) {
|
|
1578
|
+
const key = historyKey(outcome.modulePath, outcome.fullName);
|
|
1579
|
+
const diag = diagMap.get(key);
|
|
1580
|
+
const errorMessage = outcome.state === "failed" ? errorMap.get(key) ?? null : null;
|
|
1581
|
+
yield* store.writeHistory(project, outcome.fullName, outcome.modulePath, runId, baseReport.timestamp, outcome.state, diag?.duration ?? null, diag?.flaky ?? false, 0, errorMessage);
|
|
1626
1582
|
}
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1583
|
+
const failedWithClassifications = baseReport.failed.map((mod) => ({
|
|
1584
|
+
...mod,
|
|
1585
|
+
tests: mod.tests.map((test) => {
|
|
1586
|
+
const cls = classifications.get(historyKey(mod.file, test.fullName));
|
|
1587
|
+
return cls ? {
|
|
1588
|
+
...test,
|
|
1589
|
+
classification: cls
|
|
1590
|
+
} : test;
|
|
1591
|
+
})
|
|
1592
|
+
}));
|
|
1593
|
+
const classifiedReport = {
|
|
1594
|
+
...baseReport,
|
|
1595
|
+
failed: failedWithClassifications
|
|
1596
|
+
};
|
|
1597
|
+
const tagCounts = {};
|
|
1598
|
+
for (const mod of projectModules) for (const tc of mod.children.allTests()) {
|
|
1599
|
+
const state = tc.result()?.state ?? "pending";
|
|
1600
|
+
const tags = tc.tags ?? [];
|
|
1601
|
+
for (const tag of tags) {
|
|
1602
|
+
tagCounts[tag] ??= {
|
|
1603
|
+
passed: 0,
|
|
1604
|
+
failed: 0,
|
|
1605
|
+
skipped: 0
|
|
1606
|
+
};
|
|
1607
|
+
if (state === "passed") tagCounts[tag].passed++;
|
|
1608
|
+
else if (state === "failed") tagCounts[tag].failed++;
|
|
1609
|
+
else if (state === "skipped") tagCounts[tag].skipped++;
|
|
1610
|
+
}
|
|
1630
1611
|
}
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1612
|
+
const reportWithTags = Object.keys(tagCounts).length > 0 ? {
|
|
1613
|
+
...classifiedReport,
|
|
1614
|
+
tagCounts
|
|
1615
|
+
} : classifiedReport;
|
|
1616
|
+
const report = coverageReport ? {
|
|
1617
|
+
...reportWithTags,
|
|
1618
|
+
coverage: coverageReport
|
|
1619
|
+
} : reportWithTags;
|
|
1620
|
+
reports.push(report);
|
|
1621
|
+
if (coverageReport) {
|
|
1622
|
+
const tierByFile = /* @__PURE__ */ new Map();
|
|
1623
|
+
const sourceByFile = /* @__PURE__ */ new Map();
|
|
1624
|
+
for (const fc of coverageReport.belowTarget ?? []) {
|
|
1625
|
+
tierByFile.set(fc.file, "below_target");
|
|
1626
|
+
sourceByFile.set(fc.file, fc);
|
|
1627
|
+
}
|
|
1628
|
+
for (const fc of coverageReport.lowCoverage) {
|
|
1629
|
+
tierByFile.set(fc.file, "below_threshold");
|
|
1630
|
+
sourceByFile.set(fc.file, fc);
|
|
1631
|
+
}
|
|
1632
|
+
if (tierByFile.size > 0) {
|
|
1633
|
+
const coverageInputs = [];
|
|
1634
|
+
for (const [file, tier] of tierByFile) {
|
|
1635
|
+
const fc = sourceByFile.get(file);
|
|
1636
|
+
if (!fc) continue;
|
|
1637
|
+
const fileId = yield* store.ensureFile(fc.file);
|
|
1638
|
+
coverageInputs.push({
|
|
1639
|
+
fileId,
|
|
1640
|
+
statements: fc.summary.statements,
|
|
1641
|
+
branches: fc.summary.branches,
|
|
1642
|
+
functions: fc.summary.functions,
|
|
1643
|
+
lines: fc.summary.lines,
|
|
1644
|
+
uncoveredLines: fc.uncoveredLines,
|
|
1645
|
+
tier
|
|
1646
|
+
});
|
|
1647
|
+
}
|
|
1648
|
+
yield* store.writeCoverage(runId, coverageInputs);
|
|
1646
1649
|
}
|
|
1647
|
-
|
|
1650
|
+
}
|
|
1651
|
+
if (coverageReport && !coverageReport.scoped) {
|
|
1652
|
+
const existingTrends = yield* reader.getTrends(project).pipe(Effect.map((opt) => Option.getOrUndefined(opt)), Effect.catch(() => Effect.succeed(void 0)));
|
|
1653
|
+
const updatedTrends = computeTrend(coverageReport.totals, existingTrends, opts.coverageTargets);
|
|
1654
|
+
const latestEntry = updatedTrends.entries[updatedTrends.entries.length - 1];
|
|
1655
|
+
if (latestEntry) yield* store.writeTrends(project, runId, latestEntry);
|
|
1648
1656
|
}
|
|
1649
1657
|
}
|
|
1658
|
+
if (opts.autoUpdate && coverageReport) {
|
|
1659
|
+
const newBaselines = computeUpdatedBaselines(baselines, coverageReport.totals, opts.coverageTargets);
|
|
1660
|
+
yield* store.writeBaselines(newBaselines);
|
|
1661
|
+
}
|
|
1650
1662
|
if (coverageReport && !coverageReport.scoped) {
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
const latestEntry = updatedTrends.entries[updatedTrends.entries.length - 1];
|
|
1654
|
-
if (latestEntry) yield* store.writeTrends(project, runId, latestEntry);
|
|
1663
|
+
if (opts.coverageThresholds !== void 0) yield* store.writeThresholds(opts.coverageThresholds);
|
|
1664
|
+
if (opts.coverageTargets !== void 0) yield* store.writeTargets(opts.coverageTargets);
|
|
1655
1665
|
}
|
|
1656
|
-
}
|
|
1657
|
-
if (opts.autoUpdate && coverageReport) {
|
|
1658
|
-
const newBaselines = computeUpdatedBaselines(baselines, coverageReport.totals, opts.coverageTargets);
|
|
1659
|
-
yield* store.writeBaselines(newBaselines);
|
|
1660
|
-
}
|
|
1661
|
-
if (coverageReport && !coverageReport.scoped) {
|
|
1662
|
-
if (opts.coverageThresholds !== void 0) yield* store.writeThresholds(opts.coverageThresholds);
|
|
1663
|
-
if (opts.coverageTargets !== void 0) yield* store.writeTargets(opts.coverageTargets);
|
|
1664
|
-
}
|
|
1666
|
+
}));
|
|
1665
1667
|
let trendSummary;
|
|
1666
1668
|
if (coverageReport && !coverageReport.scoped) {
|
|
1667
1669
|
const firstProjectKey = Array.from(projectGroups.keys())[0];
|