@systemfsoftware/stryker-js 2.0.0 → 3.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/{Checker-DYgIIEai.d.mts → Checker-A8o5B3Ub.d.mts} +1 -1
  3. package/dist/Checker.d.mts +1 -1
  4. package/dist/{Evaluator-RZBS4oeh.d.mts → Evaluator-CnAN8-pZ.d.mts} +2 -2
  5. package/dist/Evaluator.d.mts +1 -1
  6. package/dist/ExitClass.d.mts +1 -1
  7. package/dist/ExitClass.mjs +20 -31
  8. package/dist/Metrics.d.mts +7 -0
  9. package/dist/Metrics.mjs +79 -0
  10. package/dist/Metrics.schema-BaVd6rXs.d.mts +50 -0
  11. package/dist/Metrics.schema-DZdoc46X.mjs +27 -0
  12. package/dist/{Mutant-BPRJTF8f.d.mts → Mutant-Ci25PsWA.d.mts} +6 -6
  13. package/dist/Mutant.d.mts +3 -2
  14. package/dist/Mutant.mjs +54 -78
  15. package/dist/{Mutant.schema-BTWhFTk4.mjs → Mutant.schema-H3r0ho_R.mjs} +3 -3
  16. package/dist/{Plugin-DcDAIBQi.d.mts → Plugin-BtItMchw.d.mts} +31 -13
  17. package/dist/Plugin-DXFdJP1l.mjs +105 -0
  18. package/dist/Plugin.d.mts +2 -2
  19. package/dist/Plugin.mjs +2 -2
  20. package/dist/Report.d.mts +2 -0
  21. package/dist/Report.mjs +98 -0
  22. package/dist/Report.schema-_buHXdnZ.d.mts +251 -0
  23. package/dist/Reporter-BWTwlSJf.mjs +25 -0
  24. package/dist/Reporter-C7ysGxqX.d.mts +16 -0
  25. package/dist/Reporter.d.mts +4 -2
  26. package/dist/Reporter.mjs +3 -2
  27. package/dist/ReporterEvent.d.mts +2 -0
  28. package/dist/ReporterEvent.mjs +57 -0
  29. package/dist/ReporterEvent.schema-BhtyYCZo.d.mts +189 -0
  30. package/dist/{Run-BnmGGgWj.d.mts → Run-BUpNSmcM.d.mts} +82 -89
  31. package/dist/Run.d.mts +2 -2
  32. package/dist/Run.mjs +56 -2
  33. package/dist/Run.schema-DZve3k2m.mjs +138 -0
  34. package/dist/{Schema-CXKiLnTu.d.mts → Schema-4oCWQ0P0.d.mts} +63 -64
  35. package/dist/{Schema-CdNkubPi.mjs → Schema-CMKdWMUN.mjs} +55 -57
  36. package/dist/Schema.d.mts +1 -1
  37. package/dist/Schema.mjs +1 -1
  38. package/dist/TestRunner.d.mts +1 -1
  39. package/dist/TestRunner.mjs +57 -2
  40. package/dist/{TestRunner-DC9U8Unb.mjs → TestRunner.schema-Dy0Wdro2.mjs} +2 -64
  41. package/dist/index.d.mts +6 -6
  42. package/dist/index.mjs +5 -5
  43. package/dist/provided-options.d.mts +1 -1
  44. package/package.json +10 -7
  45. package/dist/Plugin-Ceh1G8Dz.mjs +0 -117
  46. package/dist/Reporter-COVWW1my.mjs +0 -33
  47. package/dist/Reporter-eZ3M7lO6.d.mts +0 -83
  48. package/dist/Run-BcDo-hIC.mjs +0 -199
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @systemfsoftware/stryker-js
2
2
 
3
+ ## 3.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies:
8
+ - @systemfsoftware/effect-cell-types@7.0.0
9
+
10
+ ## 3.0.0
11
+
12
+ ### Major Changes
13
+
14
+ - Reporter plugins are now pull-stream consumers: a reporter exports a factory
15
+ that returns an async consumer of the four run events, instead of registering
16
+ an Effect layer that provides the `Reporter` capability service.
17
+
18
+ - Removed: `ReporterService`, `broadcastReporter`, `NamedReporter`, the
19
+ `Reporter` service class, and the legacy event payload types.
20
+ - The event protocol ships as a Standard Schema object; validate and infer it
21
+ with `import { ReporterEventSchema, type ReporterFactory, type ReporterInit }
22
+ from '@systemfsoftware/stryker-js/ReporterEvent'`.
23
+ - Event payloads are narrowed: the dry-run event no longer carries the coverage
24
+ map; the plan event carries reduced mutant descriptors instead of full run
25
+ options; `mutantTested` drops `killedBy`, `coveredBy`, `static`,
26
+ `testsCompleted` and `statusReason`, and renames `mutatorName` to `mutator`.
27
+ - `ReporterFailed.event` now names the event kind being processed instead of a
28
+ lifecycle method name; `'wrapUp'` no longer occurs.
29
+ - An unknown reporter name now fails the run at startup instead of being
30
+ silently ignored. A reporter that fails on the terminal report now fails the
31
+ run; a reporter that fails earlier is logged and detached with the exit code
32
+ unchanged.
33
+ - `@systemfsoftware/stryker-js-engine/builtin-reporters` no longer exports
34
+ `strykerPlugins`; call `makeBuiltinReporterFactories({ fileSystem, path })`.
35
+ - The built-in json and clear-text reporters write their notices directly to
36
+ stdout and stderr instead of the Effect logger, and the html reporter no
37
+ longer depends on `@effect/platform-node`.
38
+
39
+ - Remove the --llms command manifest: the CLI no longer accepts --llms and the Run stream no longer carries a manifest terminal event.
40
+
3
41
  ## 2.0.0
