@isentinel/jest-roblox 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -2
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs +284 -387
- package/dist/{executor-CNz6_04-.d.mts → executor-B2IDh6bH.d.mts} +176 -89
- package/dist/{game-output-C0KykXIi.mjs → game-output-CwmtpYhn.mjs} +531 -172
- package/dist/index.d.mts +301 -19
- package/dist/index.mjs +2 -2
- package/dist/sea/jest-roblox +0 -0
- package/dist/sea-entry.cjs +5123 -20005
- package/package.json +17 -13
- package/plugin/JestRobloxRunner.rbxm +0 -0
- package/plugin/out/shared/entry.luau +3 -2
- package/plugin/out/shared/promise.luau +2006 -0
- package/plugin/out/shared/runner.luau +69 -1
- package/plugin/out/shared/setup-timing.luau +89 -0
- package/plugin/src/init.server.luau +1 -1
- package/plugin/src/test-in-run-mode.server.luau +14 -4
|
@@ -3,6 +3,7 @@ local HttpService = game:GetService("HttpService")
|
|
|
3
3
|
local LogService = game:GetService("LogService")
|
|
4
4
|
|
|
5
5
|
local InstanceResolver = require(script.Parent:FindFirstChild('instance-resolver'))
|
|
6
|
+
local SetupTiming = require(script.Parent:FindFirstChild('setup-timing'))
|
|
6
7
|
local SnapshotPatch = require(script.Parent:FindFirstChild('snapshot-patch'))
|
|
7
8
|
|
|
8
9
|
type Config = {
|
|
@@ -133,6 +134,12 @@ function module.run(callingScript: LuaSourceContainer, config: Config): (string,
|
|
|
133
134
|
end
|
|
134
135
|
local t_resolveSetupFiles = os.clock()
|
|
135
136
|
|
|
137
|
+
local setupTimingState = SetupTiming.patch(
|
|
138
|
+
findValue,
|
|
139
|
+
config.setupFiles :: any,
|
|
140
|
+
config.setupFilesAfterEnv :: any
|
|
141
|
+
)
|
|
142
|
+
|
|
136
143
|
-- Strip private keys before Jest.runCLI (safe: single-task execution per VM)
|
|
137
144
|
config._timing = nil :: any
|
|
138
145
|
config._coverage = nil :: any
|
|
@@ -142,14 +149,29 @@ function module.run(callingScript: LuaSourceContainer, config: Config): (string,
|
|
|
142
149
|
end
|
|
143
150
|
|
|
144
151
|
local t_jestRunCLI0 = os.clock()
|
|
145
|
-
local
|
|
152
|
+
local runCLIOk, runCLIValue = pcall(function()
|
|
153
|
+
return Jest.runCLI(callingScript, config, projects):expect()
|
|
154
|
+
end)
|
|
146
155
|
local t_jestRunCLI = os.clock()
|
|
147
156
|
|
|
157
|
+
local setupSeconds = SetupTiming.getSeconds(setupTimingState)
|
|
158
|
+
SetupTiming.unpatch(setupTimingState)
|
|
159
|
+
|
|
160
|
+
if not runCLIOk then
|
|
161
|
+
error(runCLIValue, 0)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
local jestResult = runCLIValue
|
|
165
|
+
|
|
148
166
|
local result: { [string]: any } = {
|
|
149
167
|
success = true,
|
|
150
168
|
value = jestResult,
|
|
151
169
|
}
|
|
152
170
|
|
|
171
|
+
if setupSeconds > 0 then
|
|
172
|
+
result._setup = setupSeconds
|
|
173
|
+
end
|
|
174
|
+
|
|
153
175
|
if timingEnabled then
|
|
154
176
|
result._timing = {
|
|
155
177
|
findJest = t_findJest - t_findJest0,
|
|
@@ -230,4 +252,50 @@ function module.run(callingScript: LuaSourceContainer, config: Config): (string,
|
|
|
230
252
|
return jestResult, if logSuccess then logHistory else "[]"
|
|
231
253
|
end
|
|
232
254
|
|
|
255
|
+
type ProjectEntry = {
|
|
256
|
+
jestOutput: string,
|
|
257
|
+
gameOutput: string,
|
|
258
|
+
elapsedMs: number,
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
local function encodeExecutionError(err: any): string
|
|
262
|
+
return HttpService:JSONEncode({
|
|
263
|
+
success = true,
|
|
264
|
+
value = {
|
|
265
|
+
kind = "ExecutionError",
|
|
266
|
+
error = tostring(err),
|
|
267
|
+
},
|
|
268
|
+
})
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
-- TODO(runner-tests): dogfood harness for Runner.runProjects
|
|
272
|
+
function module.runProjects(
|
|
273
|
+
callingScript: LuaSourceContainer,
|
|
274
|
+
configs: { Config }
|
|
275
|
+
): { ProjectEntry }
|
|
276
|
+
local entries: { ProjectEntry } = {}
|
|
277
|
+
|
|
278
|
+
for index, cfg in configs do
|
|
279
|
+
local start = os.clock()
|
|
280
|
+
local ok, jestOutput, gameOutput = pcall(module.run, callingScript, cfg)
|
|
281
|
+
local elapsedMs = math.floor((os.clock() - start) * 1000)
|
|
282
|
+
|
|
283
|
+
if ok then
|
|
284
|
+
entries[index] = {
|
|
285
|
+
jestOutput = jestOutput :: string,
|
|
286
|
+
gameOutput = gameOutput :: string,
|
|
287
|
+
elapsedMs = elapsedMs,
|
|
288
|
+
}
|
|
289
|
+
else
|
|
290
|
+
entries[index] = {
|
|
291
|
+
jestOutput = encodeExecutionError(jestOutput),
|
|
292
|
+
gameOutput = "[]",
|
|
293
|
+
elapsedMs = elapsedMs,
|
|
294
|
+
}
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
return entries
|
|
299
|
+
end
|
|
300
|
+
|
|
233
301
|
return module
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
local InstanceResolver = require(script.Parent:FindFirstChild('instance-resolver'))
|
|
3
|
+
|
|
4
|
+
local module = {}
|
|
5
|
+
|
|
6
|
+
export type PatchState = {
|
|
7
|
+
Runtime: any,
|
|
8
|
+
originalRequireModule: any,
|
|
9
|
+
accumulatedSeconds: { value: number },
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function module.patch(
|
|
13
|
+
jestModule: ModuleScript,
|
|
14
|
+
setupFiles: { Instance }?,
|
|
15
|
+
setupFilesAfterEnv: { Instance }?
|
|
16
|
+
): PatchState?
|
|
17
|
+
local setupSet: { [Instance]: boolean } = {}
|
|
18
|
+
|
|
19
|
+
if setupFiles then
|
|
20
|
+
for _, inst in setupFiles do
|
|
21
|
+
setupSet[inst] = true
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if setupFilesAfterEnv then
|
|
26
|
+
for _, inst in setupFilesAfterEnv do
|
|
27
|
+
setupSet[inst] = true
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
if not next(setupSet) then
|
|
32
|
+
return nil
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
local jestRuntimeModule = InstanceResolver.findSiblingPackage(jestModule, "JestRuntime", "jest-runtime")
|
|
36
|
+
if not jestRuntimeModule then
|
|
37
|
+
warn("Could not find JestRuntime; setup timing unavailable")
|
|
38
|
+
return nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
local Runtime = (require :: any)(jestRuntimeModule)
|
|
42
|
+
local originalRequireModule = Runtime.requireModule
|
|
43
|
+
local accumulated = { value = 0 }
|
|
44
|
+
local insideSetupRequire = false
|
|
45
|
+
|
|
46
|
+
Runtime.requireModule = function(self: any, moduleName: any, ...): any
|
|
47
|
+
if not insideSetupRequire and typeof(moduleName) == "Instance" and setupSet[moduleName] then
|
|
48
|
+
insideSetupRequire = true
|
|
49
|
+
local t0 = os.clock()
|
|
50
|
+
local results = table.pack(pcall(originalRequireModule, self, moduleName, ...))
|
|
51
|
+
accumulated.value += os.clock() - t0
|
|
52
|
+
insideSetupRequire = false
|
|
53
|
+
|
|
54
|
+
if not results[1] then
|
|
55
|
+
error(results[2], 0)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
return table.unpack(results, 2, results.n)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
return originalRequireModule(self, moduleName, ...)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
Runtime = Runtime,
|
|
66
|
+
originalRequireModule = originalRequireModule,
|
|
67
|
+
accumulatedSeconds = accumulated,
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
function module.unpatch(state: PatchState?)
|
|
72
|
+
if not state then
|
|
73
|
+
return
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
if state.Runtime and state.originalRequireModule then
|
|
77
|
+
state.Runtime.requireModule = state.originalRequireModule
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
function module.getSeconds(state: PatchState?): number
|
|
82
|
+
if not state then
|
|
83
|
+
return 0
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
return state.accumulatedSeconds.value
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
return module
|
|
@@ -8,7 +8,17 @@ if not RunService:IsRunning() then
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
local testArgs = StudioTestService:GetTestArgs()
|
|
11
|
-
if
|
|
11
|
+
if testArgs == nil then
|
|
12
|
+
for _ = 1, 50 do
|
|
13
|
+
task.wait(0.1)
|
|
14
|
+
testArgs = StudioTestService:GetTestArgs()
|
|
15
|
+
if testArgs ~= nil then
|
|
16
|
+
break
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if testArgs == nil or testArgs.configs == nil then
|
|
12
22
|
return
|
|
13
23
|
end
|
|
14
24
|
|
|
@@ -28,9 +38,9 @@ if not loadStringEnabled then
|
|
|
28
38
|
end
|
|
29
39
|
|
|
30
40
|
local Runner = require(script.Parent.shared.runner)
|
|
31
|
-
local
|
|
41
|
+
local entries = Runner.runProjects(script, testArgs.configs)
|
|
32
42
|
|
|
33
43
|
StudioTestService:EndTest({
|
|
34
|
-
jestOutput =
|
|
35
|
-
gameOutput =
|
|
44
|
+
jestOutput = HttpService:JSONEncode({ entries = entries }),
|
|
45
|
+
gameOutput = "[]",
|
|
36
46
|
})
|