@quenty/instanceutils 13.29.2 → 13.30.0
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 +31 -496
- package/deploy.nevermore.json +10 -0
- package/package.json +3 -3
- package/src/Shared/RxInstanceUtils.lua +20 -20
- package/src/Shared/RxInstanceUtils.spec.lua +341 -0
- package/test/default.project.json +17 -0
- package/test/scripts/Server/ServerMain.server.lua +15 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/instanceutils",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.30.0",
|
|
4
4
|
"description": "Utility functions involving instances in Roblox",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"Quenty"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@quenty/brio": "14.
|
|
32
|
+
"@quenty/brio": "14.30.0",
|
|
33
33
|
"@quenty/loader": "10.11.0",
|
|
34
34
|
"@quenty/maid": "3.9.0",
|
|
35
35
|
"@quenty/nevermore-test-runner": "1.4.0",
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"publishConfig": {
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "f4a374a0a294ee8900aa5cb68ab138b0acf3e0ae"
|
|
44
44
|
}
|
|
@@ -192,23 +192,30 @@ function RxInstanceUtils.observePropertyBrio(
|
|
|
192
192
|
end) :: any
|
|
193
193
|
end
|
|
194
194
|
|
|
195
|
+
function RxInstanceUtils._toPredicate(className: string | Rx.Predicate<Instance>): Rx.Predicate<Instance>
|
|
196
|
+
if type(className) == "string" then
|
|
197
|
+
return function(instance: Instance)
|
|
198
|
+
return instance:IsA(className)
|
|
199
|
+
end
|
|
200
|
+
else
|
|
201
|
+
return className
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
195
205
|
--[=[
|
|
196
206
|
Observes the last child with a specific name.
|
|
197
|
-
|
|
198
|
-
@param parent Instance
|
|
199
|
-
@param className string
|
|
200
|
-
@param name string
|
|
201
|
-
@return Observable<Brio<Instance>>
|
|
202
207
|
]=]
|
|
203
208
|
function RxInstanceUtils.observeLastNamedChildBrio(
|
|
204
209
|
parent: Instance,
|
|
205
|
-
className: string
|
|
210
|
+
className: string | Rx.Predicate<Instance>,
|
|
206
211
|
name: string
|
|
207
212
|
): Observable.Observable<Brio.Brio<Instance>>
|
|
208
213
|
assert(typeof(parent) == "Instance", "Bad parent")
|
|
209
|
-
assert(type(className) == "string", "Bad className")
|
|
214
|
+
assert(type(className) == "string" or type(className) == "function", "Bad className")
|
|
210
215
|
assert(type(name) == "string", "Bad name")
|
|
211
216
|
|
|
217
|
+
local predicate = RxInstanceUtils._toPredicate(className)
|
|
218
|
+
|
|
212
219
|
return Observable.new(function(sub)
|
|
213
220
|
local topMaid = Maid.new()
|
|
214
221
|
local validChildren = {}
|
|
@@ -231,7 +238,7 @@ function RxInstanceUtils.observeLastNamedChildBrio(
|
|
|
231
238
|
end
|
|
232
239
|
|
|
233
240
|
local function handleChild(child: Instance)
|
|
234
|
-
if not child
|
|
241
|
+
if not predicate(child) then
|
|
235
242
|
return
|
|
236
243
|
end
|
|
237
244
|
|
|
@@ -271,26 +278,23 @@ end
|
|
|
271
278
|
|
|
272
279
|
--[=[
|
|
273
280
|
Observes the children with a specific name.
|
|
274
|
-
|
|
275
|
-
@param parent Instance
|
|
276
|
-
@param className string
|
|
277
|
-
@param name string
|
|
278
|
-
@return Observable<Brio<Instance>>
|
|
279
281
|
]=]
|
|
280
282
|
function RxInstanceUtils.observeChildrenOfNameBrio(
|
|
281
283
|
parent: Instance,
|
|
282
|
-
className: string
|
|
284
|
+
className: string | Rx.Predicate<Instance>,
|
|
283
285
|
name: string
|
|
284
286
|
): Observable.Observable<Brio.Brio<Instance>>
|
|
285
287
|
assert(typeof(parent) == "Instance", "Bad parent")
|
|
286
|
-
assert(type(className) == "string", "Bad className")
|
|
288
|
+
assert(type(className) == "string" or type(className) == "function", "Bad className")
|
|
287
289
|
assert(type(name) == "string", "Bad name")
|
|
288
290
|
|
|
291
|
+
local predicate = RxInstanceUtils._toPredicate(className)
|
|
292
|
+
|
|
289
293
|
return Observable.new(function(sub)
|
|
290
294
|
local topMaid = Maid.new()
|
|
291
295
|
|
|
292
296
|
local function handleChild(child: Instance)
|
|
293
|
-
if not child
|
|
297
|
+
if not predicate(child) then
|
|
294
298
|
return
|
|
295
299
|
end
|
|
296
300
|
|
|
@@ -328,10 +332,6 @@ end
|
|
|
328
332
|
|
|
329
333
|
--[=[
|
|
330
334
|
Observes all children of a specific class
|
|
331
|
-
|
|
332
|
-
@param parent Instance
|
|
333
|
-
@param className string
|
|
334
|
-
@return Observable<Brio<Instance>>
|
|
335
335
|
]=]
|
|
336
336
|
function RxInstanceUtils.observeChildrenOfClassBrio(
|
|
337
337
|
parent: Instance,
|
|
@@ -7,6 +7,7 @@ local require = (require :: any)(
|
|
|
7
7
|
game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent
|
|
8
8
|
).bootstrapStory(script) :: typeof(require(script.Parent.loader).load(script))
|
|
9
9
|
|
|
10
|
+
local Brio = require("Brio")
|
|
10
11
|
local Jest = require("Jest")
|
|
11
12
|
local RxInstanceUtils = require("RxInstanceUtils")
|
|
12
13
|
|
|
@@ -27,3 +28,343 @@ describe("RxInstanceUtils.observeChildrenBrio", function()
|
|
|
27
28
|
expect(externalResult).toEqual(nil)
|
|
28
29
|
end)
|
|
29
30
|
end)
|
|
31
|
+
|
|
32
|
+
describe("RxInstanceUtils.observeLastNamedChildBrio", function()
|
|
33
|
+
describe("with no children", function()
|
|
34
|
+
it("should not emit anything", function()
|
|
35
|
+
local parent = Instance.new("Folder")
|
|
36
|
+
local lastBrio = nil
|
|
37
|
+
local fireCount = 0
|
|
38
|
+
|
|
39
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "Part", "Target"):Subscribe(function(brio)
|
|
40
|
+
lastBrio = brio
|
|
41
|
+
fireCount = fireCount + 1
|
|
42
|
+
end)
|
|
43
|
+
|
|
44
|
+
expect(fireCount).toEqual(0)
|
|
45
|
+
expect(lastBrio).toBeNil()
|
|
46
|
+
|
|
47
|
+
sub:Destroy()
|
|
48
|
+
end)
|
|
49
|
+
end)
|
|
50
|
+
|
|
51
|
+
describe("with a matching child already present", function()
|
|
52
|
+
it("should emit a brio with the child", function()
|
|
53
|
+
local parent = Instance.new("Folder")
|
|
54
|
+
local child = Instance.new("Part")
|
|
55
|
+
child.Name = "Target"
|
|
56
|
+
child.Parent = parent
|
|
57
|
+
|
|
58
|
+
local lastBrio = nil
|
|
59
|
+
local fireCount = 0
|
|
60
|
+
|
|
61
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "Part", "Target"):Subscribe(function(brio)
|
|
62
|
+
lastBrio = brio
|
|
63
|
+
fireCount = fireCount + 1
|
|
64
|
+
end)
|
|
65
|
+
|
|
66
|
+
expect(fireCount).toEqual(1)
|
|
67
|
+
expect(lastBrio).never.toBeNil()
|
|
68
|
+
expect(Brio.isBrio(lastBrio)).toEqual(true)
|
|
69
|
+
expect(lastBrio:IsDead()).toEqual(false)
|
|
70
|
+
expect(lastBrio:GetValue()).toEqual(child)
|
|
71
|
+
|
|
72
|
+
sub:Destroy()
|
|
73
|
+
end)
|
|
74
|
+
end)
|
|
75
|
+
|
|
76
|
+
describe("with wrong className", function()
|
|
77
|
+
it("should not emit for a child with the wrong class", function()
|
|
78
|
+
local parent = Instance.new("Folder")
|
|
79
|
+
local child = Instance.new("Folder")
|
|
80
|
+
child.Name = "Target"
|
|
81
|
+
child.Parent = parent
|
|
82
|
+
|
|
83
|
+
local fireCount = 0
|
|
84
|
+
|
|
85
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "Part", "Target"):Subscribe(function()
|
|
86
|
+
fireCount = fireCount + 1
|
|
87
|
+
end)
|
|
88
|
+
|
|
89
|
+
expect(fireCount).toEqual(0)
|
|
90
|
+
|
|
91
|
+
sub:Destroy()
|
|
92
|
+
end)
|
|
93
|
+
end)
|
|
94
|
+
|
|
95
|
+
describe("with wrong name", function()
|
|
96
|
+
it("should not emit for a child with the wrong name", function()
|
|
97
|
+
local parent = Instance.new("Folder")
|
|
98
|
+
local child = Instance.new("Part")
|
|
99
|
+
child.Name = "Wrong"
|
|
100
|
+
child.Parent = parent
|
|
101
|
+
|
|
102
|
+
local fireCount = 0
|
|
103
|
+
|
|
104
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "Part", "Target"):Subscribe(function()
|
|
105
|
+
fireCount = fireCount + 1
|
|
106
|
+
end)
|
|
107
|
+
|
|
108
|
+
expect(fireCount).toEqual(0)
|
|
109
|
+
|
|
110
|
+
sub:Destroy()
|
|
111
|
+
end)
|
|
112
|
+
end)
|
|
113
|
+
|
|
114
|
+
describe("when a child is added after subscription", function()
|
|
115
|
+
it("should emit when a matching child is added", function()
|
|
116
|
+
local parent = Instance.new("Folder")
|
|
117
|
+
local lastBrio = nil
|
|
118
|
+
local fireCount = 0
|
|
119
|
+
|
|
120
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "Part", "Target"):Subscribe(function(brio)
|
|
121
|
+
lastBrio = brio
|
|
122
|
+
fireCount = fireCount + 1
|
|
123
|
+
end)
|
|
124
|
+
|
|
125
|
+
expect(fireCount).toEqual(0)
|
|
126
|
+
|
|
127
|
+
local child = Instance.new("Part")
|
|
128
|
+
child.Name = "Target"
|
|
129
|
+
child.Parent = parent
|
|
130
|
+
|
|
131
|
+
expect(fireCount).toEqual(1)
|
|
132
|
+
expect(lastBrio).never.toBeNil()
|
|
133
|
+
expect(Brio.isBrio(lastBrio)).toEqual(true)
|
|
134
|
+
expect(lastBrio:GetValue()).toEqual(child)
|
|
135
|
+
|
|
136
|
+
sub:Destroy()
|
|
137
|
+
end)
|
|
138
|
+
end)
|
|
139
|
+
|
|
140
|
+
describe("when a matching child is removed", function()
|
|
141
|
+
it("should kill the previous brio", function()
|
|
142
|
+
local parent = Instance.new("Folder")
|
|
143
|
+
local child = Instance.new("Part")
|
|
144
|
+
child.Name = "Target"
|
|
145
|
+
child.Parent = parent
|
|
146
|
+
|
|
147
|
+
local lastBrio = nil
|
|
148
|
+
local fireCount = 0
|
|
149
|
+
|
|
150
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "Part", "Target"):Subscribe(function(brio)
|
|
151
|
+
lastBrio = brio
|
|
152
|
+
fireCount = fireCount + 1
|
|
153
|
+
end)
|
|
154
|
+
|
|
155
|
+
expect(fireCount).toEqual(1)
|
|
156
|
+
local firstBrio = lastBrio
|
|
157
|
+
|
|
158
|
+
child.Parent = nil
|
|
159
|
+
|
|
160
|
+
expect(firstBrio:IsDead()).toEqual(true)
|
|
161
|
+
|
|
162
|
+
sub:Destroy()
|
|
163
|
+
end)
|
|
164
|
+
end)
|
|
165
|
+
|
|
166
|
+
describe("when child name changes to match", function()
|
|
167
|
+
it("should emit when a child is renamed to the target name", function()
|
|
168
|
+
local parent = Instance.new("Folder")
|
|
169
|
+
local child = Instance.new("Part")
|
|
170
|
+
child.Name = "Wrong"
|
|
171
|
+
child.Parent = parent
|
|
172
|
+
|
|
173
|
+
local lastBrio = nil
|
|
174
|
+
local fireCount = 0
|
|
175
|
+
|
|
176
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "Part", "Target"):Subscribe(function(brio)
|
|
177
|
+
lastBrio = brio
|
|
178
|
+
fireCount = fireCount + 1
|
|
179
|
+
end)
|
|
180
|
+
|
|
181
|
+
expect(fireCount).toEqual(0)
|
|
182
|
+
|
|
183
|
+
child.Name = "Target"
|
|
184
|
+
|
|
185
|
+
expect(fireCount).toEqual(1)
|
|
186
|
+
expect(lastBrio).never.toBeNil()
|
|
187
|
+
expect(lastBrio:GetValue()).toEqual(child)
|
|
188
|
+
|
|
189
|
+
sub:Destroy()
|
|
190
|
+
end)
|
|
191
|
+
end)
|
|
192
|
+
|
|
193
|
+
describe("when child name changes away from match", function()
|
|
194
|
+
it("should kill the brio when a child is renamed away", function()
|
|
195
|
+
local parent = Instance.new("Folder")
|
|
196
|
+
local child = Instance.new("Part")
|
|
197
|
+
child.Name = "Target"
|
|
198
|
+
child.Parent = parent
|
|
199
|
+
|
|
200
|
+
local lastBrio = nil
|
|
201
|
+
local fireCount = 0
|
|
202
|
+
|
|
203
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "Part", "Target"):Subscribe(function(brio)
|
|
204
|
+
lastBrio = brio
|
|
205
|
+
fireCount = fireCount + 1
|
|
206
|
+
end)
|
|
207
|
+
|
|
208
|
+
expect(fireCount).toEqual(1)
|
|
209
|
+
local firstBrio = lastBrio
|
|
210
|
+
|
|
211
|
+
child.Name = "NotTarget"
|
|
212
|
+
|
|
213
|
+
expect(firstBrio:IsDead()).toEqual(true)
|
|
214
|
+
|
|
215
|
+
sub:Destroy()
|
|
216
|
+
end)
|
|
217
|
+
end)
|
|
218
|
+
|
|
219
|
+
describe("with multiple matching children", function()
|
|
220
|
+
it("should emit a brio with one of the children", function()
|
|
221
|
+
local parent = Instance.new("Folder")
|
|
222
|
+
local child1 = Instance.new("Part")
|
|
223
|
+
child1.Name = "Target"
|
|
224
|
+
child1.Parent = parent
|
|
225
|
+
local child2 = Instance.new("Part")
|
|
226
|
+
child2.Name = "Target"
|
|
227
|
+
child2.Parent = parent
|
|
228
|
+
|
|
229
|
+
local lastBrio = nil
|
|
230
|
+
local fireCount = 0
|
|
231
|
+
|
|
232
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "Part", "Target"):Subscribe(function(brio)
|
|
233
|
+
lastBrio = brio
|
|
234
|
+
fireCount = fireCount + 1
|
|
235
|
+
end)
|
|
236
|
+
|
|
237
|
+
-- Should have emitted (possibly more than once as children are iterated)
|
|
238
|
+
expect(lastBrio).never.toBeNil()
|
|
239
|
+
expect(Brio.isBrio(lastBrio)).toEqual(true)
|
|
240
|
+
expect(lastBrio:IsDead()).toEqual(false)
|
|
241
|
+
|
|
242
|
+
local value = lastBrio:GetValue()
|
|
243
|
+
-- The emitted child should be one of the two matching children
|
|
244
|
+
expect(value:IsA("Part")).toEqual(true)
|
|
245
|
+
expect(value.Name).toEqual("Target")
|
|
246
|
+
|
|
247
|
+
sub:Destroy()
|
|
248
|
+
end)
|
|
249
|
+
|
|
250
|
+
it("should switch to remaining child when the emitted one is removed", function()
|
|
251
|
+
local parent = Instance.new("Folder")
|
|
252
|
+
local child1 = Instance.new("Part")
|
|
253
|
+
child1.Name = "Target"
|
|
254
|
+
child1.Parent = parent
|
|
255
|
+
local child2 = Instance.new("Part")
|
|
256
|
+
child2.Name = "Target"
|
|
257
|
+
child2.Parent = parent
|
|
258
|
+
|
|
259
|
+
local lastBrio = nil
|
|
260
|
+
|
|
261
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "Part", "Target"):Subscribe(function(brio)
|
|
262
|
+
lastBrio = brio
|
|
263
|
+
end)
|
|
264
|
+
|
|
265
|
+
local emittedChild = lastBrio:GetValue()
|
|
266
|
+
local otherChild = if emittedChild == child1 then child2 else child1
|
|
267
|
+
|
|
268
|
+
-- Remove the currently emitted child
|
|
269
|
+
emittedChild.Parent = nil
|
|
270
|
+
|
|
271
|
+
-- Should now emit the other child
|
|
272
|
+
expect(lastBrio).never.toBeNil()
|
|
273
|
+
expect(lastBrio:IsDead()).toEqual(false)
|
|
274
|
+
expect(lastBrio:GetValue()).toEqual(otherChild)
|
|
275
|
+
|
|
276
|
+
sub:Destroy()
|
|
277
|
+
end)
|
|
278
|
+
|
|
279
|
+
it("should emit nothing when all matching children are removed", function()
|
|
280
|
+
local parent = Instance.new("Folder")
|
|
281
|
+
local child1 = Instance.new("Part")
|
|
282
|
+
child1.Name = "Target"
|
|
283
|
+
child1.Parent = parent
|
|
284
|
+
local child2 = Instance.new("Part")
|
|
285
|
+
child2.Name = "Target"
|
|
286
|
+
child2.Parent = parent
|
|
287
|
+
|
|
288
|
+
local lastBrio = nil
|
|
289
|
+
|
|
290
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "Part", "Target"):Subscribe(function(brio)
|
|
291
|
+
lastBrio = brio
|
|
292
|
+
end)
|
|
293
|
+
|
|
294
|
+
expect(lastBrio).never.toBeNil()
|
|
295
|
+
|
|
296
|
+
child1.Parent = nil
|
|
297
|
+
child2.Parent = nil
|
|
298
|
+
|
|
299
|
+
-- The last brio should be dead since no matching children remain
|
|
300
|
+
expect(lastBrio:IsDead()).toEqual(true)
|
|
301
|
+
|
|
302
|
+
sub:Destroy()
|
|
303
|
+
end)
|
|
304
|
+
end)
|
|
305
|
+
|
|
306
|
+
describe("subscription cleanup", function()
|
|
307
|
+
it("should kill the brio when subscription is destroyed", function()
|
|
308
|
+
local parent = Instance.new("Folder")
|
|
309
|
+
local child = Instance.new("Part")
|
|
310
|
+
child.Name = "Target"
|
|
311
|
+
child.Parent = parent
|
|
312
|
+
|
|
313
|
+
local lastBrio = nil
|
|
314
|
+
|
|
315
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "Part", "Target"):Subscribe(function(brio)
|
|
316
|
+
lastBrio = brio
|
|
317
|
+
end)
|
|
318
|
+
|
|
319
|
+
expect(lastBrio).never.toBeNil()
|
|
320
|
+
expect(lastBrio:IsDead()).toEqual(false)
|
|
321
|
+
|
|
322
|
+
sub:Destroy()
|
|
323
|
+
|
|
324
|
+
expect(lastBrio:IsDead()).toEqual(true)
|
|
325
|
+
end)
|
|
326
|
+
end)
|
|
327
|
+
|
|
328
|
+
describe("className inheritance", function()
|
|
329
|
+
it("should match subclasses via IsA", function()
|
|
330
|
+
local parent = Instance.new("Folder")
|
|
331
|
+
local child = Instance.new("Part")
|
|
332
|
+
child.Name = "Target"
|
|
333
|
+
child.Parent = parent
|
|
334
|
+
|
|
335
|
+
local lastBrio = nil
|
|
336
|
+
local fireCount = 0
|
|
337
|
+
|
|
338
|
+
-- Part IsA BasePart, so this should match
|
|
339
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "BasePart", "Target"):Subscribe(function(brio)
|
|
340
|
+
lastBrio = brio
|
|
341
|
+
fireCount = fireCount + 1
|
|
342
|
+
end)
|
|
343
|
+
|
|
344
|
+
expect(fireCount).toEqual(1)
|
|
345
|
+
expect(lastBrio:GetValue()).toEqual(child)
|
|
346
|
+
|
|
347
|
+
sub:Destroy()
|
|
348
|
+
end)
|
|
349
|
+
end)
|
|
350
|
+
|
|
351
|
+
describe("non-matching child added then removed", function()
|
|
352
|
+
it("should not emit for non-matching children", function()
|
|
353
|
+
local parent = Instance.new("Folder")
|
|
354
|
+
local fireCount = 0
|
|
355
|
+
|
|
356
|
+
local sub = RxInstanceUtils.observeLastNamedChildBrio(parent, "Part", "Target"):Subscribe(function()
|
|
357
|
+
fireCount = fireCount + 1
|
|
358
|
+
end)
|
|
359
|
+
|
|
360
|
+
local child = Instance.new("Folder")
|
|
361
|
+
child.Name = "Target"
|
|
362
|
+
child.Parent = parent
|
|
363
|
+
child.Parent = nil
|
|
364
|
+
|
|
365
|
+
expect(fireCount).toEqual(0)
|
|
366
|
+
|
|
367
|
+
sub:Destroy()
|
|
368
|
+
end)
|
|
369
|
+
end)
|
|
370
|
+
end)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "InstanceUtilsTest",
|
|
3
|
+
"tree": {
|
|
4
|
+
"$className": "DataModel",
|
|
5
|
+
"ServerScriptService": {
|
|
6
|
+
"$properties": {
|
|
7
|
+
"LoadStringEnabled": true
|
|
8
|
+
},
|
|
9
|
+
"instanceutils": {
|
|
10
|
+
"$path": ".."
|
|
11
|
+
},
|
|
12
|
+
"Script": {
|
|
13
|
+
"$path": "scripts/Server"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
--!nonstrict
|
|
2
|
+
--[[
|
|
3
|
+
@class ServerMain
|
|
4
|
+
]]
|
|
5
|
+
local ServerScriptService = game:GetService("ServerScriptService")
|
|
6
|
+
|
|
7
|
+
local root = ServerScriptService.instanceutils
|
|
8
|
+
local loader = root:FindFirstChild("LoaderUtils", true).Parent
|
|
9
|
+
local require = require(loader).bootstrapGame(root)
|
|
10
|
+
|
|
11
|
+
local NevermoreTestRunnerUtils = require("NevermoreTestRunnerUtils")
|
|
12
|
+
|
|
13
|
+
if NevermoreTestRunnerUtils.runTestsIfNeededAsync(root) then
|
|
14
|
+
return
|
|
15
|
+
end
|