expo-modules-jsi 57.0.0 → 57.0.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 +21 -0
- package/apple/Sources/ExpoModulesJSI/Coding/JavaScriptCodable+Date.swift +70 -0
- package/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptRef.swift +12 -0
- package/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptRuntime.swift +83 -1
- package/apple/Sources/ExpoModulesJSI/Runtime/LongLivedObjectCollection.swift +46 -0
- package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptError.swift +15 -0
- package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptPromise.swift +89 -31
- package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptValue.swift +4 -2
- package/apple/Sources/ExpoModulesJSI-Cxx/include/JSIUtils.h +10 -0
- package/apple/Sources/ExpoModulesJSI-Cxx/include/RuntimeScheduler.h +3 -2
- package/apple/Tests/JavaScriptCodableDateTests.swift +270 -0
- package/apple/Tests/JavaScriptErrorTests.swift +33 -0
- package/apple/Tests/JavaScriptPromiseTests.swift +125 -0
- package/apple/Tests/JavaScriptRuntimeTests.swift +67 -0
- package/apple/Tests/LongLivedObjectCollectionTests.swift +228 -0
- package/package.json +2 -2
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import ExpoModulesJSI
|
|
2
|
+
import Testing
|
|
3
|
+
|
|
4
|
+
@Suite
|
|
5
|
+
@JavaScriptActor
|
|
6
|
+
struct LongLivedObjectCollectionTests {
|
|
7
|
+
/// Minimal conformer that counts how many times `allowRelease()` was called, so tests can assert
|
|
8
|
+
/// it fires exactly once (and not at all on the remove path).
|
|
9
|
+
final class TrackedObject: LongLivedObject {
|
|
10
|
+
private(set) var releaseCount = 0
|
|
11
|
+
|
|
12
|
+
func allowRelease() {
|
|
13
|
+
releaseCount += 1
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// MARK: - add / remove
|
|
18
|
+
|
|
19
|
+
@Test
|
|
20
|
+
func `a new collection is empty`() {
|
|
21
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
22
|
+
|
|
23
|
+
#expect(collection.count == 0)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@Test
|
|
27
|
+
func `add registers the object`() {
|
|
28
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
29
|
+
|
|
30
|
+
collection.add(TrackedObject())
|
|
31
|
+
|
|
32
|
+
#expect(collection.count == 1)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Test
|
|
36
|
+
func `remove deregisters the object`() {
|
|
37
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
38
|
+
let object = TrackedObject()
|
|
39
|
+
|
|
40
|
+
collection.add(object)
|
|
41
|
+
collection.remove(object)
|
|
42
|
+
|
|
43
|
+
#expect(collection.count == 0)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@Test
|
|
47
|
+
func `remove does not call allowRelease`() {
|
|
48
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
49
|
+
let object = TrackedObject()
|
|
50
|
+
|
|
51
|
+
collection.add(object)
|
|
52
|
+
collection.remove(object)
|
|
53
|
+
|
|
54
|
+
#expect(object.releaseCount == 0)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@Test
|
|
58
|
+
func `removing an object that was never added is a no-op`() {
|
|
59
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
60
|
+
let added = TrackedObject()
|
|
61
|
+
let neverAdded = TrackedObject()
|
|
62
|
+
|
|
63
|
+
collection.add(added)
|
|
64
|
+
collection.remove(neverAdded)
|
|
65
|
+
|
|
66
|
+
#expect(collection.count == 1)
|
|
67
|
+
#expect(neverAdded.releaseCount == 0)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@Test
|
|
71
|
+
func `removing one object leaves the others registered`() {
|
|
72
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
73
|
+
let first = TrackedObject()
|
|
74
|
+
let second = TrackedObject()
|
|
75
|
+
|
|
76
|
+
collection.add(first)
|
|
77
|
+
collection.add(second)
|
|
78
|
+
collection.remove(first)
|
|
79
|
+
|
|
80
|
+
#expect(collection.count == 1)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// MARK: - identity semantics
|
|
84
|
+
|
|
85
|
+
@Test
|
|
86
|
+
func `distinct objects are distinct entries`() {
|
|
87
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
88
|
+
|
|
89
|
+
collection.add(TrackedObject())
|
|
90
|
+
collection.add(TrackedObject())
|
|
91
|
+
|
|
92
|
+
#expect(collection.count == 2)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@Test
|
|
96
|
+
func `adding the same object twice keeps a single entry`() {
|
|
97
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
98
|
+
let object = TrackedObject()
|
|
99
|
+
|
|
100
|
+
collection.add(object)
|
|
101
|
+
collection.add(object)
|
|
102
|
+
|
|
103
|
+
#expect(collection.count == 1)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@Test
|
|
107
|
+
func `re-adding after remove registers again`() {
|
|
108
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
109
|
+
let object = TrackedObject()
|
|
110
|
+
|
|
111
|
+
collection.add(object)
|
|
112
|
+
collection.remove(object)
|
|
113
|
+
collection.add(object)
|
|
114
|
+
|
|
115
|
+
#expect(collection.count == 1)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// MARK: - clear
|
|
119
|
+
|
|
120
|
+
@Test
|
|
121
|
+
func `clear empties the collection`() {
|
|
122
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
123
|
+
|
|
124
|
+
collection.add(TrackedObject())
|
|
125
|
+
collection.add(TrackedObject())
|
|
126
|
+
collection.clear()
|
|
127
|
+
|
|
128
|
+
#expect(collection.count == 0)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@Test
|
|
132
|
+
func `clear calls allowRelease exactly once on every survivor`() {
|
|
133
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
134
|
+
let first = TrackedObject()
|
|
135
|
+
let second = TrackedObject()
|
|
136
|
+
|
|
137
|
+
collection.add(first)
|
|
138
|
+
collection.add(second)
|
|
139
|
+
collection.clear()
|
|
140
|
+
|
|
141
|
+
#expect(first.releaseCount == 1)
|
|
142
|
+
#expect(second.releaseCount == 1)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@Test
|
|
146
|
+
func `clear does not call allowRelease on a removed object`() {
|
|
147
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
148
|
+
let removed = TrackedObject()
|
|
149
|
+
let survivor = TrackedObject()
|
|
150
|
+
|
|
151
|
+
collection.add(removed)
|
|
152
|
+
collection.add(survivor)
|
|
153
|
+
collection.remove(removed)
|
|
154
|
+
collection.clear()
|
|
155
|
+
|
|
156
|
+
#expect(removed.releaseCount == 0)
|
|
157
|
+
#expect(survivor.releaseCount == 1)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@Test
|
|
161
|
+
func `clear on an empty collection is a no-op`() {
|
|
162
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
163
|
+
|
|
164
|
+
collection.clear()
|
|
165
|
+
|
|
166
|
+
#expect(collection.count == 0)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
@Test
|
|
170
|
+
func `the collection is reusable after clear`() {
|
|
171
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
172
|
+
|
|
173
|
+
collection.add(TrackedObject())
|
|
174
|
+
collection.clear()
|
|
175
|
+
collection.add(TrackedObject())
|
|
176
|
+
|
|
177
|
+
#expect(collection.count == 1)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// MARK: - ownership
|
|
181
|
+
|
|
182
|
+
@Test
|
|
183
|
+
func `the collection stops retaining an object after clear`() {
|
|
184
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
185
|
+
weak var weakObject: TrackedObject?
|
|
186
|
+
|
|
187
|
+
do {
|
|
188
|
+
let object = TrackedObject()
|
|
189
|
+
weakObject = object
|
|
190
|
+
collection.add(object)
|
|
191
|
+
collection.clear()
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// With no external strong reference and the collection's own reference dropped by `clear()`,
|
|
195
|
+
// the object must have been deallocated.
|
|
196
|
+
#expect(weakObject == nil)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@Test
|
|
200
|
+
func `the collection stops retaining an object after remove`() {
|
|
201
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
202
|
+
weak var weakObject: TrackedObject?
|
|
203
|
+
|
|
204
|
+
do {
|
|
205
|
+
let object = TrackedObject()
|
|
206
|
+
weakObject = object
|
|
207
|
+
collection.add(object)
|
|
208
|
+
collection.remove(object)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
#expect(weakObject == nil)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
@Test
|
|
215
|
+
func `the collection retains a registered object`() {
|
|
216
|
+
let collection = JavaScriptRuntime().longLivedObjects
|
|
217
|
+
weak var weakObject: TrackedObject?
|
|
218
|
+
|
|
219
|
+
do {
|
|
220
|
+
let object = TrackedObject()
|
|
221
|
+
weakObject = object
|
|
222
|
+
collection.add(object)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// The external strong reference is gone, but the collection still holds one.
|
|
226
|
+
#expect(weakObject != nil)
|
|
227
|
+
}
|
|
228
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-jsi",
|
|
3
|
-
"version": "57.0.
|
|
3
|
+
"version": "57.0.2",
|
|
4
4
|
"description": "The JavaScript Interface for Expo Modules",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"sideEffects": [],
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"./apple/scripts/test.sh"
|
|
42
42
|
]
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "70af1caf83d8a324b46e02e18cd5c8c4e310da20",
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "apple/scripts/build-xcframework.sh",
|
|
47
47
|
"swift:format": "../../scripts/swift-format.sh",
|