expo-modules-core 0.9.2 → 0.10.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 +18 -5
- package/android/CMakeLists.txt +154 -0
- package/android/build.gradle +293 -5
- package/android/src/main/cpp/Exceptions.cpp +22 -0
- package/android/src/main/cpp/Exceptions.h +38 -0
- package/android/src/main/cpp/ExpoModulesHostObject.cpp +47 -0
- package/android/src/main/cpp/ExpoModulesHostObject.h +32 -0
- package/android/src/main/cpp/JNIFunctionBody.cpp +29 -0
- package/android/src/main/cpp/JNIFunctionBody.h +50 -0
- package/android/src/main/cpp/JNIInjector.cpp +19 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +122 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.h +96 -0
- package/android/src/main/cpp/JSIObjectWrapper.h +33 -0
- package/android/src/main/cpp/JSITypeConverter.h +84 -0
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +138 -0
- package/android/src/main/cpp/JavaScriptModuleObject.h +122 -0
- package/android/src/main/cpp/JavaScriptObject.cpp +125 -0
- package/android/src/main/cpp/JavaScriptObject.h +131 -0
- package/android/src/main/cpp/JavaScriptRuntime.cpp +127 -0
- package/android/src/main/cpp/JavaScriptRuntime.h +87 -0
- package/android/src/main/cpp/JavaScriptValue.cpp +172 -0
- package/android/src/main/cpp/JavaScriptValue.h +78 -0
- package/android/src/main/cpp/MethodMetadata.cpp +230 -0
- package/android/src/main/cpp/MethodMetadata.h +92 -0
- package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +2 -0
- package/android/src/main/java/expo/modules/core/errors/ContextDestroyedException.kt +7 -0
- package/android/src/main/java/expo/modules/interfaces/permissions/Permissions.java +30 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +49 -1
- package/android/src/main/java/expo/modules/kotlin/ConcatIterator.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +15 -12
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +39 -3
- package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +2 -2
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +13 -0
- package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +2 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +19 -14
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +29 -7
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +13 -13
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +56 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +28 -0
- package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JNIFunctionBody.kt +39 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +89 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +44 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +113 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +35 -0
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +15 -5
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +65 -111
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +35 -2
- package/android/src/main/java/expo/modules/kotlin/providers/AppContextProvider.kt +14 -0
- package/android/src/main/java/expo/modules/kotlin/providers/CurrentActivityProvider.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +19 -2
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +7 -2
- package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +68 -20
- package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +50 -22
- package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +18 -2
- package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +18 -2
- package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +17 -2
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +43 -3
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +5 -0
- package/build/NativeModulesProxy.native.d.ts.map +1 -1
- package/build/NativeModulesProxy.native.js +9 -3
- package/build/NativeModulesProxy.native.js.map +1 -1
- package/ios/AppDelegates/EXAppDelegatesLoader.m +1 -2
- package/ios/ExpoModulesCore.podspec +1 -1
- package/ios/JSI/EXJSIConversions.mm +6 -0
- package/ios/JSI/EXJSIInstaller.h +15 -21
- package/ios/JSI/EXJSIInstaller.mm +39 -3
- package/ios/JSI/EXJSIUtils.h +47 -3
- package/ios/JSI/EXJSIUtils.mm +88 -4
- package/ios/JSI/EXJavaScriptObject.h +11 -18
- package/ios/JSI/EXJavaScriptObject.mm +37 -18
- package/ios/JSI/EXJavaScriptRuntime.h +43 -9
- package/ios/JSI/EXJavaScriptRuntime.mm +70 -27
- package/ios/JSI/EXJavaScriptTypedArray.h +30 -0
- package/ios/JSI/EXJavaScriptTypedArray.mm +29 -0
- package/ios/JSI/EXJavaScriptValue.h +3 -2
- package/ios/JSI/EXJavaScriptValue.mm +17 -20
- package/ios/JSI/EXJavaScriptWeakObject.h +23 -0
- package/ios/JSI/EXJavaScriptWeakObject.mm +53 -0
- package/ios/JSI/EXObjectDeallocator.h +27 -0
- package/ios/JSI/ExpoModulesHostObject.h +3 -3
- package/ios/JSI/ExpoModulesHostObject.mm +4 -4
- package/ios/JSI/JavaScriptRuntime.swift +38 -1
- package/ios/JSI/JavaScriptValue.swift +7 -0
- package/ios/JSI/TypedArray.cpp +67 -0
- package/ios/JSI/TypedArray.h +46 -0
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -11
- package/ios/NativeModulesProxy/EXNativeModulesProxy.h +17 -10
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +85 -77
- package/ios/NativeModulesProxy/NativeModulesProxyModule.swift +17 -0
- package/ios/Services/EXReactNativeEventEmitter.h +2 -2
- package/ios/Services/EXReactNativeEventEmitter.m +11 -6
- package/ios/Swift/AppContext.swift +208 -28
- package/ios/Swift/Arguments/AnyArgument.swift +18 -0
- package/ios/Swift/Arguments/{Types/EnumArgumentType.swift → EnumArgument.swift} +2 -17
- package/ios/Swift/Classes/ClassComponent.swift +95 -0
- package/ios/Swift/Classes/ClassComponentElement.swift +33 -0
- package/ios/Swift/Classes/ClassComponentElementsBuilder.swift +34 -0
- package/ios/Swift/Classes/ClassComponentFactories.swift +96 -0
- package/ios/Swift/DynamicTypes/AnyDynamicType.swift +44 -0
- package/ios/Swift/DynamicTypes/DynamicArrayType.swift +56 -0
- package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicEnumType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +63 -0
- package/ios/Swift/DynamicTypes/DynamicRawType.swift +33 -0
- package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +37 -0
- package/ios/Swift/DynamicTypes/DynamicType.swift +39 -0
- package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +46 -0
- package/ios/Swift/Exceptions/CodedError.swift +1 -1
- package/ios/Swift/Exceptions/Exception.swift +8 -6
- package/ios/Swift/Exceptions/UnexpectedException.swift +2 -1
- package/ios/Swift/ExpoBridgeModule.m +5 -0
- package/ios/Swift/ExpoBridgeModule.swift +65 -0
- package/ios/Swift/Functions/AnyFunction.swift +33 -31
- package/ios/Swift/Functions/AsyncFunctionComponent.swift +196 -59
- package/ios/Swift/Functions/SyncFunctionComponent.swift +142 -58
- package/ios/Swift/JavaScriptUtils.swift +32 -57
- package/ios/Swift/Logging/LogHandlers.swift +39 -0
- package/ios/Swift/Logging/LogType.swift +62 -0
- package/ios/Swift/Logging/Logger.swift +198 -0
- package/ios/Swift/ModuleHolder.swift +19 -54
- package/ios/Swift/ModuleRegistry.swift +7 -1
- package/ios/Swift/Modules/AnyModule.swift +3 -3
- package/ios/Swift/ModulesProvider.swift +2 -0
- package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +37 -0
- package/ios/Swift/Objects/ObjectDefinition.swift +74 -1
- package/ios/Swift/Objects/ObjectDefinitionComponents.swift +77 -68
- package/ios/Swift/Objects/PropertyComponent.swift +147 -0
- package/ios/Swift/Promise.swift +12 -3
- package/ios/Swift/Records/Field.swift +2 -2
- package/ios/Swift/SharedObjects/SharedObject.swift +20 -0
- package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +129 -0
- package/ios/Swift/TypedArrays/AnyTypedArray.swift +11 -0
- package/ios/Swift/TypedArrays/ConcreteTypedArrays.swift +56 -0
- package/ios/Swift/TypedArrays/GenericTypedArray.swift +49 -0
- package/ios/Swift/TypedArrays/TypedArray.swift +80 -0
- package/ios/Swift/Utilities.swift +28 -0
- package/ios/Swift/Views/ConcreteViewProp.swift +3 -3
- package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +2 -2
- package/ios/Tests/ClassComponentSpec.swift +210 -0
- package/ios/Tests/DynamicTypeSpec.swift +336 -0
- package/ios/Tests/EnumArgumentSpec.swift +48 -0
- package/ios/Tests/ExpoModulesSpec.swift +17 -3
- package/ios/Tests/FunctionSpec.swift +167 -118
- package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
- package/ios/Tests/PropertyComponentSpec.swift +95 -0
- package/ios/Tests/SharedObjectRegistrySpec.swift +109 -0
- package/ios/Tests/TypedArraysSpec.swift +136 -0
- package/package.json +2 -2
- package/src/NativeModulesProxy.native.ts +13 -3
- package/src/ts-declarations/ExpoModules.d.ts +7 -0
- package/tsconfig.json +1 -1
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +0 -15
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +0 -36
- package/ios/Swift/Arguments/AnyArgumentType.swift +0 -13
- package/ios/Swift/Arguments/ArgumentType.swift +0 -28
- package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +0 -42
- package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +0 -16
- package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +0 -49
- package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +0 -15
- package/ios/Swift/Arguments/Types/RawArgumentType.swift +0 -25
- package/ios/Swift/Functions/ConcreteFunction.swift +0 -103
- package/ios/Swift/SwiftInteropBridge.swift +0 -155
- package/ios/Tests/ArgumentTypeSpec.swift +0 -143
|
@@ -4,173 +4,222 @@ import ExpoModulesTestCore
|
|
|
4
4
|
|
|
5
5
|
class FunctionSpec: ExpoSpec {
|
|
6
6
|
override func spec() {
|
|
7
|
-
let appContext = AppContext()
|
|
7
|
+
let appContext = AppContext.create()
|
|
8
8
|
let functionName = "test function name"
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
context("native") {
|
|
11
|
+
func testFunctionReturning<T: Equatable>(value returnValue: T) {
|
|
12
|
+
waitUntil { done in
|
|
13
|
+
mockModuleHolder(appContext) {
|
|
14
|
+
AsyncFunction(functionName) {
|
|
15
|
+
return returnValue
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
.call(function: functionName, args: []) { result in
|
|
19
|
+
let value = try! result.get()
|
|
20
|
+
|
|
21
|
+
expect(value).notTo(beNil())
|
|
22
|
+
expect(value).to(beAKindOf(T.self))
|
|
23
|
+
expect(value as? T).to(equal(returnValue))
|
|
24
|
+
done()
|
|
15
25
|
}
|
|
16
|
-
}
|
|
17
|
-
.call(function: functionName, args: []) { value, _ in
|
|
18
|
-
expect(value).notTo(beNil())
|
|
19
|
-
expect(value).to(beAKindOf(T.self))
|
|
20
|
-
expect(value as? T).to(equal(returnValue))
|
|
21
|
-
done()
|
|
22
26
|
}
|
|
23
27
|
}
|
|
24
|
-
}
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
it("is called") {
|
|
30
|
+
waitUntil { done in
|
|
31
|
+
mockModuleHolder(appContext) {
|
|
32
|
+
AsyncFunction(functionName) {
|
|
33
|
+
done()
|
|
34
|
+
}
|
|
31
35
|
}
|
|
36
|
+
.call(function: functionName, args: [])
|
|
32
37
|
}
|
|
33
|
-
.call(function: functionName, args: [])
|
|
34
38
|
}
|
|
35
|
-
}
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
it("returns bool values") {
|
|
41
|
+
testFunctionReturning(value: true)
|
|
42
|
+
testFunctionReturning(value: false)
|
|
43
|
+
testFunctionReturning(value: [true, false])
|
|
44
|
+
}
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
it("returns int values") {
|
|
47
|
+
testFunctionReturning(value: 1_234)
|
|
48
|
+
testFunctionReturning(value: [2, 1, 3, 7])
|
|
49
|
+
}
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
it("returns double values") {
|
|
52
|
+
testFunctionReturning(value: 3.14)
|
|
53
|
+
testFunctionReturning(value: [0, 1.1, 2.2])
|
|
54
|
+
}
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
it("returns string values") {
|
|
57
|
+
testFunctionReturning(value: "a string")
|
|
58
|
+
testFunctionReturning(value: ["expo", "modules", "core"])
|
|
59
|
+
}
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
it("is called with nil value") {
|
|
62
|
+
let str: String? = nil
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
mockModuleHolder(appContext) {
|
|
65
|
+
AsyncFunction(functionName) { (a: String?) in
|
|
66
|
+
expect(a == nil) == true
|
|
67
|
+
}
|
|
64
68
|
}
|
|
69
|
+
.callSync(function: functionName, args: [str as Any])
|
|
65
70
|
}
|
|
66
|
-
.callSync(function: functionName, args: [str as Any])
|
|
67
|
-
}
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
it("is called with an array of arrays") {
|
|
73
|
+
let array: [[String]] = [["expo"]]
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
mockModuleHolder(appContext) {
|
|
76
|
+
AsyncFunction(functionName) { (a: [[String]]) in
|
|
77
|
+
expect(a.first!.first) == array.first!.first
|
|
78
|
+
}
|
|
75
79
|
}
|
|
80
|
+
.callSync(function: functionName, args: [array])
|
|
76
81
|
}
|
|
77
|
-
.callSync(function: functionName, args: [array])
|
|
78
|
-
}
|
|
79
82
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
83
|
+
describe("converting dicts to records") {
|
|
84
|
+
struct TestRecord: Record {
|
|
85
|
+
@Field var property: String = "expo"
|
|
86
|
+
@Field var optionalProperty: Int?
|
|
87
|
+
@Field("propertyWithCustomKey") var customKeyProperty: String = "expo"
|
|
88
|
+
}
|
|
89
|
+
let dict = [
|
|
90
|
+
"property": "Hello",
|
|
91
|
+
"propertyWithCustomKey": "Expo!"
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
it("converts to simple record when passed as an argument") {
|
|
95
|
+
waitUntil { done in
|
|
96
|
+
mockModuleHolder(appContext) {
|
|
97
|
+
AsyncFunction(functionName) { (a: TestRecord) in
|
|
98
|
+
return a.property
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
.call(function: functionName, args: [dict]) { result in
|
|
102
|
+
let value = try! result.get()
|
|
90
103
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return a.property
|
|
104
|
+
expect(value).notTo(beNil())
|
|
105
|
+
expect(value).to(beAKindOf(String.self))
|
|
106
|
+
expect(value).to(be(dict["property"]))
|
|
107
|
+
done()
|
|
96
108
|
}
|
|
97
109
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
it("converts to record with custom key") {
|
|
113
|
+
waitUntil { done in
|
|
114
|
+
mockModuleHolder(appContext) {
|
|
115
|
+
AsyncFunction(functionName) { (a: TestRecord) in
|
|
116
|
+
return a.customKeyProperty
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
.call(function: functionName, args: [dict]) { result in
|
|
120
|
+
let value = try! result.get()
|
|
121
|
+
expect(value).notTo(beNil())
|
|
122
|
+
expect(value).to(beAKindOf(String.self))
|
|
123
|
+
expect(value).to(be(dict["propertyWithCustomKey"]))
|
|
124
|
+
done()
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
it("returns the record back") {
|
|
130
|
+
waitUntil { done in
|
|
131
|
+
mockModuleHolder(appContext) {
|
|
132
|
+
AsyncFunction(functionName) { (a: TestRecord) in
|
|
133
|
+
return a.toDictionary()
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
.call(function: functionName, args: [dict]) { result in
|
|
137
|
+
let value = try! result.get()
|
|
138
|
+
|
|
139
|
+
expect(value).notTo(beNil())
|
|
140
|
+
expect(value).to(beAKindOf(Record.Dict.self))
|
|
141
|
+
|
|
142
|
+
let valueAsDict = value as! Record.Dict
|
|
143
|
+
|
|
144
|
+
expect(valueAsDict["property"] as? String).to(equal(dict["property"]))
|
|
145
|
+
expect(valueAsDict["propertyWithCustomKey"] as? String).to(equal(dict["propertyWithCustomKey"]))
|
|
146
|
+
done()
|
|
147
|
+
}
|
|
103
148
|
}
|
|
104
149
|
}
|
|
105
150
|
}
|
|
106
151
|
|
|
107
|
-
it("
|
|
152
|
+
it("throws when called with more arguments than expected") {
|
|
108
153
|
waitUntil { done in
|
|
109
154
|
mockModuleHolder(appContext) {
|
|
110
|
-
AsyncFunction(functionName) { (
|
|
111
|
-
return
|
|
155
|
+
AsyncFunction(functionName) { (_: Int) in
|
|
156
|
+
return "something"
|
|
112
157
|
}
|
|
113
158
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
159
|
+
// Function expects one argument, let's give it more.
|
|
160
|
+
.call(function: functionName, args: [1, 2]) { result in
|
|
161
|
+
switch result {
|
|
162
|
+
case .failure(let error):
|
|
163
|
+
expect(error).notTo(beNil())
|
|
164
|
+
expect(error).to(beAKindOf(InvalidArgsNumberException.self))
|
|
165
|
+
case .success(_):
|
|
166
|
+
fail()
|
|
167
|
+
}
|
|
118
168
|
done()
|
|
119
169
|
}
|
|
120
170
|
}
|
|
121
171
|
}
|
|
122
172
|
|
|
123
|
-
it("
|
|
173
|
+
it("throws when called with arguments of incompatible types") {
|
|
124
174
|
waitUntil { done in
|
|
125
175
|
mockModuleHolder(appContext) {
|
|
126
|
-
AsyncFunction(functionName) { (
|
|
127
|
-
return
|
|
176
|
+
AsyncFunction(functionName) { (_: String) in
|
|
177
|
+
return "something"
|
|
128
178
|
}
|
|
129
179
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
180
|
+
// Function expects a string, let's give it a number.
|
|
181
|
+
.call(function: functionName, args: [1]) { result in
|
|
182
|
+
switch result {
|
|
183
|
+
case .failure(let error):
|
|
184
|
+
expect(error).notTo(beNil())
|
|
185
|
+
expect(error).to(beAKindOf(ArgumentCastException.self))
|
|
186
|
+
expect(error.isCausedBy(Conversions.CastingException<String>.self)) == true
|
|
187
|
+
case .success(_):
|
|
188
|
+
fail()
|
|
189
|
+
}
|
|
138
190
|
done()
|
|
139
191
|
}
|
|
140
192
|
}
|
|
141
193
|
}
|
|
142
194
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
195
|
+
|
|
196
|
+
context("JavaScript") {
|
|
197
|
+
let runtime = appContext.runtime
|
|
198
|
+
|
|
199
|
+
beforeSuite {
|
|
200
|
+
appContext.moduleRegistry.register(holder: mockModuleHolder(appContext) {
|
|
201
|
+
Name("TestModule")
|
|
202
|
+
|
|
203
|
+
Function("returnPi") { Double.pi }
|
|
204
|
+
|
|
205
|
+
Function("returnNull") { () -> Double? in
|
|
206
|
+
return nil
|
|
149
207
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
expect(error).notTo(beNil())
|
|
154
|
-
expect(error).to(beAKindOf(InvalidArgsNumberException.self))
|
|
155
|
-
done()
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
it("throws when called with arguments of incompatible types") {
|
|
161
|
-
waitUntil { done in
|
|
162
|
-
mockModuleHolder(appContext) {
|
|
163
|
-
AsyncFunction(functionName) { (_: String) in
|
|
164
|
-
return "something"
|
|
208
|
+
|
|
209
|
+
Function("isArgNull") { (arg: Double?) -> Bool in
|
|
210
|
+
return arg == nil
|
|
165
211
|
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
212
|
+
})
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
it("returns values") {
|
|
216
|
+
expect(try runtime?.eval("ExpoModules.TestModule.returnPi()").asDouble()) == Double.pi
|
|
217
|
+
expect(try runtime?.eval("ExpoModules.TestModule.returnNull()").isNull()) == true
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
it("accepts optional arguments") {
|
|
221
|
+
expect(try runtime?.eval("ExpoModules.TestModule.isArgNull(3.14)").asBool()) == false
|
|
222
|
+
expect(try runtime?.eval("ExpoModules.TestModule.isArgNull(null)").asBool()) == true
|
|
174
223
|
}
|
|
175
224
|
}
|
|
176
225
|
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import ExpoModulesTestCore
|
|
2
|
+
|
|
3
|
+
@testable import ExpoModulesCore
|
|
4
|
+
|
|
5
|
+
class PropertyComponentSpec: ExpoSpec {
|
|
6
|
+
override func spec() {
|
|
7
|
+
describe("property") {
|
|
8
|
+
it("gets the value") {
|
|
9
|
+
let property = Property("test") { return "expo" }
|
|
10
|
+
expect(property.getValue()) == "expo"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
it("sets the value") {
|
|
14
|
+
var value = Int.random(in: 0..<100)
|
|
15
|
+
let property = Property("test")
|
|
16
|
+
.get { value }
|
|
17
|
+
.set { (newValue: Int) in
|
|
18
|
+
value = newValue
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let newValue = Int.random(in: 0..<100)
|
|
22
|
+
property.setValue(newValue)
|
|
23
|
+
|
|
24
|
+
expect(property.getValue()) == value
|
|
25
|
+
expect(value) == newValue
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe("module property") {
|
|
30
|
+
let appContext = AppContext.create()
|
|
31
|
+
let runtime = appContext.runtime
|
|
32
|
+
|
|
33
|
+
beforeSuite {
|
|
34
|
+
class PropertyTestModule: Module {
|
|
35
|
+
func definition() -> ModuleDefinition {
|
|
36
|
+
Name("PropertyTest")
|
|
37
|
+
|
|
38
|
+
Property("readOnly") {
|
|
39
|
+
return "foo"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
var writablePropertyValue = 444
|
|
43
|
+
Property("writable")
|
|
44
|
+
.get {
|
|
45
|
+
return writablePropertyValue
|
|
46
|
+
}
|
|
47
|
+
.set { value in
|
|
48
|
+
writablePropertyValue = value
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
Property("withCaller") { (caller: JavaScriptObject) -> String in
|
|
52
|
+
// Here, the caller is a JS object of the module.
|
|
53
|
+
// Return another property of itself.
|
|
54
|
+
return caller.getProperty("readOnly").getString()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
Property("undefined")
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
appContext.moduleRegistry.register(moduleType: PropertyTestModule.self)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
it("gets read-only property") {
|
|
64
|
+
let value = try runtime?.eval("ExpoModules.PropertyTest.readOnly")
|
|
65
|
+
expect(value?.getString()) == "foo"
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
it("gets writable property") {
|
|
69
|
+
let value = try runtime?.eval("ExpoModules.PropertyTest.writable")
|
|
70
|
+
expect(value?.getInt()) == 444
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
it("sets writable property") {
|
|
74
|
+
try runtime?.eval("ExpoModules.PropertyTest.writable = 777")
|
|
75
|
+
let value = try runtime?.eval("ExpoModules.PropertyTest.writable")
|
|
76
|
+
expect(value?.getInt()) == 777
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
it("is enumerable") {
|
|
80
|
+
let keys = try runtime?.eval("Object.keys(ExpoModules.PropertyTest)").getArray().map { $0.getString() } ?? []
|
|
81
|
+
expect(keys).to(contain("readOnly", "writable", "withCaller", "undefined"))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
it("is called with the caller") {
|
|
85
|
+
let value = try runtime?.eval("ExpoModules.PropertyTest.withCaller")
|
|
86
|
+
expect(value?.getString()) == "foo"
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
it("returns undefined when getter is not specified") {
|
|
90
|
+
let value = try runtime?.eval("ExpoModules.PropertyTest.undefined")
|
|
91
|
+
expect(value?.isUndefined()) == true
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import ExpoModulesTestCore
|
|
4
|
+
|
|
5
|
+
@testable import ExpoModulesCore
|
|
6
|
+
|
|
7
|
+
final class SharedObjectRegistrySpec: ExpoSpec {
|
|
8
|
+
override func spec() {
|
|
9
|
+
let appContext = AppContext.create()
|
|
10
|
+
let runtime = appContext.runtime
|
|
11
|
+
|
|
12
|
+
describe("pullNextId") {
|
|
13
|
+
it("returns nextId") {
|
|
14
|
+
let id = SharedObjectRegistry.nextId
|
|
15
|
+
expect(SharedObjectRegistry.pullNextId()) == id
|
|
16
|
+
}
|
|
17
|
+
it("increments nextId") {
|
|
18
|
+
let id = SharedObjectRegistry.nextId
|
|
19
|
+
SharedObjectRegistry.pullNextId()
|
|
20
|
+
expect(SharedObjectRegistry.nextId) == id + 1
|
|
21
|
+
}
|
|
22
|
+
it("is not increasing size") {
|
|
23
|
+
let size = SharedObjectRegistry.size
|
|
24
|
+
SharedObjectRegistry.pullNextId()
|
|
25
|
+
expect(SharedObjectRegistry.size) == size
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe("add") {
|
|
30
|
+
it("adds using nextId") {
|
|
31
|
+
let nextId = SharedObjectRegistry.nextId
|
|
32
|
+
let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime!.createObject())
|
|
33
|
+
expect(nextId) == id
|
|
34
|
+
}
|
|
35
|
+
it("is increasing size") {
|
|
36
|
+
let size = SharedObjectRegistry.size
|
|
37
|
+
SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime!.createObject())
|
|
38
|
+
expect(SharedObjectRegistry.size) == size + 1
|
|
39
|
+
}
|
|
40
|
+
it("assigns id on native object") {
|
|
41
|
+
let nativeObject = TestSharedObject()
|
|
42
|
+
let id = SharedObjectRegistry.add(native: nativeObject, javaScript: runtime!.createObject())
|
|
43
|
+
expect(nativeObject.sharedObjectId) == id
|
|
44
|
+
}
|
|
45
|
+
it("assigns id on JS object") {
|
|
46
|
+
let jsObject = runtime!.createObject()
|
|
47
|
+
let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: jsObject)
|
|
48
|
+
expect(jsObject.hasProperty(sharedObjectIdPropertyName)) == true
|
|
49
|
+
expect(try! jsObject.getProperty(sharedObjectIdPropertyName).asInt()) == id
|
|
50
|
+
}
|
|
51
|
+
it("saves objects pair") {
|
|
52
|
+
let nativeObject = TestSharedObject()
|
|
53
|
+
let jsObject = runtime!.createObject()
|
|
54
|
+
let id = SharedObjectRegistry.add(native: nativeObject, javaScript: jsObject)
|
|
55
|
+
let pair = SharedObjectRegistry.get(id)
|
|
56
|
+
expect(pair?.native) === nativeObject
|
|
57
|
+
expect(pair?.javaScript.lock()) == jsObject
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
describe("delete") {
|
|
62
|
+
it("deletes objects pair") {
|
|
63
|
+
let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime!.createObject())
|
|
64
|
+
SharedObjectRegistry.delete(id)
|
|
65
|
+
expect(SharedObjectRegistry.get(id)).to(beNil())
|
|
66
|
+
}
|
|
67
|
+
it("resets id on native object") {
|
|
68
|
+
let nativeObject = TestSharedObject()
|
|
69
|
+
let id = SharedObjectRegistry.add(native: nativeObject, javaScript: runtime!.createObject())
|
|
70
|
+
SharedObjectRegistry.delete(id)
|
|
71
|
+
expect(nativeObject.sharedObjectId) == 0
|
|
72
|
+
}
|
|
73
|
+
it("resets id on JS object") {
|
|
74
|
+
let jsObject = runtime!.createObject()
|
|
75
|
+
let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: jsObject)
|
|
76
|
+
SharedObjectRegistry.delete(id)
|
|
77
|
+
expect(try! jsObject.getProperty(sharedObjectIdPropertyName).asInt()) == 0
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
describe("toNativeObject") {
|
|
82
|
+
it("returns native object") {
|
|
83
|
+
let nativeObject = TestSharedObject()
|
|
84
|
+
let jsObject = runtime!.createObject()
|
|
85
|
+
SharedObjectRegistry.add(native: nativeObject, javaScript: jsObject)
|
|
86
|
+
expect(SharedObjectRegistry.toNativeObject(jsObject)) === nativeObject
|
|
87
|
+
}
|
|
88
|
+
it("returns nil") {
|
|
89
|
+
let jsObject = runtime!.createObject()
|
|
90
|
+
expect(SharedObjectRegistry.toNativeObject(jsObject)).to(beNil())
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
describe("toJavaScriptObject") {
|
|
95
|
+
it("returns JS object") {
|
|
96
|
+
let nativeObject = TestSharedObject()
|
|
97
|
+
let jsObject = runtime!.createObject()
|
|
98
|
+
SharedObjectRegistry.add(native: nativeObject, javaScript: jsObject)
|
|
99
|
+
expect(SharedObjectRegistry.toJavaScriptObject(nativeObject)) == jsObject
|
|
100
|
+
}
|
|
101
|
+
it("returns nil") {
|
|
102
|
+
let nativeObject = TestSharedObject()
|
|
103
|
+
expect(SharedObjectRegistry.toJavaScriptObject(nativeObject)).to(beNil())
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
fileprivate final class TestSharedObject: SharedObject {}
|