Skip to content

Commit d741dce

Browse files
committed
E2e testing of bridging Promise<interface> returns
1 parent ab19ba9 commit d741dce

File tree

7 files changed

+284
-2
lines changed

7 files changed

+284
-2
lines changed

Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,12 @@ public struct ImportTS {
301301
liftExpr = "resolved.string!"
302302
case .bool:
303303
liftExpr = "resolved.boolean!"
304-
case .jsObject:
305-
liftExpr = "resolved.object!"
304+
case .jsObject(let name):
305+
if let name {
306+
liftExpr = "\(name)(unsafelyWrapping: resolved.object!)"
307+
} else {
308+
liftExpr = "resolved.object!"
309+
}
306310
case .jsValue:
307311
liftExpr = "resolved"
308312
default:

Tests/BridgeJSRuntimeTests/AsyncImportTests.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,16 @@ import JavaScriptKit
2020
func asyncRoundTripString(v: String) async throws {
2121
try #expect(await jsAsyncRoundTripString(v) == v)
2222
}
23+
24+
@Test func fetchWeatherData() async throws {
25+
let weather = try await BridgeJSRuntimeTests.fetchWeatherData("London")
26+
#expect(try weather.temperature == 15.5)
27+
#expect(try weather.description == "Cloudy")
28+
#expect(try weather.humidity == 80)
29+
30+
let weather2 = try await BridgeJSRuntimeTests.fetchWeatherData("Tokyo")
31+
#expect(try weather2.temperature == 25.0)
32+
#expect(try weather2.description == "Sunny")
33+
#expect(try weather2.humidity == 40)
34+
}
2335
}

Tests/BridgeJSRuntimeTests/Generated/BridgeJS.Macros.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@ extension FeatureFlag: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum {}
5151

5252
@JSFunction func jsAsyncRoundTripString(_ v: String) async throws(JSException) -> String
5353

54+
@JSFunction func fetchWeatherData(_ city: String) async throws(JSException) -> WeatherData
55+
56+
@JSClass struct WeatherData {
57+
@JSGetter var temperature: Double
58+
@JSSetter func setTemperature(_ value: Double) throws(JSException)
59+
@JSGetter var description: String
60+
@JSSetter func setDescription(_ value: String) throws(JSException)
61+
@JSGetter var humidity: Double
62+
@JSSetter func setHumidity(_ value: Double) throws(JSException)
63+
}
64+
5465
@JSFunction(jsName: "$jsWeirdFunction") func _jsWeirdFunction() throws(JSException) -> Double
5566
5667
@JSClass(jsName: "$WeirdClass") struct _WeirdClass {

Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11239,6 +11239,32 @@ func _$jsAsyncRoundTripString(_ v: String) async throws(JSException) -> String {
1123911239
return resolved.string!
1124011240
}
1124111241

11242+
#if arch(wasm32)
11243+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_fetchWeatherData")
11244+
fileprivate func bjs_fetchWeatherData_extern(_ cityBytes: Int32, _ cityLength: Int32) -> Int32
11245+
#else
11246+
fileprivate func bjs_fetchWeatherData_extern(_ cityBytes: Int32, _ cityLength: Int32) -> Int32 {
11247+
fatalError("Only available on WebAssembly")
11248+
}
11249+
#endif
11250+
@inline(never) fileprivate func bjs_fetchWeatherData(_ cityBytes: Int32, _ cityLength: Int32) -> Int32 {
11251+
return bjs_fetchWeatherData_extern(cityBytes, cityLength)
11252+
}
11253+
11254+
func _$fetchWeatherData(_ city: String) async throws(JSException) -> WeatherData {
11255+
let ret0 = city.bridgeJSWithLoweredParameter { (cityBytes, cityLength) in
11256+
let ret = bjs_fetchWeatherData(cityBytes, cityLength)
11257+
return ret
11258+
}
11259+
let ret = ret0
11260+
if let error = _swift_js_take_exception() {
11261+
throw error
11262+
}
11263+
let promise = JSPromise(unsafelyWrapping: JSObject(id: UInt32(bitPattern: ret)))
11264+
let resolved = try await promise.value
11265+
return WeatherData(unsafelyWrapping: resolved.object!)
11266+
}
11267+
1124211268
#if arch(wasm32)
1124311269
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs__jsWeirdFunction")
1124411270
fileprivate func bjs__jsWeirdFunction_extern() -> Float64
@@ -11417,6 +11443,133 @@ func _$JsGreeter_changeName(_ self: JSObject, _ name: String) throws(JSException
1141711443
}
1141811444
}
1141911445

