rpsoracle_test.gno
2.07 Kb · 99 lines
1package rpsoracle
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 oracleCorrect = 0
15 var zero address
16 topOutwitter = zero
17 topOutwitterWins = 0
18}
19
20func TestJudge(t *testing.T) {
21 cases := []struct {
22 p, h Move
23 want int
24 }{
25 {Rock, Rock, 0},
26 {Paper, Paper, 0},
27 {Scissors, Scissors, 0},
28 {Paper, Rock, 1},
29 {Scissors, Paper, 1},
30 {Rock, Scissors, 1},
31 {Rock, Paper, 2},
32 {Paper, Scissors, 2},
33 {Scissors, Rock, 2},
34 }
35 for _, c := range cases {
36 if got := judge(c.p, c.h); got != c.want {
37 t.Fatalf("judge(%v,%v) = %d, want %d", c.p, c.h, got, c.want)
38 }
39 }
40}
41
42func TestBeats(t *testing.T) {
43 if beats(Rock) != Paper {
44 t.Fatal("beats(Rock) should be Paper")
45 }
46 if beats(Paper) != Scissors {
47 t.Fatal("beats(Paper) should be Scissors")
48 }
49 if beats(Scissors) != Rock {
50 t.Fatal("beats(Scissors) should be Rock")
51 }
52}
53
54func TestParseMove(t *testing.T) {
55 for _, s := range []string{"rock", "Rock", " r ", "paper", "P", "scissors", "S"} {
56 if _, ok := parseMove(s); !ok {
57 t.Fatalf("parseMove(%q) should be valid", s)
58 }
59 }
60 if _, ok := parseMove("lizard"); ok {
61 t.Fatal("parseMove(\"lizard\") should be invalid")
62 }
63}
64
65func TestPredictPicksMostFrequent(t *testing.T) {
66 ps := &playerState{}
67 ps.Counts[Paper] = 5
68 ps.Counts[Rock] = 1
69 if got := predict(ps, 0); got != Paper {
70 t.Fatalf("predict = %v, want Paper", got)
71 }
72}
73
74// Crossing: Play mutates realm state, so the test needs `cur realm`.
75func TestOracleCountersPredictableRock(cur realm, t *testing.T) {
76 resetState()
77 alice := testutils.TestAddress("alice")
78 testing.SetRealm(testing.NewUserRealm(alice))
79
80 for i := 0; i < 5; i++ {
81 Play(cross(cur), "rock")
82 }
83 ps := getOrCreate(alice)
84 if ps.Losses == 0 {
85 t.Fatal("expected the oracle to eventually counter an all-rock player")
86 }
87 if ps.Rounds != 5 {
88 t.Fatalf("Rounds = %d, want 5", ps.Rounds)
89 }
90}
91
92// Non-crossing: Render is a plain read.
93func TestRenderHome(t *testing.T) {
94 resetState()
95 out := Render("")
96 if out == "" {
97 t.Fatal("Render(\"\") should not be empty")
98 }
99}