@isentinel/jest-roblox 0.0.3 → 0.0.4
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/dist/cli.d.mts +2 -2
- package/dist/cli.mjs +107 -75
- package/dist/{game-output--EpqHGEr.mjs → game-output-DO5fOpW3.mjs} +800 -316
- package/dist/index.d.mts +74 -30
- package/dist/index.mjs +2 -2
- package/dist/{schema-hhbEFVXy.d.mts → schema-ua9HqdbX.d.mts} +23 -3
- package/package.json +36 -6
- package/plugin/JestRobloxRunner.rbxm +0 -0
- package/plugin/out/shared/entry.luau +8 -0
- package/plugin/out/shared/instance-resolver.luau +93 -0
- package/plugin/out/shared/mock/CoreScriptSyncService.luau +19 -0
- package/plugin/out/shared/mock/FileSystemService.luau +30 -0
- package/plugin/out/shared/runner.luau +172 -0
- package/plugin/out/shared/snapshot-patch.luau +99 -0
- package/plugin/plugin.project.json +4 -1
- package/plugin/src/test-in-run-mode.server.luau +2 -15
- package/plugin/sourcemap.json +0 -1
- package/plugin/src/patch/CoreScriptSyncService.luau +0 -19
- package/plugin/src/patch/FileSystemService.luau +0 -27
- package/plugin/src/patch/getDataModelService.luau +0 -19
- package/plugin/src/test-runner.luau +0 -226
package/dist/index.d.mts
CHANGED
|
@@ -1,17 +1,9 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import { WebSocketServer } from "ws";
|
|
1
|
+
import { a as SnapshotFormatOptions, i as ResolvedConfig, n as Config, o as Argv, r as DEFAULT_CONFIG, t as CliOptions } from "./schema-ua9HqdbX.mjs";
|
|
2
|
+
import { WebSocket, WebSocketServer } from "ws";
|
|
3
3
|
import buffer from "node:buffer";
|
|
4
4
|
|
|
5
5
|
//#region src/types/jest-result.d.ts
|
|
6
|
-
|
|
7
|
-
numFailedTests: number;
|
|
8
|
-
numPassedTests: number;
|
|
9
|
-
numPendingTests: number;
|
|
10
|
-
numTotalTests: number;
|
|
11
|
-
startTime: number;
|
|
12
|
-
success: boolean;
|
|
13
|
-
testResults: Array<TestFileResult>;
|
|
14
|
-
}
|
|
6
|
+
type TestStatus = "failed" | "passed" | "pending" | "skipped";
|
|
15
7
|
interface TestCaseResult {
|
|
16
8
|
ancestorTitles: Array<string>;
|
|
17
9
|
duration?: number;
|
|
@@ -21,32 +13,51 @@ interface TestCaseResult {
|
|
|
21
13
|
title: string;
|
|
22
14
|
}
|
|
23
15
|
interface TestFileResult {
|
|
16
|
+
failureMessage?: string;
|
|
24
17
|
numFailingTests: number;
|
|
25
18
|
numPassingTests: number;
|
|
26
19
|
numPendingTests: number;
|
|
27
20
|
testFilePath: string;
|
|
28
21
|
testResults: Array<TestCaseResult>;
|
|
29
22
|
}
|
|
30
|
-
|
|
23
|
+
interface SnapshotSummary {
|
|
24
|
+
added: number;
|
|
25
|
+
matched: number;
|
|
26
|
+
total: number;
|
|
27
|
+
unmatched: number;
|
|
28
|
+
updated: number;
|
|
29
|
+
}
|
|
30
|
+
interface JestResult {
|
|
31
|
+
numFailedTests: number;
|
|
32
|
+
numPassedTests: number;
|
|
33
|
+
numPendingTests: number;
|
|
34
|
+
numTotalTests: number;
|
|
35
|
+
snapshot?: SnapshotSummary;
|
|
36
|
+
startTime: number;
|
|
37
|
+
success: boolean;
|
|
38
|
+
testResults: Array<TestFileResult>;
|
|
39
|
+
}
|
|
31
40
|
//#endregion
|
|
32
41
|
//#region src/reporter/parser.d.ts
|
|
42
|
+
type SnapshotWrites = Record<string, string>;
|
|
33
43
|
interface ParseResult {
|
|
34
44
|
luauTiming?: Record<string, number>;
|
|
35
45
|
result: JestResult;
|
|
36
46
|
snapshotWrites?: SnapshotWrites;
|
|
37
47
|
}
|
|
38
|
-
type SnapshotWrites = Record<string, string>;
|
|
39
48
|
declare function extractJsonFromOutput(output: string): string | undefined;
|
|
40
49
|
declare function parseJestOutput(output: string): ParseResult;
|
|
41
50
|
//#endregion
|
|
42
51
|
//#region src/backends/interface.d.ts
|
|
43
|
-
interface Backend {
|
|
44
|
-
runTests(options: BackendOptions): Promise<BackendResult>;
|
|
45
|
-
}
|
|
46
52
|
interface BackendOptions {
|
|
47
53
|
config: ResolvedConfig;
|
|
48
54
|
testFiles: Array<string>;
|
|
49
55
|
}
|
|
56
|
+
interface BackendTiming {
|
|
57
|
+
executionMs: number;
|
|
58
|
+
uploadCached?: boolean;
|
|
59
|
+
uploadMs?: number;
|
|
60
|
+
}
|
|
50
61
|
interface BackendResult {
|
|
51
62
|
gameOutput?: string;
|
|
52
63
|
luauTiming?: Record<string, number>;
|
|
@@ -54,16 +65,11 @@ interface BackendResult {
|
|
|
54
65
|
snapshotWrites?: SnapshotWrites;
|
|
55
66
|
timing: BackendTiming;
|
|
56
67
|
}
|
|
57
|
-
interface
|
|
58
|
-
|
|
59
|
-
uploadCached?: boolean;
|
|
60
|
-
uploadMs?: number;
|
|
68
|
+
interface Backend {
|
|
69
|
+
runTests(options: BackendOptions): Promise<BackendResult>;
|
|
61
70
|
}
|
|
62
71
|
//#endregion
|
|
63
72
|
//#region src/backends/http-client.d.ts
|
|
64
|
-
interface HttpClient {
|
|
65
|
-
request(method: string, url: string, options?: RequestOptions): Promise<HttpResponse>;
|
|
66
|
-
}
|
|
67
73
|
interface HttpResponse {
|
|
68
74
|
body: unknown;
|
|
69
75
|
headers?: Record<string, string | undefined>;
|
|
@@ -74,6 +80,9 @@ interface RequestOptions {
|
|
|
74
80
|
body?: unknown;
|
|
75
81
|
headers?: Record<string, string>;
|
|
76
82
|
}
|
|
83
|
+
interface HttpClient {
|
|
84
|
+
request(method: string, url: string, options?: RequestOptions): Promise<HttpResponse>;
|
|
85
|
+
}
|
|
77
86
|
//#endregion
|
|
78
87
|
//#region src/backends/open-cloud.d.ts
|
|
79
88
|
interface OpenCloudCredentials {
|
|
@@ -101,15 +110,21 @@ declare class OpenCloudBackend implements Backend {
|
|
|
101
110
|
declare function createOpenCloudBackend(): OpenCloudBackend;
|
|
102
111
|
//#endregion
|
|
103
112
|
//#region src/backends/studio.d.ts
|
|
113
|
+
interface PreConnected {
|
|
114
|
+
server: WebSocketServer;
|
|
115
|
+
socket: WebSocket;
|
|
116
|
+
}
|
|
104
117
|
interface StudioOptions {
|
|
105
118
|
createServer?: (port: number) => WebSocketServer;
|
|
106
119
|
port: number;
|
|
120
|
+
preConnected?: PreConnected;
|
|
107
121
|
timeout?: number;
|
|
108
122
|
}
|
|
109
123
|
declare class StudioBackend implements Backend {
|
|
110
124
|
private readonly createServer;
|
|
111
125
|
private readonly port;
|
|
112
126
|
private readonly timeout;
|
|
127
|
+
private preConnected?;
|
|
113
128
|
constructor(options: StudioOptions);
|
|
114
129
|
runTests(options: BackendOptions): Promise<BackendResult>;
|
|
115
130
|
private executeViaPlugin;
|
|
@@ -118,8 +133,8 @@ declare class StudioBackend implements Backend {
|
|
|
118
133
|
declare function createStudioBackend(options: StudioOptions): StudioBackend;
|
|
119
134
|
//#endregion
|
|
120
135
|
//#region src/config/loader.d.ts
|
|
121
|
-
declare function loadConfig(configPath?: string, cwd?: string): Promise<ResolvedConfig>;
|
|
122
136
|
declare function resolveConfig(config: Config): ResolvedConfig;
|
|
137
|
+
declare function loadConfig(configPath?: string, cwd?: string): Promise<ResolvedConfig>;
|
|
123
138
|
//#endregion
|
|
124
139
|
//#region src/executor.d.ts
|
|
125
140
|
interface ExecuteOptions {
|
|
@@ -137,20 +152,22 @@ interface ExecuteResult {
|
|
|
137
152
|
declare function execute(options: ExecuteOptions): Promise<ExecuteResult>;
|
|
138
153
|
//#endregion
|
|
139
154
|
//#region src/source-mapper/index.d.ts
|
|
140
|
-
interface MappedFailure {
|
|
141
|
-
locations: Array<MappedLocation>;
|
|
142
|
-
message: string;
|
|
143
|
-
}
|
|
144
155
|
interface MappedLocation {
|
|
145
156
|
luauLine: number;
|
|
146
157
|
luauPath: string;
|
|
158
|
+
sourceContent?: string;
|
|
147
159
|
tsColumn?: number;
|
|
148
160
|
tsLine: number;
|
|
149
161
|
tsPath: string;
|
|
150
162
|
}
|
|
163
|
+
interface MappedFailure {
|
|
164
|
+
locations: Array<MappedLocation>;
|
|
165
|
+
message: string;
|
|
166
|
+
}
|
|
151
167
|
interface SourceMapper {
|
|
152
168
|
mapFailureMessage(message: string): string;
|
|
153
169
|
mapFailureWithLocations(message: string): MappedFailure;
|
|
170
|
+
resolveTestFilePath(testFilePath: string): string | undefined;
|
|
154
171
|
}
|
|
155
172
|
//#endregion
|
|
156
173
|
//#region src/types/timing.d.ts
|
|
@@ -166,6 +183,8 @@ interface TimingResult {
|
|
|
166
183
|
//#region src/formatters/formatter.d.ts
|
|
167
184
|
interface FormatOptions {
|
|
168
185
|
color: boolean;
|
|
186
|
+
gameOutput?: string;
|
|
187
|
+
outputFile?: string;
|
|
169
188
|
rootDir: string;
|
|
170
189
|
showLuau?: boolean;
|
|
171
190
|
sourceMapper?: SourceMapper;
|
|
@@ -217,8 +236,8 @@ declare function formatFailure({
|
|
|
217
236
|
totalFailures?: number;
|
|
218
237
|
useColor?: boolean;
|
|
219
238
|
}): string;
|
|
220
|
-
declare function formatResult(result: JestResult, timing: TimingResult, options: FormatOptions): string;
|
|
221
239
|
declare function formatTestSummary(result: JestResult, timing: TimingResult, styles?: Styles): string;
|
|
240
|
+
declare function formatResult(result: JestResult, timing: TimingResult, options: FormatOptions): string;
|
|
222
241
|
//#endregion
|
|
223
242
|
//#region src/formatters/json.d.ts
|
|
224
243
|
declare function formatJson(result: JestResult): string;
|
|
@@ -226,11 +245,36 @@ declare function writeJsonFile(result: JestResult, filePath: string): Promise<vo
|
|
|
226
245
|
//#endregion
|
|
227
246
|
//#region src/test-script.d.ts
|
|
228
247
|
type JestArgv = Argv & {
|
|
248
|
+
snapshotFormat?: SnapshotFormatOptions;
|
|
229
249
|
testMatch: Array<string>;
|
|
230
250
|
};
|
|
231
251
|
declare function buildJestArgv(options: BackendOptions): JestArgv;
|
|
232
252
|
declare function generateTestScript(options: BackendOptions): string;
|
|
233
253
|
//#endregion
|
|
254
|
+
//#region src/typecheck/types.d.ts
|
|
255
|
+
interface TscErrorInfo {
|
|
256
|
+
column: number;
|
|
257
|
+
errCode: number;
|
|
258
|
+
errMsg: string;
|
|
259
|
+
filePath: string;
|
|
260
|
+
line: number;
|
|
261
|
+
}
|
|
262
|
+
interface TestDefinition {
|
|
263
|
+
name: string;
|
|
264
|
+
ancestorNames: Array<string>;
|
|
265
|
+
end: number;
|
|
266
|
+
start: number;
|
|
267
|
+
type: "suite" | "test";
|
|
268
|
+
}
|
|
269
|
+
//#endregion
|
|
270
|
+
//#region src/typecheck/runner.d.ts
|
|
271
|
+
interface TypecheckOptions {
|
|
272
|
+
files: Array<string>;
|
|
273
|
+
rootDir: string;
|
|
274
|
+
tsconfig?: string;
|
|
275
|
+
}
|
|
276
|
+
declare function runTypecheck(options: TypecheckOptions): JestResult;
|
|
277
|
+
//#endregion
|
|
234
278
|
//#region src/types/game-output.d.ts
|
|
235
279
|
interface GameOutputEntry {
|
|
236
280
|
message: string;
|
|
@@ -243,4 +287,4 @@ declare function formatGameOutputNotice(filePath: string, entryCount: number): s
|
|
|
243
287
|
declare function parseGameOutput(raw: string | undefined): Array<GameOutputEntry>;
|
|
244
288
|
declare function writeGameOutput(filePath: string, entries: Array<GameOutputEntry>): void;
|
|
245
289
|
//#endregion
|
|
246
|
-
export { type Backend, type BackendOptions, type CliOptions, type Config, DEFAULT_CONFIG, type ExecuteOptions, type ExecuteResult, type GameOutputEntry, type JestArgv, type JestResult, OpenCloudBackend, type ResolvedConfig, StudioBackend, type TestCaseResult, type TestFileResult, type TestStatus, buildJestArgv, createOpenCloudBackend, createStudioBackend, execute, extractJsonFromOutput, formatFailure, formatGameOutputNotice, formatJson, formatResult, formatTestSummary, generateTestScript, loadConfig, parseGameOutput, parseJestOutput, resolveConfig, writeGameOutput, writeJsonFile };
|
|
290
|
+
export { type Backend, type BackendOptions, type CliOptions, type Config, DEFAULT_CONFIG, type ExecuteOptions, type ExecuteResult, type GameOutputEntry, type JestArgv, type JestResult, OpenCloudBackend, type ResolvedConfig, StudioBackend, type TestCaseResult, type TestDefinition, type TestFileResult, type TestStatus, type TscErrorInfo, type TypecheckOptions, buildJestArgv, createOpenCloudBackend, createStudioBackend, execute, extractJsonFromOutput, formatFailure, formatGameOutputNotice, formatJson, formatResult, formatTestSummary, generateTestScript, loadConfig, parseGameOutput, parseJestOutput, resolveConfig, runTypecheck, writeGameOutput, writeJsonFile };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { _ as
|
|
1
|
+
import { C as extractJsonFromOutput, _ as createStudioBackend, a as execute, b as buildJestArgv, c as formatFailure, d as loadConfig, f as resolveConfig, g as StudioBackend, i as runTypecheck, l as formatResult, n as parseGameOutput, o as formatJson, p as DEFAULT_CONFIG, r as writeGameOutput, s as writeJsonFile, t as formatGameOutputNotice, u as formatTestSummary, v as OpenCloudBackend, w as parseJestOutput, x as generateTestScript, y as createOpenCloudBackend } from "./game-output-DO5fOpW3.mjs";
|
|
2
2
|
|
|
3
|
-
export { DEFAULT_CONFIG, OpenCloudBackend, StudioBackend, buildJestArgv, createOpenCloudBackend, createStudioBackend, execute, extractJsonFromOutput, formatFailure, formatGameOutputNotice, formatJson, formatResult, formatTestSummary, generateTestScript, loadConfig, parseGameOutput, parseJestOutput, resolveConfig, writeGameOutput, writeJsonFile };
|
|
3
|
+
export { DEFAULT_CONFIG, OpenCloudBackend, StudioBackend, buildJestArgv, createOpenCloudBackend, createStudioBackend, execute, extractJsonFromOutput, formatFailure, formatGameOutputNotice, formatJson, formatResult, formatTestSummary, generateTestScript, loadConfig, parseGameOutput, parseJestOutput, resolveConfig, runTypecheck, writeGameOutput, writeJsonFile };
|
|
@@ -757,6 +757,17 @@ type Except<ObjectType, KeysType extends keyof ObjectType, Options extends Excep
|
|
|
757
757
|
type _Except<ObjectType, KeysType extends keyof ObjectType, Options extends Required<ExceptOptions>> = { [KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType] } & (Options['requireExactProps'] extends true ? Partial<Record<KeysType, never>> : {});
|
|
758
758
|
//#endregion
|
|
759
759
|
//#region src/config/schema.d.ts
|
|
760
|
+
type Backend = "auto" | "open-cloud" | "studio";
|
|
761
|
+
interface SnapshotFormatOptions {
|
|
762
|
+
callToJSON?: boolean;
|
|
763
|
+
escapeRegex?: boolean;
|
|
764
|
+
escapeString?: boolean;
|
|
765
|
+
indent?: number;
|
|
766
|
+
maxDepth?: number;
|
|
767
|
+
min?: boolean;
|
|
768
|
+
printBasicPrototype?: boolean;
|
|
769
|
+
printFunctionName?: boolean;
|
|
770
|
+
}
|
|
760
771
|
interface Config extends Except<Argv, "rootDir" | "setupFiles" | "setupFilesAfterEnv" | "testPathPattern"> {
|
|
761
772
|
backend?: Backend;
|
|
762
773
|
cache?: boolean;
|
|
@@ -772,13 +783,17 @@ interface Config extends Except<Argv, "rootDir" | "setupFiles" | "setupFilesAfte
|
|
|
772
783
|
setupFiles?: Array<string>;
|
|
773
784
|
setupFilesAfterEnv?: Array<string>;
|
|
774
785
|
showLuau?: boolean;
|
|
786
|
+
snapshotFormat?: SnapshotFormatOptions;
|
|
775
787
|
sourceMap?: boolean;
|
|
776
788
|
testPathPattern?: string;
|
|
777
789
|
timeout?: number;
|
|
790
|
+
typecheck?: boolean;
|
|
791
|
+
typecheckOnly?: boolean;
|
|
792
|
+
typecheckTsconfig?: string;
|
|
778
793
|
updateSnapshot?: boolean;
|
|
779
794
|
}
|
|
780
795
|
interface ResolvedConfig extends Config {
|
|
781
|
-
backend:
|
|
796
|
+
backend: Backend;
|
|
782
797
|
cache: boolean;
|
|
783
798
|
color: boolean;
|
|
784
799
|
compact: boolean;
|
|
@@ -795,9 +810,11 @@ interface ResolvedConfig extends Config {
|
|
|
795
810
|
testMatch: Array<string>;
|
|
796
811
|
testPathIgnorePatterns: Array<string>;
|
|
797
812
|
timeout: number;
|
|
813
|
+
typecheck: boolean;
|
|
814
|
+
typecheckOnly: boolean;
|
|
815
|
+
typecheckTsconfig?: string;
|
|
798
816
|
verbose: boolean;
|
|
799
817
|
}
|
|
800
|
-
type Backend = "auto" | "open-cloud" | "studio";
|
|
801
818
|
declare const DEFAULT_CONFIG: ResolvedConfig;
|
|
802
819
|
interface CliOptions {
|
|
803
820
|
backend?: Backend;
|
|
@@ -823,9 +840,12 @@ interface CliOptions {
|
|
|
823
840
|
testNamePattern?: string;
|
|
824
841
|
testPathPattern?: string;
|
|
825
842
|
timeout?: number;
|
|
843
|
+
typecheck?: boolean;
|
|
844
|
+
typecheckOnly?: boolean;
|
|
845
|
+
typecheckTsconfig?: string;
|
|
826
846
|
updateSnapshot?: boolean;
|
|
827
847
|
verbose?: boolean;
|
|
828
848
|
version?: boolean;
|
|
829
849
|
}
|
|
830
850
|
//#endregion
|
|
831
|
-
export {
|
|
851
|
+
export { SnapshotFormatOptions as a, ResolvedConfig as i, Config as n, Argv as o, DEFAULT_CONFIG as r, CliOptions as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@isentinel/jest-roblox",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Jest-compatible CLI for running roblox-ts tests via Roblox Open Cloud",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jest",
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
"testing",
|
|
10
10
|
"cli"
|
|
11
11
|
],
|
|
12
|
+
"bugs": {
|
|
13
|
+
"email": "christopher.buss@pm.me"
|
|
14
|
+
},
|
|
12
15
|
"license": "MIT",
|
|
13
16
|
"author": "Christopher Buss <christopher.buss@pm.me> (https://github.com/christopher-buss)",
|
|
14
17
|
"sideEffects": false,
|
|
@@ -30,18 +33,25 @@
|
|
|
30
33
|
"!dist/**/*.tsbuildinfo"
|
|
31
34
|
],
|
|
32
35
|
"dependencies": {
|
|
36
|
+
"@jridgewell/trace-mapping": "^0.3.25",
|
|
33
37
|
"arktype": "2.1.29",
|
|
38
|
+
"get-tsconfig": "4.13.6",
|
|
34
39
|
"highlight.js": "11.11.1",
|
|
35
40
|
"jiti": "2.6.1",
|
|
41
|
+
"oxc-parser": "0.116.0",
|
|
36
42
|
"tinyrainbow": "3.0.3",
|
|
37
43
|
"ws": "8.18.0"
|
|
38
44
|
},
|
|
39
45
|
"devDependencies": {
|
|
40
|
-
"@isentinel/eslint-config": "
|
|
46
|
+
"@isentinel/eslint-config": "5.0.0-beta.8",
|
|
47
|
+
"@oxc-project/types": "0.116.0",
|
|
41
48
|
"@rbxts/jest": "3.13.3-ts.1",
|
|
42
|
-
"@rbxts/types": "1.0.
|
|
43
|
-
"@
|
|
49
|
+
"@rbxts/types": "1.0.911",
|
|
50
|
+
"@total-typescript/shoehorn": "^0.1.2",
|
|
51
|
+
"@types/node": "24.10.13",
|
|
44
52
|
"@types/ws": "8.5.13",
|
|
53
|
+
"@typescript/native-preview": "7.0.0-dev.20260308.1",
|
|
54
|
+
"@vitest/eslint-plugin": "1.6.9",
|
|
45
55
|
"better-typescript-lib": "2.12.0",
|
|
46
56
|
"bumpp": "10.4.1",
|
|
47
57
|
"publint": "0.3.15",
|
|
@@ -53,18 +63,37 @@
|
|
|
53
63
|
"node": ">=20.0.0"
|
|
54
64
|
},
|
|
55
65
|
"nx": {
|
|
66
|
+
"name": "jest-roblox-cli",
|
|
56
67
|
"tags": [
|
|
57
68
|
"scope:tooling",
|
|
58
69
|
"type:cli"
|
|
59
70
|
],
|
|
60
71
|
"projectType": "application",
|
|
72
|
+
"includedScripts": [
|
|
73
|
+
"!build"
|
|
74
|
+
],
|
|
61
75
|
"targets": {
|
|
76
|
+
"build": {
|
|
77
|
+
"command": "pnpm build:bundle && tsdown && pnpm build:plugin",
|
|
78
|
+
"options": {
|
|
79
|
+
"cwd": "tools/jest-roblox-cli"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
62
82
|
"lint": {
|
|
63
83
|
"command": "eslint",
|
|
64
84
|
"hasTypeAwareRules": true
|
|
65
85
|
},
|
|
86
|
+
"build:bundle": {
|
|
87
|
+
"command": "pnpm build:bundle",
|
|
88
|
+
"options": {
|
|
89
|
+
"cwd": "tools/jest-roblox-cli"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
66
92
|
"test": {
|
|
67
93
|
"command": "vitest run",
|
|
94
|
+
"dependsOn": [
|
|
95
|
+
"build:bundle"
|
|
96
|
+
],
|
|
68
97
|
"options": {
|
|
69
98
|
"cwd": "tools/jest-roblox-cli"
|
|
70
99
|
}
|
|
@@ -72,8 +101,9 @@
|
|
|
72
101
|
}
|
|
73
102
|
},
|
|
74
103
|
"scripts": {
|
|
75
|
-
"build": "tsdown",
|
|
76
|
-
"build:
|
|
104
|
+
"build": "pnpm build:bundle && tsdown && pnpm build:plugin",
|
|
105
|
+
"build:bundle": "darklua process -c .darklua-bundle.json luau/entry.luau src/test-runner.bundled.luau",
|
|
106
|
+
"build:plugin": "rm -rf plugin/out && darklua process -c .darklua-plugin.json luau/ plugin/out/shared/ && rojo build plugin/plugin.project.json -o plugin/JestRobloxRunner.rbxm",
|
|
77
107
|
"release": "bumpp",
|
|
78
108
|
"watch": "tsdown --watch"
|
|
79
109
|
}
|
|
Binary file
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
|
3
|
+
|
|
4
|
+
local module = {}
|
|
5
|
+
|
|
6
|
+
function module.findInstance(path: string): Instance
|
|
7
|
+
local parts = string.split(path, "/")
|
|
8
|
+
|
|
9
|
+
local success, current = pcall(function()
|
|
10
|
+
return game:FindService(parts[1])
|
|
11
|
+
end)
|
|
12
|
+
assert(success, `Failed to find service {parts[1]}: {current}`)
|
|
13
|
+
|
|
14
|
+
for i = 2, #parts do
|
|
15
|
+
assert(current, `Failed to find '{parts[i - 1]}' in path {path}`)
|
|
16
|
+
current = current:FindFirstChild(parts[i])
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
assert(current, `Failed to find instance at path {path}`)
|
|
20
|
+
|
|
21
|
+
return current
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
function module.getJest(config: { jestPath: string? }): ModuleScript
|
|
25
|
+
local jestPath = config.jestPath
|
|
26
|
+
if jestPath then
|
|
27
|
+
local instance = module.findInstance(jestPath)
|
|
28
|
+
assert(instance, `Failed to find Jest instance at path {jestPath}`)
|
|
29
|
+
assert(instance:IsA("ModuleScript"), `Instance at path {jestPath} is not a ModuleScript`)
|
|
30
|
+
return instance :: ModuleScript
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
local jestInstance = ReplicatedStorage:FindFirstChild("Jest", true)
|
|
34
|
+
assert(jestInstance, "Failed to find Jest instance in ReplicatedStorage")
|
|
35
|
+
assert(
|
|
36
|
+
jestInstance:IsA("ModuleScript"),
|
|
37
|
+
"Jest instance in ReplicatedStorage is not a ModuleScript"
|
|
38
|
+
)
|
|
39
|
+
return jestInstance
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
function module.findRobloxShared(jestModule: ModuleScript): Instance?
|
|
43
|
+
local parent = jestModule.Parent
|
|
44
|
+
if parent then
|
|
45
|
+
local found = parent:FindFirstChild("RobloxShared")
|
|
46
|
+
or parent:FindFirstChild("jest-roblox-shared")
|
|
47
|
+
if found then
|
|
48
|
+
return found
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
if parent.Parent then
|
|
52
|
+
found = parent.Parent:FindFirstChild("RobloxShared")
|
|
53
|
+
or parent.Parent:FindFirstChild("jest-roblox-shared")
|
|
54
|
+
if found then
|
|
55
|
+
return found
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
return game:FindFirstChild("RobloxShared", true)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
function module.findSiblingPackage(jestModule: ModuleScript, ...: string): Instance?
|
|
64
|
+
local parent = jestModule.Parent
|
|
65
|
+
if parent then
|
|
66
|
+
for _, name in { ... } do
|
|
67
|
+
local found = parent:FindFirstChild(name)
|
|
68
|
+
if found then
|
|
69
|
+
return found
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
if parent.Parent then
|
|
74
|
+
for _, name in { ... } do
|
|
75
|
+
local found = parent.Parent:FindFirstChild(name)
|
|
76
|
+
if found then
|
|
77
|
+
return found
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
for _, name in { ... } do
|
|
84
|
+
local found = game:FindFirstChild(name, true)
|
|
85
|
+
if found then
|
|
86
|
+
return found
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
return nil
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
return module
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
local function getInstancePath(instance: Instance): string
|
|
3
|
+
local parts = {} :: { string }
|
|
4
|
+
local current: Instance? = instance
|
|
5
|
+
while current and current ~= game do
|
|
6
|
+
table.insert(parts, 1, current.Name)
|
|
7
|
+
current = current.Parent
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
return table.concat(parts, "/")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
local CoreScriptSyncService = {}
|
|
14
|
+
|
|
15
|
+
function CoreScriptSyncService:GetScriptFilePath(instance: Instance): string
|
|
16
|
+
return getInstancePath(instance)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
return CoreScriptSyncService
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
local function normalizeSnapPath(path: string): string
|
|
3
|
+
return (string.gsub(path, "%.snap%.lua$", ".snap.luau"))
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
local function create(snapshotWrites: { [string]: string })
|
|
7
|
+
local FileSystemService = {}
|
|
8
|
+
|
|
9
|
+
function FileSystemService:WriteFile(path: string, contents: string)
|
|
10
|
+
snapshotWrites[normalizeSnapPath(path)] = contents
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
function FileSystemService:CreateDirectories(_path: string) end
|
|
14
|
+
|
|
15
|
+
function FileSystemService:Exists(path: string): boolean
|
|
16
|
+
return snapshotWrites[normalizeSnapPath(path)] ~= nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
function FileSystemService:Remove(path: string)
|
|
20
|
+
snapshotWrites[normalizeSnapPath(path)] = nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
function FileSystemService:IsRegularFile(path: string): boolean
|
|
24
|
+
return snapshotWrites[normalizeSnapPath(path)] ~= nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
return FileSystemService
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
return create
|