@systemfsoftware/stryker-js 10.1.0 → 10.1.2
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 +14 -0
- package/dist/{Run.schema-B0ERLxQj.mjs → Run.schema-57k1klOe.mjs} +99 -73
- package/dist/{Run.schema-RWUb38ZE.d.mts → Run.schema-BsSOfQnD.d.mts} +1 -1
- package/dist/{compiler-Faeg70AC.mjs → compiler-BTpMWGqK.mjs} +1 -170
- package/dist/{compiler-Dc7TYMb_.mjs → compiler-CEwQzMxZ.mjs} +1 -170
- package/dist/config.d.mts +1 -1
- package/dist/config.mjs +1 -1
- package/dist/dist-CjdAPjrJ.mjs +1430 -0
- package/dist/dist-Cpq7Esc3.mjs +17404 -0
- package/dist/dist-DsmXFb2_.mjs +17404 -0
- 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 +20 -38
- package/dist/index.mjs +2 -2
- package/dist/main.mjs +6626 -1119
- 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/sourcemap-codec-qFD3eFBj.mjs +186 -0
- package/dist/{src-Baq6uz-6.mjs → src-jn0C-9I0.mjs} +335 -295
- package/package.json +21 -12
- 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-57k1klOe.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,17 +42,17 @@ 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";
|
|
48
48
|
import * as RpcClient from "effect/unstable/rpc/RpcClient";
|
|
49
|
+
import * as Semaphore from "effect/Semaphore";
|
|
50
|
+
import { activateSandbox, createHarnessApi, createRegistry, deactivateSandbox, drainRegistry, guardedExpect, guardedVi, installInterception, makeEffectMethods, nativeImport, uninstallInterception, writeGlobalState } from "@systemfsoftware/stryker-vm-harness";
|
|
49
51
|
import * as Schedule from "effect/Schedule";
|
|
50
52
|
import * as Data from "effect/Data";
|
|
51
53
|
import * as Equivalence from "effect/Equivalence";
|
|
52
54
|
import * as Metric from "effect/Metric";
|
|
53
55
|
import * as Pool from "effect/Pool";
|
|
54
|
-
import * as Semaphore from "effect/Semaphore";
|
|
55
56
|
import * as SchemaTransformation$1 from "effect/SchemaTransformation";
|
|
56
57
|
import { randomBytes } from "@noble/hashes/utils.js";
|
|
57
58
|
import * as Console from "effect/Console";
|
|
@@ -714,8 +715,12 @@ const incrementalDiffOfChanges = (input) => {
|
|
|
714
715
|
};
|
|
715
716
|
};
|
|
716
717
|
const computeIncrementalDiff = (input) => Match.value(input.force).pipe(Match.when(true, () => forcedDiff(input)), Match.orElse(() => incrementalDiffOfChanges(input)));
|
|
717
|
-
const
|
|
718
|
-
const
|
|
718
|
+
const filesFieldOf = (report) => Option.getOrElse(S.decodeUnknownOption(PreviousFilesSchema)(report.files), () => ({}));
|
|
719
|
+
const previousFilesFrom = (report) => Predicate.hasProperty(report, "files") ? filesFieldOf(report) : {};
|
|
720
|
+
const previousFilesOf = (rawReport) => Predicate.isObject(rawReport) ? previousFilesFrom(rawReport) : {};
|
|
721
|
+
const testFilesFieldOf = (report) => Option.getOrElse(S.decodeUnknownOption(PreviousTestFilesSchema)(report.testFiles), () => ({}));
|
|
722
|
+
const previousTestFilesFrom = (report) => Predicate.hasProperty(report, "testFiles") ? testFilesFieldOf(report) : {};
|
|
723
|
+
const previousTestFilesOf = (rawReport) => Predicate.isObject(rawReport) ? previousTestFilesFrom(rawReport) : {};
|
|
719
724
|
const hasTestFileName = (result) => result.fileName !== void 0;
|
|
720
725
|
const testIdsByRelativeFile = (testCoverage, basePath) => {
|
|
721
726
|
const byFile = {};
|
|
@@ -800,6 +805,104 @@ const compileIgnoreRule = (pattern) => {
|
|
|
800
805
|
};
|
|
801
806
|
};
|
|
802
807
|
//#endregion
|
|
808
|
+
//#region src/config-defaults.ts
|
|
809
|
+
const isNonNullObject$1 = (value) => typeof value === "object" && value !== null;
|
|
810
|
+
const isRecordValue$1 = (value) => isNonNullObject$1(value) && Array.isArray(value) === false;
|
|
811
|
+
const isArrayValue$1 = (value) => Array.isArray(value);
|
|
812
|
+
const freezeArrayValue$1 = (value) => Object.freeze(value.map((element) => deepFreeze$1(element)));
|
|
813
|
+
const freezeMapEntry$1 = ([entryKey, entryValue]) => [deepFreeze$1(entryKey), deepFreeze$1(entryValue)];
|
|
814
|
+
const freezeMapValue$1 = (value) => Object.freeze(new Map([...value.entries()].map(freezeMapEntry$1)));
|
|
815
|
+
const freezeSetValue$1 = (value) => Object.freeze(new Set([...value.values()].map((element) => deepFreeze$1(element))));
|
|
816
|
+
const freezeRegExpValue$1 = (value) => Object.freeze(value);
|
|
817
|
+
const freezeRecordValue$1 = (value) => Object.freeze(Object.entries(value).reduce((frozen, [property, propertyValue]) => {
|
|
818
|
+
frozen[property] = deepFreeze$1(propertyValue);
|
|
819
|
+
return frozen;
|
|
820
|
+
}, {}));
|
|
821
|
+
function deepFreeze$1(target) {
|
|
822
|
+
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));
|
|
823
|
+
}
|
|
824
|
+
const optionsPath$1 = (...path) => path.join(".");
|
|
825
|
+
const SUPPORTED_CONFIG_FILE_EXTENSIONS$1 = [
|
|
826
|
+
".ts",
|
|
827
|
+
".mts",
|
|
828
|
+
".js",
|
|
829
|
+
".mjs"
|
|
830
|
+
];
|
|
831
|
+
const configFileNames$1 = (extensions) => extensions.map((extension) => `stryker.config${extension}`);
|
|
832
|
+
const SUPPORTED_CONFIG_FILE_NAMES$1 = Object.freeze(configFileNames$1(SUPPORTED_CONFIG_FILE_EXTENSIONS$1));
|
|
833
|
+
const RELATIVE_SPECIFIER_PREFIXES$1 = [
|
|
834
|
+
"/",
|
|
835
|
+
"./",
|
|
836
|
+
"../",
|
|
837
|
+
"file://"
|
|
838
|
+
];
|
|
839
|
+
function isModuleSpecifier$1(value) {
|
|
840
|
+
return RELATIVE_SPECIFIER_PREFIXES$1.every((prefix) => value.startsWith(prefix) === false);
|
|
841
|
+
}
|
|
842
|
+
const CONFIG_SYNTAX_HELP$1 = `
|
|
843
|
+
Example of how a config file should look:
|
|
844
|
+
/**
|
|
845
|
+
* @type {import('@systemfsoftware/stryker-js-plugin-interface').StrykerOptions}
|
|
846
|
+
*/
|
|
847
|
+
export default {
|
|
848
|
+
mutate: ['src/**/*.js'],
|
|
849
|
+
testRunner: 'vitest',
|
|
850
|
+
reporters: ['progress', 'clear-text', 'html'],
|
|
851
|
+
concurrency: 4
|
|
852
|
+
};
|
|
853
|
+
See https://stryker-mutator.io/docs/stryker-js/config-file for more information.`.trim();
|
|
854
|
+
const createDefaultOptions$1 = S.decodeEffect(StrykerOptionsSchema)({}).pipe(Effect$1.orDie);
|
|
855
|
+
const defaultOptions$1 = Effect$1.map(createDefaultOptions$1, (opts) => deepFreeze$1(opts));
|
|
856
|
+
const scopedUnserializable = (scope) => (description) => ({
|
|
857
|
+
...description,
|
|
858
|
+
path: [scope, ...description.path]
|
|
859
|
+
});
|
|
860
|
+
const describeUnserializableChild = (child, scope) => Match.value(findUnserializables(child)).pipe(Match.when(void 0, () => []), Match.orElse((descriptions) => descriptions.map(scopedUnserializable(scope))));
|
|
861
|
+
const collectUnserializables = (groups) => {
|
|
862
|
+
const found = groups.flat();
|
|
863
|
+
if (found.length > 0) return found;
|
|
864
|
+
};
|
|
865
|
+
const describeUnserializableArray = (value) => collectUnserializables(value.map((child, index) => describeUnserializableChild(child, index.toString())));
|
|
866
|
+
const describeUnserializableRecord = (value) => collectUnserializables(Object.entries(value).map(([key, child]) => describeUnserializableChild(child, key)));
|
|
867
|
+
const isPlainObjectValue = (value) => !Array.isArray(value) && value.constructor === Object;
|
|
868
|
+
const classNameOf = (value) => Match.value(value.constructor).pipe(Match.when(Match.defined, (ctor) => ctor.name), Match.orElse(() => "Object"));
|
|
869
|
+
const describeUnserializableInstance = (value) => [{
|
|
870
|
+
path: [],
|
|
871
|
+
reason: `Value is an instance of "${classNameOf(value)}", this detail will get lost in translation during serialization`
|
|
872
|
+
}];
|
|
873
|
+
const describeUnserializableObject = (value) => Match.value(value).pipe(Match.when(isArrayValue$1, describeUnserializableArray), Match.when(isPlainObjectValue, describeUnserializableRecord), Match.orElse(describeUnserializableInstance));
|
|
874
|
+
const NON_JSON_PRIMITIVE_TYPES = [
|
|
875
|
+
"bigint",
|
|
876
|
+
"function",
|
|
877
|
+
"symbol"
|
|
878
|
+
];
|
|
879
|
+
const isNonJsonPrimitive = (value) => NON_JSON_PRIMITIVE_TYPES.includes(typeof value);
|
|
880
|
+
const describeNonJsonPrimitive = (value) => [{
|
|
881
|
+
path: [],
|
|
882
|
+
reason: `Primitive type "${typeof value}" has no JSON representation`
|
|
883
|
+
}];
|
|
884
|
+
const describeNumber = (value) => {
|
|
885
|
+
if (isFinite(value)) return void 0;
|
|
886
|
+
return [{
|
|
887
|
+
reason: `Number value \`${value}\` has no JSON representation`,
|
|
888
|
+
path: []
|
|
889
|
+
}];
|
|
890
|
+
};
|
|
891
|
+
function findUnserializables(thing) {
|
|
892
|
+
if (typeof thing === "number") return describeNumber(thing);
|
|
893
|
+
return describeNonNumberValue(thing);
|
|
894
|
+
}
|
|
895
|
+
function describeNonNumberValue(thing) {
|
|
896
|
+
return isNonJsonPrimitive(thing) ? describeNonJsonPrimitive(thing) : describeObjectValue(thing);
|
|
897
|
+
}
|
|
898
|
+
function describeObjectValue(thing) {
|
|
899
|
+
return isNonNullObject$1(thing) ? describeUnserializableObject(thing) : void 0;
|
|
900
|
+
}
|
|
901
|
+
function isWarningEnabled$1(warningType, warningOptions) {
|
|
902
|
+
if (typeof warningOptions === "boolean") return warningOptions;
|
|
903
|
+
else return warningOptions[warningType] === true;
|
|
904
|
+
}
|
|
905
|
+
//#endregion
|
|
803
906
|
//#region src/Config.schema.ts
|
|
804
907
|
const ConfigDocumentSchema = S.Record(S.String, S.Unknown);
|
|
805
908
|
const ImportedModuleSchema = S.Struct({ default: S.optional(S.Unknown) });
|
|
@@ -989,45 +1092,37 @@ const vmRunnerName = "vm";
|
|
|
989
1092
|
const ALL_TESTS_NAME = "All tests";
|
|
990
1093
|
const isVmRunner = (name) => typeof name === "string" && name.toLowerCase() === "vm";
|
|
991
1094
|
const vmRunnerCapabilities = { reloadEnvironment: true };
|
|
992
|
-
const FALLBACK_FILE_NAME = "stryker-vm-tests.js";
|
|
993
1095
|
const errorText = (error) => Match.value(error).pipe(Match.when(Match.instanceOf(Error), (failure) => failure.message), Match.orElse((value) => String(value)));
|
|
994
|
-
const
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
catch: (cause) => compileFailure(file, cause)
|
|
1003
|
-
}))));
|
|
1004
|
-
const fileName = Option.getOrElse(Option.fromUndefinedOr(testFiles.at(0)), () => FALLBACK_FILE_NAME);
|
|
1096
|
+
const isInitFailure = (error) => {
|
|
1097
|
+
if (error instanceof SyntaxError) return true;
|
|
1098
|
+
if (typeof error !== "object" || error === null) return false;
|
|
1099
|
+
if ("code" in error && error.code === "ERR_MODULE_NOT_FOUND") return true;
|
|
1100
|
+
return error instanceof Error && error.message.includes("[PARSE_ERROR]");
|
|
1101
|
+
};
|
|
1102
|
+
const runFailureFor = (file, cause) => {
|
|
1103
|
+
const fatal = isInitFailure(cause);
|
|
1005
1104
|
return {
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
catch: (cause) => compileFailure(fileName, cause)
|
|
1010
|
-
})
|
|
1011
|
-
};
|
|
1012
|
-
});
|
|
1013
|
-
const sandboxFor = (platform, fileName, activeMutantId) => {
|
|
1014
|
-
const namespace = hostStrykerNamespace();
|
|
1015
|
-
namespace[INSTRUMENTER_CONSTANTS.ACTIVE_MUTANT] = activeMutantId;
|
|
1016
|
-
const moduleExports = {};
|
|
1017
|
-
const moduleObj = { exports: moduleExports };
|
|
1018
|
-
const sandbox = {
|
|
1019
|
-
...globalThis,
|
|
1020
|
-
[INSTRUMENTER_CONSTANTS.NAMESPACE]: namespace,
|
|
1021
|
-
require: platform.module.createRequire(fileName),
|
|
1022
|
-
module: moduleObj,
|
|
1023
|
-
exports: moduleExports,
|
|
1024
|
-
__filename: fileName
|
|
1105
|
+
file,
|
|
1106
|
+
message: fatal ? `Could not load "${file}" for the in-memory runner: ${errorText(cause)}` : errorText(cause),
|
|
1107
|
+
fatal
|
|
1025
1108
|
};
|
|
1026
|
-
sandbox["global"] = sandbox;
|
|
1027
|
-
sandbox["globalThis"] = sandbox;
|
|
1028
|
-
return sandbox;
|
|
1029
1109
|
};
|
|
1030
|
-
|
|
1110
|
+
let saltCounter = 0;
|
|
1111
|
+
const isPlainObject = (value) => Predicate.isObject(value);
|
|
1112
|
+
const descriptorValue = (descriptor) => descriptor === void 0 ? void 0 : descriptor.value;
|
|
1113
|
+
const hostStrykerNamespace = () => {
|
|
1114
|
+
const current = descriptorValue(Object.getOwnPropertyDescriptor(globalThis, INSTRUMENTER_CONSTANTS.NAMESPACE));
|
|
1115
|
+
if (isPlainObject(current)) return current;
|
|
1116
|
+
const created = {};
|
|
1117
|
+
Object.defineProperty(globalThis, INSTRUMENTER_CONSTANTS.NAMESPACE, {
|
|
1118
|
+
configurable: true,
|
|
1119
|
+
enumerable: true,
|
|
1120
|
+
value: created,
|
|
1121
|
+
writable: true
|
|
1122
|
+
});
|
|
1123
|
+
return created;
|
|
1124
|
+
};
|
|
1125
|
+
const monolithicResult = (failureMessage, timeSpentMs) => Match.value(failureMessage).pipe(Match.when(Match.string, (failure) => ({
|
|
1031
1126
|
status: "complete",
|
|
1032
1127
|
tests: [{
|
|
1033
1128
|
id: "all",
|
|
@@ -1045,71 +1140,123 @@ const resultFromRun = (failureMessage, timeSpentMs) => Match.value(failureMessag
|
|
|
1045
1140
|
timeSpentMs
|
|
1046
1141
|
}]
|
|
1047
1142
|
})));
|
|
1048
|
-
const
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
const
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
configurable: true,
|
|
1062
|
-
enumerable: true,
|
|
1063
|
-
value: created,
|
|
1064
|
-
writable: true
|
|
1065
|
-
});
|
|
1066
|
-
return created;
|
|
1143
|
+
const prefixOf = (file, pathToFileURL) => {
|
|
1144
|
+
const href = pathToFileURL(file).href;
|
|
1145
|
+
const lastSlash = href.lastIndexOf("/");
|
|
1146
|
+
return href.slice(0, lastSlash + 1);
|
|
1147
|
+
};
|
|
1148
|
+
const commonPrefixOf = (files, pathToFileURL) => {
|
|
1149
|
+
const dirs = files.map((file) => prefixOf(file, pathToFileURL));
|
|
1150
|
+
let prefix = dirs[0] ?? "";
|
|
1151
|
+
for (const dir of dirs.slice(1)) while (prefix !== "" && !dir.startsWith(prefix)) {
|
|
1152
|
+
const cut = prefix.lastIndexOf("/", prefix.length - 2);
|
|
1153
|
+
prefix = cut > 0 ? prefix.slice(0, cut + 1) : "";
|
|
1154
|
+
}
|
|
1155
|
+
return prefix;
|
|
1067
1156
|
};
|
|
1068
|
-
const
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1157
|
+
const serialRunGate = Semaphore.makeUnsafe(1);
|
|
1158
|
+
const runOnce = (platform, testFiles, timeoutMs, activeMutantId, sandboxWorkingDirectory) => Effect$1.gen(function* () {
|
|
1159
|
+
if (testFiles[0] === void 0) return monolithicResult(void 0, 0);
|
|
1160
|
+
const registry = createRegistry();
|
|
1161
|
+
const api = createHarnessApi(registry);
|
|
1162
|
+
const namespace = hostStrykerNamespace();
|
|
1163
|
+
const previousActive = namespace[INSTRUMENTER_CONSTANTS.ACTIVE_MUTANT];
|
|
1164
|
+
namespace[INSTRUMENTER_CONSTANTS.ACTIVE_MUTANT] = activeMutantId;
|
|
1165
|
+
let armed = false;
|
|
1072
1166
|
try {
|
|
1073
|
-
|
|
1167
|
+
const real = yield* Effect$1.tryPromise({
|
|
1168
|
+
try: () => import("./dist-DsmXFb2_.mjs"),
|
|
1169
|
+
catch: (cause) => TestRunnerFailed.make({
|
|
1170
|
+
runnerName: "vm",
|
|
1171
|
+
phase: "init",
|
|
1172
|
+
cause: cause instanceof Error ? cause.message : "the vitest module failed to load"
|
|
1173
|
+
})
|
|
1174
|
+
});
|
|
1175
|
+
const state = {
|
|
1176
|
+
api,
|
|
1177
|
+
expect: guardedExpect(real.expect),
|
|
1178
|
+
vi: guardedVi(real.vi),
|
|
1179
|
+
effectVitest: { it: makeEffectMethods({
|
|
1180
|
+
api: api.it,
|
|
1181
|
+
describe: api.describe,
|
|
1182
|
+
hooks: api.hooks,
|
|
1183
|
+
tests: registry.tests
|
|
1184
|
+
}) }
|
|
1185
|
+
};
|
|
1186
|
+
const prefix = sandboxWorkingDirectory !== void 0 ? `${platform.pathToFileURL(sandboxWorkingDirectory).href.replace(/\/?$/, "/")}` : commonPrefixOf(testFiles, platform.pathToFileURL);
|
|
1187
|
+
installInterception(platform.moduleBuiltin);
|
|
1188
|
+
activateSandbox(prefix);
|
|
1189
|
+
writeGlobalState(state);
|
|
1190
|
+
armed = true;
|
|
1191
|
+
let runFailure;
|
|
1192
|
+
const salt = saltCounter++;
|
|
1193
|
+
for (const file of testFiles) {
|
|
1194
|
+
registry.files.current = file;
|
|
1195
|
+
registry.frames.current = [];
|
|
1196
|
+
const url = `${platform.pathToFileURL(file).href}?salt=${salt}`;
|
|
1197
|
+
const outcome = yield* Effect$1.promise(() => nativeImport(url).then(() => void 0, (cause) => ({ cause })));
|
|
1198
|
+
if (outcome !== void 0) {
|
|
1199
|
+
const failure = runFailureFor(file, outcome.cause);
|
|
1200
|
+
if (failure.fatal) return yield* TestRunnerFailed.make({
|
|
1201
|
+
runnerName: "vm",
|
|
1202
|
+
phase: "init",
|
|
1203
|
+
cause: failure.message
|
|
1204
|
+
});
|
|
1205
|
+
runFailure ??= failure;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
const outcome = yield* Effect$1.promise(() => drainRegistry(registry, timeoutMs));
|
|
1209
|
+
if (outcome.kind === "timeout") return { status: "timeout" };
|
|
1210
|
+
const drainedElapsed = outcome.tests.reduce((total, test) => total + test.timeSpentMs, 0);
|
|
1211
|
+
if (registry.tests.length === 0) return monolithicResult(runFailure?.message, drainedElapsed);
|
|
1212
|
+
const tests = outcome.tests.map((test) => {
|
|
1213
|
+
const base = {
|
|
1214
|
+
id: `${test.file}#${test.fullName}`,
|
|
1215
|
+
name: test.fullName,
|
|
1216
|
+
timeSpentMs: test.timeSpentMs
|
|
1217
|
+
};
|
|
1218
|
+
if (test.status === "failed") return {
|
|
1219
|
+
...base,
|
|
1220
|
+
status: "failed",
|
|
1221
|
+
failureMessage: test.failureMessage ?? ""
|
|
1222
|
+
};
|
|
1223
|
+
return test.status === "skipped" ? {
|
|
1224
|
+
...base,
|
|
1225
|
+
status: "skipped"
|
|
1226
|
+
} : {
|
|
1227
|
+
...base,
|
|
1228
|
+
status: "success"
|
|
1229
|
+
};
|
|
1230
|
+
});
|
|
1231
|
+
if (runFailure !== void 0) tests.push({
|
|
1232
|
+
id: `${runFailure.file}#load error`,
|
|
1233
|
+
name: `${runFailure.file} (load error)`,
|
|
1234
|
+
status: "failed",
|
|
1235
|
+
failureMessage: runFailure.message,
|
|
1236
|
+
timeSpentMs: 0
|
|
1237
|
+
});
|
|
1238
|
+
return {
|
|
1239
|
+
status: "complete",
|
|
1240
|
+
tests
|
|
1241
|
+
};
|
|
1074
1242
|
} finally {
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
const context = platform.vm.createContext(sandboxFor(platform, compiled.fileName, activeMutantId));
|
|
1080
|
-
return withActiveMutant(activeMutantId, () => {
|
|
1081
|
-
try {
|
|
1082
|
-
compiled.script.runInContext(context);
|
|
1083
|
-
return;
|
|
1084
|
-
} catch (cause) {
|
|
1085
|
-
return errorText(cause);
|
|
1243
|
+
if (armed) {
|
|
1244
|
+
writeGlobalState(void 0);
|
|
1245
|
+
deactivateSandbox();
|
|
1246
|
+
uninstallInterception();
|
|
1086
1247
|
}
|
|
1087
|
-
|
|
1088
|
-
}
|
|
1089
|
-
const runOnce = (platform, compiled, activeMutantId) => Effect$1.gen(function* () {
|
|
1090
|
-
const startedAt = yield* Clock.currentTimeMillis;
|
|
1091
|
-
const failure = yield* runInFreshContext(platform, compiled, activeMutantId);
|
|
1092
|
-
const elapsedMs = (yield* Clock.currentTimeMillis) - startedAt;
|
|
1093
|
-
return resultFromRun(failure, elapsedMs);
|
|
1248
|
+
namespace[INSTRUMENTER_CONSTANTS.ACTIVE_MUTANT] = previousActive;
|
|
1249
|
+
}
|
|
1094
1250
|
});
|
|
1095
1251
|
const vmTestRunner = (config) => Effect$1.gen(function* () {
|
|
1096
1252
|
const platform = yield* VmRunner;
|
|
1097
|
-
const
|
|
1098
|
-
const compiled = yield* Ref.make(Option.none());
|
|
1099
|
-
const compiledTests = (testFiles) => Effect$1.gen(function* () {
|
|
1100
|
-
const cached = yield* Ref.get(compiled);
|
|
1101
|
-
if (Option.isSome(cached)) return cached.value;
|
|
1102
|
-
const tests = yield* compileTests(platform, fs, testFiles);
|
|
1103
|
-
yield* Ref.set(compiled, Option.some(tests));
|
|
1104
|
-
return tests;
|
|
1105
|
-
});
|
|
1106
|
-
const run = (testFiles, activeMutantId) => compiledTests(testFiles).pipe(Effect$1.flatMap((tests) => runOnce(platform, tests, activeMutantId)));
|
|
1253
|
+
const run = (testFiles, timeoutMs, activeMutantId) => serialRunGate.withPermits(1)(runOnce(platform, testFiles, timeoutMs, activeMutantId, config.sandboxWorkingDirectory));
|
|
1107
1254
|
const testFilesOf = (override) => Match.value(config.testFiles).pipe(Match.when((files) => files.length > 0, (files) => files), Match.orElse(() => override ?? []));
|
|
1108
1255
|
return {
|
|
1109
1256
|
capabilities: Effect$1.succeed(vmRunnerCapabilities),
|
|
1110
1257
|
init: Effect$1.void,
|
|
1111
|
-
dryRun: (options) => run(testFilesOf(options.testFiles), void 0),
|
|
1112
|
-
mutantRun: (options) => run(config.testFiles, options.activeMutant.id).pipe(Effect$1.map((result) => toMutantRunResult(result, true)), Effect$1.catchTag("TestRunnerFailed", (failure) => Effect$1.succeed(toMutantRunResult({
|
|
1258
|
+
dryRun: (options) => run(testFilesOf(options.testFiles), options.timeout, void 0),
|
|
1259
|
+
mutantRun: (options) => run(config.testFiles, options.timeout, String(options.activeMutant.id)).pipe(Effect$1.map((result) => toMutantRunResult(result, true)), Effect$1.catchTag("TestRunnerFailed", (failure) => Effect$1.succeed(toMutantRunResult({
|
|
1113
1260
|
status: "error",
|
|
1114
1261
|
errorMessage: failure.cause
|
|
1115
1262
|
}, true))))
|
|
@@ -1303,8 +1450,8 @@ const nodePlatformLayer = Layer.mergeAll(nodeWorkerLauncherLayer.pipe(Layer.prov
|
|
|
1303
1450
|
* runner has no fallback to fall back to.
|
|
1304
1451
|
*/
|
|
1305
1452
|
const nodeVmPlatformLayer = Layer.effect(VmRunner, Effect$1.sync(() => ({
|
|
1306
|
-
|
|
1307
|
-
|
|
1453
|
+
moduleBuiltin: globalThis.process.getBuiltinModule("node:module"),
|
|
1454
|
+
pathToFileURL: (path) => globalThis.process.getBuiltinModule("node:url").pathToFileURL(path)
|
|
1308
1455
|
})));
|
|
1309
1456
|
S.TaggedError()("CommandRunnerUnsupportedOption", { option: S.String });
|
|
1310
1457
|
S.Struct({
|
|
@@ -1582,7 +1729,10 @@ const commandRunner = (context, spawner) => {
|
|
|
1582
1729
|
};
|
|
1583
1730
|
return withRetry(withTimeout(base));
|
|
1584
1731
|
};
|
|
1585
|
-
const inProcessRunner = (context) => Match.value(context.options.testRunner).pipe(Match.when(isCommandRunner, () => Option.some(ChildProcessSpawner.ChildProcessSpawner.pipe(Effect$1.map((spawner) => commandRunner(context, spawner))))), Match.when(isVmRunner, () => Option.some(vmTestRunner({
|
|
1732
|
+
const inProcessRunner = (context) => Match.value(context.options.testRunner).pipe(Match.when(isCommandRunner, () => Option.some(ChildProcessSpawner.ChildProcessSpawner.pipe(Effect$1.map((spawner) => commandRunner(context, spawner))))), Match.when(isVmRunner, () => Option.some(vmTestRunner({
|
|
1733
|
+
testFiles: context.testFiles,
|
|
1734
|
+
sandboxWorkingDirectory: context.sandboxWorkingDirectory
|
|
1735
|
+
}).pipe(Effect$1.provide(nodeVmPlatformLayer)))), Match.orElse(() => Option.none()));
|
|
1586
1736
|
const buildTestRunner = (context, childProcessRunner) => Effect$1.gen(function* () {
|
|
1587
1737
|
const inProcess = inProcessRunner(context);
|
|
1588
1738
|
if (Option.isSome(inProcess)) return yield* inProcess.value;
|
|
@@ -1594,78 +1744,43 @@ const buildTestRunner = (context, childProcessRunner) => Effect$1.gen(function*
|
|
|
1594
1744
|
});
|
|
1595
1745
|
//#endregion
|
|
1596
1746
|
//#region src/run/load-config.cell.ts
|
|
1597
|
-
const isNonNullObject
|
|
1598
|
-
const
|
|
1747
|
+
const isNonNullObject = (value) => typeof value === "object" && value !== null;
|
|
1748
|
+
const isRecordValue = (value) => isNonNullObject(value) && Array.isArray(value) === false;
|
|
1749
|
+
const optionsPath = (...path) => path.join(".");
|
|
1599
1750
|
const combine = (prefixes, suffixes, extensions) => prefixes.flatMap((prefix) => suffixes.flatMap((suffix) => extensions.map((extension) => `${prefix}stryker${suffix}.${extension}`)));
|
|
1600
1751
|
const CONFIG_FILE_NAME_PREFIXES = ["", "."];
|
|
1601
1752
|
const CONFIG_FILE_NAME_SUFFIXES = [".conf", ".config"];
|
|
1602
|
-
const SUPPORTED_CONFIG_FILE_EXTENSIONS
|
|
1753
|
+
const SUPPORTED_CONFIG_FILE_EXTENSIONS = [
|
|
1603
1754
|
"ts",
|
|
1604
1755
|
"mts",
|
|
1605
1756
|
"js",
|
|
1606
1757
|
"mjs"
|
|
1607
1758
|
];
|
|
1608
1759
|
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
|
|
1760
|
+
const configFileNames = (extensions) => combine([...CONFIG_FILE_NAME_PREFIXES], [...CONFIG_FILE_NAME_SUFFIXES], [...extensions]);
|
|
1761
|
+
const SUPPORTED_CONFIG_FILE_NAMES = Object.freeze(configFileNames(SUPPORTED_CONFIG_FILE_EXTENSIONS));
|
|
1762
|
+
const LEGACY_CONFIG_FILE_NAMES = Object.freeze(configFileNames(LEGACY_CONFIG_FILE_EXTENSIONS));
|
|
1763
|
+
const SUPPORTED_CONFIG_FILE_EXTENSION_GUIDE = `one of these extensions: ${SUPPORTED_CONFIG_FILE_EXTENSIONS.map((extension) => `.${extension}`).join(", ")}`;
|
|
1613
1764
|
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
1765
|
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
1766
|
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
1767
|
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
|
-
|
|
1768
|
+
const isArrayValue = (value) => Array.isArray(value);
|
|
1769
|
+
const isMapValue = (value) => value instanceof Map;
|
|
1770
|
+
const isSetValue = (value) => value instanceof Set;
|
|
1771
|
+
const freezeArrayValue = (value) => Object.freeze(value.map((element) => deepFreeze(element)));
|
|
1772
|
+
const freezeMapEntry = ([entryKey, entryValue]) => [deepFreeze(entryKey), deepFreeze(entryValue)];
|
|
1773
|
+
const freezeMapValue = (value) => Object.freeze(new Map([...value.entries()].map(freezeMapEntry)));
|
|
1774
|
+
const freezeSetValue = (value) => Object.freeze(new Set([...value.values()].map((element) => deepFreeze(element))));
|
|
1775
|
+
const freezeRegExpValue = (value) => Object.freeze(value);
|
|
1776
|
+
const freezeRecordValue = (value) => Object.freeze(Object.entries(value).reduce((frozen, [property, propertyValue]) => {
|
|
1777
|
+
frozen[property] = deepFreeze(propertyValue);
|
|
1625
1778
|
return frozen;
|
|
1626
1779
|
}, {}));
|
|
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));
|
|
1780
|
+
function deepFreeze(target) {
|
|
1781
|
+
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
1782
|
}
|
|
1668
|
-
function isWarningEnabled
|
|
1783
|
+
function isWarningEnabled(warningType, warningOptions) {
|
|
1669
1784
|
if (typeof warningOptions === "boolean") return warningOptions;
|
|
1670
1785
|
else return warningOptions[warningType] === true;
|
|
1671
1786
|
}
|
|
@@ -1724,10 +1839,18 @@ const mergePluginDescriptors = (parentPlugins, childPlugins) => {
|
|
|
1724
1839
|
const merged = [...parentPlugins, ...childPlugins];
|
|
1725
1840
|
return merged.filter(isFirstDescriptorOccurrence(merged));
|
|
1726
1841
|
};
|
|
1727
|
-
const
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1842
|
+
const isConfigOptionsRecord = (value) => isNonNullObject(value) && Array.isArray(value) === false;
|
|
1843
|
+
function mergeConfigRecords(parentNested, childNested) {
|
|
1844
|
+
return {
|
|
1845
|
+
...parentNested,
|
|
1846
|
+
...childNested
|
|
1847
|
+
};
|
|
1848
|
+
}
|
|
1849
|
+
const toConfigRecordOption = (value) => isConfigOptionsRecord(value) ? Option.some(value) : Option.none();
|
|
1850
|
+
const inheritNested = (parentValue, childValue) => Option.match(Option.all([toConfigRecordOption(parentValue), toConfigRecordOption(childValue)]), {
|
|
1851
|
+
onSome: ([parentNested, childNested]) => mergeConfigRecords(parentNested, childNested),
|
|
1852
|
+
onNone: () => childValue
|
|
1853
|
+
});
|
|
1731
1854
|
const inheritEntry = (out, key, parentValue, childValue) => Match.value(childValue).pipe(Match.when(null, () => {
|
|
1732
1855
|
const next = { ...out };
|
|
1733
1856
|
delete next[key];
|
|
@@ -1742,14 +1865,14 @@ const inheritEntry = (out, key, parentValue, childValue) => Match.value(childVal
|
|
|
1742
1865
|
function mergeConfigs(parent, child) {
|
|
1743
1866
|
return Object.entries(child).reduce((out, entry) => inheritEntry(out, entry[0], parent[entry[0]], entry[1]), { ...parent });
|
|
1744
1867
|
}
|
|
1745
|
-
const RELATIVE_SPECIFIER_PREFIXES
|
|
1868
|
+
const RELATIVE_SPECIFIER_PREFIXES = [
|
|
1746
1869
|
"./",
|
|
1747
1870
|
"../",
|
|
1748
1871
|
"/",
|
|
1749
1872
|
"\\"
|
|
1750
1873
|
];
|
|
1751
|
-
function isModuleSpecifier
|
|
1752
|
-
return RELATIVE_SPECIFIER_PREFIXES
|
|
1874
|
+
function isModuleSpecifier(value) {
|
|
1875
|
+
return RELATIVE_SPECIFIER_PREFIXES.every((prefix) => value.startsWith(prefix) === false);
|
|
1753
1876
|
}
|
|
1754
1877
|
const stripExtends = (document) => {
|
|
1755
1878
|
const { extends: _ignored, ...rest } = document;
|
|
@@ -1768,7 +1891,7 @@ const decideExtendsStep = (state, document, file, pathService) => {
|
|
|
1768
1891
|
options: document
|
|
1769
1892
|
}]
|
|
1770
1893
|
};
|
|
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
|
|
1894
|
+
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
1895
|
specifier: extendValue,
|
|
1773
1896
|
state: nextState
|
|
1774
1897
|
})), Match.when(false, () => ExtendsStepRead.make({
|
|
@@ -1783,15 +1906,20 @@ const decodeConfigDocument = (configFile, document) => S.decodeUnknownEffect(Con
|
|
|
1783
1906
|
file: configFile,
|
|
1784
1907
|
cause
|
|
1785
1908
|
})));
|
|
1786
|
-
const
|
|
1787
|
-
file: configFile,
|
|
1788
|
-
cause: "Config file must have a default export!"
|
|
1789
|
-
}))), Match.when(isNonNullObject$1, (value) => Effect$1.succeed(value)), Match.orElse(() => Effect$1.fail(ConfigFileInvalidError.make({
|
|
1909
|
+
const failInvalidConfig = (configFile, cause) => Effect$1.fail(ConfigFileInvalidError.make({
|
|
1790
1910
|
file: configFile,
|
|
1791
|
-
cause
|
|
1792
|
-
}))
|
|
1911
|
+
cause
|
|
1912
|
+
}));
|
|
1913
|
+
const requireDefaultExport = (configFile, defaultExport) => defaultExport === void 0 ? failInvalidConfig(configFile, "Config file must have a default export!") : settleObjectExport(configFile, defaultExport);
|
|
1914
|
+
function settleObjectExport(configFile, value) {
|
|
1915
|
+
return isNonNullObject(value) ? Effect$1.succeed(value) : failInvalidConfig(configFile, "Default export of config file must be an object!");
|
|
1916
|
+
}
|
|
1793
1917
|
const isConfigFactory = (value) => typeof value === "function";
|
|
1794
|
-
|
|
1918
|
+
function wrappedFactoryFailure(error) {
|
|
1919
|
+
return new Error(`Evaluating the config module's exported factory failed: ${error.message}`, { cause: error });
|
|
1920
|
+
}
|
|
1921
|
+
const factoryFailureCause = (cause) => cause instanceof Error ? wrappedFactoryFailure(cause) : cause;
|
|
1922
|
+
const applyConfigFactory = (factory, configEnv) => factory(configEnv);
|
|
1795
1923
|
/**
|
|
1796
1924
|
* Settle a config module's default export into the object the document schema decodes.
|
|
1797
1925
|
*
|
|
@@ -1802,7 +1930,7 @@ const factoryFailureCause = (cause) => Match.value(cause).pipe(Match.when(Match.
|
|
|
1802
1930
|
* non-null object and would otherwise reach the document decoder as one.
|
|
1803
1931
|
*/
|
|
1804
1932
|
const settleConfigDefault = (configFile, defaultExport, configEnv) => Effect$1.tryPromise({
|
|
1805
|
-
try: () => Promise.resolve(defaultExport).then((exported) =>
|
|
1933
|
+
try: () => Promise.resolve(defaultExport).then((exported) => isConfigFactory(exported) ? applyConfigFactory(exported, configEnv) : exported),
|
|
1806
1934
|
catch: (cause) => ConfigFileInvalidError.make({
|
|
1807
1935
|
file: configFile,
|
|
1808
1936
|
cause: factoryFailureCause(cause)
|
|
@@ -1810,14 +1938,14 @@ const settleConfigDefault = (configFile, defaultExport, configEnv) => Effect$1.t
|
|
|
1810
1938
|
}).pipe(Effect$1.flatMap((settled) => requireDefaultExport(configFile, settled)));
|
|
1811
1939
|
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
1940
|
const carriesCode = (cause) => cause instanceof Error && "code" in cause;
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
const errorMessageOf = (cause) =>
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
}
|
|
1941
|
+
function codeOf(coded) {
|
|
1942
|
+
return typeof coded.code === "string" ? coded.code : void 0;
|
|
1943
|
+
}
|
|
1944
|
+
const errorCodeOf = (cause) => carriesCode(cause) ? codeOf(cause) : void 0;
|
|
1945
|
+
const errorMessageOf = (cause) => cause instanceof Error ? errorTextOf(cause) : void 0;
|
|
1946
|
+
function errorTextOf(error) {
|
|
1947
|
+
return typeof error.message === "string" ? error.message : void 0;
|
|
1948
|
+
}
|
|
1821
1949
|
const importFailureDetail = (failure) => errorMessageOf(failure.cause) ?? failure.message;
|
|
1822
1950
|
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
1951
|
const configModuleUrl = (configFile, pathService) => Match.value(configFile.startsWith("file:")).pipe(Match.when(true, () => Effect$1.try({
|
|
@@ -1894,7 +2022,7 @@ function recordOf(value) {
|
|
|
1894
2022
|
return { ...value };
|
|
1895
2023
|
}
|
|
1896
2024
|
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
|
|
2025
|
+
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
2026
|
const matchLineNumber = (match, group) => Number.parseInt(match[group] ?? "", 10);
|
|
1899
2027
|
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
2028
|
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 +2066,7 @@ const OPTIONS_ADDED_BY_STRYKER = [
|
|
|
1938
2066
|
"configFile",
|
|
1939
2067
|
"$schema"
|
|
1940
2068
|
];
|
|
1941
|
-
const schemaPropertyNames = (schema) => Match.value(schema["properties"]).pipe(Match.when(isNonNullObject
|
|
2069
|
+
const schemaPropertyNames = (schema) => Match.value(schema["properties"]).pipe(Match.when(isNonNullObject, (properties) => Object.keys(recordOf(properties))), Match.orElse(() => []));
|
|
1942
2070
|
const excessOptionNames = (options, schema) => {
|
|
1943
2071
|
const schemaKeys = schemaPropertyNames(schema);
|
|
1944
2072
|
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 +2079,7 @@ const warnAboutUnknownOptions = (options, excessNames) => Effect$1.gen(function*
|
|
|
1951
2079
|
* Did you only write this property as a comment? If so, please postfix it with "_comment".
|
|
1952
2080
|
* You might be missing a plugin that is supposed to use it. Stryker loaded plugins from: ${pluginsJson}
|
|
1953
2081
|
* The plugin that is using it did not contribute explicit validation.
|
|
1954
|
-
(disable "${optionsPath
|
|
2082
|
+
(disable "${optionsPath("warnings", "unknownOptions")}" to ignore this warning)`);
|
|
1955
2083
|
});
|
|
1956
2084
|
const unknownOptionWarning = (options, schema) => {
|
|
1957
2085
|
const excessNames = excessOptionNames(options, schema);
|
|
@@ -1959,17 +2087,17 @@ const unknownOptionWarning = (options, schema) => {
|
|
|
1959
2087
|
};
|
|
1960
2088
|
function markExcessOptions(options, schema) {
|
|
1961
2089
|
return Effect$1.gen(function* () {
|
|
1962
|
-
if (isWarningEnabled
|
|
2090
|
+
if (isWarningEnabled("unknownOptions", options.warnings)) yield* unknownOptionWarning(options, schema);
|
|
1963
2091
|
});
|
|
1964
2092
|
}
|
|
1965
2093
|
const logUnserializableWarnings = (unserializables) => Effect$1.gen(function* () {
|
|
1966
2094
|
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
|
|
2095
|
+
yield* Effect$1.logWarning(`(disable ${optionsPath("warnings", "unserializableOptions")} to ignore this warning)`);
|
|
1968
2096
|
});
|
|
1969
|
-
const warnAboutUnserializableOptions = (options) => Match.value(findUnserializables
|
|
2097
|
+
const warnAboutUnserializableOptions = (options) => Match.value(findUnserializables(options)).pipe(Match.when(void 0, () => Effect$1.void), Match.orElse((unserializables) => logUnserializableWarnings(unserializables)));
|
|
1970
2098
|
function markUnserializableOptions(options) {
|
|
1971
2099
|
return Effect$1.gen(function* () {
|
|
1972
|
-
if (isWarningEnabled
|
|
2100
|
+
if (isWarningEnabled("unserializableOptions", options.warnings)) yield* warnAboutUnserializableOptions(options);
|
|
1973
2101
|
});
|
|
1974
2102
|
}
|
|
1975
2103
|
function markOptions(options, schema) {
|
|
@@ -1986,8 +2114,8 @@ function validateOptions(options, schema) {
|
|
|
1986
2114
|
return typed;
|
|
1987
2115
|
});
|
|
1988
2116
|
}
|
|
1989
|
-
const createDefaultOptions
|
|
1990
|
-
Effect$1.map(createDefaultOptions
|
|
2117
|
+
const createDefaultOptions = S.decodeEffect(StrykerOptionsSchema)({}).pipe(Effect$1.orDie);
|
|
2118
|
+
Effect$1.map(createDefaultOptions, (opts) => deepFreeze(opts));
|
|
1991
2119
|
`
|
|
1992
2120
|
Example of how a config file should look:
|
|
1993
2121
|
/**
|
|
@@ -2021,7 +2149,7 @@ const firstExistingConfigFile = (fileNames) => Option.match(Option.fromUndefined
|
|
|
2021
2149
|
});
|
|
2022
2150
|
const configFileFor = (configFileName) => Effect$1.gen(function* () {
|
|
2023
2151
|
const pathService = yield* Path.Path;
|
|
2024
|
-
const supported = SUPPORTED_CONFIG_FILE_EXTENSIONS
|
|
2152
|
+
const supported = SUPPORTED_CONFIG_FILE_EXTENSIONS.includes(configFileExtension(configFileName, pathService));
|
|
2025
2153
|
const legacy = isLegacyConfigFile(configFileName, pathService);
|
|
2026
2154
|
return yield* Match.value(supported).pipe(Match.when(true, () => requireExistingConfigFile(configFileName)), Match.orElse(() => Effect$1.fail(ConfigFileUnsupportedError.make({
|
|
2027
2155
|
file: configFileName,
|
|
@@ -2042,14 +2170,14 @@ const warnShadowedLegacyConfig = (supportedFile) => firstLegacyConfigFile().pipe
|
|
|
2042
2170
|
onNone: () => Effect$1.succeed(supportedFile),
|
|
2043
2171
|
onSome: (file) => Effect$1.as(legacyConfigWarning(file, supportedFile), supportedFile)
|
|
2044
2172
|
})));
|
|
2045
|
-
const discoverConfigFile = () => firstExistingConfigFile([...SUPPORTED_CONFIG_FILE_NAMES
|
|
2173
|
+
const discoverConfigFile = () => firstExistingConfigFile([...SUPPORTED_CONFIG_FILE_NAMES]).pipe(Effect$1.flatMap((found) => Option.match(found, {
|
|
2046
2174
|
onNone: () => refuseLegacyOnlyProject().pipe(Effect$1.map((legacy) => Option.getOrUndefined(legacy))),
|
|
2047
2175
|
onSome: (supportedFile) => warnShadowedLegacyConfig(supportedFile)
|
|
2048
2176
|
})));
|
|
2049
2177
|
function findConfigFile(configFileName) {
|
|
2050
|
-
return
|
|
2178
|
+
return typeof configFileName === "string" ? configFileFor(configFileName) : discoverConfigFile();
|
|
2051
2179
|
}
|
|
2052
|
-
const resolveChildExtends = (configFile, child, configEnv) =>
|
|
2180
|
+
const resolveChildExtends = (configFile, child, configEnv) => "extends" in child ? resolveExtends(configFile, child, configEnv) : Effect$1.succeed(child);
|
|
2053
2181
|
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
2182
|
function loadOptionsFromConfigFile(cliOptions, configEnv) {
|
|
2055
2183
|
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 +2192,7 @@ function readConfig(cliOptions, invocation) {
|
|
|
2064
2192
|
};
|
|
2065
2193
|
const cliRecord = yield* S.decodeEffect(ConfigDocumentSchema)(cliOptions).pipe(Effect$1.orDie);
|
|
2066
2194
|
const fileRecord = yield* loadOptionsFromConfigFile(cliRecord, configEnv);
|
|
2067
|
-
const fileOptions = yield* Result.match(S.
|
|
2195
|
+
const fileOptions = yield* Result.match(S.decodeResult(ConfigDocumentSchema)(fileRecord), {
|
|
2068
2196
|
onFailure: (cause) => Effect$1.fail(ConfigFileInvalidError.make({
|
|
2069
2197
|
file: "config",
|
|
2070
2198
|
cause
|
|
@@ -2182,7 +2310,9 @@ const failPluginLoad = (descriptor, error) => Effect$1.logWarning(`Error during
|
|
|
2182
2310
|
}))));
|
|
2183
2311
|
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
2312
|
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) =>
|
|
2313
|
+
const moduleSchemaContribution = (module) => {
|
|
2314
|
+
if (hasValidationSchemaContribution(module)) return module.strykerValidationSchema;
|
|
2315
|
+
};
|
|
2186
2316
|
const pluginContributionsOf = (module) => Result.flatMap(moduleIgnorers(module), (ignorers) => Result.map(modulePluginContributions(module), (plugins) => ({
|
|
2187
2317
|
plugins,
|
|
2188
2318
|
ignorers,
|
|
@@ -2713,96 +2843,6 @@ const planInstrumentation = Workflow.make(InstrumentCommand, (command) => Match.
|
|
|
2713
2843
|
fileCount: command.fileCount
|
|
2714
2844
|
})))));
|
|
2715
2845
|
//#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
2846
|
//#region src/IncrementalReport.schema.ts
|
|
2807
2847
|
const PositionSchema = S.Struct({
|
|
2808
2848
|
line: S.Finite,
|
|
@@ -2893,7 +2933,7 @@ const decide = (command) => Option.match(Option.fromUndefinedOr(command.report),
|
|
|
2893
2933
|
const admitIncrementalReport = Workflow.total(AdmitIncrementalReportCommand, (command) => Result.succeed(decide(command)));
|
|
2894
2934
|
//#endregion
|
|
2895
2935
|
//#region src/stryker-package.ts
|
|
2896
|
-
const strykerVersion = "10.1.
|
|
2936
|
+
const strykerVersion = "10.1.2";
|
|
2897
2937
|
//#endregion
|
|
2898
2938
|
//#region src/incremental-report.cell.ts
|
|
2899
2939
|
const parseAndDecodeIncrementalReport = S.decodeUnknownResult(S.fromJsonString(IncrementalReportSchema));
|
|
@@ -3325,7 +3365,7 @@ function readProject(options, targetMutatePatterns, basePath) {
|
|
|
3325
3365
|
];
|
|
3326
3366
|
return Effect$1.gen(function* () {
|
|
3327
3367
|
const inputFileNames = yield* resolveInputFileNames(ignoreRules, basePath);
|
|
3328
|
-
const defaults = yield* defaultOptions;
|
|
3368
|
+
const defaults = yield* defaultOptions$1;
|
|
3329
3369
|
const decision = selectFiles((() => {
|
|
3330
3370
|
if (targetMutatePatterns === void 0) return {
|
|
3331
3371
|
inputFileNames,
|
|
@@ -3667,7 +3707,7 @@ const makeDisableTypeChecksPreprocessor = (options, impl) => (project) => Effect
|
|
|
3667
3707
|
message: "disableTypeChecks failed",
|
|
3668
3708
|
cause
|
|
3669
3709
|
})), 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\`)`);
|
|
3710
|
+
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
3711
|
})), Effect$1.orElseSucceed(() => void 0));
|
|
3672
3712
|
if (content !== void 0) return withContent(file, content);
|
|
3673
3713
|
})), Match.orElse(() => Effect$1.succeedNone)), { concurrency: 24 })).forEach(mergeUpdatedInto(project));
|
|
@@ -3695,7 +3735,10 @@ const parseJsonText = (jsonText) => {
|
|
|
3695
3735
|
return Result.fail(errorToString(error));
|
|
3696
3736
|
}
|
|
3697
3737
|
};
|
|
3698
|
-
const parseTsConfigShape = (fileName, parsed) =>
|
|
3738
|
+
const parseTsConfigShape = (fileName, parsed) => {
|
|
3739
|
+
if (Schema.is(TsConfigSchema)(parsed)) return Result.succeed(parsed);
|
|
3740
|
+
return Result.fail(tsConfigParseError(fileName, `parsed to ${JSON.stringify(parsed)}, which does not match the tsconfig shape this package consumes`));
|
|
3741
|
+
};
|
|
3699
3742
|
function parseTsConfig(fileName, jsonText) {
|
|
3700
3743
|
return Result.match(parseJsonText(jsonText), {
|
|
3701
3744
|
onFailure: (reason) => Result.fail(tsConfigParseError(fileName, reason)),
|
|
@@ -5127,8 +5170,8 @@ const reportDroppedMutants = (dropped) => Match.value(dropped.length).pipe(Match
|
|
|
5127
5170
|
yield* Metric.update(checkerMutantsSkipped, dropped.length);
|
|
5128
5171
|
yield* Effect$1.logWarning(`${dropped.length} mutant(s) cannot be described to a checker and were left out of the run (${droppedIdsOf(dropped)})`);
|
|
5129
5172
|
})));
|
|
5130
|
-
const
|
|
5131
|
-
const reasonOf = (result) =>
|
|
5173
|
+
const stringReasonOrUndefined = (val) => typeof val === "string" ? val : void 0;
|
|
5174
|
+
const reasonOf = (result) => "reason" in result ? stringReasonOrUndefined(result.reason) : void 0;
|
|
5132
5175
|
const stopWallClock = (result) => {
|
|
5133
5176
|
if (!wallClockTimeoutStopsRun(result.status, reasonOf(result))) return Effect$1.void;
|
|
5134
5177
|
return Effect$1.fail(StageError.make({
|
|
@@ -5595,7 +5638,7 @@ const drawMutationScoreTable = (metricsResult, options) => {
|
|
|
5595
5638
|
//#endregion
|
|
5596
5639
|
//#region src/Reporter.schema.ts
|
|
5597
5640
|
var ClearTextReportCommand = class extends S.TaggedClass()("ClearTextReportCommand", {
|
|
5598
|
-
report: MutationTestResultSchema
|
|
5641
|
+
report: MutationTestResultSchema,
|
|
5599
5642
|
metrics: MetricsResultSchema
|
|
5600
5643
|
}) {};
|
|
5601
5644
|
//#endregion
|
|
@@ -6079,9 +6122,7 @@ var MachineReporters = class extends S.TaggedClass()("MachineReporters", { repor
|
|
|
6079
6122
|
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
6123
|
//#endregion
|
|
6081
6124
|
//#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"]);
|
|
6125
|
+
const schemaPropertiesOf = (document) => Option.getOrElse(Option.fromNullishOr(document.properties), () => ({}));
|
|
6085
6126
|
const buildMergedSchema = (core, contributions) => Match.value(contributions.length === 0).pipe(Match.when(true, () => core), Match.orElse(() => ({
|
|
6086
6127
|
...core,
|
|
6087
6128
|
properties: Object.assign({}, schemaPropertiesOf(core), ...contributions.map((contribution) => schemaPropertiesOf(contribution)))
|
|
@@ -6385,7 +6426,6 @@ const makeRunEventStream = (resolved) => Effect$1.gen(function* () {
|
|
|
6385
6426
|
const RunEventStreamLive = Layer.succeed(RunEventStreamPort, RunEventStreamPort.of({ createRunEventStream: (resolved) => makeRunEventStream(resolved) }));
|
|
6386
6427
|
//#endregion
|
|
6387
6428
|
//#region ../stryker-js-html-reporter/dist/index.mjs
|
|
6388
|
-
const MutationTestResultSchema = S.Unknown;
|
|
6389
6429
|
var HtmlReportCommand = class extends S.TaggedClass()("HtmlReportCommand", {
|
|
6390
6430
|
report: MutationTestResultSchema,
|
|
6391
6431
|
scriptContent: S.String
|
|
@@ -6515,4 +6555,4 @@ const strykerCell = (options, targetMutatePatterns) => Effect$1.gen(function* ()
|
|
|
6515
6555
|
}, prepareCommandOf(options, patterns));
|
|
6516
6556
|
});
|
|
6517
6557
|
//#endregion
|
|
6518
|
-
export {
|
|
6558
|
+
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 };
|