@systemfsoftware/stryker-js 15.0.1 → 16.0.0
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/CHANGELOG.md +34 -0
- package/README.md +12 -6
- package/dist/{Run.schema-B1HZugu9.d.mts → Run.schema-CgcTsB1w.d.mts} +1 -1
- package/dist/{RunEnvironment.service-B1bsWOQ9.d.mts → RunEnvironment.service-F8LgeCqh.d.mts} +90 -18
- package/dist/config.d.mts +2 -2
- package/dist/config.mjs +1 -1
- package/dist/events.d.mts +1 -1
- package/dist/{index-Cf9G6kA8.d.mts → index-DEphx668.d.mts} +11 -2
- package/dist/index.d.mts +11 -6
- package/dist/index.mjs +3 -2
- package/dist/main.mjs +2057 -1247
- package/dist/{merge-config-zsGl1aWc.mjs → merge-config-BYhhPA7r.mjs} +12 -5
- package/dist/{merge-config-BdQdK3PM.d.mts → merge-config-b06M-Ccx.d.mts} +2 -2
- package/dist/promises.d.mts +2 -2
- package/dist/promises.mjs +1 -1
- package/dist/{run-stages-DdVQINP9.mjs → run-stages-k4L7ymmp.mjs} +544 -233
- package/package.json +10 -10
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll$4 } from "./rolldown-runtime-8H4AJuhK.mjs";
|
|
2
|
-
import { a as MutatorCatalog_exports, c as Plugin_exports, d as TestRunner_exports, f as Trace_exports$1, i as Mutant_exports, l as Report_exports, n as mergeConfigs, o as MutatorProvider_exports, r as Checker_exports, s as Options_exports, t as mergeConfig, u as Reporter_exports } from "./merge-config-
|
|
2
|
+
import { a as MutatorCatalog_exports, c as Plugin_exports, d as TestRunner_exports, f as Trace_exports$1, i as Mutant_exports, l as Report_exports, n as mergeConfigs, o as MutatorProvider_exports, r as Checker_exports, s as Options_exports, t as mergeConfig, u as Reporter_exports } from "./merge-config-BYhhPA7r.mjs";
|
|
3
3
|
import { n as StageError, t as PrepareError } from "./Run.schema-DuaneDGd.mjs";
|
|
4
4
|
import { Blueprint, Cell, Handle, Sandwich, Workflow } from "@systemfsoftware/effect-cell-types";
|
|
5
5
|
import * as S from "effect/Schema";
|
|
@@ -33,6 +33,7 @@ import * as Queue from "effect/Queue";
|
|
|
33
33
|
import * as Scope from "effect/Scope";
|
|
34
34
|
import * as HashMap from "effect/HashMap";
|
|
35
35
|
import * as MutableHashMap from "effect/MutableHashMap";
|
|
36
|
+
import * as Exit from "effect/Exit";
|
|
36
37
|
import * as api from "@opentelemetry/api";
|
|
37
38
|
import * as Headers from "effect/http/Headers";
|
|
38
39
|
import * as Tracer from "effect/Tracer";
|
|
@@ -40,7 +41,6 @@ import * as RpcSerialization from "effect/rpc/RpcSerialization";
|
|
|
40
41
|
import * as RpcServer from "effect/rpc/RpcServer";
|
|
41
42
|
import * as SocketServer from "effect/socket/SocketServer";
|
|
42
43
|
import * as Duration from "effect/Duration";
|
|
43
|
-
import * as Exit from "effect/Exit";
|
|
44
44
|
import * as Fiber from "effect/Fiber";
|
|
45
45
|
import * as HashSet from "effect/HashSet";
|
|
46
46
|
import * as PubSub from "effect/PubSub";
|
|
@@ -185,7 +185,32 @@ const PluginLoadFailureReason = Schema.Union([
|
|
|
185
185
|
Schema.TaggedStruct("InvalidContribution", { detail: Schema.String }),
|
|
186
186
|
Schema.TaggedStruct("ImportFailed", { cause: Schema.Unknown })
|
|
187
187
|
]);
|
|
188
|
-
const
|
|
188
|
+
const ShardPlanVersion = S.Literal(1);
|
|
189
|
+
const ShardProject = S.Struct({
|
|
190
|
+
project: S.String,
|
|
191
|
+
mutants: S.Array(S.String)
|
|
192
|
+
});
|
|
193
|
+
const Shard = S.Struct({
|
|
194
|
+
index: S.Int,
|
|
195
|
+
count: S.Int,
|
|
196
|
+
predictedSeconds: S.Finite,
|
|
197
|
+
projects: S.Array(ShardProject)
|
|
198
|
+
});
|
|
199
|
+
const labelOf = (shard) => `${shard.index}/${shard.count}`;
|
|
200
|
+
const shardLabelsAreUnique = S.makeFilter((shards) => {
|
|
201
|
+
const duplicated = Mutant_exports.duplicatedValue(shards.map(labelOf));
|
|
202
|
+
return duplicated === void 0 ? void 0 : `shard plan shards share the label "${duplicated}"`;
|
|
203
|
+
}, { arbitraryConstraint: { uniqueBy: labelOf } });
|
|
204
|
+
const ShardPlan = S.Struct({
|
|
205
|
+
version: ShardPlanVersion,
|
|
206
|
+
targetSeconds: S.Finite,
|
|
207
|
+
shards: S.Array(Shard).check(shardLabelsAreUnique),
|
|
208
|
+
matrix: S.Struct({ include: S.Array(S.Struct({
|
|
209
|
+
shard: S.String,
|
|
210
|
+
predictedSeconds: S.Finite
|
|
211
|
+
})) })
|
|
212
|
+
});
|
|
213
|
+
const StreamSchemaVersion = S.Literal("6.0");
|
|
189
214
|
const RunPhase = S.Literals([
|
|
190
215
|
"prepare",
|
|
191
216
|
"instrument",
|
|
@@ -203,8 +228,18 @@ var PhaseEntered = class extends S.TaggedClass()("phase", {
|
|
|
203
228
|
phase: RunPhase,
|
|
204
229
|
elapsedMs: Report_exports.NonNegativeFinite
|
|
205
230
|
}) {};
|
|
206
|
-
var PlanKnown = class extends S.TaggedClass()("plan", {
|
|
207
|
-
|
|
231
|
+
var PlanKnown = class extends S.TaggedClass()("plan", {
|
|
232
|
+
total: Report_exports.NonNegativeInt,
|
|
233
|
+
shardPlan: S.NullOr(ShardPlan)
|
|
234
|
+
}) {};
|
|
235
|
+
const WorkerRole = S.Literals(["testRunner", "checker"]);
|
|
236
|
+
var WorkerReported = class extends S.TaggedClass()("worker", {
|
|
237
|
+
schemaVersion: StreamSchemaVersion,
|
|
238
|
+
role: WorkerRole,
|
|
239
|
+
index: Report_exports.NonNegativeInt,
|
|
240
|
+
startupMs: Report_exports.NonNegativeFinite
|
|
241
|
+
}) {};
|
|
242
|
+
const MutantCost$1 = S.Struct({
|
|
208
243
|
fixedOverheadMs: Report_exports.NonNegativeFinite,
|
|
209
244
|
testBodyMs: Report_exports.NonNegativeFinite,
|
|
210
245
|
testsExecuted: Report_exports.NonNegativeInt,
|
|
@@ -226,7 +261,7 @@ var RunMutantTestedEvent = class extends S.TaggedClass()("mutantTested", {
|
|
|
226
261
|
completed: Report_exports.NonNegativeInt,
|
|
227
262
|
total: Report_exports.NonNegativeInt,
|
|
228
263
|
static: S.Boolean,
|
|
229
|
-
cost: S.NullOr(MutantCost)
|
|
264
|
+
cost: S.NullOr(MutantCost$1)
|
|
230
265
|
}) {};
|
|
231
266
|
const RunMutantTested = S.TaggedStruct("mutant", {
|
|
232
267
|
id: Mutant_exports.MutantId,
|
|
@@ -238,7 +273,7 @@ const RunMutantTested = S.TaggedStruct("mutant", {
|
|
|
238
273
|
completed: Report_exports.NonNegativeInt,
|
|
239
274
|
total: Report_exports.NonNegativeInt,
|
|
240
275
|
static: S.Boolean,
|
|
241
|
-
cost: S.NullOr(MutantCost)
|
|
276
|
+
cost: S.NullOr(MutantCost$1)
|
|
242
277
|
}).pipe(S.decodeTo(S.toType(RunMutantTestedEvent), {
|
|
243
278
|
decode: SchemaGetter.transform((line) => RunMutantTestedEvent.make({
|
|
244
279
|
id: line.id,
|
|
@@ -290,6 +325,7 @@ const VerdictMutant = S.Struct({
|
|
|
290
325
|
});
|
|
291
326
|
const RunScope = S.Literals(["full", "diff"]);
|
|
292
327
|
const MutantSetPolicy = S.Literals(["default", "full"]);
|
|
328
|
+
const IncrementalMode = S.Literals(["incremental", "full"]);
|
|
293
329
|
const PhaseDurations = S.Struct({
|
|
294
330
|
prepare: Report_exports.NonNegativeFinite,
|
|
295
331
|
instrument: Report_exports.NonNegativeFinite,
|
|
@@ -300,6 +336,10 @@ const StaticVerdict = S.Struct({
|
|
|
300
336
|
count: Report_exports.NonNegativeInt,
|
|
301
337
|
costMs: Report_exports.NonNegativeFinite
|
|
302
338
|
});
|
|
339
|
+
const Budget = S.Struct({
|
|
340
|
+
predictedSeconds: Report_exports.NonNegativeFinite,
|
|
341
|
+
actualSeconds: Report_exports.NonNegativeFinite
|
|
342
|
+
});
|
|
303
343
|
var VerdictReached = class extends S.TaggedClass()("verdict", {
|
|
304
344
|
schemaVersion: StreamSchemaVersion,
|
|
305
345
|
runId: RunId,
|
|
@@ -312,8 +352,10 @@ var VerdictReached = class extends S.TaggedClass()("verdict", {
|
|
|
312
352
|
mutants: S.Array(VerdictMutant),
|
|
313
353
|
scope: RunScope,
|
|
314
354
|
mutantSetPolicy: MutantSetPolicy,
|
|
355
|
+
incrementalMode: S.optionalKey(IncrementalMode),
|
|
315
356
|
phaseDurations: S.NullOr(PhaseDurations),
|
|
316
|
-
static: S.NullOr(StaticVerdict)
|
|
357
|
+
static: S.NullOr(StaticVerdict),
|
|
358
|
+
budget: Budget
|
|
317
359
|
}) {};
|
|
318
360
|
const FrameworkContributionRow = S.Struct({
|
|
319
361
|
name: S.String,
|
|
@@ -360,6 +402,10 @@ var ReuseReported = class extends S.TaggedClass()("reuse", {
|
|
|
360
402
|
ran: Report_exports.NonNegativeInt,
|
|
361
403
|
refused: ReuseRefusals
|
|
362
404
|
}) {};
|
|
405
|
+
var TceReported = class extends S.TaggedClass()("tce", {
|
|
406
|
+
equivalentToOriginal: Report_exports.NonNegativeInt,
|
|
407
|
+
duplicateAtSite: Report_exports.NonNegativeInt
|
|
408
|
+
}) {};
|
|
363
409
|
var MutantDetailReported = class extends S.TaggedClass()("mutant-detail", {
|
|
364
410
|
id: Mutant_exports.MutantId,
|
|
365
411
|
status: Mutant_exports.MutantStatusSchema,
|
|
@@ -385,27 +431,37 @@ var HelpRendered = class extends S.TaggedClass()("help", {
|
|
|
385
431
|
code: S.Literals([0]),
|
|
386
432
|
help: S.String
|
|
387
433
|
}) {};
|
|
434
|
+
const RefusalRule = S.Literal("mutation-runs-on-main-ci");
|
|
435
|
+
var Refused = class extends S.TaggedClass()("refused", {
|
|
436
|
+
schemaVersion: StreamSchemaVersion,
|
|
437
|
+
rule: RefusalRule,
|
|
438
|
+
message: S.String
|
|
439
|
+
}) {};
|
|
388
440
|
const RunEvent = Object.assign(S.Union([
|
|
389
441
|
RunStarted,
|
|
390
442
|
PhaseEntered,
|
|
391
443
|
PlanKnown,
|
|
444
|
+
WorkerReported,
|
|
392
445
|
RunMutantTested,
|
|
393
446
|
Heartbeat,
|
|
394
447
|
PluginsReported,
|
|
395
448
|
FormatRegistryResolved,
|
|
396
449
|
SkippedReported,
|
|
397
450
|
ReuseReported,
|
|
451
|
+
TceReported,
|
|
398
452
|
MutantDetailReported,
|
|
399
453
|
FeedbackReported,
|
|
400
454
|
VerdictReached,
|
|
401
455
|
RunFailed,
|
|
402
|
-
HelpRendered
|
|
456
|
+
HelpRendered,
|
|
457
|
+
Refused
|
|
403
458
|
]), { QUEUE_BOUND: 256 });
|
|
404
459
|
const RunEventWireLine = S.String.pipe(S.decodeTo(S.fromJsonString(RunEvent), {
|
|
405
460
|
decode: SchemaGetter$1.transform((line) => line.replace(/\n$/, "")),
|
|
406
461
|
encode: SchemaGetter$1.transform((json) => `${json}\n`)
|
|
407
462
|
}));
|
|
408
463
|
var RunEvent_exports = /* @__PURE__ */ __exportAll$3({
|
|
464
|
+
Budget: () => Budget,
|
|
409
465
|
FeedbackJudgment: () => FeedbackJudgment,
|
|
410
466
|
FeedbackReported: () => FeedbackReported,
|
|
411
467
|
FormatClaimShadowingRow: () => FormatClaimShadowingRow,
|
|
@@ -415,7 +471,8 @@ var RunEvent_exports = /* @__PURE__ */ __exportAll$3({
|
|
|
415
471
|
FrameworkModuleRow: () => FrameworkModuleRow,
|
|
416
472
|
Heartbeat: () => Heartbeat,
|
|
417
473
|
HelpRendered: () => HelpRendered,
|
|
418
|
-
|
|
474
|
+
IncrementalMode: () => IncrementalMode,
|
|
475
|
+
MutantCost: () => MutantCost$1,
|
|
419
476
|
MutantDetailReported: () => MutantDetailReported,
|
|
420
477
|
MutantSetPolicy: () => MutantSetPolicy,
|
|
421
478
|
PhaseDurations: () => PhaseDurations,
|
|
@@ -423,6 +480,8 @@ var RunEvent_exports = /* @__PURE__ */ __exportAll$3({
|
|
|
423
480
|
PlanKnown: () => PlanKnown,
|
|
424
481
|
PluginLoadFailureReason: () => PluginLoadFailureReason,
|
|
425
482
|
PluginsReported: () => PluginsReported,
|
|
483
|
+
RefusalRule: () => RefusalRule,
|
|
484
|
+
Refused: () => Refused,
|
|
426
485
|
ReuseRefusals: () => ReuseRefusals,
|
|
427
486
|
ReuseReported: () => ReuseReported,
|
|
428
487
|
RunEvent: () => RunEvent,
|
|
@@ -438,10 +497,13 @@ var RunEvent_exports = /* @__PURE__ */ __exportAll$3({
|
|
|
438
497
|
SkippedReported: () => SkippedReported,
|
|
439
498
|
StaticVerdict: () => StaticVerdict,
|
|
440
499
|
StreamSchemaVersion: () => StreamSchemaVersion,
|
|
500
|
+
TceReported: () => TceReported,
|
|
441
501
|
VerdictLocation: () => VerdictLocation,
|
|
442
502
|
VerdictMutant: () => VerdictMutant,
|
|
443
503
|
VerdictReached: () => VerdictReached,
|
|
444
|
-
VerdictThresholds: () => VerdictThresholds
|
|
504
|
+
VerdictThresholds: () => VerdictThresholds,
|
|
505
|
+
WorkerReported: () => WorkerReported,
|
|
506
|
+
WorkerRole: () => WorkerRole
|
|
445
507
|
});
|
|
446
508
|
const SpanName = S.String.check(S.isPattern(/^[A-Za-z][A-Za-z0-9_-]*(?:\.[A-Za-z][A-Za-z0-9_-]*)*$/u, { expected: "a dot-separated span name whose segments start with a letter, such as \"stryker.checker.check\"" })).pipe(S.brand("SpanName"));
|
|
447
509
|
const SpanAttributeKey = S.String.check(S.isPattern(/^[A-Za-z][A-Za-z0-9_.-]*$/u, { expected: "an attribute key starting with a letter, such as \"stryker.checker.name\"" })).pipe(S.brand("SpanAttributeKey"));
|
|
@@ -688,74 +750,6 @@ const Spans = {
|
|
|
688
750
|
name: "stryker.load_config",
|
|
689
751
|
attributes: {}
|
|
690
752
|
},
|
|
691
|
-
mergeReports: {
|
|
692
|
-
name: "stryker.merge_reports",
|
|
693
|
-
attributes: {}
|
|
694
|
-
},
|
|
695
|
-
mergeReportsCollectPartDirs: {
|
|
696
|
-
name: "stryker.merge_reports.collect_part_dirs",
|
|
697
|
-
attributes: {}
|
|
698
|
-
},
|
|
699
|
-
mergeReportsDirectoryExists: {
|
|
700
|
-
name: "stryker.merge_reports.directory_exists",
|
|
701
|
-
attributes: {}
|
|
702
|
-
},
|
|
703
|
-
mergeReportsEncodeReport: {
|
|
704
|
-
name: "stryker.merge_reports.encode_report",
|
|
705
|
-
attributes: {}
|
|
706
|
-
},
|
|
707
|
-
mergeReportsFail: {
|
|
708
|
-
name: "stryker.merge_reports.fail",
|
|
709
|
-
attributes: {}
|
|
710
|
-
},
|
|
711
|
-
mergeReportsGather: {
|
|
712
|
-
name: "stryker.merge_reports.gather",
|
|
713
|
-
attributes: {}
|
|
714
|
-
},
|
|
715
|
-
mergeReportsListNames: {
|
|
716
|
-
name: "stryker.merge_reports.list_names",
|
|
717
|
-
attributes: {}
|
|
718
|
-
},
|
|
719
|
-
mergeReportsPutFile: {
|
|
720
|
-
name: "stryker.merge_reports.put_file",
|
|
721
|
-
attributes: {}
|
|
722
|
-
},
|
|
723
|
-
mergeReportsReadPart: {
|
|
724
|
-
name: "stryker.merge_reports.read_part",
|
|
725
|
-
attributes: {}
|
|
726
|
-
},
|
|
727
|
-
mergeReportsReadText: {
|
|
728
|
-
name: "stryker.merge_reports.read_text",
|
|
729
|
-
attributes: {}
|
|
730
|
-
},
|
|
731
|
-
mergeReportsRefuseCommand: {
|
|
732
|
-
name: "stryker.merge_reports.refuse_command",
|
|
733
|
-
attributes: {}
|
|
734
|
-
},
|
|
735
|
-
mergeReportsRefuseParts: {
|
|
736
|
-
name: "stryker.merge_reports.refuse_parts",
|
|
737
|
-
attributes: {}
|
|
738
|
-
},
|
|
739
|
-
mergeReportsRenderHtml: {
|
|
740
|
-
name: "stryker.merge_reports.render_html",
|
|
741
|
-
attributes: {}
|
|
742
|
-
},
|
|
743
|
-
mergeReportsWriteAbsent: {
|
|
744
|
-
name: "stryker.merge_reports.write_absent",
|
|
745
|
-
attributes: {}
|
|
746
|
-
},
|
|
747
|
-
mergeReportsWriteFiles: {
|
|
748
|
-
name: "stryker.merge_reports.write_files",
|
|
749
|
-
attributes: {}
|
|
750
|
-
},
|
|
751
|
-
mergeReportsWriteHtml: {
|
|
752
|
-
name: "stryker.merge_reports.write_html",
|
|
753
|
-
attributes: {}
|
|
754
|
-
},
|
|
755
|
-
mergeReportsWriteMerged: {
|
|
756
|
-
name: "stryker.merge_reports.write_merged",
|
|
757
|
-
attributes: {}
|
|
758
|
-
},
|
|
759
753
|
mutantRun: {
|
|
760
754
|
name: "stryker.mutant_run",
|
|
761
755
|
attributes: {}
|
|
@@ -10244,6 +10238,48 @@ const resolveConfig = Workflow.make({
|
|
|
10244
10238
|
})
|
|
10245
10239
|
});
|
|
10246
10240
|
//#endregion
|
|
10241
|
+
//#region src/atomic-write.cell.ts
|
|
10242
|
+
const writeFileAtomic = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReportingWriteAtomic.name)(function* (ports, file, content) {
|
|
10243
|
+
const directory = ports.path.dirname(file);
|
|
10244
|
+
yield* ports.fs.makeDirectory(directory, { recursive: true });
|
|
10245
|
+
const temp = yield* ports.fs.makeTempFile({
|
|
10246
|
+
directory,
|
|
10247
|
+
prefix: `${ports.path.basename(file)}.`,
|
|
10248
|
+
suffix: ".tmp"
|
|
10249
|
+
});
|
|
10250
|
+
yield* Effect$1.gen(function* () {
|
|
10251
|
+
yield* ports.fs.writeFileString(temp, content);
|
|
10252
|
+
yield* ports.fs.rename(temp, file);
|
|
10253
|
+
}).pipe(Effect$1.onExit((exit) => Exit.isSuccess(exit) ? Effect$1.void : ports.fs.remove(temp).pipe(Effect$1.ignore)));
|
|
10254
|
+
});
|
|
10255
|
+
//#endregion
|
|
10256
|
+
//#region src/mutant-cost.ts
|
|
10257
|
+
const executedTestBodyMsOf = (executedTests) => executedTests.reduce((total, test) => total + test.timeSpentMs, 0);
|
|
10258
|
+
const testBodyMsOf = (result) => Match$1.value(result).pipe(Match$1.when({ status: "killed" }, (killed) => executedTestBodyMsOf(killed.executedTests)), Match$1.when({ status: "survived" }, (survived) => executedTestBodyMsOf(survived.executedTests)), Match$1.orElse(() => 0));
|
|
10259
|
+
const bodyTimeWithinWall = (elapsedMs, testBodyMs) => Math.min(testBodyMs, elapsedMs);
|
|
10260
|
+
const costTotalMsOf = (cost) => cost === void 0 ? void 0 : cost.fixedOverheadMs + cost.testBodyMs;
|
|
10261
|
+
const mutantCostOf = (input) => {
|
|
10262
|
+
const testBodyMs = bodyTimeWithinWall(input.elapsedMs, input.testBodyMs);
|
|
10263
|
+
return {
|
|
10264
|
+
fixedOverheadMs: input.elapsedMs - testBodyMs,
|
|
10265
|
+
testBodyMs,
|
|
10266
|
+
testsExecuted: input.testsExecuted,
|
|
10267
|
+
shared: input.shared
|
|
10268
|
+
};
|
|
10269
|
+
};
|
|
10270
|
+
//#endregion
|
|
10271
|
+
//#region src/budget.ts
|
|
10272
|
+
const MILLIS_PER_SECOND = 1e3;
|
|
10273
|
+
const costMsOf = (result) => costTotalMsOf(result.cost) ?? 0;
|
|
10274
|
+
const predictedSecondsOf = (results, concurrency) => {
|
|
10275
|
+
const lanes = concurrency > 0 ? concurrency : 1;
|
|
10276
|
+
return Arr.reduce(results, 0, (total, result) => total + costMsOf(result)) / lanes / MILLIS_PER_SECOND;
|
|
10277
|
+
};
|
|
10278
|
+
const budgetOf$1 = (input) => ({
|
|
10279
|
+
predictedSeconds: input.planPredictedSeconds ?? predictedSecondsOf(input.results, input.concurrency),
|
|
10280
|
+
actualSeconds: input.actualSeconds
|
|
10281
|
+
});
|
|
10282
|
+
//#endregion
|
|
10247
10283
|
//#region src/build-reproducers.workflow.ts
|
|
10248
10284
|
const CONTEXT_LINES = 3;
|
|
10249
10285
|
const maxOf$1 = (left, right) => Boolean$1$1.match(left < right, {
|
|
@@ -10315,7 +10351,7 @@ const fileNameOrder = Order.mapInput(Order.String, (reproducer) => reproducer.fi
|
|
|
10315
10351
|
const idOrder$1 = Order.mapInput(Order.String, (reproducer) => reproducer.id);
|
|
10316
10352
|
const reproducersOf = (report) => Arr.sort(Arr.flatMap(Object.entries(report.files), ([fileName, file]) => Arr.map(file.mutants, (mutant) => reproducerOf(fileName, file.source, mutant))), Order.combine(fileNameOrder, idOrder$1));
|
|
10317
10353
|
const mutantsOf = (report) => Arr.flatMap(Object.values(report.files), (file) => file.mutants);
|
|
10318
|
-
const decide$
|
|
10354
|
+
const decide$24 = (command) => {
|
|
10319
10355
|
const mutants = mutantsOf(command.report);
|
|
10320
10356
|
return Boolean$1$1.match(mutants.length === 0, {
|
|
10321
10357
|
onTrue: () => NoMutantsToReproduce.make({}),
|
|
@@ -10326,7 +10362,7 @@ const buildReproducers = Workflow.make({
|
|
|
10326
10362
|
command: BuildReproducersCommand,
|
|
10327
10363
|
decision: BuildReproducersDecision,
|
|
10328
10364
|
error: S.Never,
|
|
10329
|
-
decide: (command) => Result.succeed(decide$
|
|
10365
|
+
decide: (command) => Result.succeed(decide$24(command))
|
|
10330
10366
|
});
|
|
10331
10367
|
//#endregion
|
|
10332
10368
|
//#region src/checkpoint-mutants.workflow.ts
|
|
@@ -10350,7 +10386,7 @@ var CheckpointMutantsCommand = class extends S.TaggedClass()("CheckpointMutantsC
|
|
|
10350
10386
|
};
|
|
10351
10387
|
const settledByIdOf = (settled) => HashMap.fromIterable(settled.map((row) => [row.mutant.id, row]));
|
|
10352
10388
|
const rowOf = (mutant, settledById) => Option$1.getOrElse(HashMap.get(settledById, mutant.id), () => CheckpointPendingMutant.make({ mutant }));
|
|
10353
|
-
const decide$
|
|
10389
|
+
const decide$23 = (command) => {
|
|
10354
10390
|
const settledById = settledByIdOf(command.settled);
|
|
10355
10391
|
return Result.succeed(command.plannedMutants.map((mutant) => rowOf(mutant, settledById)));
|
|
10356
10392
|
};
|
|
@@ -10358,7 +10394,7 @@ const checkpointMutants = Workflow.make({
|
|
|
10358
10394
|
command: CheckpointMutantsCommand,
|
|
10359
10395
|
decision: S.Array(CheckpointMutantRow),
|
|
10360
10396
|
error: S.Never,
|
|
10361
|
-
decide: decide$
|
|
10397
|
+
decide: decide$23
|
|
10362
10398
|
});
|
|
10363
10399
|
//#endregion
|
|
10364
10400
|
//#region src/classify-exit.workflow.ts
|
|
@@ -10407,7 +10443,7 @@ const verdictExitClass = (score, breakingThreshold) => Match$1.valueTags(score,
|
|
|
10407
10443
|
onSome: (threshold) => Match$1.value(percentage < threshold).pipe(Match$1.when(true, () => "VerdictFail"), Match$1.when(false, () => null), Match$1.exhaustive)
|
|
10408
10444
|
})
|
|
10409
10445
|
});
|
|
10410
|
-
const decide$
|
|
10446
|
+
const decide$22 = (command) => Option$1.match(Option$1.fromNullishOr(verdictExitClass(command.score, command.breakingThreshold)), {
|
|
10411
10447
|
onNone: () => Option$1.match(precedenceOf(command.pending), {
|
|
10412
10448
|
onNone: () => Result.succeed(ExitPassed.make({})),
|
|
10413
10449
|
onSome: (exitClass) => Result.succeed(decisionOf$3(exitClass))
|
|
@@ -10418,7 +10454,7 @@ const classifyExit = Workflow.make({
|
|
|
10418
10454
|
command: ClassifyExitCommand,
|
|
10419
10455
|
decision: ClassifyExitDecision,
|
|
10420
10456
|
error: S.Never,
|
|
10421
|
-
decide: decide$
|
|
10457
|
+
decide: decide$22
|
|
10422
10458
|
});
|
|
10423
10459
|
//#endregion
|
|
10424
10460
|
//#region src/IncrementalDiff.schema.ts
|
|
@@ -10480,6 +10516,61 @@ const ReuseReportSchema = S.Struct({
|
|
|
10480
10516
|
testFiles: S.optional(ReuseTestFilesSchema)
|
|
10481
10517
|
});
|
|
10482
10518
|
//#endregion
|
|
10519
|
+
//#region src/MutantCost.schema.ts
|
|
10520
|
+
const MutantCost = S.Struct({
|
|
10521
|
+
predictedMs: S.Finite,
|
|
10522
|
+
actualMs: S.NullOr(S.Finite),
|
|
10523
|
+
coveringTests: S.Int
|
|
10524
|
+
});
|
|
10525
|
+
const MutantCosts = S.Record(Mutant_exports.MutantId, MutantCost);
|
|
10526
|
+
const MutantCostSubject = S.Struct({
|
|
10527
|
+
id: Mutant_exports.MutantId,
|
|
10528
|
+
static: S.optional(S.Boolean)
|
|
10529
|
+
});
|
|
10530
|
+
S.Struct({
|
|
10531
|
+
subject: MutantCostSubject,
|
|
10532
|
+
staticCoverage: S.optional(S.Record(S.String, Report_exports.NonNegativeFinite)),
|
|
10533
|
+
allTestTimesMs: S.Array(Report_exports.NonNegativeFinite),
|
|
10534
|
+
coveringTestTimesMs: S.Array(Report_exports.NonNegativeFinite),
|
|
10535
|
+
executedActualMs: S.optional(Report_exports.NonNegativeFinite),
|
|
10536
|
+
priorActualMs: S.optional(Report_exports.NonNegativeFinite),
|
|
10537
|
+
fixedOverheadMs: Report_exports.NonNegativeFinite
|
|
10538
|
+
});
|
|
10539
|
+
S.Struct({
|
|
10540
|
+
subjects: S.Array(MutantCostSubject),
|
|
10541
|
+
staticCoverage: S.optional(S.Record(S.String, Report_exports.NonNegativeFinite)),
|
|
10542
|
+
allTestTimesMs: S.Array(Report_exports.NonNegativeFinite),
|
|
10543
|
+
coveringTestTimesMsByMutantId: S.Record(S.String, S.Array(Report_exports.NonNegativeFinite)),
|
|
10544
|
+
executedActualMsByMutantId: S.Record(S.String, Report_exports.NonNegativeFinite),
|
|
10545
|
+
priorActualMsByMutantId: S.Record(S.String, Report_exports.NonNegativeFinite),
|
|
10546
|
+
fixedOverheadMs: Report_exports.NonNegativeFinite
|
|
10547
|
+
});
|
|
10548
|
+
//#endregion
|
|
10549
|
+
//#region src/mutant-cost-model.ts
|
|
10550
|
+
const staticHitCountOf = (staticCoverage, id) => Option$1.getOrElse(Option$1.flatMap(Option$1.fromNullishOr(staticCoverage), (coverage) => Record$1.get(coverage, id)), () => 0);
|
|
10551
|
+
const hasStaticHit = (staticCoverage, id) => staticCoverage === void 0 || staticHitCountOf(staticCoverage, id) > 0;
|
|
10552
|
+
const runsWholeSuite$1 = (input) => input.subject.static === true || hasStaticHit(input.staticCoverage, input.subject.id);
|
|
10553
|
+
const coveringTimesOf = (input) => runsWholeSuite$1(input) ? input.allTestTimesMs : input.coveringTestTimesMs;
|
|
10554
|
+
const actualMsOf = (input) => Option$1.getOrElse(Option$1.firstSomeOf([Option$1.fromNullishOr(input.executedActualMs), Option$1.fromNullishOr(input.priorActualMs)]), () => null);
|
|
10555
|
+
const mutantCostOfCase = (input) => {
|
|
10556
|
+
const coveringTimes = coveringTimesOf(input);
|
|
10557
|
+
return {
|
|
10558
|
+
predictedMs: input.fixedOverheadMs + coveringTimes.reduce((total, time) => total + time, 0),
|
|
10559
|
+
actualMs: actualMsOf(input),
|
|
10560
|
+
coveringTests: coveringTimes.length
|
|
10561
|
+
};
|
|
10562
|
+
};
|
|
10563
|
+
const caseOfSubject = (input, subject) => ({
|
|
10564
|
+
subject,
|
|
10565
|
+
staticCoverage: input.staticCoverage,
|
|
10566
|
+
allTestTimesMs: input.allTestTimesMs,
|
|
10567
|
+
coveringTestTimesMs: Option$1.getOrElse(Record$1.get(input.coveringTestTimesMsByMutantId, subject.id), () => []),
|
|
10568
|
+
executedActualMs: Option$1.getOrUndefined(Record$1.get(input.executedActualMsByMutantId, subject.id)),
|
|
10569
|
+
priorActualMs: Option$1.getOrUndefined(Record$1.get(input.priorActualMsByMutantId, subject.id)),
|
|
10570
|
+
fixedOverheadMs: input.fixedOverheadMs
|
|
10571
|
+
});
|
|
10572
|
+
const mutantCostsOf = (input) => Object.fromEntries(input.subjects.map((subject) => [subject.id, mutantCostOfCase(caseOfSubject(input, subject))]));
|
|
10573
|
+
//#endregion
|
|
10483
10574
|
//#region src/mutation-reporting.schema.ts
|
|
10484
10575
|
var ManifestUnreadable = class extends Schema.TaggedError()("ManifestUnreadable", {
|
|
10485
10576
|
specifier: Schema.String,
|
|
@@ -11036,21 +11127,6 @@ S.Literal("mutation-part.json");
|
|
|
11036
11127
|
S.Literal("mutation-stream.jsonl");
|
|
11037
11128
|
const ReportFileNames = S.Record(S.String, Mutant_exports.CanonicalFileName);
|
|
11038
11129
|
//#endregion
|
|
11039
|
-
//#region src/mutant-cost.ts
|
|
11040
|
-
const executedTestBodyMsOf = (executedTests) => executedTests.reduce((total, test) => total + test.timeSpentMs, 0);
|
|
11041
|
-
const testBodyMsOf = (result) => Match$1.value(result).pipe(Match$1.when({ status: "killed" }, (killed) => executedTestBodyMsOf(killed.executedTests)), Match$1.when({ status: "survived" }, (survived) => executedTestBodyMsOf(survived.executedTests)), Match$1.orElse(() => 0));
|
|
11042
|
-
const bodyTimeWithinWall = (elapsedMs, testBodyMs) => Math.min(testBodyMs, elapsedMs);
|
|
11043
|
-
const costTotalMsOf = (cost) => cost === void 0 ? void 0 : cost.fixedOverheadMs + cost.testBodyMs;
|
|
11044
|
-
const mutantCostOf = (input) => {
|
|
11045
|
-
const testBodyMs = bodyTimeWithinWall(input.elapsedMs, input.testBodyMs);
|
|
11046
|
-
return {
|
|
11047
|
-
fixedOverheadMs: input.elapsedMs - testBodyMs,
|
|
11048
|
-
testBodyMs,
|
|
11049
|
-
testsExecuted: input.testsExecuted,
|
|
11050
|
-
shared: input.shared
|
|
11051
|
-
};
|
|
11052
|
-
};
|
|
11053
|
-
//#endregion
|
|
11054
11130
|
//#region src/reporting/static-verdict.ts
|
|
11055
11131
|
const costOrZero = (cost) => Option$1.getOrElse(Option$1.fromUndefinedOr(costTotalMsOf(cost)), () => 0);
|
|
11056
11132
|
const staticVerdictOf = (results) => {
|
|
@@ -11077,8 +11153,10 @@ var VerdictEnvelope = class extends S.Class("VerdictEnvelope")({
|
|
|
11077
11153
|
mutants: S.Array(RunEvent_exports.VerdictMutant),
|
|
11078
11154
|
scope: RunEvent_exports.RunScope,
|
|
11079
11155
|
mutantSetPolicy: RunEvent_exports.MutantSetPolicy,
|
|
11156
|
+
incrementalMode: RunEvent_exports.IncrementalMode,
|
|
11080
11157
|
phaseDurations: S.NullOr(RunEvent_exports.PhaseDurations),
|
|
11081
|
-
static: S.NullOr(RunEvent_exports.StaticVerdict)
|
|
11158
|
+
static: S.NullOr(RunEvent_exports.StaticVerdict),
|
|
11159
|
+
budget: RunEvent_exports.Budget
|
|
11082
11160
|
}) {};
|
|
11083
11161
|
//#endregion
|
|
11084
11162
|
//#region src/reporting/verdict-envelope.ts
|
|
@@ -11117,6 +11195,11 @@ const runIdTextOf = (now) => {
|
|
|
11117
11195
|
};
|
|
11118
11196
|
const generateRunId = (now) => RunEvent_exports.RunId.make(runIdTextOf(now));
|
|
11119
11197
|
const isActionableStatus = S.is(Mutant_exports.ActionableStatusSchema);
|
|
11198
|
+
const ZERO_BUDGET = RunEvent_exports.Budget.make({
|
|
11199
|
+
predictedSeconds: 0,
|
|
11200
|
+
actualSeconds: 0
|
|
11201
|
+
});
|
|
11202
|
+
const budgetOf = (report) => Option$1.getOrElse(Option$1.flatMap(Option$1.fromUndefinedOr(report["budget"]), (raw) => S.decodeUnknownOption(RunEvent_exports.Budget)(raw)), () => ZERO_BUDGET);
|
|
11120
11203
|
const actionableMutants = (files) => Arr.flatMap(Object.entries(files), ([file, fileResult]) => Arr.map(Arr.filter(fileResult.mutants, (mutant) => isActionableStatus(mutant.status)), (mutant) => RunEvent_exports.VerdictMutant.make({
|
|
11121
11204
|
id: mutant.id,
|
|
11122
11205
|
file,
|
|
@@ -11125,13 +11208,17 @@ const actionableMutants = (files) => Arr.flatMap(Object.entries(files), ([file,
|
|
|
11125
11208
|
replacement: mutant.replacement ?? null,
|
|
11126
11209
|
status: mutant.status
|
|
11127
11210
|
})));
|
|
11211
|
+
const reusesVerdicts = (config) => config.incremental === true && config.force !== true;
|
|
11212
|
+
const incrementalModeOf = (decoded) => Option$1.exists(decoded, reusesVerdicts) ? "incremental" : "full";
|
|
11128
11213
|
const embeddedConfig = (report) => {
|
|
11129
11214
|
const JsonReporterSchema = S.Struct({ fileName: S.String });
|
|
11130
11215
|
const MutatorSchema = S.StructWithRest(S.Struct({ mutantSetPolicy: S.optional(RunEvent_exports.MutantSetPolicy) }), [S.Record(S.String, S.Unknown)]);
|
|
11131
11216
|
const EmbeddedConfigSchema = S.StructWithRest(S.Struct({
|
|
11132
11217
|
jsonReporter: S.optional(JsonReporterSchema),
|
|
11133
11218
|
mutator: S.optional(MutatorSchema),
|
|
11134
|
-
since: S.optional(S.String)
|
|
11219
|
+
since: S.optional(S.String),
|
|
11220
|
+
incremental: S.optional(S.Boolean),
|
|
11221
|
+
force: S.optional(S.Boolean)
|
|
11135
11222
|
}), [S.Record(S.String, S.Unknown)]);
|
|
11136
11223
|
const decoded = S.decodeUnknownOption(EmbeddedConfigSchema)(report.config);
|
|
11137
11224
|
const jsonReporter = Option$1.flatMap(decoded, (config) => Option$1.fromUndefinedOr(config.jsonReporter));
|
|
@@ -11140,12 +11227,13 @@ const embeddedConfig = (report) => {
|
|
|
11140
11227
|
return {
|
|
11141
11228
|
jsonReporterFileName: Option$1.getOrUndefined(Option$1.map(jsonReporter, (reporter) => reporter.fileName)),
|
|
11142
11229
|
mutantSetPolicy: Option$1.getOrElse(mutantSetPolicy, () => "default"),
|
|
11143
|
-
scope: Option$1.isSome(since) ? "diff" : "full"
|
|
11230
|
+
scope: Option$1.isSome(since) ? "diff" : "full",
|
|
11231
|
+
incrementalMode: incrementalModeOf(decoded)
|
|
11144
11232
|
};
|
|
11145
11233
|
};
|
|
11146
11234
|
const buildVerdictEnvelope = dual((args) => args.length === 8, (report, mode, signal, runId, basePath, pathService, phaseDurations, staticVerdict) => {
|
|
11147
11235
|
const metrics = Report_exports.metricsFromMutants(Arr.flatMap(Object.values(report.files), (file) => file.mutants));
|
|
11148
|
-
const { jsonReporterFileName, mutantSetPolicy, scope } = embeddedConfig(report);
|
|
11236
|
+
const { jsonReporterFileName, mutantSetPolicy, scope, incrementalMode } = embeddedConfig(report);
|
|
11149
11237
|
return VerdictEnvelope.make({
|
|
11150
11238
|
schemaVersion: RunEvent_exports.StreamSchemaVersion.literal,
|
|
11151
11239
|
runId,
|
|
@@ -11165,14 +11253,33 @@ const buildVerdictEnvelope = dual((args) => args.length === 8, (report, mode, si
|
|
|
11165
11253
|
mutants: actionableMutants(report.files),
|
|
11166
11254
|
scope,
|
|
11167
11255
|
mutantSetPolicy,
|
|
11256
|
+
incrementalMode,
|
|
11168
11257
|
phaseDurations: Option$1.getOrNull(phaseDurations),
|
|
11169
|
-
static: staticVerdict
|
|
11258
|
+
static: staticVerdict,
|
|
11259
|
+
budget: budgetOf(report)
|
|
11170
11260
|
});
|
|
11171
11261
|
});
|
|
11172
11262
|
//#endregion
|
|
11173
11263
|
//#region src/run-events.service.ts
|
|
11174
11264
|
var RunEvents = class extends Context.Service()("@systemfsoftware/stryker-js/run-events.service/RunEvents") {};
|
|
11175
11265
|
var RunIdentity = class extends Context.Service()("@systemfsoftware/stryker-js/run-events.service/RunIdentity") {};
|
|
11266
|
+
var WorkerReports = class extends Context.Service()("@systemfsoftware/stryker-js/run-events.service/WorkerReports") {};
|
|
11267
|
+
const WorkerReportsLive = Layer.effect(WorkerReports, Effect$1.gen(function* () {
|
|
11268
|
+
const queue = yield* RunEvents;
|
|
11269
|
+
const counters = {
|
|
11270
|
+
testRunner: yield* Ref.make(0),
|
|
11271
|
+
checker: yield* Ref.make(0)
|
|
11272
|
+
};
|
|
11273
|
+
return WorkerReports.of({ report: (role, startupMs) => Effect$1.gen(function* () {
|
|
11274
|
+
const index = yield* Ref.getAndUpdate(counters[role], (current) => current + 1);
|
|
11275
|
+
yield* Queue.offer(queue, RunEvent_exports.WorkerReported.make({
|
|
11276
|
+
schemaVersion: RunEvent_exports.StreamSchemaVersion.literal,
|
|
11277
|
+
role,
|
|
11278
|
+
index,
|
|
11279
|
+
startupMs
|
|
11280
|
+
}));
|
|
11281
|
+
}) });
|
|
11282
|
+
}));
|
|
11176
11283
|
//#endregion
|
|
11177
11284
|
//#region src/phase-durations.ts
|
|
11178
11285
|
const elapsedOf = (marks, phase) => Option$1.map(Arr.findFirst(marks, (mark) => mark.phase === phase), (mark) => mark.elapsedMs);
|
|
@@ -11229,7 +11336,7 @@ const strykerOutputFilesOf = (options) => [
|
|
|
11229
11336
|
];
|
|
11230
11337
|
//#endregion
|
|
11231
11338
|
//#region package.json
|
|
11232
|
-
var version = "
|
|
11339
|
+
var version = "16.0.0";
|
|
11233
11340
|
//#endregion
|
|
11234
11341
|
//#region src/stryker-package.schema.ts
|
|
11235
11342
|
var StrykerPackage = class extends S.Class("StrykerPackage")({
|
|
@@ -11377,6 +11484,8 @@ var MutationReporting = class MutationReporting extends Context.Service()("@syst
|
|
|
11377
11484
|
};
|
|
11378
11485
|
return MutationReporting.of({
|
|
11379
11486
|
reportCheckFailure: (mutant, result) => reportCheckFailure(mutant, result),
|
|
11487
|
+
reportIgnored: (mutant, result) => reportIgnored(mutant, result),
|
|
11488
|
+
reportNoCoverage: (mutant) => reportNoCoverage(mutant),
|
|
11380
11489
|
reportMutantRunResult: (mutant, result) => mapRunResult(mutant, result),
|
|
11381
11490
|
reportAll: (input) => reportAll(deps, input),
|
|
11382
11491
|
checkpoint: (input, plannedMutants) => checkpoint(deps, input, plannedMutants)
|
|
@@ -11399,6 +11508,8 @@ const reportMutant = (mutant, status, outcome = {}) => Effect$1.succeed({
|
|
|
11399
11508
|
});
|
|
11400
11509
|
const reportMutantStatus = (mutant, status, statusReason) => reportMutant(mutant, status, { statusReason: statusReason ?? mutant.statusReason });
|
|
11401
11510
|
const reportCheckFailure = (mutant, result) => reportMutantStatus(mutant, "CompileError", result.reason);
|
|
11511
|
+
const reportIgnored = (mutant, result) => reportMutantStatus(mutant, "Ignored", result.reason);
|
|
11512
|
+
const reportNoCoverage = (mutant) => reportMutantStatus(mutant, "NoCoverage");
|
|
11402
11513
|
const reasonedOutcomeOf = (reason) => Option$1.match(Option$1.fromNullishOr(reason), {
|
|
11403
11514
|
onNone: () => ({}),
|
|
11404
11515
|
onSome: (present) => ({ statusReason: present })
|
|
@@ -11622,6 +11733,11 @@ const mutationTestReport = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReport
|
|
|
11622
11733
|
const { files, testFiles, identities } = yield* assembleReport(deps, input, results);
|
|
11623
11734
|
const dependencies = yield* discoverDependencies(deps);
|
|
11624
11735
|
const config = yield* S.encodeEffect(S.fromJsonString(S.Unknown))(input.options).pipe(Effect$1.flatMap(S.decodeEffect(S.fromJsonString(S.Record(S.String, S.Json)))), Effect$1.orDie);
|
|
11736
|
+
const budget = budgetOf$1({
|
|
11737
|
+
results,
|
|
11738
|
+
concurrency: input.concurrency,
|
|
11739
|
+
actualSeconds: ((yield* Clock.currentTimeMillis) - input.runStartedAt) / 1e3
|
|
11740
|
+
});
|
|
11625
11741
|
return {
|
|
11626
11742
|
report: {
|
|
11627
11743
|
files,
|
|
@@ -11633,7 +11749,8 @@ const mutationTestReport = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReport
|
|
|
11633
11749
|
framework: {
|
|
11634
11750
|
...STRYKER_FRAMEWORK,
|
|
11635
11751
|
dependencies
|
|
11636
|
-
}
|
|
11752
|
+
},
|
|
11753
|
+
budget
|
|
11637
11754
|
},
|
|
11638
11755
|
identities
|
|
11639
11756
|
};
|
|
@@ -11674,27 +11791,49 @@ const emitVerdict = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReportingEmit
|
|
|
11674
11791
|
mutants: envelope.mutants,
|
|
11675
11792
|
scope: envelope.scope,
|
|
11676
11793
|
mutantSetPolicy: envelope.mutantSetPolicy,
|
|
11794
|
+
incrementalMode: envelope.incrementalMode,
|
|
11677
11795
|
phaseDurations: envelope.phaseDurations,
|
|
11678
|
-
static: envelope.static
|
|
11796
|
+
static: envelope.static,
|
|
11797
|
+
budget: envelope.budget
|
|
11679
11798
|
}));
|
|
11680
11799
|
});
|
|
11681
11800
|
const dryRunCoverageFieldOf = (testCoverage) => Option$1.match(Option$1.fromUndefinedOr(testCoverage.dryRunCoverage), {
|
|
11682
11801
|
onNone: () => ({}),
|
|
11683
11802
|
onSome: (dryRunCoverage) => ({ dryRunCoverage })
|
|
11684
11803
|
});
|
|
11804
|
+
const testTimesOf = (tests) => Arr.map([...tests], (test) => test.timeSpentMs);
|
|
11805
|
+
const executedEntryOf = (result) => Option$1.match(Option$1.fromUndefinedOr(result.cost), {
|
|
11806
|
+
onNone: () => [],
|
|
11807
|
+
onSome: (cost) => [[result.id, costTotalMsOf(cost) ?? 0]]
|
|
11808
|
+
});
|
|
11809
|
+
const priorEntryOf = (entry) => entry[1].actualMs === null ? [] : [[entry[0], entry[1].actualMs]];
|
|
11810
|
+
const priorCostsOf = (report) => Option$1.getOrElse(Option$1.flatMap(Option$1.fromNullishOr(report), (present) => Option$1.fromNullishOr(present.costs)), () => ({}));
|
|
11811
|
+
const mutantCostModelOf = (input, results) => ({
|
|
11812
|
+
subjects: Arr.map(results, (result) => ({
|
|
11813
|
+
id: result.id,
|
|
11814
|
+
static: result.static
|
|
11815
|
+
})),
|
|
11816
|
+
staticCoverage: input.testCoverage.staticCoverage,
|
|
11817
|
+
allTestTimesMs: Arr.map([...input.testCoverage.testsById], ([, test]) => test.timeSpentMs),
|
|
11818
|
+
coveringTestTimesMsByMutantId: Object.fromEntries([...input.testCoverage.testsByMutantId].map(([mutantId, tests]) => [mutantId, testTimesOf(tests)])),
|
|
11819
|
+
executedActualMsByMutantId: Object.fromEntries(Arr.flatMap(results, executedEntryOf)),
|
|
11820
|
+
priorActualMsByMutantId: Object.fromEntries(Arr.flatMap(Object.entries(priorCostsOf(input.project.incrementalReport)), priorEntryOf)),
|
|
11821
|
+
fixedOverheadMs: input.timeOverheadMs
|
|
11822
|
+
});
|
|
11823
|
+
const costsOf = (input, results) => mutantCostsOf(mutantCostModelOf(input, results));
|
|
11685
11824
|
const writeIncrementalReport = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReportingWriteIncrementalReport.name)(function* (deps, input, report, identities) {
|
|
11686
|
-
yield* deps.fs.makeDirectory(deps.path.dirname(input.options.incrementalFile), { recursive: true });
|
|
11687
11825
|
const runInputsDigest = yield* runInputsDigestOf(deps.fs, deps.path, input.basePath, input.options);
|
|
11688
11826
|
const json = yield* S.encodeEffect(S.fromJsonString(S.Unknown, { space: 2 }))({
|
|
11689
|
-
incrementalVersion: "
|
|
11690
|
-
verdictSemanticsVersion:
|
|
11827
|
+
incrementalVersion: "3",
|
|
11828
|
+
verdictSemanticsVersion: 3,
|
|
11691
11829
|
mutantSetPolicy: input.options.mutator.mutantSetPolicy,
|
|
11692
11830
|
runInputsDigest,
|
|
11693
11831
|
...report,
|
|
11694
11832
|
files: stampFileIdentities(stampClosureDigests(report.files, input.closureDigestsByMutantId), identities),
|
|
11833
|
+
costs: costsOf(input, input.results),
|
|
11695
11834
|
...dryRunCoverageFieldOf(input.testCoverage)
|
|
11696
11835
|
}).pipe(Effect$1.orDie);
|
|
11697
|
-
yield* deps
|
|
11836
|
+
yield* writeFileAtomic(deps, input.options.incrementalFile, json);
|
|
11698
11837
|
});
|
|
11699
11838
|
const writeReproducers = (deps, input, report) => {
|
|
11700
11839
|
const decision = Result.getOrThrow(buildReproducers(BuildReproducersCommand.make({ report })));
|
|
@@ -11731,24 +11870,24 @@ const reportAll = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReportingReport
|
|
|
11731
11870
|
verdict: finalVerdict
|
|
11732
11871
|
};
|
|
11733
11872
|
});
|
|
11734
|
-
const writeAtomic = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReportingWriteAtomic.name)(function* (deps, file, content) {
|
|
11735
|
-
yield* deps.fs.makeDirectory(deps.path.dirname(file), { recursive: true });
|
|
11736
|
-
const tmp = `${file}.tmp`;
|
|
11737
|
-
yield* deps.fs.writeFileString(tmp, content);
|
|
11738
|
-
yield* deps.fs.rename(tmp, file).pipe(Effect$1.catch(() => deps.fs.copyFile(tmp, file).pipe(Effect$1.andThen(deps.fs.remove(tmp)))));
|
|
11739
|
-
});
|
|
11740
11873
|
const slimIncrementalReport = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReportingSlimIncrementalReport.name)(function* (deps, input, results) {
|
|
11741
11874
|
const { files, testFiles, identities } = yield* assembleReport(deps, input, results);
|
|
11742
11875
|
const runInputsDigest = yield* runInputsDigestOf(deps.fs, deps.path, input.basePath, input.options);
|
|
11743
11876
|
return {
|
|
11744
|
-
incrementalVersion: "
|
|
11745
|
-
verdictSemanticsVersion:
|
|
11877
|
+
incrementalVersion: "3",
|
|
11878
|
+
verdictSemanticsVersion: 3,
|
|
11746
11879
|
mutantSetPolicy: input.options.mutator.mutantSetPolicy,
|
|
11747
11880
|
runInputsDigest,
|
|
11748
11881
|
schemaVersion: Report_exports.WrittenSchemaVersion.literal,
|
|
11749
11882
|
thresholds: input.options.thresholds,
|
|
11750
11883
|
files: stampFileIdentities(stampClosureDigests(files, input.closureDigestsByMutantId), identities),
|
|
11884
|
+
costs: costsOf(input, results),
|
|
11751
11885
|
testFiles,
|
|
11886
|
+
budget: budgetOf$1({
|
|
11887
|
+
results,
|
|
11888
|
+
concurrency: input.concurrency,
|
|
11889
|
+
actualSeconds: ((yield* Clock.currentTimeMillis) - input.runStartedAt) / 1e3
|
|
11890
|
+
}),
|
|
11752
11891
|
...dryRunCoverageFieldOf(input.testCoverage)
|
|
11753
11892
|
};
|
|
11754
11893
|
});
|
|
@@ -11782,7 +11921,7 @@ const checkpointResultsOf = (input, plannedMutants) => Result.match(checkpointMu
|
|
|
11782
11921
|
const checkpointIncremental = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReportingCheckpoint.name)(function* (deps, input, plannedMutants) {
|
|
11783
11922
|
const report = yield* slimIncrementalReport(deps, input, checkpointResultsOf(input, plannedMutants));
|
|
11784
11923
|
const json = yield* S.encodeEffect(S.fromJsonString(S.Unknown))(report).pipe(Effect$1.orDie);
|
|
11785
|
-
yield*
|
|
11924
|
+
yield* writeFileAtomic(deps, input.options.incrementalFile, json);
|
|
11786
11925
|
});
|
|
11787
11926
|
const checkpoint = (deps, input, plannedMutants) => Boolean$1$1.match(input.options.incremental, {
|
|
11788
11927
|
onTrue: () => checkpointIncremental(deps, input, plannedMutants),
|
|
@@ -12399,8 +12538,8 @@ const renderJsonReport = Workflow.make({
|
|
|
12399
12538
|
});
|
|
12400
12539
|
//#endregion
|
|
12401
12540
|
//#region src/json-report.cell.ts
|
|
12402
|
-
const reportOf$
|
|
12403
|
-
const readJsonReport = (input) => Effect$1.map(Stream.fromAsyncIterable(input.events, failAsJsonReporter).pipe(Stream.filterMap(reportOf$
|
|
12541
|
+
const reportOf$1 = Filter.make((event) => Match$1.value(event).pipe(Match$1.tag("mutationTestReportReady", (ready) => Result.succeed(ready.report)), Match$1.orElse(() => Result.fail("not-ready"))));
|
|
12542
|
+
const readJsonReport = (input) => Effect$1.map(Stream.fromAsyncIterable(input.events, failAsJsonReporter).pipe(Stream.filterMap(reportOf$1), Stream.run(Sink.last())), (last) => ({
|
|
12404
12543
|
_tag: "JsonReportCommand",
|
|
12405
12544
|
reported: Option$1.getOrUndefined(last),
|
|
12406
12545
|
rendered: true,
|
|
@@ -12834,7 +12973,7 @@ const logOf = (command, results) => {
|
|
|
12834
12973
|
}]
|
|
12835
12974
|
};
|
|
12836
12975
|
};
|
|
12837
|
-
const decide$
|
|
12976
|
+
const decide$21 = (command) => {
|
|
12838
12977
|
const surfaced = surfacedOf(command);
|
|
12839
12978
|
const results = Arr.take(surfaced, command.maxResults);
|
|
12840
12979
|
const log = logOf(command, results);
|
|
@@ -12850,7 +12989,7 @@ const sarifReport = Workflow.make({
|
|
|
12850
12989
|
command: SarifReportCommand,
|
|
12851
12990
|
decision: SarifReportDecision,
|
|
12852
12991
|
error: S.Never,
|
|
12853
|
-
decide: (command) => Result.succeed(decide$
|
|
12992
|
+
decide: (command) => Result.succeed(decide$21(command))
|
|
12854
12993
|
});
|
|
12855
12994
|
//#endregion
|
|
12856
12995
|
//#region src/cap-survivors.workflow.ts
|
|
@@ -12967,7 +13106,7 @@ const linesOf = (command) => {
|
|
|
12967
13106
|
onFalse: () => Arr.flatMap(Option$1.toArray(HashMap.get(byId, ref.id)), (entry) => [lineOf(entry)])
|
|
12968
13107
|
}));
|
|
12969
13108
|
};
|
|
12970
|
-
const decide$
|
|
13109
|
+
const decide$20 = (command) => {
|
|
12971
13110
|
const lines = linesOf(command);
|
|
12972
13111
|
return Boolean$1$1.match(Arr.length(lines) === 0, {
|
|
12973
13112
|
onTrue: () => NothingToAnnotate.make({ survivorCount: Arr.length(command.survivors) }),
|
|
@@ -12978,7 +13117,7 @@ Workflow.make({
|
|
|
12978
13117
|
command: RenderAnnotationsCommand,
|
|
12979
13118
|
decision: RenderAnnotationsDecision,
|
|
12980
13119
|
error: S.Never,
|
|
12981
|
-
decide: (command) => Result.succeed(decide$
|
|
13120
|
+
decide: (command) => Result.succeed(decide$20(command))
|
|
12982
13121
|
});
|
|
12983
13122
|
//#endregion
|
|
12984
13123
|
//#region src/surfacing.ts
|
|
@@ -13054,8 +13193,8 @@ const failAsSarif = (cause) => Reporter_exports.ReporterFailed.make({
|
|
|
13054
13193
|
event: "mutationTestReportReady",
|
|
13055
13194
|
cause: Option$1.getOrElse(Option$1.map(ErrorText_exports.errorTextOf(cause), (rendered) => rendered.text), () => "")
|
|
13056
13195
|
});
|
|
13057
|
-
const reportOf
|
|
13058
|
-
const readSarifReport = (events) => Effect$1.map(Stream.fromAsyncIterable(events, failAsSarif).pipe(Stream.filterMap(reportOf
|
|
13196
|
+
const reportOf = Filter.make((event) => Match$1.value(event).pipe(Match$1.tag("mutationTestReportReady", (ready) => Result.succeed(ready.report)), Match$1.orElse(() => Result.fail("not-ready"))));
|
|
13197
|
+
const readSarifReport = (events) => Effect$1.map(Stream.fromAsyncIterable(events, failAsSarif).pipe(Stream.filterMap(reportOf), Stream.run(Sink.last())), (last) => Option$1.getOrUndefined(last));
|
|
13059
13198
|
const writeSarifReport = (options, report) => Effect$1.gen(function* () {
|
|
13060
13199
|
const fs = yield* FileSystem.FileSystem;
|
|
13061
13200
|
const path = yield* Path.Path;
|
|
@@ -13144,7 +13283,7 @@ var RunEnvironment = class extends Context.Service()("@systemfsoftware/stryker-j
|
|
|
13144
13283
|
};
|
|
13145
13284
|
const stageLayerOf = (env, events) => {
|
|
13146
13285
|
const eventsLayer = Match$1.value(events).pipe(Match$1.when(void 0, () => Layer.effect(RunEvents, Queue.bounded(RunEvent_exports.RunEvent.QUEUE_BOUND))), Match$1.orElse((queue) => Layer.succeed(RunEvents, queue)));
|
|
13147
|
-
const stageLayer = Layer.mergeAll(Layer.succeed(RunEnvironment, env), eventsLayer, PhaseClock.layer(env.runStartedAt), IdGenerator.layer, ProjectFiles.layer, Layer.effect(Scope.Scope, Effect$1.gen(function* () {
|
|
13286
|
+
const stageLayer = Layer.mergeAll(Layer.succeed(RunEnvironment, env), eventsLayer, WorkerReportsLive.pipe(Layer.provide(eventsLayer)), PhaseClock.layer(env.runStartedAt), IdGenerator.layer, ProjectFiles.layer, Layer.effect(Scope.Scope, Effect$1.gen(function* () {
|
|
13148
13287
|
const stageScope = yield* Scope.make();
|
|
13149
13288
|
yield* Effect$1.addFinalizer((exit) => Scope.close(stageScope, exit));
|
|
13150
13289
|
return stageScope;
|
|
@@ -13512,7 +13651,7 @@ var WorkerCrashed = class extends S.TaggedClass()("WorkerCrashed", {
|
|
|
13512
13651
|
};
|
|
13513
13652
|
const ClassifyWorkerExitDecision = S.Union([WorkerOutOfMemory, WorkerCrashed]);
|
|
13514
13653
|
const OutOfMemoryExitCode = S.Literals([134, 137]);
|
|
13515
|
-
const decide$
|
|
13654
|
+
const decide$19 = (command) => Boolean$1$1.match(S.is(OutOfMemoryExitCode)(command.exitCode), {
|
|
13516
13655
|
onTrue: () => Result.succeed(WorkerOutOfMemory.make({
|
|
13517
13656
|
pid: command.pid,
|
|
13518
13657
|
exitCode: command.exitCode
|
|
@@ -13526,7 +13665,7 @@ const classifyWorkerExit = Workflow.make({
|
|
|
13526
13665
|
command: ClassifyWorkerExitCommand,
|
|
13527
13666
|
decision: ClassifyWorkerExitDecision,
|
|
13528
13667
|
error: S.Never,
|
|
13529
|
-
decide: decide$
|
|
13668
|
+
decide: decide$19
|
|
13530
13669
|
});
|
|
13531
13670
|
//#endregion
|
|
13532
13671
|
//#region src/git-diff.schema.ts
|
|
@@ -13858,7 +13997,9 @@ const IncrementalReportSchema = S.StructWithRest(S.Struct({
|
|
|
13858
13997
|
runInputsDigest: S.String,
|
|
13859
13998
|
thresholds: ThresholdsLikeSchema,
|
|
13860
13999
|
files: S.Record(S.String, FileResultLikeSchema),
|
|
14000
|
+
costs: MutantCosts,
|
|
13861
14001
|
testFiles: S.optional(S.Record(S.String, TestFileLikeSchema)),
|
|
14002
|
+
budget: S.optional(RunEvent_exports.Budget),
|
|
13862
14003
|
dryRunCoverage: S.optionalKey(S.Unknown)
|
|
13863
14004
|
}), [S.Record(S.String, S.Unknown)]);
|
|
13864
14005
|
//#endregion
|
|
@@ -13936,12 +14077,12 @@ const splitOf = (details, checkerCount) => Boolean$1$1.match(checkerCount > 0, {
|
|
|
13936
14077
|
announcement: details.announcement
|
|
13937
14078
|
})
|
|
13938
14079
|
});
|
|
13939
|
-
const decide$
|
|
14080
|
+
const decide$18 = (command) => Result.succeed(splitOf(detailsOf(command.concurrency, command.availableParallelism), command.checkerCount));
|
|
13940
14081
|
const resolveConcurrency = Workflow.make({
|
|
13941
14082
|
command: ResolveConcurrency,
|
|
13942
14083
|
decision: ConcurrencySplit,
|
|
13943
14084
|
error: S.Never,
|
|
13944
|
-
decide: decide$
|
|
14085
|
+
decide: decide$18
|
|
13945
14086
|
});
|
|
13946
14087
|
//#endregion
|
|
13947
14088
|
//#region src/concurrency.cell.ts
|
|
@@ -14173,7 +14314,7 @@ const discardOf = (reason, actual, expected) => IncrementalReportDiscard.make({
|
|
|
14173
14314
|
actual,
|
|
14174
14315
|
expected
|
|
14175
14316
|
});
|
|
14176
|
-
const decide$
|
|
14317
|
+
const decide$17 = (command) => Option$1.match(Option$1.fromUndefinedOr(command.report), {
|
|
14177
14318
|
onNone: () => discardOf("noPriorRecord", void 0, command.expectedIncrementalVersion),
|
|
14178
14319
|
onSome: (report) => Option$1.match(Option$1.firstSomeOf(identityMismatchesOf(command, report).map(mismatchOptionOf)), {
|
|
14179
14320
|
onNone: () => IncrementalReportKeep.make({ report }),
|
|
@@ -14184,7 +14325,7 @@ const admitIncrementalReport = Workflow.make({
|
|
|
14184
14325
|
command: AdmitIncrementalReportCommand,
|
|
14185
14326
|
decision: S.Union([IncrementalReportKeep, IncrementalReportDiscard]),
|
|
14186
14327
|
error: S.Never,
|
|
14187
|
-
decide: (command) => Result.succeed(decide$
|
|
14328
|
+
decide: (command) => Result.succeed(decide$17(command))
|
|
14188
14329
|
});
|
|
14189
14330
|
//#endregion
|
|
14190
14331
|
//#region src/git-diff.workflow.ts
|
|
@@ -14539,11 +14680,15 @@ const ALWAYS_IGNORE = Object.freeze([
|
|
|
14539
14680
|
"/stryker.log",
|
|
14540
14681
|
".next",
|
|
14541
14682
|
".nuxt",
|
|
14542
|
-
".svelte-kit"
|
|
14683
|
+
".svelte-kit",
|
|
14684
|
+
".turbo"
|
|
14543
14685
|
]);
|
|
14544
14686
|
const CRAWL_CONCURRENCY = 256;
|
|
14545
14687
|
const DISCARD_TEXTS = {
|
|
14546
|
-
noPriorRecord: (command) => `Unable to parse incremental result file at ${command.incrementalFile}
|
|
14688
|
+
noPriorRecord: (command) => `Unable to parse incremental result file at ${command.incrementalFile}${Option$1.match(Option$1.fromUndefinedOr(command.decodeError), {
|
|
14689
|
+
onNone: () => "",
|
|
14690
|
+
onSome: (error) => `: ${error}`
|
|
14691
|
+
})}; a full mutation testing run will be performed.`,
|
|
14547
14692
|
cacheLayoutChanged: (command, discard) => `Incremental result file at ${command.incrementalFile} has cache layout version ${discard.actual ?? ""}, expected ${discard.expected}; a full mutation testing run will be performed.`,
|
|
14548
14693
|
semanticsChanged: (command, discard) => `Incremental result file at ${command.incrementalFile} has verdict semantics version ${discard.actual ?? ""}, expected ${discard.expected}; a full mutation testing run will be performed.`,
|
|
14549
14694
|
policyChanged: (command, discard) => `Incremental result file at ${command.incrementalFile} has mutant-set policy ${discard.actual ?? ""}, expected ${discard.expected}; a full mutation testing run will be performed.`,
|
|
@@ -14601,7 +14746,14 @@ const isEntryIncluded = (ignorePatterns, entry) => {
|
|
|
14601
14746
|
};
|
|
14602
14747
|
const resolveInputFileNames = (ignorePatterns, basePath) => crawlDirectory(ignorePatterns, basePath, basePath).pipe(Stream.runCollect, Effect$1.map((files) => [...files]));
|
|
14603
14748
|
const parseAndDecodeIncrementalReport = Schema.decodeUnknownResult(Schema.fromJsonString(IncrementalReportSchema));
|
|
14604
|
-
const
|
|
14749
|
+
const decodeFailureText = (failure) => failure.message.replace(/\s+/gu, " ").trim();
|
|
14750
|
+
const reportReadOf = (contents) => Option$1.match(Option$1.fromUndefinedOr(contents), {
|
|
14751
|
+
onNone: () => ({}),
|
|
14752
|
+
onSome: (text) => Result.match(parseAndDecodeIncrementalReport(text), {
|
|
14753
|
+
onFailure: (failure) => ({ decodeError: decodeFailureText(failure) }),
|
|
14754
|
+
onSuccess: (report) => ({ report })
|
|
14755
|
+
})
|
|
14756
|
+
});
|
|
14605
14757
|
const incrementalContentsOf = (fs, options) => Boolean$1.match(options.incremental, {
|
|
14606
14758
|
onFalse: () => Effect$1.succeedNone,
|
|
14607
14759
|
onTrue: () => fs.readFileString(options.incrementalFile).pipe(Effect$1.asSome, Effect$1.tapError((error) => Match$1.value(error.reason).pipe(Match$1.tag("NotFound", () => Effect$1.logInfo(`No incremental result file found at ${options.incrementalFile}, a full mutation testing run will be performed.`)), Match$1.orElse(() => Effect$1.void))), Effect$1.catchTag("PlatformError", (error) => Match$1.value(error.reason).pipe(Match$1.tag("NotFound", () => Effect$1.succeedNone), Match$1.orElse(() => Effect$1.fail(error)))))
|
|
@@ -14706,11 +14858,12 @@ const readProject = Effect$1.fn(SpanTaxonomy_exports.Spans.projectReadFromDisk.n
|
|
|
14706
14858
|
yield* Effect$1.forEach(testFilePatterns, (pattern) => warnUnmatchedTestPattern(inputFileNames, input.basePath, pattern), { discard: true });
|
|
14707
14859
|
const runInputsDigest = yield* runInputsDigestOf(fs, pathService, input.basePath, options);
|
|
14708
14860
|
const contents = Option$1.getOrUndefined(yield* incrementalContentsOf(fs, options));
|
|
14861
|
+
const reportRead = reportReadOf(contents);
|
|
14709
14862
|
return {
|
|
14710
14863
|
_tag: "AdmitIncrementalReportCommand",
|
|
14711
|
-
report:
|
|
14712
|
-
expectedIncrementalVersion: "
|
|
14713
|
-
verdictSemanticsVersion:
|
|
14864
|
+
report: reportRead.report,
|
|
14865
|
+
expectedIncrementalVersion: "3",
|
|
14866
|
+
verdictSemanticsVersion: 3,
|
|
14714
14867
|
mutantSetPolicy: options.mutator.mutantSetPolicy,
|
|
14715
14868
|
runInputsDigest,
|
|
14716
14869
|
options,
|
|
@@ -14719,6 +14872,7 @@ const readProject = Effect$1.fn(SpanTaxonomy_exports.Spans.projectReadFromDisk.n
|
|
|
14719
14872
|
incremental: options.incremental,
|
|
14720
14873
|
incrementalFile: options.incrementalFile,
|
|
14721
14874
|
contents,
|
|
14875
|
+
decodeError: reportRead.decodeError,
|
|
14722
14876
|
fileDescriptions: decision.fileDescriptions,
|
|
14723
14877
|
testFiles: [...decision.testFiles]
|
|
14724
14878
|
};
|
|
@@ -14771,6 +14925,58 @@ const readProjectCell = Sandwich.named(SpanTaxonomy_exports.Spans.projectRead.na
|
|
|
14771
14925
|
}))
|
|
14772
14926
|
});
|
|
14773
14927
|
//#endregion
|
|
14928
|
+
//#region src/refuse-local-mutation.workflow.ts
|
|
14929
|
+
const LocalMutationDecisionTypeId = Symbol.for("@systemfsoftware/stryker-js/LocalMutationDecision");
|
|
14930
|
+
var RefuseLocalMutationCommand = class extends S.TaggedClass()("RefuseLocalMutationCommand", {
|
|
14931
|
+
dryRunOnly: S.Boolean,
|
|
14932
|
+
githubActions: S.UndefinedOr(S.String),
|
|
14933
|
+
allowLocalMutation: S.UndefinedOr(S.String)
|
|
14934
|
+
}) {
|
|
14935
|
+
static [Workflow.InstrumentationBrand] = {};
|
|
14936
|
+
};
|
|
14937
|
+
var LocalMutationAllowed = class extends S.TaggedClass()("LocalMutationAllowed", {}) {
|
|
14938
|
+
[LocalMutationDecisionTypeId] = LocalMutationDecisionTypeId;
|
|
14939
|
+
};
|
|
14940
|
+
var LocalMutationRefused = class extends S.TaggedError()("LocalMutationRefused", {
|
|
14941
|
+
rule: RunEvent_exports.RefusalRule,
|
|
14942
|
+
message: S.String
|
|
14943
|
+
}) {};
|
|
14944
|
+
const decide$16 = (command) => Match$1.value({
|
|
14945
|
+
dryRunOnly: command.dryRunOnly,
|
|
14946
|
+
githubActions: command.githubActions,
|
|
14947
|
+
allowLocalMutation: command.allowLocalMutation
|
|
14948
|
+
}).pipe(Match$1.when({ dryRunOnly: true }, () => Result.succeed(LocalMutationAllowed.make({}))), Match$1.when({ githubActions: "true" }, () => Result.succeed(LocalMutationAllowed.make({}))), Match$1.when({ allowLocalMutation: "1" }, () => Result.succeed(LocalMutationAllowed.make({}))), Match$1.orElse(() => Result.fail(LocalMutationRefused.make({
|
|
14949
|
+
rule: "mutation-runs-on-main-ci",
|
|
14950
|
+
message: "mutation runs only on main CI"
|
|
14951
|
+
}))));
|
|
14952
|
+
const refuseLocalMutation = Workflow.make({
|
|
14953
|
+
command: RefuseLocalMutationCommand,
|
|
14954
|
+
decision: LocalMutationAllowed,
|
|
14955
|
+
error: LocalMutationRefused,
|
|
14956
|
+
decide: decide$16
|
|
14957
|
+
});
|
|
14958
|
+
//#endregion
|
|
14959
|
+
//#region src/refuse-local-mutation.cell.ts
|
|
14960
|
+
const envOf = (key) => Config.option(Config.String(key)).pipe(Effect$1.map(Option$1.getOrUndefined), Effect$1.orElseSucceed(() => void 0));
|
|
14961
|
+
const guardOf = (input) => Effect$1.gen(function* () {
|
|
14962
|
+
const githubActions = yield* envOf("GITHUB_ACTIONS");
|
|
14963
|
+
const allowLocalMutation = yield* envOf("ALLOW_LOCAL_MUTATION");
|
|
14964
|
+
const command = RefuseLocalMutationCommand.make({
|
|
14965
|
+
dryRunOnly: input.options.dryRunOnly,
|
|
14966
|
+
githubActions,
|
|
14967
|
+
allowLocalMutation
|
|
14968
|
+
});
|
|
14969
|
+
return yield* Result.match(refuseLocalMutation(command), {
|
|
14970
|
+
onFailure: (refused) => Effect$1.fail(StageError.make({
|
|
14971
|
+
stage: "prepare",
|
|
14972
|
+
reason: refused.message,
|
|
14973
|
+
cause: refused
|
|
14974
|
+
})),
|
|
14975
|
+
onSuccess: () => Effect$1.succeed(input)
|
|
14976
|
+
});
|
|
14977
|
+
});
|
|
14978
|
+
const refuseLocalMutationCell = (input) => Cell.fromEffect(guardOf(input));
|
|
14979
|
+
//#endregion
|
|
14774
14980
|
//#region src/dry-run-coverage.schema.ts
|
|
14775
14981
|
const DryRunCoverageSchema = S.Struct({
|
|
14776
14982
|
tests: S.Array(TestRunner_exports.TestResultSchema),
|
|
@@ -15954,6 +16160,35 @@ const buildTestRunner = dual(2, (context, childProcessRunner) => Option$1.match(
|
|
|
15954
16160
|
onNone: () => decorateChildRunner(context, childProcessRunner)
|
|
15955
16161
|
}));
|
|
15956
16162
|
//#endregion
|
|
16163
|
+
//#region src/run/dry-run-coverage.ts
|
|
16164
|
+
const testsByIdOf = (result) => MutableHashMap.fromIterable(result.tests.map((test) => [test.id, test]));
|
|
16165
|
+
const coveredMutantIdsOf = (coverage) => Object.entries(coverage).filter(([, count]) => count > 0).map(([mutantId]) => mutantId);
|
|
16166
|
+
const testsByMutantIdOf = (mutantCoverage, testsById) => Object.entries(mutantCoverage.perTest).reduce((testsByMutantId, [testId, coverage]) => Option$1.match(MutableHashMap.get(testsById, testId), {
|
|
16167
|
+
onNone: () => testsByMutantId,
|
|
16168
|
+
onSome: (test) => coveredMutantIdsOf(coverage).reduce((acc, mutantId) => MutableHashMap.set(acc, mutantId, MutableHashSet.add(Option$1.getOrElse(MutableHashMap.get(acc, mutantId), () => MutableHashSet.empty()), test)), testsByMutantId)
|
|
16169
|
+
}), MutableHashMap.empty());
|
|
16170
|
+
const hitsByMutantIdOf = (mutantCoverage) => [mutantCoverage.static, ...Object.values(mutantCoverage.perTest)].reduce((hitsByMutantId, coverage) => Object.entries(coverage).reduce((acc, [mutantId, count]) => MutableHashMap.set(acc, mutantId, Option$1.getOrElse(MutableHashMap.get(acc, mutantId), () => 0) + count), hitsByMutantId), MutableHashMap.empty());
|
|
16171
|
+
const testCoverageOf = ({ result, dryRunCoverage }) => {
|
|
16172
|
+
const testsById = testsByIdOf(result);
|
|
16173
|
+
const mutantCoverage = Option$1.fromNullishOr(result.mutantCoverage);
|
|
16174
|
+
return {
|
|
16175
|
+
testsByMutantId: Option$1.match(mutantCoverage, {
|
|
16176
|
+
onNone: () => MutableHashMap.empty(),
|
|
16177
|
+
onSome: (coverage) => testsByMutantIdOf(coverage, testsById)
|
|
16178
|
+
}),
|
|
16179
|
+
testsById,
|
|
16180
|
+
staticCoverage: Option$1.match(mutantCoverage, {
|
|
16181
|
+
onNone: () => void 0,
|
|
16182
|
+
onSome: (coverage) => coverage.static
|
|
16183
|
+
}),
|
|
16184
|
+
hitsByMutantId: Option$1.match(mutantCoverage, {
|
|
16185
|
+
onNone: () => MutableHashMap.empty(),
|
|
16186
|
+
onSome: (coverage) => hitsByMutantIdOf(coverage)
|
|
16187
|
+
}),
|
|
16188
|
+
dryRunCoverage
|
|
16189
|
+
};
|
|
16190
|
+
};
|
|
16191
|
+
//#endregion
|
|
15957
16192
|
//#region src/run/incremental-reuse.ts
|
|
15958
16193
|
const absoluteSourceOf = (path, basePath, file) => path.isAbsolute(file) ? file : path.join(basePath, file);
|
|
15959
16194
|
const matchedSourcesOf = Effect$1.fnUntraced(function* (input) {
|
|
@@ -16283,33 +16518,6 @@ const withOriginalFileName = (test, prev) => Match$1.value(test.fileName).pipe(M
|
|
|
16283
16518
|
fileName: originalFileFor(prev.sandbox, fileName)
|
|
16284
16519
|
})), Match$1.orElse(() => test));
|
|
16285
16520
|
const withOriginalFileNames = (tests, prev) => tests.map((test) => withOriginalFileName(test, prev));
|
|
16286
|
-
const testsByIdOf = (result) => MutableHashMap.fromIterable(result.tests.map((test) => [test.id, test]));
|
|
16287
|
-
const coveredMutantIdsOf = (coverage) => Object.entries(coverage).filter(([, count]) => count > 0).map(([mutantId]) => mutantId);
|
|
16288
|
-
const testsByMutantIdOf = (mutantCoverage, testsById) => Object.entries(mutantCoverage.perTest).reduce((testsByMutantId, [testId, coverage]) => Option$1.match(MutableHashMap.get(testsById, testId), {
|
|
16289
|
-
onNone: () => testsByMutantId,
|
|
16290
|
-
onSome: (test) => coveredMutantIdsOf(coverage).reduce((acc, mutantId) => MutableHashMap.set(acc, mutantId, MutableHashSet.add(Option$1.getOrElse(MutableHashMap.get(acc, mutantId), () => MutableHashSet.empty()), test)), testsByMutantId)
|
|
16291
|
-
}), MutableHashMap.empty());
|
|
16292
|
-
const hitsByMutantIdOf = (mutantCoverage) => [mutantCoverage.static, ...Object.values(mutantCoverage.perTest)].reduce((hitsByMutantId, coverage) => Object.entries(coverage).reduce((acc, [mutantId, count]) => MutableHashMap.set(acc, mutantId, Option$1.getOrElse(MutableHashMap.get(acc, mutantId), () => 0) + count), hitsByMutantId), MutableHashMap.empty());
|
|
16293
|
-
const testCoverageFrom = (result, dryRunCoverage) => {
|
|
16294
|
-
const testsById = testsByIdOf(result);
|
|
16295
|
-
const mutantCoverage = Option$1.fromNullishOr(result.mutantCoverage);
|
|
16296
|
-
return {
|
|
16297
|
-
testsByMutantId: Option$1.match(mutantCoverage, {
|
|
16298
|
-
onNone: () => MutableHashMap.empty(),
|
|
16299
|
-
onSome: (coverage) => testsByMutantIdOf(coverage, testsById)
|
|
16300
|
-
}),
|
|
16301
|
-
testsById,
|
|
16302
|
-
staticCoverage: Option$1.match(mutantCoverage, {
|
|
16303
|
-
onNone: () => void 0,
|
|
16304
|
-
onSome: (coverage) => coverage.static
|
|
16305
|
-
}),
|
|
16306
|
-
hitsByMutantId: Option$1.match(mutantCoverage, {
|
|
16307
|
-
onNone: () => MutableHashMap.empty(),
|
|
16308
|
-
onSome: (coverage) => hitsByMutantIdOf(coverage)
|
|
16309
|
-
}),
|
|
16310
|
-
dryRunCoverage
|
|
16311
|
-
};
|
|
16312
|
-
};
|
|
16313
16521
|
const announceDryRunOutcome = (tests, prev, gross, overheadMillis) => Match$1.value(tests.length).pipe(Match$1.when(0, () => Effect$1.logInfo("No tests were found")), Match$1.orElse(() => Effect$1.logInfo(`Initial test run succeeded. Ran ${tests.length} tests in ${Duration.format(gross)} (net ${totalTestTime(tests)} ms, overhead ${overheadMillis} ms).`).pipe(Effect$1.andThen(Effect$1.when(Effect$1.logInfo("Note: running the dry-run only. No mutations will be tested."), Effect$1.succeed(prev.options.dryRunOnly))))));
|
|
16314
16522
|
const reportDryRunCompleted = (raw, tests, overheadMillis) => offerReporterEvent(raw.prev.reporterStage, Reporter_exports.DryRunCompleted.make({
|
|
16315
16523
|
timing: {
|
|
@@ -16333,7 +16541,10 @@ const freshCoverageOf = (raw, dryRunResult, overheadMillis) => ({
|
|
|
16333
16541
|
const dryRunDoneOf = (raw, dryRunResult, coverage) => ({
|
|
16334
16542
|
...raw.prev,
|
|
16335
16543
|
dryRunResult,
|
|
16336
|
-
testCoverage:
|
|
16544
|
+
testCoverage: testCoverageOf({
|
|
16545
|
+
result: dryRunResult,
|
|
16546
|
+
dryRunCoverage: coverage
|
|
16547
|
+
}),
|
|
16337
16548
|
timeOverhead: Duration.millis(coverage.timeOverheadMs)
|
|
16338
16549
|
});
|
|
16339
16550
|
const completeFreshDryRun = Effect$1.fnUntraced(function* (raw, dryRunResult) {
|
|
@@ -16363,6 +16574,7 @@ const completeDryRunPassed = (raw) => Match$1.value(raw.rawResult).pipe(Match$1.
|
|
|
16363
16574
|
}))), Match$1.exhaustive);
|
|
16364
16575
|
const runFreshDryRun = Effect$1.fnUntraced(function* (command, idGenerator, currentTestClosureDigest, runInputsDigest) {
|
|
16365
16576
|
const env = yield* RunEnvironment;
|
|
16577
|
+
const reports = yield* WorkerReports;
|
|
16366
16578
|
const { files, testFiles } = yield* resolveDryRunFiles(command);
|
|
16367
16579
|
const dryRunTimeout = command.options.dryRunTimeoutMinutes * 60 * 1e3;
|
|
16368
16580
|
const options = dryRunOptionsOf(command, files, testFiles, dryRunTimeout);
|
|
@@ -16378,6 +16590,7 @@ const runFreshDryRun = Effect$1.fnUntraced(function* (command, idGenerator, curr
|
|
|
16378
16590
|
idGenerator
|
|
16379
16591
|
})));
|
|
16380
16592
|
});
|
|
16593
|
+
const startedAt = yield* Clock.currentTimeMillis;
|
|
16381
16594
|
const runner = yield* buildTestRunner({
|
|
16382
16595
|
options: command.options,
|
|
16383
16596
|
fileDescriptions: command.project.fileDescriptions,
|
|
@@ -16386,6 +16599,7 @@ const runFreshDryRun = Effect$1.fnUntraced(function* (command, idGenerator, curr
|
|
|
16386
16599
|
retire: Effect$1.void,
|
|
16387
16600
|
testFiles: testFiles ?? []
|
|
16388
16601
|
}, childRunnerEffect);
|
|
16602
|
+
yield* reports.report("testRunner", (yield* Clock.currentTimeMillis) - startedAt);
|
|
16389
16603
|
const capabilities = yield* runner.capabilities.pipe(Effect$1.mapError((cause) => StageError.make({
|
|
16390
16604
|
stage: "dryRun",
|
|
16391
16605
|
reason: "Failed to get test runner capabilities",
|
|
@@ -17337,6 +17551,10 @@ const FailedCheckResultSchema = S.Struct({
|
|
|
17337
17551
|
status: S.Literal("compileError"),
|
|
17338
17552
|
reason: S.String
|
|
17339
17553
|
});
|
|
17554
|
+
const IgnoredCheckResultSchema = S.Struct({
|
|
17555
|
+
status: S.Literal("ignored"),
|
|
17556
|
+
reason: S.String
|
|
17557
|
+
});
|
|
17340
17558
|
var CheckedPlanPassed = class extends S.TaggedClass()("CheckedPlanPassed", {
|
|
17341
17559
|
mutantId: Mutant_exports.MutantId,
|
|
17342
17560
|
entryIndex: S.Int
|
|
@@ -17351,27 +17569,48 @@ var CheckedPlanFailed = class extends S.TaggedClass()("CheckedPlanFailed", {
|
|
|
17351
17569
|
}) {
|
|
17352
17570
|
[CheckedPlanTypeId] = CheckedPlanTypeId;
|
|
17353
17571
|
};
|
|
17572
|
+
var CheckedPlanIgnored = class extends S.TaggedClass()("CheckedPlanIgnored", {
|
|
17573
|
+
mutantId: Mutant_exports.MutantId,
|
|
17574
|
+
entryIndex: S.Int,
|
|
17575
|
+
reason: S.String,
|
|
17576
|
+
result: IgnoredCheckResultSchema
|
|
17577
|
+
}) {
|
|
17578
|
+
[CheckedPlanTypeId] = CheckedPlanTypeId;
|
|
17579
|
+
};
|
|
17354
17580
|
var PartitionCheckedPlansCommand = class extends S.TaggedClass()("PartitionCheckedPlansCommand", { checked: S.Array(S.Tuple([Mutant_exports.MutantId, Checker_exports.CheckResultSchema])) }) {
|
|
17355
17581
|
static [Workflow.InstrumentationBrand] = {};
|
|
17356
17582
|
};
|
|
17357
|
-
const isFailed = (result) => result.status
|
|
17583
|
+
const isFailed = (result) => result.status === "compileError";
|
|
17584
|
+
const isIgnored = (result) => result.status === "ignored";
|
|
17358
17585
|
const failedReasonOf = (failed) => failed.reason;
|
|
17359
|
-
const decideCheckedPlan = (mutantId, result, entryIndex) => Option$1.match(Option$1.liftPredicate(result,
|
|
17360
|
-
|
|
17361
|
-
mutantId,
|
|
17362
|
-
entryIndex
|
|
17363
|
-
}),
|
|
17364
|
-
onSome: (failed) => CheckedPlanFailed.make({
|
|
17586
|
+
const decideCheckedPlan = (mutantId, result, entryIndex) => Option$1.match(Option$1.liftPredicate(result, isIgnored), {
|
|
17587
|
+
onSome: (ignored) => CheckedPlanIgnored.make({
|
|
17365
17588
|
mutantId,
|
|
17366
17589
|
entryIndex,
|
|
17367
|
-
reason:
|
|
17368
|
-
result:
|
|
17590
|
+
reason: ignored.reason,
|
|
17591
|
+
result: ignored
|
|
17592
|
+
}),
|
|
17593
|
+
onNone: () => Option$1.match(Option$1.liftPredicate(result, isFailed), {
|
|
17594
|
+
onNone: () => CheckedPlanPassed.make({
|
|
17595
|
+
mutantId,
|
|
17596
|
+
entryIndex
|
|
17597
|
+
}),
|
|
17598
|
+
onSome: (failed) => CheckedPlanFailed.make({
|
|
17599
|
+
mutantId,
|
|
17600
|
+
entryIndex,
|
|
17601
|
+
reason: failedReasonOf(failed),
|
|
17602
|
+
result: failed
|
|
17603
|
+
})
|
|
17369
17604
|
})
|
|
17370
17605
|
});
|
|
17371
17606
|
const decide$8 = (command) => Result.succeed(command.checked.map(([mutantId, result], entryIndex) => decideCheckedPlan(mutantId, result, entryIndex)));
|
|
17372
17607
|
const partitionCheckedPlans = Workflow.make({
|
|
17373
17608
|
command: PartitionCheckedPlansCommand,
|
|
17374
|
-
decision: S.Array(S.Union([
|
|
17609
|
+
decision: S.Array(S.Union([
|
|
17610
|
+
CheckedPlanPassed,
|
|
17611
|
+
CheckedPlanFailed,
|
|
17612
|
+
CheckedPlanIgnored
|
|
17613
|
+
])),
|
|
17375
17614
|
error: S.Never,
|
|
17376
17615
|
decide: decide$8
|
|
17377
17616
|
});
|
|
@@ -17408,6 +17647,7 @@ const onCheckerSlot = (pool, checkerIndex, run) => Pool.use(pool, (slot) => Opti
|
|
|
17408
17647
|
}));
|
|
17409
17648
|
const noPassedPlans = [];
|
|
17410
17649
|
const noFailedChecks = [];
|
|
17650
|
+
const noIgnoredChecks = [];
|
|
17411
17651
|
const splitCheckedPlans = Effect$1.fn(SpanTaxonomy_exports.Spans.checkerPoolSplitChecked.name)(function* (checked) {
|
|
17412
17652
|
const decisions = yield* Effect$1.fromResult(partitionCheckedPlans(PartitionCheckedPlansCommand.make({ checked: checked.map(([plan, result]) => [plan.mutant.id, result]) })));
|
|
17413
17653
|
return {
|
|
@@ -17418,6 +17658,10 @@ const splitCheckedPlans = Effect$1.fn(SpanTaxonomy_exports.Spans.checkerPoolSpli
|
|
|
17418
17658
|
failedChecks: decisions.flatMap((decision) => Option$1.match(Option$1.liftPredicate(decision, S.is(CheckedPlanFailed)), {
|
|
17419
17659
|
onNone: () => [],
|
|
17420
17660
|
onSome: (failed) => Option$1.toArray(Option$1.map(Arr.get(checked, failed.entryIndex), ([plan]) => [plan, failed.result]))
|
|
17661
|
+
})),
|
|
17662
|
+
ignoredChecks: decisions.flatMap((decision) => Option$1.match(Option$1.liftPredicate(decision, S.is(CheckedPlanIgnored)), {
|
|
17663
|
+
onNone: () => [],
|
|
17664
|
+
onSome: (ignored) => Option$1.toArray(Option$1.map(Arr.get(checked, ignored.entryIndex), ([plan]) => [plan, ignored.result]))
|
|
17421
17665
|
}))
|
|
17422
17666
|
};
|
|
17423
17667
|
});
|
|
@@ -17426,23 +17670,34 @@ const failedElement = (failedChecks) => Option$1.match(Arr.head(failedChecks), {
|
|
|
17426
17670
|
onNone: () => Stream.empty,
|
|
17427
17671
|
onSome: () => Stream.succeed({
|
|
17428
17672
|
passedPlans: noPassedPlans,
|
|
17429
|
-
failedChecks
|
|
17673
|
+
failedChecks,
|
|
17674
|
+
ignoredChecks: noIgnoredChecks
|
|
17675
|
+
})
|
|
17676
|
+
});
|
|
17677
|
+
const ignoredElement = (ignoredChecks) => Option$1.match(Arr.head(ignoredChecks), {
|
|
17678
|
+
onNone: () => Stream.empty,
|
|
17679
|
+
onSome: () => Stream.succeed({
|
|
17680
|
+
passedPlans: noPassedPlans,
|
|
17681
|
+
failedChecks: noFailedChecks,
|
|
17682
|
+
ignoredChecks
|
|
17430
17683
|
})
|
|
17431
17684
|
});
|
|
17432
17685
|
const checkedGroupsFor = (pool, checkerNames, checkerIndex, plans) => Option$1.match(Arr.get(checkerNames, checkerIndex), {
|
|
17433
17686
|
onNone: () => Stream.succeed({
|
|
17434
17687
|
passedPlans: plans,
|
|
17435
|
-
failedChecks: noFailedChecks
|
|
17688
|
+
failedChecks: noFailedChecks,
|
|
17689
|
+
ignoredChecks: noIgnoredChecks
|
|
17436
17690
|
}),
|
|
17437
17691
|
onSome: (checkerName) => Stream.unwrap(onCheckerSlot(pool, checkerIndex, (checker) => groupPlans(checker, checkerName, plans)).pipe(Effect$1.map((groups) => Stream.fromIterable(groups).pipe(Stream.mapEffect((group) => onCheckerSlot(pool, checkerIndex, (checker) => checkPlans$1(checker, checkerName, group)).pipe(Effect$1.flatMap((checked) => splitCheckedPlans(checked))), {
|
|
17438
17692
|
concurrency: "unbounded",
|
|
17439
17693
|
unordered: true
|
|
17440
|
-
}), Stream.flatMap((split) => Stream.concat(failedElement(split.failedChecks), checkedGroupsFor(pool, checkerNames, checkerIndex + 1, split.passedPlans)))))))
|
|
17694
|
+
}), Stream.flatMap((split) => Stream.concat(ignoredElement(split.ignoredChecks), Stream.concat(failedElement(split.failedChecks), checkedGroupsFor(pool, checkerNames, checkerIndex + 1, split.passedPlans))))))))
|
|
17441
17695
|
});
|
|
17442
17696
|
const checkPlansStream = dual(2, (checkerPool, plans) => Option$1.fromNullishOr(checkerPool).pipe(Option$1.match({
|
|
17443
17697
|
onNone: () => Stream.succeed({
|
|
17444
17698
|
passedPlans: plans,
|
|
17445
|
-
failedChecks: noFailedChecks
|
|
17699
|
+
failedChecks: noFailedChecks,
|
|
17700
|
+
ignoredChecks: noIgnoredChecks
|
|
17446
17701
|
}),
|
|
17447
17702
|
onSome: (handle) => checkerNamesOf(CheckerPoolHandle.slot(handle)).pipe(Effect$1.map((checkerNames) => checkedGroupsFor(CheckerPoolHandle.slot(handle), checkerNames, 0, plans)), Stream.unwrap)
|
|
17448
17703
|
}), Stream.withSpan(SpanTaxonomy_exports.Spans.checkerPoolCheckPlans.name)));
|
|
@@ -17450,16 +17705,23 @@ Effect$1.fnUntraced(function* (checkerPool, plans) {
|
|
|
17450
17705
|
const checkedGroups = yield* Stream.runCollect(checkPlansStream(checkerPool, plans));
|
|
17451
17706
|
const passedPlans = [];
|
|
17452
17707
|
const failedChecks = [];
|
|
17708
|
+
const ignoredChecks = [];
|
|
17453
17709
|
for (const group of checkedGroups) {
|
|
17454
17710
|
passedPlans.push(...group.passedPlans);
|
|
17455
17711
|
failedChecks.push(...group.failedChecks);
|
|
17712
|
+
ignoredChecks.push(...group.ignoredChecks);
|
|
17456
17713
|
}
|
|
17457
17714
|
return {
|
|
17458
17715
|
passedPlans,
|
|
17459
|
-
failedChecks
|
|
17716
|
+
failedChecks,
|
|
17717
|
+
ignoredChecks
|
|
17460
17718
|
};
|
|
17461
17719
|
});
|
|
17462
|
-
const runCheckedPlans = dual(2, (self, execution) => self.pipe(Stream.flatMap(({ passedPlans, failedChecks }) => Stream.fromIterable([
|
|
17720
|
+
const runCheckedPlans = dual(2, (self, execution) => self.pipe(Stream.flatMap(({ passedPlans, failedChecks, ignoredChecks }) => Stream.fromIterable([
|
|
17721
|
+
...failedChecks.map(([plan, result]) => () => execution.settleFailure(plan, result)),
|
|
17722
|
+
...ignoredChecks.map(([plan, result]) => () => execution.settleIgnored(plan, result)),
|
|
17723
|
+
...passedPlans.map((plan) => () => execution.runPlan(plan))
|
|
17724
|
+
])), Stream.mapEffect((work) => work(), {
|
|
17463
17725
|
concurrency: Math.max(1, execution.concurrency),
|
|
17464
17726
|
unordered: true
|
|
17465
17727
|
})));
|
|
@@ -17514,11 +17776,13 @@ const checkerWorkerSpawnOf = (loaded, configured) => Effect$1.mapError(Effect$1.
|
|
|
17514
17776
|
cause: PluginNotFoundError.make({ descriptor: missing.descriptor })
|
|
17515
17777
|
}));
|
|
17516
17778
|
const acquire$1 = Effect$1.fnUntraced(function* (spec) {
|
|
17779
|
+
const reports = yield* WorkerReports;
|
|
17517
17780
|
return yield* Boolean$1$1.match(spec.options.checkers.length === 0, {
|
|
17518
17781
|
onTrue: () => Effect$1.as(Effect$1.void, void 0),
|
|
17519
17782
|
onFalse: () => Pool.make({
|
|
17520
17783
|
acquire: Effect$1.forEach(spec.options.checkers, (checker) => Effect$1.gen(function* () {
|
|
17521
17784
|
const resolved = yield* checkerWorkerSpawnOf(spec.loadedPlugins, ConfiguredPluginModulePath.make({ modulePath: checker.plugin }));
|
|
17785
|
+
const startedAt = yield* Clock.currentTimeMillis;
|
|
17522
17786
|
const service = yield* scoped$2({
|
|
17523
17787
|
options: {
|
|
17524
17788
|
...spec.options,
|
|
@@ -17530,6 +17794,7 @@ const acquire$1 = Effect$1.fnUntraced(function* (spec) {
|
|
|
17530
17794
|
times: CHECKER_ACQUIRE_RETRIES,
|
|
17531
17795
|
while: isCheckerCrash
|
|
17532
17796
|
}));
|
|
17797
|
+
yield* reports.report("checker", (yield* Clock.currentTimeMillis) - startedAt);
|
|
17533
17798
|
return {
|
|
17534
17799
|
checkerName: resolved.name,
|
|
17535
17800
|
checker: service
|
|
@@ -17887,7 +18152,7 @@ const readIncrementalReuseCommand = Effect$1.fn(SpanTaxonomy_exports.Spans.incre
|
|
|
17887
18152
|
previousRecords: [...previousRecords],
|
|
17888
18153
|
closureDigestsByMutantId: closures.digests,
|
|
17889
18154
|
closureAnalysisFailed: closures.failed,
|
|
17890
|
-
verdictSemanticsVersion:
|
|
18155
|
+
verdictSemanticsVersion: 3,
|
|
17891
18156
|
mutantSetPolicy: input.options.mutator.mutantSetPolicy,
|
|
17892
18157
|
runInputsDigest,
|
|
17893
18158
|
force: input.force,
|
|
@@ -18070,6 +18335,7 @@ const toReportedMutant = (mutant) => Object.assign(mutant, {
|
|
|
18070
18335
|
coveredBy: mutant.coveredBy,
|
|
18071
18336
|
static: mutant.static
|
|
18072
18337
|
});
|
|
18338
|
+
const isNoCoveragePlan = (plan) => plan.runOptions.testFilter !== void 0 && plan.runOptions.testFilter.length === 0;
|
|
18073
18339
|
const inPlannedOrder = ({ planned, results }) => {
|
|
18074
18340
|
const rankById = Object.fromEntries(planned.map((mutant, index) => [mutant.id, index]));
|
|
18075
18341
|
return Arr.sortWith(results, (result) => rankById[result.id] ?? planned.length, Order.Number);
|
|
@@ -18107,11 +18373,14 @@ const reportingInputOf = (input) => ({
|
|
|
18107
18373
|
options: input.prev.options,
|
|
18108
18374
|
project: input.prev.project,
|
|
18109
18375
|
testCoverage: input.prev.testCoverage,
|
|
18376
|
+
timeOverheadMs: Duration.toMillis(input.prev.timeOverhead),
|
|
18110
18377
|
runId: input.env.runId,
|
|
18111
18378
|
resolvedMode: input.env.resolvedMode,
|
|
18112
18379
|
basePath: input.env.basePath,
|
|
18113
18380
|
reporterStage: input.prev.reporterStage,
|
|
18114
|
-
formatRegistry: input.prev.formatRegistry
|
|
18381
|
+
formatRegistry: input.prev.formatRegistry,
|
|
18382
|
+
concurrency: input.prev.concurrency.testRunners + input.prev.concurrency.checkers,
|
|
18383
|
+
runStartedAt: input.env.runStartedAt
|
|
18115
18384
|
});
|
|
18116
18385
|
const preparedStreamableOf = Effect$1.fnUntraced(function* (context, result) {
|
|
18117
18386
|
return yield* Option$1.match(Option$1.filter(Option$1.some(result.status), isMutantStatus), {
|
|
@@ -18365,10 +18634,11 @@ const coveredByField = (coveredBy) => Option$1.match(Option$1.fromUndefinedOr(co
|
|
|
18365
18634
|
onNone: () => ({}),
|
|
18366
18635
|
onSome: (present) => ({ coveredBy: [...present] })
|
|
18367
18636
|
});
|
|
18368
|
-
const testFilterField = (testFilter) => Option$1.match(Option$1.
|
|
18637
|
+
const testFilterField = (testFilter) => Option$1.match(Option$1.fromUndefinedOr(testFilter), {
|
|
18369
18638
|
onNone: () => ({}),
|
|
18370
18639
|
onSome: (present) => ({ testFilter: [...present] })
|
|
18371
18640
|
});
|
|
18641
|
+
const nonEmptyTestFilterOf = (tests) => Option$1.getOrUndefined(Option$1.filter(Option$1.fromUndefinedOr(tests), (present) => present.length > 0));
|
|
18372
18642
|
const staticCoverageCountOf = (staticCoverage, mutantId) => Option$1.getOrElse(Option$1.flatMap(Option$1.fromNullishOr(staticCoverage), (countsByMutantId) => Record$1.get(countsByMutantId, mutantId)), () => 0);
|
|
18373
18643
|
const hasCoverageForPlan = (staticCoverage) => Option$1.isSome(Option$1.fromUndefinedOr(staticCoverage));
|
|
18374
18644
|
const mutantIsStatic = (command, mutantId) => staticCoverageCountOf(command.staticCoverage, mutantId) > 0;
|
|
@@ -18454,10 +18724,13 @@ const orderedTestsOf = (command, mutantId, tests) => {
|
|
|
18454
18724
|
onSome: (present) => [present, ...rest]
|
|
18455
18725
|
});
|
|
18456
18726
|
};
|
|
18457
|
-
const runWithCoveredTests = (mutant, command, isStatic, tests, coveredBy) => toRunPlan(mutant, command, calculateTotalTimeForIds(tests, command.testTimeById), orderedTestsOf(command, mutant.id, tests), isStatic, coveredBy);
|
|
18727
|
+
const runWithCoveredTests = (mutant, command, isStatic, tests, coveredBy) => toRunPlan(mutant, command, calculateTotalTimeForIds(tests, command.testTimeById), nonEmptyTestFilterOf(orderedTestsOf(command, mutant.id, tests)), isStatic, coveredBy);
|
|
18728
|
+
const NO_COVERAGE_NET_TIME_MS = 0;
|
|
18729
|
+
const NO_COVERAGE_TEST_FILTER = [];
|
|
18730
|
+
const toNoCoverageRunPlan = (mutant, command, isStatic, coveredBy) => toRunPlan(mutant, command, NO_COVERAGE_NET_TIME_MS, NO_COVERAGE_TEST_FILTER, isStatic, coveredBy);
|
|
18458
18731
|
const planForUncoveredStatic = (mutant, command, isStatic, coveredBy) => Boolean$1$1.match(command.options.ignoreStatic, {
|
|
18459
18732
|
onTrue: () => Result.succeed(toEarlyResultPlan(mutant, isStatic, "Ignored", IGNORED_STATIC_MUTANT_REASON, coveredBy)),
|
|
18460
|
-
onFalse: () => toRunPlan(mutant, command, command.timeSpentAllTests, command.globalTestFilter, isStatic, coveredBy)
|
|
18733
|
+
onFalse: () => toRunPlan(mutant, command, command.timeSpentAllTests, nonEmptyTestFilterOf(command.globalTestFilter), isStatic, coveredBy)
|
|
18461
18734
|
});
|
|
18462
18735
|
const planForStaticallyCovered = (mutant, command, isStatic) => {
|
|
18463
18736
|
const tests = Option$1.getOrElse(Record$1.get(command.testsByMutantId, mutant.id), () => []);
|
|
@@ -18486,10 +18759,10 @@ const decidePlanForMutant = (mutant, command) => {
|
|
|
18486
18759
|
return Option$1.match(Option$1.fromUndefinedOr(mutant.status), {
|
|
18487
18760
|
onSome: (status) => Result.succeed(toEarlyResultPlan(mutant, isStatic, status, mutant.statusReason, coveredByOfMutant(mutant))),
|
|
18488
18761
|
onNone: () => Boolean$1$1.match(isPerTestUncoveredNonStatic(command, mutant, isStatic), {
|
|
18489
|
-
onTrue: () =>
|
|
18762
|
+
onTrue: () => toNoCoverageRunPlan(mutant, command, isStatic, coveringTestIdsOf(command, mutant.id)),
|
|
18490
18763
|
onFalse: () => Boolean$1$1.match(hasCoverageForPlan(command.staticCoverage), {
|
|
18491
18764
|
onTrue: () => planForStaticallyCovered(mutant, command, isStatic),
|
|
18492
|
-
onFalse: () => toRunPlan(mutant, command, command.timeSpentAllTests, command.globalTestFilter, void 0, void 0)
|
|
18765
|
+
onFalse: () => toRunPlan(mutant, command, command.timeSpentAllTests, nonEmptyTestFilterOf(command.globalTestFilter), void 0, void 0)
|
|
18493
18766
|
})
|
|
18494
18767
|
})
|
|
18495
18768
|
});
|
|
@@ -18781,7 +19054,10 @@ const planMutationTest = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationTestPlan
|
|
|
18781
19054
|
}))
|
|
18782
19055
|
})).pipe(Effect$1.ignoreCause);
|
|
18783
19056
|
const progressQueue = yield* RunEvents;
|
|
18784
|
-
yield* Queue.offer(progressQueue, RunEvent_exports.PlanKnown.make({
|
|
19057
|
+
yield* Queue.offer(progressQueue, RunEvent_exports.PlanKnown.make({
|
|
19058
|
+
total: plansForReporter.length + earlyResults.length,
|
|
19059
|
+
shardPlan: null
|
|
19060
|
+
}));
|
|
18785
19061
|
return {
|
|
18786
19062
|
runPlans: sortedPlans,
|
|
18787
19063
|
earlyResults,
|
|
@@ -18804,8 +19080,10 @@ const testRunnerWorkerSpawnOf = (loaded, configured) => Effect$1.mapError(Effect
|
|
|
18804
19080
|
cause: PluginNotFoundError.make({ descriptor: missing.descriptor })
|
|
18805
19081
|
}));
|
|
18806
19082
|
const acquire = Effect$1.fnUntraced(function* (spec) {
|
|
18807
|
-
|
|
18808
|
-
|
|
19083
|
+
const reports = yield* WorkerReports;
|
|
19084
|
+
const acquireOne = Effect$1.gen(function* () {
|
|
19085
|
+
const startedAt = yield* Clock.currentTimeMillis;
|
|
19086
|
+
const runner = yield* buildTestRunner({
|
|
18809
19087
|
options: spec.options,
|
|
18810
19088
|
fileDescriptions: spec.fileDescriptions,
|
|
18811
19089
|
sandboxWorkingDirectory: spec.sandboxWorkingDirectory,
|
|
@@ -18818,7 +19096,12 @@ const acquire = Effect$1.fnUntraced(function* (spec) {
|
|
|
18818
19096
|
sandboxWorkingDirectory: spec.sandboxWorkingDirectory,
|
|
18819
19097
|
workerEntrypoint: resolved.entrypoint,
|
|
18820
19098
|
idGenerator: spec.idGenerator
|
|
18821
|
-
})))))
|
|
19099
|
+
})))));
|
|
19100
|
+
yield* reports.report("testRunner", (yield* Clock.currentTimeMillis) - startedAt);
|
|
19101
|
+
return runner;
|
|
19102
|
+
});
|
|
19103
|
+
return yield* Pool.makeWithTTL({
|
|
19104
|
+
acquire: acquireOne,
|
|
18822
19105
|
min: spec.min,
|
|
18823
19106
|
max: spec.max,
|
|
18824
19107
|
timeToLive: IDLE_TIME_TO_LIVE
|
|
@@ -18831,6 +19114,9 @@ const TestRunnerPools = Blueprint.make()(TypeId).steps({
|
|
|
18831
19114
|
const scoped = (spec) => TestRunnerPools.of(spec).scoped;
|
|
18832
19115
|
//#endregion
|
|
18833
19116
|
//#region src/run/mutation-test.cell.ts
|
|
19117
|
+
const TCE_EQUIVALENT_TO_ORIGINAL_REASON = "equivalent-to-original: tce";
|
|
19118
|
+
const TCE_DUPLICATE_AT_SITE_REASON = "duplicate-at-site: tce";
|
|
19119
|
+
const countIgnoredByReason = (results, reason) => results.filter((result) => result.status === "Ignored" && result.statusReason === reason).length;
|
|
18834
19120
|
const writeMutationTestNoTests = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationTestNoTests.name)(function* () {
|
|
18835
19121
|
const env = yield* RunEnvironment;
|
|
18836
19122
|
const now = yield* Clock.currentTimeMillis;
|
|
@@ -18934,22 +19220,26 @@ const proceedPipeline = Effect$1.fnUntraced(function* (raw) {
|
|
|
18934
19220
|
});
|
|
18935
19221
|
const runResults = yield* Effect$1.scoped(Effect$1.gen(function* () {
|
|
18936
19222
|
const checkpoint = yield* makeCheckpointWriter(context, settledResults);
|
|
19223
|
+
const settleReported = (reported) => Effect$1.gen(function* () {
|
|
19224
|
+
yield* announceSettledMutant(context, reported);
|
|
19225
|
+
yield* checkpoint.record(reported);
|
|
19226
|
+
return reported;
|
|
19227
|
+
});
|
|
18937
19228
|
return yield* withPhaseSpan(SpanTaxonomy_exports.Spans.mutationTestBatch, {
|
|
18938
19229
|
total: plan.plannedTotal,
|
|
18939
19230
|
testRunners: prev.concurrency.testRunners
|
|
18940
19231
|
}, () => runCheckedPlans(checkedPlans, {
|
|
18941
|
-
settleFailure: (mutantPlan, result) => Effect$1.
|
|
18942
|
-
|
|
18943
|
-
|
|
18944
|
-
|
|
18945
|
-
|
|
19232
|
+
settleFailure: (mutantPlan, result) => reporting.reportCheckFailure(toReportedMutant(mutantPlan.mutant), result).pipe(Effect$1.flatMap(settleReported)),
|
|
19233
|
+
settleIgnored: (mutantPlan, result) => reporting.reportIgnored(toReportedMutant(mutantPlan.mutant), result).pipe(Effect$1.flatMap(settleReported)),
|
|
19234
|
+
runPlan: (runPlan) => Option$1.match(Option$1.liftPredicate(runPlan, isNoCoveragePlan), {
|
|
19235
|
+
onNone: () => Effect$1.scoped(mutantRunCell.run({
|
|
19236
|
+
context,
|
|
19237
|
+
testRunnerPool,
|
|
19238
|
+
checkpoint,
|
|
19239
|
+
plan: runPlan
|
|
19240
|
+
})),
|
|
19241
|
+
onSome: (noCoverageRunPlan) => reporting.reportNoCoverage(toReportedMutant(noCoverageRunPlan.mutant)).pipe(Effect$1.flatMap(settleReported))
|
|
18946
19242
|
}),
|
|
18947
|
-
runPlan: (runPlan) => Effect$1.scoped(mutantRunCell.run({
|
|
18948
|
-
context,
|
|
18949
|
-
testRunnerPool,
|
|
18950
|
-
checkpoint,
|
|
18951
|
-
plan: runPlan
|
|
18952
|
-
})),
|
|
18953
19243
|
concurrency: testRunnerCapacity
|
|
18954
19244
|
}).pipe(Stream.runFold(() => [], (acc, result) => {
|
|
18955
19245
|
acc.push(result);
|
|
@@ -18965,6 +19255,10 @@ const proceedPipeline = Effect$1.fnUntraced(function* (raw) {
|
|
|
18965
19255
|
requested: requestedIdsOf(prev.options),
|
|
18966
19256
|
results: allResults
|
|
18967
19257
|
}), (detail) => Queue.offer(progressQueue, detail), { discard: true });
|
|
19258
|
+
yield* Queue.offer(progressQueue, RunEvent_exports.TceReported.make({
|
|
19259
|
+
equivalentToOriginal: countIgnoredByReason(allResults, TCE_EQUIVALENT_TO_ORIGINAL_REASON),
|
|
19260
|
+
duplicateAtSite: countIgnoredByReason(allResults, TCE_DUPLICATE_AT_SITE_REASON)
|
|
19261
|
+
}));
|
|
18968
19262
|
const outcomeResult = yield* reporting.reportAll({
|
|
18969
19263
|
...reportingInputOf({
|
|
18970
19264
|
prev,
|
|
@@ -20056,11 +20350,11 @@ const prepareCell = Sandwich.named(SpanTaxonomy_exports.Spans.prepare.name)(read
|
|
|
20056
20350
|
//#endregion
|
|
20057
20351
|
//#region src/run/run-stages.cell.ts
|
|
20058
20352
|
const configReadReasonOf = (cause) => Match$1.value(cause).pipe(Match$1.tag("ConfigError", (refused) => refused.message), Match$1.orElse(() => "Failed to read config"));
|
|
20059
|
-
const mutationTestCell = Cell.andThen(Cell.andThen(Cell.andThen(Cell.mapError(loadConfigCell, (cause) => StageError.make({
|
|
20353
|
+
const mutationTestCell = Cell.andThen(Cell.andThen(Cell.andThen(Cell.andThen(Cell.mapError(loadConfigCell, (cause) => StageError.make({
|
|
20060
20354
|
stage: "prepare",
|
|
20061
20355
|
reason: configReadReasonOf(cause),
|
|
20062
20356
|
cause
|
|
20063
|
-
})), Cell.mapError(readProjectCell, (cause) => StageError.make({
|
|
20357
|
+
})), (loaded) => refuseLocalMutationCell(loaded)), Cell.mapError(readProjectCell, (cause) => StageError.make({
|
|
20064
20358
|
stage: "prepare",
|
|
20065
20359
|
reason: "Failed to read project",
|
|
20066
20360
|
cause
|
|
@@ -20203,7 +20497,7 @@ S.Struct({
|
|
|
20203
20497
|
mode: OutputMode_exports.OutputMode,
|
|
20204
20498
|
signal: OutputMode_exports.ModeSignal
|
|
20205
20499
|
});
|
|
20206
|
-
const nextFramingState = (state, event) => Match$1.value(event).pipe(Match$1.tag("verdict", "error", "help", () => FramingState.make({
|
|
20500
|
+
const nextFramingState = (state, event) => Match$1.value(event).pipe(Match$1.tag("verdict", "error", "help", "refused", () => FramingState.make({
|
|
20207
20501
|
mode: state.mode,
|
|
20208
20502
|
signal: state.signal,
|
|
20209
20503
|
headerWritten: state.headerWritten,
|
|
@@ -20224,7 +20518,7 @@ const nextFramingState = (state, event) => Match$1.value(event).pipe(Match$1.tag
|
|
|
20224
20518
|
terminalSeen: state.terminalSeen,
|
|
20225
20519
|
completed: e.completed,
|
|
20226
20520
|
total: e.total
|
|
20227
|
-
})), Match$1.tag("stream", () => state), Match$1.tag("phase", () => state), Match$1.tag("tick", () => state), Match$1.tag("plugins", () => state), Match$1.tag("formats", () => state), Match$1.tag("skipped", () => state), Match$1.tag("reuse", "mutant-detail", "feedback", () => state), Match$1.exhaustive);
|
|
20521
|
+
})), Match$1.tag("stream", () => state), Match$1.tag("phase", () => state), Match$1.tag("tick", () => state), Match$1.tag("worker", () => state), Match$1.tag("plugins", () => state), Match$1.tag("formats", () => state), Match$1.tag("skipped", () => state), Match$1.tag("reuse", "tce", "mutant-detail", "feedback", () => state), Match$1.exhaustive);
|
|
20228
20522
|
const noteState = (state, event) => nextFramingState(state, event);
|
|
20229
20523
|
const formatScore = (score) => Option$1.match(Option$1.fromNullishOr(score), {
|
|
20230
20524
|
onNone: () => "n/a",
|
|
@@ -20234,7 +20528,7 @@ const formatTotal = (total) => Option$1.match(Option$1.fromNullishOr(total), {
|
|
|
20234
20528
|
onNone: () => "?",
|
|
20235
20529
|
onSome: (val) => String(val)
|
|
20236
20530
|
});
|
|
20237
|
-
const formatStderrEvent = (event) => Match$1.value(event).pipe(Match$1.tag("plan", (e) => `plan ${e.total} mutants`), Match$1.tag("phase", (e) => `phase ${e.phase}`), Match$1.tag("tick", (e) => `${e.completed}/${formatTotal(e.total)} elapsed ${e.elapsedMs}ms`), Match$1.tag("verdict", (e) => `score ${formatScore(e.score)} killed ${e.counts.killed} survived ${e.counts.survived}`), Match$1.tag("error", (e) => `error ${e.error}`), Match$1.tag("stream", () => null), Match$1.tag("mutantTested", () => null), Match$1.tag("help", () => null), Match$1.tag("plugins", () => null), Match$1.tag("formats", () => null), Match$1.tag("skipped", () => null), Match$1.tag("reuse", "mutant-detail", "feedback", () => null), Match$1.exhaustive);
|
|
20531
|
+
const formatStderrEvent = (event) => Match$1.value(event).pipe(Match$1.tag("plan", (e) => `plan ${e.total} mutants`), Match$1.tag("phase", (e) => `phase ${e.phase}`), Match$1.tag("tick", (e) => `${e.completed}/${formatTotal(e.total)} elapsed ${e.elapsedMs}ms`), Match$1.tag("verdict", (e) => `score ${formatScore(e.score)} killed ${e.counts.killed} survived ${e.counts.survived}`), Match$1.tag("error", (e) => `error ${e.error}`), Match$1.tag("refused", (e) => `refused ${e.rule}`), Match$1.tag("stream", () => null), Match$1.tag("mutantTested", () => null), Match$1.tag("worker", () => null), Match$1.tag("help", () => null), Match$1.tag("plugins", () => null), Match$1.tag("formats", () => null), Match$1.tag("skipped", () => null), Match$1.tag("reuse", "tce", "mutant-detail", "feedback", () => null), Match$1.exhaustive);
|
|
20238
20532
|
const stderrLineFor = (state, event) => Boolean$1$1.match(Boolean$1$1.and(state.mode === "human", !state.terminalSeen), {
|
|
20239
20533
|
onTrue: () => formatStderrEvent(event),
|
|
20240
20534
|
onFalse: () => null
|
|
@@ -20398,16 +20692,17 @@ const CONFIG_CODE = 2;
|
|
|
20398
20692
|
const UNKNOWN_FAILURE = "Unknown failure";
|
|
20399
20693
|
const SIGNAL_REMEDIATION = "the run was interrupted by a signal; re-run it to continue";
|
|
20400
20694
|
const PARSE_REMEDIATION = "re-run with --help to see the full usage";
|
|
20695
|
+
const REFUSAL_REMEDIATION = "run mutation testing on main CI (GitHub Actions)";
|
|
20401
20696
|
const DEFAULT_REMEDIATION = "see --reportFile or the verdict envelope on stdout";
|
|
20402
|
-
const exitCodeOf = (outcome) => Match$1.value(outcome).pipe(Match$1.tag("RunOk", () => 0), Match$1.tag("RunInterrupted", (error) => error.code), Match$1.tag("RunParseFailed", () => CONFIG_CODE), Match$1.tag("RunSurvivorsRejected", () => CONFIG_CODE), Match$1.tag("RunConfigFailed", () => CONFIG_CODE), Match$1.tag("RunFailed", (failed) => failed.code), Match$1.exhaustive);
|
|
20697
|
+
const exitCodeOf = (outcome) => Match$1.value(outcome).pipe(Match$1.tag("RunOk", () => 0), Match$1.tag("RunInterrupted", (error) => error.code), Match$1.tag("RunParseFailed", () => CONFIG_CODE), Match$1.tag("RunSurvivorsRejected", () => CONFIG_CODE), Match$1.tag("RunConfigFailed", () => CONFIG_CODE), Match$1.tag("RunRefused", () => CONFIG_CODE), Match$1.tag("RunFailed", (failed) => failed.code), Match$1.exhaustive);
|
|
20403
20698
|
const nonEmptyText = Option$1.liftPredicate(S.is(S.NonEmptyString));
|
|
20404
20699
|
const capturedOrUnknown = (captured) => Option$1.getOrElse(nonEmptyText(captured), () => UNKNOWN_FAILURE);
|
|
20405
20700
|
const capturedThenRecorded = (captured, recorded) => Option$1.getOrElse(nonEmptyText(captured), () => Option$1.getOrElse(Option$1.fromNullishOr(recorded), () => UNKNOWN_FAILURE));
|
|
20406
|
-
const failureTextOf = (error, captured) => Match$1.value(error).pipe(Match$1.tag("RunParseFailed", (failed) => Option$1.getOrElse(Option$1.map(Option$1.fromNullishOr(failed.unrecognized), (value) => `Received unknown argument: '${value}'`), () => capturedOrUnknown(captured))), Match$1.tag("RunSurvivorsRejected", (failed) => Option$1.getOrElse(Option$1.fromNullishOr(failed.diagnostic), () => UNKNOWN_FAILURE)), Match$1.tag("RunInterrupted", () => capturedOrUnknown(captured)), Match$1.tag("RunConfigFailed", (failed) => capturedThenRecorded(captured, failed.detail)), Match$1.tag("RunFailed", (failed) => capturedThenRecorded(captured, failed.diagnostic)), Match$1.exhaustive);
|
|
20701
|
+
const failureTextOf = (error, captured) => Match$1.value(error).pipe(Match$1.tag("RunParseFailed", (failed) => Option$1.getOrElse(Option$1.map(Option$1.fromNullishOr(failed.unrecognized), (value) => `Received unknown argument: '${value}'`), () => capturedOrUnknown(captured))), Match$1.tag("RunSurvivorsRejected", (failed) => Option$1.getOrElse(Option$1.fromNullishOr(failed.diagnostic), () => UNKNOWN_FAILURE)), Match$1.tag("RunInterrupted", () => capturedOrUnknown(captured)), Match$1.tag("RunConfigFailed", (failed) => capturedThenRecorded(captured, failed.detail)), Match$1.tag("RunRefused", (failed) => failed.message), Match$1.tag("RunFailed", (failed) => capturedThenRecorded(captured, failed.diagnostic)), Match$1.exhaustive);
|
|
20407
20702
|
const remediationTextOf = (error) => Match$1.value(error).pipe(Match$1.tag("RunInterrupted", () => SIGNAL_REMEDIATION), Match$1.tag("RunParseFailed", () => PARSE_REMEDIATION), Match$1.tag("RunSurvivorsRejected", (failed) => Option$1.getOrElse(Option$1.fromNullishOr(failed.diagnostic), () => DEFAULT_REMEDIATION)), Match$1.tag("RunConfigFailed", (failed) => Option$1.match(Option$1.fromNullishOr(failed.detail), {
|
|
20408
20703
|
onSome: (detail) => `check the config file: ${detail}`,
|
|
20409
20704
|
onNone: () => "check the config file"
|
|
20410
|
-
})), Match$1.tag("RunFailed", () => DEFAULT_REMEDIATION), Match$1.exhaustive);
|
|
20705
|
+
})), Match$1.tag("RunRefused", () => REFUSAL_REMEDIATION), Match$1.tag("RunFailed", () => DEFAULT_REMEDIATION), Match$1.exhaustive);
|
|
20411
20706
|
const errorEnvelopeFromOutcome = (input) => ErrorEnvelope.make({
|
|
20412
20707
|
schemaVersion: RunEvent_exports.StreamSchemaVersion.literal,
|
|
20413
20708
|
code: exitCodeOf(input.error),
|
|
@@ -20504,22 +20799,33 @@ const emitNullScoreVerdict = (params) => {
|
|
|
20504
20799
|
version: StrykerPackage.version
|
|
20505
20800
|
}
|
|
20506
20801
|
};
|
|
20507
|
-
|
|
20508
|
-
|
|
20509
|
-
|
|
20510
|
-
|
|
20511
|
-
|
|
20512
|
-
|
|
20513
|
-
|
|
20514
|
-
|
|
20515
|
-
|
|
20516
|
-
|
|
20517
|
-
|
|
20518
|
-
|
|
20519
|
-
|
|
20520
|
-
|
|
20521
|
-
|
|
20522
|
-
|
|
20802
|
+
return Effect$1.gen(function* () {
|
|
20803
|
+
const now = yield* Clock.currentTimeMillis;
|
|
20804
|
+
const envelope = buildVerdictEnvelope({
|
|
20805
|
+
...report,
|
|
20806
|
+
budget: {
|
|
20807
|
+
predictedSeconds: 0,
|
|
20808
|
+
actualSeconds: (now - stream.startedAt) / 1e3
|
|
20809
|
+
}
|
|
20810
|
+
}, mode.mode, mode.signal, stream.runId, basePath, pathService, Option$1.none(), null);
|
|
20811
|
+
yield* Queue.offer(stream.queue, RunEvent_exports.VerdictReached.make({
|
|
20812
|
+
schemaVersion: envelope.schemaVersion,
|
|
20813
|
+
runId: envelope.runId,
|
|
20814
|
+
mode: envelope.mode,
|
|
20815
|
+
signal: envelope.signal,
|
|
20816
|
+
score: envelope.score,
|
|
20817
|
+
thresholds: envelope.thresholds,
|
|
20818
|
+
reportFile: envelope.reportFile,
|
|
20819
|
+
counts: envelope.counts,
|
|
20820
|
+
mutants: envelope.mutants,
|
|
20821
|
+
scope: envelope.scope,
|
|
20822
|
+
mutantSetPolicy: envelope.mutantSetPolicy,
|
|
20823
|
+
incrementalMode: envelope.incrementalMode,
|
|
20824
|
+
phaseDurations: envelope.phaseDurations,
|
|
20825
|
+
static: envelope.static,
|
|
20826
|
+
budget: envelope.budget
|
|
20827
|
+
}));
|
|
20828
|
+
});
|
|
20523
20829
|
};
|
|
20524
20830
|
const offerFailureEnvelope = (stream, failed, captured) => {
|
|
20525
20831
|
const envelope = errorEnvelopeFromOutcome({
|
|
@@ -20534,6 +20840,11 @@ const offerFailureEnvelope = (stream, failed, captured) => {
|
|
|
20534
20840
|
reason: null
|
|
20535
20841
|
}));
|
|
20536
20842
|
};
|
|
20843
|
+
const offerRefusedEnvelope = (stream, refused) => Queue.offer(stream.queue, RunEvent_exports.Refused.make({
|
|
20844
|
+
schemaVersion: RunEvent_exports.StreamSchemaVersion.literal,
|
|
20845
|
+
rule: refused.rule,
|
|
20846
|
+
message: refused.message
|
|
20847
|
+
}));
|
|
20537
20848
|
const emitHelpEnvelope = (stream, help) => Queue.offer(stream.queue, RunEvent_exports.HelpRendered.make({
|
|
20538
20849
|
schemaVersion: RunEvent_exports.StreamSchemaVersion.literal,
|
|
20539
20850
|
code: 0,
|
|
@@ -20565,7 +20876,7 @@ const emitMachineModeOutput = Effect$1.fn(SpanTaxonomy_exports.Spans.runEventStr
|
|
|
20565
20876
|
onSuccess: (decision) => Match$1.value(decision).pipe(Match$1.tag("RunOk", (ok) => Option$1.match(helpPayload(ok, captured), {
|
|
20566
20877
|
onSome: (help) => emitHelpEnvelope(stream, help),
|
|
20567
20878
|
onNone: () => emitNullScoreVerdictWhenOpen(stream, mode, basePath, pathService)
|
|
20568
|
-
})), Match$1.tag("RunParseFailed", (failed) => offerFailureEnvelope(stream, failed, captured)), Match$1.tag("RunSurvivorsRejected", (failed) => offerFailureEnvelope(stream, failed, captured)), Match$1.tag("RunConfigFailed", (failed) => offerFailureEnvelope(stream, failed, captured)), Match$1.tag("RunFailed", (failed) => offerFailureEnvelope(stream, failed, captured)), Match$1.exhaustive),
|
|
20879
|
+
})), Match$1.tag("RunParseFailed", (failed) => offerFailureEnvelope(stream, failed, captured)), Match$1.tag("RunSurvivorsRejected", (failed) => offerFailureEnvelope(stream, failed, captured)), Match$1.tag("RunConfigFailed", (failed) => offerFailureEnvelope(stream, failed, captured)), Match$1.tag("RunRefused", (refused) => offerRefusedEnvelope(stream, refused)), Match$1.tag("RunFailed", (failed) => offerFailureEnvelope(stream, failed, captured)), Match$1.exhaustive),
|
|
20569
20880
|
onFailure: (failure) => offerFailureEnvelope(stream, failure, captured)
|
|
20570
20881
|
});
|
|
20571
20882
|
});
|