tamagotchi_test.gno
3.69 Kb · 170 lines
1package tamagotchi
2
3import (
4 "strings"
5 "testing"
6
7 "gno.land/p/nt/avl/v0"
8 "gno.land/p/nt/testutils/v0"
9)
10
11func resetState() {
12 pets = avl.Tree{}
13}
14
15func TestClamp(t *testing.T) {
16 if clamp(150, 0, 100) != 100 {
17 t.Fatal("clamp should cap at hi")
18 }
19 if clamp(-5, 0, 100) != 0 {
20 t.Fatal("clamp should floor at lo")
21 }
22 if clamp(50, 0, 100) != 50 {
23 t.Fatal("clamp should pass through in-range values")
24 }
25}
26
27func TestHatchCreatesLivingPet(t *testing.T) {
28 resetState()
29 alice := testutils.TestAddress("alice")
30
31 hatch(alice, "Fluffy", 100)
32
33 p, ok := get(alice)
34 if !ok || !p.alive {
35 t.Fatal("expected a living pet after hatch")
36 }
37 if p.name != "Fluffy" {
38 t.Fatalf("expected name Fluffy, got %s", p.name)
39 }
40}
41
42func TestHatchTwiceWhileAlivePanics(t *testing.T) {
43 resetState()
44 alice := testutils.TestAddress("alice")
45 hatch(alice, "Fluffy", 100)
46
47 defer func() {
48 if r := recover(); r == nil {
49 t.Fatal("expected panic hatching a second living pet")
50 }
51 }()
52 hatch(alice, "Again", 101)
53}
54
55func TestHatchAfterDeathKeepsLifetimeStats(t *testing.T) {
56 resetState()
57 alice := testutils.TestAddress("alice")
58 hatch(alice, "Fluffy", 0)
59 feed(alice, 0)
60
61 p, _ := get(alice)
62 p.alive = false
63 p.deaths = 1
64
65 hatch(alice, "Fluffy2", 10)
66
67 p, _ = get(alice)
68 if p.feeds != 1 || p.deaths != 1 {
69 t.Fatalf("expected lifetime stats to carry over, got feeds=%d deaths=%d", p.feeds, p.deaths)
70 }
71 if !p.alive {
72 t.Fatal("expected the new pet to be alive")
73 }
74}
75
76func TestFeedReducesHunger(t *testing.T) {
77 resetState()
78 alice := testutils.TestAddress("alice")
79 hatch(alice, "Fluffy", 100)
80
81 p, _ := get(alice)
82 p.hunger = 60
83
84 feed(alice, 100)
85 if p.hunger != 30 {
86 t.Fatalf("expected hunger 30 after feed, got %d", p.hunger)
87 }
88 if p.feeds != 1 {
89 t.Fatalf("expected feeds counter to increment, got %d", p.feeds)
90 }
91}
92
93func TestPlayRefusesWhenTooTired(t *testing.T) {
94 resetState()
95 alice := testutils.TestAddress("alice")
96 hatch(alice, "Fluffy", 100)
97
98 p, _ := get(alice)
99 p.energy = 5
100
101 out := play(alice, 100)
102 if !strings.Contains(out, "too tired") {
103 t.Fatalf("expected too-tired message, got %q", out)
104 }
105 if p.plays != 0 {
106 t.Fatal("play should not have counted while too tired")
107 }
108}
109
110func TestNeglectKillsPet(t *testing.T) {
111 resetState()
112 alice := testutils.TestAddress("alice")
113 hatch(alice, "Fluffy", 0)
114
115 defer func() {
116 if r := recover(); r == nil {
117 t.Fatal("expected panic acting on a neglected/dead pet")
118 }
119 }()
120 // Feed re-ticks against a much later height, starving the pet to death.
121 feed(alice, 1000)
122}
123
124func TestFeedWithoutPetPanics(t *testing.T) {
125 resetState()
126 bob := testutils.TestAddress("bob")
127
128 defer func() {
129 if r := recover(); r == nil {
130 t.Fatal("expected panic feeding without a pet")
131 }
132 }()
133 feed(bob, 100)
134}
135
136func TestRenderShowsEmptyThenPet(t *testing.T) {
137 resetState()
138 if !strings.Contains(Render(""), "No pets hatched yet") {
139 t.Fatal("expected empty-state placeholder")
140 }
141
142 alice := testutils.TestAddress("alice")
143 hatch(alice, "Fluffy", 100)
144
145 out := Render("")
146 if !strings.Contains(out, "Fluffy") {
147 t.Fatal("expected pet name in leaderboard render")
148 }
149
150 detail := Render(alice.String())
151 if !strings.Contains(detail, "Hunger") {
152 t.Fatal("expected detail card to show hunger stat")
153 }
154}
155
156// TestHatchViaCrossingCall smoke-tests the exported, realm-crossing entry
157// point end to end (as an on-chain caller would invoke it).
158func TestHatchViaCrossingCall(cur realm, t *testing.T) {
159 resetState()
160 alice := testutils.TestAddress("alice")
161 testing.SetRealm(testing.NewUserRealm(alice))
162
163 msg := Hatch(cross(cur), "Fluffy")
164 if !strings.Contains(msg, "hatched") {
165 t.Fatalf("expected hatch confirmation, got %q", msg)
166 }
167 if _, ok := get(alice); !ok {
168 t.Fatal("expected pet to be persisted for caller")
169 }
170}