Add hot reload for development
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>
This commit is contained in:
102
host/inject_test.go
Normal file
102
host/inject_test.go
Normal file
@@ -0,0 +1,102 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user