@quenty/binder 14.44.0 → 14.46.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 CHANGED
@@ -3,6 +3,16 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [14.46.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@14.45.0...@quenty/binder@14.46.0) (2026-09-02)
7
+
8
+ ### Features
9
+
10
+ - Add RxBinderUtils.observeBoundAncestor<T>() and make sure everything is using binder:ObserveInstance() for performance ([9236c34](https://github.com/Quenty/NevermoreEngine/commit/9236c343fb438d75d29bcfcbaae71025fd344b0e))
11
+
12
+ # [14.45.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@14.44.0...@quenty/binder@14.45.0) (2026-08-28)
13
+
14
+ **Note:** Version bump only for package @quenty/binder
15
+
6
16
  # [14.44.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@14.43.2...@quenty/binder@14.44.0) (2026-08-28)
7
17
 
8
18
  **Note:** Version bump only for package @quenty/binder
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/binder",
3
- "version": "14.44.0",
3
+ "version": "14.46.0",
4
4
  "description": "Utility object to Bind a class to Roblox object, and associated helper methods",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -29,10 +29,11 @@
29
29
  ],
30
30
  "dependencies": {
31
31
  "@quenty/baseobject": "10.16.0",
32
- "@quenty/brio": "14.36.0",
32
+ "@quenty/brio": "14.37.0",
33
33
  "@quenty/canceltoken": "11.25.0",
34
- "@quenty/instanceutils": "13.36.0",
35
- "@quenty/linkutils": "13.37.0",
34
+ "@quenty/instanceutils": "13.37.0",
35
+ "@quenty/jestutils": "1.1.0",
36
+ "@quenty/linkutils": "13.38.0",
36
37
  "@quenty/loader": "10.11.1",
37
38
  "@quenty/maid": "3.12.0",
38
39
  "@quenty/nevermore-test-runner": "1.6.0",
@@ -41,11 +42,10 @@
41
42
  "@quenty/servicebag": "11.21.0",
42
43
  "@quenty/signal": "7.13.2",
43
44
  "@quenty/table": "3.9.2",
44
- "@quenty/valueobject": "13.37.0",
45
45
  "@quentystudios/jest-lua": "3.10.0-quenty.2"
46
46
  },
47
47
  "publishConfig": {
48
48
  "access": "public"
49
49
  },
50
- "gitHead": "f75f93d5b2ac51cf7da3b7599788dcce31fd8a29"
50
+ "gitHead": "278f4ca25486a8ba0601704b27a11da8c77499c9"
51
51
  }
@@ -49,6 +49,6 @@ describe("Binder load abandonment", function()
49
49
  expect(binder:Get(inst)).toBeNil()
50
50
  expect(constructed).toEqual(1)
51
51
 
52
- controller.destroy()
52
+ controller:Destroy()
53
53
  end)
54
54
  end)
@@ -43,7 +43,7 @@ describe("Binder:ObserveBrio()", function()
43
43
  expect(brios[1]:GetValue()).toEqual(class)
44
44
 
45
45
  sub:Destroy()
46
- controller.destroy()
46
+ controller:Destroy()
47
47
  end)
48
48
 