11446+
#if arch(wasm32)
11447+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_WeatherData_temperature_get")
11448+
fileprivate func bjs_WeatherData_temperature_get_extern(_ self: Int32) -> Float64
11449+
#else
11450+
fileprivate func bjs_WeatherData_temperature_get_extern(_ self: Int32) -> Float64 {
11451+
fatalError("Only available on WebAssembly")
11452+
}
11453+
#endif
11454+
@inline(never) fileprivate func bjs_WeatherData_temperature_get(_ self: Int32) -> Float64 {
11455+
return bjs_WeatherData_temperature_get_extern(self)
11456+
}
11457+
11458+
#if arch(wasm32)
11459+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_WeatherData_description_get")
11460+
fileprivate func bjs_WeatherData_description_get_extern(_ self: Int32) -> Int32
11461+
#else
11462+
fileprivate func bjs_WeatherData_description_get_extern(_ self: Int32) -> Int32 {
11463+
fatalError("Only available on WebAssembly")
11464+
}
11465+
#endif
11466+
@inline(never) fileprivate func bjs_WeatherData_description_get(_ self: Int32) -> Int32 {
11467+
return bjs_WeatherData_description_get_extern(self)
11468+
}
11469+
11470+
#if arch(wasm32)
11471+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_WeatherData_humidity_get")
11472+
fileprivate func bjs_WeatherData_humidity_get_extern(_ self: Int32) -> Float64
11473+
#else
11474+
fileprivate func bjs_WeatherData_humidity_get_extern(_ self: Int32) -> Float64 {
11475+
fatalError("Only available on WebAssembly")
11476+
}
11477+
#endif
11478+
@inline(never) fileprivate func bjs_WeatherData_humidity_get(_ self: Int32) -> Float64 {
11479+
return bjs_WeatherData_humidity_get_extern(self)
11480+
}
11481+
11482+
#if arch(wasm32)
11483+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_WeatherData_temperature_set")
11484+
fileprivate func bjs_WeatherData_temperature_set_extern(_ self: Int32, _ newValue: Float64) -> Void
11485+
#else
11486+
fileprivate func bjs_WeatherData_temperature_set_extern(_ self: Int32, _ newValue: Float64) -> Void {
11487+
fatalError("Only available on WebAssembly")
11488+
}
11489+
#endif
11490+
@inline(never) fileprivate func bjs_WeatherData_temperature_set(_ self: Int32, _ newValue: Float64) -> Void {
11491+
return bjs_WeatherData_temperature_set_extern(self, newValue)
11492+
}
11493+
11494+
#if arch(wasm32)
11495+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_WeatherData_description_set")
11496+
fileprivate func bjs_WeatherData_description_set_extern(_ self: Int32, _ newValueBytes: Int32, _ newValueLength: Int32) -> Void
11497+
#else
11498+
fileprivate func bjs_WeatherData_description_set_extern(_ self: Int32, _ newValueBytes: Int32, _ newValueLength: Int32) -> Void {
11499+
fatalError("Only available on WebAssembly")
11500+
}
11501+
#endif
11502+
@inline(never) fileprivate func bjs_WeatherData_description_set(_ self: Int32, _ newValueBytes: Int32, _ newValueLength: Int32) -> Void {
11503+
return bjs_WeatherData_description_set_extern(self, newValueBytes, newValueLength)
11504+
}
11505+
11506+
#if arch(wasm32)
11507+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_WeatherData_humidity_set")
11508+
fileprivate func bjs_WeatherData_humidity_set_extern(_ self: Int32, _ newValue: Float64) -> Void
11509+
#else
11510+
fileprivate func bjs_WeatherData_humidity_set_extern(_ self: Int32, _ newValue: Float64) -> Void {
11511+
fatalError("Only available on WebAssembly")
11512+
}
11513+
#endif
11514+
@inline(never) fileprivate func bjs_WeatherData_humidity_set(_ self: Int32, _ newValue: Float64) -> Void {
11515+
return bjs_WeatherData_humidity_set_extern(self, newValue)
11516+
}
11517+
11518+
func _$WeatherData_temperature_get(_ self: JSObject) throws(JSException) -> Double {
11519+
let selfValue = self.bridgeJSLowerParameter()
11520+
let ret = bjs_WeatherData_temperature_get(selfValue)
11521+
if let error = _swift_js_take_exception() {
11522+
throw error
11523+
}
11524+
return Double.bridgeJSLiftReturn(ret)
11525+
}
11526+
11527+
func _$WeatherData_description_get(_ self: JSObject) throws(JSException) -> String {
11528+
let selfValue = self.bridgeJSLowerParameter()
11529+
let ret = bjs_WeatherData_description_get(selfValue)
11530+
if let error = _swift_js_take_exception() {
11531+
throw error
11532+
}
11533+
return String.bridgeJSLiftReturn(ret)
11534+
}
11535+
11536+
func _$WeatherData_humidity_get(_ self: JSObject) throws(JSException) -> Double {
11537+
let selfValue = self.bridgeJSLowerParameter()
11538+
let ret = bjs_WeatherData_humidity_get(selfValue)
11539+
if let error = _swift_js_take_exception() {
11540+
throw error
11541+
}
11542+
return Double.bridgeJSLiftReturn(ret)
11543+
}
11544+
11545+
func _$WeatherData_temperature_set(_ self: JSObject, _ newValue: Double) throws(JSException) -> Void {
11546+
let selfValue = self.bridgeJSLowerParameter()
11547+
let newValueValue = newValue.bridgeJSLowerParameter()
11548+
bjs_WeatherData_temperature_set(selfValue, newValueValue)
11549+
if let error = _swift_js_take_exception() {
11550+
throw error
11551+
}
11552+
}
11553+
11554+
func _$WeatherData_description_set(_ self: JSObject, _ newValue: String) throws(JSException) -> Void {
11555+
let selfValue = self.bridgeJSLowerParameter()
11556+
newValue.bridgeJSWithLoweredParameter { (newValueBytes, newValueLength) in
11557+
bjs_WeatherData_description_set(selfValue, newValueBytes, newValueLength)
11558+
}
11559+
if let error = _swift_js_take_exception() {
11560+
throw error
11561+
}
11562+
}
11563+
11564+
func _$WeatherData_humidity_set(_ self: JSObject, _ newValue: Double) throws(JSException) -> Void {
11565+
let selfValue = self.bridgeJSLowerParameter()
11566+
let newValueValue = newValue.bridgeJSLowerParameter()
11567+
bjs_WeatherData_humidity_set(selfValue, newValueValue)
11568+
if let error = _swift_js_take_exception() {
11569+
throw error
11570+
}
11571+
}
11572+
1142011573
#if arch(wasm32)
1142111574
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs__WeirdClass_init")
1142211575
fileprivate func bjs__WeirdClass_init_extern() -> Int32

Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18103,6 +18103,29 @@
1810318103
}
1810418104
}
1810518105
},
18106+
{
18107+
"effects" : {
18108+
"isAsync" : true,
18109+
"isStatic" : false,
18110+
"isThrows" : true
18111+
},
18112+
"name" : "fetchWeatherData",
18113+
"parameters" : [
18114+
{
18115+
"name" : "city",
18116+
"type" : {
18117+
"string" : {
18118+
18119+
}
18120+
}
18121+
}
18122+
],
18123+
"returnType" : {
18124+
"jsObject" : {
18125+
"_0" : "WeatherData"
18126+
}
18127+
}
18128+
},
1810618129
{
1810718130
"effects" : {
1810818131
"isAsync" : false,
@@ -18253,6 +18276,70 @@
1825318276

1825418277
]
1825518278
},
18279+
{
18280+
"getters" : [
18281+
{
18282+
"name" : "temperature",
18283+
"type" : {
18284+
"double" : {
18285+
18286+
}
18287+
}
18288+
},
18289+
{
18290+
"name" : "description",
18291+
"type" : {
18292+
"string" : {
18293+
18294+
}
18295+
}
18296+
},
18297+
{
18298+
"name" : "humidity",
18299+
"type" : {
18300+
"double" : {
18301+
18302+
}
18303+
}
18304+
}
18305+
],
18306+
"methods" : [
18307+
18308+
],
18309+
"name" : "WeatherData",
18310+
"setters" : [
18311+
{
18312+
"functionName" : "temperature_set",
18313+
"name" : "temperature",
18314+
"type" : {
18315+
"double" : {
18316+
18317+
}
18318+
}
18319+
},
18320+
{
18321+
"functionName" : "description_set",
18322+
"name" : "description",
18323+
"type" : {
18324+
"string" : {
18325+
18326+
}
18327+
}
18328+
},
18329+
{
18330+
"functionName" : "humidity_set",
18331+
"name" : "humidity",
18332+
"type" : {
18333+
"double" : {
18334+
18335+
}
18336+
}
18337+
}
18338+
],
18339+
"staticMethods" : [
18340+
18341+
]
18342+
},
1825618343
{
1825718344
"constructor" : {
1825818345
"parameters" : [

Tests/BridgeJSRuntimeTests/bridge-js.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ export function jsAsyncRoundTripNumber(v: number): Promise<number>;
3232
export function jsAsyncRoundTripBool(v: boolean): Promise<boolean>;
3333
export function jsAsyncRoundTripString(v: string): Promise<string>;
3434

35+
// Async fetch-like test with structured return type
36+
export interface WeatherData {
37+
temperature: number;
38+
description: string;
39+
humidity: number;
40+
}
41+
export function fetchWeatherData(city: string): Promise<WeatherData>;
42+
3543
// jsName tests
3644
export function $jsWeirdFunction(): number;
3745

Tests/prelude.mjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ export async function setupOptions(options, context) {
119119
},
120120
StaticBox,
121121
Foo: ImportedFoo,
122+
"fetchWeatherData": (city) => {
123+
return Promise.resolve({
124+
temperature: city === "London" ? 15.5 : 25.0,
125+
description: city === "London" ? "Cloudy" : "Sunny",
126+
humidity: city === "London" ? 80 : 40,
127+
});
128+
},
122129
"jsAsyncRoundTripVoid": () => {
123130
return Promise.resolve();
124131
},

0 commit comments

Comments
 (0)