Skip to content

Commit 4a682aa

Browse files
committed
BridgeJS: Unified prelude.mjs tests with 2 test targets
BridgeJS: Extend snapshot test setup for exports <-> global this by including mixed module test case
1 parent 0f70f64 commit 4a682aa

35 files changed

+2316
-404
lines changed

Makefile

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,6 @@ unittest:
1111
--disable-sandbox \
1212
js test --prelude ./Tests/prelude.mjs -Xnode --expose-gc
1313

14-
.PHONY: unittest-with-global
15-
unittest-with-global:
16-
cp Tests/BridgeJSRuntimeTests/bridge-js.config.exposeToGlobal.json Tests/BridgeJSRuntimeTests/bridge-js.config.local.json
17-
swift package --allow-writing-to-directory Tests/BridgeJSRuntimeTests \
18-
bridge-js --package-path Tests/BridgeJSRuntimeTests
19-
rm -f Tests/BridgeJSRuntimeTests/bridge-js.config.local.json
20-
env JAVASCRIPTKIT_EXPERIMENTAL_BRIDGEJS=1 swift package --swift-sdk "$(SWIFT_SDK_ID)" \
21-
--disable-sandbox \
22-
js test --prelude ./Tests/prelude.exposeToGlobal.mjs -Xnode --expose-gc
23-
2414
.PHONY: regenerate_swiftpm_resources
2515
regenerate_swiftpm_resources:
2616
npm run build

Package.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,5 +180,18 @@ let package = Package(
180180
],
181181
linkerSettings: testingLinkerFlags
182182
),
183+
.testTarget(
184+
name: "BridgeJSGlobalTests",
185+
dependencies: ["JavaScriptKit", "JavaScriptEventLoop"],
186+
exclude: [
187+
"bridge-js.config.json",
188+
"bridge-js.d.ts",
189+
"Generated/JavaScript",
190+
],
191+
swiftSettings: [
192+
.enableExperimentalFeature("Extern")
193+
],
194+
linkerSettings: testingLinkerFlags
195+
),
183196
]
184197
)

Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,13 +1127,13 @@ struct BridgeJSLink {
11271127
}
11281128

