1+ package io .github .quafadas .sjsls
2+
3+ import mill .api .Discover
4+ import mill .api .Task .Simple
5+ import mill .testkit .TestRootModule
6+ import mill .testkit .UnitTester
7+ import mill .util .TokenReaders .*
8+ import mill .javalib .DepSyntax
9+ import utest .*
10+
11+ object MemWasmTests extends TestSuite :
12+ def tests : Tests = Tests {
13+ test(" fastLinkJS WASM output has a hashed wasm file, not hashed JS files" ) {
14+ object build extends TestRootModule with InMemoryFastLinkHashScalaJSModule :
15+ override def scalaVersion : Simple [String ] = " 3.8.2"
16+ override def scalaJSExperimentalUseWebAssembly = true
17+
18+ override def mvnDeps = Seq (
19+ mvn " com.raquo::laminar::17.0.0 "
20+ )
21+
22+ lazy val millDiscover = Discover [this .type ]
23+ end build
24+
25+ val resourceFolder = os.Path (sys.env(" MILL_TEST_RESOURCE_DIR" ))
26+
27+ UnitTester (build, resourceFolder / " simple" ).scoped {
28+ eval =>
29+
30+ val Right (result) = eval(build.fastLinkJS).runtimeChecked
31+ val report = result.value
32+
33+ // Files live in-memory, not on disk
34+ val memFiles = build.inMemoryOutputDirectory.fileNames().toSet
35+
36+ // The main entry-point JS file must be renamed to a hashed filename.
37+ assert(! memFiles.contains(" main.wasm" ))
38+ assert(memFiles.contains(" __loader.js" ))
39+ assert(memFiles.contains(" main.js" ))
40+
41+
42+ // The WASM binary must be preserved (not renamed).
43+ if ! memFiles.exists(_.endsWith(" .wasm" )) then
44+ throw new java.lang.AssertionError (s " no .wasm file found in: $memFiles" )
45+ end if
46+
47+ // The Report's public module must reference the hashed JS file.
48+ assert(report.publicModules.nonEmpty)
49+ val reported = report.publicModules.head.jsFileName
50+ if reported != " main.js" then
51+ throw new java.lang.AssertionError (
52+ s " report module jsFileName should be main.js, was $reported"
53+ )
54+ end if
55+ }
56+ }
57+
58+ test(" InMemoryFastLinkHashScalaJSModule fullLinkJS runs wasm-opt and hashes the optimised binary" ) {
59+ object build extends TestRootModule with InMemoryFastLinkHashScalaJSModule :
60+ override def scalaVersion : Simple [String ] = " 3.8.2"
61+ override def scalaJSExperimentalUseWebAssembly = true
62+
63+ override def mvnDeps = Seq (
64+ mvn " com.raquo::laminar::17.0.0 "
65+ )
66+
67+ lazy val millDiscover = Discover [this .type ]
68+ end build
69+
70+ val resourceFolder = os.Path (sys.env(" MILL_TEST_RESOURCE_DIR" ))
71+
72+ UnitTester (build, resourceFolder / " simple" ).scoped {
73+ eval =>
74+ // Run fastLinkJS first to capture the unoptimised wasm size (lives in-memory).
75+ val Right (_) = eval(build.fastLinkJS).runtimeChecked
76+ val fastWasmNames = build.inMemoryOutputDirectory.fileNames().filter(_.endsWith(" .wasm" ))
77+ if fastWasmNames.size != 1 then
78+ throw new java.lang.AssertionError (s " Expected exactly 1 wasm file after fastLinkJS, got: $fastWasmNames" )
79+ end if
80+ val fastBuf = build.inMemoryOutputDirectory.content(fastWasmNames.head).get
81+ val fastWasmSize = fastBuf.remaining().toLong
82+
83+ // Run fullLinkJS: wasm-opt should produce a smaller binary with a different hash.
84+ // fullLinkJS writes file-based output to Task.dest (not in-memory).
85+ val Right (fullResult) = eval(build.fullLinkJS).runtimeChecked
86+ val fullDir = fullResult.value.dest.path
87+ val fullWasmFiles = os.list(fullDir).filter(p => os.isFile(p) && p.ext == " wasm" )
88+ if fullWasmFiles.size != 1 then
89+ throw new java.lang.AssertionError (
90+ s " Expected exactly 1 wasm file after fullLinkJS, got: $fullWasmFiles"
91+ )
92+ end if
93+ val fullWasm = fullWasmFiles.head
94+ val fullWasmSize = os.size(fullWasm)
95+
96+ // The name must be content-hashed (base.<hash>.wasm), not the bare original name.
97+ val nameParts = fullWasm.baseName.split('.' )
98+ if nameParts.length < 2 then
99+ throw new java.lang.AssertionError (
100+ s " Expected hashed wasm filename like 'main.<hash>.wasm', got: ${fullWasm.last}"
101+ )
102+ end if
103+
104+ // The optimised binary must be strictly smaller.
105+ if fullWasmSize >= fastWasmSize then
106+ throw new java.lang.AssertionError (
107+ s " wasm-opt did not reduce size: fastLinkJS= $fastWasmSize bytes, fullLinkJS= $fullWasmSize bytes "
108+ )
109+ end if
110+ }
111+ }
112+ }
113+
114+ end MemWasmTests
0 commit comments