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