11291129
// Generate wrapper functions for each module
1130-
for (moduleName, classes) in modulesByName {
1130+
for (moduleName, classes) in modulesByName.sorted(by: { $0.key < $1.key }) {
11311131
wrapperLines.append("// Wrapper functions for module: \(moduleName)")
11321132
wrapperLines.append("if (!importObject[\"\(moduleName)\"]) {")
11331133
wrapperLines.append(" importObject[\"\(moduleName)\"] = {};")
11341134
wrapperLines.append("}")
11351135

1136-
for klass in classes {
1136+
for klass in classes.sorted(by: { $0.name < $1.name }) {
11371137
let wrapperFunctionName = "bjs_\(klass.name)_wrap"
11381138
wrapperLines.append("importObject[\"\(moduleName)\"][\"\(wrapperFunctionName)\"] = function(pointer) {")
11391139
wrapperLines.append(" const obj = \(klass.name).__construct(pointer);")
@@ -2639,14 +2639,14 @@ extension BridgeJSLink {
26392639
renderTSSignatureCallback: @escaping ([Parameter], BridgeType, Effects) -> String
26402640
) -> [String] {
26412641
let printer = CodeFragmentPrinter()
2642-
2642+
26432643
let globalSkeletons = exportedSkeletons.filter { $0.exposeToGlobal }
26442644
let nonGlobalSkeletons = exportedSkeletons.filter { !$0.exposeToGlobal }
2645-
2645+
26462646
if !globalSkeletons.isEmpty {
26472647
let globalRootNode = NamespaceNode(name: "")
26482648
buildExportsTree(rootNode: globalRootNode, exportedSkeletons: globalSkeletons)
2649-
2649+
26502650
if !globalRootNode.children.isEmpty {
26512651
printer.write("export {};")
26522652
printer.nextLine()
@@ -2664,11 +2664,11 @@ extension BridgeJSLink {
26642664
printer.nextLine()
26652665
}
26662666
}
2667-
2667+
26682668
if !nonGlobalSkeletons.isEmpty {
26692669
let localRootNode = NamespaceNode(name: "")
26702670
buildExportsTree(rootNode: localRootNode, exportedSkeletons: nonGlobalSkeletons)
2671-
2671+
26722672
if !localRootNode.children.isEmpty {
26732673
generateNamespaceDeclarationsForNode(
26742674
node: localRootNode,
@@ -2682,7 +2682,7 @@ extension BridgeJSLink {
26822682

26832683
return printer.lines
26842684
}
2685-
2685+
26862686
private func generateNamespaceDeclarationsForNode(
26872687
node: NamespaceNode,
26882688
depth: Int,
@@ -2871,13 +2871,19 @@ extension BridgeJSLink {
28712871
}
28722872
}
28732873

2874-
generateNamespaceDeclarationsForNode(node: childNode, depth: depth + 1, printer: printer, exposeToGlobal: exposeToGlobal, renderTSSignatureCallback: renderTSSignatureCallback)
2874+
generateNamespaceDeclarationsForNode(
2875+
node: childNode,
2876+
depth: depth + 1,
2877+
printer: printer,
2878+
exposeToGlobal: exposeToGlobal,
2879+
renderTSSignatureCallback: renderTSSignatureCallback
2880+
)
28752881

28762882
printer.unindent()
28772883
printer.write("}")
28782884
}
28792885
}
2880-
2886+
28812887
generateNamespaceDeclarations(node: node, depth: depth)
28822888
}
28832889
}

Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,25 @@ import Testing
9191
let bridgeJSLink: BridgeJSLink = BridgeJSLink(exportedSkeletons: [outputSkeleton], sharedMemory: false)
9292
try snapshot(bridgeJSLink: bridgeJSLink, name: name + ".Global.Export")
9393
}
94+
95+
@Test
96+
func snapshotMixedModuleExposure() throws {
97+
let globalURL = Self.inputsDirectory.appendingPathComponent("MixedGlobal.swift")
98+
let globalSourceFile = Parser.parse(source: try String(contentsOf: globalURL, encoding: .utf8))
99+
let globalAPI = ExportSwift(progress: .silent, moduleName: "GlobalModule", exposeToGlobal: true)
100+
try globalAPI.addSourceFile(globalSourceFile, "MixedGlobal.swift")
101+
let (_, globalSkeleton) = try #require(try globalAPI.finalize())
102+
103+
let privateURL = Self.inputsDirectory.appendingPathComponent("MixedPrivate.swift")
104+
let privateSourceFile = Parser.parse(source: try String(contentsOf: privateURL, encoding: .utf8))
105+
let privateAPI = ExportSwift(progress: .silent, moduleName: "PrivateModule", exposeToGlobal: false)
106+
try privateAPI.addSourceFile(privateSourceFile, "MixedPrivate.swift")
107+
let (_, privateSkeleton) = try #require(try privateAPI.finalize())
108+
109+
let bridgeJSLink = BridgeJSLink(
110+
exportedSkeletons: [globalSkeleton, privateSkeleton],
111+
sharedMemory: false
112+
)
113+
try snapshot(bridgeJSLink: bridgeJSLink, name: "MixedModules.Export")
114+
}
94115
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@JS(namespace: "GlobalAPI")
2+
func globalFunction() -> String
3+
4+
@JS(namespace: "GlobalAPI")
5+
class GlobalClass {
6+
@JS public init()
7+
@JS public func greet() -> String
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@JS(namespace: "PrivateAPI")
2+
func privateFunction() -> String
3+
4+
@JS(namespace: "PrivateAPI")
5+
class PrivateClass {
6+
@JS public init()
7+
@JS public func greet() -> String
8+
}

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.Export.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ export async function createInstantiator(options, swift) {
191191
if (!importObject["TestModule"]) {
192192
importObject["TestModule"] = {};
193193
}
194+
importObject["TestModule"]["bjs_ConstructorDefaults_wrap"] = function(pointer) {
195+
const obj = ConstructorDefaults.__construct(pointer);
196+
return swift.memory.retain(obj);
197+
};
194198
importObject["TestModule"]["bjs_DefaultGreeter_wrap"] = function(pointer) {
195199
const obj = DefaultGreeter.__construct(pointer);
196200
return swift.memory.retain(obj);
@@ -199,10 +203,6 @@ export async function createInstantiator(options, swift) {
199203
const obj = EmptyGreeter.__construct(pointer);
200204
return swift.memory.retain(obj);
201205
};
202-
importObject["TestModule"]["bjs_ConstructorDefaults_wrap"] = function(pointer) {
203-
const obj = ConstructorDefaults.__construct(pointer);
204-
return swift.memory.retain(obj);
205-
};
206206
},
207207
setInstance: (i) => {
208208
instance = i;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
2+
// DO NOT EDIT.
3+
//
4+
// To update this file, just rebuild your project or run
5+
// `swift package bridge-js`.
6+
7+
/// Represents a Swift heap object like a class instance or an actor instance.
8+
export interface SwiftHeapObject {
9+
/// Release the heap object.
10+
///
11+
/// Note: Calling this method will release the heap object and it will no longer be accessible.
12+
release(): void;
13+
}
14+
export interface GlobalClass extends SwiftHeapObject {
15+
greet(): string;
16+
}
17+
export type Exports = {
18+
GlobalAPI: {
19+
GlobalClass: {
20+
new(): GlobalClass;
21+
}
22+
globalFunction(): string;
23+
},
24+
}
25+
export type Imports = {
26+
}
27+
export function createInstantiator(options: {
28+
imports: Imports;
29+
}, swift: any): Promise<{
30+
addImports: (importObject: WebAssembly.Imports) => void;
31+
setInstance: (instance: WebAssembly.Instance) => void;
32+
createExports: (instance: WebAssembly.Instance) => Exports;
33+
}>;

0 commit comments

Comments
 (0)