@systemfsoftware/stryker-js 10.1.0 → 10.1.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 +6 -0
- package/dist/{Run.schema-B0ERLxQj.mjs → Run.schema-B_KpPeBA.mjs} +98 -72
- package/dist/{Run.schema-RWUb38ZE.d.mts → Run.schema-BsSOfQnD.d.mts} +1 -1
- package/dist/config.d.mts +1 -1
- package/dist/config.mjs +1 -1
- package/dist/events.d.mts +1 -1
- package/dist/events.mjs +1 -1
- package/dist/{index-BopuZXrl.d.mts → index-CogNSD0V.d.mts} +6 -5
- package/dist/index.d.mts +15 -14
- package/dist/index.mjs +2 -2
- package/dist/main.mjs +541 -298
- package/dist/merge-config-CHZWyvVQ.mjs +19 -0
- package/dist/{mutation-test.cell-CobzlfL-.d.mts → mutation-test.cell-DS86DvC9.d.mts} +32 -32
- package/dist/promises.d.mts +2 -2
- package/dist/promises.mjs +1 -1
- package/dist/{src-Baq6uz-6.mjs → src-BkTsNvl0.mjs} +199 -209
- package/package.json +7 -7
- package/dist/merge-config-BrrNQWje.mjs +0 -16
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $ as WorkerEntryUrl, F as MutationTestingPlanReady, G as TRACEPARENT_HEADER, I as NonNegativeInt, J as TestRunnerFailed, K as TRACESTATE_HEADER, L as PropagatedTrace, M as MutantTested, N as MutationTestReportReady, O as Metrics, P as MutationTestResultSchema
|
|
2
|
-
import { t as mergeConfig } from "./merge-config-
|
|
1
|
+
import { $ as WorkerEntryUrl, F as MutationTestingPlanReady, G as TRACEPARENT_HEADER, I as NonNegativeInt, J as TestRunnerFailed, K as TRACESTATE_HEADER, L as PropagatedTrace, M as MutantTested, N as MutationTestReportReady, O as Metrics, P as MutationTestResultSchema, Q as WALL_CLOCK_TIMEOUT_REASON, S as CheckerMutantWire, T as DryRunCompleted, U as ReporterRpcs, V as ReporterFailed, W as StrykerOptionsSchema, X as TraceContextMiddleware, Y as TestRunnerRpcs, Z as TraceContextReference, _ as RunStarted, at as wallClockTimeoutStopsRun, c as PhaseEntered, ct as Mutant, et as WorkerPluginKind, f as RunEvent, ft as disableTypeChecks, ht as normalizeFileName$4, it as toMutantRunResult, k as MetricsResultSchema, l as PlanKnown, m as RunMutantTested, mt as instrument, n as StageError, nt as isCustomTestRunner, ot as INSTRUMENTER_CONSTANTS, pt as errorToString, r as Heartbeat, rt as parseTraceparent, t as PrepareError, tt as formatTraceparent, v as VerdictReached, w as CheckerRpcs } from "./Run.schema-B_KpPeBA.mjs";
|
|
2
|
+
import { t as mergeConfig } from "./merge-config-CHZWyvVQ.mjs";
|
|
3
3
|
import * as Effect$1 from "effect/Effect";
|
|
4
4
|
import * as FileSystem from "effect/FileSystem";
|
|
5
5
|
import * as Path from "effect/Path";
|
|
@@ -26,6 +26,7 @@ import * as Exit from "effect/Exit";
|
|
|
26
26
|
import * as Scope from "effect/Scope";
|
|
27
27
|
import * as Duration from "effect/Duration";
|
|
28
28
|
import * as MutableHashMap from "effect/MutableHashMap";
|
|
29
|
+
import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner";
|
|
29
30
|
import * as MutableHashSet from "effect/MutableHashSet";
|
|
30
31
|
import * as HashMap from "effect/HashMap";
|
|
31
32
|
import * as HashSet from "effect/HashSet";
|
|
@@ -41,7 +42,6 @@ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
|
41
42
|
import { SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
42
43
|
import * as Cause from "effect/Cause";
|
|
43
44
|
import * as ChildProcess from "effect/unstable/process/ChildProcess";
|
|
44
|
-
import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner";
|
|
45
45
|
import * as NodeChildProcessSpawner from "@effect/platform-node-shared/NodeChildProcessSpawner";
|
|
46
46
|
import * as NodeCrypto from "@effect/platform-node-shared/NodeCrypto";
|
|
47
47
|
import * as Crypto from "effect/Crypto";
|
|
@@ -714,8 +714,12 @@ const incrementalDiffOfChanges = (input) => {
|
|
|
714
714
|
};
|
|
715
715
|
};
|
|
716
716
|
const computeIncrementalDiff = (input) => Match.value(input.force).pipe(Match.when(true, () => forcedDiff(input)), Match.orElse(() => incrementalDiffOfChanges(input)));
|
|
717
|
-
const
|
|
718
|
-
const
|
|
717
|
+
const filesFieldOf = (report) => Option.getOrElse(S.decodeUnknownOption(PreviousFilesSchema)(report.files), () => ({}));
|
|
718
|
+
const previousFilesFrom = (report) => Predicate.hasProperty(report, "files") ? filesFieldOf(report) : {};
|
|
719
|
+
const previousFilesOf = (rawReport) => Predicate.isObject(rawReport) ? previousFilesFrom(rawReport) : {};
|
|
720
|
+
const testFilesFieldOf = (report) => Option.getOrElse(S.decodeUnknownOption(PreviousTestFilesSchema)(report.testFiles), () => ({}));
|
|
721
|
+
const previousTestFilesFrom = (report) => Predicate.hasProperty(report, "testFiles") ? testFilesFieldOf(report) : {};
|
|
722
|
+
const previousTestFilesOf = (rawReport) => Predicate.isObject(rawReport) ? previousTestFilesFrom(rawReport) : {};
|
|
719
723
|
const hasTestFileName = (result) => result.fileName !== void 0;
|
|
720
724
|
const testIdsByRelativeFile = (testCoverage, basePath) => {
|
|
721
725
|
const byFile = {};
|
|
@@ -800,6 +804,104 @@ const compileIgnoreRule = (pattern) => {
|
|
|
800
804
|
};
|
|
801
805
|
};
|
|
802
806
|
//#endregion
|
|
807
|
+
//#region src/config-defaults.ts
|
|
808
|
+
const isNonNullObject$1 = (value) => typeof value === "object" && value !== null;
|
|
809
|
+
const isRecordValue$1 = (value) => isNonNullObject$1(value) && Array.isArray(value) === false;
|
|
810
|
+
const isArrayValue$1 = (value) => Array.isArray(value);
|
|
811
|
+
const freezeArrayValue$1 = (value) => Object.freeze(value.map((element) => deepFreeze$1(element)));
|
|
812
|
+
const freezeMapEntry$1 = ([entryKey, entryValue]) => [deepFreeze$1(entryKey), deepFreeze$1(entryValue)];
|
|
813
|
+
const freezeMapValue$1 = (value) => Object.freeze(new Map([...value.entries()].map(freezeMapEntry$1)));
|
|
814
|
+
const freezeSetValue$1 = (value) => Object.freeze(new Set([...value.values()].map((element) => deepFreeze$1(element))));
|
|
815
|
+
const freezeRegExpValue$1 = (value) => Object.freeze(value);
|
|
816
|
+
const freezeRecordValue$1 = (value) => Object.freeze(Object.entries(value).reduce((frozen, [property, propertyValue]) => {
|
|
817
|
+
frozen[property] = deepFreeze$1(propertyValue);
|
|
818
|
+
return frozen;
|
|
819
|
+
}, {}));
|
|
820
|
+
function deepFreeze$1(target) {
|
|
821
|
+
return Match.value(target).pipe(Match.when(isArrayValue$1, freezeArrayValue$1), Match.when((value) => value instanceof Map, freezeMapValue$1), Match.when((value) => value instanceof RegExp, freezeRegExpValue$1), Match.when((value) => value instanceof Set, freezeSetValue$1), Match.when(isRecordValue$1, freezeRecordValue$1), Match.orElse(() => target));
|
|
822
|
+
}
|
|
823
|
+
const optionsPath$1 = (...path) => path.join(".");
|
|
824
|
+
const SUPPORTED_CONFIG_FILE_EXTENSIONS$1 = [
|
|
825
|
+
".ts",
|
|
826
|
+
".mts",
|
|
827
|
+
".js",
|
|
828
|
+
".mjs"
|
|
829
|
+
];
|
|
830
|
+
const configFileNames$1 = (extensions) => extensions.map((extension) => `stryker.config${extension}`);
|
|
831
|
+
const SUPPORTED_CONFIG_FILE_NAMES$1 = Object.freeze(configFileNames$1(SUPPORTED_CONFIG_FILE_EXTENSIONS$1));
|
|
832
|
+
const RELATIVE_SPECIFIER_PREFIXES$1 = [
|
|
833
|
+
"/",
|
|
834
|
+
"./",
|
|
835
|
+
"../",
|
|
836
|
+
"file://"
|
|
837
|
+
];
|
|
838
|
+
function isModuleSpecifier$1(value) {
|
|
839
|
+
return RELATIVE_SPECIFIER_PREFIXES$1.every((prefix) => value.startsWith(prefix) === false);
|
|
840
|
+
}
|
|
841
|
+
const CONFIG_SYNTAX_HELP$1 = `
|
|
842
|
+
Example of how a config file should look:
|
|
843
|
+
/**
|
|
844
|
+
* @type {import('@systemfsoftware/stryker-js-plugin-interface').StrykerOptions}
|
|
845
|
+
*/
|
|
846
|
+
export default {
|
|
847
|
+
mutate: ['src/**/*.js'],
|
|
848
|
+
testRunner: 'vitest',
|
|
849
|
+
reporters: ['progress', 'clear-text', 'html'],
|
|
850
|
+
concurrency: 4
|
|
851
|
+
};
|
|
852
|
+
See https://stryker-mutator.io/docs/stryker-js/config-file for more information.`.trim();
|
|
853
|
+
const createDefaultOptions$1 = S.decodeEffect(StrykerOptionsSchema)({}).pipe(Effect$1.orDie);
|
|
854
|
+
const defaultOptions$1 = Effect$1.map(createDefaultOptions$1, (opts) => deepFreeze$1(opts));
|
|
855
|
+
const scopedUnserializable = (scope) => (description) => ({
|
|
856
|
+
...description,
|
|
857
|
+
path: [scope, ...description.path]
|
|
858
|
+
});
|
|
859
|
+
const describeUnserializableChild = (child, scope) => Match.value(findUnserializables(child)).pipe(Match.when(void 0, () => []), Match.orElse((descriptions) => descriptions.map(scopedUnserializable(scope))));
|
|
860
|
+
const collectUnserializables = (groups) => {
|
|
861
|
+
const found = groups.flat();
|
|
862
|
+
if (found.length > 0) return found;
|
|
863
|
+
};
|
|
864
|
+
const describeUnserializableArray = (value) => collectUnserializables(value.map((child, index) => describeUnserializableChild(child, index.toString())));
|
|
865
|
+
const describeUnserializableRecord = (value) => collectUnserializables(Object.entries(value).map(([key, child]) => describeUnserializableChild(child, key)));
|
|
866
|
+
const isPlainObjectValue = (value) => !Array.isArray(value) && value.constructor === Object;
|
|
867
|
+
const classNameOf = (value) => Match.value(value.constructor).pipe(Match.when(Match.defined, (ctor) => ctor.name), Match.orElse(() => "Object"));
|
|
868
|
+
const describeUnserializableInstance = (value) => [{
|
|
869
|
+
path: [],
|
|
870
|
+
reason: `Value is an instance of "${classNameOf(value)}", this detail will get lost in translation during serialization`
|
|
871
|
+
}];
|
|
872
|
+
const describeUnserializableObject = (value) => Match.value(value).pipe(Match.when(isArrayValue$1, describeUnserializableArray), Match.when(isPlainObjectValue, describeUnserializableRecord), Match.orElse(describeUnserializableInstance));
|
|
873
|
+
const NON_JSON_PRIMITIVE_TYPES = [
|
|
874
|
+
"bigint",
|
|
875
|
+
"function",
|
|
876
|
+
"symbol"
|
|
877
|
+
];
|
|
878
|
+
const isNonJsonPrimitive = (value) => NON_JSON_PRIMITIVE_TYPES.includes(typeof value);
|
|
879
|
+
const describeNonJsonPrimitive = (value) => [{
|
|
880
|
+
path: [],
|
|
881
|
+
reason: `Primitive type "${typeof value}" has no JSON representation`
|
|
882
|
+
}];
|
|
883
|
+
const describeNumber = (value) => {
|
|
884
|
+
if (isFinite(value)) return void 0;
|
|
885
|
+
return [{
|
|
886
|
+
reason: `Number value \`${value}\` has no JSON representation`,
|
|
887
|
+
path: []
|
|
888
|
+
}];
|
|
889
|
+
};
|
|
890
|
+
function findUnserializables(thing) {
|
|
891
|
+
if (typeof thing === "number") return describeNumber(thing);
|
|
892
|
+
return describeNonNumberValue(thing);
|
|
893
|
+
}
|
|
894
|
+
function describeNonNumberValue(thing) {
|
|
895
|
+
return isNonJsonPrimitive(thing) ? describeNonJsonPrimitive(thing) : describeObjectValue(thing);
|
|
896
|
+
}
|
|
897
|
+
function describeObjectValue(thing) {
|
|
898
|
+
return isNonNullObject$1(thing) ? describeUnserializableObject(thing) : void 0;
|
|
899
|
+
}
|
|
900
|
+
function isWarningEnabled$1(warningType, warningOptions) {
|
|
901
|
+
if (typeof warningOptions === "boolean") return warningOptions;
|
|
902
|
+
else return warningOptions[warningType] === true;
|
|
903
|
+
}
|
|
904
|
+
//#endregion
|
|
803
905
|
//#region src/Config.schema.ts
|
|
804
906
|
const ConfigDocumentSchema = S.Record(S.String, S.Unknown);
|
|
805
907
|
const ImportedModuleSchema = S.Struct({ default: S.optional(S.Unknown) });
|
|
@@ -1023,9 +1125,10 @@ const sandboxFor = (platform, fileName, activeMutantId) => {
|
|
|
1023
1125
|
exports: moduleExports,
|
|
1024
1126
|
__filename: fileName
|
|
1025
1127
|
};
|
|
1026
|
-
sandbox
|
|
1027
|
-
|
|
1028
|
-
|
|
1128
|
+
return Object.assign(sandbox, {
|
|
1129
|
+
global: sandbox,
|
|
1130
|
+
globalThis: sandbox
|
|
1131
|
+
});
|
|
1029
1132
|
};
|
|
1030
1133
|
const resultFromRun = (failureMessage, timeSpentMs) => Match.value(failureMessage).pipe(Match.when(Match.string, (failure) => ({
|
|
1031
1134
|
status: "complete",
|
|
@@ -1049,10 +1152,7 @@ const isPlainObject = (value) => {
|
|
|
1049
1152
|
if (!Predicate.isObject(value)) return false;
|
|
1050
1153
|
return true;
|
|
1051
1154
|
};
|
|
1052
|
-
const descriptorValue = (descriptor) =>
|
|
1053
|
-
if (descriptor === void 0) return;
|
|
1054
|
-
return descriptor.value;
|
|
1055
|
-
};
|
|
1155
|
+
const descriptorValue = (descriptor) => descriptor === void 0 ? void 0 : descriptor.value;
|
|
1056
1156
|
const hostStrykerNamespace = () => {
|
|
1057
1157
|
const current = descriptorValue(Object.getOwnPropertyDescriptor(globalThis, INSTRUMENTER_CONSTANTS.NAMESPACE));
|
|
1058
1158
|
if (isPlainObject(current)) return current;
|
|
@@ -1594,78 +1694,43 @@ const buildTestRunner = (context, childProcessRunner) => Effect$1.gen(function*
|
|
|
1594
1694
|
});
|
|
1595
1695
|
//#endregion
|
|
1596
1696
|
//#region src/run/load-config.cell.ts
|
|
1597
|
-
const isNonNullObject
|
|
1598
|
-
const
|
|
1697
|
+
const isNonNullObject = (value) => typeof value === "object" && value !== null;
|
|
1698
|
+
const isRecordValue = (value) => isNonNullObject(value) && Array.isArray(value) === false;
|
|
1699
|
+
const optionsPath = (...path) => path.join(".");
|
|
1599
1700
|
const combine = (prefixes, suffixes, extensions) => prefixes.flatMap((prefix) => suffixes.flatMap((suffix) => extensions.map((extension) => `${prefix}stryker${suffix}.${extension}`)));
|
|
1600
1701
|
const CONFIG_FILE_NAME_PREFIXES = ["", "."];
|
|
1601
1702
|
const CONFIG_FILE_NAME_SUFFIXES = [".conf", ".config"];
|
|
1602
|
-
const SUPPORTED_CONFIG_FILE_EXTENSIONS
|
|
1703
|
+
const SUPPORTED_CONFIG_FILE_EXTENSIONS = [
|
|
1603
1704
|
"ts",
|
|
1604
1705
|
"mts",
|
|
1605
1706
|
"js",
|
|
1606
1707
|
"mjs"
|
|
1607
1708
|
];
|
|
1608
1709
|
const LEGACY_CONFIG_FILE_EXTENSIONS = ["json", "cjs"];
|
|
1609
|
-
const configFileNames
|
|
1610
|
-
const SUPPORTED_CONFIG_FILE_NAMES
|
|
1611
|
-
const LEGACY_CONFIG_FILE_NAMES = Object.freeze(configFileNames
|
|
1612
|
-
const SUPPORTED_CONFIG_FILE_EXTENSION_GUIDE = `one of these extensions: ${SUPPORTED_CONFIG_FILE_EXTENSIONS
|
|
1710
|
+
const configFileNames = (extensions) => combine([...CONFIG_FILE_NAME_PREFIXES], [...CONFIG_FILE_NAME_SUFFIXES], [...extensions]);
|
|
1711
|
+
const SUPPORTED_CONFIG_FILE_NAMES = Object.freeze(configFileNames(SUPPORTED_CONFIG_FILE_EXTENSIONS));
|
|
1712
|
+
const LEGACY_CONFIG_FILE_NAMES = Object.freeze(configFileNames(LEGACY_CONFIG_FILE_EXTENSIONS));
|
|
1713
|
+
const SUPPORTED_CONFIG_FILE_EXTENSION_GUIDE = `one of these extensions: ${SUPPORTED_CONFIG_FILE_EXTENSIONS.map((extension) => `.${extension}`).join(", ")}`;
|
|
1613
1714
|
const legacyConfigHint = (file) => `Stryker no longer reads JSON or CommonJS config files. Convert "${file}" to a config module with an "export default { ... }" object — Stryker reads config modules with ${SUPPORTED_CONFIG_FILE_EXTENSION_GUIDE} — and delete the legacy file.`;
|
|
1614
1715
|
const unsupportedConfigHint = (file) => `"${file}" is not a supported config file. Stryker reads config modules with ${SUPPORTED_CONFIG_FILE_EXTENSION_GUIDE}, for example "stryker.config.ts" with an "export default { ... }" object.`;
|
|
1615
1716
|
const extendsChildHint = (file) => `The extended config "${file}" is a JSON or CommonJS config file, which Stryker no longer reads. Convert it to a config module — Stryker reads config modules with ${SUPPORTED_CONFIG_FILE_EXTENSION_GUIDE} — and point "extends" at the converted file.`;
|
|
1616
1717
|
const shadowedLegacyWarning = (legacyFile, supportedFile) => `Ignoring the legacy config file "${legacyFile}": "${supportedFile}" is the config Stryker reads. Stryker no longer reads JSON or CommonJS config files; delete the legacy file.`;
|
|
1617
|
-
const isArrayValue
|
|
1618
|
-
const
|
|
1619
|
-
const
|
|
1620
|
-
const
|
|
1621
|
-
const
|
|
1622
|
-
const
|
|
1623
|
-
const
|
|
1624
|
-
|
|
1718
|
+
const isArrayValue = (value) => Array.isArray(value);
|
|
1719
|
+
const isMapValue = (value) => value instanceof Map;
|
|
1720
|
+
const isSetValue = (value) => value instanceof Set;
|
|
1721
|
+
const freezeArrayValue = (value) => Object.freeze(value.map((element) => deepFreeze(element)));
|
|
1722
|
+
const freezeMapEntry = ([entryKey, entryValue]) => [deepFreeze(entryKey), deepFreeze(entryValue)];
|
|
1723
|
+
const freezeMapValue = (value) => Object.freeze(new Map([...value.entries()].map(freezeMapEntry)));
|
|
1724
|
+
const freezeSetValue = (value) => Object.freeze(new Set([...value.values()].map((element) => deepFreeze(element))));
|
|
1725
|
+
const freezeRegExpValue = (value) => Object.freeze(value);
|
|
1726
|
+
const freezeRecordValue = (value) => Object.freeze(Object.entries(value).reduce((frozen, [property, propertyValue]) => {
|
|
1727
|
+
frozen[property] = deepFreeze(propertyValue);
|
|
1625
1728
|
return frozen;
|
|
1626
1729
|
}, {}));
|
|
1627
|
-
function deepFreeze
|
|
1628
|
-
return Match.value(target).pipe(Match.when(isArrayValue
|
|
1629
|
-
}
|
|
1630
|
-
const scopedUnserializable$1 = (scope) => (description) => ({
|
|
1631
|
-
...description,
|
|
1632
|
-
path: [scope, ...description.path]
|
|
1633
|
-
});
|
|
1634
|
-
const describeUnserializableChild$1 = (child, scope) => Match.value(findUnserializables$1(child)).pipe(Match.when(void 0, () => []), Match.orElse((descriptions) => descriptions.map(scopedUnserializable$1(scope))));
|
|
1635
|
-
const collectUnserializables$1 = (groups) => {
|
|
1636
|
-
const found = groups.flat();
|
|
1637
|
-
if (found.length > 0) return found;
|
|
1638
|
-
};
|
|
1639
|
-
const describeUnserializableArray$1 = (value) => collectUnserializables$1(value.map((child, index) => describeUnserializableChild$1(child, index.toString())));
|
|
1640
|
-
const describeUnserializableRecord$1 = (value) => collectUnserializables$1(Object.entries(value).map(([key, child]) => describeUnserializableChild$1(child, key)));
|
|
1641
|
-
const isPlainObjectValue$1 = (value) => !Array.isArray(value) && value.constructor === Object;
|
|
1642
|
-
const classNameOf$1 = (value) => Match.value(value.constructor).pipe(Match.when(Match.defined, (ctor) => ctor.name), Match.orElse(() => "Object"));
|
|
1643
|
-
const describeUnserializableInstance$1 = (value) => [{
|
|
1644
|
-
path: [],
|
|
1645
|
-
reason: `Value is an instance of "${classNameOf$1(value)}", this detail will get lost in translation during serialization`
|
|
1646
|
-
}];
|
|
1647
|
-
const describeUnserializableObject$1 = (value) => Match.value(value).pipe(Match.when(isArrayValue$1, describeUnserializableArray$1), Match.when(isPlainObjectValue$1, describeUnserializableRecord$1), Match.orElse(describeUnserializableInstance$1));
|
|
1648
|
-
const NON_JSON_PRIMITIVE_TYPES$1 = [
|
|
1649
|
-
"bigint",
|
|
1650
|
-
"function",
|
|
1651
|
-
"symbol"
|
|
1652
|
-
];
|
|
1653
|
-
const isNonJsonPrimitive$1 = (value) => NON_JSON_PRIMITIVE_TYPES$1.includes(typeof value);
|
|
1654
|
-
const describeNonJsonPrimitive$1 = (value) => [{
|
|
1655
|
-
path: [],
|
|
1656
|
-
reason: `Primitive type "${typeof value}" has no JSON representation`
|
|
1657
|
-
}];
|
|
1658
|
-
const describeNumber$1 = (value) => {
|
|
1659
|
-
if (isFinite(value)) return void 0;
|
|
1660
|
-
return [{
|
|
1661
|
-
reason: `Number value \`${value}\` has no JSON representation`,
|
|
1662
|
-
path: []
|
|
1663
|
-
}];
|
|
1664
|
-
};
|
|
1665
|
-
function findUnserializables$1(thing) {
|
|
1666
|
-
return Match.value(thing).pipe(Match.when((value) => typeof value === "number", describeNumber$1), Match.when(isNonJsonPrimitive$1, describeNonJsonPrimitive$1), Match.when(isNonNullObject$1, describeUnserializableObject$1), Match.orElse(() => void 0));
|
|
1730
|
+
function deepFreeze(target) {
|
|
1731
|
+
return Match.value(target).pipe(Match.when(isArrayValue, freezeArrayValue), Match.when(isMapValue, freezeMapValue), Match.when((value) => value instanceof RegExp, freezeRegExpValue), Match.when(isSetValue, freezeSetValue), Match.when(isRecordValue, freezeRecordValue), Match.orElse(() => target));
|
|
1667
1732
|
}
|
|
1668
|
-
function isWarningEnabled
|
|
1733
|
+
function isWarningEnabled(warningType, warningOptions) {
|
|
1669
1734
|
if (typeof warningOptions === "boolean") return warningOptions;
|
|
1670
1735
|
else return warningOptions[warningType] === true;
|
|
1671
1736
|
}
|
|
@@ -1724,10 +1789,18 @@ const mergePluginDescriptors = (parentPlugins, childPlugins) => {
|
|
|
1724
1789
|
const merged = [...parentPlugins, ...childPlugins];
|
|
1725
1790
|
return merged.filter(isFirstDescriptorOccurrence(merged));
|
|
1726
1791
|
};
|
|
1727
|
-
const
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1792
|
+
const isConfigOptionsRecord = (value) => isNonNullObject(value) && Array.isArray(value) === false;
|
|
1793
|
+
function mergeConfigRecords(parentNested, childNested) {
|
|
1794
|
+
return {
|
|
1795
|
+
...parentNested,
|
|
1796
|
+
...childNested
|
|
1797
|
+
};
|
|
1798
|
+
}
|
|
1799
|
+
const toConfigRecordOption = (value) => isConfigOptionsRecord(value) ? Option.some(value) : Option.none();
|
|
1800
|
+
const inheritNested = (parentValue, childValue) => Option.match(Option.all([toConfigRecordOption(parentValue), toConfigRecordOption(childValue)]), {
|
|
1801
|
+
onSome: ([parentNested, childNested]) => mergeConfigRecords(parentNested, childNested),
|
|
1802
|
+
onNone: () => childValue
|
|
1803
|
+
});
|
|
1731
1804
|
const inheritEntry = (out, key, parentValue, childValue) => Match.value(childValue).pipe(Match.when(null, () => {
|
|
1732
1805
|
const next = { ...out };
|
|
1733
1806
|
delete next[key];
|
|
@@ -1742,14 +1815,14 @@ const inheritEntry = (out, key, parentValue, childValue) => Match.value(childVal
|
|
|
1742
1815
|
function mergeConfigs(parent, child) {
|
|
1743
1816
|
return Object.entries(child).reduce((out, entry) => inheritEntry(out, entry[0], parent[entry[0]], entry[1]), { ...parent });
|
|
1744
1817
|
}
|
|
1745
|
-
const RELATIVE_SPECIFIER_PREFIXES
|
|
1818
|
+
const RELATIVE_SPECIFIER_PREFIXES = [
|
|
1746
1819
|
"./",
|
|
1747
1820
|
"../",
|
|
1748
1821
|
"/",
|
|
1749
1822
|
"\\"
|
|
1750
1823
|
];
|
|
1751
|
-
function isModuleSpecifier
|
|
1752
|
-
return RELATIVE_SPECIFIER_PREFIXES
|
|
1824
|
+
function isModuleSpecifier(value) {
|
|
1825
|
+
return RELATIVE_SPECIFIER_PREFIXES.every((prefix) => value.startsWith(prefix) === false);
|
|
1753
1826
|
}
|
|
1754
1827
|
const stripExtends = (document) => {
|
|
1755
1828
|
const { extends: _ignored, ...rest } = document;
|
|
@@ -1768,7 +1841,7 @@ const decideExtendsStep = (state, document, file, pathService) => {
|
|
|
1768
1841
|
options: document
|
|
1769
1842
|
}]
|
|
1770
1843
|
};
|
|
1771
|
-
return Match.value(document["extends"]).pipe(Match.when(void 0, () => ExtendsStepDone.make({ options: mergeChainDocuments(nextState.documents) })), Match.when(null, () => ExtendsStepDone.make({ options: mergeChainDocuments(nextState.documents) })), Match.when(Match.string, (extendValue) => Match.value(isModuleSpecifier
|
|
1844
|
+
return Match.value(document["extends"]).pipe(Match.when(void 0, () => ExtendsStepDone.make({ options: mergeChainDocuments(nextState.documents) })), Match.when(null, () => ExtendsStepDone.make({ options: mergeChainDocuments(nextState.documents) })), Match.when(Match.string, (extendValue) => Match.value(isModuleSpecifier(extendValue)).pipe(Match.when(true, () => ExtendsStepResolve.make({
|
|
1772
1845
|
specifier: extendValue,
|
|
1773
1846
|
state: nextState
|
|
1774
1847
|
})), Match.when(false, () => ExtendsStepRead.make({
|
|
@@ -1783,15 +1856,20 @@ const decodeConfigDocument = (configFile, document) => S.decodeUnknownEffect(Con
|
|
|
1783
1856
|
file: configFile,
|
|
1784
1857
|
cause
|
|
1785
1858
|
})));
|
|
1786
|
-
const
|
|
1859
|
+
const failInvalidConfig = (configFile, cause) => Effect$1.fail(ConfigFileInvalidError.make({
|
|
1787
1860
|
file: configFile,
|
|
1788
|
-
cause
|
|
1789
|
-
}))
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1861
|
+
cause
|
|
1862
|
+
}));
|
|
1863
|
+
const requireDefaultExport = (configFile, defaultExport) => defaultExport === void 0 ? failInvalidConfig(configFile, "Config file must have a default export!") : settleObjectExport(configFile, defaultExport);
|
|
1864
|
+
function settleObjectExport(configFile, value) {
|
|
1865
|
+
return isNonNullObject(value) ? Effect$1.succeed(value) : failInvalidConfig(configFile, "Default export of config file must be an object!");
|
|
1866
|
+
}
|
|
1793
1867
|
const isConfigFactory = (value) => typeof value === "function";
|
|
1794
|
-
|
|
1868
|
+
function wrappedFactoryFailure(error) {
|
|
1869
|
+
return new Error(`Evaluating the config module's exported factory failed: ${error.message}`, { cause: error });
|
|
1870
|
+
}
|
|
1871
|
+
const factoryFailureCause = (cause) => cause instanceof Error ? wrappedFactoryFailure(cause) : cause;
|
|
1872
|
+
const applyConfigFactory = (factory, configEnv) => factory(configEnv);
|
|
1795
1873
|
/**
|
|
1796
1874
|
* Settle a config module's default export into the object the document schema decodes.
|
|
1797
1875
|
*
|
|
@@ -1802,7 +1880,7 @@ const factoryFailureCause = (cause) => Match.value(cause).pipe(Match.when(Match.
|
|
|
1802
1880
|
* non-null object and would otherwise reach the document decoder as one.
|
|
1803
1881
|
*/
|
|
1804
1882
|
const settleConfigDefault = (configFile, defaultExport, configEnv) => Effect$1.tryPromise({
|
|
1805
|
-
try: () => Promise.resolve(defaultExport).then((exported) =>
|
|
1883
|
+
try: () => Promise.resolve(defaultExport).then((exported) => isConfigFactory(exported) ? applyConfigFactory(exported, configEnv) : exported),
|
|
1806
1884
|
catch: (cause) => ConfigFileInvalidError.make({
|
|
1807
1885
|
file: configFile,
|
|
1808
1886
|
cause: factoryFailureCause(cause)
|
|
@@ -1810,14 +1888,14 @@ const settleConfigDefault = (configFile, defaultExport, configEnv) => Effect$1.t
|
|
|
1810
1888
|
}).pipe(Effect$1.flatMap((settled) => requireDefaultExport(configFile, settled)));
|
|
1811
1889
|
const ERASABLE_SYNTAX_HELP = "Config modules may use only erasable TypeScript syntax: no enums, no namespaces with runtime code, no parameter properties, and no decorators.";
|
|
1812
1890
|
const carriesCode = (cause) => cause instanceof Error && "code" in cause;
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
const errorMessageOf = (cause) =>
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
}
|
|
1891
|
+
function codeOf(coded) {
|
|
1892
|
+
return typeof coded.code === "string" ? coded.code : void 0;
|
|
1893
|
+
}
|
|
1894
|
+
const errorCodeOf = (cause) => carriesCode(cause) ? codeOf(cause) : void 0;
|
|
1895
|
+
const errorMessageOf = (cause) => cause instanceof Error ? errorTextOf(cause) : void 0;
|
|
1896
|
+
function errorTextOf(error) {
|
|
1897
|
+
return typeof error.message === "string" ? error.message : void 0;
|
|
1898
|
+
}
|
|
1821
1899
|
const importFailureDetail = (failure) => errorMessageOf(failure.cause) ?? failure.message;
|
|
1822
1900
|
const configImportCause = (configFile, failure) => Match.value(errorCodeOf(failure.cause)).pipe(Match.when("ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX", () => new Error(`The config file "${configFile}" uses TypeScript syntax Node cannot execute. ${ERASABLE_SYNTAX_HELP}`, { cause: failure.cause })), Match.when("ERR_UNKNOWN_FILE_EXTENSION", () => new Error(`The config file "${configFile}" has an extension Node cannot load. Stryker reads config modules with ${SUPPORTED_CONFIG_FILE_EXTENSION_GUIDE}.`, { cause: failure.cause })), Match.when("ERR_MODULE_NOT_FOUND", () => new Error(`The config file "${configFile}" imports a module Node cannot find. The specifier is most likely not installed — install it as a dependency of the project, or remove the import. Node reported: ${importFailureDetail(failure)}`, { cause: failure.cause })), Match.when("ERR_PACKAGE_PATH_NOT_EXPORTED", () => new Error(`The config file "${configFile}" imports a path a package does not export. The package is installed but its "exports" map leaves this specifier out — import a path the package publishes. Node reported: ${importFailureDetail(failure)}`, { cause: failure.cause })), Match.orElse(() => failure));
|
|
1823
1901
|
const configModuleUrl = (configFile, pathService) => Match.value(configFile.startsWith("file:")).pipe(Match.when(true, () => Effect$1.try({
|
|
@@ -1894,7 +1972,7 @@ function recordOf(value) {
|
|
|
1894
1972
|
return { ...value };
|
|
1895
1973
|
}
|
|
1896
1974
|
const thresholdErrors = (options) => Match.value(options.thresholds.high < options.thresholds.low).pipe(Match.when(true, () => ["Config option \"thresholds.high\" should be higher than \"thresholds.low\"."]), Match.orElse(() => []));
|
|
1897
|
-
const ignoreStaticErrors = (options) => Match.value(options.ignoreStatic && options.coverageAnalysis !== "perTest").pipe(Match.when(true, () => [`Config option "${optionsPath
|
|
1975
|
+
const ignoreStaticErrors = (options) => Match.value(options.ignoreStatic && options.coverageAnalysis !== "perTest").pipe(Match.when(true, () => [`Config option "${optionsPath("ignoreStatic")}" is not supported with coverage analysis "${options.coverageAnalysis}". Either turn off "${optionsPath("ignoreStatic")}", or configure "${optionsPath("coverageAnalysis")}" to be "perTest".`]), Match.orElse(() => []));
|
|
1898
1976
|
const matchLineNumber = (match, group) => Number.parseInt(match[group] ?? "", 10);
|
|
1899
1977
|
const startLineErrors = (index, mutationRange, start) => Match.value(start < 1).pipe(Match.when(true, () => [`Config option "mutate[${index}]" is invalid. Mutation range "${mutationRange}" is invalid, line ${start} does not exist (lines start at 1).`]), Match.orElse(() => []));
|
|
1900
1978
|
const lineOrderErrors = (index, mutationRange, start, end) => Match.value(start > end).pipe(Match.when(true, () => [`Config option "mutate[${index}]" is invalid. Mutation range "${mutationRange}" is invalid. The "from" line number (${start}) should be less then the "to" line number (${end}).`]), Match.orElse(() => []));
|
|
@@ -1938,7 +2016,7 @@ const OPTIONS_ADDED_BY_STRYKER = [
|
|
|
1938
2016
|
"configFile",
|
|
1939
2017
|
"$schema"
|
|
1940
2018
|
];
|
|
1941
|
-
const schemaPropertyNames = (schema) => Match.value(schema["properties"]).pipe(Match.when(isNonNullObject
|
|
2019
|
+
const schemaPropertyNames = (schema) => Match.value(schema["properties"]).pipe(Match.when(isNonNullObject, (properties) => Object.keys(recordOf(properties))), Match.orElse(() => []));
|
|
1942
2020
|
const excessOptionNames = (options, schema) => {
|
|
1943
2021
|
const schemaKeys = schemaPropertyNames(schema);
|
|
1944
2022
|
return Object.keys(options).filter((key) => key.endsWith("_comment") === false).filter((key) => OPTIONS_ADDED_BY_STRYKER.includes(key) === false).filter((key) => schemaKeys.includes(key) === false);
|
|
@@ -1951,7 +2029,7 @@ const warnAboutUnknownOptions = (options, excessNames) => Effect$1.gen(function*
|
|
|
1951
2029
|
* Did you only write this property as a comment? If so, please postfix it with "_comment".
|
|
1952
2030
|
* You might be missing a plugin that is supposed to use it. Stryker loaded plugins from: ${pluginsJson}
|
|
1953
2031
|
* The plugin that is using it did not contribute explicit validation.
|
|
1954
|
-
(disable "${optionsPath
|
|
2032
|
+
(disable "${optionsPath("warnings", "unknownOptions")}" to ignore this warning)`);
|
|
1955
2033
|
});
|
|
1956
2034
|
const unknownOptionWarning = (options, schema) => {
|
|
1957
2035
|
const excessNames = excessOptionNames(options, schema);
|
|
@@ -1959,17 +2037,17 @@ const unknownOptionWarning = (options, schema) => {
|
|
|
1959
2037
|
};
|
|
1960
2038
|
function markExcessOptions(options, schema) {
|
|
1961
2039
|
return Effect$1.gen(function* () {
|
|
1962
|
-
if (isWarningEnabled
|
|
2040
|
+
if (isWarningEnabled("unknownOptions", options.warnings)) yield* unknownOptionWarning(options, schema);
|
|
1963
2041
|
});
|
|
1964
2042
|
}
|
|
1965
2043
|
const logUnserializableWarnings = (unserializables) => Effect$1.gen(function* () {
|
|
1966
2044
|
for (const unserializable of unserializables) yield* Effect$1.logWarning(`Config option "${unserializable.path.join(".")}" is not (fully) serializable. ${unserializable.reason}. Any test runner or checker worker processes might not receive this value as intended.`);
|
|
1967
|
-
yield* Effect$1.logWarning(`(disable ${optionsPath
|
|
2045
|
+
yield* Effect$1.logWarning(`(disable ${optionsPath("warnings", "unserializableOptions")} to ignore this warning)`);
|
|
1968
2046
|
});
|
|
1969
|
-
const warnAboutUnserializableOptions = (options) => Match.value(findUnserializables
|
|
2047
|
+
const warnAboutUnserializableOptions = (options) => Match.value(findUnserializables(options)).pipe(Match.when(void 0, () => Effect$1.void), Match.orElse((unserializables) => logUnserializableWarnings(unserializables)));
|
|
1970
2048
|
function markUnserializableOptions(options) {
|
|
1971
2049
|
return Effect$1.gen(function* () {
|
|
1972
|
-
if (isWarningEnabled
|
|
2050
|
+
if (isWarningEnabled("unserializableOptions", options.warnings)) yield* warnAboutUnserializableOptions(options);
|
|
1973
2051
|
});
|
|
1974
2052
|
}
|
|
1975
2053
|
function markOptions(options, schema) {
|
|
@@ -1986,8 +2064,8 @@ function validateOptions(options, schema) {
|
|
|
1986
2064
|
return typed;
|
|
1987
2065
|
});
|
|
1988
2066
|
}
|
|
1989
|
-
const createDefaultOptions
|
|
1990
|
-
Effect$1.map(createDefaultOptions
|
|
2067
|
+
const createDefaultOptions = S.decodeEffect(StrykerOptionsSchema)({}).pipe(Effect$1.orDie);
|
|
2068
|
+
Effect$1.map(createDefaultOptions, (opts) => deepFreeze(opts));
|
|
1991
2069
|
`
|
|
1992
2070
|
Example of how a config file should look:
|
|
1993
2071
|
/**
|
|
@@ -2021,7 +2099,7 @@ const firstExistingConfigFile = (fileNames) => Option.match(Option.fromUndefined
|
|
|
2021
2099
|
});
|
|
2022
2100
|
const configFileFor = (configFileName) => Effect$1.gen(function* () {
|
|
2023
2101
|
const pathService = yield* Path.Path;
|
|
2024
|
-
const supported = SUPPORTED_CONFIG_FILE_EXTENSIONS
|
|
2102
|
+
const supported = SUPPORTED_CONFIG_FILE_EXTENSIONS.includes(configFileExtension(configFileName, pathService));
|
|
2025
2103
|
const legacy = isLegacyConfigFile(configFileName, pathService);
|
|
2026
2104
|
return yield* Match.value(supported).pipe(Match.when(true, () => requireExistingConfigFile(configFileName)), Match.orElse(() => Effect$1.fail(ConfigFileUnsupportedError.make({
|
|
2027
2105
|
file: configFileName,
|
|
@@ -2042,14 +2120,14 @@ const warnShadowedLegacyConfig = (supportedFile) => firstLegacyConfigFile().pipe
|
|
|
2042
2120
|
onNone: () => Effect$1.succeed(supportedFile),
|
|
2043
2121
|
onSome: (file) => Effect$1.as(legacyConfigWarning(file, supportedFile), supportedFile)
|
|
2044
2122
|
})));
|
|
2045
|
-
const discoverConfigFile = () => firstExistingConfigFile([...SUPPORTED_CONFIG_FILE_NAMES
|
|
2123
|
+
const discoverConfigFile = () => firstExistingConfigFile([...SUPPORTED_CONFIG_FILE_NAMES]).pipe(Effect$1.flatMap((found) => Option.match(found, {
|
|
2046
2124
|
onNone: () => refuseLegacyOnlyProject().pipe(Effect$1.map((legacy) => Option.getOrUndefined(legacy))),
|
|
2047
2125
|
onSome: (supportedFile) => warnShadowedLegacyConfig(supportedFile)
|
|
2048
2126
|
})));
|
|
2049
2127
|
function findConfigFile(configFileName) {
|
|
2050
|
-
return
|
|
2128
|
+
return typeof configFileName === "string" ? configFileFor(configFileName) : discoverConfigFile();
|
|
2051
2129
|
}
|
|
2052
|
-
const resolveChildExtends = (configFile, child, configEnv) =>
|
|
2130
|
+
const resolveChildExtends = (configFile, child, configEnv) => "extends" in child ? resolveExtends(configFile, child, configEnv) : Effect$1.succeed(child);
|
|
2053
2131
|
const isCiEnvironment = Config.String("CI").pipe(Effect$1.map((value) => Match.value(value.trim().toLowerCase()).pipe(Match.when("", () => false), Match.when("0", () => false), Match.when("false", () => false), Match.orElse(() => true))), Effect$1.orElseSucceed(() => false));
|
|
2054
2132
|
function loadOptionsFromConfigFile(cliOptions, configEnv) {
|
|
2055
2133
|
return findConfigFile(cliOptions["configFile"]).pipe(Effect$1.flatMap((configFile) => Match.value(configFile).pipe(Match.when(void 0, () => Effect$1.succeed({})), Match.orElse((found) => readConfigModule(found, configEnv).pipe(Effect$1.flatMap((child) => resolveChildExtends(found, child, configEnv)))))));
|
|
@@ -2064,7 +2142,7 @@ function readConfig(cliOptions, invocation) {
|
|
|
2064
2142
|
};
|
|
2065
2143
|
const cliRecord = yield* S.decodeEffect(ConfigDocumentSchema)(cliOptions).pipe(Effect$1.orDie);
|
|
2066
2144
|
const fileRecord = yield* loadOptionsFromConfigFile(cliRecord, configEnv);
|
|
2067
|
-
const fileOptions = yield* Result.match(S.
|
|
2145
|
+
const fileOptions = yield* Result.match(S.decodeResult(ConfigDocumentSchema)(fileRecord), {
|
|
2068
2146
|
onFailure: (cause) => Effect$1.fail(ConfigFileInvalidError.make({
|
|
2069
2147
|
file: "config",
|
|
2070
2148
|
cause
|
|
@@ -2182,7 +2260,9 @@ const failPluginLoad = (descriptor, error) => Effect$1.logWarning(`Error during
|
|
|
2182
2260
|
}))));
|
|
2183
2261
|
const modulePluginContributions = (module) => Match.value(Predicate.hasProperty(module, "strykerPlugins")).pipe(Match.when(true, () => Schema.decodeUnknownResult(PluginModuleSchema)(module).pipe(Result.map((pluginModule) => pluginModule.strykerPlugins))), Match.orElse(() => Result.succeed(void 0)));
|
|
2184
2262
|
const moduleIgnorers = (module) => Match.value(Predicate.hasProperty(module, "strykerIgnorers")).pipe(Match.when(true, () => Schema.decodeUnknownResult(IgnorerModuleSchema)(module).pipe(Result.map((ignorerModule) => ignorerModule.strykerIgnorers))), Match.orElse(() => Result.succeed(void 0)));
|
|
2185
|
-
const moduleSchemaContribution = (module) =>
|
|
2263
|
+
const moduleSchemaContribution = (module) => {
|
|
2264
|
+
if (hasValidationSchemaContribution(module)) return module.strykerValidationSchema;
|
|
2265
|
+
};
|
|
2186
2266
|
const pluginContributionsOf = (module) => Result.flatMap(moduleIgnorers(module), (ignorers) => Result.map(modulePluginContributions(module), (plugins) => ({
|
|
2187
2267
|
plugins,
|
|
2188
2268
|
ignorers,
|
|
@@ -2713,96 +2793,6 @@ const planInstrumentation = Workflow.make(InstrumentCommand, (command) => Match.
|
|
|
2713
2793
|
fileCount: command.fileCount
|
|
2714
2794
|
})))));
|
|
2715
2795
|
//#endregion
|
|
2716
|
-
//#region src/config-defaults.ts
|
|
2717
|
-
const isNonNullObject = (value) => typeof value === "object" && value !== null;
|
|
2718
|
-
const isArrayValue = (value) => Array.isArray(value);
|
|
2719
|
-
const freezeArrayValue = (value) => Object.freeze(value.map(deepFreeze));
|
|
2720
|
-
const freezeMapEntry = ([entryKey, entryValue]) => [deepFreeze(entryKey), deepFreeze(entryValue)];
|
|
2721
|
-
const freezeMapValue = (value) => Object.freeze(new Map([...value.entries()].map(freezeMapEntry)));
|
|
2722
|
-
const freezeSetValue = (value) => Object.freeze(new Set([...value.values()].map(deepFreeze)));
|
|
2723
|
-
const freezeRegExpValue = (value) => Object.freeze(value);
|
|
2724
|
-
const freezeRecordValue = (value) => Object.freeze(Object.entries(value).reduce((frozen, [property, propertyValue]) => {
|
|
2725
|
-
frozen[property] = deepFreeze(propertyValue);
|
|
2726
|
-
return frozen;
|
|
2727
|
-
}, {}));
|
|
2728
|
-
function deepFreeze(target) {
|
|
2729
|
-
return Match.value(target).pipe(Match.when(isArrayValue, freezeArrayValue), Match.when((value) => value instanceof Map, freezeMapValue), Match.when((value) => value instanceof RegExp, freezeRegExpValue), Match.when((value) => value instanceof Set, freezeSetValue), Match.when(isNonNullObject, freezeRecordValue), Match.orElse(() => target));
|
|
2730
|
-
}
|
|
2731
|
-
const optionsPath = (...path) => path.join(".");
|
|
2732
|
-
const SUPPORTED_CONFIG_FILE_EXTENSIONS = [
|
|
2733
|
-
".ts",
|
|
2734
|
-
".mts",
|
|
2735
|
-
".js",
|
|
2736
|
-
".mjs"
|
|
2737
|
-
];
|
|
2738
|
-
const configFileNames = (extensions) => extensions.map((extension) => `stryker.config${extension}`);
|
|
2739
|
-
const SUPPORTED_CONFIG_FILE_NAMES = Object.freeze(configFileNames(SUPPORTED_CONFIG_FILE_EXTENSIONS));
|
|
2740
|
-
const RELATIVE_SPECIFIER_PREFIXES = [
|
|
2741
|
-
"/",
|
|
2742
|
-
"./",
|
|
2743
|
-
"../",
|
|
2744
|
-
"file://"
|
|
2745
|
-
];
|
|
2746
|
-
function isModuleSpecifier(value) {
|
|
2747
|
-
return RELATIVE_SPECIFIER_PREFIXES.every((prefix) => value.startsWith(prefix) === false);
|
|
2748
|
-
}
|
|
2749
|
-
const CONFIG_SYNTAX_HELP = `
|
|
2750
|
-
Example of how a config file should look:
|
|
2751
|
-
/**
|
|
2752
|
-
* @type {import('@systemfsoftware/stryker-js-plugin-interface').StrykerOptions}
|
|
2753
|
-
*/
|
|
2754
|
-
export default {
|
|
2755
|
-
mutate: ['src/**/*.js'],
|
|
2756
|
-
testRunner: 'vitest',
|
|
2757
|
-
reporters: ['progress', 'clear-text', 'html'],
|
|
2758
|
-
concurrency: 4
|
|
2759
|
-
};
|
|
2760
|
-
See https://stryker-mutator.io/docs/stryker-js/config-file for more information.`.trim();
|
|
2761
|
-
const createDefaultOptions = S.decodeEffect(StrykerOptionsSchema)({}).pipe(Effect$1.orDie);
|
|
2762
|
-
const defaultOptions = Effect$1.map(createDefaultOptions, (opts) => deepFreeze(opts));
|
|
2763
|
-
const scopedUnserializable = (scope) => (description) => ({
|
|
2764
|
-
...description,
|
|
2765
|
-
path: [scope, ...description.path]
|
|
2766
|
-
});
|
|
2767
|
-
const describeUnserializableChild = (child, scope) => Match.value(findUnserializables(child)).pipe(Match.when(void 0, () => []), Match.orElse((descriptions) => descriptions.map(scopedUnserializable(scope))));
|
|
2768
|
-
const collectUnserializables = (groups) => {
|
|
2769
|
-
const found = groups.flat();
|
|
2770
|
-
if (found.length > 0) return found;
|
|
2771
|
-
};
|
|
2772
|
-
const describeUnserializableArray = (value) => collectUnserializables(value.map((child, index) => describeUnserializableChild(child, index.toString())));
|
|
2773
|
-
const describeUnserializableRecord = (value) => collectUnserializables(Object.entries(value).map(([key, child]) => describeUnserializableChild(child, key)));
|
|
2774
|
-
const isPlainObjectValue = (value) => !Array.isArray(value) && value.constructor === Object;
|
|
2775
|
-
const classNameOf = (value) => Match.value(value.constructor).pipe(Match.when(Match.defined, (ctor) => ctor.name), Match.orElse(() => "Object"));
|
|
2776
|
-
const describeUnserializableInstance = (value) => [{
|
|
2777
|
-
path: [],
|
|
2778
|
-
reason: `Value is an instance of "${classNameOf(value)}", this detail will get lost in translation during serialization`
|
|
2779
|
-
}];
|
|
2780
|
-
const describeUnserializableObject = (value) => Match.value(value).pipe(Match.when(isArrayValue, describeUnserializableArray), Match.when(isPlainObjectValue, describeUnserializableRecord), Match.orElse(describeUnserializableInstance));
|
|
2781
|
-
const NON_JSON_PRIMITIVE_TYPES = [
|
|
2782
|
-
"bigint",
|
|
2783
|
-
"function",
|
|
2784
|
-
"symbol"
|
|
2785
|
-
];
|
|
2786
|
-
const isNonJsonPrimitive = (value) => NON_JSON_PRIMITIVE_TYPES.includes(typeof value);
|
|
2787
|
-
const describeNonJsonPrimitive = (value) => [{
|
|
2788
|
-
path: [],
|
|
2789
|
-
reason: `Primitive type "${typeof value}" has no JSON representation`
|
|
2790
|
-
}];
|
|
2791
|
-
const describeNumber = (value) => {
|
|
2792
|
-
if (isFinite(value)) return void 0;
|
|
2793
|
-
return [{
|
|
2794
|
-
reason: `Number value \`${value}\` has no JSON representation`,
|
|
2795
|
-
path: []
|
|
2796
|
-
}];
|
|
2797
|
-
};
|
|
2798
|
-
function findUnserializables(thing) {
|
|
2799
|
-
return Match.value(thing).pipe(Match.when((value) => typeof value === "number", describeNumber), Match.when(isNonJsonPrimitive, describeNonJsonPrimitive), Match.when(isNonNullObject, describeUnserializableObject), Match.orElse(() => void 0));
|
|
2800
|
-
}
|
|
2801
|
-
function isWarningEnabled(warningType, warningOptions) {
|
|
2802
|
-
if (typeof warningOptions === "boolean") return warningOptions;
|
|
2803
|
-
else return warningOptions[warningType] === true;
|
|
2804
|
-
}
|
|
2805
|
-
//#endregion
|
|
2806
2796
|
//#region src/IncrementalReport.schema.ts
|
|
2807
2797
|
const PositionSchema = S.Struct({
|
|
2808
2798
|
line: S.Finite,
|
|
@@ -2893,7 +2883,7 @@ const decide = (command) => Option.match(Option.fromUndefinedOr(command.report),
|
|
|
2893
2883
|
const admitIncrementalReport = Workflow.total(AdmitIncrementalReportCommand, (command) => Result.succeed(decide(command)));
|
|
2894
2884
|
//#endregion
|
|
2895
2885
|
//#region src/stryker-package.ts
|
|
2896
|
-
const strykerVersion = "10.1.
|
|
2886
|
+
const strykerVersion = "10.1.1";
|
|
2897
2887
|
//#endregion
|
|
2898
2888
|
//#region src/incremental-report.cell.ts
|
|
2899
2889
|
const parseAndDecodeIncrementalReport = S.decodeUnknownResult(S.fromJsonString(IncrementalReportSchema));
|
|
@@ -3325,7 +3315,7 @@ function readProject(options, targetMutatePatterns, basePath) {
|
|
|
3325
3315
|
];
|
|
3326
3316
|
return Effect$1.gen(function* () {
|
|
3327
3317
|
const inputFileNames = yield* resolveInputFileNames(ignoreRules, basePath);
|
|
3328
|
-
const defaults = yield* defaultOptions;
|
|
3318
|
+
const defaults = yield* defaultOptions$1;
|
|
3329
3319
|
const decision = selectFiles((() => {
|
|
3330
3320
|
if (targetMutatePatterns === void 0) return {
|
|
3331
3321
|
inputFileNames,
|
|
@@ -3667,7 +3657,7 @@ const makeDisableTypeChecksPreprocessor = (options, impl) => (project) => Effect
|
|
|
3667
3657
|
message: "disableTypeChecks failed",
|
|
3668
3658
|
cause
|
|
3669
3659
|
})), Effect$1.tapError(() => Effect$1.gen(function* () {
|
|
3670
|
-
if (isWarningEnabled("preprocessorErrors", options.warnings)) yield* Effect$1.logWarning(`Unable to disable type checking for file "${name}". Shouldn't type checking be disabled for this file? Consider configuring a more restrictive "${optionsPath("disableTypeChecks")}" settings (or turn it completely off with \`false\`)`);
|
|
3660
|
+
if (isWarningEnabled$1("preprocessorErrors", options.warnings)) yield* Effect$1.logWarning(`Unable to disable type checking for file "${name}". Shouldn't type checking be disabled for this file? Consider configuring a more restrictive "${optionsPath$1("disableTypeChecks")}" settings (or turn it completely off with \`false\`)`);
|
|
3671
3661
|
})), Effect$1.orElseSucceed(() => void 0));
|
|
3672
3662
|
if (content !== void 0) return withContent(file, content);
|
|
3673
3663
|
})), Match.orElse(() => Effect$1.succeedNone)), { concurrency: 24 })).forEach(mergeUpdatedInto(project));
|
|
@@ -3695,7 +3685,10 @@ const parseJsonText = (jsonText) => {
|
|
|
3695
3685
|
return Result.fail(errorToString(error));
|
|
3696
3686
|
}
|
|
3697
3687
|
};
|
|
3698
|
-
const parseTsConfigShape = (fileName, parsed) =>
|
|
3688
|
+
const parseTsConfigShape = (fileName, parsed) => {
|
|
3689
|
+
if (Schema.is(TsConfigSchema)(parsed)) return Result.succeed(parsed);
|
|
3690
|
+
return Result.fail(tsConfigParseError(fileName, `parsed to ${JSON.stringify(parsed)}, which does not match the tsconfig shape this package consumes`));
|
|
3691
|
+
};
|
|
3699
3692
|
function parseTsConfig(fileName, jsonText) {
|
|
3700
3693
|
return Result.match(parseJsonText(jsonText), {
|
|
3701
3694
|
onFailure: (reason) => Result.fail(tsConfigParseError(fileName, reason)),
|
|
@@ -5127,8 +5120,8 @@ const reportDroppedMutants = (dropped) => Match.value(dropped.length).pipe(Match
|
|
|
5127
5120
|
yield* Metric.update(checkerMutantsSkipped, dropped.length);
|
|
5128
5121
|
yield* Effect$1.logWarning(`${dropped.length} mutant(s) cannot be described to a checker and were left out of the run (${droppedIdsOf(dropped)})`);
|
|
5129
5122
|
})));
|
|
5130
|
-
const
|
|
5131
|
-
const reasonOf = (result) =>
|
|
5123
|
+
const stringReasonOrUndefined = (val) => typeof val === "string" ? val : void 0;
|
|
5124
|
+
const reasonOf = (result) => "reason" in result ? stringReasonOrUndefined(result.reason) : void 0;
|
|
5132
5125
|
const stopWallClock = (result) => {
|
|
5133
5126
|
if (!wallClockTimeoutStopsRun(result.status, reasonOf(result))) return Effect$1.void;
|
|
5134
5127
|
return Effect$1.fail(StageError.make({
|
|
@@ -5595,7 +5588,7 @@ const drawMutationScoreTable = (metricsResult, options) => {
|
|
|
5595
5588
|
//#endregion
|
|
5596
5589
|
//#region src/Reporter.schema.ts
|
|
5597
5590
|
var ClearTextReportCommand = class extends S.TaggedClass()("ClearTextReportCommand", {
|
|
5598
|
-
report: MutationTestResultSchema
|
|
5591
|
+
report: MutationTestResultSchema,
|
|
5599
5592
|
metrics: MetricsResultSchema
|
|
5600
5593
|
}) {};
|
|
5601
5594
|
//#endregion
|
|
@@ -6079,9 +6072,7 @@ var MachineReporters = class extends S.TaggedClass()("MachineReporters", { repor
|
|
|
6079
6072
|
const planPrepare = Workflow.total(PrepareDecoded, (decoded) => Match.value(decoded.mode).pipe(Match.when("human", () => Result.succeed(HumanReporters.make({ reporters: decoded.reporters }))), Match.when("machine", () => Result.succeed(MachineReporters.make({ reporters: decoded.reporters }))), Match.exhaustive));
|
|
6080
6073
|
//#endregion
|
|
6081
6074
|
//#region src/run/prepare.cell.ts
|
|
6082
|
-
const
|
|
6083
|
-
const asRecord = (value) => Match.value(value).pipe(Match.when(isRecord, (record) => Object.fromEntries(Object.entries(record))), Match.orElse(() => ({})));
|
|
6084
|
-
const schemaPropertiesOf = (document) => asRecord(asRecord(document)["properties"]);
|
|
6075
|
+
const schemaPropertiesOf = (document) => Option.getOrElse(Option.fromNullishOr(document.properties), () => ({}));
|
|
6085
6076
|
const buildMergedSchema = (core, contributions) => Match.value(contributions.length === 0).pipe(Match.when(true, () => core), Match.orElse(() => ({
|
|
6086
6077
|
...core,
|
|
6087
6078
|
properties: Object.assign({}, schemaPropertiesOf(core), ...contributions.map((contribution) => schemaPropertiesOf(contribution)))
|
|
@@ -6385,7 +6376,6 @@ const makeRunEventStream = (resolved) => Effect$1.gen(function* () {
|
|
|
6385
6376
|
const RunEventStreamLive = Layer.succeed(RunEventStreamPort, RunEventStreamPort.of({ createRunEventStream: (resolved) => makeRunEventStream(resolved) }));
|
|
6386
6377
|
//#endregion
|
|
6387
6378
|
//#region ../stryker-js-html-reporter/dist/index.mjs
|
|
6388
|
-
const MutationTestResultSchema = S.Unknown;
|
|
6389
6379
|
var HtmlReportCommand = class extends S.TaggedClass()("HtmlReportCommand", {
|
|
6390
6380
|
report: MutationTestResultSchema,
|
|
6391
6381
|
scriptContent: S.String
|
|
@@ -6515,4 +6505,4 @@ const strykerCell = (options, targetMutatePatterns) => Effect$1.gen(function* ()
|
|
|
6515
6505
|
}, prepareCommandOf(options, patterns));
|
|
6516
6506
|
});
|
|
6517
6507
|
//#endregion
|
|
6518
|
-
export {
|
|
6508
|
+
export { OutOfMemoryError as $, strykerVersion as A, defaultOptions$1 as At, initialExtendsStepState as B, checkerMutantsSkipped as C, extendsPropertySchema as Ct, CheckerSkippedRequested as D, SUPPORTED_CONFIG_FILE_NAMES$1 as Dt, CheckerAnsweredUnrequested as E, CONFIG_SYNTAX_HELP$1 as Et, spawnReporterWorker as F, toRelativeNormalizedFileName as Ft, buildTestRunner as G, mergeConfigs as H, decideExtendsStep as I, RunEvents as It, connectRetry as J, isCommandRunner as K, describeErrors as L, RunIdentity as Lt, RunEnvironment as M, isModuleSpecifier$1 as Mt, REPORTER_EVENT_BATCH_BOUND as N, isWarningEnabled$1 as Nt, createFileMatcher as O, createDefaultOptions$1 as Ot, reporterWorkerFactory as P, optionsPath$1 as Pt, ChildProcessCrashedError as Q, forkCoreSchema as R, RunEventWireLine as Rt, checkerMutantsChecked as S, ReadConfigCommand as St, checkerRpcFailures as T, survivorsPriorReport as Tt, readConfig as U, loadConfigCell as V, validateOptions as W, IdGenerator as X, makeWorkerClient as Y, classifyWorkerExit as Z, verdictExitClass as _, ExtendsStepResolve as _t, RUN_EVENTS_QUEUE_BOUND as a, vmTestRunner as at, checkGroupedPlans as b, MergeCommand as bt, shouldKeepTempDir as c, ConfigError as ct, buildVerdictEnvelope as d, ConfigFileUnreadableError as dt, WorkerBootTimeoutError as et, generateRunId as f, ConfigFileUnsupportedError as ft, resolveExitCode as g, ExtendsStepRefused as gt, highestExitClass as h, ExtendsStepRead as ht, makeRunEventStream as i, vmRunnerName as it, IncrementalReportSchema as j, findUnserializables as jt, matchesFile as k, deepFreeze$1 as kt, ACTIONABLE_STATUSES as l, ConfigFileInvalidError as lt, EXIT_CODE as m, ExtendsStepDone as mt, RunEventDrain as n, isVmRunner as nt, makeRunLayer as o, StrykerError as ot, isActionableStatus as p, ExtendsStepDocumentSchema as pt, WorkerLauncher as q, RunEventDrainLive as r, vmRunnerCapabilities as rt, mutationTestCell as s, ConfigDocumentSchema as st, strykerCell as t, VmRunner as tt, VERDICT_ENVELOPE_SCHEMA_VERSION as u, ConfigFileNotFoundError as ut, calculateMetrics as v, ExtendsStepStateSchema as vt, checkerProcessCrashes as w, forkOptionsSchema as wt, checkerDuration as x, MergeResult as xt, countMutants as y, ImportedModuleSchema as yt, importModule as z, S as zt };
|