@systemfsoftware/stryker-js 23.0.1 → 23.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @systemfsoftware/stryker-js
2
2
 
3
+ ## 23.1.0
4
+
5
+ `stryker audit` reports an orphaned test with one of two reasons:
6
+
7
+ - `every-kill-held-by-a-kept-mutant`: every mutant the test kills is dropped, and every pair of those mutants is a contained Pass. The kept set therefore detects the same faults, and the orphan is reported without failing the audit.
8
+ - `every-killed-mutant-dropped`: anything else. It still fails the audit, and `failures.orphanedTests` counts only these.
9
+
3
10
  ## 23.0.1
4
11
 
5
12
  The workspace dogfoods @systemfsoftware/stryker-js 23.0.0 and the TypeScript checker 10.0.0, and every package resolves one @systemfsoftware/effect-cell-types (12.1.4). The TypeScript checker and the vitest runner bundle 12.1.4 in place of 12.0.0, and stryker-js and the checker bundle @jsr/std__jsonc 1.0.3 in place of 1.0.2. Every package that takes @systemfsoftware/effect-cell-types from the catalog publishes the range ^12.1.4 in place of ^12.0.0.
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
2
  import { i as Mutant_exports, l as Report_exports, n as mergeConfigs } from "./merge-config-BWQeU3-p.mjs";