4
42
 
5
43
  ### Major Changes
@@ -1,4 +1,4 @@
1
- import { _t as Mutant } from "./Mutant-BPRJTF8f.mjs";
1
+ import { gt as Mutant } from "./Mutant-Ci25PsWA.mjs";
2
2
  import * as Context from "effect/Context";
3
3
  import * as S from "effect/Schema";
4
4
  import * as Effect from "effect/Effect";
@@ -1,2 +1,2 @@
1
- import { a as FailedCheckResult, c as CheckStatus, l as CheckerFailed, n as Checker, o as PassedCheckResult, r as CheckerService, s as CheckResultSchema, t as CheckResult } from "./Checker-DYgIIEai.mjs";
1
+ import { a as FailedCheckResult, c as CheckStatus, l as CheckerFailed, n as Checker, o as PassedCheckResult, r as CheckerService, s as CheckResultSchema, t as CheckResult } from "./Checker-A8o5B3Ub.mjs";
2
2
  export { CheckResult, CheckResultSchema, CheckStatus, Checker, CheckerFailed, CheckerService, FailedCheckResult, PassedCheckResult };
@@ -1,7 +1,7 @@
1
+ import { _ as MutationTestResult } from "./Report.schema-_buHXdnZ.mjs";
1
2
  import { r as ExitClass } from "./ExitClass.schema-BmOIK5zT.mjs";
2
3
  import * as Context from "effect/Context";
3
4
  import * as S from "effect/Schema";
4
- import * as schema from "mutation-testing-report-schema/api";
5
5
  import * as Effect from "effect/Effect";
6
6
  //#region src/Evaluator.schema.d.ts
