All checks were successful
CI / build (pull_request) Successful in 32s
Implement automatic rebuild and browser reload during development:
- File watcher monitors .go files for changes with configurable extensions
- Builder compiles Go source to WASM on file changes
- LiveReload WebSocket server notifies connected browsers to reload
- DevServer combines all components for easy development setup
- HTML injection adds reload script automatically
Usage:
dev := host.NewDevServer("public", "index.html", ".", "public/app.wasm")
dev.ListenAndServe(":8080")
Closes #9
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
103 lines
2.4 KiB
Go
103 lines
2.4 KiB
Go
package host
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestInjectReloadScript_BeforeBody(t *testing.T) {
|
|
html := []byte(`<!DOCTYPE html>
|
|
<html>
|
|
<head><title>Test</title></head>
|
|
<body>
|
|
<h1>Hello</h1>
|
|
</body>
|
|
</html>`)
|
|
|
|
result := InjectReloadScript(html)
|
|
|
|
// Should contain the script
|
|
if !strings.Contains(string(result), "livereload") {
|
|
t.Error("Expected result to contain livereload script")
|
|
}
|
|
|
|
// Script should be before </body>
|
|
bodyIndex := strings.Index(string(result), "</body>")
|
|
scriptIndex := strings.Index(string(result), "<script>")
|
|
|
|
if scriptIndex > bodyIndex {
|
|
t.Error("Expected script to be injected before </body>")
|
|
}
|
|
}
|
|
|
|
func TestInjectReloadScript_BeforeHTML(t *testing.T) {
|
|
// HTML without body tag
|
|
html := []byte(`<!DOCTYPE html>
|
|
<html>
|
|
<head><title>Test</title></head>
|
|
<div>Hello</div>
|
|
</html>`)
|
|
|
|
result := InjectReloadScript(html)
|
|
|
|
// Should contain the script
|
|
if !strings.Contains(string(result), "livereload") {
|
|
t.Error("Expected result to contain livereload script")
|
|
}
|
|
|
|
// Script should be before </html>
|
|
htmlIndex := strings.Index(string(result), "</html>")
|
|
scriptIndex := strings.Index(string(result), "<script>")
|
|
|
|
if scriptIndex > htmlIndex {
|
|
t.Error("Expected script to be injected before </html>")
|
|
}
|
|
}
|
|
|
|
func TestInjectReloadScript_Fallback(t *testing.T) {
|
|
// Minimal HTML without body or html closing tags
|
|
html := []byte(`<div>Hello</div>`)
|
|
|
|
result := InjectReloadScript(html)
|
|
|
|
// Should contain the script
|
|
if !strings.Contains(string(result), "livereload") {
|
|
t.Error("Expected result to contain livereload script")
|
|
}
|
|
|
|
// Should be appended at the end
|
|
if !strings.HasSuffix(string(result), "</script>") {
|
|
t.Error("Expected script to be appended at the end")
|
|
}
|
|
}
|
|
|
|
func TestInjectReloadScript_ContainsReconnect(t *testing.T) {
|
|
html := []byte(`<html><body></body></html>`)
|
|
result := InjectReloadScript(html)
|
|
|
|
// Should contain reconnection logic
|
|
if !strings.Contains(string(result), "reconnect") {
|
|
t.Error("Expected script to contain reconnection logic")
|
|
}
|
|
}
|
|
|
|
func TestIsHTMLContent(t *testing.T) {
|
|
tests := []struct {
|
|
contentType string
|
|
expected bool
|
|
}{
|
|
{"text/html", true},
|
|
{"text/html; charset=utf-8", true},
|
|
{"application/json", false},
|
|
{"text/css", false},
|
|
{"application/javascript", false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
result := IsHTMLContent(tt.contentType)
|
|
if result != tt.expected {
|
|
t.Errorf("IsHTMLContent(%q) = %v, want %v", tt.contentType, result, tt.expected)
|
|
}
|
|
}
|
|
}
|