Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions Sources/JavaScriptKit/BridgeJSIntrinsics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -510,12 +510,13 @@ extension _JSBridgedClass {
@_spi(BridgeJS) public static func bridgeJSLiftParameter(_ id: Int32) -> Self {
Self(unsafelyWrapping: JSObject.bridgeJSLiftParameter(id))
}
@_spi(BridgeJS) public static func bridgeJSStackPop() -> Self {
bridgeJSLiftParameter(_swift_js_pop_i32())
}
@_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> Int32 { jsObject.bridgeJSLowerReturn() }
@_spi(BridgeJS) public consuming func bridgeJSStackPush() {
_swift_js_push_i32(bridgeJSLowerReturn())

public static func bridgeJSStackPop() -> Self {
Self(unsafelyWrapping: JSObject.bridgeJSStackPop())
}
public consuming func bridgeJSStackPush() {
jsObject.bridgeJSStackPush()
}
}

Expand Down
8 changes: 7 additions & 1 deletion Sources/JavaScriptKit/JSBridgedType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extension JSBridgedType {
/// A protocol that Swift classes that are exposed to JavaScript via `@JS class` conform to.
///
/// The conformance is automatically synthesized by `@JSClass` for BridgeJS-generated declarations.
public protocol _JSBridgedClass {
public protocol _JSBridgedClass: Equatable, _BridgedSwiftStackType {
/// The JavaScript object wrapped by this instance.
/// You may assume that `jsObject instanceof Self.constructor == true`
var jsObject: JSObject { get }
Expand All @@ -26,6 +26,12 @@ public protocol _JSBridgedClass {
init(unsafelyWrapping jsObject: JSObject)
}

extension _JSBridgedClass {
public static func == (lhs: Self, rhs: Self) -> Bool {
lhs.jsObject == rhs.jsObject
}
}

/// Conform to this protocol when your Swift class wraps a JavaScript class.
public protocol JSBridgedClass: JSBridgedType, _JSBridgedClass {
/// The constructor function for the JavaScript class
Expand Down
119 changes: 119 additions & 0 deletions Tests/BridgeJSRuntimeTests/ArraySupportTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import XCTest
import JavaScriptKit

@JSClass struct ArrayElementObject {
@JSGetter var id: String

@JSFunction init(id: String) throws(JSException)
}

@JSClass struct ArraySupportImports {
@JSFunction static func jsIntArrayLength(_ items: [Int]) throws(JSException) -> Int

@JSFunction static func jsRoundTripIntArray(_ items: [Int]) throws(JSException) -> [Int]
@JSFunction static func jsRoundTripNumberArray(_ values: [Double]) throws(JSException) -> [Double]
@JSFunction static func jsRoundTripStringArray(_ values: [String]) throws(JSException) -> [String]
@JSFunction static func jsRoundTripBoolArray(_ values: [Bool]) throws(JSException) -> [Bool]

@JSFunction static func jsRoundTripJSValueArray(_ v: [JSValue]) throws(JSException) -> [JSValue]
@JSFunction static func jsRoundTripOptionalJSValueArray(
_ v: Optional<[JSValue]>
) throws(JSException) -> Optional<[JSValue]>

@JSFunction static func jsRoundTripJSObjectArray(_ values: [JSObject]) throws(JSException) -> [JSObject]

@JSFunction static func jsRoundTripJSClassArray(
_ values: [ArrayElementObject]
) throws(JSException) -> [ArrayElementObject]

@JSFunction static func jsSumNumberArray(_ values: [Double]) throws(JSException) -> Double
@JSFunction static func jsCreateNumberArray() throws(JSException) -> [Double]
}

final class ArraySupportTests: XCTestCase {

func testRoundTripIntArray() throws {
let values = [1, 2, 3, 4, 5]
let result = try ArraySupportImports.jsRoundTripIntArray(values)
XCTAssertEqual(result, values)
XCTAssertEqual(try ArraySupportImports.jsIntArrayLength(values), values.count)
XCTAssertEqual(try ArraySupportImports.jsRoundTripIntArray([]), [])
}

func testRoundTripNumberArray() throws {
let input: [Double] = [1.0, 2.5, 3.0, -4.5]
let result = try ArraySupportImports.jsRoundTripNumberArray(input)
XCTAssertEqual(result, input)
XCTAssertEqual(try ArraySupportImports.jsRoundTripNumberArray([]), [])
XCTAssertEqual(try ArraySupportImports.jsRoundTripNumberArray([42.0]), [42.0])
}

func testRoundTripStringArray() throws {
let input = ["Hello", "World", "🎉"]
let result = try ArraySupportImports.jsRoundTripStringArray(input)
XCTAssertEqual(result, input)
XCTAssertEqual(try ArraySupportImports.jsRoundTripStringArray([]), [])
XCTAssertEqual(try ArraySupportImports.jsRoundTripStringArray(["", "a", ""]), ["", "a", ""])
}

func testRoundTripBoolArray() throws {
let input = [true, false, true, false]
let result = try ArraySupportImports.jsRoundTripBoolArray(input)
XCTAssertEqual(result, input)
XCTAssertEqual(try ArraySupportImports.jsRoundTripBoolArray([]), [])
}

func testSumNumberArray() throws {
XCTAssertEqual(try ArraySupportImports.jsSumNumberArray([1.0, 2.0, 3.0, 4.0]), 10.0)
XCTAssertEqual(try ArraySupportImports.jsSumNumberArray([]), 0.0)
XCTAssertEqual(try ArraySupportImports.jsSumNumberArray([42.0]), 42.0)
}

func testCreateNumberArray() throws {
let result = try ArraySupportImports.jsCreateNumberArray()
XCTAssertEqual(result, [1.0, 2.0, 3.0, 4.0, 5.0])
}

func testRoundTripJSValueArray() throws {
let object = JSObject.global
let symbol = JSSymbol("array")
let bigInt = JSBigInt(_slowBridge: Int64(42))
let values: [JSValue] = [
.boolean(false),
.number(123.5),
.string(JSString("hello")),
.object(object),
.null,
.undefined,
.symbol(symbol),
.bigInt(bigInt),
]
let roundTripped = try ArraySupportImports.jsRoundTripJSValueArray(values)
XCTAssertEqual(roundTripped, values)
XCTAssertEqual(try ArraySupportImports.jsRoundTripJSValueArray([]), [])
}

func testRoundTripOptionalJSValueArray() throws {
XCTAssertNil(try ArraySupportImports.jsRoundTripOptionalJSValueArray(nil))
let values: [JSValue] = [.number(1), .undefined, .null]
let result = try ArraySupportImports.jsRoundTripOptionalJSValueArray(values)
XCTAssertEqual(result, values)
}

func testRoundTripJSObjectArray() throws {
let values: [JSObject] = [.global, JSObject(), ["a": 1, "b": 2]]
let result = try ArraySupportImports.jsRoundTripJSObjectArray(values)
XCTAssertEqual(result, values)
}

func testRoundTripJSClassArray() throws {
let values = try [ArrayElementObject(id: "1"), ArrayElementObject(id: "2"), ArrayElementObject(id: "3")]
let result = try ArraySupportImports.jsRoundTripJSClassArray(values)
XCTAssertEqual(result, values)
XCTAssertEqual(try result[0].id, "1")
XCTAssertEqual(try result[1].id, "2")
XCTAssertEqual(try result[2].id, "3")

XCTAssertEqual(try ArraySupportImports.jsRoundTripJSClassArray([]), [])
}
}
14 changes: 0 additions & 14 deletions Tests/BridgeJSRuntimeTests/Generated/BridgeJS.Macros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@

@JSFunction func jsRoundTripJSValue(_ v: JSValue) throws(JSException) -> JSValue

@JSFunction func jsRoundTripJSValueArray(_ v: [JSValue]) throws(JSException) -> [JSValue]

@JSFunction func jsRoundTripOptionalJSValueArray(_ v: Optional<[JSValue]>) throws(JSException) -> Optional<[JSValue]>

@JSFunction func jsThrowOrVoid(_ shouldThrow: Bool) throws(JSException) -> Void

@JSFunction func jsThrowOrNumber(_ shouldThrow: Bool) throws(JSException) -> Double
Expand Down Expand Up @@ -63,16 +59,6 @@ extension FeatureFlag: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum {}
@JSFunction(jsName: "with-dashes") static func with_dashes() throws(JSException) -> StaticBox
}

@JSFunction func jsRoundTripNumberArray(_ values: [Double]) throws(JSException) -> [Double]

@JSFunction func jsRoundTripStringArray(_ values: [String]) throws(JSException) -> [String]

@JSFunction func jsRoundTripBoolArray(_ values: [Bool]) throws(JSException) -> [Bool]

@JSFunction func jsSumNumberArray(_ values: [Double]) throws(JSException) -> Double

@JSFunction func jsCreateNumberArray() throws(JSException) -> [Double]

@JSFunction(from: .global) func parseInt(_ string: String) throws(JSException) -> Double

@JSClass(from: .global) struct Animal {
Expand Down
Loading