Update fetch for static page gen, fix DOM patching
This commit is contained in:
86
go/wasmruntime/reconcile_test.go
Normal file
86
go/wasmruntime/reconcile_test.go
Normal file
@@ -0,0 +1,86 @@
|
||||
//go:build js && wasm
|
||||
|
||||
package wasmruntime
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"kjol/vdom"
|
||||
)
|
||||
|
||||
// The reconciler is wasm-only and needs a DOM, so these do not run under a plain
|
||||
// `go test ./...` (the native build of this package is an empty placeholder).
|
||||
// Run them against the minimal DOM in testdata/domexec.js — from kjol/go:
|
||||
//
|
||||
// GOOS=js GOARCH=wasm go test -exec="node testdata/domexec.js" ./wasmruntime
|
||||
|
||||
// A Raw() node carries its markup in VNode.HTML and has NO children — the markup
|
||||
// only exists in the DOM. So when the diff reuses that element for a node that
|
||||
// has children instead (same tag, same index — e.g. a route change from a page
|
||||
// with a server-rendered SVG to one without), the new children must not simply be
|
||||
// appended alongside the surviving markup.
|
||||
func TestPatchClearsRawHTMLWhenElementIsReused(t *testing.T) {
|
||||
root := document.Call("createElement", "div")
|
||||
|
||||
chart := vdom.El("div", vdom.Attr("class", "grid"),
|
||||
vdom.El("div", vdom.Attr("class", "cell"), vdom.Raw(`<svg id="bar"></svg>`)),
|
||||
)
|
||||
patchChildren(root, nil, one(chart))
|
||||
if got := root.Get("innerHTML").String(); !strings.Contains(got, `<svg id="bar">`) {
|
||||
t.Fatalf("raw HTML was not mounted: %s", got)
|
||||
}
|
||||
|
||||
// Same tags at the same indexes, so the diff adopts the DOM rather than
|
||||
// replacing it.
|
||||
data := vdom.El("div", vdom.Attr("class", "cards"),
|
||||
vdom.El("div", vdom.Attr("class", "card"), vdom.Text("gob section")),
|
||||
)
|
||||
patchChildren(root, one(chart), one(data))
|
||||
|
||||
got := root.Get("innerHTML").String()
|
||||
if strings.Contains(got, "svg") {
|
||||
t.Errorf("stale raw HTML survived the patch (the chart would follow you to the next page):\n%s", got)
|
||||
}
|
||||
if !strings.Contains(got, "gob section") {
|
||||
t.Errorf("new children were not rendered:\n%s", got)
|
||||
}
|
||||
}
|
||||
|
||||
// The reverse transition: an element with real children reused for a Raw() node.
|
||||
// innerHTML replaces the children wholesale, so nothing may linger.
|
||||
func TestPatchReplacesChildrenWithRawHTML(t *testing.T) {
|
||||
root := document.Call("createElement", "div")
|
||||
|
||||
withKids := vdom.El("div", vdom.El("span", vdom.Text("hello")))
|
||||
patchChildren(root, nil, one(withKids))
|
||||
|
||||
withRaw := vdom.El("div", vdom.Raw(`<svg id="pie"></svg>`))
|
||||
patchChildren(root, one(withKids), one(withRaw))
|
||||
|
||||
got := root.Get("innerHTML").String()
|
||||
if strings.Contains(got, "hello") || strings.Contains(got, "span") {
|
||||
t.Errorf("old children survived under raw HTML:\n%s", got)
|
||||
}
|
||||
if !strings.Contains(got, `<svg id="pie">`) {
|
||||
t.Errorf("raw HTML was not applied:\n%s", got)
|
||||
}
|
||||
}
|
||||
|
||||
// Raw markup that does not change must be left alone (it is not re-set on every
|
||||
// render, which would blow away any DOM state inside it).
|
||||
func TestPatchKeepsUnchangedRawHTML(t *testing.T) {
|
||||
root := document.Call("createElement", "div")
|
||||
|
||||
a := vdom.El("div", vdom.Raw(`<svg id="bar"></svg>`))
|
||||
patchChildren(root, nil, one(a))
|
||||
before := rt(a).dom.Get("childNodes").Index(0)
|
||||
|
||||
b := vdom.El("div", vdom.Raw(`<svg id="bar"></svg>`))
|
||||
patchChildren(root, one(a), one(b))
|
||||
|
||||
after := rt(b).dom.Get("childNodes").Index(0)
|
||||
if !before.Equal(after) {
|
||||
t.Error("unchanged raw HTML was re-parsed instead of being left in place")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user