From 3bc82e27ce06a92b3e6edb903e70fa703bd39982 Mon Sep 17 00:00:00 2001 From: Virgil Date: Sat, 4 Apr 2026 01:35:13 +0000 Subject: [PATCH] test(wasm): add host-side render coverage Co-Authored-By: Virgil --- cmd/wasm/main.go | 23 ++++------------ cmd/wasm/render_shared.go | 35 ++++++++++++++++++++++++ cmd/wasm/render_shared_test.go | 49 ++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 cmd/wasm/render_shared.go create mode 100644 cmd/wasm/render_shared_test.go diff --git a/cmd/wasm/main.go b/cmd/wasm/main.go index 33a7eba..7ce280f 100644 --- a/cmd/wasm/main.go +++ b/cmd/wasm/main.go @@ -25,32 +25,19 @@ func renderToString(_ js.Value, args []js.Value) any { if len(args) >= 2 && args[1].Type() == js.TypeString { locale = args[1].String() } - ctx := html.NewContext(locale) - - layout := html.NewLayout(variant) + slots := make(map[string]html.Node) if len(args) >= 3 && args[2].Type() == js.TypeObject { - slots := args[2] + jsSlots := args[2] for _, slot := range []string{"H", "L", "C", "R", "F"} { - content := slots.Get(slot) + content := jsSlots.Get(slot) if content.Type() == js.TypeString && content.String() != "" { - switch slot { - case "H": - layout.H(html.Raw(content.String())) - case "L": - layout.L(html.Raw(content.String())) - case "C": - layout.C(html.Raw(content.String())) - case "R": - layout.R(html.Raw(content.String())) - case "F": - layout.F(html.Raw(content.String())) - } + slots[slot] = html.Raw(content.String()) } } } - return layout.Render(ctx) + return renderLayout(variant, locale, slots) } // registerComponents defines custom elements from the HLCRF slot map. diff --git a/cmd/wasm/render_shared.go b/cmd/wasm/render_shared.go new file mode 100644 index 0000000..42187e4 --- /dev/null +++ b/cmd/wasm/render_shared.go @@ -0,0 +1,35 @@ +// SPDX-Licence-Identifier: EUPL-1.2 + +package main + +import html "dappco.re/go/core/html" + +// renderLayout builds an HLCRF layout from slot nodes and renders it. +// The helper is shared by the JS entrypoint and host-side tests so the +// slot-to-layout mapping stays covered outside the wasm build. +func renderLayout(variant, locale string, slots map[string]html.Node) string { + ctx := html.NewContext(locale) + layout := html.NewLayout(variant) + + for _, slot := range canonicalSlotOrder { + node, ok := slots[slot] + if !ok || node == nil { + continue + } + + switch slot { + case "H": + layout.H(node) + case "L": + layout.L(node) + case "C": + layout.C(node) + case "R": + layout.R(node) + case "F": + layout.F(node) + } + } + + return layout.Render(ctx) +} diff --git a/cmd/wasm/render_shared_test.go b/cmd/wasm/render_shared_test.go new file mode 100644 index 0000000..7288cbf --- /dev/null +++ b/cmd/wasm/render_shared_test.go @@ -0,0 +1,49 @@ +//go:build !js + +// SPDX-Licence-Identifier: EUPL-1.2 + +package main + +import ( + "testing" + + html "dappco.re/go/core/html" +) + +func TestRenderLayout_RendersSlotsInVariantOrder(t *testing.T) { + got := renderLayout("HCF", "en-GB", map[string]html.Node{ + "H": html.Raw("head"), + "C": html.Raw("body"), + "F": html.Raw("foot"), + }) + + want := `
head
` + + `
body
` + + `
foot
` + if got != want { + t.Fatalf("renderLayout() = %q, want %q", got, want) + } +} + +func TestRenderLayout_UsesLocaleAwareTextNodes(t *testing.T) { + got := renderLayout("C", "fr-FR", map[string]html.Node{ + "C": html.El("p", html.Text("prompt.yes")), + }) + + want := `

o

` + if got != want { + t.Fatalf("renderLayout() with locale = %q, want %q", got, want) + } +} + +func TestRenderLayout_IgnoresMissingAndUnknownSlots(t *testing.T) { + got := renderLayout("C", "en-GB", map[string]html.Node{ + "C": html.Raw("content"), + "X": html.Raw("ignored"), + }) + + want := `
content
` + if got != want { + t.Fatalf("renderLayout() with unknown slots = %q, want %q", got, want) + } +}