7
7
  declare const EvaluatorFailed_base: S.Class<EvaluatorFailed, S.TaggedStruct<"EvaluatorFailed", {
@@ -11,7 +11,7 @@ declare class EvaluatorFailed extends EvaluatorFailed_base {}
11
11
  //#endregion
12
12
  //#region src/Evaluator.d.ts
13
13
  interface EvaluatorService {
14
- readonly evaluate: (report: schema.MutationTestResult) => Effect.Effect<ExitClass | null, EvaluatorFailed>;
14
+ readonly evaluate: (report: MutationTestResult) => Effect.Effect<ExitClass | null, EvaluatorFailed>;
15
15
  }
16
16
  declare const Evaluator_base: Context.ServiceClass<Evaluator, "~@systemfsoftware/stryker-js/Evaluator", EvaluatorService>;
17
17
  declare class Evaluator extends Evaluator_base {}
@@ -1,3 +1,3 @@
1
- import { n as EvaluatorService, r as EvaluatorFailed, t as Evaluator } from "./Evaluator-RZBS4oeh.mjs";
1
+ import { n as EvaluatorService, r as EvaluatorFailed, t as Evaluator } from "./Evaluator-CnAN8-pZ.mjs";
2
2
  import { r as ExitClass } from "./ExitClass.schema-BmOIK5zT.mjs";
3
3
  export { Evaluator, EvaluatorFailed, EvaluatorService, type ExitClass };
@@ -1,9 +1,9 @@
1
1
  import { n as ClassifyExitDecision, r as ExitClass, t as ClassifyExitCommand } from "./ExitClass.schema-BmOIK5zT.mjs";
2
2
  //#region src/ExitClass.d.ts
3
3
  declare const EXIT_CODE: Record<ExitClass, number>;
4
- declare function verdictExitClass(score: number | null, breakingThreshold: number | null): ExitClass | null;
5
4
  declare function highestExitClass(pending: Iterable<ExitClass>): ExitClass | null;
6
5
  declare function resolveExitCode(pending: Iterable<ExitClass>, signal: number | null): number;
6
+ declare function verdictExitClass(score: number | null, breakingThreshold: number | null): ExitClass | null;
7
7
  declare const classifyExit: (command: ClassifyExitCommand) => ClassifyExitDecision;
8
8
  //#endregion
9
9
  export { EXIT_CODE, ExitClass, classifyExit, highestExitClass, resolveExitCode, verdictExitClass };
@@ -1,5 +1,6 @@
1
1
  import * as S from "effect/Schema";
2
2
  import * as Match from "effect/Match";
3
+ import * as Option from "effect/Option";
3
4
  //#region src/ExitClass.schema.ts
4
5
  const ExitClass = S.Literals([
5
6
  "VerdictFail",
@@ -25,42 +26,30 @@ const EXIT_CODE = {
25
26
  RuntimeError: 3,
26
27
  InternalError: 4
27
28
  };
28
- function verdictExitClass(score, breakingThreshold) {
29
- if (breakingThreshold === null || score === null) return null;
30
- if (score < breakingThreshold) return "VerdictFail";
31
- return null;
32
- }
33
29
  function highestExitClass(pending) {
34
- let highest = null;
35
- for (const exitClass of pending) if (highest === null || EXIT_CODE[exitClass] > EXIT_CODE[highest]) highest = exitClass;
36
- return highest;
30
+ return Array.from(pending).reduce((incumbent, challenger) => Option.match(Option.fromNullishOr(incumbent), {
31
+ onNone: () => challenger,
32
+ onSome: (value) => Match.value(EXIT_CODE[value] < EXIT_CODE[challenger]).pipe(Match.when(true, () => challenger), Match.when(false, () => value), Match.exhaustive)
33
+ }), null);
37
34
  }
38
35
  function resolveExitCode(pending, signal) {
39
- if (signal !== null) return 128 + signal;
40
- const highest = highestExitClass(pending);
41
- if (highest === null) return 0;
42
- return EXIT_CODE[highest];
36
+ return Option.match(Option.fromNullishOr(signal), {
37
+ onNone: () => Option.match(Option.fromNullishOr(highestExitClass(pending)), {
38
+ onNone: () => 0,
39
+ onSome: (exitClass) => EXIT_CODE[exitClass]
40
+ }),
41
+ onSome: (value) => 128 + value
42
+ });
43
+ }
44
+ function verdictExitClass(score, breakingThreshold) {
45
+ return Option.getOrNull(Option.zipWith(Option.fromNullishOr(score), Option.fromNullishOr(breakingThreshold), (value, threshold) => Match.value(value < threshold).pipe(Match.when(true, () => "VerdictFail"), Match.when(false, () => null), Match.exhaustive)));
43
46
  }
44
- const deriveVerdict = (score, breakingThreshold) => {
45
- if (score === null || breakingThreshold === null) return null;
46
- if (score < breakingThreshold) return "VerdictFail";
47
- return null;
48
- };
49
- const rank = (value) => Match.value(value).pipe(Match.when("InternalError", () => 4), Match.when("RuntimeError", () => 3), Match.when("ConfigError", () => 2), Match.when("VerdictFail", () => 1), Match.exhaustive);
50
- const withVerdict = (pending, verdict) => {
51
- if (verdict === null) return pending;
52
- if (pending.includes(verdict)) return pending;
53
- return [...pending, verdict];
54
- };
55
- const highestOf = (values) => values.reduce((acc, cur) => {
56
- if (acc === null) return cur;
57
- if (rank(cur) > rank(acc)) return cur;
58
- return acc;
59
- }, null);
60
47
  const classifyExit = (command) => {
61
- const verdictClass = deriveVerdict(command.score, command.breakingThreshold);
62
- const pendingWithVerdict = withVerdict(command.pending, verdictClass);
63
- const highestClass = highestOf(pendingWithVerdict);
48
+ const verdictClass = verdictExitClass(command.score, command.breakingThreshold);
49
+ const highestClass = highestExitClass(Option.match(Option.fromNullishOr(verdictClass), {
50
+ onNone: () => command.pending,
51
+ onSome: (verdict) => Array.from(/* @__PURE__ */ new Set([...command.pending, verdict]))
52
+ }));
64
53
  return ClassifyExitDecision.make({
65
54
  highestClass,
66
55
  verdictClass
@@ -0,0 +1,7 @@
1
+ import { a as FileResult, p as MutantResult } from "./Report.schema-_buHXdnZ.mjs";
2
+ import { i as MetricsSchema, n as MetricsResult, r as MetricsResultSchema, t as Metrics } from "./Metrics.schema-BaVd6rXs.mjs";
3
+ //#region src/Metrics.d.ts
4
+ declare const countMutants: (mutants: readonly MutantResult[]) => Metrics;
5
+ declare const calculateMetrics: (files: Readonly<Record<string, FileResult>>) => MetricsResult;
6
+ //#endregion
7
+ export { type Metrics, type MetricsResult, MetricsResultSchema, MetricsSchema, calculateMetrics, countMutants };
@@ -0,0 +1,79 @@
1
+ import { n as MetricsSchema, t as MetricsResultSchema } from "./Metrics.schema-DZdoc46X.mjs";
2
+ import * as Match from "effect/Match";
3
+ import * as Option from "effect/Option";
4
+ import * as Arr from "effect/Array";
5
+ //#region src/Metrics.ts
6
+ const countStatus = (mutants, status) => mutants.filter((mutant) => mutant.status === status).length;
7
+ const percentage = (numerator, denominator) => numerator / denominator * 100;
8
+ /** A percentage whose denominator is zero is not 0%; `emptyDenominator` says what it is instead. */
9
+ const percentOr = (emptyDenominator, numerator, denominator) => Match.value(denominator).pipe(Match.when(0, () => emptyDenominator), Match.orElse(() => percentage(numerator, denominator)));
10
+ const coveredFraction = (totalDetected, totalCovered, totalValid) => Match.value(totalValid).pipe(Match.when(0, () => NaN), Match.orElse(() => percentOr(0, totalDetected, totalCovered)));
11
+ const countMutants = (mutants) => {
12
+ const pending = countStatus(mutants, "Pending");
13
+ const killed = countStatus(mutants, "Killed");
14
+ const timeout = countStatus(mutants, "Timeout");
15
+ const survived = countStatus(mutants, "Survived");
16
+ const noCoverage = countStatus(mutants, "NoCoverage");
17
+ const runtimeErrors = countStatus(mutants, "RuntimeError");
18
+ const compileErrors = countStatus(mutants, "CompileError");
19
+ const ignored = countStatus(mutants, "Ignored");
20
+ const totalDetected = timeout + killed;
21
+ const totalUndetected = survived + noCoverage;
22
+ const totalCovered = totalDetected + survived;
23
+ const totalValid = totalUndetected + totalDetected;
24
+ const totalInvalid = runtimeErrors + compileErrors;
25
+ return {
26
+ pending,
27
+ killed,
28
+ timeout,
29
+ survived,
30
+ noCoverage,
31
+ runtimeErrors,
32
+ compileErrors,
33
+ ignored,
34
+ totalDetected,
35
+ totalUndetected,
36
+ totalCovered,
37
+ totalValid,
38
+ totalInvalid,
39
+ totalMutants: totalValid + totalInvalid + ignored + pending,
40
+ mutationScore: percentOr(NaN, totalDetected, totalValid),
41
+ mutationScoreBasedOnCoveredCode: coveredFraction(totalDetected, totalCovered, totalValid)
42
+ };
43
+ };
44
+ const segmentOf = (fileName) => {
45
+ const separator = fileName.indexOf("/");
46
+ if (separator === -1) return fileName;
47
+ return fileName.slice(0, separator);
48
+ };
49
+ const groupBySegment = (files) => Object.entries(files).reduce((groups, [fileName, file]) => {
50
+ const segment = segmentOf(fileName);
51
+ const group = groups[segment] ?? {};
52
+ group[fileName] = file;
53
+ groups[segment] = group;
54
+ return groups;
55
+ }, {});
56
+ const metricsOf = (files) => countMutants(Object.values(files).flatMap((file) => file.mutants));
57
+ const fileResultOf = (fileName, file) => ({
58
+ name: fileName,
59
+ metrics: countMutants(file.mutants),
60
+ childResults: []
61
+ });
62
+ const nestedGroupResult = (segment, entries) => {
63
+ const nested = Object.fromEntries(entries.map(([fileName, file]) => [fileName.slice(segment.length + 1), file]));
64
+ return {
65
+ name: segment,
66
+ metrics: metricsOf(nested),
67
+ childResults: childResultsOf(nested)
68
+ };
69
+ };
70
+ const soleSegmentFileResult = (segment, entries) => Option.flatMap(Arr.head(entries), ([fileName, file]) => Match.value(fileName === segment && entries.length === 1).pipe(Match.when(true, () => Option.some(fileResultOf(fileName, file))), Match.orElse(() => Option.none())));
71
+ const childResultOf = (segment, entries) => Option.getOrElse(soleSegmentFileResult(segment, entries), () => nestedGroupResult(segment, entries));
72
+ const childResultsOf = (files) => Object.entries(groupBySegment(files)).map(([segment, grouped]) => childResultOf(segment, Object.entries(grouped))).sort((left, right) => left.name.localeCompare(right.name));
73
+ const calculateMetrics = (files) => ({
74
+ name: "All files",
75
+ metrics: metricsOf(files),
76
+ childResults: childResultsOf(files)
77
+ });
78
+ //#endregion
79
+ export { MetricsResultSchema, MetricsSchema, calculateMetrics, countMutants };
@@ -0,0 +1,50 @@
1
+ import * as S from "effect/Schema";
2
+ //#region src/Metrics.schema.d.ts
3
+ declare const MetricsSchema: S.Struct<{
4
+ readonly pending: S.Finite;
5
+ readonly killed: S.Finite;
6
+ readonly timeout: S.Finite;
7
+ readonly survived: S.Finite;
8
+ readonly noCoverage: S.Finite;
9
+ readonly runtimeErrors: S.Finite;
10
+ readonly compileErrors: S.Finite;
11
+ readonly ignored: S.Finite;
12
+ readonly totalDetected: S.Finite;
13
+ readonly totalUndetected: S.Finite;
14
+ readonly totalInvalid: S.Finite;
15
+ readonly totalValid: S.Finite;
16
+ readonly totalMutants: S.Finite;
17
+ readonly totalCovered: S.Finite;
18
+ readonly mutationScore: S.Finite;
19
+ readonly mutationScoreBasedOnCoveredCode: S.Finite;
20
+ }>;
21
+ type Metrics = typeof MetricsSchema.Type;
22
+ interface MetricsResult {
23
+ readonly name: string;
24
+ readonly metrics: Metrics;
25
+ readonly childResults: readonly MetricsResult[];
26
+ }
27
+ declare const MetricsResultSchema: S.Struct<{
28
+ readonly name: S.String;
29
+ readonly metrics: S.Struct<{
30
+ readonly pending: S.Finite;
31
+ readonly killed: S.Finite;
32
+ readonly timeout: S.Finite;
33
+ readonly survived: S.Finite;
34
+ readonly noCoverage: S.Finite;
35
+ readonly runtimeErrors: S.Finite;
36
+ readonly compileErrors: S.Finite;
37
+ readonly ignored: S.Finite;
38
+ readonly totalDetected: S.Finite;
39
+ readonly totalUndetected: S.Finite;
40
+ readonly totalInvalid: S.Finite;
41
+ readonly totalValid: S.Finite;
42
+ readonly totalMutants: S.Finite;
43
+ readonly totalCovered: S.Finite;
44
+ readonly mutationScore: S.Finite;
45
+ readonly mutationScoreBasedOnCoveredCode: S.Finite;
46
+ }>;
47
+ readonly childResults: S.$Array<S.suspend<S.Codec<MetricsResult, MetricsResult, never, never>>>;
48
+ }>;
49
+ //#endregion
50
+ export { MetricsSchema as i, MetricsResult as n, MetricsResultSchema as r, Metrics as t };
@@ -0,0 +1,27 @@
1
+ import * as S from "effect/Schema";
2
+ //#region src/Metrics.schema.ts
3
+ const MetricsSchema = S.Struct({
4
+ pending: S.Finite,
5
+ killed: S.Finite,
6
+ timeout: S.Finite,
7
+ survived: S.Finite,
8
+ noCoverage: S.Finite,
9
+ runtimeErrors: S.Finite,
10
+ compileErrors: S.Finite,
11
+ ignored: S.Finite,
12
+ totalDetected: S.Finite,
13
+ totalUndetected: S.Finite,
14
+ totalInvalid: S.Finite,
15
+ totalValid: S.Finite,
16
+ totalMutants: S.Finite,
17
+ totalCovered: S.Finite,
18
+ mutationScore: S.Finite,
19
+ mutationScoreBasedOnCoveredCode: S.Finite
20
+ });
21
+ const MetricsResultSchema = S.Struct({
22
+ name: S.String,
23
+ metrics: MetricsSchema,
24
+ childResults: S.Array(S.suspend(() => MetricsResultSchema))
25
+ }).annotate({ identifier: "MetricsResult" });
26
+ //#endregion
27
+ export { MetricsSchema as n, MetricsResultSchema as t };
@@ -1,6 +1,6 @@
1
+ import { C as Report_schema_d_exports } from "./Report.schema-_buHXdnZ.mjs";
1
2
  import * as Context from "effect/Context";
2
3
  import * as S from "effect/Schema";
3
- import * as schema from "mutation-testing-report-schema/api";
4
4
  import * as Effect from "effect/Effect";
5
5
  //#region src/Mutant.schema.d.ts
6
6
  declare const PositionSchema: S.Struct<{
@@ -18,9 +18,9 @@ declare const LocationSchema: S.Struct<{
18
18
  }>;
19
19
  }>;
20
20
  declare const Mutant_base: S.Class<Mutant, S.TaggedStruct<"Mutant", {
21
- readonly id: S.String;
22
- readonly fileName: S.String;
23
- readonly mutatorName: S.String;
21
+ readonly id: S.NonEmptyString;
22
+ readonly fileName: S.NonEmptyString;
23
+ readonly mutatorName: S.NonEmptyString;
24
24
  readonly replacement: S.String;
25
25
  readonly location: S.Struct<{
26
26
  readonly start: S.Struct<{
@@ -272,7 +272,7 @@ declare function testFilesProvided(options: {
272
272
  readonly testFiles?: readonly string[];
273
273
  }): boolean;
274
274
  declare namespace Mutant_d_exports {
275
- export { Coverage, CoverageData, CoveragePerTestId, ERROR_CODES, EarlyResultPlan, ErrnoException, FileDescription, FileDescriptions, INSTRUMENTER_CONSTANTS, InstrumenterContext, Location, LocationSchema, Mutant, MutantCoverage, MutantEarlyResultPlan, MutantResult, MutantRunPlan, MutantStatus, MutantTestCoverage, MutantTestPlan, MutateDescription, MutationRange, Position$1 as Position, PositionSchema, RunPlan, TestPlan, causeText, errorToString, isErrnoException, isMutant, normalizeFileName, schema };
275
+ export { Coverage, CoverageData, CoveragePerTestId, ERROR_CODES, EarlyResultPlan, ErrnoException, FileDescription, FileDescriptions, INSTRUMENTER_CONSTANTS, InstrumenterContext, Location, LocationSchema, Mutant, MutantCoverage, MutantEarlyResultPlan, MutantResult, MutantRunPlan, MutantStatus, MutantTestCoverage, MutantTestPlan, MutateDescription, MutationRange, Position$1 as Position, PositionSchema, RunPlan, TestPlan, causeText, errorToString, isErrnoException, isMutant, normalizeFileName, Report_schema_d_exports as schema };
276
276
  }
277
277
  type CoverageData = Record<string, number>;
278
278
  type CoveragePerTestId = Record<string, CoverageData>;
@@ -348,4 +348,4 @@ type MutantEarlyResultPlan = EarlyResultPlan;
348
348
  type MutantTestPlan = TestPlan;
349
349
  declare const causeText: (cause: unknown, depth: number) => string | undefined;
350
350
  //#endregion
351
- export { TimeoutMutantRunResult as $, CompleteDryRunResult as A, MutantRunOptions as B, causeText as C, normalizeFileName as D, isMutant as E, ErrorMutantRunResult as F, SuccessTestResult as G, Position as H, FailedTestResult as I, TestRunner as J, SurvivedMutantRunResult as K, KilledMutantRunResult as L, DryRunOptions as M, DryRunResult as N, schema as O, ErrorDryRunResult as P, TimeoutDryRunResult as Q, MutantActivation as R, TestPlan as S, isErrnoException as T, RunOptions as U, MutantRunResult as V, SkippedTestResult as W, TestRunnerService as X, TestRunnerCapabilities as Y, TestRunner_d_exports as Z, MutantTestPlan as _, Mutant as _t, EarlyResultPlan as a, DryRunStatus as at, MutationRange as b, FileDescriptions as c, MutantRunOptionsSchema as ct, MutantCoverage as d, TestResultSchema as dt, testFilesProvided as et, MutantEarlyResultPlan as f, TestRunnerCapabilitiesSchema as ft, MutantTestCoverage as g, LocationSchema as gt, MutantStatus as h, Location as ht, ERROR_CODES as i, DryRunResultSchema as it, CoverageAnalysis as j, BaseTestResult as k, INSTRUMENTER_CONSTANTS as l, MutantRunResultSchema as lt, MutantRunPlan as m, TestStatus as mt, CoverageData as n, CoverageAnalysisSchema as nt, ErrnoException as o, MutantActivationSchema as ot, MutantResult as p, TestRunnerFailed as pt, TestResult as q, CoveragePerTestId as r, DryRunOptionsSchema as rt, FileDescription as s, MutantCoverageSchema as st, Coverage as t, toMutantRunResult as tt, InstrumenterContext as u, MutantRunStatus as ut, Mutant_d_exports as v, Position$1 as vt, errorToString as w, RunPlan as x, MutateDescription as y, PositionSchema as yt, MutantCoverage$1 as z };
351
+ export { testFilesProvided as $, CoverageAnalysis as A, MutantRunResult as B, causeText as C, normalizeFileName as D, isMutant as E, FailedTestResult as F, SurvivedMutantRunResult as G, RunOptions as H, KilledMutantRunResult as I, TestRunnerCapabilities as J, TestResult as K, MutantActivation as L, DryRunResult as M, ErrorDryRunResult as N, BaseTestResult as O, ErrorMutantRunResult as P, TimeoutMutantRunResult as Q, MutantCoverage$1 as R, TestPlan as S, isErrnoException as T, SkippedTestResult as U, Position as V, SuccessTestResult as W, TestRunner_d_exports as X, TestRunnerService as Y, TimeoutDryRunResult as Z, MutantTestPlan as _, Position$1 as _t, EarlyResultPlan as a, MutantActivationSchema as at, MutationRange as b, FileDescriptions as c, MutantRunResultSchema as ct, MutantCoverage as d, TestRunnerCapabilitiesSchema as dt, toMutantRunResult as et, MutantEarlyResultPlan as f, TestRunnerFailed as ft, MutantTestCoverage as g, Mutant as gt, MutantStatus as h, LocationSchema as ht, ERROR_CODES as i, DryRunStatus as it, DryRunOptions as j, CompleteDryRunResult as k, INSTRUMENTER_CONSTANTS as l, MutantRunStatus as lt, MutantRunPlan as m, Location as mt, CoverageData as n, DryRunOptionsSchema as nt, ErrnoException as o, MutantCoverageSchema as ot, MutantResult as p, TestStatus as pt, TestRunner as q, CoveragePerTestId as r, DryRunResultSchema as rt, FileDescription as s, MutantRunOptionsSchema as st, Coverage as t, CoverageAnalysisSchema as tt, InstrumenterContext as u, TestResultSchema as ut, Mutant_d_exports as v, PositionSchema as vt, errorToString as w, RunPlan as x, MutateDescription as y, MutantRunOptions as z };
package/dist/Mutant.d.mts CHANGED
@@ -1,2 +1,3 @@
1
- import { C as causeText, D as normalizeFileName, E as isMutant, O as schema, S as TestPlan, T as isErrnoException, _ as MutantTestPlan, _t as Mutant, a as EarlyResultPlan, b as MutationRange, c as FileDescriptions, d as MutantCoverage, f as MutantEarlyResultPlan, g as MutantTestCoverage, gt as LocationSchema, h as MutantStatus, ht as Location, i as ERROR_CODES, l as INSTRUMENTER_CONSTANTS, m as MutantRunPlan, n as CoverageData, o as ErrnoException, p as MutantResult, r as CoveragePerTestId, s as FileDescription, t as Coverage, u as InstrumenterContext, vt as Position, w as errorToString, x as RunPlan, y as MutateDescription, yt as PositionSchema } from "./Mutant-BPRJTF8f.mjs";
2
- export { Coverage, CoverageData, CoveragePerTestId, ERROR_CODES, EarlyResultPlan, ErrnoException, FileDescription, FileDescriptions, INSTRUMENTER_CONSTANTS, InstrumenterContext, type Location, LocationSchema, Mutant, MutantCoverage, MutantEarlyResultPlan, MutantResult, MutantRunPlan, MutantStatus, MutantTestCoverage, MutantTestPlan, MutateDescription, MutationRange, type Position, PositionSchema, RunPlan, TestPlan, causeText, errorToString, isErrnoException, isMutant, normalizeFileName, schema };
1
+ import { C as causeText, D as normalizeFileName, E as isMutant, S as TestPlan, T as isErrnoException, _ as MutantTestPlan, _t as Position, a as EarlyResultPlan, b as MutationRange, c as FileDescriptions, d as MutantCoverage, f as MutantEarlyResultPlan, g as MutantTestCoverage, gt as Mutant, h as MutantStatus, ht as LocationSchema, i as ERROR_CODES, l as INSTRUMENTER_CONSTANTS, m as MutantRunPlan, mt as Location, n as CoverageData, o as ErrnoException, p as MutantResult, r as CoveragePerTestId, s as FileDescription, t as Coverage, u as InstrumenterContext, vt as PositionSchema, w as errorToString, x as RunPlan, y as MutateDescription } from "./Mutant-Ci25PsWA.mjs";
2
+ import { C as Report_schema_d_exports } from "./Report.schema-_buHXdnZ.mjs";
3
+ export { Coverage, CoverageData, CoveragePerTestId, ERROR_CODES, EarlyResultPlan, ErrnoException, FileDescription, FileDescriptions, INSTRUMENTER_CONSTANTS, InstrumenterContext, type Location, LocationSchema, Mutant, MutantCoverage, MutantEarlyResultPlan, MutantResult, MutantRunPlan, MutantStatus, MutantTestCoverage, MutantTestPlan, MutateDescription, MutationRange, type Position, PositionSchema, RunPlan, TestPlan, causeText, errorToString, isErrnoException, isMutant, normalizeFileName, Report_schema_d_exports as schema };
package/dist/Mutant.mjs CHANGED
@@ -1,6 +1,9 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { n as Mutant, r as PositionSchema, t as LocationSchema } from "./Mutant.schema-BTWhFTk4.mjs";
3
- import * as schema from "mutation-testing-report-schema/api";
2
+ import { n as Mutant, r as PositionSchema, t as LocationSchema } from "./Mutant.schema-H3r0ho_R.mjs";
3
+ import { t as Report_schema_exports } from "./Report.mjs";
4
+ import * as Match from "effect/Match";
5
+ import * as Option from "effect/Option";
6
+ import * as Predicate from "effect/Predicate";
4
7
  //#region src/Mutant.ts
5
8
  var Mutant_exports = /* @__PURE__ */ __exportAll({
6
9
  ERROR_CODES: () => ERROR_CODES,
@@ -13,7 +16,7 @@ var Mutant_exports = /* @__PURE__ */ __exportAll({
13
16
  isErrnoException: () => isErrnoException,
14
17
  isMutant: () => isMutant,
15
18
  normalizeFileName: () => normalizeFileName,
16
- schema: () => schema
19
+ schema: () => Report_schema_exports
17
20
  });
18
21
  const isMutant = (value) => value instanceof Mutant;
19
22
  const INSTRUMENTER_CONSTANTS = Object.freeze({
@@ -28,87 +31,60 @@ const INSTRUMENTER_CONSTANTS = Object.freeze({
28
31
  function normalizeFileName(fileName) {
29
32
  return fileName.replace(/\\/g, "/");
30
33
  }
34
+ const hasText = (value) => Predicate.isString(value) && value.length > 0;
35
+ const textIfNonEmpty = (value) => Option.getOrUndefined(Option.filter(Option.fromUndefinedOr(value), hasText));
36
+ const fieldOf = (value, key) => Match.value(key in value).pipe(Match.when(true, () => {
37
+ return Reflect.get(value, key);
38
+ }), Match.orElse(() => void 0));
39
+ const hasStringCode = (error) => Match.value(fieldOf(error, "code")).pipe(Match.when(Match.string, () => true), Match.orElse(() => false));
31
40
  function isErrnoException(error) {
32
- if (!(error instanceof Error)) return false;
33
- if (!("code" in error)) return false;
34
- return typeof Reflect.get(error, "code") === "string";
41
+ return Match.value(error).pipe(Match.when(Match.instanceOf(Error), hasStringCode), Match.orElse(() => false));
35
42
  }
36
- const isEmptyError = (error) => {
37
- if (error === void 0 || error === null) return true;
38
- if (typeof error === "string" && error.length === 0) return true;
39
- if (error === 0 || error === false) return true;
40
- if (typeof error === "number" && Number.isNaN(error)) return true;
41
- return false;
42
- };
43
- const formatErrnoException = (error) => {
44
- const stack = error.stack;
45
- if (stack !== void 0 && stack.length > 0) return `${error.name}: ${error.code} (${error.syscall}) ${stack}`;
46
- return `${error.name}: ${error.code} (${error.syscall})`;
47
- };
48
- const formatError = (error) => {
49
- const message = `${error.name}: ${error.message}`;
50
- if (error.stack !== void 0 && error.stack.length > 0) return `${message}\n${error.stack.toString()}`;
51
- return message;
52
- };
53
- const stringifyNonError = (error) => {
54
- if (typeof error === "string") return error;
55
- if (typeof error === "number" || typeof error === "boolean" || typeof error === "bigint") return JSON.stringify(error);
43
+ const isEmptyNumber = (value) => Match.value(value).pipe(Match.when(0, () => true), Match.orElse(Number.isNaN));
44
+ const isEmptyError = (error) => Match.value(error).pipe(Match.when(Match.undefined, () => true), Match.when(Match.null, () => true), Match.when(Match.string, (text) => text.length === 0), Match.when(Match.number, isEmptyNumber), Match.when(Match.boolean, (value) => !value), Match.orElse(() => false));
45
+ const formatErrnoException = (error) => Match.value(error.stack).pipe(Match.when(hasText, (stack) => `${error.name}: ${error.code} (${error.syscall}) ${stack}`), Match.orElse(() => `${error.name}: ${error.code} (${error.syscall})`));
46
+ const formatError = (error) => Match.value(error.stack).pipe(Match.when(hasText, (stack) => `${error.name}: ${error.message}\n${stack}`), Match.orElse(() => `${error.name}: ${error.message}`));
47
+ const isJsonPrimitive = (value) => Match.value(value).pipe(Match.when(Match.number, () => true), Match.when(Match.boolean, () => true), Match.when(Match.bigint, () => true), Match.orElse(() => false));
48
+ const jsonText = (error) => {
56
49
  try {
57
- const json = JSON.stringify(error);
58
- if (typeof json === "string" && json.length > 0) return json;
59
- } catch {}
60
- if (typeof error === "object" && error !== null && "toString" in error) {
61
- const toStringValue = Reflect.get(error, "toString");
62
- if (typeof toStringValue === "function") try {
63
- const text = Reflect.apply(toStringValue, error, []);
64
- if (typeof text === "string" && text.length > 0 && text !== "[object Object]") return text;
65
- } catch {}
50
+ return textIfNonEmpty(JSON.stringify(error));
51
+ } catch {
52
+ return;
66
53
  }
67
- return "";
68
54
  };
69
- function errorToString(error) {
70
- if (isEmptyError(error)) return "";
71
- if (error instanceof Error) {
72
- if (isErrnoException(error)) return formatErrnoException(error);
73
- return formatError(error);
55
+ const isNonPlaceholderText = (text) => Match.value({
56
+ hasLength: text.length > 0,
57
+ isPlaceholder: text === "[object Object]"
58
+ }).pipe(Match.when({
59
+ hasLength: true,
60
+ isPlaceholder: false
61
+ }, () => true), Match.orElse(() => false));
62
+ const isUsableText = (value) => Match.value(value).pipe(Match.when(Match.string, isNonPlaceholderText), Match.orElse(() => false));
63
+ const usableText = (value) => Match.value(value).pipe(Match.when(isUsableText, (text) => text), Match.orElse(() => ""));
64
+ const objectToStringText = (value) => Match.value(fieldOf(value, "toString")).pipe(Match.when(Match.instanceOf(Function), (callable) => {
65
+ try {
66
+ return usableText(Reflect.apply(callable, value, []));
67
+ } catch {
68
+ return "";
74
69
  }
75
- return stringifyNonError(error);
70
+ }), Match.orElse(() => ""));
71
+ const isObjectType = (cause) => typeof cause === "object";
72
+ const toStringText = (error) => Match.value(error).pipe(Match.when(Match.null, () => ""), Match.when(isObjectType, (value) => objectToStringText(value)), Match.orElse(() => ""));
73
+ const stringifyRest = (error) => Match.value(jsonText(error)).pipe(Match.when(hasText, (json) => json), Match.orElse(() => toStringText(error)));
74
+ const stringifyNonError = (error) => Match.value(error).pipe(Match.when(Match.string, (text) => text), Match.when(isJsonPrimitive, (primitive) => JSON.stringify(primitive)), Match.orElse(() => stringifyRest(error)));
75
+ const errorText = (error) => Match.value(error).pipe(Match.when(isErrnoException, formatErrnoException), Match.orElse(() => formatError(error)));
76
+ function errorToString(error) {
77
+ return Match.value(error).pipe(Match.when(isEmptyError, () => ""), Match.when(Match.instanceOf(Error), errorText), Match.orElse(() => stringifyNonError(error)));
76
78
  }
77
79
  const ERROR_CODES = Object.freeze({ NoSuchFileOrDirectory: "ENOENT" });
78
- const stringField = (value, key) => {
79
- if (!(key in value)) return;
80
- const field = Reflect.get(value, key);
81
- if (typeof field === "string" && field.length > 0) return field;
82
- };
83
- const tagOf = (value) => {
84
- let tag;
85
- if ("_tag" in value) tag = Reflect.get(value, "_tag");
86
- else tag = void 0;
87
- if (typeof tag === "string" && tag.length > 0) return tag;
88
- if (value instanceof Error && value.name.length > 0) return value.name;
89
- };
90
- const causeText = (cause, depth) => {
91
- if (depth > 4 || cause === void 0 || cause === null) return;
92
- if (typeof cause === "string") {
93
- if (cause.length > 0) return cause;
94
- return;
95
- }
96
- if (typeof cause !== "object") return;
97
- let own;
98
- const reason = stringField(cause, "reason");
99
- if (reason !== void 0) own = reason;
100
- else {
101
- const message = stringField(cause, "message");
102
- if (message !== void 0) own = message;
103
- else if (cause instanceof Error && cause.message.length > 0) own = cause.message;
104
- else own = tagOf(cause);
105
- }
106
- let nested;
107
- if ("cause" in cause) nested = causeText(Reflect.get(cause, "cause"), depth + 1);
108
- else nested = void 0;
109
- if (own === void 0) return nested;
110
- if (nested === void 0) return own;
111
- return `${own}: ${nested}`;
112
- };
80
+ const errorNameOf = (value) => Match.value(value).pipe(Match.when(Match.instanceOf(Error), (error) => textIfNonEmpty(error.name)), Match.orElse(() => void 0));
81
+ const tagOf = (value) => Match.value(textIfNonEmpty(fieldOf(value, "_tag"))).pipe(Match.when(hasText, (tag) => tag), Match.orElse(() => errorNameOf(value)));
82
+ const textWithNested = (own, nested) => Match.value(own).pipe(Match.when(hasText, (text) => appendNested(text, nested)), Match.orElse(() => nested));
83
+ const appendNested = (own, nested) => Match.value(nested).pipe(Match.when(hasText, (text) => `${own}: ${text}`), Match.orElse(() => own));
84
+ const errorMessage = (error) => Match.value(error.message.length > 0).pipe(Match.when(true, () => error.message), Match.orElse(() => tagOf(error)));
85
+ const errorMessageOrTag = (value) => Match.value(value).pipe(Match.when(Match.instanceOf(Error), errorMessage), Match.orElse(() => tagOf(value)));
86
+ const messageText = (value) => Match.value(textIfNonEmpty(fieldOf(value, "message"))).pipe(Match.when(hasText, (message) => message), Match.orElse(() => errorMessageOrTag(value)));
87
+ const ownCauseText = (value) => Match.value(textIfNonEmpty(fieldOf(value, "reason"))).pipe(Match.when(hasText, (reason) => reason), Match.orElse(() => messageText(value)));
88
+ const causeText = (cause, depth) => Match.value(cause).pipe(Match.when(() => depth > 4, () => void 0), Match.when(Match.undefined, () => void 0), Match.when(Match.null, () => void 0), Match.when(Match.string, textIfNonEmpty), Match.when(isObjectType, (value) => textWithNested(ownCauseText(value), causeText(fieldOf(value, "cause"), depth + 1))), Match.orElse(() => void 0));
113
89
  //#endregion
114
- export { ERROR_CODES, INSTRUMENTER_CONSTANTS, LocationSchema, Mutant, PositionSchema, causeText, errorToString, isErrnoException, isMutant, normalizeFileName, schema, Mutant_exports as t };
90
+ export { ERROR_CODES, INSTRUMENTER_CONSTANTS, LocationSchema, Mutant, PositionSchema, causeText, errorToString, isErrnoException, isMutant, normalizeFileName, Report_schema_exports as schema, Mutant_exports as t };
@@ -9,9 +9,9 @@ const LocationSchema = S.Struct({
9
9
  end: PositionSchema
10
10
  });
11
11
  var Mutant = class extends S.TaggedClass()("Mutant", {
12
- id: S.String,
13
- fileName: S.String,
14
- mutatorName: S.String,
12
+ id: S.NonEmptyString,
13
+ fileName: S.NonEmptyString,
14
+ mutatorName: S.NonEmptyString,
15
15
  replacement: S.String,
16
16
  location: LocationSchema,
17
17
  status: S.optional(S.Literals([