@isentinel/jest-roblox 0.0.2 → 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 +114 -75
- package/dist/{game-output-BDatGA9S.mjs → game-output-DO5fOpW3.mjs} +801 -317
- package/dist/index.d.mts +74 -30
- package/dist/index.mjs +2 -2
- package/dist/{schema-CEsyg-FX.d.mts → schema-ua9HqdbX.d.mts} +26 -4
- 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 -217
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,7 +757,18 @@ 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
|
-
|
|
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
|
+
}
|
|
771
|
+
interface Config extends Except<Argv, "rootDir" | "setupFiles" | "setupFilesAfterEnv" | "testPathPattern"> {
|
|
761
772
|
backend?: Backend;
|
|
762
773
|
cache?: boolean;
|
|
763
774
|
compact?: boolean;
|
|
@@ -770,14 +781,19 @@ interface Config extends Except<Argv, "rootDir" | "setupFiles" | "testPathPatter
|
|
|
770
781
|
rojoProject?: string;
|
|
771
782
|
rootDir?: string;
|
|
772
783
|
setupFiles?: Array<string>;
|
|
784
|
+
setupFilesAfterEnv?: Array<string>;
|
|
773
785
|
showLuau?: boolean;
|
|
786
|
+
snapshotFormat?: SnapshotFormatOptions;
|
|
774
787
|
sourceMap?: boolean;
|
|
775
788
|
testPathPattern?: string;
|
|
776
789
|
timeout?: number;
|
|
790
|
+
typecheck?: boolean;
|
|
791
|
+
typecheckOnly?: boolean;
|
|
792
|
+
typecheckTsconfig?: string;
|
|
777
793
|
updateSnapshot?: boolean;
|
|
778
794
|
}
|
|
779
795
|
interface ResolvedConfig extends Config {
|
|
780
|
-
backend:
|
|
796
|
+
backend: Backend;
|
|
781
797
|
cache: boolean;
|
|
782
798
|
color: boolean;
|
|
783
799
|
compact: boolean;
|
|
@@ -794,9 +810,11 @@ interface ResolvedConfig extends Config {
|
|
|
794
810
|
testMatch: Array<string>;
|
|
795
811
|
testPathIgnorePatterns: Array<string>;
|
|
796
812
|
timeout: number;
|
|
813
|
+
typecheck: boolean;
|
|
814
|
+
typecheckOnly: boolean;
|
|
815
|
+
typecheckTsconfig?: string;
|
|
797
816
|
verbose: boolean;
|
|
798
817
|
}
|
|
799
|
-
type Backend = "auto" | "open-cloud" | "studio";
|
|
800
818
|
declare const DEFAULT_CONFIG: ResolvedConfig;
|
|
801
819
|
interface CliOptions {
|
|
802
820
|
backend?: Backend;
|
|
@@ -815,15 +833,19 @@ interface CliOptions {
|
|
|
815
833
|
projects?: Array<string>;
|
|
816
834
|
rojoProject?: string;
|
|
817
835
|
setupFiles?: Array<string>;
|
|
836
|
+
setupFilesAfterEnv?: Array<string>;
|
|
818
837
|
showLuau?: boolean;
|
|
819
838
|
silent?: boolean;
|
|
820
839
|
sourceMap?: boolean;
|
|
821
840
|
testNamePattern?: string;
|
|
822
841
|
testPathPattern?: string;
|
|
823
842
|
timeout?: number;
|
|
843
|
+
typecheck?: boolean;
|
|
844
|
+
typecheckOnly?: boolean;
|
|
845
|
+
typecheckTsconfig?: string;
|
|
824
846
|
updateSnapshot?: boolean;
|
|
825
847
|
verbose?: boolean;
|
|
826
848
|
version?: boolean;
|
|
827
849
|
}
|
|
828
850
|
//#endregion
|
|
829
|
-
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
|