across_test.gno
5.39 Kb · 139 lines
1package across
2
3import (
4 "strings"
5 "testing"
6
7 "gno.land/p/nt/testutils/v0"
8 "gno.land/p/nt/uassert/v0"
9
10 "gno.land/r/moul/x/daily/erc20/v0"
11 "gno.land/r/moul/x/daily/streak/v0"
12 "gno.land/r/moul/x/pairs/aaa/v0"
13 "gno.land/r/moul/x/pairs/bbb/v0"
14)
15
16// seeded is the address the mutation tests build state for. Everything after
17// TestReportReadsCrossRealmState sees whatever they left in the imported
18// realms, which is the whole point of the demo but also makes test order load
19// bearing: nothing below may assume a clean source realm for this address.
20var seeded = testutils.TestAddress("across-seeded")
21
22// fresh is never written to by anything here, so every source answers it with
23// its zero value. ExampleRender pins that page.
24var fresh = testutils.TestAddress("across-fresh")
25
26func TestSourceCount(t *testing.T) {
27 // The package doc and the rendered prose both say fifteen. If this fails,
28 // one of them is now a lie.
29 uassert.Equal(t, 15, Sources())
30}
31
32// Report must never name a realm that sourceRealms does not list, or the index
33// table silently stops covering what the report reads.
34func TestSourcesCoverReport(t *testing.T) {
35 known := map[string]bool{}
36 for _, s := range sourceRealms {
37 known[s] = true
38 }
39 for _, f := range Report(fresh) {
40 uassert.True(t, known[f.source], "report names an unlisted source: "+f.source)
41 }
42}
43
44// Every source answers, and no source panics. The count is asserted rather
45// than the values, so this stays true as the sources gain state.
46func TestReportAnswersFromEverySource(t *testing.T) {
47 facts := Report(fresh)
48 uassert.Equal(t, 18, len(facts))
49
50 seen := map[string]bool{}
51 for _, f := range facts {
52 seen[f.source] = true
53 }
54 // amm is the one listed source that contributes to the index only.
55 uassert.Equal(t, 14, len(seen))
56 uassert.False(t, seen["r/moul/x/amm/v0"], "amm must not be read per address")
57}
58
59// The load-bearing test: write to four realms that know nothing about this one,
60// then read all four back through Report. Break any of the four reads and this
61// goes red.
62func TestReportReadsCrossRealmState(cur realm, t *testing.T) {
63 // SetRealm governs only the crossing calls made from this frame, so the
64 // switch has to stay inline with the calls it is meant to cover.
65 testing.SetRealm(testing.NewUserRealm(seeded))
66 erc20.Mint(cross(cur), seeded, 4_200)
67 aaa.Faucet(cross(cur))
68 bbb.Faucet(cross(cur))
69 days := streak.CheckIn(cross(cur))
70 uassert.Equal(t, 1, days, "first check-in is day 1")
71
72 got := map[string]string{}
73 for _, f := range Report(seeded) {
74 if f.zero {
75 continue
76 }
77 got[f.source+" "+f.what] = f.value
78 }
79
80 uassert.Equal(t, "4200 "+erc20.Symbol(), got["r/moul/x/daily/erc20/v0 balance"])
81 uassert.Equal(t, "1 day(s)", got["r/moul/x/daily/streak/v0 current streak"])
82 uassert.Equal(t, "1 day(s)", got["r/moul/x/daily/streak/v0 best streak"])
83 uassert.True(t, got["r/moul/x/pairs/aaa/v0 balance"] != "", "aaa faucet must show up")
84 uassert.True(t, got["r/moul/x/pairs/bbb/v0 balance"] != "", "bbb faucet must show up")
85}
86
87// The rendered page for the seeded address must carry the same four facts, and
88// must hide the reads that came back empty rather than printing a wall of zeros.
89func TestRenderAddressShowsOnlyLiveFacts(t *testing.T) {
90 out := Render(seeded.String())
91
92 uassert.True(t, strings.Contains(out, "4200 "+erc20.Symbol()), "erc20 balance on the page")
93 uassert.True(t, strings.Contains(out, "current streak"), "streak on the page")
94 uassert.True(t, strings.Contains(out, "r/moul/x/pairs/aaa/v0"), "aaa on the page")
95 uassert.True(t, strings.Contains(out, "reads came back empty and are hidden"), "quiet rows hidden")
96 uassert.False(t, strings.Contains(out, "vesting grant"), "an empty grant must not render")
97}
98
99// An address-shaped path that is not an address must not reach a source realm.
100func TestRenderRejectsNonAddress(t *testing.T) {
101 out := Render("not-an-address")
102 uassert.True(t, strings.Contains(out, "is not a valid address"), "explicit refusal")
103 uassert.False(t, strings.Contains(out, "## Answers"), "no report for a bad path")
104}
105
106// The index reads a global from every source. Pinned by Contains rather than by
107// an example, because most of those globals move with chain state.
108func TestRenderIndexReadsEverySource(t *testing.T) {
109 out := Render("")
110 for _, s := range sourceRealms {
111 uassert.True(t, strings.Contains(out, s), "index must list "+s)
112 }
113 uassert.True(t, strings.Contains(out, "pool(s), index only"), "amm is flagged index-only")
114 uassert.True(t, strings.Contains(out, "roll(s) all time"), "dice global is read")
115 uassert.True(t, strings.Contains(out, "page(s) reacted to"), "reactions global is read")
116}
117
118// ExampleRender pins the report for an address no test writes to. Every value
119// in it comes from a source realm's zero state, except the rate limiter, which
120// answers a full bucket for an address it has never seen: absence and a fresh
121// allowance are the same thing there, and the report says so rather than
122// pretending the read was empty.
123func ExampleRender() {
124 print(Render(fresh.String()))
125 // Output:
126 // # across: `g1v93hymmnwvkkvun9wd597h6lta047h6l220muq`
127 //
128 // What 15 independently deployed realms say about this address. None of them was changed to answer.
129 //
130 // ## Answers
131 //
132 // | source | fact | value |
133 // | --- | --- | --- |
134 // | [`r/moul/x/daily/ratelimitdemo/v0`](/r/moul/x/daily/ratelimitdemo/v0) | rate-limit tokens left | 5 |
135 //
136 // 17 of 18 reads came back empty and are hidden.
137 //
138 // [back to the index](/r/moul/x/across/v0)
139}