1+ import Foundation
2+ import Testing
3+
4+ @testable import PackageToJS
5+
6+ @Suite struct WasmOptTests {
7+
8+ /// A mock system that simulates wasm-opt not being available
9+ class MockPackagingSystemWithoutWasmOpt : PackagingSystem {
10+ var warnings : [ String ] = [ ]
11+ var wasmOptCalls : [ ( arguments: [ String ] , input: String , output: String ) ] = [ ]
12+
13+ func npmInstall( packageDir: String ) throws {
14+ // No-op for testing
15+ }
16+
17+ func wasmOpt( _ arguments: [ String ] , input: String , output: String ) throws {
18+ wasmOptCalls. append ( ( arguments, input, output) )
19+
20+ // Simulate wasm-opt not found by using the same logic as DefaultPackagingSystem
21+ // but without the actual which() call succeeding
22+ warnings. append ( " Warning: wasm-opt is not installed, optimizations will not be applied " )
23+
24+ // Test the file copy logic that would happen when wasm-opt is not found
25+ // (This matches the fixed behavior that removes existing files first)
26+ if FileManager . default. fileExists ( atPath: output) {
27+ try FileManager . default. removeItem ( atPath: output)
28+ }
29+ try FileManager . default. copyItem ( atPath: input, toPath: output)
30+ }
31+ }
32+
33+ /// A mock system that fails when copying files (to test error handling)
34+ class MockPackagingSystemWithCopyFailure : PackagingSystem {
35+ var wasmOptCalls : [ ( arguments: [ String ] , input: String , output: String ) ] = [ ]
36+
37+ func npmInstall( packageDir: String ) throws {
38+ // No-op for testing
39+ }
40+
41+ func wasmOpt( _ arguments: [ String ] , input: String , output: String ) throws {
42+ wasmOptCalls. append ( ( arguments, input, output) )
43+
44+ // Simulate the case where wasm-opt is not found and file copy fails
45+ throw PackageToJSError ( " Permission denied when copying wasm file " )
46+ }
47+ }
48+
49+ @Test func wasmOptNotInstalledFallbackWorksCorrectly( ) throws {
50+ try withTemporaryDirectory { tempDir, _ in
51+ // Create a dummy input wasm file
52+ let inputFile = tempDir. appendingPathComponent ( " input.wasm " )
53+ let outputFile = tempDir. appendingPathComponent ( " output.wasm " )
54+ let dummyContent = Data ( " dummy wasm content " . utf8)
55+ try dummyContent. write ( to: inputFile)
56+
57+ let mockSystem = MockPackagingSystemWithoutWasmOpt ( )
58+
59+ // This should copy the file instead of optimizing
60+ try mockSystem. wasmOpt ( [ " -Os " ] , input: inputFile. path, output: outputFile. path)
61+
62+ // Verify the file was copied
63+ #expect( FileManager . default. fileExists ( atPath: outputFile. path) )
64+ let copiedContent = try Data ( contentsOf: outputFile)
65+ #expect( copiedContent == dummyContent)
66+
67+ // Verify warning was recorded
68+ #expect( mockSystem. warnings. count == 1 )
69+ #expect( mockSystem. warnings [ 0 ] . contains ( " wasm-opt is not installed " ) )
70+
71+ // Verify the call was made
72+ #expect( mockSystem. wasmOptCalls. count == 1 )
73+ #expect( mockSystem. wasmOptCalls [ 0 ] . arguments == [ " -Os " ] )
74+ }
75+ }
76+
77+ @Test func wasmOptNotInstalledHandlesExistingOutputFile( ) throws {
78+ try withTemporaryDirectory { tempDir, _ in
79+ // Create a dummy input wasm file
80+ let inputFile = tempDir. appendingPathComponent ( " input.wasm " )
81+ let outputFile = tempDir. appendingPathComponent ( " output.wasm " )
82+ let inputContent = Data ( " input wasm content " . utf8)
83+ let existingContent = Data ( " existing output content " . utf8)
84+
85+ try inputContent. write ( to: inputFile)
86+ try existingContent. write ( to: outputFile)
87+
88+ let mockSystem = MockPackagingSystemWithoutWasmOpt ( )
89+
90+ // This should overwrite the existing output file
91+ try mockSystem. wasmOpt ( [ " -Os " ] , input: inputFile. path, output: outputFile. path)
92+
93+ // Verify the output file has the input content (not the existing content)
94+ #expect( FileManager . default. fileExists ( atPath: outputFile. path) )
95+ let finalContent = try Data ( contentsOf: outputFile)
96+ #expect( finalContent == inputContent)
97+ #expect( finalContent != existingContent)
98+ }
99+ }
100+
101+ @Test func wasmOptCopyFailureThrowsError( ) throws {
102+ try withTemporaryDirectory { tempDir, _ in
103+ let inputFile = tempDir. appendingPathComponent ( " input.wasm " )
104+ let outputFile = tempDir. appendingPathComponent ( " output.wasm " )
105+
106+ let mockSystem = MockPackagingSystemWithCopyFailure ( )
107+
108+ // This should throw an error
109+ #expect( throws: PackageToJSError . self) {
110+ try mockSystem. wasmOpt ( [ " -Os " ] , input: inputFile. path, output: outputFile. path)
111+ }
112+
113+ // Verify the call was made
114+ #expect( mockSystem. wasmOptCalls. count == 1 )
115+ }
116+ }
117+
118+ @Test func realDefaultPackagingSystemFallbackBehavior( ) throws {
119+ try withTemporaryDirectory { tempDir, _ in
120+ // Create a dummy input wasm file
121+ let inputFile = tempDir. appendingPathComponent ( " input.wasm " )
122+ let outputFile = tempDir. appendingPathComponent ( " output.wasm " )
123+ let dummyContent = Data ( " dummy wasm content " . utf8)
124+ try dummyContent. write ( to: inputFile)
125+
126+ var capturedWarnings : [ String ] = [ ]
127+ let realSystem = DefaultPackagingSystem { warning in
128+ capturedWarnings. append ( warning)
129+ }
130+
131+ // Temporarily move wasm-opt out of the way to simulate it not being installed
132+ let wasmOptPath = " /opt/homebrew/bin/wasm-opt "
133+ let tempWasmOptPath = " /tmp/wasm-opt-backup-for-test "
134+
135+ let wasmOptExists = FileManager . default. fileExists ( atPath: wasmOptPath)
136+ if wasmOptExists {
137+ try ? FileManager . default. moveItem ( atPath: wasmOptPath, toPath: tempWasmOptPath)
138+ }
139+
140+ defer {
141+ // Restore wasm-opt if it existed
142+ if wasmOptExists {
143+ try ? FileManager . default. moveItem ( atPath: tempWasmOptPath, toPath: wasmOptPath)
144+ }
145+ }
146+
147+ // This should fall back to copying since wasm-opt is not available
148+ try realSystem. wasmOpt ( [ " -Os " ] , input: inputFile. path, output: outputFile. path)
149+
150+ // Verify the file was copied
151+ #expect( FileManager . default. fileExists ( atPath: outputFile. path) )
152+ let copiedContent = try Data ( contentsOf: outputFile)
153+ #expect( copiedContent == dummyContent)
154+
155+ // Verify warning was issued
156+ #expect( capturedWarnings. count >= 1 )
157+ #expect( capturedWarnings [ 0 ] . contains ( " wasm-opt is not installed " ) )
158+ }
159+ }
160+ }
0 commit comments