49
49
  it("emits immediately when the instance is already bound", function()
@@ -67,7 +67,7 @@ describe("Binder:ObserveBrio()", function()
67
67
  expect(brios[1]:GetValue()).toEqual(class)
68
68
 
69
69
  sub:Destroy()
70
- controller.destroy()
70
+ controller:Destroy()
71
71
  end)
72
72
 
73
73
  it("kills the emitted brio when the instance unbinds", function()
@@ -93,7 +93,7 @@ describe("Binder:ObserveBrio()", function()
93
93
  expect(brios[1]:IsDead()).toEqual(true)
94
94
 
95
95
  sub:Destroy()
96
- controller.destroy()
96
+ controller:Destroy()
97
97
  end)
98
98
 
99
99
  it("emits a fresh live brio when the instance rebinds", function()
@@ -125,7 +125,7 @@ describe("Binder:ObserveBrio()", function()
125
125
  expect(brios[2]:GetValue()).toEqual(class)
126
126
 
127
127
  sub:Destroy()
128
- controller.destroy()
128
+ controller:Destroy()
129
129
  end)
130
130
  end)
131
131
 
@@ -153,7 +153,7 @@ describe("Binder:ObserveAllBrio()", function()
153
153
  expect(values[binder:Get(instB)]).toEqual(true)
154
154
 
155
155
  sub:Destroy()
156
- controller.destroy()
156
+ controller:Destroy()
157
157
  end)
158
158
 
159
159
  it("emits a brio when a new class is added", function()
@@ -178,7 +178,7 @@ describe("Binder:ObserveAllBrio()", function()
178
178
  expect(brios[1]:GetValue()).toEqual(binder:Get(inst))
179
179
 
180
180
  sub:Destroy()
181
- controller.destroy()
181
+ controller:Destroy()
182
182
  end)
183
183
 
184
184
  it("kills the brio when the class is removed", function()
@@ -204,6 +204,6 @@ describe("Binder:ObserveAllBrio()", function()
204
204
  expect(brios[1]:IsDead()).toEqual(true)
205
205
 
206
206
  sub:Destroy()
207
- controller.destroy()
207
+ controller:Destroy()
208
208
  end)
209
209
  end)
@@ -58,7 +58,7 @@ describe("Binder.new()", function()
58
58
  expect(class.a).toEqual("a")
59
59
  expect(class.b).toEqual("b")
60
60
 
61
- controller.destroy()
61
+ controller:Destroy()
62
62
  end)
63
63
  end)
64
64
 
@@ -109,7 +109,7 @@ describe("Binder constructor variants", function()
109
109
  expect(class.kind).toEqual("function")
110
110
  expect(class.instance).toEqual(inst)
111
111
 
112
- controller.destroy()
112
+ controller:Destroy()
113
113
  end)
114
114
 
115
115
  it("supports a class table with .new", function()
@@ -126,7 +126,7 @@ describe("Binder constructor variants", function()
126
126
  assert(ok, "Never bound")
127
127
  expect(class.instance).toEqual(inst)
128
128
 
129
- controller.destroy()
129
+ controller:Destroy()
130
130
  end)
131
131
 
132
132
  it("supports a provider table with :Create", function()
@@ -147,7 +147,7 @@ describe("Binder constructor variants", function()
147
147
  assert(ok, "Never bound")
148
148
  expect(class.kind).toEqual("provider")
149
149
 
150
- controller.destroy()
150
+ controller:Destroy()
151
151
  end)
152
152
  end)
153
153
 
@@ -192,7 +192,7 @@ describe("Binder binding via ServiceBag", function()
192
192
 
193
193
  expect(binder:Get(inst)).never.toBeNil()
194
194
 
195
- controller.destroy()
195
+ controller:Destroy()
196
196
  end)
197
197
 
198
198
  it("binds instances tagged after start", function()
@@ -207,7 +207,7 @@ describe("Binder binding via ServiceBag", function()
207
207
  local ok = binder:Promise(inst):Yield()
208
208
  expect(ok).toEqual(true)
209
209
 
210
- controller.destroy()
210
+ controller:Destroy()
211
211
  end)
212
212
  end)
213
213
 
@@ -220,7 +220,7 @@ describe("Binder:Get()", function()
220
220
 
221
221
  expect(binder:Get(controller.newInstance())).toBeNil()
222
222
 
223
- controller.destroy()
223
+ controller:Destroy()
224
224
  end)
225
225
 
226
226
  it("throws when passed a non-instance", function()
@@ -233,7 +233,7 @@ describe("Binder:Get()", function()
233
233
  binder:Get(5 :: any)
234
234
  end).toThrow()
235
235
 
236
- controller.destroy()
236
+ controller:Destroy()
237
237
  end)
238
238
  end)
239
239
 
@@ -251,7 +251,7 @@ describe("Binder tagging", function()
251
251
  binder:Untag(inst)
252
252
  expect(binder:HasTag(inst)).toEqual(false)
253
253
 
254
- controller.destroy()
254
+ controller:Destroy()
255
255
  end)
256
256
 
257
257
  it("Bind tags and Unbind untags on the server", function()
@@ -270,7 +270,7 @@ describe("Binder tagging", function()
270
270
  binder:Unbind(inst)
271
271
  expect(binder:HasTag(inst)).toEqual(false)
272
272
 
273
- controller.destroy()
273
+ controller:Destroy()
274
274
  end)
275
275
  end)
276
276
 
@@ -325,7 +325,7 @@ describe("Binder:GetAll() / GetAllSet()", function()
325
325
  expect(set[binder:Get(instA)]).toEqual(true)
326
326
  expect(set[binder:Get(instB)]).toEqual(true)
327
327
 
328
- controller.destroy()
328
+ controller:Destroy()
329
329
  end)
330
330
  end)
331
331
 
@@ -340,7 +340,7 @@ describe("Binder signals", function()
340
340
  expect(binder:GetClassRemovingSignal()).toEqual(binder:GetClassRemovingSignal())
341
341
  expect(binder:GetClassRemovedSignal()).toEqual(binder:GetClassRemovedSignal())
342
342
 
343
- controller.destroy()
343
+ controller:Destroy()
344
344
  end)
345
345
 
346
346
  it("fires the added signal with the class and instance", function()
@@ -362,7 +362,7 @@ describe("Binder signals", function()
362
362
  expect(firedInst).toEqual(inst)
363
363
  expect(firedClass).toEqual(binder:Get(inst))
364
364
 
365
- controller.destroy()
365
+ controller:Destroy()
366
366
  end)
367
367
 
368
368
  it("fires removing then removed on unbind", function()
@@ -389,7 +389,7 @@ describe("Binder signals", function()
389
389
  expect(order[1]).toEqual("removing")
390
390
  expect(order[2]).toEqual("removed")
391
391
 
392
- controller.destroy()
392
+ controller:Destroy()
393
393
  end)
394
394
 
395
395
  it("destroys the bound class when it is removed", function()
@@ -408,7 +408,7 @@ describe("Binder signals", function()
408
408
 
409
409
  expect(class.destroyed).toEqual(true)
410
410
 
411
- controller.destroy()
411
+ controller:Destroy()
412
412
  end)
413
413
  end)
414
414
 
@@ -440,7 +440,7 @@ describe("Binder:ObserveInstance()", function()
440
440
 
441
441
  cleanup()
442
442
 
443
- controller.destroy()
443
+ controller:Destroy()
444
444
  end)
445
445
 
446
446
  it("returns a cleanup that stops future callbacks", function()
@@ -462,7 +462,7 @@ describe("Binder:ObserveInstance()", function()
462
462
 
463
463
  expect(count).toEqual(0)
464
464
 
465
- controller.destroy()
465
+ controller:Destroy()
466
466
  end)
467
467
 
468
468
  it("throws for a non-instance or non-function", function()
@@ -478,7 +478,7 @@ describe("Binder:ObserveInstance()", function()
478
478
  binder:ObserveInstance(controller.newInstance(), 5 :: any)
479
479
  end).toThrow()
480
480
 
481
- controller.destroy()
481
+ controller:Destroy()
482
482
  end)
483
483
  end)
484
484
 
@@ -507,7 +507,7 @@ describe("Binder:Observe()", function()
507
507
  expect(emissions[2].value).toEqual(binder:Get(inst))
508
508
 
509
509
  sub:Destroy()
510
- controller.destroy()
510
+ controller:Destroy()
511
511
  end)
512
512
  end)
513
513
 
@@ -524,7 +524,7 @@ describe("Binder:Promise()", function()
524
524
  local promise = binder:Promise(inst)
525
525
  expect(promise:IsFulfilled()).toEqual(true)
526
526
 
527
- controller.destroy()
527
+ controller:Destroy()
528
528
  end)
529
529
 
530
530
  it("throws when passed a non-instance", function()
@@ -537,7 +537,7 @@ describe("Binder:Promise()", function()
537
537
  binder:Promise(5 :: any)
538
538
  end).toThrow()
539
539
 
540
- controller.destroy()
540
+ controller:Destroy()
541
541
  end)
542
542
  end)
543
543
 
@@ -561,7 +561,7 @@ describe("Binder:_add() dedupe", function()
561
561
 
562
562
  expect(constructed).toEqual(1)
563
563
 
564
- controller.destroy()
564
+ controller:Destroy()
565
565
  end)
566
566
  end)