3
- import { $ as IncrementalReportSchema, $t as checkCell, A as optionalField, At as ExtendsStepDone, B as nodePlatformLayer, Bt as createDefaultOptions, C as offerSkipsIfAny, Ct as WorkerLauncher, D as dryRunChoiceOf, Dt as importModule, E as reusedTestCoverage, Et as decideExtendsStep, F as diffScopeDecisionOf, Ft as ConfigError, G as git_diff_service_exports, Gt as ImportedModuleSchema, H as SourceParser, Ht as ConfigDocumentSchema, I as DryRunCoverageReused, It as ConfigFileInvalidError, J as git_diff_schema_exports, Jt as ReadConfigCommand, K as ChangedSince, Kt as MergeCommand, L as scoped$1, Lt as ConfigFileNotFoundError, M as relativeNormalizedFileName, Mt as ExtendsStepRefused, N as requireDryRun, Nt as ExtendsStepResolve, O as requireDryRunCommandOf, Ot as initialExtendsStepState, P as readProjectCell, Pt as FileMatcher, Q as classifyWorkerExit, Qt as groupCell, R as makeCheckerPoolHandle, Rt as ConfigFileUnreadableError, S as instrumentFiles, St as makeWorkerClient, T as readIncrementalReuse, Tt as ReproducerSchema, U as source_parser_service_exports, Ut as ExtendsStepDocumentSchema, V as layerWorkerProtocol, Vt as defaultOptions, W as GitDiff, Wt as ExtendsStepStateSchema, X as ClassifyWorkerExitCommand, Xt as forkOptionsSchema, Y as EmptyDirectory, Yt as extendsPropertySchema, Z as ClassifyWorkerExitDecision, Zt as survivorsPriorReport, _ as testRunnerConfigOf, _t as metricsResultFromFiles, a as HtmlReporter_exports, an as ShardPlan, at as RunEnvironment, b as planPrepare, bt as spawnReporterWorker, c as instrumentCell, cn as SpanTaxonomy_exports, ct as SurfacingFields, d as isCommandRunner, dn as CheckerSkippedRequested, dt as RunEvents, en as ChildProcessCrashedError, et as validateOptions, f as mutantDetailEventsOf, ft as RunIdentity, g as isVmRunner, gt as staticVerdictOf, h as readPrepare, ht as VerdictEnvelope, i as MachineConsole, in as RunEvent_exports$1, it as readConfig, j as import_closure_cell_exports, jt as ExtendsStepRead, k as incrementalReportTextsOf, kt as StrykerError, l as buildTestRunner, ln as CheckerAnsweredUnrequested, lt as SurvivorRef, m as admitPreparedProject, mt as generateRunId, n as RunEventDrain, nn as WorkerBootTimeoutError, nt as describeErrors, o as mutationTestCell, on as ShardPlanVersion, ot as IdGenerator, p as concurrencyCell, pt as buildVerdictEnvelope, q as WholeProject, qt as MergeResult, r as makeRunEventStream, rn as OutputMode_exports, rt as forkCoreSchema, s as prepareCell, sn as ShardProject, st as surfacedSurvivorsOf, t as strykerCell, tn as OutOfMemoryError, tt as loadConfigCell, u as makeChildProcessTestRunner, un as CheckerIgnoredWithoutRule, ut as StrykerPackage, v as vmRunnerPluginUrl, vt as MetricsResultFromReport, w as planInstrumentation, wt as make, x as enteringInstrumentPhase, xt as withPhaseSpan, y as vmTestRunnerConfig, yt as reporterWorkerFactory, z as programDigestOf, zt as ConfigFileUnsupportedError } from "./run-stages-CNIjqDP3.mjs";
3
+ import { $ as IncrementalReportSchema, $t as checkCell, A as optionalField, At as ExtendsStepDone, B as nodePlatformLayer, Bt as createDefaultOptions, C as offerSkipsIfAny, Ct as WorkerLauncher, D as dryRunChoiceOf, Dt as importModule, E as reusedTestCoverage, Et as decideExtendsStep, F as diffScopeDecisionOf, Ft as ConfigError, G as git_diff_service_exports, Gt as ImportedModuleSchema, H as SourceParser, Ht as ConfigDocumentSchema, I as DryRunCoverageReused, It as ConfigFileInvalidError, J as git_diff_schema_exports, Jt as ReadConfigCommand, K as ChangedSince, Kt as MergeCommand, L as scoped$1, Lt as ConfigFileNotFoundError, M as relativeNormalizedFileName, Mt as ExtendsStepRefused, N as requireDryRun, Nt as ExtendsStepResolve, O as requireDryRunCommandOf, Ot as initialExtendsStepState, P as readProjectCell, Pt as FileMatcher, Q as classifyWorkerExit, Qt as groupCell, R as makeCheckerPoolHandle, Rt as ConfigFileUnreadableError, S as instrumentFiles, St as makeWorkerClient, T as readIncrementalReuse, Tt as ReproducerSchema, U as source_parser_service_exports, Ut as ExtendsStepDocumentSchema, V as layerWorkerProtocol, Vt as defaultOptions, W as GitDiff, Wt as ExtendsStepStateSchema, X as ClassifyWorkerExitCommand, Xt as forkOptionsSchema, Y as EmptyDirectory, Yt as extendsPropertySchema, Z as ClassifyWorkerExitDecision, Zt as survivorsPriorReport, _ as testRunnerConfigOf, _t as metricsResultFromFiles, a as HtmlReporter_exports, an as ShardPlan, at as RunEnvironment, b as planPrepare, bt as spawnReporterWorker, c as instrumentCell, cn as SpanTaxonomy_exports, ct as SurfacingFields, d as isCommandRunner, dn as CheckerSkippedRequested, dt as RunEvents, en as ChildProcessCrashedError, et as validateOptions, f as mutantDetailEventsOf, ft as RunIdentity, g as isVmRunner, gt as staticVerdictOf, h as readPrepare, ht as VerdictEnvelope, i as MachineConsole, in as RunEvent_exports$1, it as readConfig, j as import_closure_cell_exports, jt as ExtendsStepRead, k as incrementalReportTextsOf, kt as StrykerError, l as buildTestRunner, ln as CheckerAnsweredUnrequested, lt as SurvivorRef, m as admitPreparedProject, mt as generateRunId, n as RunEventDrain, nn as WorkerBootTimeoutError, nt as describeErrors, o as mutationTestCell, on as ShardPlanVersion, ot as IdGenerator, p as concurrencyCell, pt as buildVerdictEnvelope, q as WholeProject, qt as MergeResult, r as makeRunEventStream, rn as OutputMode_exports, rt as forkCoreSchema, s as prepareCell, sn as ShardProject, st as surfacedSurvivorsOf, t as strykerCell, tn as OutOfMemoryError, tt as loadConfigCell, u as makeChildProcessTestRunner, un as CheckerIgnoredWithoutRule, ut as StrykerPackage, v as vmRunnerPluginUrl, vt as MetricsResultFromReport, w as planInstrumentation, wt as make, x as enteringInstrumentPhase, xt as withPhaseSpan, y as vmTestRunnerConfig, yt as reporterWorkerFactory, z as programDigestOf, zt as ConfigFileUnsupportedError } from "./run-stages-CMs0dSA_.mjs";
4
4
  import { n as StageError } from "./Run.schema-DuaneDGd.mjs";
