Add fonts, autotable, autotable examples
This commit is contained in:
80
go/wasmruntime/hydrate_test.go
Normal file
80
go/wasmruntime/hydrate_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
//go:build js && wasm
|
||||
|
||||
package wasmruntime
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"syscall/js"
|
||||
"testing"
|
||||
|
||||
"kjol/vdom"
|
||||
)
|
||||
|
||||
// buildServerDOM fakes what the HTML parser hands us: a real DOM tree, built from
|
||||
// the SERVER's VNode tree, which hydration then adopts.
|
||||
func buildServerDOM(server *vdom.VNode) js.Value { return createDOM(server, "") }
|
||||
|
||||
// Hydration ADOPTS the server's DOM. If the server's HTML and the client's render
|
||||
// disagree, the disagreement has to be resolved in the CLIENT's favour — it is the
|
||||
// one that is running, and it is the only one that can still change.
|
||||
//
|
||||
// Left unreconciled, the divergence is permanent and invisible: the DOM keeps the
|
||||
// server's value, and no later re-render corrects it either, because updateAttrs
|
||||
// compares one client VNode against the next — which agree with each other and
|
||||
// disagree with the DOM. The symptom is a page that is right when you navigate to it
|
||||
// and wrong when you refresh onto it.
|
||||
func TestHydrationReconcilesAttributes(t *testing.T) {
|
||||
root := document.Call("createElement", "div")
|
||||
|
||||
// What the server rendered (say, from a stale binary).
|
||||
server := vdom.El("main", vdom.Attr("class", "mx-auto max-w-5xl px-4"))
|
||||
root.Call("appendChild", buildServerDOM(server))
|
||||
|
||||
// What the client actually renders now.
|
||||
client := vdom.El("main", vdom.Attr("class", "mx-auto max-w-[100rem] px-4"))
|
||||
hydrateNode(root.Get("firstChild"), client)
|
||||
|
||||
got := root.Get("firstChild").Call("getAttribute", "class").String()
|
||||
if got != "mx-auto max-w-[100rem] px-4" {
|
||||
t.Errorf("after hydration class = %q, want the client's value — the server's stale class was kept", got)
|
||||
}
|
||||
}
|
||||
|
||||
// And the ordinary case must still work: matching markup is adopted, not rebuilt.
|
||||
func TestHydrationAdoptsMatchingMarkup(t *testing.T) {
|
||||
root := document.Call("createElement", "div")
|
||||
|
||||
server := vdom.El("div", vdom.Attr("class", "a"),
|
||||
vdom.El("span", vdom.Text("hello")),
|
||||
)
|
||||
root.Call("appendChild", buildServerDOM(server))
|
||||
adopted := root.Get("firstChild")
|
||||
|
||||
client := vdom.El("div", vdom.Attr("class", "a"),
|
||||
vdom.El("span", vdom.Text("hello")),
|
||||
)
|
||||
hydrateNode(root.Get("firstChild"), client)
|
||||
|
||||
// Same node — hydration adopted it rather than replacing it.
|
||||
if !rt(client).dom.Equal(adopted) {
|
||||
t.Error("hydration replaced a matching node instead of adopting it")
|
||||
}
|
||||
if got := root.Get("innerHTML").String(); !strings.Contains(got, "hello") {
|
||||
t.Errorf("content lost: %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
// A text node that disagrees is corrected too (this already worked; pin it).
|
||||
func TestHydrationCorrectsText(t *testing.T) {
|
||||
root := document.Call("createElement", "div")
|
||||
|
||||
server := vdom.El("p", vdom.Text("stale"))
|
||||
root.Call("appendChild", buildServerDOM(server))
|
||||
|
||||
client := vdom.El("p", vdom.Text("fresh"))
|
||||
hydrateNode(root.Get("firstChild"), client)
|
||||
|
||||
if got := root.Get("innerHTML").String(); !strings.Contains(got, "fresh") {
|
||||
t.Errorf("stale server text survived hydration: %s", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user