rpsmatch_test.gno
2.11 Kb · 97 lines
1package rpsmatch
2
3import (
4 "testing"
5
6 "gno.land/p/nt/avl/v0"
7 "gno.land/p/nt/testutils/v0"
8)
9
10func resetState() {
11 players = avl.Tree{}
12 nonce = 0
13 totalRounds = 0
14 var zero address
15 champion = zero
16 championWins = 0
17}
18
19func TestJudge(t *testing.T) {
20 cases := []struct {
21 p, h Move
22 want int
23 }{
24 {Rock, Rock, 0},
25 {Paper, Paper, 0},
26 {Scissors, Scissors, 0},
27 {Paper, Rock, 1},
28 {Scissors, Paper, 1},
29 {Rock, Scissors, 1},
30 {Rock, Paper, 2},
31 {Paper, Scissors, 2},
32 {Scissors, Rock, 2},
33 }
34 for _, c := range cases {
35 if got := judge(c.p, c.h); got != c.want {
36 t.Fatalf("judge(%v,%v) = %d, want %d", c.p, c.h, got, c.want)
37 }
38 }
39}
40
41func TestParseMove(t *testing.T) {
42 for _, s := range []string{"rock", "Rock", " r ", "paper", "P", "scissors", "S"} {
43 if _, ok := parseMove(s); !ok {
44 t.Fatalf("parseMove(%q) should be valid", s)
45 }
46 }
47 if _, ok := parseMove("lizard"); ok {
48 t.Fatal("parseMove(\"lizard\") should be invalid")
49 }
50}
51
52// Crossing: Throw mutates realm state, so the test needs `cur realm`.
53func TestThrowUpdatesStats(cur realm, t *testing.T) {
54 resetState()
55 alice := testutils.TestAddress("alice")
56 testing.SetRealm(testing.NewUserRealm(alice))
57 Throw(cross(cur), "rock")
58
59 ps := getOrCreate(alice)
60 if ps.RoundsPlayed != 1 {
61 t.Fatalf("RoundsPlayed = %d, want 1", ps.RoundsPlayed)
62 }
63 if totalRounds != 1 {
64 t.Fatalf("totalRounds = %d, want 1", totalRounds)
65 }
66}
67
68func TestMatchCompletes(cur realm, t *testing.T) {
69 resetState()
70 alice := testutils.TestAddress("alice")
71 testing.SetRealm(testing.NewUserRealm(alice))
72
73 for i := 0; i < 10; i++ {
74 ps := getOrCreate(alice)
75 if ps.Active == nil && ps.MatchesPlayed > 0 {
76 break
77 }
78 Throw(cross(cur), "rock")
79 }
80
81 ps := getOrCreate(alice)
82 if ps.MatchesPlayed == 0 {
83 t.Fatal("expected a match to complete within 10 rounds")
84 }
85 if ps.MatchWins+ps.MatchLosses != ps.MatchesPlayed {
86 t.Fatalf("wins+losses (%d) != matchesPlayed (%d)", ps.MatchWins+ps.MatchLosses, ps.MatchesPlayed)
87 }
88}
89
90// Non-crossing: Render is a plain read.
91func TestRenderHome(t *testing.T) {
92 resetState()
93 out := Render("")
94 if out == "" {
95 t.Fatal("Render(\"\") should not be empty")
96 }
97}