@quenty/nevermore-cli 4.47.0 → 4.47.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/CHANGELOG.md +11 -0
- package/dist/commands/batch-command/batch-deploy-command.d.ts.map +1 -1
- package/dist/commands/batch-command/batch-deploy-command.js +4 -3
- package/dist/commands/batch-command/batch-deploy-command.js.map +1 -1
- package/dist/utils/build/upload.d.ts.map +1 -1
- package/dist/utils/build/upload.js +4 -1
- package/dist/utils/build/upload.js.map +1 -1
- package/dist/utils/job-context/cloud-job-context.d.ts.map +1 -1
- package/dist/utils/job-context/cloud-job-context.js +5 -3
- package/dist/utils/job-context/cloud-job-context.js.map +1 -1
- package/dist/utils/open-cloud/open-cloud-client.d.ts +4 -4
- package/dist/utils/open-cloud/open-cloud-client.d.ts.map +1 -1
- package/dist/utils/open-cloud/open-cloud-client.js +6 -5
- package/dist/utils/open-cloud/open-cloud-client.js.map +1 -1
- package/dist/utils/open-cloud/rate-limiter.d.ts +29 -2
- package/dist/utils/open-cloud/rate-limiter.d.ts.map +1 -1
- package/dist/utils/open-cloud/rate-limiter.js +98 -20
- package/dist/utils/open-cloud/rate-limiter.js.map +1 -1
- package/dist/utils/open-cloud/rate-limiter.test.js +64 -4
- package/dist/utils/open-cloud/rate-limiter.test.js.map +1 -1
- package/dist/utils/testing/parsers/batch-log-parser.test.js +1 -1
- package/dist/utils/testing/parsers/batch-log-parser.test.js.map +1 -1
- package/dist/utils/testing/runner/test-runner.d.ts.map +1 -1
- package/dist/utils/testing/runner/test-runner.js +8 -7
- package/dist/utils/testing/runner/test-runner.js.map +1 -1
- package/dist/utils/testing/runner/test-runner.test.js +1 -1
- package/dist/utils/testing/runner/test-runner.test.js.map +1 -1
- package/package.json +3 -3
- package/src/commands/batch-command/batch-deploy-command.ts +11 -3
- package/src/utils/build/upload.ts +5 -1
- package/src/utils/job-context/cloud-job-context.ts +24 -15
- package/src/utils/open-cloud/open-cloud-client.ts +25 -12
- package/src/utils/open-cloud/rate-limiter.test.ts +106 -4
- package/src/utils/open-cloud/rate-limiter.ts +150 -21
- package/src/utils/testing/parsers/batch-log-parser.test.ts +3 -3
- package/src/utils/testing/runner/test-runner.test.ts +1 -1
- package/src/utils/testing/runner/test-runner.ts +8 -9
- package/templates/batch-test-runner.lua +176 -172
- package/templates/game-template/src/scripts/Server/ServerMain.server.lua +3 -2
- package/templates/nevermore-library-package-template/test/scripts/Server/ServerMain.server.lua +3 -2
- package/templates/nevermore-service-package-template/test/scripts/Server/ServerMain.server.lua +3 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
--
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
--[[
|
|
2
|
+
Runs every package's test script sequentially in one execution task, isolating
|
|
3
|
+
each package under ServerScriptService and cleaning up after it.
|
|
4
|
+
|
|
5
|
+
PACKAGE_SLUGS_JSON is replaced with a JSON array of slugs at runtime. Test
|
|
6
|
+
scripts are found by the `_BatchTest_<slug>` tag set by combine-test-places.lua.
|
|
7
|
+
]]
|
|
4
8
|
|
|
5
9
|
local CollectionService = game:GetService("CollectionService")
|
|
6
10
|
local HttpService = game:GetService("HttpService")
|
|
@@ -8,56 +12,28 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
|
|
8
12
|
local RunService = game:GetService("RunService")
|
|
9
13
|
local ServerScriptService = game:GetService("ServerScriptService")
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
local packageSlugs: { string } = HttpService:JSONDecode([==[{{ PACKAGE_SLUGS_JSON }}]==])
|
|
13
|
-
|
|
14
|
-
-- Discover test scripts via tags (set by combine-test-places.lua)
|
|
15
|
-
local scriptSources = {}
|
|
16
|
-
for _, slug in packageSlugs do
|
|
17
|
-
local tagged = CollectionService:GetTagged(`_BatchTest_{slug}`)
|
|
18
|
-
local inst = tagged[1]
|
|
19
|
-
if inst then
|
|
20
|
-
scriptSources[slug] = inst.Source
|
|
21
|
-
else
|
|
22
|
-
warn(`[BatchTest] Failed to find script source for {slug}`)
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
-- Snapshot all package roots (keep references even when unparented)
|
|
27
|
-
local allPackages = {}
|
|
28
|
-
for _, child in ServerScriptService:GetChildren() do
|
|
29
|
-
allPackages[child.Name] = child
|
|
30
|
-
end
|
|
15
|
+
local BatchTestRunnerUtils = {}
|
|
31
16
|
|
|
32
|
-
--
|
|
33
|
-
|
|
34
|
-
-- it likes, so only a tagged table is read as results.
|
|
17
|
+
-- stylua: ignore
|
|
18
|
+
local PACKAGE_SLUGS: { PackageSlug } = HttpService:JSONDecode([==[{{ PACKAGE_SLUGS_JSON }}]==])
|
|
35
19
|
local RESULTS_FORMAT = "nevermore-test-results@1"
|
|
36
|
-
|
|
37
|
-
-- Module NevermoreTestRunnerUtils leaves a run's results in, regardless of what
|
|
38
|
-
-- the script did with them. Most test scripts discard the return value
|
|
39
|
-
-- (`if runTestsIfNeededAsync(root) then return end`), and without this their
|
|
40
|
-
-- counts exist only in Jest's printed report — the first thing a long batch's
|
|
41
|
-
-- log window drops. Read as a fallback, never in preference to what the script
|
|
42
|
-
-- actually returned.
|
|
43
|
-
--
|
|
44
|
-
-- Named rather than required by path: this script is raw source with no loader,
|
|
45
|
-
-- so it finds the module under the package it just ran and requires the
|
|
46
|
-
-- instance. Requiring the same instance twice returns the same table, which is
|
|
47
|
-
-- what makes this a mailbox and not a copy.
|
|
48
20
|
local STATE_MODULE_NAME = "NevermoreTestRunnerState.global"
|
|
21
|
+
local COUNT_FIELDS = { "passed", "failed", "skipped", "total", "suitesPassed", "suitesFailed", "suitesTotal" }
|
|
49
22
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
]]
|
|
54
|
-
local function findStateModule(package: Instance): ModuleScript?
|
|
55
|
-
local found = package:FindFirstChild(STATE_MODULE_NAME, true)
|
|
23
|
+
type PackageSlug = string
|
|
24
|
+
type PackageLookupMap = { [PackageSlug]: Instance }
|
|
25
|
+
type ScriptSourceLookupMap = { [PackageSlug]: string }
|
|
56
26
|
|
|
57
|
-
|
|
58
|
-
|
|
27
|
+
type TestResult = {
|
|
28
|
+
success: boolean,
|
|
29
|
+
slug: PackageSlug,
|
|
30
|
+
durationMs: number,
|
|
31
|
+
error: string?,
|
|
32
|
+
counts: TestCountsResult?,
|
|
33
|
+
ranJest: boolean?,
|
|
34
|
+
}
|
|
59
35
|
|
|
60
|
-
type
|
|
36
|
+
type TestCountsResult = {
|
|
61
37
|
passed: number,
|
|
62
38
|
failed: number,
|
|
63
39
|
skipped: number,
|
|
@@ -67,92 +43,142 @@ type TestCounts = {
|
|
|
67
43
|
suitesTotal: number,
|
|
68
44
|
}
|
|
69
45
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
slug
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
46
|
+
function BatchTestRunnerUtils.getScriptSourceLookupMap(slugs: { PackageSlug }): ScriptSourceLookupMap
|
|
47
|
+
local scriptSourceLookupMap: ScriptSourceLookupMap = {}
|
|
48
|
+
for _, slug in slugs do
|
|
49
|
+
local inst = CollectionService:GetTagged(`_BatchTest_{slug}`)[1]
|
|
50
|
+
if inst then
|
|
51
|
+
scriptSourceLookupMap[slug] = (inst :: Script).Source
|
|
52
|
+
else
|
|
53
|
+
warn(`[BatchTest] Failed to find script source for {slug}`)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
return table.freeze(scriptSourceLookupMap)
|
|
57
|
+
end
|
|
82
58
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if type(returned) ~= "table" or returned.format ~= RESULTS_FORMAT then
|
|
89
|
-
return nil
|
|
59
|
+
function BatchTestRunnerUtils.detachPackages(): (PackageLookupMap, () -> ())
|
|
60
|
+
local packageLookupMap: PackageLookupMap = {}
|
|
61
|
+
for _, child in ServerScriptService:GetChildren() do
|
|
62
|
+
packageLookupMap[child.Name] = child
|
|
63
|
+
child.Parent = nil
|
|
90
64
|
end
|
|
65
|
+
table.freeze(packageLookupMap)
|
|
91
66
|
|
|
92
|
-
local
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return nil
|
|
67
|
+
local function restore()
|
|
68
|
+
for _, package in packageLookupMap do
|
|
69
|
+
package.Parent = ServerScriptService
|
|
96
70
|
end
|
|
97
|
-
counts[field] = returned[field]
|
|
98
71
|
end
|
|
99
72
|
|
|
100
|
-
return
|
|
73
|
+
return packageLookupMap, restore
|
|
101
74
|
end
|
|
102
75
|
|
|
103
|
-
|
|
104
|
-
|
|
76
|
+
function BatchTestRunnerUtils.toSet<T>(list: { T }): { [T]: true }
|
|
77
|
+
local set: { [T]: true } = {}
|
|
78
|
+
for _, item in list do
|
|
79
|
+
set[item] = true
|
|
80
|
+
end
|
|
81
|
+
return table.freeze(set)
|
|
105
82
|
end
|
|
106
83
|
|
|
107
|
-
|
|
84
|
+
function BatchTestRunnerUtils.isolatePackage(package: Instance): () -> ()
|
|
85
|
+
package.Parent = ServerScriptService
|
|
108
86
|
|
|
109
|
-
|
|
110
|
-
local
|
|
111
|
-
if not scriptSource then
|
|
112
|
-
print("===BATCH_TEST_BEGIN " .. slug .. "===")
|
|
113
|
-
warn(`[BatchTest] {slug}: No test script found for {slug}. Is it tagged with _BatchTest_{slug}?`)
|
|
114
|
-
print("===BATCH_TEST_END " .. slug .. " FAIL 0===")
|
|
115
|
-
table.insert(results, { slug = slug, success = false, durationMs = 0, error = "No test script found" })
|
|
116
|
-
continue
|
|
117
|
-
end
|
|
87
|
+
local preWorkspace = BatchTestRunnerUtils.toSet(workspace:GetChildren())
|
|
88
|
+
local preReplicatedStorage = BatchTestRunnerUtils.toSet(ReplicatedStorage:GetChildren())
|
|
118
89
|
|
|
119
|
-
|
|
120
|
-
for _, package in allPackages do
|
|
90
|
+
return function()
|
|
121
91
|
package.Parent = nil
|
|
92
|
+
|
|
93
|
+
for _, child in workspace:GetChildren() do
|
|
94
|
+
if not preWorkspace[child] and not child:IsA("Terrain") and not child:IsA("Camera") then
|
|
95
|
+
pcall(child.Destroy, child)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
for _, child in ReplicatedStorage:GetChildren() do
|
|
99
|
+
if not preReplicatedStorage[child] then
|
|
100
|
+
pcall(child.Destroy, child)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
for _, desc in package:GetDescendants() do
|
|
104
|
+
if not desc.Archivable and desc:IsA("ModuleScript") and desc.Name == "loader" then
|
|
105
|
+
pcall(desc.Destroy, desc)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
122
108
|
end
|
|
123
|
-
|
|
109
|
+
end
|
|
124
110
|
|
|
125
|
-
|
|
126
|
-
local
|
|
127
|
-
|
|
128
|
-
|
|
111
|
+
function BatchTestRunnerUtils.resetTestResultsMailbox(package: Instance): any
|
|
112
|
+
local found = package:FindFirstChild(STATE_MODULE_NAME, true)
|
|
113
|
+
if not (found and found:IsA("ModuleScript")) then
|
|
114
|
+
return nil
|
|
129
115
|
end
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
116
|
+
|
|
117
|
+
local state = (require :: any)(found)
|
|
118
|
+
state.results = nil
|
|
119
|
+
return state
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
function BatchTestRunnerUtils.isFailedTestResult(returned: any): boolean
|
|
123
|
+
return type(returned) == "table" and returned.format == RESULTS_FORMAT and returned.success ~= true
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
function BatchTestRunnerUtils.readTestResultCounts(returned: any): TestCountsResult?
|
|
127
|
+
if type(returned) ~= "table" or returned.format ~= RESULTS_FORMAT then
|
|
128
|
+
return nil
|
|
133
129
|
end
|
|
134
130
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
131
|
+
local counts: { [string]: number } = {}
|
|
132
|
+
for _, field in COUNT_FIELDS do
|
|
133
|
+
if type(returned[field]) ~= "number" then
|
|
134
|
+
return nil
|
|
135
|
+
end
|
|
136
|
+
counts[field] = returned[field]
|
|
137
|
+
end
|
|
140
138
|
|
|
141
|
-
|
|
139
|
+
return table.freeze(counts) :: any
|
|
140
|
+
end
|
|
142
141
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
142
|
+
function BatchTestRunnerUtils.createTestResult(
|
|
143
|
+
slug: PackageSlug,
|
|
144
|
+
testOk: boolean,
|
|
145
|
+
returned: any,
|
|
146
|
+
state: any,
|
|
147
|
+
durationMs: number
|
|
148
|
+
): TestResult
|
|
149
|
+
local mailboxResults = if state then state.results else nil
|
|
150
|
+
local reported = if testOk and BatchTestRunnerUtils.readTestResultCounts(returned) then returned else mailboxResults
|
|
151
|
+
|
|
152
|
+
local counts = if testOk then BatchTestRunnerUtils.readTestResultCounts(reported) else nil
|
|
153
|
+
local success = testOk and not BatchTestRunnerUtils.isFailedTestResult(reported)
|
|
154
|
+
local failureReason: string? = nil
|
|
155
|
+
if not testOk then
|
|
156
|
+
failureReason = tostring(returned)
|
|
157
|
+
elseif not success then
|
|
158
|
+
failureReason = tostring((reported :: any).error or "the test runner reported the run as failed")
|
|
149
159
|
end
|
|
150
160
|
|
|
151
|
-
|
|
152
|
-
|
|
161
|
+
return table.freeze({
|
|
162
|
+
slug = slug,
|
|
163
|
+
success = success,
|
|
164
|
+
durationMs = durationMs,
|
|
165
|
+
error = failureReason,
|
|
166
|
+
counts = counts,
|
|
167
|
+
ranJest = if counts then (reported :: any).ranJest == true else nil,
|
|
168
|
+
})
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
function BatchTestRunnerUtils.reportMissingScriptResult(slug: PackageSlug): TestResult
|
|
172
|
+
print("===BATCH_TEST_BEGIN " .. slug .. "===")
|
|
173
|
+
warn(`[BatchTest] {slug}: No test script found for {slug}. Is it tagged with _BatchTest_{slug}?`)
|
|
174
|
+
print("===BATCH_TEST_END " .. slug .. " FAIL 0===")
|
|
175
|
+
return table.freeze({ slug = slug, success = false, durationMs = 0, error = "No test script found" })
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
function BatchTestRunnerUtils.runScriptTimed(slug: PackageSlug, scriptSource: string): (boolean, any, number)
|
|
153
179
|
local startClock = os.clock()
|
|
154
180
|
|
|
155
|
-
local
|
|
181
|
+
local ok, returned = pcall(function()
|
|
156
182
|
local fn, compileErr = loadstring(scriptSource, slug)
|
|
157
183
|
if not fn then
|
|
158
184
|
error("Compile error: " .. tostring(compileErr))
|
|
@@ -161,82 +187,60 @@ for _, slug in packageSlugs do
|
|
|
161
187
|
end)
|
|
162
188
|
|
|
163
189
|
local durationMs = math.floor((os.clock() - startClock) * 1000 + 0.5)
|
|
190
|
+
return ok, returned, durationMs
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
function BatchTestRunnerUtils.runPackage(
|
|
194
|
+
packageLookupMap: PackageLookupMap,
|
|
195
|
+
slug: PackageSlug,
|
|
196
|
+
scriptSource: string?
|
|
197
|
+
): TestResult
|
|
198
|
+
if not scriptSource then
|
|
199
|
+
return BatchTestRunnerUtils.reportMissingScriptResult(slug)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
local package = packageLookupMap[slug]
|
|
203
|
+
local restore = BatchTestRunnerUtils.isolatePackage(package)
|
|
164
204
|
|
|
165
|
-
-- Yield before the END marker for the same reason: leaked deferred
|
|
166
|
-
-- callbacks may fire during fn() and their output must land before
|
|
167
|
-
-- the marker in the log stream.
|
|
168
205
|
RunService.Heartbeat:Wait()
|
|
206
|
+
print("===BATCH_TEST_BEGIN " .. slug .. "===")
|
|
169
207
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
for _, child in ReplicatedStorage:GetChildren() do
|
|
178
|
-
if not preRunService[child] then
|
|
179
|
-
pcall(child.Destroy, child)
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
-- Destroy injected LoaderLinks (non-archivable, created by LoaderLinkCreator)
|
|
183
|
-
for _, desc in allPackages[slug]:GetDescendants() do
|
|
184
|
-
if not desc.Archivable and desc:IsA("ModuleScript") and desc.Name == "loader" then
|
|
185
|
-
pcall(desc.Destroy, desc)
|
|
186
|
-
end
|
|
187
|
-
end
|
|
208
|
+
local state = BatchTestRunnerUtils.resetTestResultsMailbox(package)
|
|
209
|
+
local testOk, returned, durationMs = BatchTestRunnerUtils.runScriptTimed(slug, scriptSource)
|
|
210
|
+
|
|
211
|
+
RunService.Heartbeat:Wait()
|
|
212
|
+
restore()
|
|
188
213
|
|
|
189
|
-
-- Flush lingering deferred callbacks. Heavy packages (Binder, ServiceBag)
|
|
190
|
-
-- schedule deferred callbacks via CollectionService that survive cleanup.
|
|
191
|
-
-- Yielding across multiple heartbeat frames is more reliable than a fixed
|
|
192
|
-
-- time wait, since each frame drains its deferred queue.
|
|
193
214
|
for _ = 1, 3 do
|
|
194
215
|
RunService.Heartbeat:Wait()
|
|
195
216
|
end
|
|
196
217
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
-- return its results independent of the state module.
|
|
201
|
-
local published = if state then state.results else nil
|
|
202
|
-
local reported = if testOk and toCounts(returned) then returned else published
|
|
203
|
-
|
|
204
|
-
-- A test script that does not throw has still failed if the results say so,
|
|
205
|
-
-- which is the whole reason they are read at all: a failing suite used to
|
|
206
|
-
-- announce itself by erroring, and an error carries no counts.
|
|
207
|
-
local counts = if testOk then toCounts(reported) else nil
|
|
208
|
-
local success = testOk and not isStructuredFailure(reported)
|
|
209
|
-
local failureReason: string? = nil
|
|
210
|
-
if not testOk then
|
|
211
|
-
failureReason = tostring(returned)
|
|
212
|
-
elseif not success then
|
|
213
|
-
failureReason = tostring((reported :: any).error or "the test runner reported the run as failed")
|
|
218
|
+
local result = BatchTestRunnerUtils.createTestResult(slug, testOk, returned, state, durationMs)
|
|
219
|
+
if result.error then
|
|
220
|
+
warn("[BatchTest] " .. slug .. ": " .. result.error)
|
|
214
221
|
end
|
|
222
|
+
print(
|
|
223
|
+
"===BATCH_TEST_END " .. slug .. (if result.success then " PASS " else " FAIL ") .. tostring(durationMs) .. "==="
|
|
224
|
+
)
|
|
215
225
|
|
|
216
|
-
|
|
217
|
-
warn("[BatchTest] " .. slug .. ": " .. failureReason)
|
|
218
|
-
end
|
|
219
|
-
print("===BATCH_TEST_END " .. slug .. (if success then " PASS " else " FAIL ") .. tostring(durationMs) .. "===")
|
|
220
|
-
table.insert(results, {
|
|
221
|
-
slug = slug,
|
|
222
|
-
success = success,
|
|
223
|
-
durationMs = durationMs,
|
|
224
|
-
error = failureReason,
|
|
225
|
-
counts = counts,
|
|
226
|
-
ranJest = if counts then (reported :: any).ranJest == true else nil,
|
|
227
|
-
})
|
|
226
|
+
return result
|
|
228
227
|
end
|
|
229
228
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
229
|
+
function BatchTestRunnerUtils.printResultsSummary(results: { TestResult })
|
|
230
|
+
print("===BATCH_TEST_SUMMARY===")
|
|
231
|
+
print(HttpService:JSONEncode(results))
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
local scriptSourceLookupMap = BatchTestRunnerUtils.getScriptSourceLookupMap(PACKAGE_SLUGS)
|
|
235
|
+
local packageLookupMap, restorePackages = BatchTestRunnerUtils.detachPackages()
|
|
236
|
+
|
|
237
|
+
local results: { TestResult } = {}
|
|
238
|
+
for _, slug in PACKAGE_SLUGS do
|
|
239
|
+
table.insert(results, BatchTestRunnerUtils.runPackage(packageLookupMap, slug, scriptSourceLookupMap[slug]))
|
|
233
240
|
end
|
|
241
|
+
table.freeze(results)
|
|
234
242
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
-- truncated, since an oversize return fails the task outright rather than
|
|
238
|
-
-- arriving short. Counts only, so it stays far inside that limit.
|
|
239
|
-
print("===BATCH_TEST_SUMMARY===")
|
|
240
|
-
print(HttpService:JSONEncode(results))
|
|
243
|
+
restorePackages()
|
|
244
|
+
BatchTestRunnerUtils.printResultsSummary(results)
|
|
241
245
|
|
|
242
246
|
return results
|
|
@@ -10,8 +10,9 @@ local require = require(loader).bootstrapGame(root)
|
|
|
10
10
|
|
|
11
11
|
local NevermoreTestRunnerUtils = require("NevermoreTestRunnerUtils")
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
local results = NevermoreTestRunnerUtils.runTestsIfNeededAsync(root.game)
|
|
14
|
+
if results then
|
|
15
|
+
return results
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
local serviceBag = require("ServiceBag").new()
|
package/templates/nevermore-library-package-template/test/scripts/Server/ServerMain.server.lua
CHANGED
|
@@ -8,6 +8,7 @@ local loader = root:FindFirstChild("LoaderUtils", true).Parent
|
|
|
8
8
|
local require = require(loader).bootstrapGame(root)
|
|
9
9
|
|
|
10
10
|
local NevermoreTestRunnerUtils = require("NevermoreTestRunnerUtils")
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
local results = NevermoreTestRunnerUtils.runTestsIfNeededAsync(root)
|
|
12
|
+
if results then
|
|
13
|
+
return results
|
|
13
14
|
end
|
package/templates/nevermore-service-package-template/test/scripts/Server/ServerMain.server.lua
CHANGED
|
@@ -8,8 +8,9 @@ local loader = root:FindFirstChild("LoaderUtils", true).Parent
|
|
|
8
8
|
local require = require(loader).bootstrapGame(root)
|
|
9
9
|
|
|
10
10
|
local NevermoreTestRunnerUtils = require("NevermoreTestRunnerUtils")
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
local results = NevermoreTestRunnerUtils.runTestsIfNeededAsync(root)
|
|
12
|
+
if results then
|
|
13
|
+
return results
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
local serviceBag = require("ServiceBag").new()
|