expo-modules-core 0.7.0 → 0.8.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.
Files changed (124) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +1 -1
  3. package/android/ExpoModulesCorePlugin.gradle +15 -0
  4. package/android/build.gradle +46 -32
  5. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +5 -5
  6. package/android/src/main/java/expo/modules/adapters/react/services/UIManagerModuleWrapper.java +13 -0
  7. package/android/src/main/java/expo/modules/core/ViewManager.java +9 -0
  8. package/android/src/main/java/expo/modules/core/interfaces/JavaScriptContextProvider.java +4 -0
  9. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +37 -1
  10. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +19 -0
  11. package/android/src/main/java/expo/modules/core/interfaces/services/UIManager.java +2 -0
  12. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +13 -5
  13. package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +2 -13
  14. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +11 -5
  15. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +5 -1
  16. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +17 -0
  17. package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallback.kt +14 -3
  18. package/android/src/main/java/expo/modules/kotlin/events/EventEmitter.kt +13 -0
  19. package/android/src/main/java/expo/modules/kotlin/events/KModuleEventEmitterWrapper.kt +102 -0
  20. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +25 -1
  21. package/android/src/main/java/expo/modules/kotlin/{methods/AnyMethod.kt → functions/AnyFunction.kt} +6 -5
  22. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +15 -0
  23. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +61 -0
  24. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +15 -0
  25. package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +36 -0
  26. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +14 -0
  27. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +176 -27
  28. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +2 -2
  29. package/android/src/main/java/expo/modules/kotlin/records/FieldValidator.kt +139 -0
  30. package/android/src/main/java/expo/modules/kotlin/records/Record.kt +0 -39
  31. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +59 -10
  32. package/android/src/main/java/expo/modules/kotlin/records/Required.kt +5 -0
  33. package/android/src/main/java/expo/modules/kotlin/records/ValidationBinder.kt +110 -0
  34. package/android/src/main/java/expo/modules/kotlin/records/Validators.kt +61 -0
  35. package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverter.kt +35 -0
  36. package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverterHelper.kt +148 -0
  37. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +9 -1
  38. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +49 -0
  39. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinition.kt +18 -0
  40. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +64 -0
  41. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +4 -1
  42. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +15 -2
  43. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +3 -0
  44. package/build/NativeModulesProxy.native.d.ts +0 -4
  45. package/build/NativeModulesProxy.native.d.ts.map +1 -1
  46. package/build/NativeModulesProxy.native.js +1 -14
  47. package/build/NativeModulesProxy.native.js.map +1 -1
  48. package/build/NativeModulesProxy.types.d.ts +0 -3
  49. package/build/NativeModulesProxy.types.d.ts.map +1 -1
  50. package/build/NativeModulesProxy.types.js.map +1 -1
  51. package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
  52. package/build/NativeViewManagerAdapter.native.js +9 -33
  53. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  54. package/build/sweet/NativeErrorManager.js +1 -1
  55. package/build/sweet/NativeErrorManager.js.map +1 -1
  56. package/ios/AppDelegates/EXAppDelegatesLoader.m +4 -8
  57. package/ios/AppDelegates/ExpoAppDelegate.swift +4 -10
  58. package/ios/EXAppDefines.h +1 -0
  59. package/ios/EXAppDefines.m +6 -0
  60. package/ios/EXUtilities.h +2 -0
  61. package/ios/EXUtilities.m +12 -0
  62. package/ios/ExpoModulesCore.h +4 -0
  63. package/ios/ExpoModulesCore.podspec +4 -2
  64. package/ios/Interfaces/FileSystem/EXFileSystemInterface.h +1 -1
  65. package/ios/Interfaces/TaskManager/EXTaskServiceInterface.h +1 -0
  66. package/ios/JSI/{JSIConversions.h → EXJSIConversions.h} +4 -1
  67. package/ios/JSI/{JSIConversions.mm → EXJSIConversions.mm} +16 -5
  68. package/ios/JSI/{JSIInstaller.h → EXJSIInstaller.h} +3 -3
  69. package/ios/JSI/EXJSIInstaller.mm +17 -0
  70. package/ios/JSI/{ExpoModulesProxySpec.h → EXJSIUtils.h} +0 -9
  71. package/ios/JSI/{ExpoModulesProxySpec.mm → EXJSIUtils.mm} +4 -48
  72. package/ios/JSI/EXJavaScriptObject.h +97 -0
  73. package/ios/JSI/EXJavaScriptObject.mm +121 -0
  74. package/ios/JSI/{JavaScriptRuntime.h → EXJavaScriptRuntime.h} +27 -8
  75. package/ios/JSI/EXJavaScriptRuntime.mm +153 -0
  76. package/ios/JSI/EXJavaScriptValue.h +57 -0
  77. package/ios/JSI/EXJavaScriptValue.mm +166 -0
  78. package/ios/JSI/ExpoModulesHostObject.mm +2 -1
  79. package/ios/JSI/JavaScriptRuntime.swift +32 -0
  80. package/ios/JSI/JavaScriptValue.swift +94 -0
  81. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +1 -11
  82. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +2 -2
  83. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +24 -22
  84. package/ios/ReactDelegates/EXReactCompatibleHelpers.h +18 -0
  85. package/ios/ReactDelegates/EXReactCompatibleHelpers.m +19 -0
  86. package/ios/ReactDelegates/ExpoReactDelegate.swift +2 -2
  87. package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +1 -1
  88. package/ios/Swift/AppContext.swift +27 -1
  89. package/ios/Swift/Functions/AsyncFunction.swift +17 -0
  90. package/ios/Swift/Functions/ConcreteFunction.swift +6 -1
  91. package/ios/Swift/JavaScriptUtils.swift +11 -0
  92. package/ios/Swift/ModuleHolder.swift +14 -3
  93. package/ios/Swift/ModulesProvider.swift +3 -10
  94. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +176 -0
  95. package/ios/Swift/SwiftInteropBridge.swift +14 -5
  96. package/ios/Swift/Views/ComponentData.swift +2 -1
  97. package/ios/Swift/Views/ExpoView.swift +8 -0
  98. package/ios/Swift.h +5 -0
  99. package/ios/Tests/ArgumentTypeSpec.swift +2 -3
  100. package/ios/Tests/ConstantsSpec.swift +2 -3
  101. package/ios/Tests/ConvertiblesSpec.swift +2 -3
  102. package/ios/Tests/ExceptionsSpec.swift +2 -3
  103. package/ios/Tests/ExpoModulesSpec.swift +76 -0
  104. package/ios/Tests/FunctionSpec.swift +2 -3
  105. package/ios/Tests/FunctionWithConvertiblesSpec.swift +2 -3
  106. package/ios/Tests/JavaScriptObjectSpec.swift +97 -0
  107. package/ios/Tests/JavaScriptRuntimeSpec.swift +94 -0
  108. package/ios/Tests/ModuleEventListenersSpec.swift +2 -3
  109. package/ios/Tests/ModuleRegistrySpec.swift +2 -3
  110. package/ios/Tests/RecordSpec.swift +2 -3
  111. package/package.json +2 -2
  112. package/src/NativeModulesProxy.native.ts +2 -22
  113. package/src/NativeModulesProxy.types.ts +0 -8
  114. package/src/NativeViewManagerAdapter.native.tsx +12 -28
  115. package/src/sweet/NativeErrorManager.ts +1 -1
  116. package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +0 -26
  117. package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +0 -14
  118. package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +0 -15
  119. package/ios/JSI/JSIInstaller.mm +0 -34
  120. package/ios/JSI/JavaScriptObject.h +0 -60
  121. package/ios/JSI/JavaScriptObject.mm +0 -93
  122. package/ios/JSI/JavaScriptRuntime.mm +0 -102
  123. package/ios/NativeModulesProxy/EXComponentDataCompatibleWrapper.h +0 -16
  124. package/ios/NativeModulesProxy/EXComponentDataCompatibleWrapper.m +0 -28
