@isentinel/jest-roblox 0.2.4 → 0.2.6
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/bin/jest-roblox.js +2 -2
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs +209 -95
- package/dist/{executor-B2IDh6bH.d.mts → executor-COuwZJJX.d.mts} +15 -2
- package/dist/{game-output-BtWj32M8.mjs → game-output-CCPIQMWm.mjs} +70 -34
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +1 -1
- package/dist/sea/jest-roblox +0 -0
- package/dist/sea-entry.cjs +1045 -5289
- package/package.json +4 -4
|
@@ -60,37 +60,12 @@ function extractJsonFromOutput(output) {
|
|
|
60
60
|
}
|
|
61
61
|
function parseJestOutput(output) {
|
|
62
62
|
const trimmed = output.trim();
|
|
63
|
-
if (trimmed.startsWith("{")) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const luauTiming = extractLuauTiming(parsed);
|
|
67
|
-
const setupSeconds = extractSetupSeconds(parsed);
|
|
68
|
-
const snapshotWrites = extractSnapshotWrites(parsed);
|
|
69
|
-
const unwrapped = unwrapResult(parsed);
|
|
70
|
-
if (unwrapped["kind"] === "ExecutionError") {
|
|
71
|
-
const errorMessage = extractExecutionError(unwrapped);
|
|
72
|
-
throw new Error(`Jest execution failed: ${errorMessage}`);
|
|
73
|
-
}
|
|
74
|
-
if (unwrapped["results"] !== void 0 && typeof unwrapped["results"] === "object") return {
|
|
75
|
-
coverageData,
|
|
76
|
-
luauTiming,
|
|
77
|
-
result: validateJestResult(unwrapped["results"]),
|
|
78
|
-
setupSeconds,
|
|
79
|
-
snapshotWrites
|
|
80
|
-
};
|
|
81
|
-
try {
|
|
82
|
-
return {
|
|
83
|
-
coverageData,
|
|
84
|
-
luauTiming,
|
|
85
|
-
result: validateJestResult(unwrapped),
|
|
86
|
-
setupSeconds,
|
|
87
|
-
snapshotWrites
|
|
88
|
-
};
|
|
89
|
-
} catch {}
|
|
90
|
-
}
|
|
63
|
+
if (trimmed.startsWith("{")) try {
|
|
64
|
+
return parseParsedOutput(JSON.parse(trimmed));
|
|
65
|
+
} catch {}
|
|
91
66
|
const jsonString = extractJsonFromOutput(output);
|
|
92
67
|
if (jsonString === void 0) throw new Error(`No valid Jest result JSON found in output, output was:\n${output}`);
|
|
93
|
-
return
|
|
68
|
+
return parseParsedOutput(JSON.parse(jsonString));
|
|
94
69
|
}
|
|
95
70
|
function countBraces(line) {
|
|
96
71
|
let count = 0;
|
|
@@ -201,6 +176,31 @@ function extractSetupSeconds(parsed) {
|
|
|
201
176
|
if (typeof setup !== "number") return;
|
|
202
177
|
return setup;
|
|
203
178
|
}
|
|
179
|
+
function parseParsedOutput(parsed) {
|
|
180
|
+
const coverageData = extractCoverageData(parsed);
|
|
181
|
+
const luauTiming = extractLuauTiming(parsed);
|
|
182
|
+
const setupSeconds = extractSetupSeconds(parsed);
|
|
183
|
+
const snapshotWrites = extractSnapshotWrites(parsed);
|
|
184
|
+
const unwrapped = unwrapResult(parsed);
|
|
185
|
+
if (unwrapped["kind"] === "ExecutionError") {
|
|
186
|
+
const errorMessage = extractExecutionError(unwrapped);
|
|
187
|
+
throw new Error(`Jest execution failed: ${errorMessage}`);
|
|
188
|
+
}
|
|
189
|
+
if (unwrapped["results"] !== void 0 && typeof unwrapped["results"] === "object") return {
|
|
190
|
+
coverageData,
|
|
191
|
+
luauTiming,
|
|
192
|
+
result: validateJestResult(unwrapped["results"]),
|
|
193
|
+
setupSeconds,
|
|
194
|
+
snapshotWrites
|
|
195
|
+
};
|
|
196
|
+
return {
|
|
197
|
+
coverageData,
|
|
198
|
+
luauTiming,
|
|
199
|
+
result: validateJestResult(unwrapped),
|
|
200
|
+
setupSeconds,
|
|
201
|
+
snapshotWrites
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
204
|
//#endregion
|
|
205
205
|
//#region packages/roblox-runner/dist/index.mjs
|
|
206
206
|
const CACHE_DIR_NAME = "jest-roblox";
|
|
@@ -520,7 +520,7 @@ function generateTestScript(options) {
|
|
|
520
520
|
//#endregion
|
|
521
521
|
//#region src/backends/open-cloud.ts
|
|
522
522
|
const PARALLEL_AUTO_CAP = 3;
|
|
523
|
-
const
|
|
523
|
+
const DEFAULT_OPEN_CLOUD_BASE_URL = "https://apis.roblox.com";
|
|
524
524
|
const RATE_LIMIT_DEFAULT_WAIT_MS = 5e3;
|
|
525
525
|
const MAX_RATE_LIMIT_RETRIES = 5;
|
|
526
526
|
const taskResponse = type({ path: "string" });
|
|
@@ -535,12 +535,14 @@ const envelopeSchema$1 = type({ entries: type({
|
|
|
535
535
|
"jestOutput": "string"
|
|
536
536
|
}).array() });
|
|
537
537
|
var OpenCloudBackend = class {
|
|
538
|
+
baseUrl;
|
|
538
539
|
credentials;
|
|
539
540
|
http;
|
|
540
541
|
readFile;
|
|
541
542
|
sleepFn;
|
|
542
543
|
kind = "open-cloud";
|
|
543
544
|
constructor(credentials, options) {
|
|
545
|
+
this.baseUrl = resolveOpenCloudBaseUrl();
|
|
544
546
|
this.credentials = credentials;
|
|
545
547
|
this.http = options?.http ?? createFetchClient({ "x-api-key": credentials.apiKey });
|
|
546
548
|
this.readFile = options?.readFile ?? ((filePath) => fs$1.readFileSync(filePath));
|
|
@@ -587,7 +589,7 @@ var OpenCloudBackend = class {
|
|
|
587
589
|
};
|
|
588
590
|
}
|
|
589
591
|
async createExecutionTask(inputs, timeoutMs) {
|
|
590
|
-
const url = `${
|
|
592
|
+
const url = `${this.baseUrl}/cloud/v2/universes/${this.credentials.universeId}/places/${this.credentials.placeId}/luau-execution-session-tasks`;
|
|
591
593
|
const script = generateTestScript(inputs);
|
|
592
594
|
const response = await this.http.request("POST", url, { body: {
|
|
593
595
|
script,
|
|
@@ -597,7 +599,7 @@ var OpenCloudBackend = class {
|
|
|
597
599
|
return taskResponse.assert(response.body).path;
|
|
598
600
|
}
|
|
599
601
|
async pollForCompletion(taskPath, timeoutMs, pollIntervalMs) {
|
|
600
|
-
const url = `${
|
|
602
|
+
const url = `${this.baseUrl}/cloud/v2/${taskPath}`;
|
|
601
603
|
const startTime = Date.now();
|
|
602
604
|
let rateLimitRetries = 0;
|
|
603
605
|
while (Date.now() - startTime < timeoutMs) {
|
|
@@ -657,7 +659,7 @@ var OpenCloudBackend = class {
|
|
|
657
659
|
return false;
|
|
658
660
|
}
|
|
659
661
|
async uploadPlaceData(placeData) {
|
|
660
|
-
const url = `${
|
|
662
|
+
const url = `${this.baseUrl}/universes/v1/${this.credentials.universeId}/places/${this.credentials.placeId}/versions?versionType=Saved`;
|
|
661
663
|
const response = await this.http.request("POST", url, {
|
|
662
664
|
body: placeData,
|
|
663
665
|
headers: { "Content-Type": "application/octet-stream" }
|
|
@@ -678,6 +680,11 @@ function createOpenCloudBackend() {
|
|
|
678
680
|
universeId
|
|
679
681
|
});
|
|
680
682
|
}
|
|
683
|
+
function resolveOpenCloudBaseUrl() {
|
|
684
|
+
const override = process.env["JEST_ROBLOX_OPEN_CLOUD_BASE_URL"];
|
|
685
|
+
if (override === void 0 || override.trim() === "") return DEFAULT_OPEN_CLOUD_BASE_URL;
|
|
686
|
+
return override.replace(/\/+$/, "");
|
|
687
|
+
}
|
|
681
688
|
function resolveBucketCount(parallel, jobCount) {
|
|
682
689
|
if (parallel === void 0) return 1;
|
|
683
690
|
if (parallel === "auto") return Math.min(jobCount, PARALLEL_AUTO_CAP);
|
|
@@ -995,6 +1002,35 @@ function resolveTree(node, currentDirectory, originalRoot, visited) {
|
|
|
995
1002
|
}
|
|
996
1003
|
return resolved;
|
|
997
1004
|
}
|
|
1005
|
+
function collectMounts(node, currentDataModelPath, classify) {
|
|
1006
|
+
const result = [];
|
|
1007
|
+
walk(node, currentDataModelPath, classify, result);
|
|
1008
|
+
return result;
|
|
1009
|
+
}
|
|
1010
|
+
function pruneAncestors(paths) {
|
|
1011
|
+
return paths.filter((candidate) => !paths.some((other) => other !== candidate && candidate.startsWith(`${other}/`)));
|
|
1012
|
+
}
|
|
1013
|
+
function addDirectoryMount(node, dataModelPath, classify, result) {
|
|
1014
|
+
const rawPath = node.$path;
|
|
1015
|
+
if (typeof rawPath !== "string") return;
|
|
1016
|
+
if (rawPath.endsWith(".project.json")) return;
|
|
1017
|
+
const fsPath = rawPath.replace(/\/$/, "");
|
|
1018
|
+
if (classify(fsPath) === "directory") result.push({
|
|
1019
|
+
dataModelPath,
|
|
1020
|
+
fsPath
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
1023
|
+
function isTreeChild(value) {
|
|
1024
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1025
|
+
}
|
|
1026
|
+
function walk(node, currentDataModelPath, classify, result) {
|
|
1027
|
+
for (const [key, value] of Object.entries(node)) {
|
|
1028
|
+
if (key.startsWith("$") || !isTreeChild(value)) continue;
|
|
1029
|
+
const childDataModelPath = currentDataModelPath === "" ? key : `${currentDataModelPath}/${key}`;
|
|
1030
|
+
addDirectoryMount(value, childDataModelPath, classify, result);
|
|
1031
|
+
walk(value, childDataModelPath, classify, result);
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
998
1034
|
function matchNodePath(childNode, targetPath, childDataModelPath) {
|
|
999
1035
|
const nodePath = childNode.$path;
|
|
1000
1036
|
if (typeof nodePath !== "string") return;
|
|
@@ -3604,4 +3640,4 @@ function writeGameOutput(filePath, entries) {
|
|
|
3604
3640
|
fs$1.writeFileSync(absolutePath, JSON.stringify(entries, null, 2));
|
|
3605
3641
|
}
|
|
3606
3642
|
//#endregion
|
|
3607
|
-
export {
|
|
3643
|
+
export { collectMounts as A, createOpenCloudBackend as B, formatFailure as C, formatTypecheckSummary as D, formatTestSummary as E, loadConfig$1 as F, VALID_BACKENDS as G, generateTestScript as H, resolveConfig as I, isValidBackend as J, defineConfig as K, StudioBackend as L, findInTree as M, pruneAncestors as N, formatBanner as O, resolveNestedProjects as P, parseJestOutput as Q, createStudioBackend as R, formatAgentMultiProject as S, formatResult as T, DEFAULT_CONFIG as U, buildJestArgv as V, ROOT_ONLY_KEYS as W, LuauScriptError as X, hashBuffer as Y, extractJsonFromOutput as Z, resolveTsconfigDirectories as _, formatAnnotations as a, formatJson as b, visitBlock as c, buildProjectJob as d, execute as f, processProjectResult as g, loadCoverageManifest as h, runTypecheck as i, collectPaths as j, combineSourceMappers as k, visitExpression as l, formatExecuteOutput as m, parseGameOutput as n, formatJobSummary as o, executeBackend as p, defineProject as q, writeGameOutput as r, resolveGitHubActionsOptions as s, formatGameOutputNotice as t, visitStatement as u, rojoProjectSchema as v, formatMultiProjectResult as w, writeJsonFile as x, findFormatterOptions as y, OpenCloudBackend as z };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as defineConfig, C as FormatterEntry, D as ROOT_ONLY_KEYS, E as ProjectTestConfig, M as Argv, O as ResolvedConfig, S as DisplayName, T as ProjectEntry, _ as ResolvedProjectConfig, a as formatExecuteOutput, b as ConfigInput, c as Backend, d as extractJsonFromOutput, f as parseJestOutput, g as TestStatus, h as TestFileResult, i as execute, j as defineProject, k as SnapshotFormatOptions, l as BackendOptions, m as TestCaseResult, n as ExecuteResult, o as TimingResult, p as JestResult, r as FormatOutputOptions, s as SourceMapper, t as ExecuteOptions, u as BackendResult, v as CliOptions, w as InlineProjectConfig, x as DEFAULT_CONFIG, y as Config } from "./executor-
|
|
1
|
+
import { A as defineConfig, C as FormatterEntry, D as ROOT_ONLY_KEYS, E as ProjectTestConfig, M as Argv, O as ResolvedConfig, S as DisplayName, T as ProjectEntry, _ as ResolvedProjectConfig, a as formatExecuteOutput, b as ConfigInput, c as Backend, d as extractJsonFromOutput, f as parseJestOutput, g as TestStatus, h as TestFileResult, i as execute, j as defineProject, k as SnapshotFormatOptions, l as BackendOptions, m as TestCaseResult, n as ExecuteResult, o as TimingResult, p as JestResult, r as FormatOutputOptions, s as SourceMapper, t as ExecuteOptions, u as BackendResult, v as CliOptions, w as InlineProjectConfig, x as DEFAULT_CONFIG, y as Config } from "./executor-COuwZJJX.mjs";
|
|
2
2
|
import { WebSocket, WebSocketServer } from "ws";
|
|
3
3
|
import buffer from "node:buffer";
|
|
4
4
|
|
|
@@ -31,6 +31,7 @@ interface OpenCloudOptions {
|
|
|
31
31
|
}
|
|
32
32
|
type FileReader = (path: string) => buffer.Buffer;
|
|
33
33
|
declare class OpenCloudBackend implements Backend {
|
|
34
|
+
private readonly baseUrl;
|
|
34
35
|
private readonly credentials;
|
|
35
36
|
private readonly http;
|
|
36
37
|
private readonly readFile;
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { B as
|
|
1
|
+
import { B as createOpenCloudBackend, C as formatFailure, E as formatTestSummary, F as loadConfig, H as generateTestScript, I as resolveConfig, K as defineConfig, L as StudioBackend, Q as parseJestOutput, R as createStudioBackend, T as formatResult, U as DEFAULT_CONFIG, V as buildJestArgv, W as ROOT_ONLY_KEYS, Z as extractJsonFromOutput, a as formatAnnotations, b as formatJson, c as visitBlock, f as execute, i as runTypecheck, l as visitExpression, m as formatExecuteOutput, n as parseGameOutput, o as formatJobSummary, q as defineProject, r as writeGameOutput, t as formatGameOutputNotice, u as visitStatement, x as writeJsonFile, z as OpenCloudBackend } from "./game-output-CCPIQMWm.mjs";
|
|
2
2
|
export { DEFAULT_CONFIG, OpenCloudBackend, ROOT_ONLY_KEYS, StudioBackend, buildJestArgv, createOpenCloudBackend, createStudioBackend, defineConfig, defineProject, execute, extractJsonFromOutput, formatAnnotations, formatExecuteOutput, formatFailure, formatGameOutputNotice, formatJobSummary, formatJson, formatResult, formatTestSummary, generateTestScript, loadConfig, parseGameOutput, parseJestOutput, resolveConfig, runTypecheck, visitBlock, visitExpression, visitStatement, writeGameOutput, writeJsonFile };
|
package/dist/sea/jest-roblox
CHANGED
|
Binary file
|