@isentinel/jest-roblox 0.3.0 → 0.3.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/README.md +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +36 -0
- package/dist/index.mjs +1 -1
- package/dist/{run-BEUPi80L.mjs → run-Cl5gYSQr.mjs} +339 -228
- package/dist/sea-entry.cjs +343 -227
- package/package.json +4 -4
package/dist/sea-entry.cjs
CHANGED
|
@@ -686,7 +686,7 @@ function C$4({ force: e } = {}) {
|
|
|
686
686
|
var y$3 = C$4();
|
|
687
687
|
//#endregion
|
|
688
688
|
//#region package.json
|
|
689
|
-
var version = "0.3.
|
|
689
|
+
var version = "0.3.1";
|
|
690
690
|
//#endregion
|
|
691
691
|
//#region src/config/errors.ts
|
|
692
692
|
var ConfigError = class extends Error {
|
|
@@ -5332,6 +5332,11 @@ async function findWorkspaceDir(id = process.cwd(), options = {}) {
|
|
|
5332
5332
|
throw new Error(`Cannot detect workspace root from ${id}`);
|
|
5333
5333
|
}
|
|
5334
5334
|
//#endregion
|
|
5335
|
+
//#region \0sea-stub:giget
|
|
5336
|
+
var require__sea_stub_giget = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
5337
|
+
module.exports = {};
|
|
5338
|
+
}));
|
|
5339
|
+
//#endregion
|
|
5335
5340
|
//#region node_modules/.pnpm/c12@4.0.0-beta.5_jiti@2.7.0_magicast@0.5.3/node_modules/c12/dist/_chunks/libs/ohash.mjs
|
|
5336
5341
|
var ohash_exports = /* @__PURE__ */ __exportAll$1({
|
|
5337
5342
|
n: () => dist_exports,
|
|
@@ -11261,7 +11266,7 @@ async function resolveConfig$1(source, options, sourceOptions = {}) {
|
|
|
11261
11266
|
const customProviderKeys = Object.keys(sourceOptions.giget?.providers || {}).map((key) => `${key}:`);
|
|
11262
11267
|
const gigetPrefixes = customProviderKeys.length > 0 ? [...new Set([...customProviderKeys, ...GIGET_PREFIXES])] : GIGET_PREFIXES;
|
|
11263
11268
|
if (options.giget !== false && gigetPrefixes.some((prefix) => source.startsWith(prefix))) {
|
|
11264
|
-
const { downloadTemplate } = await
|
|
11269
|
+
const { downloadTemplate } = await Promise.resolve().then(() => /* @__PURE__ */ __toESM(require__sea_stub_giget(), 1)).catch((error) => {
|
|
11265
11270
|
throw new Error(`Extending config from \`${source}\` requires \`giget\` peer dependency to be installed.\n\nInstall it with: \`npx nypm i giget\``, { cause: error });
|
|
11266
11271
|
});
|
|
11267
11272
|
const { digest } = await Promise.resolve().then(() => (init_ohash(), ohash_exports)).then((n) => n.n);
|
|
@@ -24412,6 +24417,7 @@ function convertToLuau(filePath) {
|
|
|
24412
24417
|
const RbxPathParent = Symbol("Parent");
|
|
24413
24418
|
var RojoResolver = class RojoResolver {
|
|
24414
24419
|
rbxPath = new Array();
|
|
24420
|
+
realpathCache = /* @__PURE__ */ new Map();
|
|
24415
24421
|
walkedConfigFilesInternal = /* @__PURE__ */ new Set();
|
|
24416
24422
|
walkedDirectoriesInternal = /* @__PURE__ */ new Set();
|
|
24417
24423
|
filePathToRbxPathMap = /* @__PURE__ */ new Map();
|
|
@@ -24422,12 +24428,12 @@ var RojoResolver = class RojoResolver {
|
|
|
24422
24428
|
static findRojoConfigFilePath(projectPath) {
|
|
24423
24429
|
const warnings = new Array();
|
|
24424
24430
|
const defaultPath = node_path.default.join(projectPath, ROJO_DEFAULT_NAME);
|
|
24425
|
-
if (
|
|
24431
|
+
if (node_fs.existsSync(defaultPath)) return {
|
|
24426
24432
|
path: defaultPath,
|
|
24427
24433
|
warnings
|
|
24428
24434
|
};
|
|
24429
24435
|
const candidates = new Array();
|
|
24430
|
-
for (const fileName of
|
|
24436
|
+
for (const fileName of node_fs.readdirSync(projectPath)) if (fileName !== ROJO_DEFAULT_NAME && (fileName === ROJO_OLD_NAME || ROJO_FILE_REGEX.test(fileName))) candidates.push(node_path.default.join(projectPath, fileName));
|
|
24431
24437
|
if (candidates.length > 1) warnings.push(`Multiple *.project.json files found, using ${candidates[0]}`);
|
|
24432
24438
|
return {
|
|
24433
24439
|
path: candidates[0],
|
|
@@ -24563,34 +24569,42 @@ var RojoResolver = class RojoResolver {
|
|
|
24563
24569
|
get walkedDirectories() {
|
|
24564
24570
|
return this.walkedDirectoriesInternal;
|
|
24565
24571
|
}
|
|
24572
|
+
cachedRealpath(targetPath) {
|
|
24573
|
+
let resolved = this.realpathCache.get(targetPath);
|
|
24574
|
+
if (resolved === void 0) {
|
|
24575
|
+
resolved = node_fs.realpathSync(targetPath);
|
|
24576
|
+
this.realpathCache.set(targetPath, resolved);
|
|
24577
|
+
}
|
|
24578
|
+
return resolved;
|
|
24579
|
+
}
|
|
24566
24580
|
getContainer(from, rbxPath) {
|
|
24567
24581
|
if (this.isGame && rbxPath) {
|
|
24568
24582
|
for (const container of from) if (arrayStartsWith(rbxPath, container)) return container;
|
|
24569
24583
|
}
|
|
24570
24584
|
}
|
|
24571
24585
|
parseConfig(rojoConfigFilePath, doNotPush = false) {
|
|
24572
|
-
if (!
|
|
24586
|
+
if (!node_fs.existsSync(rojoConfigFilePath)) {
|
|
24573
24587
|
this.warn(`RojoResolver: Path does not exist "${rojoConfigFilePath}"`);
|
|
24574
24588
|
return;
|
|
24575
24589
|
}
|
|
24576
|
-
const realPath =
|
|
24590
|
+
const realPath = this.cachedRealpath(rojoConfigFilePath);
|
|
24577
24591
|
this.walkedConfigFilesInternal.add(realPath);
|
|
24578
24592
|
let configJson;
|
|
24579
24593
|
try {
|
|
24580
|
-
configJson = JSON.parse(
|
|
24594
|
+
configJson = JSON.parse(node_fs.readFileSync(realPath, "utf8"));
|
|
24581
24595
|
} catch {}
|
|
24582
24596
|
if (isValidRojoConfig(configJson)) this.parseTree(node_path.default.dirname(rojoConfigFilePath), configJson.name, configJson.tree, doNotPush);
|
|
24583
24597
|
else this.warn("RojoResolver: Invalid configuration!");
|
|
24584
24598
|
}
|
|
24585
24599
|
parsePath(itemPath) {
|
|
24586
24600
|
const luauPath = convertToLuau(itemPath);
|
|
24587
|
-
const realPath =
|
|
24601
|
+
const realPath = node_fs.existsSync(luauPath) ? this.cachedRealpath(luauPath) : luauPath;
|
|
24588
24602
|
const extension = node_path.default.extname(luauPath);
|
|
24589
24603
|
if (ROJO_MODULE_EXTS.has(extension)) this.filePathToRbxPathMap.set(luauPath, [...this.rbxPath]);
|
|
24590
24604
|
else {
|
|
24591
|
-
const isDirectory =
|
|
24605
|
+
const isDirectory = node_fs.existsSync(realPath) && node_fs.statSync(realPath).isDirectory();
|
|
24592
24606
|
if (isDirectory) this.walkedDirectoriesInternal.add(realPath);
|
|
24593
|
-
if (isDirectory &&
|
|
24607
|
+
if (isDirectory && node_fs.readdirSync(realPath).includes(ROJO_DEFAULT_NAME)) this.parseConfig(node_path.default.join(luauPath, ROJO_DEFAULT_NAME), true);
|
|
24594
24608
|
else {
|
|
24595
24609
|
this.partitions.unshift({
|
|
24596
24610
|
fsPath: luauPath,
|
|
@@ -24607,26 +24621,40 @@ var RojoResolver = class RojoResolver {
|
|
|
24607
24621
|
for (const childName of Object.keys(tree).filter((value) => !value.startsWith("$"))) this.parseTree(basePath, childName, tree[childName]);
|
|
24608
24622
|
if (!doNotPush) this.rbxPath.pop();
|
|
24609
24623
|
}
|
|
24610
|
-
searchChildren(directory,
|
|
24611
|
-
|
|
24612
|
-
|
|
24613
|
-
|
|
24614
|
-
|
|
24615
|
-
|
|
24616
|
-
|
|
24617
|
-
if (
|
|
24624
|
+
searchChildren(directory, directoryEntries) {
|
|
24625
|
+
const projectFiles = new Array();
|
|
24626
|
+
const subDirectories = new Array();
|
|
24627
|
+
for (const entry of directoryEntries) {
|
|
24628
|
+
const childPath = node_path.default.join(directory, entry.name);
|
|
24629
|
+
let isFile = entry.isFile();
|
|
24630
|
+
let isDirectory = entry.isDirectory();
|
|
24631
|
+
if (!isFile && !isDirectory) try {
|
|
24632
|
+
const stat = node_fs.statSync(this.cachedRealpath(childPath));
|
|
24633
|
+
isFile = stat.isFile();
|
|
24634
|
+
isDirectory = stat.isDirectory();
|
|
24635
|
+
} catch (err) {
|
|
24636
|
+
this.warn(`RojoResolver: Failed to resolve "${childPath}" (${err.message})`);
|
|
24637
|
+
continue;
|
|
24638
|
+
}
|
|
24639
|
+
if (isFile && ROJO_FILE_REGEX.test(entry.name)) projectFiles.push(childPath);
|
|
24640
|
+
else if (isDirectory) subDirectories.push({
|
|
24641
|
+
name: entry.name,
|
|
24642
|
+
path: childPath
|
|
24643
|
+
});
|
|
24618
24644
|
}
|
|
24645
|
+
for (const childPath of projectFiles) this.parseConfig(childPath);
|
|
24646
|
+
for (const { name, path: childPath } of subDirectories) this.searchDirectory(childPath, name);
|
|
24619
24647
|
}
|
|
24620
24648
|
searchDirectory(directory, item) {
|
|
24621
|
-
const realPath =
|
|
24649
|
+
const realPath = this.cachedRealpath(directory);
|
|
24622
24650
|
this.walkedDirectoriesInternal.add(realPath);
|
|
24623
|
-
const
|
|
24624
|
-
if (
|
|
24651
|
+
const directoryEntries = node_fs.readdirSync(directory, { withFileTypes: true });
|
|
24652
|
+
if (directoryEntries.some((entry) => entry.name === ROJO_DEFAULT_NAME)) {
|
|
24625
24653
|
this.parseConfig(node_path.default.join(directory, ROJO_DEFAULT_NAME));
|
|
24626
24654
|
return;
|
|
24627
24655
|
}
|
|
24628
24656
|
if (item !== void 0) this.rbxPath.push(item);
|
|
24629
|
-
this.searchChildren(directory,
|
|
24657
|
+
this.searchChildren(directory, directoryEntries);
|
|
24630
24658
|
if (item !== void 0) this.rbxPath.pop();
|
|
24631
24659
|
}
|
|
24632
24660
|
warn(str) {
|
|
@@ -30020,7 +30048,7 @@ function createSnapshotPathResolver(config) {
|
|
|
30020
30048
|
const result = `${basePath}/${normalized.slice(prefix.length + 1)}`;
|
|
30021
30049
|
const mapping = findMapping(result, tsconfigMappings);
|
|
30022
30050
|
if (mapping !== void 0) return {
|
|
30023
|
-
filePath: replacePrefix(result, mapping.outDir, mapping.rootDir)
|
|
30051
|
+
filePath: replacePrefix(result, mapping.outDir, mapping.rootDir),
|
|
30024
30052
|
mapping
|
|
30025
30053
|
};
|
|
30026
30054
|
return { filePath: result };
|
|
@@ -30040,6 +30068,96 @@ function buildMappings(tree, prefix) {
|
|
|
30040
30068
|
return mappings;
|
|
30041
30069
|
}
|
|
30042
30070
|
//#endregion
|
|
30071
|
+
//#region src/timing/orchestration-collector.ts
|
|
30072
|
+
/**
|
|
30073
|
+
* A buffered span-tree profiler for a single, sequential host run. Nesting is
|
|
30074
|
+
* tracked with one shared stack, so spans must open and close in LIFO order:
|
|
30075
|
+
* profile a phase, and any spans it opens nest under it. It is NOT safe to run
|
|
30076
|
+
* two `profile` / `profileAsync` calls concurrently on the same collector (e.g.
|
|
30077
|
+
* `Promise.all`) — interleaved opens/closes would corrupt the stack. Create one
|
|
30078
|
+
* collector per run; `flushTimingReport` empties it so a second flush is a
|
|
30079
|
+
* no-op.
|
|
30080
|
+
*/
|
|
30081
|
+
function createTimingCollector(options = {}) {
|
|
30082
|
+
const clock = options.clock ?? { now: () => node_perf_hooks.performance.now() };
|
|
30083
|
+
const sink = options.sink ?? ((line) => void node_process.default.stderr.write(`${line}\n`));
|
|
30084
|
+
const enabled = options.enabled ?? node_process.default.env["TIMING"] !== void 0;
|
|
30085
|
+
const roots = /* @__PURE__ */ new Map();
|
|
30086
|
+
const stack = [];
|
|
30087
|
+
function open(name) {
|
|
30088
|
+
const top = stack.at(-1);
|
|
30089
|
+
const node = childOf(top === void 0 ? roots : top.children, name);
|
|
30090
|
+
stack.push(node);
|
|
30091
|
+
const start = clock.now();
|
|
30092
|
+
return () => {
|
|
30093
|
+
node.elapsedMs += clock.now() - start;
|
|
30094
|
+
stack.pop();
|
|
30095
|
+
};
|
|
30096
|
+
}
|
|
30097
|
+
function profile(name, func) {
|
|
30098
|
+
if (!enabled) return func();
|
|
30099
|
+
const close = open(name);
|
|
30100
|
+
try {
|
|
30101
|
+
return func();
|
|
30102
|
+
} finally {
|
|
30103
|
+
close();
|
|
30104
|
+
}
|
|
30105
|
+
}
|
|
30106
|
+
async function profileAsync(name, func) {
|
|
30107
|
+
if (!enabled) return func();
|
|
30108
|
+
const close = open(name);
|
|
30109
|
+
try {
|
|
30110
|
+
return await func();
|
|
30111
|
+
} finally {
|
|
30112
|
+
close();
|
|
30113
|
+
}
|
|
30114
|
+
}
|
|
30115
|
+
function record(name, elapsedMs) {
|
|
30116
|
+
if (!enabled) return;
|
|
30117
|
+
const top = stack.at(-1);
|
|
30118
|
+
const node = childOf(top === void 0 ? roots : top.children, name);
|
|
30119
|
+
node.elapsedMs += elapsedMs;
|
|
30120
|
+
}
|
|
30121
|
+
function emit(node, depth) {
|
|
30122
|
+
sink(`[TIMING] ${" ".repeat(depth)}${node.name}: ${String(Math.round(node.elapsedMs))}ms`);
|
|
30123
|
+
for (const child of node.children.values()) emit(child, depth + 1);
|
|
30124
|
+
}
|
|
30125
|
+
function flushTimingReport() {
|
|
30126
|
+
if (!enabled || roots.size === 0) return;
|
|
30127
|
+
let total = 0;
|
|
30128
|
+
for (const node of roots.values()) {
|
|
30129
|
+
emit(node, 0);
|
|
30130
|
+
total += Math.round(node.elapsedMs);
|
|
30131
|
+
}
|
|
30132
|
+
sink(`[TIMING] TOTAL (host): ${String(total)}ms`);
|
|
30133
|
+
roots.clear();
|
|
30134
|
+
}
|
|
30135
|
+
return {
|
|
30136
|
+
flushTimingReport,
|
|
30137
|
+
profile,
|
|
30138
|
+
profileAsync,
|
|
30139
|
+
record
|
|
30140
|
+
};
|
|
30141
|
+
}
|
|
30142
|
+
/**
|
|
30143
|
+
* Shared disabled collector for callers that thread a profiler through their
|
|
30144
|
+
* signatures but are invoked outside a profiled workspace run (single-mode
|
|
30145
|
+
* coverage, the `instrument` subcommand, tests). Every method is a no-op.
|
|
30146
|
+
*/
|
|
30147
|
+
const NOOP_TIMING_COLLECTOR = createTimingCollector({ enabled: false });
|
|
30148
|
+
function childOf(parent, name) {
|
|
30149
|
+
let node = parent.get(name);
|
|
30150
|
+
if (node === void 0) {
|
|
30151
|
+
node = {
|
|
30152
|
+
name,
|
|
30153
|
+
children: /* @__PURE__ */ new Map(),
|
|
30154
|
+
elapsedMs: 0
|
|
30155
|
+
};
|
|
30156
|
+
parent.set(name, node);
|
|
30157
|
+
}
|
|
30158
|
+
return node;
|
|
30159
|
+
}
|
|
30160
|
+
//#endregion
|
|
30043
30161
|
//#region src/types/rojo.ts
|
|
30044
30162
|
const rojoProjectSchema = type({
|
|
30045
30163
|
"name": "string",
|
|
@@ -30189,38 +30307,48 @@ function formatExecuteOutput(options) {
|
|
|
30189
30307
|
* config.
|
|
30190
30308
|
*/
|
|
30191
30309
|
async function runProjects(options) {
|
|
30192
|
-
const
|
|
30193
|
-
const
|
|
30194
|
-
|
|
30195
|
-
|
|
30196
|
-
|
|
30197
|
-
|
|
30198
|
-
|
|
30310
|
+
const timing = options.timing ?? NOOP_TIMING_COLLECTOR;
|
|
30311
|
+
const jobs = timing.profile("buildJobs", () => {
|
|
30312
|
+
return options.projects.map((project) => buildProjectJob(project, timing));
|
|
30313
|
+
});
|
|
30314
|
+
const { rawResults, timing: backendTiming } = await timing.profileAsync("backend.runTests", async () => {
|
|
30315
|
+
const result = await options.backend.runTests({
|
|
30316
|
+
jobs,
|
|
30317
|
+
parallel: options.parallel,
|
|
30318
|
+
scriptOverride: options.scriptOverride,
|
|
30319
|
+
streaming: options.streaming,
|
|
30320
|
+
workStealing: options.workStealing
|
|
30321
|
+
});
|
|
30322
|
+
recordBackendTimingSpans(timing, result.timing);
|
|
30323
|
+
return result;
|
|
30199
30324
|
});
|
|
30200
30325
|
if (rawResults.length !== jobs.length) throw new Error(`Backend returned ${rawResults.length.toString()} results for ${jobs.length.toString()} jobs — rawResults must be parallel to jobs`);
|
|
30201
30326
|
return {
|
|
30202
30327
|
backendTiming,
|
|
30203
|
-
results:
|
|
30204
|
-
|
|
30205
|
-
|
|
30206
|
-
|
|
30207
|
-
|
|
30208
|
-
|
|
30209
|
-
|
|
30210
|
-
|
|
30211
|
-
|
|
30212
|
-
|
|
30213
|
-
|
|
30214
|
-
|
|
30215
|
-
|
|
30216
|
-
|
|
30217
|
-
|
|
30218
|
-
|
|
30219
|
-
|
|
30220
|
-
|
|
30221
|
-
|
|
30222
|
-
|
|
30223
|
-
|
|
30328
|
+
results: timing.profile("processResults", () => {
|
|
30329
|
+
return rawResults.map((raw, index) => {
|
|
30330
|
+
const job = jobs[index];
|
|
30331
|
+
try {
|
|
30332
|
+
return processProjectResult(buildProjectResult(raw.entry, job, raw.fallbackGameOutput), {
|
|
30333
|
+
backendTiming,
|
|
30334
|
+
config: job.config,
|
|
30335
|
+
deferFormatting: options.deferFormatting,
|
|
30336
|
+
startTime: options.startTime,
|
|
30337
|
+
timing,
|
|
30338
|
+
version: options.version
|
|
30339
|
+
});
|
|
30340
|
+
} catch (err) {
|
|
30341
|
+
if (!(err instanceof LuauScriptError)) throw err;
|
|
30342
|
+
return buildExecutionErrorResult({
|
|
30343
|
+
backendTiming,
|
|
30344
|
+
config: job.config,
|
|
30345
|
+
deferFormatting: options.deferFormatting,
|
|
30346
|
+
error: err,
|
|
30347
|
+
startTime: options.startTime,
|
|
30348
|
+
version: options.version
|
|
30349
|
+
});
|
|
30350
|
+
}
|
|
30351
|
+
});
|
|
30224
30352
|
})
|
|
30225
30353
|
};
|
|
30226
30354
|
}
|
|
@@ -30261,6 +30389,10 @@ function parseTsconfigMappings(options) {
|
|
|
30261
30389
|
rootDir: normalizeDirectoryPath(options.rootDir ?? "src")
|
|
30262
30390
|
}];
|
|
30263
30391
|
}
|
|
30392
|
+
function recordBackendTimingSpans(timing, backendTiming) {
|
|
30393
|
+
if (backendTiming.uploadMs !== void 0) timing.record("uploadMs", backendTiming.uploadMs);
|
|
30394
|
+
timing.record("executionMs", backendTiming.executionMs);
|
|
30395
|
+
}
|
|
30264
30396
|
const EXIT_CODE_MESSAGE$1 = /^Exited with code: \d+$/;
|
|
30265
30397
|
/**
|
|
30266
30398
|
* Compose the human-readable failure message for an exec-error file
|
|
@@ -30461,7 +30593,7 @@ function writeSnapshots(snapshotWrites, config, tsconfigMappings) {
|
|
|
30461
30593
|
node_fs.writeFileSync(absolutePath, content);
|
|
30462
30594
|
const { filePath, mapping } = resolved;
|
|
30463
30595
|
if (mapping !== void 0) {
|
|
30464
|
-
const outPath = mapping.
|
|
30596
|
+
const outPath = replacePrefix(filePath, mapping.rootDir, mapping.outDir);
|
|
30465
30597
|
const absoluteOutPath = node_path.resolve(config.rootDir, outPath);
|
|
30466
30598
|
node_fs.mkdirSync(node_path.dirname(absoluteOutPath), { recursive: true });
|
|
30467
30599
|
node_fs.writeFileSync(absoluteOutPath, content);
|
|
@@ -30490,19 +30622,23 @@ function writeSnapshots(snapshotWrites, config, tsconfigMappings) {
|
|
|
30490
30622
|
* formatter output. Called once per job.
|
|
30491
30623
|
*/
|
|
30492
30624
|
function processProjectResult(entry, options) {
|
|
30493
|
-
const { backendTiming, config, deferFormatting, startTime, version } = options;
|
|
30625
|
+
const { backendTiming, config, deferFormatting, startTime, timing, version } = options;
|
|
30494
30626
|
const { coverageData, gameOutput, luauTiming, result, setupMs, snapshotWrites } = entry;
|
|
30495
|
-
const tsconfigMappings =
|
|
30496
|
-
|
|
30627
|
+
const tsconfigMappings = timing.profile("resolveTsconfigMappings", () => {
|
|
30628
|
+
return resolveAllTsconfigMappings(config.rootDir);
|
|
30629
|
+
});
|
|
30630
|
+
const writeCounts = snapshotWrites !== void 0 ? timing.profile("writeSnapshots", () => {
|
|
30631
|
+
return writeSnapshots(snapshotWrites, config, tsconfigMappings);
|
|
30632
|
+
}) : {
|
|
30497
30633
|
attempted: 0,
|
|
30498
30634
|
failed: 0,
|
|
30499
30635
|
written: 0
|
|
30500
30636
|
};
|
|
30501
30637
|
const testsMs = calculateTestsMs(result.testResults);
|
|
30502
|
-
const sourceMapper = config.sourceMap ? buildSourceMapper(config, tsconfigMappings) : void 0;
|
|
30638
|
+
const sourceMapper = config.sourceMap ? timing.profile("buildSourceMapper", () => buildSourceMapper(config, tsconfigMappings)) : void 0;
|
|
30503
30639
|
resolveTestFilePaths(result, sourceMapper);
|
|
30504
30640
|
const totalMs = Date.now() - startTime;
|
|
30505
|
-
const
|
|
30641
|
+
const resultTiming = {
|
|
30506
30642
|
executionMs: backendTiming.executionMs,
|
|
30507
30643
|
setupMs,
|
|
30508
30644
|
startTime,
|
|
@@ -30515,7 +30651,7 @@ function processProjectResult(entry, options) {
|
|
|
30515
30651
|
result,
|
|
30516
30652
|
snapshotWriteFailures: writeCounts.failed,
|
|
30517
30653
|
sourceMapper,
|
|
30518
|
-
timing,
|
|
30654
|
+
timing: resultTiming,
|
|
30519
30655
|
version
|
|
30520
30656
|
}) : "";
|
|
30521
30657
|
if (luauTiming !== void 0) printLuauTiming(luauTiming);
|
|
@@ -30527,7 +30663,7 @@ function processProjectResult(entry, options) {
|
|
|
30527
30663
|
result,
|
|
30528
30664
|
snapshotWriteFailures: writeCounts.failed > 0 ? writeCounts.failed : void 0,
|
|
30529
30665
|
sourceMapper,
|
|
30530
|
-
timing
|
|
30666
|
+
timing: resultTiming
|
|
30531
30667
|
};
|
|
30532
30668
|
}
|
|
30533
30669
|
/**
|
|
@@ -30535,8 +30671,10 @@ function processProjectResult(entry, options) {
|
|
|
30535
30671
|
* carries its own config so the Luau runner never re-resolves or shares format
|
|
30536
30672
|
* state across projects (fixes the spike's snapshot-diff regression — C1).
|
|
30537
30673
|
*/
|
|
30538
|
-
function buildProjectJob(parameters) {
|
|
30539
|
-
const tsconfigMappings =
|
|
30674
|
+
function buildProjectJob(parameters, timing) {
|
|
30675
|
+
const tsconfigMappings = timing.profile("resolveTsconfigMappings", () => {
|
|
30676
|
+
return resolveAllTsconfigMappings(parameters.config.rootDir);
|
|
30677
|
+
});
|
|
30540
30678
|
const luauProject = isLuauProject(parameters.testFiles, tsconfigMappings);
|
|
30541
30679
|
return {
|
|
30542
30680
|
config: applySnapshotFormatDefaults(parameters.config, luauProject),
|
|
@@ -38915,89 +39053,6 @@ function buildWithRojo(projectPath, outputPath) {
|
|
|
38915
39053
|
}
|
|
38916
39054
|
}
|
|
38917
39055
|
//#endregion
|
|
38918
|
-
//#region src/timing/orchestration-collector.ts
|
|
38919
|
-
/**
|
|
38920
|
-
* A buffered span-tree profiler for a single, sequential host run. Nesting is
|
|
38921
|
-
* tracked with one shared stack, so spans must open and close in LIFO order:
|
|
38922
|
-
* profile a phase, and any spans it opens nest under it. It is NOT safe to run
|
|
38923
|
-
* two `profile` / `profileAsync` calls concurrently on the same collector (e.g.
|
|
38924
|
-
* `Promise.all`) — interleaved opens/closes would corrupt the stack. Create one
|
|
38925
|
-
* collector per run; `flushTimingReport` empties it so a second flush is a
|
|
38926
|
-
* no-op.
|
|
38927
|
-
*/
|
|
38928
|
-
function createTimingCollector(options = {}) {
|
|
38929
|
-
const clock = options.clock ?? { now: () => node_perf_hooks.performance.now() };
|
|
38930
|
-
const sink = options.sink ?? ((line) => void node_process.default.stderr.write(`${line}\n`));
|
|
38931
|
-
const enabled = options.enabled ?? node_process.default.env["TIMING"] !== void 0;
|
|
38932
|
-
const roots = /* @__PURE__ */ new Map();
|
|
38933
|
-
const stack = [];
|
|
38934
|
-
function open(name) {
|
|
38935
|
-
const top = stack.at(-1);
|
|
38936
|
-
const node = childOf(top === void 0 ? roots : top.children, name);
|
|
38937
|
-
stack.push(node);
|
|
38938
|
-
const start = clock.now();
|
|
38939
|
-
return () => {
|
|
38940
|
-
node.elapsedMs += clock.now() - start;
|
|
38941
|
-
stack.pop();
|
|
38942
|
-
};
|
|
38943
|
-
}
|
|
38944
|
-
function profile(name, func) {
|
|
38945
|
-
if (!enabled) return func();
|
|
38946
|
-
const close = open(name);
|
|
38947
|
-
try {
|
|
38948
|
-
return func();
|
|
38949
|
-
} finally {
|
|
38950
|
-
close();
|
|
38951
|
-
}
|
|
38952
|
-
}
|
|
38953
|
-
async function profileAsync(name, func) {
|
|
38954
|
-
if (!enabled) return func();
|
|
38955
|
-
const close = open(name);
|
|
38956
|
-
try {
|
|
38957
|
-
return await func();
|
|
38958
|
-
} finally {
|
|
38959
|
-
close();
|
|
38960
|
-
}
|
|
38961
|
-
}
|
|
38962
|
-
function emit(node, depth) {
|
|
38963
|
-
sink(`[TIMING] ${" ".repeat(depth)}${node.name}: ${String(Math.round(node.elapsedMs))}ms`);
|
|
38964
|
-
for (const child of node.children.values()) emit(child, depth + 1);
|
|
38965
|
-
}
|
|
38966
|
-
function flushTimingReport() {
|
|
38967
|
-
if (!enabled || roots.size === 0) return;
|
|
38968
|
-
let total = 0;
|
|
38969
|
-
for (const node of roots.values()) {
|
|
38970
|
-
emit(node, 0);
|
|
38971
|
-
total += Math.round(node.elapsedMs);
|
|
38972
|
-
}
|
|
38973
|
-
sink(`[TIMING] TOTAL (host): ${String(total)}ms`);
|
|
38974
|
-
roots.clear();
|
|
38975
|
-
}
|
|
38976
|
-
return {
|
|
38977
|
-
flushTimingReport,
|
|
38978
|
-
profile,
|
|
38979
|
-
profileAsync
|
|
38980
|
-
};
|
|
38981
|
-
}
|
|
38982
|
-
/**
|
|
38983
|
-
* Shared disabled collector for callers that thread a profiler through their
|
|
38984
|
-
* signatures but are invoked outside a profiled workspace run (single-mode
|
|
38985
|
-
* coverage, the `instrument` subcommand, tests). Every method is a no-op.
|
|
38986
|
-
*/
|
|
38987
|
-
const NOOP_TIMING_COLLECTOR = createTimingCollector({ enabled: false });
|
|
38988
|
-
function childOf(parent, name) {
|
|
38989
|
-
let node = parent.get(name);
|
|
38990
|
-
if (node === void 0) {
|
|
38991
|
-
node = {
|
|
38992
|
-
name,
|
|
38993
|
-
children: /* @__PURE__ */ new Map(),
|
|
38994
|
-
elapsedMs: 0
|
|
38995
|
-
};
|
|
38996
|
-
parent.set(name, node);
|
|
38997
|
-
}
|
|
38998
|
-
return node;
|
|
38999
|
-
}
|
|
39000
|
-
//#endregion
|
|
39001
39056
|
//#region src/utils/hash.ts
|
|
39002
39057
|
function hashBuffer(data) {
|
|
39003
39058
|
return (0, node_crypto.createHash)("sha256").update(data).digest("hex");
|
|
@@ -40472,15 +40527,26 @@ function classifyTestFiles(files, config) {
|
|
|
40472
40527
|
typeTestFiles
|
|
40473
40528
|
};
|
|
40474
40529
|
}
|
|
40530
|
+
function resolveAllSetupFilePaths(configs) {
|
|
40531
|
+
const resolvers = /* @__PURE__ */ new Map();
|
|
40532
|
+
for (const config of configs) {
|
|
40533
|
+
if (config.setupFiles === void 0 && config.setupFilesAfterEnv === void 0) continue;
|
|
40534
|
+
const rojoConfigPath = node_path.resolve(config.rootDir, config.rojoProject ?? DEFAULT_ROJO_PROJECT$1);
|
|
40535
|
+
const key = JSON.stringify([config.rootDir, rojoConfigPath]);
|
|
40536
|
+
let resolve = resolvers.get(key);
|
|
40537
|
+
if (resolve === void 0) {
|
|
40538
|
+
resolve = createSetupResolver({
|
|
40539
|
+
configDirectory: config.rootDir,
|
|
40540
|
+
rojoConfigPath
|
|
40541
|
+
});
|
|
40542
|
+
resolvers.set(key, resolve);
|
|
40543
|
+
}
|
|
40544
|
+
if (config.setupFiles !== void 0) config.setupFiles = config.setupFiles.map(resolve);
|
|
40545
|
+
if (config.setupFilesAfterEnv !== void 0) config.setupFilesAfterEnv = config.setupFilesAfterEnv.map(resolve);
|
|
40546
|
+
}
|
|
40547
|
+
}
|
|
40475
40548
|
function resolveSetupFilePaths(config) {
|
|
40476
|
-
|
|
40477
|
-
const rojoConfigPath = node_path.resolve(config.rootDir, config.rojoProject ?? DEFAULT_ROJO_PROJECT$1);
|
|
40478
|
-
const resolve = createSetupResolver({
|
|
40479
|
-
configDirectory: config.rootDir,
|
|
40480
|
-
rojoConfigPath
|
|
40481
|
-
});
|
|
40482
|
-
if (config.setupFiles !== void 0) config.setupFiles = config.setupFiles.map(resolve);
|
|
40483
|
-
if (config.setupFilesAfterEnv !== void 0) config.setupFilesAfterEnv = config.setupFilesAfterEnv.map(resolve);
|
|
40549
|
+
resolveAllSetupFilePaths([config]);
|
|
40484
40550
|
}
|
|
40485
40551
|
//#endregion
|
|
40486
40552
|
//#region src/run/multi.ts
|
|
@@ -40488,30 +40554,52 @@ const DEFAULT_ROJO_PROJECT = "default.project.json";
|
|
|
40488
40554
|
const VERSION$3 = version;
|
|
40489
40555
|
async function runMultiProject(options) {
|
|
40490
40556
|
const { cli, config: rootConfig, rawProjects } = options;
|
|
40491
|
-
const
|
|
40492
|
-
|
|
40493
|
-
const
|
|
40557
|
+
const timing = options.timing ?? NOOP_TIMING_COLLECTOR;
|
|
40558
|
+
const rojoTree = timing.profile("loadRojoTree", () => loadRojoTree(rootConfig));
|
|
40559
|
+
const allProjects = await timing.profileAsync("resolveAllProjects", async () => {
|
|
40560
|
+
return resolveAllProjects(rawProjects, rootConfig, rojoTree, rootConfig.rootDir);
|
|
40561
|
+
});
|
|
40562
|
+
timing.profile("resolveSetupFilePaths", () => {
|
|
40563
|
+
resolveAllSetupFilePaths(allProjects.map((project) => project.config));
|
|
40564
|
+
});
|
|
40565
|
+
const { filesByProject, projects } = timing.profile("selectProjects", () => {
|
|
40566
|
+
return selectProjects(allProjects, cli.project, cli.files, rootConfig.rootDir);
|
|
40567
|
+
});
|
|
40494
40568
|
const cacheRoot = node_path.resolve(rootConfig.rootDir, ".jest-roblox", "cache");
|
|
40495
|
-
const cleaned = cleanLeftoverStubs
|
|
40569
|
+
const cleaned = timing.profile("cleanLeftoverStubs", () => {
|
|
40570
|
+
return cleanLeftoverStubs(projects, rootConfig.rootDir);
|
|
40571
|
+
});
|
|
40496
40572
|
if (cleaned.length > 0) node_process.default.stderr.write(`jest-roblox: cleaned ${String(cleaned.length)} leftover stub(s):\n${cleaned.map((stubPath) => ` ${stubPath}\n`).join("")}`);
|
|
40497
|
-
generateProjectStubs
|
|
40498
|
-
|
|
40499
|
-
|
|
40573
|
+
timing.profile("generateProjectStubs", () => {
|
|
40574
|
+
generateProjectStubs(projects, rootConfig.rootDir, cacheRoot);
|
|
40575
|
+
});
|
|
40576
|
+
const { effectiveConfig, preCoverageMs } = timing.profile("prepareCoverage", () => {
|
|
40577
|
+
return prepareMultiProjectCoverage(rootConfig, projects, cacheRoot);
|
|
40578
|
+
});
|
|
40579
|
+
const backend = await timing.profileAsync("resolveBackend", async () => {
|
|
40580
|
+
return resolveBackend(cli, effectiveConfig);
|
|
40581
|
+
});
|
|
40500
40582
|
const parallel = effectiveParallelForBackend(effectiveConfig.parallel, backend);
|
|
40501
|
-
if (!rootConfig.collectCoverage && backend.kind === "open-cloud") buildOpenCloudPlace
|
|
40502
|
-
|
|
40503
|
-
cliFiles: cli.files,
|
|
40504
|
-
effectivePlaceFile: effectiveConfig.placeFile,
|
|
40505
|
-
filesByProject,
|
|
40506
|
-
projects,
|
|
40507
|
-
rootConfig
|
|
40583
|
+
if (!rootConfig.collectCoverage && backend.kind === "open-cloud") timing.profile("buildOpenCloudPlace", () => {
|
|
40584
|
+
buildOpenCloudPlace(rootConfig, projects, cacheRoot);
|
|
40508
40585
|
});
|
|
40509
|
-
const
|
|
40586
|
+
const { allTypeTestFiles, pendingJobs } = timing.profile("collectPendingJobs", () => {
|
|
40587
|
+
return collectPendingJobs({
|
|
40588
|
+
cliFiles: cli.files,
|
|
40589
|
+
effectivePlaceFile: effectiveConfig.placeFile,
|
|
40590
|
+
filesByProject,
|
|
40591
|
+
projects,
|
|
40592
|
+
rootConfig
|
|
40593
|
+
});
|
|
40594
|
+
});
|
|
40595
|
+
const projectResults = await runJobs(backend, pendingJobs, parallel, timing);
|
|
40510
40596
|
const uniqueTypeTestFiles = [...new Set(allTypeTestFiles)];
|
|
40511
|
-
const typecheckResult = uniqueTypeTestFiles.length > 0 ? runTypecheck({
|
|
40512
|
-
|
|
40513
|
-
|
|
40514
|
-
|
|
40597
|
+
const typecheckResult = uniqueTypeTestFiles.length > 0 ? timing.profile("runTypecheck", () => {
|
|
40598
|
+
return runTypecheck({
|
|
40599
|
+
files: uniqueTypeTestFiles,
|
|
40600
|
+
rootDir: rootConfig.rootDir,
|
|
40601
|
+
tsconfig: rootConfig.typecheckTsconfig
|
|
40602
|
+
});
|
|
40515
40603
|
}) : void 0;
|
|
40516
40604
|
if (projectResults.length === 0 && typecheckResult === void 0) {
|
|
40517
40605
|
if (rootConfig.passWithNoTests) return {
|
|
@@ -40599,28 +40687,31 @@ function collectPendingJobs(arguments_) {
|
|
|
40599
40687
|
pendingJobs
|
|
40600
40688
|
};
|
|
40601
40689
|
}
|
|
40602
|
-
async function runJobs(backend, pendingJobs, parallel) {
|
|
40690
|
+
async function runJobs(backend, pendingJobs, parallel, timing) {
|
|
40603
40691
|
if (pendingJobs.length === 0) {
|
|
40604
40692
|
await backend.close?.();
|
|
40605
40693
|
return [];
|
|
40606
40694
|
}
|
|
40607
40695
|
let runResult;
|
|
40608
40696
|
try {
|
|
40609
|
-
runResult = await runProjects({
|
|
40610
|
-
|
|
40611
|
-
|
|
40612
|
-
|
|
40613
|
-
|
|
40614
|
-
|
|
40615
|
-
|
|
40616
|
-
|
|
40617
|
-
|
|
40618
|
-
|
|
40619
|
-
|
|
40620
|
-
|
|
40621
|
-
|
|
40622
|
-
|
|
40623
|
-
|
|
40697
|
+
runResult = await timing.profileAsync("runProjects", async () => {
|
|
40698
|
+
return runProjects({
|
|
40699
|
+
backend,
|
|
40700
|
+
deferFormatting: true,
|
|
40701
|
+
parallel,
|
|
40702
|
+
projects: pendingJobs.map((pending) => {
|
|
40703
|
+
return {
|
|
40704
|
+
config: pending.config,
|
|
40705
|
+
displayColor: pending.displayColor,
|
|
40706
|
+
displayName: pending.displayName,
|
|
40707
|
+
runtimeInjectionPaths: pending.runtimeInjectionPaths,
|
|
40708
|
+
testFiles: pending.runtimeFiles
|
|
40709
|
+
};
|
|
40710
|
+
}),
|
|
40711
|
+
startTime: Date.now(),
|
|
40712
|
+
timing,
|
|
40713
|
+
version: VERSION$3
|
|
40714
|
+
});
|
|
40624
40715
|
});
|
|
40625
40716
|
} finally {
|
|
40626
40717
|
await backend.close?.();
|
|
@@ -40697,9 +40788,14 @@ function selectProjects(allProjects, projectNames, cliFiles, rootDirectory) {
|
|
|
40697
40788
|
const VERSION$2 = version;
|
|
40698
40789
|
async function runSingleProject(options) {
|
|
40699
40790
|
const { cli } = options;
|
|
40700
|
-
const
|
|
40701
|
-
|
|
40702
|
-
|
|
40791
|
+
const timing = options.timing ?? NOOP_TIMING_COLLECTOR;
|
|
40792
|
+
const config = timing.profile("narrowConfigByFiles", () => {
|
|
40793
|
+
return narrowConfigByFiles(options.config, cli.files ?? []);
|
|
40794
|
+
});
|
|
40795
|
+
timing.profile("resolveSetupFilePaths", () => {
|
|
40796
|
+
resolveSetupFilePaths(config);
|
|
40797
|
+
});
|
|
40798
|
+
const discovery = timing.profile("discoverTestFiles", () => discoverTestFiles(config, cli.files));
|
|
40703
40799
|
if (discovery.files.length === 0) {
|
|
40704
40800
|
if (config.passWithNoTests) return {
|
|
40705
40801
|
mode: "single",
|
|
@@ -40712,7 +40808,9 @@ async function runSingleProject(options) {
|
|
|
40712
40808
|
validationExitCode: 2
|
|
40713
40809
|
};
|
|
40714
40810
|
}
|
|
40715
|
-
const { runtimeFiles, typeTestFiles } = classifyTestFiles
|
|
40811
|
+
const { runtimeFiles, typeTestFiles } = timing.profile("classifyTestFiles", () => {
|
|
40812
|
+
return classifyTestFiles(discovery.files, config);
|
|
40813
|
+
});
|
|
40716
40814
|
if (typeTestFiles.length === 0 && runtimeFiles.length === 0) {
|
|
40717
40815
|
if (config.passWithNoTests) return {
|
|
40718
40816
|
mode: "single",
|
|
@@ -40729,19 +40827,27 @@ async function runSingleProject(options) {
|
|
|
40729
40827
|
let effectiveConfig = config;
|
|
40730
40828
|
if (config.collectCoverage && !config.typecheckOnly && runtimeFiles.length > 0) {
|
|
40731
40829
|
const preCoverageStart = Date.now();
|
|
40732
|
-
const { placeFile } = prepareCoverage(config);
|
|
40830
|
+
const { placeFile } = timing.profile("prepareCoverage", () => prepareCoverage(config));
|
|
40733
40831
|
preCoverageMs = Date.now() - preCoverageStart;
|
|
40734
40832
|
effectiveConfig = {
|
|
40735
40833
|
...config,
|
|
40736
40834
|
placeFile
|
|
40737
40835
|
};
|
|
40738
40836
|
}
|
|
40739
|
-
const typecheckResult = typeTestFiles.length > 0 ? runTypecheck({
|
|
40740
|
-
|
|
40741
|
-
|
|
40742
|
-
|
|
40837
|
+
const typecheckResult = typeTestFiles.length > 0 ? timing.profile("runTypecheck", () => {
|
|
40838
|
+
return runTypecheck({
|
|
40839
|
+
files: typeTestFiles,
|
|
40840
|
+
rootDir: effectiveConfig.rootDir,
|
|
40841
|
+
tsconfig: effectiveConfig.typecheckTsconfig
|
|
40842
|
+
});
|
|
40843
|
+
}) : void 0;
|
|
40844
|
+
const runtimeResult = runtimeFiles.length > 0 ? await executeRuntimeTests({
|
|
40845
|
+
cli,
|
|
40846
|
+
config: effectiveConfig,
|
|
40847
|
+
testFiles: runtimeFiles,
|
|
40848
|
+
timing,
|
|
40849
|
+
totalFiles: discovery.totalFiles
|
|
40743
40850
|
}) : void 0;
|
|
40744
|
-
const runtimeResult = runtimeFiles.length > 0 ? await executeRuntimeTests(options, effectiveConfig, runtimeFiles, discovery.totalFiles) : void 0;
|
|
40745
40851
|
return {
|
|
40746
40852
|
mode: "single",
|
|
40747
40853
|
preCoverageMs,
|
|
@@ -40749,19 +40855,25 @@ async function runSingleProject(options) {
|
|
|
40749
40855
|
typecheckResult
|
|
40750
40856
|
};
|
|
40751
40857
|
}
|
|
40752
|
-
async function executeRuntimeTests(options
|
|
40858
|
+
async function executeRuntimeTests(options) {
|
|
40859
|
+
const { cli, config, testFiles, timing, totalFiles } = options;
|
|
40753
40860
|
if (!config.silent && !usesAgentFormatter(config.formatters, config.verbose) && !hasFormatter(config.formatters, "json") && testFiles.length !== totalFiles) node_process.default.stderr.write(`Running ${String(testFiles.length)} of ${String(totalFiles)} test files\n`);
|
|
40754
|
-
const backend = await resolveBackend
|
|
40861
|
+
const backend = await timing.profileAsync("resolveBackend", async () => {
|
|
40862
|
+
return resolveBackend(cli, config);
|
|
40863
|
+
});
|
|
40755
40864
|
try {
|
|
40756
|
-
const { results } = await runProjects({
|
|
40757
|
-
|
|
40758
|
-
|
|
40759
|
-
|
|
40760
|
-
|
|
40761
|
-
|
|
40762
|
-
|
|
40763
|
-
|
|
40764
|
-
|
|
40865
|
+
const { results } = await timing.profileAsync("runProjects", async () => {
|
|
40866
|
+
return runProjects({
|
|
40867
|
+
backend,
|
|
40868
|
+
deferFormatting: true,
|
|
40869
|
+
projects: [{
|
|
40870
|
+
config,
|
|
40871
|
+
testFiles
|
|
40872
|
+
}],
|
|
40873
|
+
startTime: Date.now(),
|
|
40874
|
+
timing,
|
|
40875
|
+
version: VERSION$2
|
|
40876
|
+
});
|
|
40765
40877
|
});
|
|
40766
40878
|
return results[0];
|
|
40767
40879
|
} finally {
|
|
@@ -41497,12 +41609,7 @@ const SYNTHESIZED_PLACE_FILE = "synthesized.rbxl";
|
|
|
41497
41609
|
const WORKSPACE_CACHE_DIRECTORY = node_path.join(".jest-roblox", "workspace");
|
|
41498
41610
|
const ROJO_PROJECT_DEFAULT = "test.project.json";
|
|
41499
41611
|
async function runWorkspace(options) {
|
|
41500
|
-
|
|
41501
|
-
try {
|
|
41502
|
-
return await runWorkspaceProfiled(options, timing);
|
|
41503
|
-
} finally {
|
|
41504
|
-
timing.flushTimingReport();
|
|
41505
|
-
}
|
|
41612
|
+
return runWorkspaceProfiled(options, options.timing ?? NOOP_TIMING_COLLECTOR);
|
|
41506
41613
|
}
|
|
41507
41614
|
function buildCoverageMap(entries) {
|
|
41508
41615
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -41616,6 +41723,7 @@ async function runWorkspaceProfiled(options, timing) {
|
|
|
41616
41723
|
};
|
|
41617
41724
|
}),
|
|
41618
41725
|
startTime,
|
|
41726
|
+
timing,
|
|
41619
41727
|
version,
|
|
41620
41728
|
...dispatchSpec
|
|
41621
41729
|
});
|
|
@@ -42215,7 +42323,7 @@ const EMPTY_RESULT = {
|
|
|
42215
42323
|
preCoverageMs: 0,
|
|
42216
42324
|
projectResults: []
|
|
42217
42325
|
};
|
|
42218
|
-
async function runWorkspaceMode(cli, workspace) {
|
|
42326
|
+
async function runWorkspaceMode(cli, workspace, timing) {
|
|
42219
42327
|
const basicValidation = validateBasicWorkspaceFlags(cli);
|
|
42220
42328
|
if (!basicValidation.ok) return {
|
|
42221
42329
|
...EMPTY_RESULT,
|
|
@@ -42288,6 +42396,7 @@ async function runWorkspaceMode(cli, workspace) {
|
|
|
42288
42396
|
...onStreamingResult !== void 0 ? { onStreamingResult } : {},
|
|
42289
42397
|
packageInfos,
|
|
42290
42398
|
runOptions,
|
|
42399
|
+
timing,
|
|
42291
42400
|
version: VERSION$1,
|
|
42292
42401
|
workspaceRoot,
|
|
42293
42402
|
workStealingCredentials
|
|
@@ -42390,18 +42499,25 @@ function isWorkspaceInvocation(cli) {
|
|
|
42390
42499
|
return cli.workspace === true || cli.packages !== void 0 || cli.affectedSince !== void 0;
|
|
42391
42500
|
}
|
|
42392
42501
|
async function runJestRoblox(cli, config) {
|
|
42393
|
-
|
|
42394
|
-
|
|
42395
|
-
|
|
42396
|
-
|
|
42397
|
-
|
|
42398
|
-
|
|
42399
|
-
|
|
42400
|
-
|
|
42401
|
-
|
|
42402
|
-
|
|
42403
|
-
|
|
42404
|
-
|
|
42502
|
+
const timing = createTimingCollector();
|
|
42503
|
+
try {
|
|
42504
|
+
if (isWorkspaceInvocation(cli)) return await runWorkspaceMode(cli, config.workspace, timing);
|
|
42505
|
+
const merged = mergeCliWithConfig(cli, config);
|
|
42506
|
+
const rawProjects = merged.projects;
|
|
42507
|
+
if (rawProjects !== void 0 && rawProjects.length > 0) return await runMultiProject({
|
|
42508
|
+
cli,
|
|
42509
|
+
config: merged,
|
|
42510
|
+
rawProjects,
|
|
42511
|
+
timing
|
|
42512
|
+
});
|
|
42513
|
+
return await runSingleProject({
|
|
42514
|
+
cli,
|
|
42515
|
+
config: merged,
|
|
42516
|
+
timing
|
|
42517
|
+
});
|
|
42518
|
+
} finally {
|
|
42519
|
+
timing.flushTimingReport();
|
|
42520
|
+
}
|
|
42405
42521
|
}
|
|
42406
42522
|
//#endregion
|
|
42407
42523
|
//#region src/utils/error-chain.ts
|