@@ -22,6 +22,7 @@ public func constants(_ body: @autoclosure @escaping () -> [String: Any?]) -> An
22
22
  /**
23
23
  Function without arguments.
24
24
  */
25
+ @available(*, deprecated, renamed: "asyncFunction")
25
26
  public func function<R>(
26
27
  _ name: String,
27
28
  _ closure: @escaping () throws -> R
@@ -36,6 +37,7 @@ public func function<R>(
36
37
  /**
37
38
  Function with one argument.
38
39
  */
40
+ @available(*, deprecated, renamed: "asyncFunction")
39
41
  public func function<R, A0: AnyArgument>(
40
42
  _ name: String,
41
43
  _ closure: @escaping (A0) throws -> R
@@ -50,6 +52,7 @@ public func function<R, A0: AnyArgument>(
50
52
  /**
51
53
  Function with two arguments.
52
54
  */
55
+ @available(*, deprecated, renamed: "asyncFunction")
53
56
  public func function<R, A0: AnyArgument, A1: AnyArgument>(
54
57
  _ name: String,
55
58
  _ closure: @escaping (A0, A1) throws -> R
@@ -64,6 +67,7 @@ public func function<R, A0: AnyArgument, A1: AnyArgument>(
64
67
  /**
65
68
  Function with three arguments.
66
69
  */
70
+ @available(*, deprecated, renamed: "asyncFunction")
67
71
  public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument>(
68
72
  _ name: String,
69
73
  _ closure: @escaping (A0, A1, A2) throws -> R
@@ -82,6 +86,7 @@ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument>(
82
86
  /**
83
87
  Function with four arguments.
84
88
  */
89
+ @available(*, deprecated, renamed: "asyncFunction")
85
90
  public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument>(
86
91
  _ name: String,
87
92
  _ closure: @escaping (A0, A1, A2, A3) throws -> R
@@ -101,6 +106,7 @@ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: A
101
106
  /**
102
107
  Function with five arguments.
103
108
  */
109
+ @available(*, deprecated, renamed: "asyncFunction")
104
110
  public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument>(
105
111
  _ name: String,
106
112
  _ closure: @escaping (A0, A1, A2, A3, A4) throws -> R
@@ -121,6 +127,7 @@ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: A
121
127
  /**
122
128
  Function with six arguments.
123
129
  */
130
+ @available(*, deprecated, renamed: "asyncFunction")
124
131
  public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument>(
125
132
  _ name: String,
126
133
  _ closure: @escaping (A0, A1, A2, A3, A4, A5) throws -> R
@@ -142,6 +149,7 @@ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: A
142
149
  /**
143
150
  Function with seven arguments.
144
151
  */
152
+ @available(*, deprecated, renamed: "asyncFunction")
145
153
  public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument>(
146
154
  _ name: String,
147
155
  _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6) throws -> R
@@ -164,6 +172,7 @@ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: A
164
172
  /**
165
173
  Function with eight arguments.
166
174
  */
175
+ @available(*, deprecated, renamed: "asyncFunction")
167
176
  public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument, A7: AnyArgument>(
168
177
  _ name: String,
169
178
  _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6, A7) throws -> R
@@ -184,6 +193,173 @@ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: A
184
193
  )
185
194
  }
186
195
 
196
+ // MARK: - Asynchronous functions
197
+
198
+ /**
199
+ Asynchronous function without arguments.
200
+ */
201
+ public func asyncFunction<R>(
202
+ _ name: String,
203
+ _ closure: @escaping () throws -> R
204
+ ) -> AnyFunction {
205
+ return AsyncFunction(
206
+ name,
207
+ argTypes: [],
208
+ closure
209
+ )
210
+ }
211
+
212
+ /**
213
+ Asynchronous function with one argument.
214
+ */
215
+ public func asyncFunction<R, A0: AnyArgument>(
216
+ _ name: String,
217
+ _ closure: @escaping (A0) throws -> R
218
+ ) -> AnyFunction {
219
+ return AsyncFunction(
220
+ name,
221
+ argTypes: [ArgumentType(A0.self)],
222
+ closure
223
+ )
224
+ }
225
+
226
+ /**
227
+ Asynchronous function with two arguments.
228
+ */
229
+ public func asyncFunction<R, A0: AnyArgument, A1: AnyArgument>(
230
+ _ name: String,
231
+ _ closure: @escaping (A0, A1) throws -> R
232
+ ) -> AnyFunction {
233
+ return AsyncFunction(
234
+ name,
235
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self)],
236
+ closure
237
+ )
238
+ }
239
+
240
+ /**
241
+ Asynchronous function with three arguments.
242
+ */
243
+ public func asyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument>(
244
+ _ name: String,
245
+ _ closure: @escaping (A0, A1, A2) throws -> R
246
+ ) -> AnyFunction {
247
+ return AsyncFunction(
248
+ name,
249
+ argTypes: [
250
+ ArgumentType(A0.self),
251
+ ArgumentType(A1.self),
252
+ ArgumentType(A2.self)
253
+ ],
254
+ closure
255
+ )
256
+ }
257
+
258
+ /**
259
+ Asynchronous function with four arguments.
260
+ */
261
+ public func asyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument>(
262
+ _ name: String,
263
+ _ closure: @escaping (A0, A1, A2, A3) throws -> R
264
+ ) -> AnyFunction {
265
+ return AsyncFunction(
266
+ name,
267
+ argTypes: [
268
+ ArgumentType(A0.self),
269
+ ArgumentType(A1.self),
270
+ ArgumentType(A2.self),
271
+ ArgumentType(A3.self)
272
+ ],
273
+ closure
274
+ )
275
+ }
276
+
277
+ /**
278
+ Asynchronous function with five arguments.
279
+ */
280
+ public func asyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument>(
281
+ _ name: String,
282
+ _ closure: @escaping (A0, A1, A2, A3, A4) throws -> R
283
+ ) -> AnyFunction {
284
+ return AsyncFunction(
285
+ name,
286
+ argTypes: [
287
+ ArgumentType(A0.self),
288
+ ArgumentType(A1.self),
289
+ ArgumentType(A2.self),
290
+ ArgumentType(A3.self),
291
+ ArgumentType(A4.self)
292
+ ],
293
+ closure
294
+ )
295
+ }
296
+
297
+ /**
298
+ Asynchronous function with six arguments.
299
+ */
300
+ public func asyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument>(
301
+ _ name: String,
302
+ _ closure: @escaping (A0, A1, A2, A3, A4, A5) throws -> R
303
+ ) -> AnyFunction {
304
+ return AsyncFunction(
305
+ name,
306
+ argTypes: [
307
+ ArgumentType(A0.self),
308
+ ArgumentType(A1.self),
309
+ ArgumentType(A2.self),
310
+ ArgumentType(A3.self),
311
+ ArgumentType(A4.self),
312
+ ArgumentType(A5.self)
313
+ ],
314
+ closure
315
+ )
316
+ }
317
+
318
+ /**
319
+ Asynchronous function with seven arguments.
320
+ */
321
+ public func asyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument>(
322
+ _ name: String,
323
+ _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6) throws -> R
324
+ ) -> AnyFunction {
325
+ return AsyncFunction(
326
+ name,
327
+ argTypes: [
328
+ ArgumentType(A0.self),
329
+ ArgumentType(A1.self),
330
+ ArgumentType(A2.self),
331
+ ArgumentType(A3.self),
332
+ ArgumentType(A4.self),
333
+ ArgumentType(A5.self),
334
+ ArgumentType(A6.self)
335
+ ],
336
+ closure
337
+ )
338
+ }
339
+
340
+ /**
341
+ Asynchronous function with eight arguments.
342
+ */
343
+ public func asyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument, A7: AnyArgument>(
344
+ _ name: String,
345
+ _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6, A7) throws -> R
346
+ ) -> AnyFunction {
347
+ return AsyncFunction(
348
+ name,
349
+ argTypes: [
350
+ ArgumentType(A0.self),
351
+ ArgumentType(A1.self),
352
+ ArgumentType(A2.self),
353
+ ArgumentType(A3.self),
354
+ ArgumentType(A4.self),
355
+ ArgumentType(A5.self),
356
+ ArgumentType(A6.self),
357
+ ArgumentType(A7.self)
358
+ ],
359
+ closure
360
+ )
361
+ }
362
+
187
363
  // MARK: - Events
188
364
 
189
365
  /**
@@ -11,9 +11,14 @@ public final class SwiftInteropBridge: NSObject {
11
11
  appContext.moduleRegistry
12
12
  }
13
13
 
14
+ internal init(appContext: AppContext) {
15
+ self.appContext = appContext
16
+ super.init()
17
+ }
18
+
14
19
  @objc
15
- public init(modulesProvider: ModulesProviderObjCProtocol, legacyModuleRegistry: EXModuleRegistry) {
16
- self.appContext = AppContext(withModulesProvider: modulesProvider as! ModulesProviderProtocol, legacyModuleRegistry: legacyModuleRegistry)
20
+ public init(modulesProvider: ModulesProvider, legacyModuleRegistry: EXModuleRegistry) {
21
+ self.appContext = AppContext(withModulesProvider: modulesProvider, legacyModuleRegistry: legacyModuleRegistry)
17
22
  super.init()
18
23
  }
19
24
 
@@ -83,9 +88,13 @@ public final class SwiftInteropBridge: NSObject {
83
88
  }
84
89
 
85
90
  @objc
86
- public func exportedViewManagersNames() -> [String] {
87
- return registry.compactMap { holder in
88
- return holder.definition.viewManager != nil ? holder.name : nil
91
+ public func viewManagersMetadata() -> [String: Any] {
92
+ return registry.reduce(into: [String: Any]()) { acc, holder in
93
+ if let viewManager = holder.definition.viewManager {
94
+ acc[holder.name] = [
95
+ "propsNames": viewManager.props.map { $0.name }
96
+ ]
97
+ }
89
98
  }
90
99
  }
91
100
 
@@ -1,12 +1,13 @@
1
1
  // Copyright 2021-present 650 Industries. All rights reserved.
2
2
 
3
+ import React
3
4
 
4
5
  /**
5
6
  Custom component data extending `RCTComponentData`. Its main purpose is to handle event-based props (callbacks),
6
7
  but it also simplifies capturing the view config so we can omit some reflections that React Native executes.
7
8
  */
8
9
  @objc(EXComponentData)
9
- public final class ComponentData: EXComponentDataCompatibleWrapper {
10
+ public final class ComponentData: RCTComponentData {
10
11
  /**
11
12
  Weak pointer to the holder of a module that the component data was created for.
12
13
  */
@@ -0,0 +1,8 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ import React
4
+
5
+ /**
6
+ The view that just extends `RCTView`. In the future we may add more features here.
7
+ */
8
+ open class ExpoView: RCTView {}
package/ios/Swift.h CHANGED
@@ -1,5 +1,10 @@
1
1
  // Copyright 2018-present 650 Industries. All rights reserved.
2
2
 
3
+ // The generated swift header may depend on some Objective-C declarations,
4
+ // adding dependency imports here to prevent declarations not found errors.
5
+ #import <ExpoModulesCore/EXDefines.h>
6
+ #import <ExpoModulesCore/RCTComponentData+Privates.h>
7
+
3
8
  // When `use_frameworks!` is used, the generated Swift header is inside ExpoModulesCore module.
4
9
  // Otherwise, it's available only locally with double-quoted imports.
5
10
  #if __has_include(<ExpoModulesCore/ExpoModulesCore-Swift.h>)
@@ -1,11 +1,10 @@
1
1
  // Copyright 2021-present 650 Industries. All rights reserved.
2
2
 
3
- import Quick
4
- import Nimble
3
+ import ExpoModulesTestCore
5
4
 
6
5
  @testable import ExpoModulesCore
7
6
 
8
- class ArgumentTypeSpec: QuickSpec {
7
+ class ArgumentTypeSpec: ExpoSpec {
9
8
  override func spec() {
10
9
  it("casts primitives") {
11
10
  let type = ArgumentType(Int.self)
@@ -1,9 +1,8 @@
1
- import Quick
2
- import Nimble
1
+ import ExpoModulesTestCore
3
2
 
4
3
  @testable import ExpoModulesCore
5
4
 
6
- class ConstantsSpec: QuickSpec {
5
+ class ConstantsSpec: ExpoSpec {
7
6
  override func spec() {
8
7
  let appContext = AppContext()
9
8
 
@@ -1,12 +1,11 @@
1
1
  // Copyright 2018-present 650 Industries. All rights reserved.
2
2
 
3
3
  import CoreGraphics
4
- import Quick
5
- import Nimble
4
+ import ExpoModulesTestCore
6
5
 
7
6
  @testable import ExpoModulesCore
8
7
 
9
- class ConvertiblesSpec: QuickSpec {
8
+ class ConvertiblesSpec: ExpoSpec {
10
9
  override func spec() {
11
10
  describe("URL") {
12
11
  it("converts from remote url") {
@@ -1,11 +1,10 @@
1
1
  // Copyright 2021-present 650 Industries. All rights reserved.
2
2
 
3
- import Quick
4
- import Nimble
3
+ import ExpoModulesTestCore
5
4
 
6
5
  @testable import ExpoModulesCore
7
6
 
8
- final class ExceptionsSpec: QuickSpec {
7
+ final class ExceptionsSpec: ExpoSpec {
9
8
  override func spec() {
10
9
  it("has name") {
11
10
  let error = TestException()
@@ -0,0 +1,76 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesTestCore
4
+
5
+ @testable import ExpoModulesCore
6
+
7
+ class ExpoModulesSpec: ExpoSpec {
8
+ override func spec() {
9
+ let appContext = AppContext.create()
10
+ let interopBridge = SwiftInteropBridge(appContext: appContext)
11
+ let runtime = appContext.runtime
12
+ let testModuleName = "TestModule"
13
+ let testFunctionName = "testFunction"
14
+ let constantsDict: [String: Any] = [
15
+ "expo": "is cool",
16
+ "sdk": 45,
17
+ ]
18
+
19
+ beforeSuite {
20
+ try! appContext.installExpoModulesHostObject(interopBridge)
21
+
22
+ appContext.moduleRegistry.register(holder: mockModuleHolder(appContext) {
23
+ $0.name(testModuleName)
24
+
25
+ constants(constantsDict)
26
+
27
+ function(testFunctionName) { Double.pi }
28
+ .runSynchronously()
29
+ })
30
+ }
31
+
32
+ describe("host object") {
33
+ it("is defined") {
34
+ expect(try! runtime?.eval("'ExpoModules' in this").asBool()) === true
35
+ }
36
+
37
+ it("has native module defined") {
38
+ expect(try! runtime?.eval("'\(testModuleName)' in ExpoModules").asBool()) === true
39
+ }
40
+
41
+ it("can access native module") {
42
+ let nativeModule = try! runtime?.eval("ExpoModules.\(testModuleName)")
43
+ expect(nativeModule?.isUndefined()) == false
44
+ expect(nativeModule?.isObject()) == true
45
+ expect(nativeModule?.getRaw()).notTo(beNil())
46
+ }
47
+
48
+ it("has keys for registered modules") {
49
+ let registeredModuleNames = appContext.moduleRegistry.getModuleNames()
50
+ let keys = try! runtime?.eval("Object.keys(ExpoModules)").asArray().compactMap {
51
+ return try! $0?.asString()
52
+ }
53
+ expect(keys).to(contain(registeredModuleNames))
54
+ }
55
+ }
56
+
57
+ describe("module") {
58
+ it("exposes constants") {
59
+ let dict = try! runtime!.eval("ExpoModules.TestModule").asDict()
60
+
61
+ dict.forEach { (key: String, value: Any) in
62
+ expect(value) === dict[key]!
63
+ }
64
+ }
65
+
66
+ it("has function") {
67
+ expect(try! runtime?.eval("typeof ExpoModules.TestModule.\(testFunctionName)").asString()) == "function"
68
+ expect(try! runtime?.eval("ExpoModules.TestModule.\(testFunctionName)").isFunction()) == true
69
+ }
70
+
71
+ it("calls function") {
72
+ expect(try! runtime?.eval("ExpoModules.TestModule.\(testFunctionName)()").asDouble()) == Double.pi
73
+ }
74
+ }
75
+ }
76
+ }
@@ -1,9 +1,8 @@
1
- import Quick
2
- import Nimble
1
+ import ExpoModulesTestCore
3
2
 
4
3
  @testable import ExpoModulesCore
5
4
 
6
- class FunctionSpec: QuickSpec {
5
+ class FunctionSpec: ExpoSpec {
7
6
  override func spec() {
8
7
  let appContext = AppContext()
9
8
  let functionName = "test function name"
@@ -1,12 +1,11 @@
1
1
  // Copyright 2018-present 650 Industries. All rights reserved.
2
2
 
3
3
  import CoreGraphics
4
- import Quick
5
- import Nimble
4
+ import ExpoModulesTestCore
6
5
 
7
6
  @testable import ExpoModulesCore
8
7
 
9
- class FunctionWithConvertiblesSpec: QuickSpec {
8
+ class FunctionWithConvertiblesSpec: ExpoSpec {
10
9
  override func spec() {
11
10
  let appContext = AppContext()
12
11
  let functionName = "function"
@@ -0,0 +1,97 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesTestCore
4
+
5
+ @testable import ExpoModulesCore
6
+
7
+ final class JavaScriptObjectSpec: ExpoSpec {
8
+ override func spec() {
9
+ let runtime = JavaScriptRuntime()
10
+ var object: JavaScriptObject?
11
+
12
+ let key = "expo"
13
+ let value1 = "💙"
14
+ let value2 = "💛"
15
+
16
+ beforeEach {
17
+ object = runtime.createObject()
18
+ }
19
+
20
+ describe("hasProperty") {
21
+ it("returns false when the property is missing") {
22
+ expect(object?.hasProperty(key)) == false
23
+ }
24
+
25
+ it("returns true when the property exists") {
26
+ object?.setProperty(key, value: value1)
27
+ expect(object?.hasProperty(key)) == true
28
+ }
29
+
30
+ it("returns true when the property is explicitly set to undefined") {
31
+ object?.setProperty(key, value: nil)
32
+ expect(object?.hasProperty(key)) == true
33
+ expect(object?.getProperty(key).isUndefined()) == true
34
+ }
35
+ }
36
+
37
+ describe("getProperty") {
38
+ it("returns correct value") {
39
+ object?.setProperty(key, value: value1)
40
+ expect(try! object?.getProperty(key).asString()) == value1
41
+ }
42
+
43
+ it("returns undefined") {
44
+ expect(object?.getProperty("bar").isUndefined()) == true
45
+ }
46
+ }
47
+
48
+ describe("setProperty") {
49
+ it("sets") {
50
+ object?.setProperty(key, value: value1)
51
+ expect(try! object?.getProperty(key).asString()) == value1
52
+ }
53
+
54
+ it("overrides") {
55
+ object?.setProperty(key, value: value1)
56
+ object?.setProperty(key, value: value2)
57
+ expect(try! object?.getProperty(key).asString()) == value2
58
+ }
59
+
60
+ it("unsets") {
61
+ object?.setProperty(key, value: nil)
62
+ expect(object?.getProperty(key).isUndefined()) == true
63
+ }
64
+ }
65
+
66
+ describe("defineProperty") {
67
+ it("defines non-enumerable property") {
68
+ object?.defineProperty(key, value: value1, options: [])
69
+ expect(try! object?.getProperty(key).asString()) == value1
70
+ expect(object?.getPropertyNames()).notTo(contain(key))
71
+ }
72
+
73
+ it("defines enumerable property") {
74
+ // When the property is enumerable, it is listed in the property names
75
+ object?.defineProperty(key, value: value1, options: .enumerable)
76
+ expect(try! object?.getProperty(key).asString()) == value1
77
+ expect(object?.getPropertyNames()).to(contain(key))
78
+ }
79
+
80
+ it("defines configurable property") {
81
+ // Configurable allows to redefine the property
82
+ object?.defineProperty(key, value: value1, options: .configurable)
83
+ expect(try! object?.getProperty(key).asString()) == value1
84
+ object?.defineProperty(key, value: value2, options: [])
85
+ expect(try! object?.getProperty(key).asString()) == value2
86
+ }
87
+
88
+ it("defines writable property") {
89
+ // Writable allows changing the property
90
+ object?.defineProperty(key, value: value1, options: .writable)
91
+ expect(try! object?.getProperty(key).asString()) == value1
92
+ object?.setProperty(key, value: value2)
93
+ expect(try! object?.getProperty(key).asString()) == value2
94
+ }
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,94 @@
1
+ import ExpoModulesTestCore
2
+
3
+ @testable import ExpoModulesCore
4
+
5
+ class JavaScriptRuntimeSpec: ExpoSpec {
6
+ override func spec() {
7
+ let runtime = JavaScriptRuntime()
8
+
9
+ it("has global object accessible") {
10
+ expect(runtime.global) !== nil
11
+ }
12
+
13
+ describe("eval") {
14
+ it("returns undefined") {
15
+ let undefined = try! runtime.eval("undefined")
16
+ expect(undefined.isUndefined()) == true
17
+ expect(undefined.kind) == .undefined
18
+ expect(undefined.isNull()) == false
19
+ expect(undefined.getRaw()).to(beNil())
20
+ }
21
+
22
+ it("returns null") {
23
+ let null = try! runtime.eval("null")
24
+ expect(null.isNull()) == true
25
+ expect(null.kind) == .null
26
+ expect(null.getRaw()).to(beNil())
27
+ }
28
+
29
+ it("returns bool") {
30
+ let boolTrue = try! runtime.eval("true")
31
+ let boolFalse = try! runtime.eval("false")
32
+ expect(boolTrue.isBool()) == true
33
+ expect(boolFalse.isBool()) == true
34
+ expect(boolTrue.kind) == .bool
35
+ expect(boolFalse.kind) == .bool
36
+ expect(try! boolTrue.asBool()) == true
37
+ expect(try! boolFalse.asBool()) == false
38
+ }
39
+
40
+ it("returns number") {
41
+ let number = try! runtime.eval("1.23")
42
+ expect(number.isNumber()) == true
43
+ expect(number.kind) == .number
44
+ expect(try! number.asInt()) == 1
45
+ expect(try! number.asDouble()) == 1.23
46
+ }
47
+
48
+ it("returns string") {
49
+ let string = try! runtime.eval("'foobar'")
50
+ expect(string.isString()) == true
51
+ expect(string.kind) == .string
52
+ expect(try! string.asString()) == "foobar"
53
+ }
54
+
55
+ it("returns array") {
56
+ let array = try! runtime.eval("(['foo', 'bar'])")
57
+ expect(array.isObject()) == true
58
+ expect(array.kind) == .object
59
+ expect(try! array.asArray().map { try $0?.asString() }) == ["foo", "bar"]
60
+ }
61
+
62
+ it("returns dict") {
63
+ let dict1 = try! runtime.eval("({ 'foo': 123 })")
64
+ let dict2 = try! runtime.eval("({ 'foo': 'bar' })")
65
+ expect(dict1.isObject()) == true
66
+ expect(dict2.isObject()) == true
67
+ expect(dict1.kind) == .object
68
+ expect(dict2.kind) == .object
69
+ expect(try! dict1.asDict() as? [String: Int]) == ["foo": 123]
70
+ expect(try! dict2.asDict() as? [String: String]) == ["foo": "bar"]
71
+ }
72
+
73
+ it("returns function") {
74
+ let function = try! runtime.eval("(function() {})")
75
+ expect(function.isObject()) == true
76
+ expect(function.isFunction()) == true
77
+ expect(function.kind) == .function
78
+ }
79
+
80
+ it("returns symbol") {
81
+ let symbol = try! runtime.eval("Symbol('foo')")
82
+ expect(symbol.isSymbol()) == true
83
+ expect(symbol.kind) == .symbol
84
+ }
85
+
86
+ it("throws evaluation exception") {
87
+ expect({ try runtime.eval("foo") }).to(throwError { error in
88
+ expect(error).to(beAKindOf(JavaScriptEvalException.self))
89
+ expect((error as! JavaScriptEvalException).reason).to(contain("Can't find variable: foo"))
90
+ })
91
+ }
92
+ }
93
+ }
94
+ }
@@ -1,5 +1,4 @@
1
- import Quick
2
- import Nimble
1
+ import ExpoModulesTestCore
3
2
 
4
3
  @testable import ExpoModulesCore
5
4
 
@@ -11,7 +10,7 @@ import Nimble
11
10
 
12
11
  NOTE: Each test registers the module because only registered modules can capture events.
13
12
  */
14
- class ModuleEventListenersSpec: QuickSpec {
13
+ class ModuleEventListenersSpec: ExpoSpec {
15
14
  override func spec() {
16
15
  var appContext: AppContext!
17
16