@isentinel/jest-roblox 0.3.6 → 0.3.8
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 +80 -14
- package/bin/jest-roblox.js +4 -2
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs +11 -2
- package/dist/index.d.mts +207 -9
- package/dist/index.mjs +2 -2
- package/dist/{run-C4GuftZH.mjs → run-Cirdb_CB.mjs} +1374 -252
- package/dist/{schema-BCTnsaiC.d.mts → schema-i-pZhLCV.d.mts} +240 -8
- package/loaders/luau-raw.d.mts +4 -4
- package/loaders/luau-raw.mjs +5 -5
- package/package.json +3 -3
- package/plugin/JestRobloxRunner.rbxm +0 -0
- package/plugin/src/init.server.luau +11 -4
- package/plugin/src/test-in-run-mode.server.luau +73 -20
|
@@ -7,11 +7,23 @@ if not RunService:IsRunning() then
|
|
|
7
7
|
return
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
-- Plugin/CLI protocol version. Must match `STUDIO_PROTOCOL_VERSION` in
|
|
11
|
+
-- `src/backends/studio.ts` and `STUDIO_CLI_PROTOCOL_VERSION` in
|
|
12
|
+
-- `src/backends/studio-cli.ts`. v3 added the run-mode workspace dispatch + this
|
|
13
|
+
-- version echo. The runner validates the version the CLI sent and echoes its own
|
|
14
|
+
-- in `EndTest`, so the CLI surfaces a clean "update the plugin" error against a
|
|
15
|
+
-- mismatched plugin rather than running with stale runtime semantics.
|
|
16
|
+
local PROTOCOL_VERSION = 3
|
|
17
|
+
|
|
18
|
+
-- Every result (success or failure) echoes `protocolVersion` so the studio-cli
|
|
19
|
+
-- host can detect a stale plugin: one predating this echo omits the field and
|
|
20
|
+
-- the host rejects it as a version mismatch.
|
|
21
|
+
local function endTest(jestOutput: string, gameOutput: string?): ()
|
|
11
22
|
local ok, endErr = pcall(function()
|
|
12
23
|
StudioTestService:EndTest({
|
|
13
|
-
jestOutput =
|
|
14
|
-
gameOutput = "[]",
|
|
24
|
+
jestOutput = jestOutput,
|
|
25
|
+
gameOutput = gameOutput or "[]",
|
|
26
|
+
protocolVersion = PROTOCOL_VERSION,
|
|
15
27
|
})
|
|
16
28
|
end)
|
|
17
29
|
if not ok then
|
|
@@ -19,6 +31,10 @@ local function endWithError(err: string): ()
|
|
|
19
31
|
end
|
|
20
32
|
end
|
|
21
33
|
|
|
34
|
+
local function endWithError(err: string): ()
|
|
35
|
+
endTest(HttpService:JSONEncode({ success = false, err = err }), "[]")
|
|
36
|
+
end
|
|
37
|
+
|
|
22
38
|
local testArgs = StudioTestService:GetTestArgs()
|
|
23
39
|
if testArgs == nil then
|
|
24
40
|
for _ = 1, 50 do
|
|
@@ -34,16 +50,24 @@ if testArgs == nil then
|
|
|
34
50
|
return
|
|
35
51
|
end
|
|
36
52
|
|
|
37
|
-
|
|
38
|
-
|
|
53
|
+
-- Version handshake: reject a missing or mismatched `protocolVersion` before
|
|
54
|
+
-- running anything, mirroring the WebSocket `version_mismatch` path. The error
|
|
55
|
+
-- envelope still echoes our version (via endTest), so the CLI surfaces the
|
|
56
|
+
-- upgrade message either through this error or the version echo.
|
|
57
|
+
local clientVersion = if typeof(testArgs.protocolVersion) == "number"
|
|
58
|
+
then testArgs.protocolVersion
|
|
59
|
+
else nil
|
|
60
|
+
if clientVersion ~= PROTOCOL_VERSION then
|
|
39
61
|
endWithError(
|
|
40
|
-
"
|
|
62
|
+
"Studio plugin protocol version mismatch — plugin v"
|
|
63
|
+
.. tostring(PROTOCOL_VERSION)
|
|
64
|
+
.. ", CLI v"
|
|
65
|
+
.. tostring(clientVersion)
|
|
66
|
+
.. ". Update the jest-roblox Studio plugin to match the CLI."
|
|
41
67
|
)
|
|
42
68
|
return
|
|
43
69
|
end
|
|
44
70
|
|
|
45
|
-
local configs = testArgs.config.configs
|
|
46
|
-
|
|
47
71
|
local loadStringEnabled = pcall(function()
|
|
48
72
|
loadstring("return true")
|
|
49
73
|
end)
|
|
@@ -53,6 +77,41 @@ if not loadStringEnabled then
|
|
|
53
77
|
return
|
|
54
78
|
end
|
|
55
79
|
|
|
80
|
+
-- Dispatch by payload shape. A `workspace` payload drives the staged
|
|
81
|
+
-- materializer (clone each package from the mega-place's `__pkg_stage`, run,
|
|
82
|
+
-- reset) via the shared single-process embedded runner — the same code OCALE
|
|
83
|
+
-- runs, minus the MemoryStore queue. Otherwise the existing single-/multi-
|
|
84
|
+
-- project configs path runs `Runner.runProjects`.
|
|
85
|
+
if testArgs.workspace ~= nil then
|
|
86
|
+
local embeddedOk, EmbeddedRunner =
|
|
87
|
+
pcall(require, script.Parent.shared.staging["embedded-runner"])
|
|
88
|
+
if not embeddedOk then
|
|
89
|
+
endWithError(
|
|
90
|
+
"Failed to require shared.staging.embedded-runner: " .. tostring(EmbeddedRunner)
|
|
91
|
+
)
|
|
92
|
+
return
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
local runOk, entriesOrErr = pcall(EmbeddedRunner.runEmbedded, script, testArgs.workspace)
|
|
96
|
+
if not runOk then
|
|
97
|
+
endWithError("EmbeddedRunner.runEmbedded threw: " .. tostring(entriesOrErr))
|
|
98
|
+
return
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
endTest(HttpService:JSONEncode({ entries = entriesOrErr }), "[]")
|
|
102
|
+
return
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
if testArgs.config == nil or testArgs.config.configs == nil then
|
|
106
|
+
local keysOk, keys = pcall(HttpService.JSONEncode, HttpService, testArgs)
|
|
107
|
+
endWithError(
|
|
108
|
+
"testArgs.config.configs is nil. Keys: " .. (if keysOk then keys else "<unencodable>")
|
|
109
|
+
)
|
|
110
|
+
return
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
local configs = testArgs.config.configs
|
|
114
|
+
|
|
56
115
|
local requireOk, Runner = pcall(require, script.Parent.shared.runner)
|
|
57
116
|
if not requireOk then
|
|
58
117
|
endWithError("Failed to require shared.runner: " .. tostring(Runner))
|
|
@@ -117,11 +176,7 @@ local function injectStubsForConfig(cfg, configIndex: number, injectionPaths: {
|
|
|
117
176
|
)
|
|
118
177
|
local stub = Instance.new("ModuleScript")
|
|
119
178
|
stub.Name = "jest.config"
|
|
120
|
-
stub.Source = string.format(
|
|
121
|
-
'return _G["%s"].configs[%d]',
|
|
122
|
-
SESSION_KEY,
|
|
123
|
-
configIndex
|
|
124
|
-
)
|
|
179
|
+
stub.Source = string.format('return _G["%s"].configs[%d]', SESSION_KEY, configIndex)
|
|
125
180
|
stub.Parent = leaf
|
|
126
181
|
-- Record immediately after parenting so a subsequent mount's
|
|
127
182
|
-- failure does not strand this one.
|
|
@@ -133,7 +188,9 @@ local function cleanupStubsForConfig(configIndex: number)
|
|
|
133
188
|
local injected = injectedPerConfig[configIndex]
|
|
134
189
|
if injected ~= nil then
|
|
135
190
|
for _, inst in injected do
|
|
136
|
-
pcall(function()
|
|
191
|
+
pcall(function()
|
|
192
|
+
inst:Destroy()
|
|
193
|
+
end)
|
|
137
194
|
end
|
|
138
195
|
injectedPerConfig[configIndex] = nil
|
|
139
196
|
end
|
|
@@ -159,8 +216,7 @@ end
|
|
|
159
216
|
-- nested-project mounts (e.g. `ReplicatedStorage` and `ReplicatedStorage/Foo`)
|
|
160
217
|
-- never have stubs in DataModel simultaneously — which would let Jest's
|
|
161
218
|
-- parent-traversal config lookup resolve the wrong project's config.
|
|
162
|
-
local runtimeStubMounts: { { string } } = testArgs.runtimeStubMounts
|
|
163
|
-
or table.create(#configs, {})
|
|
219
|
+
local runtimeStubMounts: { { string } } = testArgs.runtimeStubMounts or table.create(#configs, {})
|
|
164
220
|
|
|
165
221
|
local hooks = {
|
|
166
222
|
beforeConfig = function(cfg, index)
|
|
@@ -181,7 +237,4 @@ if not runOk then
|
|
|
181
237
|
return
|
|
182
238
|
end
|
|
183
239
|
|
|
184
|
-
|
|
185
|
-
jestOutput = HttpService:JSONEncode({ entries = entriesOrErr }),
|
|
186
|
-
gameOutput = "[]",
|
|
187
|
-
})
|
|
240
|
+
endTest(HttpService:JSONEncode({ entries = entriesOrErr }), "[]")
|