Skip to content

Commit

Permalink
Merge pull request #59 from omochi/browser-tests
Browse files Browse the repository at this point in the history
ブラウザで動かすテストを作る
  • Loading branch information
omochi authored Apr 17, 2024
2 parents 3fe0532 + 9e539a2 commit 10ec657
Show file tree
Hide file tree
Showing 19 changed files with 1,624 additions and 6 deletions.
11 changes: 11 additions & 0 deletions BrowserTests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
.swiftpm
dist
node_modules
32 changes: 32 additions & 0 deletions BrowserTests/Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"pins" : [
{
"identity" : "javascriptkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swiftwasm/JavaScriptKit",
"state" : {
"revision" : "3b5af3d442179900455307c725fe6a111a714b27",
"version" : "0.19.2"
}
},
{
"identity" : "swift-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-algorithms",
"state" : {
"revision" : "f6919dfc309e7f1b56224378b11e28bab5bccc42",
"version" : "1.2.0"
}
},
{
"identity" : "swift-numerics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-numerics.git",
"state" : {
"revision" : "0a5bc04095a675662cf24757cc0640aa2204253b",
"version" : "1.0.2"
}
}
],
"version" : 2
}
45 changes: 45 additions & 0 deletions BrowserTests/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// swift-tools-version: 5.9

import PackageDescription

var products: [Product] = []
var targets: [Target] = []

func addPage(name: String) {
targets.append(
.executableTarget(
name: name,
dependencies: [
.product(name: "React", package: "swift-react")
]
)
)
products.append(
.executable(name: name, targets: [name])
)
}

addPage(name: "QSComponents")

let package = Package(
name: "BrowserTests",
platforms: [.macOS(.v14)],
products: products + [
.executable(name: "gen-pages", targets: ["gen-pages"])
],
dependencies: [
.package(path: "../")
],
targets: targets + [
.target(
name: "GenPagesModule",
swiftSettings: [.enableUpcomingFeature("BareSlashRegexLiterals")]
),
.executableTarget(
name: "gen-pages",
dependencies: [
.target(name: "GenPagesModule", condition: .when(platforms: [.macOS]))
]
)
]
)
120 changes: 120 additions & 0 deletions BrowserTests/Sources/GenPagesModule/GenPages.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import Foundation

public struct GenPages {
public init() throws {
rootDir = URL(fileURLWithPath: ".", isDirectory: true)
pagesDir = rootDir.appending(component: "pages", directoryHint: .isDirectory)
pages = try Self.pages(rootDir: rootDir)
}

var rootDir: URL
var pagesDir: URL
var pages: [String]

public func run() throws {
try clearPagesDir()
for page in pages {
try generateEntryHTML(page: page)
}
try generateViteConfig()
try generateIndexPage()
}

private static func pages(rootDir: URL) throws -> [String] {
let packageCode = try String(contentsOf: rootDir.appending(components: "Package.swift"))
let pageRegex = /addPage\(name: "(\w*)"\)/
return packageCode.matches(of: pageRegex).map { String($0.output.1) }
}

private func clearPagesDir() throws {
let fm = FileManager.default

try? fm.removeItem(at: pagesDir)
try fm.createDirectory(at: pagesDir, withIntermediateDirectories: false)
}

private func generateEntryHTML(page: String) throws {
let html = """
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>\(page)</title>
<script type="module">
import { load } from "/src/loader/load.ts";
load("/.build/wasm32-unknown-wasi/debug/\(page).wasm");
</script>
</head>
<body>
</body>
</html>
"""

let file = pagesDir.appending(component: "\(page).html")
try html.write(to: file, atomically: true, encoding: .utf8)
}

private func generateViteConfig() throws {
var parts: [String] = []

parts.append("""
import { resolve } from 'path';
import { defineConfig } from 'vite';
export default defineConfig({
build: {
rollupOptions: {
input: {
""")

for page in pages {
parts.append("""
\(page): resolve(__dirname, "pages/\(page).html"),
""")
}

parts.append("""
},
},
}
});
""")

let code = parts.joined(separator: "\n")
let file = rootDir.appending(component: "vite.config.js")
try code.write(to: file, atomically: true, encoding: .utf8)
}

private func generateIndexPage() throws {
var parts: [String] = []

parts.append("""
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>index</title>
</head>
<body>
<ul>
""")

for page in pages {
parts.append("""
<li>
<a href="./pages/\(page).html">\(page)</a>
</li>
""")
}

parts.append("""
</ul>
</body>
</html>
""")

let code = parts.joined(separator: "\n")
let file = rootDir.appending(component: "index.html")
try code.write(to: file, atomically: true, encoding: .utf8)
}
}
28 changes: 28 additions & 0 deletions BrowserTests/Sources/QSComponents/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React
import SRTDOM
import JavaScriptKit

// https://ja.react.dev/learn

struct MyButton: Component {
func render() -> Node {
button {
"I'm a button"
}
}
}

struct MyApp: Component {
func render() -> Node {
div {
h1 {
"Welcome to my app"
}
MyButton()
}
}
}

let body = try JSWindow.global.document.body.unwrap("body")
let root = ReactRoot(element: body)
root.render(node: MyApp())
9 changes: 9 additions & 0 deletions BrowserTests/Sources/gen-pages/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#if os(WASI)
print("empty")
#else

import GenPagesModule

try GenPages().run()

#endif
16 changes: 16 additions & 0 deletions BrowserTests/bin/build
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
set -ueo pipefail
cd "$(dirname "$0")/.."

set -x

swift build --experimental-swift-sdk wasm32-unknown-wasi \
-Xswiftc -static-stdlib \
-Xswiftc -Xclang-linker -Xswiftc -mexec-model=reactor \
-Xlinker --export-if-defined=__main_argc_argv \
--disable-build-manifest-caching \
-Xlinker --stack-first \
-Xlinker --global-base=1048576 \
-Xlinker -z -Xlinker stack-size=1048576

swift run gen-pages
14 changes: 14 additions & 0 deletions BrowserTests/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>index</title>
</head>
<body>
<ul>
<li>
<a href="./pages/QSComponents.html">QSComponents</a>
</li>
</ul>
</body>
</html>
Loading

0 comments on commit 10ec657

Please sign in to comment.