expo-modules-core 1.2.6 → 1.3.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 (180) hide show
  1. package/CHANGELOG.md +33 -4
  2. package/ExpoModulesCore.podspec +1 -0
  3. package/README.md +1 -1
  4. package/android/ExpoModulesCorePlugin.gradle +16 -0
  5. package/android/build.gradle +3 -2
  6. package/android/src/main/cpp/Exceptions.cpp +8 -0
  7. package/android/src/main/cpp/Exceptions.h +11 -0
  8. package/android/src/main/cpp/ExpoModulesHostObject.cpp +22 -5
  9. package/android/src/main/cpp/ExpoModulesHostObject.h +5 -0
  10. package/android/src/main/cpp/JNIInjector.cpp +2 -0
  11. package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +25 -1
  12. package/android/src/main/cpp/JSIInteropModuleRegistry.h +14 -0
  13. package/android/src/main/cpp/JSIObjectWrapper.h +15 -4
  14. package/android/src/main/cpp/JSITypeConverter.h +3 -2
  15. package/android/src/main/cpp/JavaReferencesCache.cpp +2 -0
  16. package/android/src/main/cpp/JavaScriptFunction.cpp +56 -0
  17. package/android/src/main/cpp/JavaScriptFunction.h +54 -0
  18. package/android/src/main/cpp/JavaScriptModuleObject.cpp +225 -105
  19. package/android/src/main/cpp/JavaScriptModuleObject.h +67 -34
  20. package/android/src/main/cpp/JavaScriptObject.cpp +55 -1
  21. package/android/src/main/cpp/JavaScriptObject.h +17 -13
  22. package/android/src/main/cpp/JavaScriptRuntime.cpp +12 -3
  23. package/android/src/main/cpp/JavaScriptRuntime.h +9 -1
  24. package/android/src/main/cpp/JavaScriptValue.cpp +9 -0
  25. package/android/src/main/cpp/JavaScriptValue.h +4 -0
  26. package/android/src/main/cpp/MethodMetadata.cpp +66 -87
  27. package/android/src/main/cpp/MethodMetadata.h +18 -16
  28. package/android/src/main/cpp/ObjectDeallocator.h +25 -0
  29. package/android/src/main/cpp/WeakRuntimeHolder.cpp +7 -0
  30. package/android/src/main/cpp/WeakRuntimeHolder.h +4 -0
  31. package/android/src/main/cpp/types/CppType.h +4 -1
  32. package/android/src/main/cpp/types/FrontendConverter.cpp +58 -0
  33. package/android/src/main/cpp/types/FrontendConverter.h +45 -0
  34. package/android/src/main/cpp/types/FrontendConverterProvider.cpp +3 -0
  35. package/android/src/main/cpp/types/JNIToJSIConverter.cpp +88 -0
  36. package/android/src/main/cpp/types/JNIToJSIConverter.h +22 -0
  37. package/android/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMapHelper.kt +10 -0
  38. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +18 -25
  39. package/android/src/main/java/expo/modules/kotlin/FilteredIterator.kt +37 -0
  40. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +1 -1
  41. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +34 -21
  42. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +13 -3
  43. package/android/src/main/java/expo/modules/kotlin/Utils.kt +21 -0
  44. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +21 -1
  45. package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +112 -0
  46. package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassDefinitionData.kt +10 -0
  47. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +21 -0
  48. package/android/src/main/java/expo/modules/kotlin/exception/CommonExceptions.kt +15 -0
  49. package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +17 -4
  50. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +38 -8
  51. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +3 -2
  52. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +3 -2
  53. package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +1 -0
  54. package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +18 -11
  55. package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +4 -1
  56. package/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt +73 -0
  57. package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +28 -2
  58. package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +8 -1
  59. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptFunction.kt +48 -0
  60. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +40 -3
  61. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +23 -3
  62. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +26 -1
  63. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +0 -11
  64. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +26 -16
  65. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +3 -1
  66. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObject.kt +12 -0
  67. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +62 -0
  68. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectTypeConverter.kt +27 -0
  69. package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +2 -1
  70. package/android/src/main/java/expo/modules/kotlin/types/EitherTypeConverter.kt +7 -6
  71. package/android/src/main/java/expo/modules/kotlin/types/JavaScriptFunctionTypeConverter.kt +22 -0
  72. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +30 -24
  73. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +45 -1
  74. package/android/src/main/java/expo/modules/kotlin/types/TypedArrayTypeConverter.kt +3 -2
  75. package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +3 -1
  76. package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +3 -3
  77. package/android/src/main/java/expo/modules/kotlin/views/FilteredReadableMap.kt +53 -0
  78. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +25 -5
  79. package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +25 -5
  80. package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +161 -10
  81. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -67
  82. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +7 -8
  83. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +40 -3
  84. package/android/src/main/java/expo/modules/kotlin/views/ViewTypeConverter.kt +44 -0
  85. package/android-annotation/build.gradle +45 -0
  86. package/android-annotation/src/main/java/expo/modules/annotation/Config.kt +7 -0
  87. package/android-annotation/src/main/java/expo/modules/annotation/ConverterBinder.kt +7 -0
  88. package/android-annotation-processor/build.gradle +51 -0
  89. package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessor.kt +175 -0
  90. package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessorProvider.kt +10 -0
  91. package/android-annotation-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +1 -0
  92. package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
  93. package/build/NativeViewManagerAdapter.native.js +36 -23
  94. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  95. package/build/requireNativeModule.js +2 -2
  96. package/build/requireNativeModule.js.map +1 -1
  97. package/common/cpp/fabric/ExpoViewProps.cpp +18 -3
  98. package/common/cpp/fabric/ExpoViewProps.h +4 -1
  99. package/ios/Fabric/ExpoFabricView.swift +10 -10
  100. package/ios/Fabric/ExpoFabricViewObjC.h +2 -0
  101. package/ios/Fabric/ExpoFabricViewObjC.mm +17 -2
  102. package/ios/JSI/EXJSIInstaller.mm +1 -1
  103. package/ios/JSI/EXJSIUtils.h +5 -0
  104. package/ios/JSI/EXJSIUtils.mm +17 -0
  105. package/ios/JSI/EXJavaScriptRuntime.h +5 -0
  106. package/ios/JSI/EXJavaScriptRuntime.mm +6 -0
  107. package/ios/JSI/EXJavaScriptValue.h +2 -0
  108. package/ios/JSI/EXJavaScriptValue.mm +8 -0
  109. package/ios/JSI/EXJavaScriptWeakObject.mm +29 -8
  110. package/ios/JSI/EXRawJavaScriptFunction.h +24 -0
  111. package/ios/JSI/EXRawJavaScriptFunction.mm +52 -0
  112. package/ios/JSI/ExpoModulesHostObject.mm +1 -1
  113. package/ios/JSI/JavaScriptValue.swift +28 -1
  114. package/ios/ModuleRegistry/EXModuleRegistry.h +0 -4
  115. package/ios/ModuleRegistry/EXModuleRegistry.m +0 -23
  116. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -16
  117. package/ios/ModuleRegistryProvider/EXModuleRegistryProvider.m +0 -6
  118. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +1 -31
  119. package/ios/Swift/AppContext.swift +46 -6
  120. package/ios/Swift/Arguments/Convertible.swift +3 -3
  121. package/ios/Swift/Arguments/Convertibles.swift +5 -5
  122. package/ios/Swift/Classes/ClassComponent.swift +18 -12
  123. package/ios/Swift/Classes/ClassRegistry.swift +31 -0
  124. package/ios/Swift/Conversions.swift +19 -3
  125. package/ios/Swift/Convertibles/Convertibles+Color.swift +3 -3
  126. package/ios/Swift/Convertibles/Either.swift +6 -4
  127. package/ios/Swift/DynamicTypes/AnyDynamicType.swift +18 -2
  128. package/ios/Swift/DynamicTypes/DynamicArrayType.swift +3 -3
  129. package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +2 -2
  130. package/ios/Swift/DynamicTypes/DynamicEnumType.swift +1 -1
  131. package/ios/Swift/DynamicTypes/DynamicJavaScriptType.swift +27 -0
  132. package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +9 -2
  133. package/ios/Swift/DynamicTypes/DynamicRawType.swift +1 -1
  134. package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +16 -2
  135. package/ios/Swift/DynamicTypes/DynamicType.swift +6 -0
  136. package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +15 -4
  137. package/ios/Swift/DynamicTypes/DynamicViewType.swift +68 -0
  138. package/ios/Swift/ExpoBridgeModule.swift +1 -1
  139. package/ios/Swift/Functions/AnyFunction.swift +5 -4
  140. package/ios/Swift/Functions/AsyncFunctionComponent.swift +22 -19
  141. package/ios/Swift/Functions/ConcurrentFunctionDefinition.swift +29 -13
  142. package/ios/Swift/Functions/SyncFunctionComponent.swift +26 -15
  143. package/ios/Swift/JavaScriptFunction.swift +68 -0
  144. package/ios/Swift/JavaScriptUtils.swift +57 -18
  145. package/ios/Swift/ModuleHolder.swift +22 -10
  146. package/ios/Swift/Modules/ModuleDefinition.swift +8 -2
  147. package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +8 -8
  148. package/ios/Swift/Objects/ObjectDefinition.swift +17 -15
  149. package/ios/Swift/Objects/PropertyComponent.swift +23 -17
  150. package/ios/Swift/Records/AnyField.swift +1 -1
  151. package/ios/Swift/Records/Field.swift +2 -2
  152. package/ios/Swift/Records/Record.swift +5 -5
  153. package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +4 -0
  154. package/ios/Swift/Views/AnyViewProp.swift +1 -1
  155. package/ios/Swift/Views/ComponentData.swift +37 -2
  156. package/ios/Swift/Views/ConcreteViewProp.swift +2 -2
  157. package/ios/Swift/Views/ViewDefinition.swift +39 -0
  158. package/ios/Swift/Views/ViewModuleWrapper.swift +0 -29
  159. package/ios/Tests/ClassComponentSpec.swift +39 -27
  160. package/ios/Tests/ConvertiblesSpec.swift +75 -49
  161. package/ios/Tests/DynamicTypeSpec.swift +29 -27
  162. package/ios/Tests/EitherSpec.swift +9 -7
  163. package/ios/Tests/ExpoModulesSpec.swift +13 -13
  164. package/ios/Tests/FunctionSpec.swift +38 -22
  165. package/ios/Tests/JavaScriptRuntimeSpec.swift +4 -0
  166. package/ios/Tests/PropertyComponentSpec.swift +33 -30
  167. package/ios/Tests/RecordSpec.swift +7 -5
  168. package/ios/Tests/SharedObjectRegistrySpec.swift +12 -12
  169. package/ios/Tests/TypedArraysSpec.swift +1 -1
  170. package/ios/Tests/ViewDefinitionSpec.swift +4 -2
  171. package/package.json +2 -2
  172. package/src/NativeViewManagerAdapter.native.tsx +33 -29
  173. package/src/requireNativeModule.ts +2 -2
  174. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -132
  175. package/ios/EXViewManager.h +0 -21
  176. package/ios/EXViewManager.m +0 -128
  177. package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.h +0 -17
  178. package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.m +0 -67
  179. package/ios/ViewManagerAdapter/EXViewManagerAdapter.h +0 -17
  180. package/ios/ViewManagerAdapter/EXViewManagerAdapter.m +0 -45
