Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

render_test.gno

4.98 Kb · 140 lines
  1package home
  2
  3import (
  4	"strings"
  5	"testing"
  6
  7	"gno.land/p/nt/uassert/v0"
  8)
  9
 10// Tests that need no crossing: pure helpers and the built-in views. The
 11// crossing behavior (writes, authority, theme lifecycle) is in home_test.gno,
 12// from outside the package, because a call into one's own realm never crosses.
 13
 14func TestValidSlug(t *testing.T) {
 15	for _, ok := range []string{"a", "now", "style.accent", "a-b_c.d", strings.Repeat("x", 64)} {
 16		uassert.True(t, validSlug(ok), ok)
 17	}
 18	for _, bad := range []string{"", "Now", "a:b", "a b", "a/b", strings.Repeat("x", 65)} {
 19		uassert.False(t, validSlug(bad), bad)
 20	}
 21}
 22
 23func TestFence(t *testing.T) {
 24	uassert.Equal(t, "```", fence("plain"))
 25	uassert.Equal(t, "```", fence("has `one` and ``two``"))
 26	uassert.Equal(t, "````", fence("```go\nx\n```"))
 27	uassert.Equal(t, "`````", fence("````"))
 28}
 29
 30func TestAttr(t *testing.T) {
 31	uassert.Equal(t, "a &amp; b &quot;c&quot; &lt;d&gt;\\n\\te", attr("a & b \"c\" <d>\r\n\te"))
 32}
 33
 34func TestFillerIsLazySinglePassAndOrderIndependent(t *testing.T) {
 35	ResetForTest()
 36	SeedForTest("a", "A says :b:")
 37	SeedForTest("b", "B")
 38	calls := 0
 39	f := NewFiller()
 40	f.Add("expensive", func() string { calls++; return "X" })
 41
 42	uassert.Equal(t, "A says :b: B :nope:", f.Fill(":a: :b: :nope:"))
 43	uassert.Equal(t, 0, calls, "an absent placeholder never runs its callback")
 44	uassert.Equal(t, "X", f.Fill(":expensive:"))
 45
 46	// A later Add for a slot's name wins: that is how a theme widget overrides.
 47	f.Add("a", func() string { return "widget" })
 48	uassert.Equal(t, "widget", f.Fill(":a:"))
 49}
 50
 51func TestRenderWithoutLayoutOrTheme(t *testing.T) {
 52	ResetForTest()
 53	out := Render("")
 54	uassert.True(t, strings.Contains(out, "# gno.land/r/g1lnkytfqcjwllws63gvf0mv9yt04aswy4y9amhm/home"), out)
 55	uassert.True(t, strings.Contains(out, "No theme is live"), out)
 56	uassert.True(t, strings.Contains(out, "_no slots yet_"), out)
 57	uassert.True(t, strings.Contains(out, "theme built-in"), out)
 58	uassert.False(t, strings.Contains(out, ":slots:"), "computed placeholders must resolve")
 59}
 60
 61func TestRenderLayoutSubstitution(t *testing.T) {
 62	ResetForTest()
 63	SeedForTest("intro", "Hello :rev: world") // placeholders inside a body stay put
 64	SeedForTest("layout", "# Page\n\n:intro:\n\nrev :rev: · :missing: · :realm:\n")
 65
 66	uassert.Equal(t, "# Page\n\nHello :rev: world\n\nrev 2 · :missing: · gno.land/r/g1lnkytfqcjwllws63gvf0mv9yt04aswy4y9amhm/home\n", Render(""))
 67}
 68
 69func TestRenderIndexAndSlot(t *testing.T) {
 70	ResetForTest()
 71	SeedForTest("now", "```go\nx := 1\n```")
 72
 73	idx := Render("slots")
 74	uassert.True(t, strings.Contains(idx, "| [now](/r/g1lnkytfqcjwllws63gvf0mv9yt04aswy4y9amhm/home:slots/now) |"), idx)
 75	uassert.True(t, strings.Contains(idx, "[edit](/r/g1lnkytfqcjwllws63gvf0mv9yt04aswy4y9amhm/home:edit/now)"), idx)
 76
 77	raw := Render("slots/now")
 78	uassert.True(t, strings.Contains(raw, "# now\n"), raw)
 79	uassert.True(t, strings.Contains(raw, "````\n```go\nx := 1\n```\n````\n"), "fence must outgrow the body: "+raw)
 80
 81	uassert.True(t, strings.Contains(Render("slots/nope"), "# Not found"))
 82	uassert.True(t, strings.Contains(Render("nope"), "# Not found"))
 83	uassert.True(t, strings.Contains(Render("slots?x=1"), "# Slots"), "query strings are ignored")
 84	uassert.Equal(t, Manifest(), Render("manifest"))
 85}
 86
 87func TestSlugsEachManifest(t *testing.T) {
 88	ResetForTest()
 89	SeedForTest("b", "two")
 90	SeedForTest("a", "one")
 91
 92	uassert.Equal(t, 2, len(Slugs()))
 93	uassert.Equal(t, "a", Slugs()[0])
 94
 95	visited := []string{}
 96	Each(func(slug string, s Slot) bool {
 97		visited = append(visited, slug+"="+s.Body)
 98		return false
 99	})
100	uassert.Equal(t, "a=one b=two", strings.Join(visited, " "))
101
102	lines := strings.Split(strings.TrimSpace(Manifest()), "\n")
103	uassert.Equal(t, 2, len(lines))
104	uassert.True(t, strings.HasPrefix(lines[0], "a\t2\t3\t"), lines[0])
105	uassert.Equal(t, 4, len(strings.Split(lines[0], "\t")))
106
107	s, ok := Lookup("a")
108	uassert.True(t, ok)
109	uassert.Equal(t, 2, s.Rev)
110	_, ok = Lookup("zzz")
111	uassert.False(t, ok)
112	uassert.Equal(t, "#000", Style("missing", "#000"))
113}
114
115func TestRenderEdit(t *testing.T) {
116	ResetForTest()
117	SeedForTest("intro", "line \"one\"\n<two> & three\ttab")
118
119	blank := Render("edit")
120	uassert.True(t, strings.Contains(blank, "<gno-form exec=\"Set\">"), blank)
121	uassert.True(t, strings.Contains(blank, "<gno-form exec=\"Delete\">"), blank)
122	uassert.True(t, strings.Contains(blank, "[edit](/r/g1lnkytfqcjwllws63gvf0mv9yt04aswy4y9amhm/home:edit/intro)"), blank)
123
124	one := Render("edit/intro")
125	uassert.True(t, strings.Contains(one, "value=\"intro\""), one)
126	uassert.True(t, strings.Contains(one,
127		"value=\"line &quot;one&quot;\\n&lt;two&gt; &amp; three\\ttab\""), one)
128
129	missing := Render("edit/later")
130	uassert.True(t, strings.Contains(missing, "Saving creates it"), missing)
131}
132
133func TestRenderSystem(t *testing.T) {
134	ResetForTest()
135	out := Render("system")
136	uassert.True(t, strings.Contains(out, "built-in fallback"), out)
137	uassert.True(t, strings.Contains(out, Admin.String()), out)
138	uassert.True(t, strings.Contains(out, "$help&func=Rollback"), out)
139	uassert.True(t, strings.Contains(out, "| last write | never |"), out)
140}