blocks_test.gno
4.73 Kb · 126 lines
1package config
2
3import (
4 "testing"
5
6 "gno.land/p/nt/uassert/v0"
7)
8
9const otherRealm = "gno.land/r/moul/gns"
10
11func TestKeyGrammar(t *testing.T) {
12 uassert.Equal(t, "pause", KeyFor("pause", ""))
13 uassert.Equal(t, "pause@r/moul/home", KeyFor("pause", "gno.land/r/moul/home"))
14 uassert.Equal(t, "pause@r/moul/home", KeyFor("pause", "r/moul/home"))
15
16 // A path this cannot scope to falls back to the global key rather than
17 // inventing one nobody can type.
18 uassert.Equal(t, "pause", KeyFor("pause", "not a path"))
19 uassert.Equal(t, "pause", KeyFor("pause", "gno.land/"))
20
21 name, scope := SplitKey("block.top@r/moul/home")
22 uassert.Equal(t, "block.top", name)
23 uassert.Equal(t, "r/moul/home", scope)
24
25 name, scope = SplitKey("block.top")
26 uassert.Equal(t, "block.top", name)
27 uassert.Equal(t, "", scope)
28}
29
30func TestScope(t *testing.T) {
31 uassert.Equal(t, "r/moul/home", Scope("gno.land/r/moul/home"))
32 uassert.Equal(t, "r/moul/home", Scope("r/moul/home"))
33 uassert.Equal(t, "p/moul/kit/ui", Scope("gno.land/p/moul/kit/ui"))
34 uassert.Equal(t, "", Scope(""))
35 uassert.Equal(t, "", Scope("gno.land/"))
36 uassert.Equal(t, "", Scope("r/moul/ho me"))
37 uassert.Equal(t, "", Scope("r//moul"))
38}
39
40// TestBlocksDefaultEmpty is the property every realm depends on: a realm that
41// renders config.TopBlock() unconditionally must be byte-for-byte what it was
42// before, until moul sets something.
43func TestBlocksDefaultEmpty(t *testing.T) {
44 resetSettings()
45 uassert.Equal(t, "", TopBlockFor(otherRealm))
46 uassert.Equal(t, "", BottomBlockFor(otherRealm))
47}
48
49func TestBlocksGlobalAndScoped(cur realm, t *testing.T) {
50 resetSettings()
51 testing.SetRealm(testing.NewUserRealm(originAddr))
52 Set(cross(cur), KeyBlockTop, "> chain migration on Tuesday")
53
54 // Global alone reaches every realm, and ends with a blank line so a realm
55 // can concatenate without a separator of its own.
56 uassert.Equal(t, "> chain migration on Tuesday\n\n", TopBlockFor(otherRealm))
57 uassert.Equal(t, "> chain migration on Tuesday\n\n", TopBlockFor("gno.land/r/moul/home"))
58
59 testing.SetRealm(testing.NewUserRealm(originAddr))
60 Set(cross(cur), KeyFor(KeyBlockTop, otherRealm), "> v2 shipped")
61
62 // BOTH are shown, global first. A chain-wide warning and a per-realm
63 // changelog are different messages; dropping either would be the
64 // surprising behaviour.
65 uassert.Equal(t,
66 "> chain migration on Tuesday\n\n> v2 shipped\n\n",
67 TopBlockFor(otherRealm))
68
69 // And the scoped one reaches only its own realm.
70 uassert.Equal(t, "> chain migration on Tuesday\n\n", TopBlockFor("gno.land/r/moul/home"))
71}
72
73func TestBottomBlock(cur realm, t *testing.T) {
74 resetSettings()
75 testing.SetRealm(testing.NewUserRealm(originAddr))
76 Set(cross(cur), KeyBlockBottom, "built by moul")
77
78 uassert.Equal(t, "built by moul\n\n", BottomBlockFor(otherRealm))
79
80 // The pause banner belongs to the top only: one banner is enough, and the
81 // top is where it gets read.
82 testing.SetRealm(testing.NewUserRealm(originAddr))
83 Set(cross(cur), KeyPause, "paused")
84 uassert.Equal(t, "built by moul\n\n", BottomBlockFor(otherRealm))
85}
86
87// TestTopBlockCarriesPause is the integration that makes guarding writes
88// enough: a realm that calls AssertWritable and renders TopBlock explains the
89// refusal on its own page without writing a line of banner code.
90func TestTopBlockCarriesPause(cur realm, t *testing.T) {
91 resetSettings()
92 testing.SetRealm(testing.NewUserRealm(originAddr))
93 Set(cross(cur), KeyPause, "readonly: migrating storage")
94
95 uassert.Equal(t,
96 "> **Read-only.** This realm is still readable, but not accepting changes. migrating storage\n\n",
97 TopBlockFor(otherRealm))
98
99 // And it comes first, before the messages.
100 testing.SetRealm(testing.NewUserRealm(originAddr))
101 Set(cross(cur), KeyBlockTop, "> news")
102 uassert.Equal(t,
103 "> **Read-only.** This realm is still readable, but not accepting changes. migrating storage\n\n> news\n\n",
104 TopBlockFor(otherRealm))
105}
106
107// TestZeroArgFormsNameTheCaller pins the borrow behaviour the whole
108// zero-argument API rests on: these are plain reads with no `cur realm`, so
109// gno opens no realm frame and the realm asking is the realm answered about.
110//
111// If this ever fails, every zero-argument helper here has silently started
112// answering for gno.land/r/moul/config instead, and the …For variants are the
113// only correct ones.
114func TestZeroArgFormsNameTheCaller(cur realm, t *testing.T) {
115 resetSettings()
116 testing.SetRealm(testing.NewUserRealm(originAddr))
117 Set(cross(cur), KeyFor(KeyBlockTop, otherRealm), "> only for gns")
118
119 testing.SetRealm(testing.NewCodeRealm(otherRealm))
120 uassert.Equal(t, "> only for gns\n\n", TopBlock())
121 uassert.Equal(t, otherRealm, caller())
122
123 testing.SetRealm(testing.NewCodeRealm("gno.land/r/moul/home"))
124 uassert.Equal(t, "", TopBlock(), "another realm sees nothing")
125 uassert.Equal(t, "gno.land/r/moul/home", caller())
126}