@systemfsoftware/stryker-js 15.0.1 → 16.0.1
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 +44 -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 +2113 -1233
- 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-DYuRm353.mjs} +556 -235
- package/package.json +9 -9
|
@@ -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: {}
|
|
@@ -2160,6 +2154,13 @@ const createDefaultOptions = S.decodeEffect(Options_exports.StrykerOptionsSchema
|
|
|
2160
2154
|
const defaultOptions = Effect$1.map(createDefaultOptions, (options) => deepFreeze(options));
|
|
2161
2155
|
//#endregion
|
|
2162
2156
|
//#region src/ConfigError.schema.ts
|
|
2157
|
+
const CAUSE_DEPTH = 4;
|
|
2158
|
+
const ownMessageOf = (value) => Option$1.filter(Option$1.map(Option$1.liftPredicate(value, Predicate$1.hasProperty("message")), (carrier) => String(carrier.message)), S.is(S.NonEmptyString));
|
|
2159
|
+
const causeMessagesOf = (value, depth) => depth === 0 ? [] : [...Option$1.toArray(ownMessageOf(value)), ...Option$1.match(Option$1.liftPredicate(value, Predicate$1.hasProperty("cause")), {
|
|
2160
|
+
onNone: () => [],
|
|
2161
|
+
onSome: (carrier) => causeMessagesOf(carrier.cause, depth - 1)
|
|
2162
|
+
})];
|
|
2163
|
+
const causeTextOf$1 = (cause) => Option$1.liftPredicate(causeMessagesOf(cause, CAUSE_DEPTH).join(": "), S.is(S.NonEmptyString));
|
|
2163
2164
|
var ConfigFileNotFoundError = class extends S.TaggedError()("ConfigFileNotFoundError", { file: S.String }) {
|
|
2164
2165
|
exitClass = "ConfigError";
|
|
2165
2166
|
get message() {
|
|
@@ -2181,7 +2182,10 @@ var ConfigFileUnreadableError = class extends S.TaggedError()("ConfigFileUnreada
|
|
|
2181
2182
|
}) {
|
|
2182
2183
|
exitClass = "ConfigError";
|
|
2183
2184
|
get message() {
|
|
2184
|
-
return
|
|
2185
|
+
return Option$1.match(causeTextOf$1(this.cause), {
|
|
2186
|
+
onNone: () => `Config file is unreadable: ${this.file}`,
|
|
2187
|
+
onSome: (cause) => `Config file is unreadable: ${this.file}: ${cause}`
|
|
2188
|
+
});
|
|
2185
2189
|
}
|
|
2186
2190
|
};
|
|
2187
2191
|
var ConfigFileInvalidError = class extends S.TaggedError()("ConfigFileInvalidError", {
|
|
@@ -10244,6 +10248,48 @@ const resolveConfig = Workflow.make({
|
|
|
10244
10248
|
})
|
|
10245
10249
|
});
|
|
10246
10250
|
//#endregion
|
|
10251
|
+
//#region src/atomic-write.cell.ts
|
|
10252
|
+
const writeFileAtomic = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReportingWriteAtomic.name)(function* (ports, file, content) {
|
|
10253
|
+
const directory = ports.path.dirname(file);
|
|
10254
|
+
yield* ports.fs.makeDirectory(directory, { recursive: true });
|
|
10255
|
+
const temp = yield* ports.fs.makeTempFile({
|
|
10256
|
+
directory,
|
|
10257
|
+
prefix: `${ports.path.basename(file)}.`,
|
|
10258
|
+
suffix: ".tmp"
|
|
10259
|
+
});
|
|
10260
|
+
yield* Effect$1.gen(function* () {
|
|
10261
|
+
yield* ports.fs.writeFileString(temp, content);
|
|
10262
|
+
yield* ports.fs.rename(temp, file);
|
|
10263
|
+
}).pipe(Effect$1.onExit((exit) => Exit.isSuccess(exit) ? Effect$1.void : ports.fs.remove(temp).pipe(Effect$1.ignore)));
|
|
10264
|
+
});
|
|
10265
|
+
//#endregion
|
|
10266
|
+
//#region src/mutant-cost.ts
|
|
10267
|
+
const executedTestBodyMsOf = (executedTests) => executedTests.reduce((total, test) => total + test.timeSpentMs, 0);
|
|
10268
|
+
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));
|
|
10269
|
+
const bodyTimeWithinWall = (elapsedMs, testBodyMs) => Math.min(testBodyMs, elapsedMs);
|
|
10270
|
+
const costTotalMsOf = (cost) => cost === void 0 ? void 0 : cost.fixedOverheadMs + cost.testBodyMs;
|
|
10271
|
+
const mutantCostOf = (input) => {
|
|
10272
|
+
const testBodyMs = bodyTimeWithinWall(input.elapsedMs, input.testBodyMs);
|
|
10273
|
+
return {
|
|
10274
|
+
fixedOverheadMs: input.elapsedMs - testBodyMs,
|
|
10275
|
+
testBodyMs,
|
|
10276
|
+
testsExecuted: input.testsExecuted,
|
|
10277
|
+
shared: input.shared
|
|
10278
|
+
};
|
|
10279
|
+
};
|
|
10280
|
+
//#endregion
|
|
10281
|
+
//#region src/budget.ts
|
|
10282
|
+
const MILLIS_PER_SECOND = 1e3;
|
|
10283
|
+
const costMsOf = (result) => costTotalMsOf(result.cost) ?? 0;
|
|
10284
|
+
const predictedSecondsOf = (results, concurrency) => {
|
|
10285
|
+
const lanes = concurrency > 0 ? concurrency : 1;
|
|
10286
|
+
return Arr.reduce(results, 0, (total, result) => total + costMsOf(result)) / lanes / MILLIS_PER_SECOND;
|
|
10287
|
+
};
|
|
10288
|
+
const budgetOf$1 = (input) => ({
|
|
10289
|
+
predictedSeconds: input.planPredictedSeconds ?? predictedSecondsOf(input.results, input.concurrency),
|
|
10290
|
+
actualSeconds: input.actualSeconds
|
|
10291
|
+
});
|
|
10292
|
+
//#endregion
|
|
10247
10293
|
//#region src/build-reproducers.workflow.ts
|
|
10248
10294
|
const CONTEXT_LINES = 3;
|
|
10249
10295
|
const maxOf$1 = (left, right) => Boolean$1$1.match(left < right, {
|
|
@@ -10315,7 +10361,7 @@ const fileNameOrder = Order.mapInput(Order.String, (reproducer) => reproducer.fi
|
|
|
10315
10361
|
const idOrder$1 = Order.mapInput(Order.String, (reproducer) => reproducer.id);
|
|
10316
10362
|
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
10363
|
const mutantsOf = (report) => Arr.flatMap(Object.values(report.files), (file) => file.mutants);
|
|
10318
|
-
const decide$
|
|
10364
|
+
const decide$24 = (command) => {
|
|
10319
10365
|
const mutants = mutantsOf(command.report);
|
|
10320
10366
|
return Boolean$1$1.match(mutants.length === 0, {
|
|
10321
10367
|
onTrue: () => NoMutantsToReproduce.make({}),
|
|
@@ -10326,7 +10372,7 @@ const buildReproducers = Workflow.make({
|
|
|
10326
10372
|
command: BuildReproducersCommand,
|
|
10327
10373
|
decision: BuildReproducersDecision,
|
|
10328
10374
|
error: S.Never,
|
|
10329
|
-
decide: (command) => Result.succeed(decide$
|
|
10375
|
+
decide: (command) => Result.succeed(decide$24(command))
|
|
10330
10376
|
});
|
|
10331
10377
|
//#endregion
|
|
10332
10378
|
//#region src/checkpoint-mutants.workflow.ts
|
|
@@ -10350,7 +10396,7 @@ var CheckpointMutantsCommand = class extends S.TaggedClass()("CheckpointMutantsC
|
|
|
10350
10396
|
};
|
|
10351
10397
|
const settledByIdOf = (settled) => HashMap.fromIterable(settled.map((row) => [row.mutant.id, row]));
|
|
10352
10398
|
const rowOf = (mutant, settledById) => Option$1.getOrElse(HashMap.get(settledById, mutant.id), () => CheckpointPendingMutant.make({ mutant }));
|
|
10353
|
-
const decide$
|
|
10399
|
+
const decide$23 = (command) => {
|
|
10354
10400
|
const settledById = settledByIdOf(command.settled);
|
|
10355
10401
|
return Result.succeed(command.plannedMutants.map((mutant) => rowOf(mutant, settledById)));
|
|
10356
10402
|
};
|
|
@@ -10358,7 +10404,7 @@ const checkpointMutants = Workflow.make({
|
|
|
10358
10404
|
command: CheckpointMutantsCommand,
|
|
10359
10405
|
decision: S.Array(CheckpointMutantRow),
|
|
10360
10406
|
error: S.Never,
|
|
10361
|
-
decide: decide$
|
|
10407
|
+
decide: decide$23
|
|
10362
10408
|
});
|
|
10363
10409
|
//#endregion
|
|
10364
10410
|
//#region src/classify-exit.workflow.ts
|
|
@@ -10407,7 +10453,7 @@ const verdictExitClass = (score, breakingThreshold) => Match$1.valueTags(score,
|
|
|
10407
10453
|
onSome: (threshold) => Match$1.value(percentage < threshold).pipe(Match$1.when(true, () => "VerdictFail"), Match$1.when(false, () => null), Match$1.exhaustive)
|
|
10408
10454
|
})
|
|
10409
10455
|
});
|
|
10410
|
-
const decide$
|
|
10456
|
+
const decide$22 = (command) => Option$1.match(Option$1.fromNullishOr(verdictExitClass(command.score, command.breakingThreshold)), {
|
|
10411
10457
|
onNone: () => Option$1.match(precedenceOf(command.pending), {
|
|
10412
10458
|
onNone: () => Result.succeed(ExitPassed.make({})),
|
|
10413
10459
|
onSome: (exitClass) => Result.succeed(decisionOf$3(exitClass))
|
|
@@ -10418,7 +10464,7 @@ const classifyExit = Workflow.make({
|
|
|
10418
10464
|
command: ClassifyExitCommand,
|
|
10419
10465
|
decision: ClassifyExitDecision,
|
|
10420
10466
|
error: S.Never,
|
|
10421
|
-
decide: decide$
|
|
10467
|
+
decide: decide$22
|
|
10422
10468
|
});
|
|
10423
10469
|
//#endregion
|
|
10424
10470
|
//#region src/IncrementalDiff.schema.ts
|
|
@@ -10480,6 +10526,61 @@ const ReuseReportSchema = S.Struct({
|
|
|
10480
10526
|
testFiles: S.optional(ReuseTestFilesSchema)
|
|
10481
10527
|
});
|
|
10482
10528
|
//#endregion
|
|
10529
|
+
//#region src/MutantCost.schema.ts
|
|
10530
|
+
const MutantCost = S.Struct({
|
|
10531
|
+
predictedMs: S.Finite,
|
|
10532
|
+
actualMs: S.NullOr(S.Finite),
|
|
10533
|
+
coveringTests: S.Int
|
|
10534
|
+
});
|
|
10535
|
+
const MutantCosts = S.Record(Mutant_exports.MutantId, MutantCost);
|
|
10536
|
+
const MutantCostSubject = S.Struct({
|
|
10537
|
+
id: Mutant_exports.MutantId,
|
|
10538
|
+
static: S.optional(S.Boolean)
|
|
10539
|
+
});
|
|
10540
|
+
S.Struct({
|
|
10541
|
+
subject: MutantCostSubject,
|
|
10542
|
+
staticCoverage: S.optional(S.Record(S.String, Report_exports.NonNegativeFinite)),
|
|
10543
|
+
allTestTimesMs: S.Array(Report_exports.NonNegativeFinite),
|
|
10544
|
+
coveringTestTimesMs: S.Array(Report_exports.NonNegativeFinite),
|
|
10545
|
+
executedActualMs: S.optional(Report_exports.NonNegativeFinite),
|
|
10546
|
+
priorActualMs: S.optional(Report_exports.NonNegativeFinite),
|
|
10547
|
+
fixedOverheadMs: Report_exports.NonNegativeFinite
|
|
10548
|
+
});
|
|
10549
|
+
S.Struct({
|
|
10550
|
+
subjects: S.Array(MutantCostSubject),
|
|
10551
|
+
staticCoverage: S.optional(S.Record(S.String, Report_exports.NonNegativeFinite)),
|
|
10552
|
+
allTestTimesMs: S.Array(Report_exports.NonNegativeFinite),
|
|
10553
|
+
coveringTestTimesMsByMutantId: S.Record(S.String, S.Array(Report_exports.NonNegativeFinite)),
|
|
10554
|
+
executedActualMsByMutantId: S.Record(S.String, Report_exports.NonNegativeFinite),
|
|
10555
|
+
priorActualMsByMutantId: S.Record(S.String, Report_exports.NonNegativeFinite),
|
|
10556
|
+
fixedOverheadMs: Report_exports.NonNegativeFinite
|
|
10557
|
+
});
|
|
10558
|
+
//#endregion
|
|
10559
|
+
//#region src/mutant-cost-model.ts
|
|
10560
|
+
const staticHitCountOf = (staticCoverage, id) => Option$1.getOrElse(Option$1.flatMap(Option$1.fromNullishOr(staticCoverage), (coverage) => Record$1.get(coverage, id)), () => 0);
|
|
10561
|
+
const hasStaticHit = (staticCoverage, id) => staticCoverage === void 0 || staticHitCountOf(staticCoverage, id) > 0;
|
|
10562
|
+
const runsWholeSuite$1 = (input) => input.subject.static === true || hasStaticHit(input.staticCoverage, input.subject.id);
|
|
10563
|
+
const coveringTimesOf = (input) => runsWholeSuite$1(input) ? input.allTestTimesMs : input.coveringTestTimesMs;
|
|
10564
|
+
const actualMsOf = (input) => Option$1.getOrElse(Option$1.firstSomeOf([Option$1.fromNullishOr(input.executedActualMs), Option$1.fromNullishOr(input.priorActualMs)]), () => null);
|
|
10565
|
+
const mutantCostOfCase = (input) => {
|
|
10566
|
+
const coveringTimes = coveringTimesOf(input);
|
|
10567
|
+
return {
|
|
10568
|
+
predictedMs: input.fixedOverheadMs + coveringTimes.reduce((total, time) => total + time, 0),
|
|
10569
|
+
actualMs: actualMsOf(input),
|
|
10570
|
+
coveringTests: coveringTimes.length
|
|
10571
|
+
};
|
|
10572
|
+
};
|
|
10573
|
+
const caseOfSubject = (input, subject) => ({
|
|
10574
|
+
subject,
|
|
10575
|
+
staticCoverage: input.staticCoverage,
|
|
10576
|
+
allTestTimesMs: input.allTestTimesMs,
|
|
10577
|
+
coveringTestTimesMs: Option$1.getOrElse(Record$1.get(input.coveringTestTimesMsByMutantId, subject.id), () => []),
|
|
10578
|
+
executedActualMs: Option$1.getOrUndefined(Record$1.get(input.executedActualMsByMutantId, subject.id)),
|
|
10579
|
+
priorActualMs: Option$1.getOrUndefined(Record$1.get(input.priorActualMsByMutantId, subject.id)),
|
|
10580
|
+
fixedOverheadMs: input.fixedOverheadMs
|
|
10581
|
+
});
|
|
10582
|
+
const mutantCostsOf = (input) => Object.fromEntries(input.subjects.map((subject) => [subject.id, mutantCostOfCase(caseOfSubject(input, subject))]));
|
|
10583
|
+
//#endregion
|
|
10483
10584
|
//#region src/mutation-reporting.schema.ts
|
|
10484
10585
|
var ManifestUnreadable = class extends Schema.TaggedError()("ManifestUnreadable", {
|
|
10485
10586
|
specifier: Schema.String,
|
|
@@ -11036,21 +11137,6 @@ S.Literal("mutation-part.json");
|
|
|
11036
11137
|
S.Literal("mutation-stream.jsonl");
|
|
11037
11138
|
const ReportFileNames = S.Record(S.String, Mutant_exports.CanonicalFileName);
|
|
11038
11139
|
//#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
11140
|
//#region src/reporting/static-verdict.ts
|
|
11055
11141
|
const costOrZero = (cost) => Option$1.getOrElse(Option$1.fromUndefinedOr(costTotalMsOf(cost)), () => 0);
|
|
11056
11142
|
const staticVerdictOf = (results) => {
|
|
@@ -11077,8 +11163,10 @@ var VerdictEnvelope = class extends S.Class("VerdictEnvelope")({
|
|
|
11077
11163
|
mutants: S.Array(RunEvent_exports.VerdictMutant),
|
|
11078
11164
|
scope: RunEvent_exports.RunScope,
|
|
11079
11165
|
mutantSetPolicy: RunEvent_exports.MutantSetPolicy,
|
|
11166
|
+
incrementalMode: RunEvent_exports.IncrementalMode,
|
|
11080
11167
|
phaseDurations: S.NullOr(RunEvent_exports.PhaseDurations),
|
|
11081
|
-
static: S.NullOr(RunEvent_exports.StaticVerdict)
|
|
11168
|
+
static: S.NullOr(RunEvent_exports.StaticVerdict),
|
|
11169
|
+
budget: RunEvent_exports.Budget
|
|
11082
11170
|
}) {};
|
|
11083
11171
|
//#endregion
|
|
11084
11172
|
//#region src/reporting/verdict-envelope.ts
|
|
@@ -11117,6 +11205,11 @@ const runIdTextOf = (now) => {
|
|
|
11117
11205
|
};
|
|
11118
11206
|
const generateRunId = (now) => RunEvent_exports.RunId.make(runIdTextOf(now));
|
|
11119
11207
|
const isActionableStatus = S.is(Mutant_exports.ActionableStatusSchema);
|
|
11208
|
+
const ZERO_BUDGET = RunEvent_exports.Budget.make({
|
|
11209
|
+
predictedSeconds: 0,
|
|
11210
|
+
actualSeconds: 0
|
|
11211
|
+
});
|
|
11212
|
+
const budgetOf = (report) => Option$1.getOrElse(Option$1.flatMap(Option$1.fromUndefinedOr(report["budget"]), (raw) => S.decodeUnknownOption(RunEvent_exports.Budget)(raw)), () => ZERO_BUDGET);
|
|
11120
11213
|
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
11214
|
id: mutant.id,
|
|
11122
11215
|
file,
|
|
@@ -11125,13 +11218,17 @@ const actionableMutants = (files) => Arr.flatMap(Object.entries(files), ([file,
|
|
|
11125
11218
|
replacement: mutant.replacement ?? null,
|
|
11126
11219
|
status: mutant.status
|
|
11127
11220
|
})));
|
|
11221
|
+
const reusesVerdicts = (config) => config.incremental === true && config.force !== true;
|
|
11222
|
+
const incrementalModeOf = (decoded) => Option$1.exists(decoded, reusesVerdicts) ? "incremental" : "full";
|
|
11128
11223
|
const embeddedConfig = (report) => {
|
|
11129
11224
|
const JsonReporterSchema = S.Struct({ fileName: S.String });
|
|
11130
11225
|
const MutatorSchema = S.StructWithRest(S.Struct({ mutantSetPolicy: S.optional(RunEvent_exports.MutantSetPolicy) }), [S.Record(S.String, S.Unknown)]);
|
|
11131
11226
|
const EmbeddedConfigSchema = S.StructWithRest(S.Struct({
|
|
11132
11227
|
jsonReporter: S.optional(JsonReporterSchema),
|
|
11133
11228
|
mutator: S.optional(MutatorSchema),
|
|
11134
|
-
since: S.optional(S.String)
|
|
11229
|
+
since: S.optional(S.String),
|
|
11230
|
+
incremental: S.optional(S.Boolean),
|
|
11231
|
+
force: S.optional(S.Boolean)
|
|
11135
11232
|
}), [S.Record(S.String, S.Unknown)]);
|
|
11136
11233
|
const decoded = S.decodeUnknownOption(EmbeddedConfigSchema)(report.config);
|
|
11137
11234
|
const jsonReporter = Option$1.flatMap(decoded, (config) => Option$1.fromUndefinedOr(config.jsonReporter));
|
|
@@ -11140,12 +11237,13 @@ const embeddedConfig = (report) => {
|
|
|
11140
11237
|
return {
|
|
11141
11238
|
jsonReporterFileName: Option$1.getOrUndefined(Option$1.map(jsonReporter, (reporter) => reporter.fileName)),
|
|
11142
11239
|
mutantSetPolicy: Option$1.getOrElse(mutantSetPolicy, () => "default"),
|
|
11143
|
-
scope: Option$1.isSome(since) ? "diff" : "full"
|
|
11240
|
+
scope: Option$1.isSome(since) ? "diff" : "full",
|
|
11241
|
+
incrementalMode: incrementalModeOf(decoded)
|
|
11144
11242
|
};
|
|
11145
11243
|
};
|
|
11146
11244
|
const buildVerdictEnvelope = dual((args) => args.length === 8, (report, mode, signal, runId, basePath, pathService, phaseDurations, staticVerdict) => {
|
|
11147
11245
|
const metrics = Report_exports.metricsFromMutants(Arr.flatMap(Object.values(report.files), (file) => file.mutants));
|
|
11148
|
-
const { jsonReporterFileName, mutantSetPolicy, scope } = embeddedConfig(report);
|
|
11246
|
+
const { jsonReporterFileName, mutantSetPolicy, scope, incrementalMode } = embeddedConfig(report);
|
|
11149
11247
|
return VerdictEnvelope.make({
|
|
11150
11248
|
schemaVersion: RunEvent_exports.StreamSchemaVersion.literal,
|
|
11151
11249
|
runId,
|
|
@@ -11165,14 +11263,33 @@ const buildVerdictEnvelope = dual((args) => args.length === 8, (report, mode, si
|
|
|
11165
11263
|
mutants: actionableMutants(report.files),
|
|
11166
11264
|
scope,
|
|
11167
11265
|
mutantSetPolicy,
|
|
11266
|
+
incrementalMode,
|
|
11168
11267
|
phaseDurations: Option$1.getOrNull(phaseDurations),
|
|
11169
|
-
static: staticVerdict
|
|
11268
|
+
static: staticVerdict,
|
|
11269
|
+
budget: budgetOf(report)
|
|
11170
11270
|
});
|
|
11171
11271
|
});
|
|
11172
11272
|
//#endregion
|
|
11173
11273
|
//#region src/run-events.service.ts
|
|
11174
11274
|
var RunEvents = class extends Context.Service()("@systemfsoftware/stryker-js/run-events.service/RunEvents") {};
|
|
11175
11275
|
var RunIdentity = class extends Context.Service()("@systemfsoftware/stryker-js/run-events.service/RunIdentity") {};
|
|
11276
|
+
var WorkerReports = class extends Context.Service()("@systemfsoftware/stryker-js/run-events.service/WorkerReports") {};
|
|
11277
|
+
const WorkerReportsLive = Layer.effect(WorkerReports, Effect$1.gen(function* () {
|
|
11278
|
+
const queue = yield* RunEvents;
|
|
11279
|
+
const counters = {
|
|
11280
|
+
testRunner: yield* Ref.make(0),
|
|
11281
|
+
checker: yield* Ref.make(0)
|
|
11282
|
+
};
|
|
11283
|
+
return WorkerReports.of({ report: (role, startupMs) => Effect$1.gen(function* () {
|
|
11284
|
+
const index = yield* Ref.getAndUpdate(counters[role], (current) => current + 1);
|
|
11285
|
+
yield* Queue.offer(queue, RunEvent_exports.WorkerReported.make({
|
|
11286
|
+
schemaVersion: RunEvent_exports.StreamSchemaVersion.literal,
|
|
11287
|
+
role,
|
|
11288
|
+
index,
|
|
11289
|
+
startupMs
|
|
11290
|
+
}));
|
|
11291
|
+
}) });
|
|
11292
|
+
}));
|
|
11176
11293
|
//#endregion
|
|
11177
11294
|
//#region src/phase-durations.ts
|
|
11178
11295
|
const elapsedOf = (marks, phase) => Option$1.map(Arr.findFirst(marks, (mark) => mark.phase === phase), (mark) => mark.elapsedMs);
|
|
@@ -11229,7 +11346,7 @@ const strykerOutputFilesOf = (options) => [
|
|
|
11229
11346
|
];
|
|
11230
11347
|
//#endregion
|
|
11231
11348
|
//#region package.json
|
|
11232
|
-
var version = "
|
|
11349
|
+
var version = "16.0.1";
|
|
11233
11350
|
//#endregion
|
|
11234
11351
|
//#region src/stryker-package.schema.ts
|
|
11235
11352
|
var StrykerPackage = class extends S.Class("StrykerPackage")({
|
|
@@ -11377,6 +11494,8 @@ var MutationReporting = class MutationReporting extends Context.Service()("@syst
|
|
|
11377
11494
|
};
|
|
11378
11495
|
return MutationReporting.of({
|
|
11379
11496
|
reportCheckFailure: (mutant, result) => reportCheckFailure(mutant, result),
|
|
11497
|
+
reportIgnored: (mutant, result) => reportIgnored(mutant, result),
|
|
11498
|
+
reportNoCoverage: (mutant) => reportNoCoverage(mutant),
|
|
11380
11499
|
reportMutantRunResult: (mutant, result) => mapRunResult(mutant, result),
|
|
11381
11500
|
reportAll: (input) => reportAll(deps, input),
|
|
11382
11501
|
checkpoint: (input, plannedMutants) => checkpoint(deps, input, plannedMutants)
|
|
@@ -11399,6 +11518,8 @@ const reportMutant = (mutant, status, outcome = {}) => Effect$1.succeed({
|
|
|
11399
11518
|
});
|
|
11400
11519
|
const reportMutantStatus = (mutant, status, statusReason) => reportMutant(mutant, status, { statusReason: statusReason ?? mutant.statusReason });
|
|
11401
11520
|
const reportCheckFailure = (mutant, result) => reportMutantStatus(mutant, "CompileError", result.reason);
|
|
11521
|
+
const reportIgnored = (mutant, result) => reportMutantStatus(mutant, "Ignored", result.reason);
|
|
11522
|
+
const reportNoCoverage = (mutant) => reportMutantStatus(mutant, "NoCoverage");
|
|
11402
11523
|
const reasonedOutcomeOf = (reason) => Option$1.match(Option$1.fromNullishOr(reason), {
|
|
11403
11524
|
onNone: () => ({}),
|
|
11404
11525
|
onSome: (present) => ({ statusReason: present })
|
|
@@ -11622,6 +11743,11 @@ const mutationTestReport = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReport
|
|
|
11622
11743
|
const { files, testFiles, identities } = yield* assembleReport(deps, input, results);
|
|
11623
11744
|
const dependencies = yield* discoverDependencies(deps);
|
|
11624
11745
|
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);
|
|
11746
|
+
const budget = budgetOf$1({
|
|
11747
|
+
results,
|
|
11748
|
+
concurrency: input.concurrency,
|
|
11749
|
+
actualSeconds: ((yield* Clock.currentTimeMillis) - input.runStartedAt) / 1e3
|
|
11750
|
+
});
|
|
11625
11751
|
return {
|
|
11626
11752
|
report: {
|
|
11627
11753
|
files,
|
|
@@ -11633,7 +11759,8 @@ const mutationTestReport = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReport
|
|
|
11633
11759
|
framework: {
|
|
11634
11760
|
...STRYKER_FRAMEWORK,
|
|
11635
11761
|
dependencies
|
|
11636
|
-
}
|
|
11762
|
+
},
|
|
11763
|
+
budget
|
|
11637
11764
|
},
|
|
11638
11765
|
identities
|
|
11639
11766
|
};
|
|
@@ -11674,27 +11801,49 @@ const emitVerdict = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReportingEmit
|
|
|
11674
11801
|
mutants: envelope.mutants,
|
|
11675
11802
|
scope: envelope.scope,
|
|
11676
11803
|
mutantSetPolicy: envelope.mutantSetPolicy,
|
|
11804
|
+
incrementalMode: envelope.incrementalMode,
|
|
11677
11805
|
phaseDurations: envelope.phaseDurations,
|
|
11678
|
-
static: envelope.static
|
|
11806
|
+
static: envelope.static,
|
|
11807
|
+
budget: envelope.budget
|
|
11679
11808
|
}));
|
|
11680
11809
|
});
|
|
11681
11810
|
const dryRunCoverageFieldOf = (testCoverage) => Option$1.match(Option$1.fromUndefinedOr(testCoverage.dryRunCoverage), {
|
|
11682
11811
|
onNone: () => ({}),
|
|
11683
11812
|
onSome: (dryRunCoverage) => ({ dryRunCoverage })
|
|
11684
11813
|
});
|
|
11814
|
+
const testTimesOf = (tests) => Arr.map([...tests], (test) => test.timeSpentMs);
|
|
11815
|
+
const executedEntryOf = (result) => Option$1.match(Option$1.fromUndefinedOr(result.cost), {
|
|
11816
|
+
onNone: () => [],
|
|
11817
|
+
onSome: (cost) => [[result.id, costTotalMsOf(cost) ?? 0]]
|
|
11818
|
+
});
|
|
11819
|
+
const priorEntryOf = (entry) => entry[1].actualMs === null ? [] : [[entry[0], entry[1].actualMs]];
|
|
11820
|
+
const priorCostsOf = (report) => Option$1.getOrElse(Option$1.flatMap(Option$1.fromNullishOr(report), (present) => Option$1.fromNullishOr(present.costs)), () => ({}));
|
|
11821
|
+
const mutantCostModelOf = (input, results) => ({
|
|
11822
|
+
subjects: Arr.map(results, (result) => ({
|
|
11823
|
+
id: result.id,
|
|
11824
|
+
static: result.static
|
|
11825
|
+
})),
|
|
11826
|
+
staticCoverage: input.testCoverage.staticCoverage,
|
|
11827
|
+
allTestTimesMs: Arr.map([...input.testCoverage.testsById], ([, test]) => test.timeSpentMs),
|
|
11828
|
+
coveringTestTimesMsByMutantId: Object.fromEntries([...input.testCoverage.testsByMutantId].map(([mutantId, tests]) => [mutantId, testTimesOf(tests)])),
|
|
11829
|
+
executedActualMsByMutantId: Object.fromEntries(Arr.flatMap(results, executedEntryOf)),
|
|
11830
|
+
priorActualMsByMutantId: Object.fromEntries(Arr.flatMap(Object.entries(priorCostsOf(input.project.incrementalReport)), priorEntryOf)),
|
|
11831
|
+
fixedOverheadMs: input.timeOverheadMs
|
|
11832
|
+
});
|
|
11833
|
+
const costsOf = (input, results) => mutantCostsOf(mutantCostModelOf(input, results));
|
|
11685
11834
|
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
11835
|
const runInputsDigest = yield* runInputsDigestOf(deps.fs, deps.path, input.basePath, input.options);
|
|
11688
11836
|
const json = yield* S.encodeEffect(S.fromJsonString(S.Unknown, { space: 2 }))({
|
|
11689
|
-
incrementalVersion: "
|
|
11690
|
-
verdictSemanticsVersion:
|
|
11837
|
+
incrementalVersion: "3",
|
|
11838
|
+
verdictSemanticsVersion: 3,
|
|
11691
11839
|
mutantSetPolicy: input.options.mutator.mutantSetPolicy,
|
|
11692
11840
|
runInputsDigest,
|
|
11693
11841
|
...report,
|
|
11694
11842
|
files: stampFileIdentities(stampClosureDigests(report.files, input.closureDigestsByMutantId), identities),
|
|
11843
|
+
costs: costsOf(input, input.results),
|
|
11695
11844
|
...dryRunCoverageFieldOf(input.testCoverage)
|
|
11696
11845
|
}).pipe(Effect$1.orDie);
|
|
11697
|
-
yield* deps
|
|
11846
|
+
yield* writeFileAtomic(deps, input.options.incrementalFile, json);
|
|
11698
11847
|
});
|
|
11699
11848
|
const writeReproducers = (deps, input, report) => {
|
|
11700
11849
|
const decision = Result.getOrThrow(buildReproducers(BuildReproducersCommand.make({ report })));
|
|
@@ -11731,24 +11880,24 @@ const reportAll = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReportingReport
|
|
|
11731
11880
|
verdict: finalVerdict
|
|
11732
11881
|
};
|
|
11733
11882
|
});
|
|
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
11883
|
const slimIncrementalReport = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReportingSlimIncrementalReport.name)(function* (deps, input, results) {
|
|
11741
11884
|
const { files, testFiles, identities } = yield* assembleReport(deps, input, results);
|
|
11742
11885
|
const runInputsDigest = yield* runInputsDigestOf(deps.fs, deps.path, input.basePath, input.options);
|
|
11743
11886
|
return {
|
|
11744
|
-
incrementalVersion: "
|
|
11745
|
-
verdictSemanticsVersion:
|
|
11887
|
+
incrementalVersion: "3",
|
|
11888
|
+
verdictSemanticsVersion: 3,
|
|
11746
11889
|
mutantSetPolicy: input.options.mutator.mutantSetPolicy,
|
|
11747
11890
|
runInputsDigest,
|
|
11748
11891
|
schemaVersion: Report_exports.WrittenSchemaVersion.literal,
|
|
11749
11892
|
thresholds: input.options.thresholds,
|
|
11750
11893
|
files: stampFileIdentities(stampClosureDigests(files, input.closureDigestsByMutantId), identities),
|
|
11894
|
+
costs: costsOf(input, results),
|
|
11751
11895
|
testFiles,
|
|
11896
|
+
budget: budgetOf$1({
|
|
11897
|
+
results,
|
|
11898
|
+
concurrency: input.concurrency,
|
|
11899
|
+
actualSeconds: ((yield* Clock.currentTimeMillis) - input.runStartedAt) / 1e3
|
|
11900
|
+
}),
|
|
11752
11901
|
...dryRunCoverageFieldOf(input.testCoverage)
|
|
11753
11902
|
};
|
|
11754
11903
|
});
|
|
@@ -11782,7 +11931,7 @@ const checkpointResultsOf = (input, plannedMutants) => Result.match(checkpointMu
|
|
|
11782
11931
|
const checkpointIncremental = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationReportingCheckpoint.name)(function* (deps, input, plannedMutants) {
|
|
11783
11932
|
const report = yield* slimIncrementalReport(deps, input, checkpointResultsOf(input, plannedMutants));
|
|
11784
11933
|
const json = yield* S.encodeEffect(S.fromJsonString(S.Unknown))(report).pipe(Effect$1.orDie);
|
|
11785
|
-
yield*
|
|
11934
|
+
yield* writeFileAtomic(deps, input.options.incrementalFile, json);
|
|
11786
11935
|
});
|
|
11787
11936
|
const checkpoint = (deps, input, plannedMutants) => Boolean$1$1.match(input.options.incremental, {
|
|
11788
11937
|
onTrue: () => checkpointIncremental(deps, input, plannedMutants),
|
|
@@ -12399,8 +12548,8 @@ const renderJsonReport = Workflow.make({
|
|
|
12399
12548
|
});
|
|
12400
12549
|
//#endregion
|
|
12401
12550
|
//#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$
|
|
12551
|
+
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"))));
|
|
12552
|
+
const readJsonReport = (input) => Effect$1.map(Stream.fromAsyncIterable(input.events, failAsJsonReporter).pipe(Stream.filterMap(reportOf$1), Stream.run(Sink.last())), (last) => ({
|
|
12404
12553
|
_tag: "JsonReportCommand",
|
|
12405
12554
|
reported: Option$1.getOrUndefined(last),
|
|
12406
12555
|
rendered: true,
|
|
@@ -12834,7 +12983,7 @@ const logOf = (command, results) => {
|
|
|
12834
12983
|
}]
|
|
12835
12984
|
};
|
|
12836
12985
|
};
|
|
12837
|
-
const decide$
|
|
12986
|
+
const decide$21 = (command) => {
|
|
12838
12987
|
const surfaced = surfacedOf(command);
|
|
12839
12988
|
const results = Arr.take(surfaced, command.maxResults);
|
|
12840
12989
|
const log = logOf(command, results);
|
|
@@ -12850,7 +12999,7 @@ const sarifReport = Workflow.make({
|
|
|
12850
12999
|
command: SarifReportCommand,
|
|
12851
13000
|
decision: SarifReportDecision,
|
|
12852
13001
|
error: S.Never,
|
|
12853
|
-
decide: (command) => Result.succeed(decide$
|
|
13002
|
+
decide: (command) => Result.succeed(decide$21(command))
|
|
12854
13003
|
});
|
|
12855
13004
|
//#endregion
|
|
12856
13005
|
//#region src/cap-survivors.workflow.ts
|
|
@@ -12967,7 +13116,7 @@ const linesOf = (command) => {
|
|
|
12967
13116
|
onFalse: () => Arr.flatMap(Option$1.toArray(HashMap.get(byId, ref.id)), (entry) => [lineOf(entry)])
|
|
12968
13117
|
}));
|
|
12969
13118
|
};
|
|
12970
|
-
const decide$
|
|
13119
|
+
const decide$20 = (command) => {
|
|
12971
13120
|
const lines = linesOf(command);
|
|
12972
13121
|
return Boolean$1$1.match(Arr.length(lines) === 0, {
|
|
12973
13122
|
onTrue: () => NothingToAnnotate.make({ survivorCount: Arr.length(command.survivors) }),
|
|
@@ -12978,7 +13127,7 @@ Workflow.make({
|
|
|
12978
13127
|
command: RenderAnnotationsCommand,
|
|
12979
13128
|
decision: RenderAnnotationsDecision,
|
|
12980
13129
|
error: S.Never,
|
|
12981
|
-
decide: (command) => Result.succeed(decide$
|
|
13130
|
+
decide: (command) => Result.succeed(decide$20(command))
|
|
12982
13131
|
});
|
|
12983
13132
|
//#endregion
|
|
12984
13133
|
//#region src/surfacing.ts
|
|
@@ -13054,8 +13203,8 @@ const failAsSarif = (cause) => Reporter_exports.ReporterFailed.make({
|
|
|
13054
13203
|
event: "mutationTestReportReady",
|
|
13055
13204
|
cause: Option$1.getOrElse(Option$1.map(ErrorText_exports.errorTextOf(cause), (rendered) => rendered.text), () => "")
|
|
13056
13205
|
});
|
|
13057
|
-
const reportOf
|
|
13058
|
-
const readSarifReport = (events) => Effect$1.map(Stream.fromAsyncIterable(events, failAsSarif).pipe(Stream.filterMap(reportOf
|
|
13206
|
+
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"))));
|
|
13207
|
+
const readSarifReport = (events) => Effect$1.map(Stream.fromAsyncIterable(events, failAsSarif).pipe(Stream.filterMap(reportOf), Stream.run(Sink.last())), (last) => Option$1.getOrUndefined(last));
|
|
13059
13208
|
const writeSarifReport = (options, report) => Effect$1.gen(function* () {
|
|
13060
13209
|
const fs = yield* FileSystem.FileSystem;
|
|
13061
13210
|
const path = yield* Path.Path;
|
|
@@ -13144,7 +13293,7 @@ var RunEnvironment = class extends Context.Service()("@systemfsoftware/stryker-j
|
|
|
13144
13293
|
};
|
|
13145
13294
|
const stageLayerOf = (env, events) => {
|
|
13146
13295
|
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* () {
|
|
13296
|
+
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
13297
|
const stageScope = yield* Scope.make();
|
|
13149
13298
|
yield* Effect$1.addFinalizer((exit) => Scope.close(stageScope, exit));
|
|
13150
13299
|
return stageScope;
|
|
@@ -13512,7 +13661,7 @@ var WorkerCrashed = class extends S.TaggedClass()("WorkerCrashed", {
|
|
|
13512
13661
|
};
|
|
13513
13662
|
const ClassifyWorkerExitDecision = S.Union([WorkerOutOfMemory, WorkerCrashed]);
|
|
13514
13663
|
const OutOfMemoryExitCode = S.Literals([134, 137]);
|
|
13515
|
-
const decide$
|
|
13664
|
+
const decide$19 = (command) => Boolean$1$1.match(S.is(OutOfMemoryExitCode)(command.exitCode), {
|
|
13516
13665
|
onTrue: () => Result.succeed(WorkerOutOfMemory.make({
|
|
13517
13666
|
pid: command.pid,
|
|
13518
13667
|
exitCode: command.exitCode
|
|
@@ -13526,7 +13675,7 @@ const classifyWorkerExit = Workflow.make({
|
|
|
13526
13675
|
command: ClassifyWorkerExitCommand,
|
|
13527
13676
|
decision: ClassifyWorkerExitDecision,
|
|
13528
13677
|
error: S.Never,
|
|
13529
|
-
decide: decide$
|
|
13678
|
+
decide: decide$19
|
|
13530
13679
|
});
|
|
13531
13680
|
//#endregion
|
|
13532
13681
|
//#region src/git-diff.schema.ts
|
|
@@ -13858,7 +14007,9 @@ const IncrementalReportSchema = S.StructWithRest(S.Struct({
|
|
|
13858
14007
|
runInputsDigest: S.String,
|
|
13859
14008
|
thresholds: ThresholdsLikeSchema,
|
|
13860
14009
|
files: S.Record(S.String, FileResultLikeSchema),
|
|
14010
|
+
costs: MutantCosts,
|
|
13861
14011
|
testFiles: S.optional(S.Record(S.String, TestFileLikeSchema)),
|
|
14012
|
+
budget: S.optional(RunEvent_exports.Budget),
|
|
13862
14013
|
dryRunCoverage: S.optionalKey(S.Unknown)
|
|
13863
14014
|
}), [S.Record(S.String, S.Unknown)]);
|
|
13864
14015
|
//#endregion
|
|
@@ -13936,12 +14087,12 @@ const splitOf = (details, checkerCount) => Boolean$1$1.match(checkerCount > 0, {
|
|
|
13936
14087
|
announcement: details.announcement
|
|
13937
14088
|
})
|
|
13938
14089
|
});
|
|
13939
|
-
const decide$
|
|
14090
|
+
const decide$18 = (command) => Result.succeed(splitOf(detailsOf(command.concurrency, command.availableParallelism), command.checkerCount));
|
|
13940
14091
|
const resolveConcurrency = Workflow.make({
|
|
13941
14092
|
command: ResolveConcurrency,
|
|
13942
14093
|
decision: ConcurrencySplit,
|
|
13943
14094
|
error: S.Never,
|
|
13944
|
-
decide: decide$
|
|
14095
|
+
decide: decide$18
|
|
13945
14096
|
});
|
|
13946
14097
|
//#endregion
|
|
13947
14098
|
//#region src/concurrency.cell.ts
|
|
@@ -14173,7 +14324,7 @@ const discardOf = (reason, actual, expected) => IncrementalReportDiscard.make({
|
|
|
14173
14324
|
actual,
|
|
14174
14325
|
expected
|
|
14175
14326
|
});
|
|
14176
|
-
const decide$
|
|
14327
|
+
const decide$17 = (command) => Option$1.match(Option$1.fromUndefinedOr(command.report), {
|
|
14177
14328
|
onNone: () => discardOf("noPriorRecord", void 0, command.expectedIncrementalVersion),
|
|
14178
14329
|
onSome: (report) => Option$1.match(Option$1.firstSomeOf(identityMismatchesOf(command, report).map(mismatchOptionOf)), {
|
|
14179
14330
|
onNone: () => IncrementalReportKeep.make({ report }),
|
|
@@ -14184,7 +14335,7 @@ const admitIncrementalReport = Workflow.make({
|
|
|
14184
14335
|
command: AdmitIncrementalReportCommand,
|
|
14185
14336
|
decision: S.Union([IncrementalReportKeep, IncrementalReportDiscard]),
|
|
14186
14337
|
error: S.Never,
|
|
14187
|
-
decide: (command) => Result.succeed(decide$
|
|
14338
|
+
decide: (command) => Result.succeed(decide$17(command))
|
|
14188
14339
|
});
|
|
14189
14340
|
//#endregion
|
|
14190
14341
|
//#region src/git-diff.workflow.ts
|
|
@@ -14539,11 +14690,15 @@ const ALWAYS_IGNORE = Object.freeze([
|
|
|
14539
14690
|
"/stryker.log",
|
|
14540
14691
|
".next",
|
|
14541
14692
|
".nuxt",
|
|
14542
|
-
".svelte-kit"
|
|
14693
|
+
".svelte-kit",
|
|
14694
|
+
".turbo"
|
|
14543
14695
|
]);
|
|
14544
14696
|
const CRAWL_CONCURRENCY = 256;
|
|
14545
14697
|
const DISCARD_TEXTS = {
|
|
14546
|
-
noPriorRecord: (command) => `Unable to parse incremental result file at ${command.incrementalFile}
|
|
14698
|
+
noPriorRecord: (command) => `Unable to parse incremental result file at ${command.incrementalFile}${Option$1.match(Option$1.fromUndefinedOr(command.decodeError), {
|
|
14699
|
+
onNone: () => "",
|
|
14700
|
+
onSome: (error) => `: ${error}`
|
|
14701
|
+
})}; a full mutation testing run will be performed.`,
|
|
14547
14702
|
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
14703
|
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
14704
|
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 +14756,14 @@ const isEntryIncluded = (ignorePatterns, entry) => {
|
|
|
14601
14756
|
};
|
|
14602
14757
|
const resolveInputFileNames = (ignorePatterns, basePath) => crawlDirectory(ignorePatterns, basePath, basePath).pipe(Stream.runCollect, Effect$1.map((files) => [...files]));
|
|
14603
14758
|
const parseAndDecodeIncrementalReport = Schema.decodeUnknownResult(Schema.fromJsonString(IncrementalReportSchema));
|
|
14604
|
-
const
|
|
14759
|
+
const decodeFailureText = (failure) => failure.message.replace(/\s+/gu, " ").trim();
|
|
14760
|
+
const reportReadOf = (contents) => Option$1.match(Option$1.fromUndefinedOr(contents), {
|
|
14761
|
+
onNone: () => ({}),
|
|
14762
|
+
onSome: (text) => Result.match(parseAndDecodeIncrementalReport(text), {
|
|
14763
|
+
onFailure: (failure) => ({ decodeError: decodeFailureText(failure) }),
|
|
14764
|
+
onSuccess: (report) => ({ report })
|
|
14765
|
+
})
|
|
14766
|
+
});
|
|
14605
14767
|
const incrementalContentsOf = (fs, options) => Boolean$1.match(options.incremental, {
|
|
14606
14768
|
onFalse: () => Effect$1.succeedNone,
|
|
14607
14769
|
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 +14868,12 @@ const readProject = Effect$1.fn(SpanTaxonomy_exports.Spans.projectReadFromDisk.n
|
|
|
14706
14868
|
yield* Effect$1.forEach(testFilePatterns, (pattern) => warnUnmatchedTestPattern(inputFileNames, input.basePath, pattern), { discard: true });
|
|
14707
14869
|
const runInputsDigest = yield* runInputsDigestOf(fs, pathService, input.basePath, options);
|
|
14708
14870
|
const contents = Option$1.getOrUndefined(yield* incrementalContentsOf(fs, options));
|
|
14871
|
+
const reportRead = reportReadOf(contents);
|
|
14709
14872
|
return {
|
|
14710
14873
|
_tag: "AdmitIncrementalReportCommand",
|
|
14711
|
-
report:
|
|
14712
|
-
expectedIncrementalVersion: "
|
|
14713
|
-
verdictSemanticsVersion:
|
|
14874
|
+
report: reportRead.report,
|
|
14875
|
+
expectedIncrementalVersion: "3",
|
|
14876
|
+
verdictSemanticsVersion: 3,
|
|
14714
14877
|
mutantSetPolicy: options.mutator.mutantSetPolicy,
|
|
14715
14878
|
runInputsDigest,
|
|
14716
14879
|
options,
|
|
@@ -14719,6 +14882,7 @@ const readProject = Effect$1.fn(SpanTaxonomy_exports.Spans.projectReadFromDisk.n
|
|
|
14719
14882
|
incremental: options.incremental,
|
|
14720
14883
|
incrementalFile: options.incrementalFile,
|
|
14721
14884
|
contents,
|
|
14885
|
+
decodeError: reportRead.decodeError,
|
|
14722
14886
|
fileDescriptions: decision.fileDescriptions,
|
|
14723
14887
|
testFiles: [...decision.testFiles]
|
|
14724
14888
|
};
|
|
@@ -14771,6 +14935,58 @@ const readProjectCell = Sandwich.named(SpanTaxonomy_exports.Spans.projectRead.na
|
|
|
14771
14935
|
}))
|
|
14772
14936
|
});
|
|
14773
14937
|
//#endregion
|
|
14938
|
+
//#region src/refuse-local-mutation.workflow.ts
|
|
14939
|
+
const LocalMutationDecisionTypeId = Symbol.for("@systemfsoftware/stryker-js/LocalMutationDecision");
|
|
14940
|
+
var RefuseLocalMutationCommand = class extends S.TaggedClass()("RefuseLocalMutationCommand", {
|
|
14941
|
+
dryRunOnly: S.Boolean,
|
|
14942
|
+
githubActions: S.UndefinedOr(S.String),
|
|
14943
|
+
allowLocalMutation: S.UndefinedOr(S.String)
|
|
14944
|
+
}) {
|
|
14945
|
+
static [Workflow.InstrumentationBrand] = {};
|
|
14946
|
+
};
|
|
14947
|
+
var LocalMutationAllowed = class extends S.TaggedClass()("LocalMutationAllowed", {}) {
|
|
14948
|
+
[LocalMutationDecisionTypeId] = LocalMutationDecisionTypeId;
|
|
14949
|
+
};
|
|
14950
|
+
var LocalMutationRefused = class extends S.TaggedError()("LocalMutationRefused", {
|
|
14951
|
+
rule: RunEvent_exports.RefusalRule,
|
|
14952
|
+
message: S.String
|
|
14953
|
+
}) {};
|
|
14954
|
+
const decide$16 = (command) => Match$1.value({
|
|
14955
|
+
dryRunOnly: command.dryRunOnly,
|
|
14956
|
+
githubActions: command.githubActions,
|
|
14957
|
+
allowLocalMutation: command.allowLocalMutation
|
|
14958
|
+
}).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({
|
|
14959
|
+
rule: "mutation-runs-on-main-ci",
|
|
14960
|
+
message: "mutation runs only on main CI"
|
|
14961
|
+
}))));
|
|
14962
|
+
const refuseLocalMutation = Workflow.make({
|
|
14963
|
+
command: RefuseLocalMutationCommand,
|
|
14964
|
+
decision: LocalMutationAllowed,
|
|
14965
|
+
error: LocalMutationRefused,
|
|
14966
|
+
decide: decide$16
|
|
14967
|
+
});
|
|
14968
|
+
//#endregion
|
|
14969
|
+
//#region src/refuse-local-mutation.cell.ts
|
|
14970
|
+
const envOf = (key) => Config.option(Config.String(key)).pipe(Effect$1.map(Option$1.getOrUndefined), Effect$1.orElseSucceed(() => void 0));
|
|
14971
|
+
const guardOf = (input) => Effect$1.gen(function* () {
|
|
14972
|
+
const githubActions = yield* envOf("GITHUB_ACTIONS");
|
|
14973
|
+
const allowLocalMutation = yield* envOf("ALLOW_LOCAL_MUTATION");
|
|
14974
|
+
const command = RefuseLocalMutationCommand.make({
|
|
14975
|
+
dryRunOnly: input.options.dryRunOnly,
|
|
14976
|
+
githubActions,
|
|
14977
|
+
allowLocalMutation
|
|
14978
|
+
});
|
|
14979
|
+
return yield* Result.match(refuseLocalMutation(command), {
|
|
14980
|
+
onFailure: (refused) => Effect$1.fail(StageError.make({
|
|
14981
|
+
stage: "prepare",
|
|
14982
|
+
reason: refused.message,
|
|
14983
|
+
cause: refused
|
|
14984
|
+
})),
|
|
14985
|
+
onSuccess: () => Effect$1.succeed(input)
|
|
14986
|
+
});
|
|
14987
|
+
});
|
|
14988
|
+
const refuseLocalMutationCell = (input) => Cell.fromEffect(guardOf(input));
|
|
14989
|
+
//#endregion
|
|
14774
14990
|
//#region src/dry-run-coverage.schema.ts
|
|
14775
14991
|
const DryRunCoverageSchema = S.Struct({
|
|
14776
14992
|
tests: S.Array(TestRunner_exports.TestResultSchema),
|
|
@@ -15954,6 +16170,35 @@ const buildTestRunner = dual(2, (context, childProcessRunner) => Option$1.match(
|
|
|
15954
16170
|
onNone: () => decorateChildRunner(context, childProcessRunner)
|
|
15955
16171
|
}));
|
|
15956
16172
|
//#endregion
|
|
16173
|
+
//#region src/run/dry-run-coverage.ts
|
|
16174
|
+
const testsByIdOf = (result) => MutableHashMap.fromIterable(result.tests.map((test) => [test.id, test]));
|
|
16175
|
+
const coveredMutantIdsOf = (coverage) => Object.entries(coverage).filter(([, count]) => count > 0).map(([mutantId]) => mutantId);
|
|
16176
|
+
const testsByMutantIdOf = (mutantCoverage, testsById) => Object.entries(mutantCoverage.perTest).reduce((testsByMutantId, [testId, coverage]) => Option$1.match(MutableHashMap.get(testsById, testId), {
|
|
16177
|
+
onNone: () => testsByMutantId,
|
|
16178
|
+
onSome: (test) => coveredMutantIdsOf(coverage).reduce((acc, mutantId) => MutableHashMap.set(acc, mutantId, MutableHashSet.add(Option$1.getOrElse(MutableHashMap.get(acc, mutantId), () => MutableHashSet.empty()), test)), testsByMutantId)
|
|
16179
|
+
}), MutableHashMap.empty());
|
|
16180
|
+
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());
|
|
16181
|
+
const testCoverageOf = ({ result, dryRunCoverage }) => {
|
|
16182
|
+
const testsById = testsByIdOf(result);
|
|
16183
|
+
const mutantCoverage = Option$1.fromNullishOr(result.mutantCoverage);
|
|
16184
|
+
return {
|
|
16185
|
+
testsByMutantId: Option$1.match(mutantCoverage, {
|
|
16186
|
+
onNone: () => MutableHashMap.empty(),
|
|
16187
|
+
onSome: (coverage) => testsByMutantIdOf(coverage, testsById)
|
|
16188
|
+
}),
|
|
16189
|
+
testsById,
|
|
16190
|
+
staticCoverage: Option$1.match(mutantCoverage, {
|
|
16191
|
+
onNone: () => void 0,
|
|
16192
|
+
onSome: (coverage) => coverage.static
|
|
16193
|
+
}),
|
|
16194
|
+
hitsByMutantId: Option$1.match(mutantCoverage, {
|
|
16195
|
+
onNone: () => MutableHashMap.empty(),
|
|
16196
|
+
onSome: (coverage) => hitsByMutantIdOf(coverage)
|
|
16197
|
+
}),
|
|
16198
|
+
dryRunCoverage
|
|
16199
|
+
};
|
|
16200
|
+
};
|
|
16201
|
+
//#endregion
|
|
15957
16202
|
//#region src/run/incremental-reuse.ts
|
|
15958
16203
|
const absoluteSourceOf = (path, basePath, file) => path.isAbsolute(file) ? file : path.join(basePath, file);
|
|
15959
16204
|
const matchedSourcesOf = Effect$1.fnUntraced(function* (input) {
|
|
@@ -16283,33 +16528,6 @@ const withOriginalFileName = (test, prev) => Match$1.value(test.fileName).pipe(M
|
|
|
16283
16528
|
fileName: originalFileFor(prev.sandbox, fileName)
|
|
16284
16529
|
})), Match$1.orElse(() => test));
|
|
16285
16530
|
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
16531
|
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
16532
|
const reportDryRunCompleted = (raw, tests, overheadMillis) => offerReporterEvent(raw.prev.reporterStage, Reporter_exports.DryRunCompleted.make({
|
|
16315
16533
|
timing: {
|
|
@@ -16333,7 +16551,10 @@ const freshCoverageOf = (raw, dryRunResult, overheadMillis) => ({
|
|
|
16333
16551
|
const dryRunDoneOf = (raw, dryRunResult, coverage) => ({
|
|
16334
16552
|
...raw.prev,
|
|
16335
16553
|
dryRunResult,
|
|
16336
|
-
testCoverage:
|
|
16554
|
+
testCoverage: testCoverageOf({
|
|
16555
|
+
result: dryRunResult,
|
|
16556
|
+
dryRunCoverage: coverage
|
|
16557
|
+
}),
|
|
16337
16558
|
timeOverhead: Duration.millis(coverage.timeOverheadMs)
|
|
16338
16559
|
});
|
|
16339
16560
|
const completeFreshDryRun = Effect$1.fnUntraced(function* (raw, dryRunResult) {
|
|
@@ -16363,6 +16584,7 @@ const completeDryRunPassed = (raw) => Match$1.value(raw.rawResult).pipe(Match$1.
|
|
|
16363
16584
|
}))), Match$1.exhaustive);
|
|
16364
16585
|
const runFreshDryRun = Effect$1.fnUntraced(function* (command, idGenerator, currentTestClosureDigest, runInputsDigest) {
|
|
16365
16586
|
const env = yield* RunEnvironment;
|
|
16587
|
+
const reports = yield* WorkerReports;
|
|
16366
16588
|
const { files, testFiles } = yield* resolveDryRunFiles(command);
|
|
16367
16589
|
const dryRunTimeout = command.options.dryRunTimeoutMinutes * 60 * 1e3;
|
|
16368
16590
|
const options = dryRunOptionsOf(command, files, testFiles, dryRunTimeout);
|
|
@@ -16378,6 +16600,7 @@ const runFreshDryRun = Effect$1.fnUntraced(function* (command, idGenerator, curr
|
|
|
16378
16600
|
idGenerator
|
|
16379
16601
|
})));
|
|
16380
16602
|
});
|
|
16603
|
+
const startedAt = yield* Clock.currentTimeMillis;
|
|
16381
16604
|
const runner = yield* buildTestRunner({
|
|
16382
16605
|
options: command.options,
|
|
16383
16606
|
fileDescriptions: command.project.fileDescriptions,
|
|
@@ -16386,6 +16609,7 @@ const runFreshDryRun = Effect$1.fnUntraced(function* (command, idGenerator, curr
|
|
|
16386
16609
|
retire: Effect$1.void,
|
|
16387
16610
|
testFiles: testFiles ?? []
|
|
16388
16611
|
}, childRunnerEffect);
|
|
16612
|
+
yield* reports.report("testRunner", (yield* Clock.currentTimeMillis) - startedAt);
|
|
16389
16613
|
const capabilities = yield* runner.capabilities.pipe(Effect$1.mapError((cause) => StageError.make({
|
|
16390
16614
|
stage: "dryRun",
|
|
16391
16615
|
reason: "Failed to get test runner capabilities",
|
|
@@ -17337,6 +17561,10 @@ const FailedCheckResultSchema = S.Struct({
|
|
|
17337
17561
|
status: S.Literal("compileError"),
|
|
17338
17562
|
reason: S.String
|
|
17339
17563
|
});
|
|
17564
|
+
const IgnoredCheckResultSchema = S.Struct({
|
|
17565
|
+
status: S.Literal("ignored"),
|
|
17566
|
+
reason: S.String
|
|
17567
|
+
});
|
|
17340
17568
|
var CheckedPlanPassed = class extends S.TaggedClass()("CheckedPlanPassed", {
|
|
17341
17569
|
mutantId: Mutant_exports.MutantId,
|
|
17342
17570
|
entryIndex: S.Int
|
|
@@ -17351,27 +17579,48 @@ var CheckedPlanFailed = class extends S.TaggedClass()("CheckedPlanFailed", {
|
|
|
17351
17579
|
}) {
|
|
17352
17580
|
[CheckedPlanTypeId] = CheckedPlanTypeId;
|
|
17353
17581
|
};
|
|
17582
|
+
var CheckedPlanIgnored = class extends S.TaggedClass()("CheckedPlanIgnored", {
|
|
17583
|
+
mutantId: Mutant_exports.MutantId,
|
|
17584
|
+
entryIndex: S.Int,
|
|
17585
|
+
reason: S.String,
|
|
17586
|
+
result: IgnoredCheckResultSchema
|
|
17587
|
+
}) {
|
|
17588
|
+
[CheckedPlanTypeId] = CheckedPlanTypeId;
|
|
17589
|
+
};
|
|
17354
17590
|
var PartitionCheckedPlansCommand = class extends S.TaggedClass()("PartitionCheckedPlansCommand", { checked: S.Array(S.Tuple([Mutant_exports.MutantId, Checker_exports.CheckResultSchema])) }) {
|
|
17355
17591
|
static [Workflow.InstrumentationBrand] = {};
|
|
17356
17592
|
};
|
|
17357
|
-
const isFailed = (result) => result.status
|
|
17593
|
+
const isFailed = (result) => result.status === "compileError";
|
|
17594
|
+
const isIgnored = (result) => result.status === "ignored";
|
|
17358
17595
|
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({
|
|
17596
|
+
const decideCheckedPlan = (mutantId, result, entryIndex) => Option$1.match(Option$1.liftPredicate(result, isIgnored), {
|
|
17597
|
+
onSome: (ignored) => CheckedPlanIgnored.make({
|
|
17365
17598
|
mutantId,
|
|
17366
17599
|
entryIndex,
|
|
17367
|
-
reason:
|
|
17368
|
-
result:
|
|
17600
|
+
reason: ignored.reason,
|
|
17601
|
+
result: ignored
|
|
17602
|
+
}),
|
|
17603
|
+
onNone: () => Option$1.match(Option$1.liftPredicate(result, isFailed), {
|
|
17604
|
+
onNone: () => CheckedPlanPassed.make({
|
|
17605
|
+
mutantId,
|
|
17606
|
+
entryIndex
|
|
17607
|
+
}),
|
|
17608
|
+
onSome: (failed) => CheckedPlanFailed.make({
|
|
17609
|
+
mutantId,
|
|
17610
|
+
entryIndex,
|
|
17611
|
+
reason: failedReasonOf(failed),
|
|
17612
|
+
result: failed
|
|
17613
|
+
})
|
|
17369
17614
|
})
|
|
17370
17615
|
});
|
|
17371
17616
|
const decide$8 = (command) => Result.succeed(command.checked.map(([mutantId, result], entryIndex) => decideCheckedPlan(mutantId, result, entryIndex)));
|
|
17372
17617
|
const partitionCheckedPlans = Workflow.make({
|
|
17373
17618
|
command: PartitionCheckedPlansCommand,
|
|
17374
|
-
decision: S.Array(S.Union([
|
|
17619
|
+
decision: S.Array(S.Union([
|
|
17620
|
+
CheckedPlanPassed,
|
|
17621
|
+
CheckedPlanFailed,
|
|
17622
|
+
CheckedPlanIgnored
|
|
17623
|
+
])),
|
|
17375
17624
|
error: S.Never,
|
|
17376
17625
|
decide: decide$8
|
|
17377
17626
|
});
|
|
@@ -17408,6 +17657,7 @@ const onCheckerSlot = (pool, checkerIndex, run) => Pool.use(pool, (slot) => Opti
|
|
|
17408
17657
|
}));
|
|
17409
17658
|
const noPassedPlans = [];
|
|
17410
17659
|
const noFailedChecks = [];
|
|
17660
|
+
const noIgnoredChecks = [];
|
|
17411
17661
|
const splitCheckedPlans = Effect$1.fn(SpanTaxonomy_exports.Spans.checkerPoolSplitChecked.name)(function* (checked) {
|
|
17412
17662
|
const decisions = yield* Effect$1.fromResult(partitionCheckedPlans(PartitionCheckedPlansCommand.make({ checked: checked.map(([plan, result]) => [plan.mutant.id, result]) })));
|
|
17413
17663
|
return {
|
|
@@ -17418,6 +17668,10 @@ const splitCheckedPlans = Effect$1.fn(SpanTaxonomy_exports.Spans.checkerPoolSpli
|
|
|
17418
17668
|
failedChecks: decisions.flatMap((decision) => Option$1.match(Option$1.liftPredicate(decision, S.is(CheckedPlanFailed)), {
|
|
17419
17669
|
onNone: () => [],
|
|
17420
17670
|
onSome: (failed) => Option$1.toArray(Option$1.map(Arr.get(checked, failed.entryIndex), ([plan]) => [plan, failed.result]))
|
|
17671
|
+
})),
|
|
17672
|
+
ignoredChecks: decisions.flatMap((decision) => Option$1.match(Option$1.liftPredicate(decision, S.is(CheckedPlanIgnored)), {
|
|
17673
|
+
onNone: () => [],
|
|
17674
|
+
onSome: (ignored) => Option$1.toArray(Option$1.map(Arr.get(checked, ignored.entryIndex), ([plan]) => [plan, ignored.result]))
|
|
17421
17675
|
}))
|
|
17422
17676
|
};
|
|
17423
17677
|
});
|
|
@@ -17426,23 +17680,34 @@ const failedElement = (failedChecks) => Option$1.match(Arr.head(failedChecks), {
|
|
|
17426
17680
|
onNone: () => Stream.empty,
|
|
17427
17681
|
onSome: () => Stream.succeed({
|
|
17428
17682
|
passedPlans: noPassedPlans,
|
|
17429
|
-
failedChecks
|
|
17683
|
+
failedChecks,
|
|
17684
|
+
ignoredChecks: noIgnoredChecks
|
|
17685
|
+
})
|
|
17686
|
+
});
|
|
17687
|
+
const ignoredElement = (ignoredChecks) => Option$1.match(Arr.head(ignoredChecks), {
|
|
17688
|
+
onNone: () => Stream.empty,
|
|
17689
|
+
onSome: () => Stream.succeed({
|
|
17690
|
+
passedPlans: noPassedPlans,
|
|
17691
|
+
failedChecks: noFailedChecks,
|
|
17692
|
+
ignoredChecks
|
|
17430
17693
|
})
|
|
17431
17694
|
});
|
|
17432
17695
|
const checkedGroupsFor = (pool, checkerNames, checkerIndex, plans) => Option$1.match(Arr.get(checkerNames, checkerIndex), {
|
|
17433
17696
|
onNone: () => Stream.succeed({
|
|
17434
17697
|
passedPlans: plans,
|
|
17435
|
-
failedChecks: noFailedChecks
|
|
17698
|
+
failedChecks: noFailedChecks,
|
|
17699
|
+
ignoredChecks: noIgnoredChecks
|
|
17436
17700
|
}),
|
|
17437
17701
|
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
17702
|
concurrency: "unbounded",
|
|
17439
17703
|
unordered: true
|
|
17440
|
-
}), Stream.flatMap((split) => Stream.concat(failedElement(split.failedChecks), checkedGroupsFor(pool, checkerNames, checkerIndex + 1, split.passedPlans)))))))
|
|
17704
|
+
}), Stream.flatMap((split) => Stream.concat(ignoredElement(split.ignoredChecks), Stream.concat(failedElement(split.failedChecks), checkedGroupsFor(pool, checkerNames, checkerIndex + 1, split.passedPlans))))))))
|
|
17441
17705
|
});
|
|
17442
17706
|
const checkPlansStream = dual(2, (checkerPool, plans) => Option$1.fromNullishOr(checkerPool).pipe(Option$1.match({
|
|
17443
17707
|
onNone: () => Stream.succeed({
|
|
17444
17708
|
passedPlans: plans,
|
|
17445
|
-
failedChecks: noFailedChecks
|
|
17709
|
+
failedChecks: noFailedChecks,
|
|
17710
|
+
ignoredChecks: noIgnoredChecks
|
|
17446
17711
|
}),
|
|
17447
17712
|
onSome: (handle) => checkerNamesOf(CheckerPoolHandle.slot(handle)).pipe(Effect$1.map((checkerNames) => checkedGroupsFor(CheckerPoolHandle.slot(handle), checkerNames, 0, plans)), Stream.unwrap)
|
|
17448
17713
|
}), Stream.withSpan(SpanTaxonomy_exports.Spans.checkerPoolCheckPlans.name)));
|
|
@@ -17450,16 +17715,23 @@ Effect$1.fnUntraced(function* (checkerPool, plans) {
|
|
|
17450
17715
|
const checkedGroups = yield* Stream.runCollect(checkPlansStream(checkerPool, plans));
|
|
17451
17716
|
const passedPlans = [];
|
|
17452
17717
|
const failedChecks = [];
|
|
17718
|
+
const ignoredChecks = [];
|
|
17453
17719
|
for (const group of checkedGroups) {
|
|
17454
17720
|
passedPlans.push(...group.passedPlans);
|
|
17455
17721
|
failedChecks.push(...group.failedChecks);
|
|
17722
|
+
ignoredChecks.push(...group.ignoredChecks);
|
|
17456
17723
|
}
|
|
17457
17724
|
return {
|
|
17458
17725
|
passedPlans,
|
|
17459
|
-
failedChecks
|
|
17726
|
+
failedChecks,
|
|
17727
|
+
ignoredChecks
|
|
17460
17728
|
};
|
|
17461
17729
|
});
|
|
17462
|
-
const runCheckedPlans = dual(2, (self, execution) => self.pipe(Stream.flatMap(({ passedPlans, failedChecks }) => Stream.fromIterable([
|
|
17730
|
+
const runCheckedPlans = dual(2, (self, execution) => self.pipe(Stream.flatMap(({ passedPlans, failedChecks, ignoredChecks }) => Stream.fromIterable([
|
|
17731
|
+
...failedChecks.map(([plan, result]) => () => execution.settleFailure(plan, result)),
|
|
17732
|
+
...ignoredChecks.map(([plan, result]) => () => execution.settleIgnored(plan, result)),
|
|
17733
|
+
...passedPlans.map((plan) => () => execution.runPlan(plan))
|
|
17734
|
+
])), Stream.mapEffect((work) => work(), {
|
|
17463
17735
|
concurrency: Math.max(1, execution.concurrency),
|
|
17464
17736
|
unordered: true
|
|
17465
17737
|
})));
|
|
@@ -17514,11 +17786,13 @@ const checkerWorkerSpawnOf = (loaded, configured) => Effect$1.mapError(Effect$1.
|
|
|
17514
17786
|
cause: PluginNotFoundError.make({ descriptor: missing.descriptor })
|
|
17515
17787
|
}));
|
|
17516
17788
|
const acquire$1 = Effect$1.fnUntraced(function* (spec) {
|
|
17789
|
+
const reports = yield* WorkerReports;
|
|
17517
17790
|
return yield* Boolean$1$1.match(spec.options.checkers.length === 0, {
|
|
17518
17791
|
onTrue: () => Effect$1.as(Effect$1.void, void 0),
|
|
17519
17792
|
onFalse: () => Pool.make({
|
|
17520
17793
|
acquire: Effect$1.forEach(spec.options.checkers, (checker) => Effect$1.gen(function* () {
|
|
17521
17794
|
const resolved = yield* checkerWorkerSpawnOf(spec.loadedPlugins, ConfiguredPluginModulePath.make({ modulePath: checker.plugin }));
|
|
17795
|
+
const startedAt = yield* Clock.currentTimeMillis;
|
|
17522
17796
|
const service = yield* scoped$2({
|
|
17523
17797
|
options: {
|
|
17524
17798
|
...spec.options,
|
|
@@ -17530,6 +17804,7 @@ const acquire$1 = Effect$1.fnUntraced(function* (spec) {
|
|
|
17530
17804
|
times: CHECKER_ACQUIRE_RETRIES,
|
|
17531
17805
|
while: isCheckerCrash
|
|
17532
17806
|
}));
|
|
17807
|
+
yield* reports.report("checker", (yield* Clock.currentTimeMillis) - startedAt);
|
|
17533
17808
|
return {
|
|
17534
17809
|
checkerName: resolved.name,
|
|
17535
17810
|
checker: service
|
|
@@ -17887,7 +18162,7 @@ const readIncrementalReuseCommand = Effect$1.fn(SpanTaxonomy_exports.Spans.incre
|
|
|
17887
18162
|
previousRecords: [...previousRecords],
|
|
17888
18163
|
closureDigestsByMutantId: closures.digests,
|
|
17889
18164
|
closureAnalysisFailed: closures.failed,
|
|
17890
|
-
verdictSemanticsVersion:
|
|
18165
|
+
verdictSemanticsVersion: 3,
|
|
17891
18166
|
mutantSetPolicy: input.options.mutator.mutantSetPolicy,
|
|
17892
18167
|
runInputsDigest,
|
|
17893
18168
|
force: input.force,
|
|
@@ -18070,6 +18345,7 @@ const toReportedMutant = (mutant) => Object.assign(mutant, {
|
|
|
18070
18345
|
coveredBy: mutant.coveredBy,
|
|
18071
18346
|
static: mutant.static
|
|
18072
18347
|
});
|
|
18348
|
+
const isNoCoveragePlan = (plan) => plan.runOptions.testFilter !== void 0 && plan.runOptions.testFilter.length === 0;
|
|
18073
18349
|
const inPlannedOrder = ({ planned, results }) => {
|
|
18074
18350
|
const rankById = Object.fromEntries(planned.map((mutant, index) => [mutant.id, index]));
|
|
18075
18351
|
return Arr.sortWith(results, (result) => rankById[result.id] ?? planned.length, Order.Number);
|
|
@@ -18107,11 +18383,14 @@ const reportingInputOf = (input) => ({
|
|
|
18107
18383
|
options: input.prev.options,
|
|
18108
18384
|
project: input.prev.project,
|
|
18109
18385
|
testCoverage: input.prev.testCoverage,
|
|
18386
|
+
timeOverheadMs: Duration.toMillis(input.prev.timeOverhead),
|
|
18110
18387
|
runId: input.env.runId,
|
|
18111
18388
|
resolvedMode: input.env.resolvedMode,
|
|
18112
18389
|
basePath: input.env.basePath,
|
|
18113
18390
|
reporterStage: input.prev.reporterStage,
|
|
18114
|
-
formatRegistry: input.prev.formatRegistry
|
|
18391
|
+
formatRegistry: input.prev.formatRegistry,
|
|
18392
|
+
concurrency: input.prev.concurrency.testRunners + input.prev.concurrency.checkers,
|
|
18393
|
+
runStartedAt: input.env.runStartedAt
|
|
18115
18394
|
});
|
|
18116
18395
|
const preparedStreamableOf = Effect$1.fnUntraced(function* (context, result) {
|
|
18117
18396
|
return yield* Option$1.match(Option$1.filter(Option$1.some(result.status), isMutantStatus), {
|
|
@@ -18365,10 +18644,11 @@ const coveredByField = (coveredBy) => Option$1.match(Option$1.fromUndefinedOr(co
|
|
|
18365
18644
|
onNone: () => ({}),
|
|
18366
18645
|
onSome: (present) => ({ coveredBy: [...present] })
|
|
18367
18646
|
});
|
|
18368
|
-
const testFilterField = (testFilter) => Option$1.match(Option$1.
|
|
18647
|
+
const testFilterField = (testFilter) => Option$1.match(Option$1.fromUndefinedOr(testFilter), {
|
|
18369
18648
|
onNone: () => ({}),
|
|
18370
18649
|
onSome: (present) => ({ testFilter: [...present] })
|
|
18371
18650
|
});
|
|
18651
|
+
const nonEmptyTestFilterOf = (tests) => Option$1.getOrUndefined(Option$1.filter(Option$1.fromUndefinedOr(tests), (present) => present.length > 0));
|
|
18372
18652
|
const staticCoverageCountOf = (staticCoverage, mutantId) => Option$1.getOrElse(Option$1.flatMap(Option$1.fromNullishOr(staticCoverage), (countsByMutantId) => Record$1.get(countsByMutantId, mutantId)), () => 0);
|
|
18373
18653
|
const hasCoverageForPlan = (staticCoverage) => Option$1.isSome(Option$1.fromUndefinedOr(staticCoverage));
|
|
18374
18654
|
const mutantIsStatic = (command, mutantId) => staticCoverageCountOf(command.staticCoverage, mutantId) > 0;
|
|
@@ -18454,10 +18734,13 @@ const orderedTestsOf = (command, mutantId, tests) => {
|
|
|
18454
18734
|
onSome: (present) => [present, ...rest]
|
|
18455
18735
|
});
|
|
18456
18736
|
};
|
|
18457
|
-
const runWithCoveredTests = (mutant, command, isStatic, tests, coveredBy) => toRunPlan(mutant, command, calculateTotalTimeForIds(tests, command.testTimeById), orderedTestsOf(command, mutant.id, tests), isStatic, coveredBy);
|
|
18737
|
+
const runWithCoveredTests = (mutant, command, isStatic, tests, coveredBy) => toRunPlan(mutant, command, calculateTotalTimeForIds(tests, command.testTimeById), nonEmptyTestFilterOf(orderedTestsOf(command, mutant.id, tests)), isStatic, coveredBy);
|
|
18738
|
+
const NO_COVERAGE_NET_TIME_MS = 0;
|
|
18739
|
+
const NO_COVERAGE_TEST_FILTER = [];
|
|
18740
|
+
const toNoCoverageRunPlan = (mutant, command, isStatic, coveredBy) => toRunPlan(mutant, command, NO_COVERAGE_NET_TIME_MS, NO_COVERAGE_TEST_FILTER, isStatic, coveredBy);
|
|
18458
18741
|
const planForUncoveredStatic = (mutant, command, isStatic, coveredBy) => Boolean$1$1.match(command.options.ignoreStatic, {
|
|
18459
18742
|
onTrue: () => Result.succeed(toEarlyResultPlan(mutant, isStatic, "Ignored", IGNORED_STATIC_MUTANT_REASON, coveredBy)),
|
|
18460
|
-
onFalse: () => toRunPlan(mutant, command, command.timeSpentAllTests, command.globalTestFilter, isStatic, coveredBy)
|
|
18743
|
+
onFalse: () => toRunPlan(mutant, command, command.timeSpentAllTests, nonEmptyTestFilterOf(command.globalTestFilter), isStatic, coveredBy)
|
|
18461
18744
|
});
|
|
18462
18745
|
const planForStaticallyCovered = (mutant, command, isStatic) => {
|
|
18463
18746
|
const tests = Option$1.getOrElse(Record$1.get(command.testsByMutantId, mutant.id), () => []);
|
|
@@ -18486,10 +18769,10 @@ const decidePlanForMutant = (mutant, command) => {
|
|
|
18486
18769
|
return Option$1.match(Option$1.fromUndefinedOr(mutant.status), {
|
|
18487
18770
|
onSome: (status) => Result.succeed(toEarlyResultPlan(mutant, isStatic, status, mutant.statusReason, coveredByOfMutant(mutant))),
|
|
18488
18771
|
onNone: () => Boolean$1$1.match(isPerTestUncoveredNonStatic(command, mutant, isStatic), {
|
|
18489
|
-
onTrue: () =>
|
|
18772
|
+
onTrue: () => toNoCoverageRunPlan(mutant, command, isStatic, coveringTestIdsOf(command, mutant.id)),
|
|
18490
18773
|
onFalse: () => Boolean$1$1.match(hasCoverageForPlan(command.staticCoverage), {
|
|
18491
18774
|
onTrue: () => planForStaticallyCovered(mutant, command, isStatic),
|
|
18492
|
-
onFalse: () => toRunPlan(mutant, command, command.timeSpentAllTests, command.globalTestFilter, void 0, void 0)
|
|
18775
|
+
onFalse: () => toRunPlan(mutant, command, command.timeSpentAllTests, nonEmptyTestFilterOf(command.globalTestFilter), void 0, void 0)
|
|
18493
18776
|
})
|
|
18494
18777
|
})
|
|
18495
18778
|
});
|
|
@@ -18781,7 +19064,10 @@ const planMutationTest = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationTestPlan
|
|
|
18781
19064
|
}))
|
|
18782
19065
|
})).pipe(Effect$1.ignoreCause);
|
|
18783
19066
|
const progressQueue = yield* RunEvents;
|
|
18784
|
-
yield* Queue.offer(progressQueue, RunEvent_exports.PlanKnown.make({
|
|
19067
|
+
yield* Queue.offer(progressQueue, RunEvent_exports.PlanKnown.make({
|
|
19068
|
+
total: plansForReporter.length + earlyResults.length,
|
|
19069
|
+
shardPlan: null
|
|
19070
|
+
}));
|
|
18785
19071
|
return {
|
|
18786
19072
|
runPlans: sortedPlans,
|
|
18787
19073
|
earlyResults,
|
|
@@ -18804,8 +19090,10 @@ const testRunnerWorkerSpawnOf = (loaded, configured) => Effect$1.mapError(Effect
|
|
|
18804
19090
|
cause: PluginNotFoundError.make({ descriptor: missing.descriptor })
|
|
18805
19091
|
}));
|
|
18806
19092
|
const acquire = Effect$1.fnUntraced(function* (spec) {
|
|
18807
|
-
|
|
18808
|
-
|
|
19093
|
+
const reports = yield* WorkerReports;
|
|
19094
|
+
const acquireOne = Effect$1.gen(function* () {
|
|
19095
|
+
const startedAt = yield* Clock.currentTimeMillis;
|
|
19096
|
+
const runner = yield* buildTestRunner({
|
|
18809
19097
|
options: spec.options,
|
|
18810
19098
|
fileDescriptions: spec.fileDescriptions,
|
|
18811
19099
|
sandboxWorkingDirectory: spec.sandboxWorkingDirectory,
|
|
@@ -18818,7 +19106,12 @@ const acquire = Effect$1.fnUntraced(function* (spec) {
|
|
|
18818
19106
|
sandboxWorkingDirectory: spec.sandboxWorkingDirectory,
|
|
18819
19107
|
workerEntrypoint: resolved.entrypoint,
|
|
18820
19108
|
idGenerator: spec.idGenerator
|
|
18821
|
-
})))))
|
|
19109
|
+
})))));
|
|
19110
|
+
yield* reports.report("testRunner", (yield* Clock.currentTimeMillis) - startedAt);
|
|
19111
|
+
return runner;
|
|
19112
|
+
});
|
|
19113
|
+
return yield* Pool.makeWithTTL({
|
|
19114
|
+
acquire: acquireOne,
|
|
18822
19115
|
min: spec.min,
|
|
18823
19116
|
max: spec.max,
|
|
18824
19117
|
timeToLive: IDLE_TIME_TO_LIVE
|
|
@@ -18831,6 +19124,9 @@ const TestRunnerPools = Blueprint.make()(TypeId).steps({
|
|
|
18831
19124
|
const scoped = (spec) => TestRunnerPools.of(spec).scoped;
|
|
18832
19125
|
//#endregion
|
|
18833
19126
|
//#region src/run/mutation-test.cell.ts
|
|
19127
|
+
const TCE_EQUIVALENT_TO_ORIGINAL_REASON = "equivalent-to-original: tce";
|
|
19128
|
+
const TCE_DUPLICATE_AT_SITE_REASON = "duplicate-at-site: tce";
|
|
19129
|
+
const countIgnoredByReason = (results, reason) => results.filter((result) => result.status === "Ignored" && result.statusReason === reason).length;
|
|
18834
19130
|
const writeMutationTestNoTests = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationTestNoTests.name)(function* () {
|
|
18835
19131
|
const env = yield* RunEnvironment;
|
|
18836
19132
|
const now = yield* Clock.currentTimeMillis;
|
|
@@ -18934,22 +19230,26 @@ const proceedPipeline = Effect$1.fnUntraced(function* (raw) {
|
|
|
18934
19230
|
});
|
|
18935
19231
|
const runResults = yield* Effect$1.scoped(Effect$1.gen(function* () {
|
|
18936
19232
|
const checkpoint = yield* makeCheckpointWriter(context, settledResults);
|
|
19233
|
+
const settleReported = (reported) => Effect$1.gen(function* () {
|
|
19234
|
+
yield* announceSettledMutant(context, reported);
|
|
19235
|
+
yield* checkpoint.record(reported);
|
|
19236
|
+
return reported;
|
|
19237
|
+
});
|
|
18937
19238
|
return yield* withPhaseSpan(SpanTaxonomy_exports.Spans.mutationTestBatch, {
|
|
18938
19239
|
total: plan.plannedTotal,
|
|
18939
19240
|
testRunners: prev.concurrency.testRunners
|
|
18940
19241
|
}, () => runCheckedPlans(checkedPlans, {
|
|
18941
|
-
settleFailure: (mutantPlan, result) => Effect$1.
|
|
18942
|
-
|
|
18943
|
-
|
|
18944
|
-
|
|
18945
|
-
|
|
19242
|
+
settleFailure: (mutantPlan, result) => reporting.reportCheckFailure(toReportedMutant(mutantPlan.mutant), result).pipe(Effect$1.flatMap(settleReported)),
|
|
19243
|
+
settleIgnored: (mutantPlan, result) => reporting.reportIgnored(toReportedMutant(mutantPlan.mutant), result).pipe(Effect$1.flatMap(settleReported)),
|
|
19244
|
+
runPlan: (runPlan) => Option$1.match(Option$1.liftPredicate(runPlan, isNoCoveragePlan), {
|
|
19245
|
+
onNone: () => Effect$1.scoped(mutantRunCell.run({
|
|
19246
|
+
context,
|
|
19247
|
+
testRunnerPool,
|
|
19248
|
+
checkpoint,
|
|
19249
|
+
plan: runPlan
|
|
19250
|
+
})),
|
|
19251
|
+
onSome: (noCoverageRunPlan) => reporting.reportNoCoverage(toReportedMutant(noCoverageRunPlan.mutant)).pipe(Effect$1.flatMap(settleReported))
|
|
18946
19252
|
}),
|
|
18947
|
-
runPlan: (runPlan) => Effect$1.scoped(mutantRunCell.run({
|
|
18948
|
-
context,
|
|
18949
|
-
testRunnerPool,
|
|
18950
|
-
checkpoint,
|
|
18951
|
-
plan: runPlan
|
|
18952
|
-
})),
|
|
18953
19253
|
concurrency: testRunnerCapacity
|
|
18954
19254
|
}).pipe(Stream.runFold(() => [], (acc, result) => {
|
|
18955
19255
|
acc.push(result);
|
|
@@ -18965,6 +19265,10 @@ const proceedPipeline = Effect$1.fnUntraced(function* (raw) {
|
|
|
18965
19265
|
requested: requestedIdsOf(prev.options),
|
|
18966
19266
|
results: allResults
|
|
18967
19267
|
}), (detail) => Queue.offer(progressQueue, detail), { discard: true });
|
|
19268
|
+
yield* Queue.offer(progressQueue, RunEvent_exports.TceReported.make({
|
|
19269
|
+
equivalentToOriginal: countIgnoredByReason(allResults, TCE_EQUIVALENT_TO_ORIGINAL_REASON),
|
|
19270
|
+
duplicateAtSite: countIgnoredByReason(allResults, TCE_DUPLICATE_AT_SITE_REASON)
|
|
19271
|
+
}));
|
|
18968
19272
|
const outcomeResult = yield* reporting.reportAll({
|
|
18969
19273
|
...reportingInputOf({
|
|
18970
19274
|
prev,
|
|
@@ -20055,12 +20359,12 @@ const prepareCell = Sandwich.named(SpanTaxonomy_exports.Spans.prepare.name)(read
|
|
|
20055
20359
|
});
|
|
20056
20360
|
//#endregion
|
|
20057
20361
|
//#region src/run/run-stages.cell.ts
|
|
20058
|
-
const configReadReasonOf = (cause) =>
|
|
20059
|
-
const mutationTestCell = Cell.andThen(Cell.andThen(Cell.andThen(Cell.mapError(loadConfigCell, (cause) => StageError.make({
|
|
20362
|
+
const configReadReasonOf = (cause) => cause.message;
|
|
20363
|
+
const mutationTestCell = Cell.andThen(Cell.andThen(Cell.andThen(Cell.andThen(Cell.mapError(loadConfigCell, (cause) => StageError.make({
|
|
20060
20364
|
stage: "prepare",
|
|
20061
20365
|
reason: configReadReasonOf(cause),
|
|
20062
20366
|
cause
|
|
20063
|
-
})), Cell.mapError(readProjectCell, (cause) => StageError.make({
|
|
20367
|
+
})), (loaded) => refuseLocalMutationCell(loaded)), Cell.mapError(readProjectCell, (cause) => StageError.make({
|
|
20064
20368
|
stage: "prepare",
|
|
20065
20369
|
reason: "Failed to read project",
|
|
20066
20370
|
cause
|
|
@@ -20203,7 +20507,7 @@ S.Struct({
|
|
|
20203
20507
|
mode: OutputMode_exports.OutputMode,
|
|
20204
20508
|
signal: OutputMode_exports.ModeSignal
|
|
20205
20509
|
});
|
|
20206
|
-
const nextFramingState = (state, event) => Match$1.value(event).pipe(Match$1.tag("verdict", "error", "help", () => FramingState.make({
|
|
20510
|
+
const nextFramingState = (state, event) => Match$1.value(event).pipe(Match$1.tag("verdict", "error", "help", "refused", () => FramingState.make({
|
|
20207
20511
|
mode: state.mode,
|
|
20208
20512
|
signal: state.signal,
|
|
20209
20513
|
headerWritten: state.headerWritten,
|
|
@@ -20224,7 +20528,7 @@ const nextFramingState = (state, event) => Match$1.value(event).pipe(Match$1.tag
|
|
|
20224
20528
|
terminalSeen: state.terminalSeen,
|
|
20225
20529
|
completed: e.completed,
|
|
20226
20530
|
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);
|
|
20531
|
+
})), 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
20532
|
const noteState = (state, event) => nextFramingState(state, event);
|
|
20229
20533
|
const formatScore = (score) => Option$1.match(Option$1.fromNullishOr(score), {
|
|
20230
20534
|
onNone: () => "n/a",
|
|
@@ -20234,7 +20538,7 @@ const formatTotal = (total) => Option$1.match(Option$1.fromNullishOr(total), {
|
|
|
20234
20538
|
onNone: () => "?",
|
|
20235
20539
|
onSome: (val) => String(val)
|
|
20236
20540
|
});
|
|
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);
|
|
20541
|
+
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
20542
|
const stderrLineFor = (state, event) => Boolean$1$1.match(Boolean$1$1.and(state.mode === "human", !state.terminalSeen), {
|
|
20239
20543
|
onTrue: () => formatStderrEvent(event),
|
|
20240
20544
|
onFalse: () => null
|
|
@@ -20398,16 +20702,17 @@ const CONFIG_CODE = 2;
|
|
|
20398
20702
|
const UNKNOWN_FAILURE = "Unknown failure";
|
|
20399
20703
|
const SIGNAL_REMEDIATION = "the run was interrupted by a signal; re-run it to continue";
|
|
20400
20704
|
const PARSE_REMEDIATION = "re-run with --help to see the full usage";
|
|
20705
|
+
const REFUSAL_REMEDIATION = "run mutation testing on main CI (GitHub Actions)";
|
|
20401
20706
|
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);
|
|
20707
|
+
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
20708
|
const nonEmptyText = Option$1.liftPredicate(S.is(S.NonEmptyString));
|
|
20404
20709
|
const capturedOrUnknown = (captured) => Option$1.getOrElse(nonEmptyText(captured), () => UNKNOWN_FAILURE);
|
|
20405
20710
|
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);
|
|
20711
|
+
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
20712
|
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
20713
|
onSome: (detail) => `check the config file: ${detail}`,
|
|
20409
20714
|
onNone: () => "check the config file"
|
|
20410
|
-
})), Match$1.tag("RunFailed", () => DEFAULT_REMEDIATION), Match$1.exhaustive);
|
|
20715
|
+
})), Match$1.tag("RunRefused", () => REFUSAL_REMEDIATION), Match$1.tag("RunFailed", () => DEFAULT_REMEDIATION), Match$1.exhaustive);
|
|
20411
20716
|
const errorEnvelopeFromOutcome = (input) => ErrorEnvelope.make({
|
|
20412
20717
|
schemaVersion: RunEvent_exports.StreamSchemaVersion.literal,
|
|
20413
20718
|
code: exitCodeOf(input.error),
|
|
@@ -20504,22 +20809,33 @@ const emitNullScoreVerdict = (params) => {
|
|
|
20504
20809
|
version: StrykerPackage.version
|
|
20505
20810
|
}
|
|
20506
20811
|
};
|
|
20507
|
-
|
|
20508
|
-
|
|
20509
|
-
|
|
20510
|
-
|
|
20511
|
-
|
|
20512
|
-
|
|
20513
|
-
|
|
20514
|
-
|
|
20515
|
-
|
|
20516
|
-
|
|
20517
|
-
|
|
20518
|
-
|
|
20519
|
-
|
|
20520
|
-
|
|
20521
|
-
|
|
20522
|
-
|
|
20812
|
+
return Effect$1.gen(function* () {
|
|
20813
|
+
const now = yield* Clock.currentTimeMillis;
|
|
20814
|
+
const envelope = buildVerdictEnvelope({
|
|
20815
|
+
...report,
|
|
20816
|
+
budget: {
|
|
20817
|
+
predictedSeconds: 0,
|
|
20818
|
+
actualSeconds: (now - stream.startedAt) / 1e3
|
|
20819
|
+
}
|
|
20820
|
+
}, mode.mode, mode.signal, stream.runId, basePath, pathService, Option$1.none(), null);
|
|
20821
|
+
yield* Queue.offer(stream.queue, RunEvent_exports.VerdictReached.make({
|
|
20822
|
+
schemaVersion: envelope.schemaVersion,
|
|
20823
|
+
runId: envelope.runId,
|
|
20824
|
+
mode: envelope.mode,
|
|
20825
|
+
signal: envelope.signal,
|
|
20826
|
+
score: envelope.score,
|
|
20827
|
+
thresholds: envelope.thresholds,
|
|
20828
|
+
reportFile: envelope.reportFile,
|
|
20829
|
+
counts: envelope.counts,
|
|
20830
|
+
mutants: envelope.mutants,
|
|
20831
|
+
scope: envelope.scope,
|
|
20832
|
+
mutantSetPolicy: envelope.mutantSetPolicy,
|
|
20833
|
+
incrementalMode: envelope.incrementalMode,
|
|
20834
|
+
phaseDurations: envelope.phaseDurations,
|
|
20835
|
+
static: envelope.static,
|
|
20836
|
+
budget: envelope.budget
|
|
20837
|
+
}));
|
|
20838
|
+
});
|
|
20523
20839
|
};
|
|
20524
20840
|
const offerFailureEnvelope = (stream, failed, captured) => {
|
|
20525
20841
|
const envelope = errorEnvelopeFromOutcome({
|
|
@@ -20534,6 +20850,11 @@ const offerFailureEnvelope = (stream, failed, captured) => {
|
|
|
20534
20850
|
reason: null
|
|
20535
20851
|
}));
|
|
20536
20852
|
};
|
|
20853
|
+
const offerRefusedEnvelope = (stream, refused) => Queue.offer(stream.queue, RunEvent_exports.Refused.make({
|
|
20854
|
+
schemaVersion: RunEvent_exports.StreamSchemaVersion.literal,
|
|
20855
|
+
rule: refused.rule,
|
|
20856
|
+
message: refused.message
|
|
20857
|
+
}));
|
|
20537
20858
|
const emitHelpEnvelope = (stream, help) => Queue.offer(stream.queue, RunEvent_exports.HelpRendered.make({
|
|
20538
20859
|
schemaVersion: RunEvent_exports.StreamSchemaVersion.literal,
|
|
20539
20860
|
code: 0,
|
|
@@ -20565,7 +20886,7 @@ const emitMachineModeOutput = Effect$1.fn(SpanTaxonomy_exports.Spans.runEventStr
|
|
|
20565
20886
|
onSuccess: (decision) => Match$1.value(decision).pipe(Match$1.tag("RunOk", (ok) => Option$1.match(helpPayload(ok, captured), {
|
|
20566
20887
|
onSome: (help) => emitHelpEnvelope(stream, help),
|
|
20567
20888
|
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),
|
|
20889
|
+
})), 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
20890
|
onFailure: (failure) => offerFailureEnvelope(stream, failure, captured)
|
|
20570
20891
|
});
|
|
20571
20892
|
});
|