5
5
  import { Blueprint, Cell, Handle, Sandwich, Workflow } from "@systemfsoftware/effect-cell-types";
6
6
  import * as S from "effect/Schema";
package/dist/main.mjs CHANGED
@@ -82762,7 +82762,7 @@ const makeHtmlReporter = dual(2, (options, _init) => (events) => build(nodeFsPat
82762
82762
  var HtmlReporter_exports = /* @__PURE__ */ __exportAll$3({ makeHtmlReporter: () => makeHtmlReporter });
82763
82763
  //#endregion
82764
82764
  //#region package.json
82765
- var version = "23.0.1";
82765
+ var version = "23.1.0";
82766
82766
  //#endregion
82767
82767
  //#region ../../node_modules/.pnpm/effect@4.1.2/node_modules/effect/dist/cli/internal/ansi.js
82768
82768
  /**
@@ -108994,7 +108994,13 @@ const OrphanedTest = Struct({
108994
108994
  project: String$7,
108995
108995
  test: String$7,
108996
108996
  killed: NonEmptyArray(String$7),
108997
- reason: Literal("every-killed-mutant-dropped"),
108997
+ /**
108998
+ * `every-killed-mutant-dropped`: some mutant the test kills has a pair that is not a contained Pass, so the drop
108999
+ * may lose a fault the full set detects; this fails the audit. `every-kill-held-by-a-kept-mutant`: every mutant the
109000
+ * test kills is dropped for kept mutants whose every killer also kills it, so the kept set detects the same faults
109001
+ * and the test only stops adding to the score; this is reported and does not fail the audit.
109002
+ */
109003
+ reason: Literals$3(["every-killed-mutant-dropped", "every-kill-held-by-a-kept-mutant"]),
108998
109004
  next: String$7
108999
109005
  });
