//go:build js && wasm package wasmruntime import ( "strings" "syscall/js" "testing" "kjol/vdom" ) // Run from kjol/go: // // GOOS=js GOARCH=wasm go test -exec="node testdata/domexec.js" ./wasmruntime // A Ref must be attached when the element is created, survive a diff that reuses // the element, and be nil again once the element is gone — otherwise measurement // code silently reads a stale node. func TestRefLifecycle(t *testing.T) { root := document.Call("createElement", "div") panel := vdom.NewRef() if panel.Mounted() { t.Fatal("a fresh ref should not be mounted") } a := vdom.El("div", vdom.WithRef(panel), vdom.Attr("class", "one")) patchChildren(root, nil, one(a)) if !panel.Mounted() { t.Fatal("ref was not attached on create") } created, _ := panel.Node().(js.Value) // A re-render builds a fresh VNode carrying the same *Ref; the diff adopts the // existing element, so the ref must still point at it. b := vdom.El("div", vdom.WithRef(panel), vdom.Attr("class", "two")) patchChildren(root, one(a), one(b)) if !panel.Mounted() { t.Fatal("ref was detached by a re-render that reused the element") } if adopted, _ := panel.Node().(js.Value); !adopted.Equal(created) { t.Error("ref points at a different node after a reusing diff") } // Removing the element must clear the ref. patchChildren(root, one(b), nil) if panel.Mounted() { t.Error("ref still points at a removed element") } } // A tag change replaces the element. createDOM runs before release (replaceChild // needs both nodes), so a naive detach-on-release would nil the ref that was just // pointed at the NEW element. func TestRefSurvivesTagChange(t *testing.T) { root := document.Call("createElement", "div") r := vdom.NewRef() a := vdom.El("div", vdom.WithRef(r)) patchChildren(root, nil, one(a)) b := vdom.El("span", vdom.WithRef(r)) patchChildren(root, one(a), one(b)) if !r.Mounted() { t.Fatal("ref was cleared when the element changed tag") } if got := Measure(r); got != (Rect{}) { // shim reports a zero rect by default _ = got } if !strings.Contains(root.Get("innerHTML").String(), "