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
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Generic TypedArray with an associated numeric ContentType (e.g. UInt8, Int16, Double).
|
|
5
|
+
*/
|
|
6
|
+
public class GenericTypedArray<ContentType: Numeric>: TypedArray {
|
|
7
|
+
/**
|
|
8
|
+
The unsafe mutable typed buffer that shares the same memory as the underlying JavaScript `ArrayBuffer`.
|
|
9
|
+
*/
|
|
10
|
+
lazy var buffer = UnsafeMutableBufferPointer<ContentType>(start: pointer, count: length)
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
The unsafe mutable typed pointer to the start of the array buffer.
|
|
14
|
+
*/
|
|
15
|
+
lazy var pointer = rawPointer.bindMemory(to: ContentType.self, capacity: length)
|
|
16
|
+
|
|
17
|
+
public subscript(index: Int) -> ContentType {
|
|
18
|
+
get {
|
|
19
|
+
return buffer[index]
|
|
20
|
+
}
|
|
21
|
+
set {
|
|
22
|
+
buffer[index] = newValue
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
subscript(range: Range<Int>) -> [ContentType] {
|
|
27
|
+
get {
|
|
28
|
+
return Array(buffer[range])
|
|
29
|
+
}
|
|
30
|
+
set {
|
|
31
|
+
var newValues = newValue
|
|
32
|
+
newValues.withUnsafeMutableBufferPointer { newValuesBuffer in
|
|
33
|
+
buffer[range] = newValuesBuffer[0..<(range.upperBound - range.lowerBound)]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
subscript(range: ClosedRange<Int>) -> [ContentType] {
|
|
39
|
+
get {
|
|
40
|
+
return Array(buffer[range])
|
|
41
|
+
}
|
|
42
|
+
set {
|
|
43
|
+
var newValues = newValue
|
|
44
|
+
newValues.withUnsafeMutableBufferPointer { newValuesBuffer in
|
|
45
|
+
buffer[range] = newValuesBuffer[0...(range.upperBound - range.lowerBound)]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
The base class for any type of the typed array.
|
|
5
|
+
*/
|
|
6
|
+
public class TypedArray: AnyTypedArray {
|
|
7
|
+
/**
|
|
8
|
+
Creates a concrete TypedArray from the given JavaScriptTypedArray
|
|
9
|
+
*/
|
|
10
|
+
internal static func create(from jsTypedArray: JavaScriptTypedArray) -> TypedArray {
|
|
11
|
+
switch jsTypedArray.kind {
|
|
12
|
+
case .Int8Array:
|
|
13
|
+
return Int8Array(jsTypedArray)
|
|
14
|
+
case .Int16Array:
|
|
15
|
+
return Int16Array(jsTypedArray)
|
|
16
|
+
case .Int32Array:
|
|
17
|
+
return Int32Array(jsTypedArray)
|
|
18
|
+
case .Uint8Array:
|
|
19
|
+
return Uint8Array(jsTypedArray)
|
|
20
|
+
case .Uint8ClampedArray:
|
|
21
|
+
return Uint8ClampedArray(jsTypedArray)
|
|
22
|
+
case .Uint16Array:
|
|
23
|
+
return Uint16Array(jsTypedArray)
|
|
24
|
+
case .Uint32Array:
|
|
25
|
+
return Uint32Array(jsTypedArray)
|
|
26
|
+
case .Float32Array:
|
|
27
|
+
return Float32Array(jsTypedArray)
|
|
28
|
+
case .Float64Array:
|
|
29
|
+
return Float64Array(jsTypedArray)
|
|
30
|
+
case .BigInt64Array:
|
|
31
|
+
return BigInt64Array(jsTypedArray)
|
|
32
|
+
case .BigUint64Array:
|
|
33
|
+
return BigUint64Array(jsTypedArray)
|
|
34
|
+
@unknown default:
|
|
35
|
+
fatalError("Unknown kind of the TypedArray")
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
A JavaScript object of the underlying typed array.
|
|
41
|
+
*/
|
|
42
|
+
let jsTypedArray: JavaScriptTypedArray
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
The length in bytes from the start of the underlying ArrayBuffer.
|
|
46
|
+
Fixed at construction time and thus read-only.
|
|
47
|
+
*/
|
|
48
|
+
public lazy var byteLength: Int = jsTypedArray.getProperty("byteLength").getInt()
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
The offset in bytes from the start of the underlying ArrayBuffer.
|
|
52
|
+
Fixed at construction time and thus read-only.
|
|
53
|
+
*/
|
|
54
|
+
public lazy var byteOffset: Int = jsTypedArray.getProperty("byteOffset").getInt()
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
Returns the number of elements held in the typed array.
|
|
58
|
+
Fixed at construction time and thus read only.
|
|
59
|
+
*/
|
|
60
|
+
public lazy var length: Int = jsTypedArray.getProperty("length").getInt()
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
The unsafe mutable raw pointer to the start of the array buffer.
|
|
64
|
+
*/
|
|
65
|
+
public lazy var rawPointer: UnsafeMutableRawPointer = jsTypedArray.getUnsafeMutableRawPointer()
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
Returns the kind of the typed array, such as `Int8Array` or `Float32Array`.
|
|
69
|
+
*/
|
|
70
|
+
public var kind: TypedArrayKind {
|
|
71
|
+
return jsTypedArray.kind
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
Initializes the typed array with the given JS typed array.
|
|
76
|
+
*/
|
|
77
|
+
required init(_ jsTypedArray: JavaScriptTypedArray) {
|
|
78
|
+
self.jsTypedArray = jsTypedArray
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Executes the given Swift closure and if it throws, the `NSError` is set on the given `NSErrorPointer` and the original error is rethrown.
|
|
5
|
+
This is especially useful for ObjC<->Swift interop, specifically when the ObjC needs to catch errors thrown by Swift closure.
|
|
6
|
+
*/
|
|
7
|
+
internal func runWithErrorPointer<R>(_ errorPointer: NSErrorPointer, _ closure: () throws -> R) rethrows -> R? {
|
|
8
|
+
do {
|
|
9
|
+
return try closure()
|
|
10
|
+
} catch {
|
|
11
|
+
errorPointer?.pointee = toNSError(error)
|
|
12
|
+
throw error
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
Converts Swift errors to `NSError` so that they can be handled from the ObjC code.
|
|
18
|
+
*/
|
|
19
|
+
internal func toNSError(_ error: Error) -> NSError {
|
|
20
|
+
if let error = error as? Exception {
|
|
21
|
+
return NSError(domain: "dev.expo.modules", code: 0, userInfo: [
|
|
22
|
+
"name": error.name,
|
|
23
|
+
"code": error.code,
|
|
24
|
+
"message": error.debugDescription,
|
|
25
|
+
])
|
|
26
|
+
}
|
|
27
|
+
return error as NSError
|
|
28
|
+
}
|
|
@@ -14,16 +14,16 @@ public final class ConcreteViewProp<ViewType: UIView, PropType: AnyArgument>: An
|
|
|
14
14
|
public let name: String
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
|
|
17
|
+
A dynamic type for the prop's value type.
|
|
18
18
|
*/
|
|
19
|
-
private let propType:
|
|
19
|
+
private let propType: AnyDynamicType
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
Closure to call to set the actual property on the given view.
|
|
23
23
|
*/
|
|
24
24
|
private let setter: SetterType
|
|
25
25
|
|
|
26
|
-
internal init(name: String, propType:
|
|
26
|
+
internal init(name: String, propType: AnyDynamicType, setter: @escaping SetterType) {
|
|
27
27
|
self.name = name
|
|
28
28
|
self.propType = propType
|
|
29
29
|
self.setter = setter
|
|
@@ -29,7 +29,7 @@ public func prop<ViewType: UIView, PropType: AnyArgument>(
|
|
|
29
29
|
) -> ViewManagerDefinitionComponent {
|
|
30
30
|
return ConcreteViewProp(
|
|
31
31
|
name: name,
|
|
32
|
-
propType:
|
|
32
|
+
propType: ~PropType.self,
|
|
33
33
|
setter: setter
|
|
34
34
|
)
|
|
35
35
|
}
|
|
@@ -43,7 +43,7 @@ public func Prop<ViewType: UIView, PropType: AnyArgument>(
|
|
|
43
43
|
) -> ViewManagerDefinitionComponent {
|
|
44
44
|
return ConcreteViewProp(
|
|
45
45
|
name: name,
|
|
46
|
-
propType:
|
|
46
|
+
propType: ~PropType.self,
|
|
47
47
|
setter: setter
|
|
48
48
|
)
|
|
49
49
|
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import ExpoModulesTestCore
|
|
2
|
+
|
|
3
|
+
@testable import ExpoModulesCore
|
|
4
|
+
|
|
5
|
+
class ClassComponentSpec: ExpoSpec {
|
|
6
|
+
override func spec() {
|
|
7
|
+
describe("basic") {
|
|
8
|
+
it("factory returns a component") {
|
|
9
|
+
let klass = Class("") {}
|
|
10
|
+
expect(klass).to(beAnInstanceOf(ClassComponent.self))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
it("has a name") {
|
|
14
|
+
let expoClassName = "ExpoClass"
|
|
15
|
+
let klass = Class(expoClassName) {}
|
|
16
|
+
expect(klass.name) == expoClassName
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
it("is without native constructor") {
|
|
20
|
+
let klass = Class("") {}
|
|
21
|
+
expect(klass.constructor).to(beNil())
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
it("has native constructor") {
|
|
25
|
+
let klass = Class("") { Constructor {} }
|
|
26
|
+
expect(klass.constructor).notTo(beNil())
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
it("ignores constructor as function") {
|
|
30
|
+
let klass = Class("") { Constructor {} }
|
|
31
|
+
expect(klass.functions["constructor"]).to(beNil())
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
it("builds a class") {
|
|
35
|
+
let runtime = JavaScriptRuntime()
|
|
36
|
+
let klass = Class("") {}
|
|
37
|
+
let object = klass.build(inRuntime: runtime)
|
|
38
|
+
|
|
39
|
+
expect(object.hasProperty("prototype")) == true
|
|
40
|
+
expect(object.getProperty("prototype").kind) == .object
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
describe("module") {
|
|
45
|
+
let appContext = AppContext.create()
|
|
46
|
+
let runtime = appContext.runtime
|
|
47
|
+
|
|
48
|
+
beforeSuite {
|
|
49
|
+
class ClassTestModule: Module {
|
|
50
|
+
func definition() -> ModuleDefinition {
|
|
51
|
+
Name("ClassTest")
|
|
52
|
+
|
|
53
|
+
Class("MyClass") {
|
|
54
|
+
Constructor {}
|
|
55
|
+
|
|
56
|
+
Function("myFunction") {
|
|
57
|
+
return "foobar"
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
Property("foo") {
|
|
61
|
+
return "bar"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
appContext.moduleRegistry.register(moduleType: ClassTestModule.self)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
it("is a function") {
|
|
70
|
+
let klass = try runtime?.eval("ExpoModules.ClassTest.MyClass")
|
|
71
|
+
expect(klass?.isFunction()) == true
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
it("has a name") {
|
|
75
|
+
let klass = try runtime?.eval("ExpoModules.ClassTest.MyClass.name")
|
|
76
|
+
expect(klass?.getString()) == "MyClass"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
it("has a prototype") {
|
|
80
|
+
let prototype = try runtime?.eval("ExpoModules.ClassTest.MyClass.prototype")
|
|
81
|
+
expect(prototype?.isObject()) == true
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
it("has keys in prototype") {
|
|
85
|
+
let prototypeKeys = try runtime?.eval("Object.keys(ExpoModules.ClassTest.MyClass.prototype)")
|
|
86
|
+
.getArray()
|
|
87
|
+
.map { $0.getString() } ?? []
|
|
88
|
+
|
|
89
|
+
expect(prototypeKeys).to(contain("myFunction"))
|
|
90
|
+
expect(prototypeKeys).notTo(contain("__native_constructor__"))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
it("is an instance of") {
|
|
94
|
+
let isInstanceOf = try runtime?.eval([
|
|
95
|
+
"myObject = new ExpoModules.ClassTest.MyClass()",
|
|
96
|
+
"myObject instanceof ExpoModules.ClassTest.MyClass",
|
|
97
|
+
])
|
|
98
|
+
|
|
99
|
+
expect(isInstanceOf?.getBool()) == true
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
it("defines properties on initialization") {
|
|
103
|
+
// The properties are not specified in the prototype, but defined during initialization.
|
|
104
|
+
let object = try runtime?.eval("new ExpoModules.ClassTest.MyClass()").asObject()
|
|
105
|
+
expect(object?.getPropertyNames()).to(contain("foo"))
|
|
106
|
+
expect(object?.getProperty("foo").getString()) == "bar"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
describe("class with associated type") {
|
|
111
|
+
let appContext = AppContext.create()
|
|
112
|
+
let runtime = appContext.runtime
|
|
113
|
+
|
|
114
|
+
beforeSuite {
|
|
115
|
+
appContext.moduleRegistry.register(moduleType: ModuleWithCounterClass.self)
|
|
116
|
+
}
|
|
117
|
+
it("is defined") {
|
|
118
|
+
let isDefined = try! runtime!.eval("'Counter' in ExpoModules.TestModule")
|
|
119
|
+
|
|
120
|
+
expect(isDefined.getBool()) == true
|
|
121
|
+
}
|
|
122
|
+
it("creates shared object") {
|
|
123
|
+
let jsObject = try! runtime!.eval("new ExpoModules.TestModule.Counter(0)").getObject()
|
|
124
|
+
let nativeObject = SharedObjectRegistry.toNativeObject(jsObject)
|
|
125
|
+
|
|
126
|
+
expect(nativeObject).notTo(beNil())
|
|
127
|
+
}
|
|
128
|
+
it("registers shared object") {
|
|
129
|
+
let oldSize = SharedObjectRegistry.size
|
|
130
|
+
try! runtime?.eval("object = new ExpoModules.TestModule.Counter(0)")
|
|
131
|
+
|
|
132
|
+
expect(SharedObjectRegistry.size) == oldSize + 1
|
|
133
|
+
}
|
|
134
|
+
it("calls function with owner") {
|
|
135
|
+
try runtime?.eval([
|
|
136
|
+
"object = new ExpoModules.TestModule.Counter(0)",
|
|
137
|
+
"object.increment(1)",
|
|
138
|
+
])
|
|
139
|
+
// no expectations, just checking if it doesn't fail
|
|
140
|
+
}
|
|
141
|
+
it("creates with initial value") {
|
|
142
|
+
let initialValue = Int.random(in: 1..<100)
|
|
143
|
+
let value = try runtime!.eval([
|
|
144
|
+
"object = new ExpoModules.TestModule.Counter(\(initialValue))",
|
|
145
|
+
"object.getValue()",
|
|
146
|
+
])
|
|
147
|
+
|
|
148
|
+
expect(value.kind) == .number
|
|
149
|
+
expect(value.getInt()) == initialValue
|
|
150
|
+
}
|
|
151
|
+
it("gets shared object value") {
|
|
152
|
+
let value = try runtime!.eval([
|
|
153
|
+
"object = new ExpoModules.TestModule.Counter(0)",
|
|
154
|
+
"object.getValue()",
|
|
155
|
+
])
|
|
156
|
+
|
|
157
|
+
expect(value.kind) == .number
|
|
158
|
+
expect(value.isNumber()) == true
|
|
159
|
+
}
|
|
160
|
+
it("changes shared object") {
|
|
161
|
+
try! runtime?.eval("object = new ExpoModules.TestModule.Counter(0)")
|
|
162
|
+
let incrementBy = Int.random(in: 1..<100)
|
|
163
|
+
let value = try runtime!.eval("object.getValue()").asInt()
|
|
164
|
+
let newValue = try runtime!.eval([
|
|
165
|
+
"object.increment(\(incrementBy))",
|
|
166
|
+
"object.getValue()",
|
|
167
|
+
])
|
|
168
|
+
|
|
169
|
+
expect(newValue.kind) == .number
|
|
170
|
+
expect(newValue.getInt()) == value + incrementBy
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
A module that exposes a Counter class with an associated shared object class.
|
|
178
|
+
*/
|
|
179
|
+
fileprivate final class ModuleWithCounterClass: Module {
|
|
180
|
+
func definition() -> ModuleDefinition {
|
|
181
|
+
Name("TestModule")
|
|
182
|
+
|
|
183
|
+
Class(Counter.self) {
|
|
184
|
+
Constructor { (initialValue: Int) in
|
|
185
|
+
return Counter(initialValue: initialValue)
|
|
186
|
+
}
|
|
187
|
+
Function("increment") { (counter, value: Int) in
|
|
188
|
+
counter.increment(by: value)
|
|
189
|
+
}
|
|
190
|
+
Function("getValue") { counter in
|
|
191
|
+
return counter.currentValue
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
A shared object class that stores some native value and can be used as an associated type of the JS class.
|
|
199
|
+
*/
|
|
200
|
+
fileprivate final class Counter: SharedObject {
|
|
201
|
+
var currentValue = 0
|
|
202
|
+
|
|
203
|
+
init(initialValue: Int = 0) {
|
|
204
|
+
self.currentValue = initialValue
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
func increment(by value: Int = 1) {
|
|
208
|
+
currentValue += value
|
|
209
|
+
}
|
|
210
|
+
}
|