109000
109006
  const DropAuditFields = {
@@ -109153,7 +109159,10 @@ const NEXT_ACTION = {
109153
109159
  "status-unsettled": `The kill matrix holds the pair as Pending. ${RERUN_MATRIX}`
109154
109160
  };
109155
109161
  const UNATTESTED_NEXT = `No drop of this rule joined the kill matrix, so nothing checks it. ${RERUN_MATRIX} Do not ship the rule until a pair joins.`;
109156
- const ORPHANED_NEXT = `Signal lost: this test kills only dropped mutants, so it kills nothing once they are dropped. ${FIX_THE_RULE}`;
109162
+ const ORPHAN_NEXT = {
109163
+ "every-killed-mutant-dropped": `Signal lost: this test kills only dropped mutants, and some of them are not held by a kept mutant whose killers they share. ${FIX_THE_RULE}`,
109164
+ "every-kill-held-by-a-kept-mutant": "No signal lost: every mutant this test kills is dropped for a kept mutant whose every killer also kills it, so the kept set detects the same faults. The test no longer adds to the score; keep it as a specification, or extend it to kill the kept mutant."
109165
+ };
109157
109166
  const EMPTY_INDEX = {
109158
109167
  mutants: {},
109159
109168
  tests: {}
@@ -109290,20 +109299,40 @@ const isUnattested = (rule) => valueTags(rule, {
109290
109299
  Attested: () => false,
109291
109300
  Unattested: () => true
109292
109301
  });
109293
- const orphansOf = (project, index, dropped) => {
109302
+ const isContainmentVerdict = (verdict) => valueTags(verdict, {
109303
+ Pass: (passed) => passed.reason === "killers-contained",
109304
+ Vacuous: () => false,
109305
+ AttributionUnverified: () => false,
109306
+ Fail: () => false
109307
+ });
109308
+ const isContainedPass = (pair) => valueTags(pair, {
109309
+ UnjoinablePair: () => false,
109310
+ JoinedPair: (joined) => isContainmentVerdict(joined.verdict)
109311
+ });
109312
+ /** The dropped mutants of a project whose every pair is a contained Pass: a kept mutant holds each of their kills. */
109313
+ const heldOf = (pairs) => lookupOf(Object.entries(groupBy(pairs, (pair) => pair.mutant)).filter(([, mutantPairs]) => mutantPairs.every(isContainedPass)).map(([mutant]) => mutant));
109314
+ const orphanReasonOf = (killed, held) => match$1(killed.every((mutant) => has$6(held, mutant)), {
109315
+ onTrue: () => "every-kill-held-by-a-kept-mutant",
109316
+ onFalse: () => "every-killed-mutant-dropped"
109317
+ });
109318
+ const orphansOf = (project, index, dropped, held) => {
109294
109319
  const droppedIds = lookupOf(dropped.map((drop) => drop.mutant));
109295
109320
  const kills = project.mutants.filter((mutant) => mutant.status === "Killed").flatMap((mutant) => mutant.killedBy.map((test) => ({
109296
109321
  test,
109297
109322
  mutant: mutant.id
109298
109323
  }))).filter((kill) => has$6(index.tests, kill.test));
109299
109324
  return Object.entries(groupBy(kills, (kill) => kill.test)).flatMap(([test, killedBy]) => match$1(killedBy.every((kill) => has$6(droppedIds, kill.mutant)), {
109300
- onTrue: () => [{
109301
- project: project.project,
109302
- test,
109303
- killed: map$10(killedBy, (kill) => kill.mutant),
109304
- reason: "every-killed-mutant-dropped",
109305
- next: ORPHANED_NEXT
109306
- }],
109325
+ onTrue: () => {
109326
+ const killed = map$10(killedBy, (kill) => kill.mutant);
109327
+ const reason = orphanReasonOf(killed, held);
109328
+ return [{
109329
+ project: project.project,
109330
+ test,
109331
+ killed,
109332
+ reason,
109333
+ next: ORPHAN_NEXT[reason]
109334
+ }];
109335
+ },
109307
109336
  onFalse: () => []
109308
109337
  }));
109309
109338
  };
@@ -109318,7 +109347,8 @@ const decide$36 = (command) => {
109318
109347
  const rule = headNonEmpty(drops).subsumed.rule;
109319
109348
  return ruleSummaryOf(rule, drops.length, getOrElse$1(fromUndefinedOr(pairsByRule[rule]), () => []));
109320
109349
  }), mapInput$2(String$11, (rule) => rule.rule));
109321
- const orphanedTests = sort(command.matrix.flatMap((project) => orphansOf(project, getOrElse$1(get$12(indexes, project.project), () => EMPTY_INDEX), dropsOf(project))), orphanOrder);
109350
+ const pairsByProject = groupBy(pairs, (pair) => pair.project);
109351
+ const orphanedTests = sort(command.matrix.flatMap((project) => orphansOf(project, getOrElse$1(get$12(indexes, project.project), () => EMPTY_INDEX), dropsOf(project), heldOf(getOrElse$1(get$12(pairsByProject, project.project), () => [])))), orphanOrder);
109322
109352
  const fields = {
109323
109353
  schemaVersion: "1",
109324
109354
  scope: command.scope,
@@ -109334,7 +109364,7 @@ const decide$36 = (command) => {
109334
109364
  const failures = {
109335
109365
  pairs: tallyCountsOf(pairs).fail,
109336
109366
  unattestedRules: rules.filter(isUnattested).length,
109337
- orphanedTests: orphanedTests.length
109367
+ orphanedTests: orphanedTests.filter((orphan) => orphan.reason === "every-killed-mutant-dropped").length
109338
109368
  };
109339
109369
  return match$1(failures.pairs + failures.unattestedRules + failures.orphanedTests === 0, {
109340
109370
  onTrue: () => DropAuditPassed.make(fields),
package/dist/promises.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { B as nodePlatformLayer, t as strykerCell } from "./run-stages-CNIjqDP3.mjs";
1
+ import { B as nodePlatformLayer, t as strykerCell } from "./run-stages-CMs0dSA_.mjs";
2
2
  import * as Effect from "effect/Effect";
3
3
  import { dual } from "effect/Function";
4
4
  //#region src/promises/run.ts
@@ -12200,7 +12200,7 @@ const strykerOutputFilesOf = (options) => STRYKER_OUTPUTS.map((output) => output
12200
12200
  STRYKER_OUTPUTS.map((output) => output.label);
12201
12201
  //#endregion
12202
12202
  //#region package.json
12203
- var version = "23.0.1";
12203
+ var version = "23.1.0";
12204
12204
  //#endregion
12205
12205
  //#region src/stryker-package.schema.ts
12206
12206
  var StrykerPackage = class extends S.Class("StrykerPackage")({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@systemfsoftware/stryker-js",
3
- "version": "23.0.1",
3
+ "version": "23.1.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/systemfsoftware/stryker-js-effect.git",