@@ -7,10 +7,12 @@ import ExpoModulesTestCore
7
7
 
8
8
  class ConvertiblesSpec: ExpoSpec {
9
9
  override func spec() {
10
+ let appContext = AppContext.create()
11
+
10
12
  describe("URL") {
11
13
  it("converts from remote url") {
12
14
  let remoteUrlString = "https://expo.dev"
13
- let url = try URL.convert(from: remoteUrlString)
15
+ let url = try URL.convert(from: remoteUrlString, appContext: appContext)
14
16
 
15
17
  expect(url.path) == ""
16
18
  expect(url.absoluteString) == remoteUrlString
@@ -19,7 +21,7 @@ class ConvertiblesSpec: ExpoSpec {
19
21
  it("converts from url with unencoded query") {
20
22
  let query = "param=🥓"
21
23
  let urlString = "https://expo.dev/?\(query)"
22
- let url = try URL.convert(from: urlString)
24
+ let url = try URL.convert(from: urlString, appContext: appContext)
23
25
 
24
26
  if #available(iOS 16.0, *) {
25
27
  expect(url.query(percentEncoded: true)) == "param=%F0%9F%A5%93"
@@ -33,7 +35,7 @@ class ConvertiblesSpec: ExpoSpec {
33
35
  it("converts from url with encoded query") {
34
36
  let query = "param=%F0%9F%A5%93"
35
37
  let urlString = "https://expo.dev/?\(query)"
36
- let url = try URL.convert(from: urlString)
38
+ let url = try URL.convert(from: urlString, appContext: appContext)
37
39
 
38
40
  if #available(iOS 16.0, *) {
39
41
  expect(url.query(percentEncoded: true)) == query
@@ -47,7 +49,7 @@ class ConvertiblesSpec: ExpoSpec {
47
49
  it("converts from url with encoded query containg the anchor") {
48
50
  let query = "color=%230000ff"
49
51
  let urlString = "https://expo.dev/?\(query)#anchor"
50
- let url = try URL.convert(from: urlString)
52
+ let url = try URL.convert(from: urlString, appContext: appContext)
51
53
 
52
54
  expect(url.query) == query
53
55
  expect(url.absoluteString) == urlString
@@ -58,7 +60,7 @@ class ConvertiblesSpec: ExpoSpec {
58
60
  it("converts from url with encoded path") {
59
61
  let path = "/expo/%2F%25%3F%5E%26/test" // -> /expo//%?^&/test
60
62
  let urlString = "https://expo.dev\(path)"
61
- let url = try URL.convert(from: urlString)
63
+ let url = try URL.convert(from: urlString, appContext: appContext)
62
64
 
63
65
  expect(url.absoluteString) == urlString
64
66
  expect(url.path) == path.removingPercentEncoding
@@ -73,7 +75,7 @@ class ConvertiblesSpec: ExpoSpec {
73
75
  // The percent character alone must be percent-encoded to `%25` beforehand, otherwise it should throw an exception.
74
76
  let urlString = "https://expo.dev/?param=%"
75
77
 
76
- expect({ try URL.convert(from: urlString) }).to(throwError(errorType: UrlContainsInvalidCharactersException.self))
78
+ expect({ try URL.convert(from: urlString, appContext: appContext) }).to(throwError(errorType: UrlContainsInvalidCharactersException.self))
77
79
  }
78
80
 
79
81
  it("converts from url containing the anchor") {
@@ -82,7 +84,7 @@ class ConvertiblesSpec: ExpoSpec {
82
84
  // thus it cannot be percent-encoded.
83
85
  let query = "param=#expo"
84
86
  let urlString = "https://expo.dev/?\(query)"
85
- let url = try URL.convert(from: urlString)
87
+ let url = try URL.convert(from: urlString, appContext: appContext)
86
88
 
87
89
  expect(url.query) == "param="
88
90
  expect(url.fragment) == "expo"
@@ -91,7 +93,7 @@ class ConvertiblesSpec: ExpoSpec {
91
93
 
92
94
  it("converts from file url") {
93
95
  let fileUrlString = "file:///expo/tmp"
94
- let url = try URL.convert(from: fileUrlString)
96
+ let url = try URL.convert(from: fileUrlString, appContext: appContext)
95
97
 
96
98
  expect(url.path) == "/expo/tmp"
97
99
  expect(url.absoluteString) == fileUrlString
@@ -100,7 +102,7 @@ class ConvertiblesSpec: ExpoSpec {
100
102
 
101
103
  it("converts from file path") {
102
104
  let filePath = "/expo/image.png"
103
- let url = try URL.convert(from: filePath)
105
+ let url = try URL.convert(from: filePath, appContext: appContext)
104
106
 
105
107
  expect(url.scheme) == "file"
106
108
  expect(url.path) == filePath
@@ -110,7 +112,7 @@ class ConvertiblesSpec: ExpoSpec {
110
112
 
111
113
  it("converts from file path with UTF8 characters") {
112
114
  let filePath = "/中文ÅÄÖąÓśĆñ.gif"
113
- let url = try URL.convert(from: filePath)
115
+ let url = try URL.convert(from: filePath, appContext: appContext)
114
116
 
115
117
  expect(url.scheme) == "file"
116
118
  expect(url.path) == filePath
@@ -119,7 +121,7 @@ class ConvertiblesSpec: ExpoSpec {
119
121
 
120
122
  it("converts from file path containing percent character") {
121
123
  let filePath = "/%.png"
122
- let url = try URL.convert(from: filePath)
124
+ let url = try URL.convert(from: filePath, appContext: appContext)
123
125
 
124
126
  expect(url.scheme) == "file"
125
127
  expect(url.path) == filePath
@@ -127,7 +129,7 @@ class ConvertiblesSpec: ExpoSpec {
127
129
  }
128
130
 
129
131
  it("throws when no string") {
130
- expect { try URL.convert(from: 29.5) }.to(
132
+ expect { try URL.convert(from: 29.5, appContext: appContext) }.to(
131
133
  throwError(errorType: Conversions.ConvertingException<URL>.self)
132
134
  )
133
135
  }
@@ -138,34 +140,40 @@ class ConvertiblesSpec: ExpoSpec {
138
140
  let y = 4.6
139
141
 
140
142
  it("converts from array of doubles") {
141
- let point = try CGPoint.convert(from: [x, y])
143
+ let point = try CGPoint.convert(from: [x, y], appContext: appContext)
142
144
 
143
145
  expect(point.x) == x
144
146
  expect(point.y) == y
145
147
  }
146
148
 
147
149
  it("converts from dict") {
148
- let point = try CGPoint.convert(from: ["x": x, "y": y])
150
+ let point = try CGPoint.convert(from: ["x": x, "y": y], appContext: appContext)
149
151
 
150
152
  expect(point.x) == x
151
153
  expect(point.y) == y
152
154
  }
153
155
 
154
156
  it("throws when array size is unexpected") { // different than two
155
- expect { try CGPoint.convert(from: []) }.to(throwError(errorType: Conversions.ConvertingException<CGPoint>.self))
156
- expect { try CGPoint.convert(from: [x]) }.to(throwError(errorType: Conversions.ConvertingException<CGPoint>.self))
157
- expect { try CGPoint.convert(from: [x, y, x]) }.to(throwError(errorType: Conversions.ConvertingException<CGPoint>.self))
157
+ expect { try CGPoint.convert(from: [], appContext: appContext) }.to(
158
+ throwError(errorType: Conversions.ConvertingException<CGPoint>.self)
159
+ )
160
+ expect { try CGPoint.convert(from: [x], appContext: appContext) }.to(
161
+ throwError(errorType: Conversions.ConvertingException<CGPoint>.self)
162
+ )
163
+ expect { try CGPoint.convert(from: [x, y, x], appContext: appContext) }.to(
164
+ throwError(errorType: Conversions.ConvertingException<CGPoint>.self)
165
+ )
158
166
  }
159
167
 
160
168
  it("throws when dict is missing some keys") {
161
- expect { try CGPoint.convert(from: ["test": x]) }.to(throwError {
169
+ expect { try CGPoint.convert(from: ["test": x], appContext: appContext) }.to(throwError {
162
170
  expect($0).to(beAKindOf(Conversions.MissingKeysException<Double>.self))
163
171
  expect(($0 as! CodedError).description) == Conversions.MissingKeysException<Double>(["x", "y"]).description
164
172
  })
165
173
  }
166
174
 
167
175
  it("throws when dict has uncastable keys") {
168
- expect { try CGPoint.convert(from: ["x": x, "y": "string"]) }.to(throwError {
176
+ expect { try CGPoint.convert(from: ["x": x, "y": "string"], appContext: appContext) }.to(throwError {
169
177
  expect($0).to(beAKindOf(Conversions.CastingValuesException<Double>.self))
170
178
  expect(($0 as! CodedError).description) == Conversions.CastingValuesException<Double>(["y"]).description
171
179
  })
@@ -177,34 +185,40 @@ class ConvertiblesSpec: ExpoSpec {
177
185
  let height = 81.7
178
186
 
179
187
  it("converts from array of doubles") {
180
- let size = try CGSize.convert(from: [width, height])
188
+ let size = try CGSize.convert(from: [width, height], appContext: appContext)
181
189
 
182
190
  expect(size.width) == width
183
191
  expect(size.height) == height
184
192
  }
185
193
 
186
194
  it("converts from dict") {
187
- let size = try CGSize.convert(from: ["width": width, "height": height])
195
+ let size = try CGSize.convert(from: ["width": width, "height": height], appContext: appContext)
188
196
 
189
197
  expect(size.width) == width
190
198
  expect(size.height) == height
191
199
  }
192
200
 
193
201
  it("throws when array size is unexpected") { // different than two
194
- expect { try CGSize.convert(from: []) }.to(throwError(errorType: Conversions.ConvertingException<CGSize>.self))
195
- expect { try CGSize.convert(from: [width]) }.to(throwError(errorType: Conversions.ConvertingException<CGSize>.self))
196
- expect { try CGSize.convert(from: [width, height, width]) }.to(throwError(errorType: Conversions.ConvertingException<CGSize>.self))
202
+ expect { try CGSize.convert(from: [], appContext: appContext) }.to(
203
+ throwError(errorType: Conversions.ConvertingException<CGSize>.self)
204
+ )
205
+ expect { try CGSize.convert(from: [width], appContext: appContext) }.to(
206
+ throwError(errorType: Conversions.ConvertingException<CGSize>.self)
207
+ )
208
+ expect { try CGSize.convert(from: [width, height, width], appContext: appContext) }.to(
209
+ throwError(errorType: Conversions.ConvertingException<CGSize>.self)
210
+ )
197
211
  }
198
212
 
199
213
  it("throws when dict is missing some keys") {
200
- expect { try CGSize.convert(from: ["width": width]) }.to(throwError {
214
+ expect { try CGSize.convert(from: ["width": width], appContext: appContext) }.to(throwError {
201
215
  expect($0).to(beAKindOf(Conversions.MissingKeysException<Double>.self))
202
216
  expect(($0 as! CodedError).description) == Conversions.MissingKeysException<Double>(["height"]).description
203
217
  })
204
218
  }
205
219
 
206
220
  it("throws when dict has uncastable keys") {
207
- expect { try CGSize.convert(from: ["width": "test", "height": height]) }.to(throwError {
221
+ expect { try CGSize.convert(from: ["width": "test", "height": height], appContext: appContext) }.to(throwError {
208
222
  expect($0).to(beAKindOf(Conversions.CastingValuesException<Double>.self))
209
223
  expect(($0 as! CodedError).description) == Conversions.CastingValuesException<Double>(["width"]).description
210
224
  })
@@ -216,34 +230,40 @@ class ConvertiblesSpec: ExpoSpec {
216
230
  let dy = -4.0
217
231
 
218
232
  it("converts from array of doubles") {
219
- let vector = try CGVector.convert(from: [dx, dy])
233
+ let vector = try CGVector.convert(from: [dx, dy], appContext: appContext)
220
234
 
221
235
  expect(vector.dx) == dx
222
236
  expect(vector.dy) == dy
223
237
  }
224
238
 
225
239
  it("converts from dict") {
226
- let vector = try CGVector.convert(from: ["dx": dx, "dy": dy])
240
+ let vector = try CGVector.convert(from: ["dx": dx, "dy": dy], appContext: appContext)
227
241
 
228
242
  expect(vector.dx) == dx
229
243
  expect(vector.dy) == dy
230
244
  }
231
245
 
232
246
  it("throws when array size is unexpected") { // different than two
233
- expect { try CGVector.convert(from: []) }.to(throwError(errorType: Conversions.ConvertingException<CGVector>.self))
234
- expect { try CGVector.convert(from: [dx]) }.to(throwError(errorType: Conversions.ConvertingException<CGVector>.self))
235
- expect { try CGVector.convert(from: [dx, dy, dx]) }.to(throwError(errorType: Conversions.ConvertingException<CGVector>.self))
247
+ expect { try CGVector.convert(from: [], appContext: appContext) }.to(
248
+ throwError(errorType: Conversions.ConvertingException<CGVector>.self)
249
+ )
250
+ expect { try CGVector.convert(from: [dx], appContext: appContext) }.to(
251
+ throwError(errorType: Conversions.ConvertingException<CGVector>.self)
252
+ )
253
+ expect { try CGVector.convert(from: [dx, dy, dx], appContext: appContext) }.to(
254
+ throwError(errorType: Conversions.ConvertingException<CGVector>.self)
255
+ )
236
256
  }
237
257
 
238
258
  it("throws when dict is missing some keys") {
239
- expect { try CGVector.convert(from: ["dx": dx]) }.to(throwError {
259
+ expect { try CGVector.convert(from: ["dx": dx], appContext: appContext) }.to(throwError {
240
260
  expect($0).to(beAKindOf(Conversions.MissingKeysException<Double>.self))
241
261
  expect(($0 as! CodedError).description) == Conversions.MissingKeysException<Double>(["dy"]).description
242
262
  })
243
263
  }
244
264
 
245
265
  it("throws when dict has uncastable keys") {
246
- expect { try CGVector.convert(from: ["dx": "dx", "dy": dy]) }.to(throwError {
266
+ expect { try CGVector.convert(from: ["dx": "dx", "dy": dy], appContext: appContext) }.to(throwError {
247
267
  expect($0).to(beAKindOf(Conversions.CastingValuesException<Double>.self))
248
268
  expect(($0 as! CodedError).description) == Conversions.CastingValuesException<Double>(["dx"]).description
249
269
  })
@@ -257,7 +277,7 @@ class ConvertiblesSpec: ExpoSpec {
257
277
  let height = 81.7
258
278
 
259
279
  it("converts from array of doubles") {
260
- let rect = try CGRect.convert(from: [x, y, width, height])
280
+ let rect = try CGRect.convert(from: [x, y, width, height], appContext: appContext)
261
281
 
262
282
  expect(rect.origin.x) == x
263
283
  expect(rect.origin.y) == y
@@ -266,7 +286,7 @@ class ConvertiblesSpec: ExpoSpec {
266
286
  }
267
287
 
268
288
  it("converts from dict") {
269
- let rect = try CGRect.convert(from: ["x": x, "y": y, "width": width, "height": height])
289
+ let rect = try CGRect.convert(from: ["x": x, "y": y, "width": width, "height": height], appContext: appContext)
270
290
 
271
291
  expect(rect.origin.x) == x
272
292
  expect(rect.origin.y) == y
@@ -275,20 +295,26 @@ class ConvertiblesSpec: ExpoSpec {
275
295
  }
276
296
 
277
297
  it("throws when array size is unexpected") { // different than four
278
- expect { try CGRect.convert(from: [x]) }.to(throwError(errorType: Conversions.ConvertingException<CGRect>.self))
279
- expect { try CGRect.convert(from: [x, y]) }.to(throwError(errorType: Conversions.ConvertingException<CGRect>.self))
280
- expect { try CGRect.convert(from: [x, y, width, height, y]) }.to(throwError(errorType: Conversions.ConvertingException<CGRect>.self))
298
+ expect { try CGRect.convert(from: [x], appContext: appContext) }.to(
299
+ throwError(errorType: Conversions.ConvertingException<CGRect>.self)
300
+ )
301
+ expect { try CGRect.convert(from: [x, y], appContext: appContext) }.to(
302
+ throwError(errorType: Conversions.ConvertingException<CGRect>.self)
303
+ )
304
+ expect { try CGRect.convert(from: [x, y, width, height, y], appContext: appContext) }.to(
305
+ throwError(errorType: Conversions.ConvertingException<CGRect>.self)
306
+ )
281
307
  }
282
308
 
283
309
  it("throws when dict is missing some keys") {
284
- expect { try CGRect.convert(from: ["x": x]) }.to(throwError {
310
+ expect { try CGRect.convert(from: ["x": x], appContext: appContext) }.to(throwError {
285
311
  expect($0).to(beAKindOf(Conversions.MissingKeysException<Double>.self))
286
312
  expect(($0 as! CodedError).description) == Conversions.MissingKeysException<Double>(["y", "width", "height"]).description
287
313
  })
288
314
  }
289
315
 
290
316
  it("throws when dict has uncastable keys") {
291
- expect { try CGRect.convert(from: ["x": x, "y": nil, "width": width, "height": "\(height)"]) }.to(throwError {
317
+ expect { try CGRect.convert(from: ["x": x, "y": nil, "width": width, "height": "\(height)"], appContext: appContext) }.to(throwError {
292
318
  expect($0).to(beAKindOf(Conversions.CastingValuesException<Double>.self))
293
319
  expect(($0 as! CodedError).description) == Conversions.CastingValuesException<Double>(["y", "height"]).description
294
320
  })
@@ -303,7 +329,7 @@ class ConvertiblesSpec: ExpoSpec {
303
329
  expect(color.components?[3]) == alpha / 255.0
304
330
  }
305
331
  func testInvalidHexColor(_ hex: String) {
306
- expect { try CGColor.convert(from: hex) }.to(throwError {
332
+ expect { try CGColor.convert(from: hex, appContext: appContext) }.to(throwError {
307
333
  expect($0).to(beAKindOf(Conversions.InvalidHexColorException.self))
308
334
  expect(($0 as! CodedError).description) == Conversions.InvalidHexColorException(hex).description
309
335
  })
@@ -311,37 +337,37 @@ class ConvertiblesSpec: ExpoSpec {
311
337
 
312
338
  it("converts from ARGB int") {
313
339
  // NOTE: int representation has alpha channel at the beginning
314
- let color = try CGColor.convert(from: 0x5147AC7F)
340
+ let color = try CGColor.convert(from: 0x5147AC7F, appContext: appContext)
315
341
  testColorComponents(color, 0x47, 0xAC, 0x7F, 0x51)
316
342
  }
317
343
 
318
344
  it("converts from RGBA hex string") {
319
- let color = try CGColor.convert(from: "47AC7F51")
345
+ let color = try CGColor.convert(from: "47AC7F51", appContext: appContext)
320
346
  testColorComponents(color, 0x47, 0xAC, 0x7F, 0x51)
321
347
  }
322
348
 
323
349
  it("converts from #RGBA hex string") {
324
- let color = try CGColor.convert(from: " #47AC7F51")
350
+ let color = try CGColor.convert(from: " #47AC7F51", appContext: appContext)
325
351
  testColorComponents(color, 0x47, 0xAC, 0x7F, 0x51)
326
352
  }
327
353
 
328
354
  it("converts from 3-character shorthand hex string") {
329
- let color = try CGColor.convert(from: "C2B ")
355
+ let color = try CGColor.convert(from: "C2B ", appContext: appContext)
330
356
  testColorComponents(color, 0xCC, 0x22, 0xBB, 0xFF)
331
357
  }
332
358
 
333
359
  it("converts from 4-character shorthand hex string") {
334
- let color = try CGColor.convert(from: " #9EA5 ")
360
+ let color = try CGColor.convert(from: " #9EA5 ", appContext: appContext)
335
361
  testColorComponents(color, 0x99, 0xEE, 0xAA, 0x55)
336
362
  }
337
363
 
338
364
  it("converts from CSS named color") {
339
- let papayawhip = try CGColor.convert(from: "papayawhip")
365
+ let papayawhip = try CGColor.convert(from: "papayawhip", appContext: appContext)
340
366
  testColorComponents(papayawhip, 0xFF, 0xEF, 0xD5, 0xFF)
341
367
  }
342
368
 
343
369
  it("converts from transparent") {
344
- let transparent = try CGColor.convert(from: "transparent")
370
+ let transparent = try CGColor.convert(from: "transparent", appContext: appContext)
345
371
  expect(transparent.alpha) == .zero
346
372
  }
347
373
 
@@ -356,7 +382,7 @@ class ConvertiblesSpec: ExpoSpec {
356
382
 
357
383
  it("throws when int overflows") {
358
384
  let hex = 0xBBAA88FF2
359
- expect { try CGColor.convert(from: hex) }.to(throwError {
385
+ expect { try CGColor.convert(from: hex, appContext: appContext) }.to(throwError {
360
386
  expect($0).to(beAKindOf(Conversions.HexColorOverflowException.self))
361
387
  expect(($0 as! CodedError).description) == Conversions.HexColorOverflowException(UInt64(hex)).description
362
388
  })
@@ -7,6 +7,8 @@ import ExpoModulesTestCore
7
7
 
8
8
  final class DynamicTypeSpec: ExpoSpec {
9
9
  override func spec() {
10
+ let appContext = AppContext.create()
11
+
10
12
  // MARK: - DynamicRawType
11
13
 
12
14
  describe("DynamicRawType") {
@@ -17,20 +19,20 @@ final class DynamicTypeSpec: ExpoSpec {
17
19
  }
18
20
  describe("casts") {
19
21
  it("succeeds") {
20
- expect(try (~String.self).cast("expo") as? String) == "expo"
21
- expect(try (~Double.self).cast(2.1) as? Double) == 2.1
22
- expect(try (~Bool.self).cast(false) as? Bool) == false
22
+ expect(try (~String.self).cast("expo", appContext: appContext) as? String) == "expo"
23
+ expect(try (~Double.self).cast(2.1, appContext: appContext) as? Double) == 2.1
24
+ expect(try (~Bool.self).cast(false, appContext: appContext) as? Bool) == false
23
25
  }
24
26
  it("throws NullCastException") {
25
27
  let value: Double? = nil
26
28
  let anyValue = value as Any
27
29
 
28
- expect { try (~Double.self).cast(anyValue) }.to(
30
+ expect { try (~Double.self).cast(anyValue, appContext: appContext) }.to(
29
31
  throwError(errorType: Conversions.NullCastException<Double>.self)
30
32
  )
31
33
  }
32
34
  it("throws CastingException") {
33
- expect { try (~String.self).cast(true) }.to(
35
+ expect { try (~String.self).cast(true, appContext: appContext) }.to(
34
36
  throwError(errorType: Conversions.CastingException<String>.self)
35
37
  )
36
38
  }
@@ -72,13 +74,13 @@ final class DynamicTypeSpec: ExpoSpec {
72
74
  }
73
75
  describe("casts") {
74
76
  it("succeeds") {
75
- expect(try (~[Double].self).cast([1.2, 3.4]) as? [Double]) == [1.2, 3.4]
76
- expect(try (~[[String]].self).cast([["hello", "expo"]]) as? [[String]]) == [["hello", "expo"]]
77
+ expect(try (~[Double].self).cast([1.2, 3.4], appContext: appContext) as? [Double]) == [1.2, 3.4]
78
+ expect(try (~[[String]].self).cast([["hello", "expo"]], appContext: appContext) as? [[String]]) == [["hello", "expo"]]
77
79
  }
78
80
  it("casts arrays") {
79
81
  let value = 9.9
80
82
  let anyValue = [value] as [Any]
81
- let result = try (~[Double].self).cast(anyValue) as! [Any]
83
+ let result = try (~[Double].self).cast(anyValue, appContext: appContext) as! [Any]
82
84
 
83
85
  expect(result).to(beAKindOf([Double].self))
84
86
  expect(result as? [Double]) == [value]
@@ -86,11 +88,11 @@ final class DynamicTypeSpec: ExpoSpec {
86
88
  it("arrayizes single element") {
87
89
  // The dynamic array type can arrayize the single element
88
90
  // if only the array element's dynamic type can cast it.
89
- expect(try (~[Int].self).cast(50) as? [Int]) == [50]
90
- expect(try (~[String].self).cast("not an array") as? [String]) == ["not an array"]
91
+ expect(try (~[Int].self).cast(50, appContext: appContext) as? [Int]) == [50]
92
+ expect(try (~[String].self).cast("not an array", appContext: appContext) as? [String]) == ["not an array"]
91
93
  }
92
94
  it("throws CastingException") {
93
- expect { try (~[String].self).cast(84) }.to(
95
+ expect { try (~[String].self).cast(84, appContext: appContext) }.to(
94
96
  throwError(errorType: Conversions.CastingException<String>.self)
95
97
  )
96
98
  }
@@ -131,12 +133,12 @@ final class DynamicTypeSpec: ExpoSpec {
131
133
  }
132
134
  describe("casts") {
133
135
  it("succeeds") {
134
- expect(try (~CGPoint.self).cast([2.1, 3.7]) as? CGPoint) == CGPoint(x: 2.1, y: 3.7)
135
- expect(try (~CGVector.self).cast(["dx": 0.8, "dy": 4.1]) as? CGVector) == CGVector(dx: 0.8, dy: 4.1)
136
- expect(try (~URL.self).cast("/test/path") as? URL) == URL(fileURLWithPath: "/test/path")
136
+ expect(try (~CGPoint.self).cast([2.1, 3.7], appContext: appContext) as? CGPoint) == CGPoint(x: 2.1, y: 3.7)
137
+ expect(try (~CGVector.self).cast(["dx": 0.8, "dy": 4.1], appContext: appContext) as? CGVector) == CGVector(dx: 0.8, dy: 4.1)
138
+ expect(try (~URL.self).cast("/test/path", appContext: appContext) as? URL) == URL(fileURLWithPath: "/test/path")
137
139
  }
138
140
  it("throws ConvertingException") {
139
- expect { try (~CGRect.self).cast("not a rect") as? CGRect }.to(
141
+ expect { try (~CGRect.self).cast("not a rect", appContext: appContext) as? CGRect }.to(
140
142
  throwError(errorType: Conversions.ConvertingException<CGRect>.self)
141
143
  )
142
144
  }
@@ -185,16 +187,16 @@ final class DynamicTypeSpec: ExpoSpec {
185
187
  }
186
188
  describe("casts") {
187
189
  it("succeeds") {
188
- expect(try (~StringTestEnum.self).cast("expo") as? StringTestEnum) == .expo
189
- expect(try (~IntTestEnum.self).cast(1) as? IntTestEnum) == .positive
190
+ expect(try (~StringTestEnum.self).cast("expo", appContext: appContext) as? StringTestEnum) == .expo
191
+ expect(try (~IntTestEnum.self).cast(1, appContext: appContext) as? IntTestEnum) == .positive
190
192
  }
191
193
  it("throws EnumNoSuchValueException") {
192
- expect { try (~StringTestEnum.self).cast("react native") as? StringTestEnum }.to(
194
+ expect { try (~StringTestEnum.self).cast("react native", appContext: appContext) as? StringTestEnum }.to(
193
195
  throwError(errorType: EnumNoSuchValueException.self)
194
196
  )
195
197
  }
196
198
  it("throws EnumCastingException") {
197
- expect { try (~IntTestEnum.self).cast(true) as? StringTestEnum }.to(
199
+ expect { try (~IntTestEnum.self).cast(true, appContext: appContext) as? StringTestEnum }.to(
198
200
  throwError(errorType: EnumCastingException.self)
199
201
  )
200
202
  }
@@ -234,12 +236,12 @@ final class DynamicTypeSpec: ExpoSpec {
234
236
  }
235
237
  describe("casts") {
236
238
  it("succeeds") {
237
- expect(try (~String?.self).cast("expo") as? String) == "expo"
238
- expect(try (~Bool?.self).cast(false) as? Bool) == false
239
+ expect(try (~String?.self).cast("expo", appContext: appContext) as? String) == "expo"
240
+ expect(try (~Bool?.self).cast(false, appContext: appContext) as? Bool) == false
239
241
  }
240
242
  it("succeeds with nil") {
241
243
  let value: Double? = nil
242
- let result = try (~Double?.self).cast(value as Any)
244
+ let result = try (~Double?.self).cast(value as Any, appContext: appContext)
243
245
 
244
246
  expect(result).to(beAKindOf(Double?.self))
245
247
 
@@ -249,12 +251,12 @@ final class DynamicTypeSpec: ExpoSpec {
249
251
  }
250
252
  it("succeeds with NSNull") {
251
253
  let value = NSNull()
252
- let result = try (~Double?.self).cast(value as Any)
254
+ let result = try (~Double?.self).cast(value as Any, appContext: appContext)
253
255
  expect(result).to(beAKindOf(Double?.self))
254
256
  expect(Optional.isNil(result)) == true
255
257
  }
256
258
  it("throws CastingException") {
257
- expect { try (~Double?.self).cast("a string") as? Double }.to(
259
+ expect { try (~Double?.self).cast("a string", appContext: appContext) as? Double }.to(
258
260
  throwError(errorType: Conversions.CastingException<Double>.self)
259
261
  )
260
262
  }
@@ -296,16 +298,16 @@ final class DynamicTypeSpec: ExpoSpec {
296
298
  it("succeeds") {
297
299
  let appContext = AppContext.create()
298
300
  let nativeObject = TestSharedObject()
299
- let jsObjectValue = try appContext.runtime!.eval("({})")
301
+ let jsObjectValue = try appContext.runtime.eval("({})")
300
302
 
301
303
  SharedObjectRegistry.add(native: nativeObject, javaScript: try jsObjectValue.asObject())
302
304
 
303
305
  // `DynamicSharedObjectType` only supports casting
304
306
  // from `JavaScriptValue`, but not from `JavaScriptObject`.
305
- expect(try (~TestSharedObject.self).cast(jsObjectValue) as? TestSharedObject) === nativeObject
307
+ expect(try (~TestSharedObject.self).cast(jsValue: jsObjectValue, appContext: appContext) as? TestSharedObject) === nativeObject
306
308
  }
307
309
  it("throws NativeSharedObjectNotFoundException") {
308
- expect { try (~TestSharedObject.self).cast("a string") as? TestSharedObject }.to(
310
+ expect { try (~TestSharedObject.self).cast("a string", appContext: appContext) as? TestSharedObject }.to(
309
311
  throwError(errorType: NativeSharedObjectNotFoundException.self)
310
312
  )
311
313
  }
@@ -6,6 +6,8 @@ import ExpoModulesTestCore
6
6
 
7
7
  final class EitherSpec: ExpoSpec {
8
8
  override func spec() {
9
+ let appContext = AppContext.create()
10
+
9
11
  describe("Either") {
10
12
  it("is the first type") {
11
13
  let either = Either<String, Int>("string")
@@ -33,16 +35,16 @@ final class EitherSpec: ExpoSpec {
33
35
  expect(value).notTo(beNil())
34
36
  }
35
37
  it("converts as convertible") {
36
- let either = try Either<String, Int>.convert(from: 123)
38
+ let either = try Either<String, Int>.convert(from: 123, appContext: appContext)
37
39
  expect(either.is(String.self)) == false
38
40
  expect(either.is(Int.self)) == true
39
41
  }
40
42
  it("throws when converting from neither type") {
41
- expect({ try Either<String, Int>.convert(from: true) }).to(throwError(errorType: NeitherTypeException.self))
43
+ expect({ try Either<String, Int>.convert(from: true, appContext: appContext) }).to(throwError(errorType: NeitherTypeException.self))
42
44
  }
43
45
 
44
46
  it("supports arrays") {
45
- let either = try Either<String, [String]>.convert(from: ["foo"])
47
+ let either = try Either<String, [String]>.convert(from: ["foo"], appContext: appContext)
46
48
  let value: [String]? = either.get()
47
49
 
48
50
  expect(either.is([String].self)) == true
@@ -50,7 +52,7 @@ final class EitherSpec: ExpoSpec {
50
52
  }
51
53
 
52
54
  it("supports convertibles (UIColor)") {
53
- let either = try Either<Int, UIColor>.convert(from: "blue")
55
+ let either = try Either<Int, UIColor>.convert(from: "blue", appContext: appContext)
54
56
  let color: UIColor? = either.get()
55
57
 
56
58
  expect(either.is(UIColor.self)) == true
@@ -62,7 +64,7 @@ final class EitherSpec: ExpoSpec {
62
64
  @Field
63
65
  var foo: String
64
66
  }
65
- let either = try Either<String, TestRecord>.convert(from: ["foo": "bar"])
67
+ let either = try Either<String, TestRecord>.convert(from: ["foo": "bar"], appContext: appContext)
66
68
  let record: TestRecord? = either.get()
67
69
 
68
70
  expect(either.is(TestRecord.self)) == true
@@ -88,7 +90,7 @@ final class EitherSpec: ExpoSpec {
88
90
  expect(value).notTo(beNil())
89
91
  }
90
92
  it("throws when converting from neither type") {
91
- expect({ try EitherOfThree<String, Int, Double>.convert(from: false) }).to(throwError(errorType: NeitherTypeException.self))
93
+ expect({ try EitherOfThree<String, Int, Double>.convert(from: false, appContext: appContext) }).to(throwError(errorType: NeitherTypeException.self))
92
94
  }
93
95
  }
94
96
  describe("EitherOfFour") {
@@ -112,7 +114,7 @@ final class EitherSpec: ExpoSpec {
112
114
  expect(value).notTo(beNil())
113
115
  }
114
116
  it("throws when converting from neither type") {
115
- expect({ try EitherOfFour<String, Int, Double, Bool>.convert(from: [1, 2]) }).to(throwError(errorType: NeitherTypeException.self))
117
+ expect({ try EitherOfFour<String, Int, Double, Bool>.convert(from: [1, 2], appContext: appContext) }).to(throwError(errorType: NeitherTypeException.self))
116
118
  }
117
119
  }
118
120
  }
@@ -7,7 +7,7 @@ import ExpoModulesTestCore
7
7
  class ExpoModulesSpec: ExpoSpec {
8
8
  override func spec() {
9
9
  let appContext = AppContext.create()
10
- let runtime = appContext.runtime
10
+ let runtime = try! appContext.runtime
11
11
  let testModuleName = "TestModule"
12
12
  let testFunctionName = "testFunction"
13
13
  let throwingFunctionName = "throwingFunction"
@@ -33,23 +33,23 @@ class ExpoModulesSpec: ExpoSpec {
33
33
 
34
34
  describe("host object") {
35
35
  it("is defined") {
36
- expect(try! runtime?.eval("'ExpoModules' in this").asBool()) === true
36
+ expect(try! runtime.eval("'ExpoModules' in this").asBool()) === true
37
37
  }
38
38
 
39
39
  it("has native module defined") {
40
- expect(try! runtime?.eval("'\(testModuleName)' in ExpoModules").asBool()) === true
40
+ expect(try! runtime.eval("'\(testModuleName)' in ExpoModules").asBool()) === true
41
41
  }
42
42
 
43
43
  it("can access native module") {
44
- let nativeModule = try! runtime?.eval("expo.modules.\(testModuleName)")
45
- expect(nativeModule?.isUndefined()) == false
46
- expect(nativeModule?.isObject()) == true
47
- expect(nativeModule?.getRaw()).notTo(beNil())
44
+ let nativeModule = try runtime.eval("expo.modules.\(testModuleName)")
45
+ expect(nativeModule.isUndefined()) == false
46
+ expect(nativeModule.isObject()) == true
47
+ expect(nativeModule.getRaw()).notTo(beNil())
48
48
  }
49
49
 
50
50
  it("has keys for registered modules") {
51
51
  let registeredModuleNames = appContext.moduleRegistry.getModuleNames()
52
- let keys = try! runtime?.eval("Object.keys(ExpoModules)").asArray().compactMap {
52
+ let keys = try runtime.eval("Object.keys(ExpoModules)").asArray().compactMap {
53
53
  return try! $0?.asString()
54
54
  }
55
55
  expect(keys).to(contain(registeredModuleNames))
@@ -58,7 +58,7 @@ class ExpoModulesSpec: ExpoSpec {
58
58
 
59
59
  describe("module") {
60
60
  it("exposes constants") {
61
- let dict = try! runtime!.eval("expo.modules.TestModule").asDict()
61
+ let dict = try runtime.eval("expo.modules.TestModule").asDict()
62
62
 
63
63
  dict.forEach { (key: String, value: Any) in
64
64
  expect(value) === dict[key]!
@@ -66,17 +66,17 @@ class ExpoModulesSpec: ExpoSpec {
66
66
  }
67
67
 
68
68
  it("has function") {
69
- expect(try! runtime?.eval("typeof expo.modules.TestModule.\(testFunctionName)").asString()) == "function"
70
- expect(try! runtime?.eval("expo.modules.TestModule.\(testFunctionName)").isFunction()) == true
69
+ expect(try runtime.eval("typeof expo.modules.TestModule.\(testFunctionName)").asString()) == "function"
70
+ expect(try runtime.eval("expo.modules.TestModule.\(testFunctionName)").isFunction()) == true
71
71
  }
72
72
 
73
73
  it("calls function") {
74
- expect(try! runtime?.eval("expo.modules.TestModule.\(testFunctionName)()").asDouble()) == Double.pi
74
+ expect(try runtime.eval("expo.modules.TestModule.\(testFunctionName)()").asDouble()) == Double.pi
75
75
  }
76
76
 
77
77
  it("throws from sync function") {
78
78
  // Invoke the throwing function and return the error (eval shouldn't rethrow here)
79
- let error = try! runtime!.eval("try { expo.modules.TestModule.\(throwingFunctionName)() } catch (error) { error }").asObject()
79
+ let error = try runtime.eval("try { expo.modules.TestModule.\(throwingFunctionName)() } catch (error) { error }").asObject()
80
80
 
81
81
  // We just check if it contains the description — they won't be equal for the following reasons:
82
82
  // - the `exceptionToThrow` is just the root cause, in fact it returns `FunctionCallException`