567
567
 
@@ -581,6 +581,6 @@ describe("Binder teardown", function()
581
581
 
582
582
  expect(class.destroyed).toEqual(true)
583
583
 
584
- controller.destroy()
584
+ controller:Destroy()
585
585
  end)
586
586
  end)
@@ -8,6 +8,8 @@ local require = require(script.Parent.loader).load(script)
8
8
  local Binder = require("Binder")
9
9
  local BinderGroup = require("BinderGroup")
10
10
  local Jest = require("Jest")
11
+ local JestUtils = require("JestUtils")
12
+ local Maid = require("Maid")
11
13
 
12
14
  local describe = Jest.Globals.describe
13
15
  local expect = Jest.Globals.expect
@@ -16,6 +18,8 @@ local it = Jest.Globals.it
16
18
  local tagCounter = 0
17
19
 
18
20
  local function setup()
21
+ local maid = Maid.new()
22
+
19
23
  local binders: { any } = {}
20
24
 
21
25
  local function newBinder(): Binder.Binder<any>
@@ -27,16 +31,24 @@ local function setup()
27
31
  return binder
28
32
  end
29
33
 
30
- return {
34
+ maid:GiveTask(function()
35
+ for _, binder in binders do
36
+ pcall(function()
37
+ binder:Destroy()
38
+ end)
39
+ end
40
+ end)
41
+
42
+ local controller = {
31
43
  newBinder = newBinder,
32
- destroy = function()
33
- for _, binder in binders do
34
- pcall(function()
35
- binder:Destroy()
36
- end)
37
- end
44
+ Destroy = function(_self)
45
+ maid:DoCleaning()
38
46
  end,
39
47
  }
48
+
49
+ maid:GiveTask(JestUtils.afterThis(controller))
50
+
51
+ return controller
40
52
  end
41
53
 
42
54
  describe("BinderGroup.new()", function()
@@ -49,7 +61,7 @@ describe("BinderGroup.new()", function()
49
61
 
50
62
  expect(#group:GetBinders()).toEqual(2)
51
63
 
52
- controller.destroy()
64
+ controller:Destroy()
53
65
  end)
54
66
 
55
67
  it("constructs empty", function()
@@ -68,7 +80,7 @@ describe("BinderGroup:Add()", function()
68
80
 
69
81
  expect(group:GetBinders()[1]).toEqual(binder)
70
82
 
71
- controller.destroy()
83
+ controller:Destroy()
72
84
  end)
73
85
 
74
86
  it("fires BinderAdded with the added binder", function()
@@ -85,7 +97,7 @@ describe("BinderGroup:Add()", function()
85
97
 
86
98
  expect(fired).toEqual(binder)
87
99
 
88
- controller.destroy()
100
+ controller:Destroy()
89
101
  end)
90
102
 
91
103
  it("throws when the value is not a binder", function()
@@ -111,7 +123,7 @@ describe("BinderGroup constructor validation", function()
111
123
 
112
124
  expect(validated[1]).toEqual(binder:GetConstructor())
113
125
 
114
- controller.destroy()
126
+ controller:Destroy()
115
127
  end)
116
128
 
117
129
  it("throws when the constructor fails validation", function()
@@ -126,7 +138,7 @@ describe("BinderGroup constructor validation", function()
126
138
  group:Add(binder)
127
139
  end).toThrow()
128
140
 
129
- controller.destroy()
141
+ controller:Destroy()
130
142
  end)
131
143
  end)
132
144
 
@@ -139,7 +151,7 @@ describe("BinderGroup:AddList()", function()
139
151
 
140
152
  expect(#group:GetBinders()).toEqual(2)
141
153
 
142
- controller.destroy()
154
+ controller:Destroy()
143
155
  end)
144
156
 
145
157
  it("throws on a non-table argument", function()
@@ -7,7 +7,7 @@
7
7
 
8
8
  Tags are global and the test place is shared across a batch run, so every binder gets a distinct
9
9
  tag from a single module-level counter -- shared across every spec file that requires this module,
10
- so tags never collide between files -- and each controller cleans up after itself via `destroy()`.
10
+ so tags never collide between files -- and each controller cleans up after itself via `Destroy()`.
11
11
 
12
12
  @class BinderTestUtils
13
13
  ]=]
@@ -16,6 +16,8 @@ local require = require(script.Parent.loader).load(script)
16
16
 
17
17
  local Binder = require("Binder")
18
18
  local BinderProvider = require("BinderProvider")
19
+ local JestUtils = require("JestUtils")
20
+ local Maid = require("Maid")
19
21
  local ServiceBag = require("ServiceBag")
20
22
 
21
23
  local BinderTestUtils = {}
@@ -74,11 +76,11 @@ end
74
76
  --[=[
75
77
  Builds the controller the Binder specs share. Register binders with `addBinder`, boot them all at
76
78
  once through a ServiceBag with `boot`, create adornees with `newInstance`, and tear everything down
77
- with `destroy` (or just the service bag with `destroyServiceBag`).
79
+ with `Destroy` (or just the service bag with `destroyServiceBag`).
78
80
 
79
81
  Fields: `container`.
80
82
  Builders: `addBinder(constructor, ...)` -> Binder, `newInstance(parent?, className?)` -> Instance.
81
- Lifecycle: `boot()`, `destroyServiceBag()`, `destroy()`.
83
+ Lifecycle: `boot()`, `destroyServiceBag()`, `Destroy()`.
82
84
  Helpers: `uniqueTag()` -> string.
83
85
 
84
86
  @return { ... }
@@ -87,6 +89,8 @@ function BinderTestUtils.setup()
87
89
  specCounter += 1
88
90
  local suffix = specCounter
89
91
 
92
+ local maid = Maid.new()
93
+
90
94
  local serviceBag = ServiceBag.new()
91
95
  local serviceBagDestroyed = false
92
96
 
@@ -141,23 +145,31 @@ function BinderTestUtils.setup()
141
145
  end
142
146
  end
143
147
 
144
- return {
148
+ maid:GiveTask(function()
149
+ destroyServiceBag()
150
+ for _, inst in instances do
151
+ pcall(function()
152
+ inst:Destroy()
153
+ end)
154
+ end
155
+ container:Destroy()
156
+ end)
157
+
158
+ local controller = {
145
159
  container = container,
146
160
  uniqueTag = uniqueTag,
147
161
  addBinder = addBinder,
148
162
  boot = boot,
149
163
  newInstance = newInstance,
150
164
  destroyServiceBag = destroyServiceBag,
151
- destroy = function()
152
- destroyServiceBag()
153
- for _, inst in instances do
154
- pcall(function()
155
- inst:Destroy()
156
- end)
157
- end
158
- container:Destroy()
165
+ Destroy = function(_self)
166
+ maid:DoCleaning()
159
167
  end,
160
168
  }
169
+
170
+ maid:GiveTask(JestUtils.afterThis(controller))
171
+
172
+ return controller
161
173
  end
162
174
 
163
175
  return BinderTestUtils
@@ -9,6 +9,8 @@ local Binder = require("Binder")
9
9
  local BinderProvider = require("BinderProvider")
10
10
  local BinderUtils = require("BinderUtils")
11
11
  local Jest = require("Jest")
12
+ local JestUtils = require("JestUtils")
13
+ local Maid = require("Maid")
12
14
  local ServiceBag = require("ServiceBag")
13
15
 
14
16
  local describe = Jest.Globals.describe
@@ -29,6 +31,8 @@ local function makeClass()
29
31
  end
30
32
 
31
33
  local function setup()
34
+ local maid = Maid.new()
35
+
32
36
  specCounter += 1
33
37
  local suffix = specCounter
34
38
 
@@ -37,7 +41,7 @@ local function setup()
37
41
  container.Name = "BinderUtilsSpecContainer"
38
42
  container.Parent = workspace
39
43
 
40
- local instances = {}
44
+ local instances: { Instance } = {}
41
45
  local pendingBinders: { any } = {}
42
46
  local tagCounter = 0
43
47
  local booted = false
@@ -72,21 +76,29 @@ local function setup()
72
76
  serviceBag:Start()
73
77
  end
74
78
 
75
- return {
79
+ maid:GiveTask(function()
80
+ serviceBag:Destroy()
81
+ for _, inst in instances do
82
+ pcall(function()
83
+ inst:Destroy()
84
+ end)
85
+ end
86
+ container:Destroy()
87
+ end)
88
+
89
+ local controller = {
76
90
  container = container,
77
91
  newBinder = newBinder,
78
92
  newInstance = newInstance,
79
93
  boot = boot,
80
- destroy = function()
81
- serviceBag:Destroy()
82
- for _, inst in instances do
83
- pcall(function()
84
- inst:Destroy()
85
- end)
86
- end
87
- container:Destroy()
94
+ Destroy = function(_self)
95
+ maid:DoCleaning()
88
96
  end,
89
97
  }
98
+
99
+ maid:GiveTask(JestUtils.afterThis(controller))
100
+
101
+ return controller
90
102
  end
91
103
 
92
104
  describe("BinderUtils.findFirstAncestor()", function()
@@ -104,7 +116,7 @@ describe("BinderUtils.findFirstAncestor()", function()
104
116
 
105
117
  expect(BinderUtils.findFirstAncestor(binder, child)).toEqual(binder:Get(grandparent))
106
118
 
107
- controller.destroy()
119
+ controller:Destroy()
108
120
  end)
109
121
 
110
122
  it("returns nil when no ancestor is bound", function()
@@ -117,7 +129,7 @@ describe("BinderUtils.findFirstAncestor()", function()
117
129
 
118
130
  expect(BinderUtils.findFirstAncestor(binder, child)).toBeNil()
119
131
 
120
- controller.destroy()
132
+ controller:Destroy()
121
133
  end)
122
134
 
123
135
  it("throws for a non-instance child", function()
@@ -129,7 +141,7 @@ describe("BinderUtils.findFirstAncestor()", function()
129
141
  BinderUtils.findFirstAncestor(binder, 5 :: any)
130
142
  end).toThrow()
131
143
 
132
- controller.destroy()
144
+ controller:Destroy()
133
145
  end)
134
146
  end)
135
147
 
@@ -148,7 +160,7 @@ describe("BinderUtils.findFirstChild()", function()
148
160
  expect(BinderUtils.findFirstChild(binder, parent)).toEqual(binder:Get(boundChild))
149
161
  expect(binder:Get(unboundChild)).toBeNil()
150
162
 
151
- controller.destroy()
163
+ controller:Destroy()
152
164
  end)
153
165
 
154
166
  it("returns nil when no child is bound", function()
@@ -161,7 +173,7 @@ describe("BinderUtils.findFirstChild()", function()
161
173
 
162
174
  expect(BinderUtils.findFirstChild(binder, parent)).toBeNil()
163
175
 
164
- controller.destroy()
176
+ controller:Destroy()
165
177
  end)
166
178
  end)
167
179
 
@@ -181,7 +193,7 @@ describe("BinderUtils.getChildren()", function()
181
193
 
182
194
  expect(#BinderUtils.getChildren(binder, parent)).toEqual(2)
183
195
 
184
- controller.destroy()
196
+ controller:Destroy()
185
197
  end)
186
198
 
187
199
  it("does not include bound descendants deeper than one level", function()
@@ -197,7 +209,7 @@ describe("BinderUtils.getChildren()", function()
197
209
 
198
210
  expect(#BinderUtils.getChildren(binder, parent)).toEqual(0)
199
211
 
200
- controller.destroy()
212
+ controller:Destroy()
201
213
  end)
202
214
  end)
203
215
 
@@ -216,7 +228,7 @@ describe("BinderUtils.getDescendants()", function()
216
228
 
217
229
  expect(#BinderUtils.getDescendants(binder, parent)).toEqual(2)
218
230
 
219
- controller.destroy()
231
+ controller:Destroy()
220
232
  end)
221
233
  end)
222
234
 
@@ -232,7 +244,7 @@ describe("BinderUtils.mapBinderListToTable()", function()
232
244
  expect(map[binderA:GetTag()]).toEqual(binderA)
233
245
  expect(map[binderB:GetTag()]).toEqual(binderB)
234
246
 
235
- controller.destroy()
247
+ controller:Destroy()
236
248
  end)
237
249
  end)
238
250
 
@@ -253,7 +265,7 @@ describe("BinderUtils.getMappedFromList()", function()
253
265
 
254
266
  expect(#objects).toEqual(2)
255
267
 
256
- controller.destroy()
268
+ controller:Destroy()
257
269
  end)
258
270
  end)
259
271
 
@@ -273,7 +285,7 @@ describe("BinderUtils.getChildrenOfBinders()", function()
273
285
 
274
286
  expect(#BinderUtils.getChildrenOfBinders({ binderA, binderB }, parent)).toEqual(2)
275
287
 
276
- controller.destroy()
288
+ controller:Destroy()
277
289
  end)
278
290
  end)
279
291
 
@@ -295,7 +307,7 @@ describe("BinderUtils.getLinkedChildren()", function()
295
307
  expect(#objects).toEqual(1)
296
308
  expect(objects[1]).toEqual(binder:Get(target))
297
309
 
298
- controller.destroy()
310
+ controller:Destroy()
299
311
  end)
300
312
 
301
313
  it("ignores links whose name does not match", function()
@@ -313,7 +325,7 @@ describe("BinderUtils.getLinkedChildren()", function()
313
325
 
314
326
  expect(#BinderUtils.getLinkedChildren(binder, "Link", parent)).toEqual(0)
315
327
 
316
- controller.destroy()
328
+ controller:Destroy()
317
329
  end)
318
330
 
319
331
  it("deduplicates when two links point to the same bound target", function()
@@ -333,6 +345,6 @@ describe("BinderUtils.getLinkedChildren()", function()
333
345
 
334
346
  expect(#BinderUtils.getLinkedChildren(binder, "Link", parent)).toEqual(1)
335
347
 
336
- controller.destroy()
348
+ controller:Destroy()
337
349
  end)
338
350
  end)