Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

tictactoe_test.gno

3.08 Kb · 112 lines
  1package tictactoe
  2
  3import (
  4	"testing"
  5
  6	"gno.land/p/nt/testutils/v0"
  7	"gno.land/p/nt/uassert/v0"
  8)
  9
 10var (
 11	alice = testutils.TestAddress("alice")
 12	bob   = testutils.TestAddress("bob")
 13	carol = testutils.TestAddress("carol")
 14)
 15
 16// TestXWins: alice (X) beats bob (O) on the top row.
 17func TestXWins(cur realm, t *testing.T) {
 18	testing.SetRealm(testing.NewUserRealm(alice))
 19	id := NewGame(cross(cur), bob)
 20	uassert.True(t, id >= 1, "expected a game id")
 21
 22	// alice X -> 0
 23	testing.SetRealm(testing.NewUserRealm(alice))
 24	Move(cross(cur), id, 0)
 25	// bob O -> 3
 26	testing.SetRealm(testing.NewUserRealm(bob))
 27	Move(cross(cur), id, 3)
 28	// alice X -> 1
 29	testing.SetRealm(testing.NewUserRealm(alice))
 30	Move(cross(cur), id, 1)
 31	// bob O -> 4
 32	testing.SetRealm(testing.NewUserRealm(bob))
 33	Move(cross(cur), id, 4)
 34	// alice X -> 2 wins top row
 35	testing.SetRealm(testing.NewUserRealm(alice))
 36	Move(cross(cur), id, 2)
 37
 38	g, err := GetGame(id)
 39	uassert.NoError(t, err)
 40	uassert.True(t, g.finished, "game should be finished")
 41	uassert.Equal(t, markX, g.winner)
 42	uassert.False(t, g.draw, "should not be a draw")
 43}
 44
 45// TestTurnAndTakenGuards: rejects out-of-turn moves, taken cells, and non-players.
 46func TestTurnAndTakenGuards(cur realm, t *testing.T) {
 47	testing.SetRealm(testing.NewUserRealm(alice))
 48	id := NewGame(cross(cur), bob)
 49
 50	// bob (O) cannot move first — it's X's turn.
 51	testing.SetRealm(testing.NewUserRealm(bob))
 52	uassert.AbortsWithMessage(t, cur, "not your turn", func() {
 53		Move(cross(cur), id, 0)
 54	})
 55
 56	// alice (X) plays 0.
 57	testing.SetRealm(testing.NewUserRealm(alice))
 58	Move(cross(cur), id, 0)
 59
 60	// alice cannot play twice in a row.
 61	testing.SetRealm(testing.NewUserRealm(alice))
 62	uassert.AbortsWithMessage(t, cur, "not your turn", func() {
 63		Move(cross(cur), id, 1)
 64	})
 65
 66	// bob cannot take an occupied cell.
 67	testing.SetRealm(testing.NewUserRealm(bob))
 68	uassert.AbortsWithMessage(t, cur, "cell already taken", func() {
 69		Move(cross(cur), id, 0)
 70	})
 71
 72	// carol is not a player.
 73	testing.SetRealm(testing.NewUserRealm(carol))
 74	uassert.AbortsWithMessage(t, cur, "caller is not a player in this game", func() {
 75		Move(cross(cur), id, 5)
 76	})
 77}
 78
 79// TestDraw: fill the board with no winner.
 80func TestDraw(cur realm, t *testing.T) {
 81	testing.SetRealm(testing.NewUserRealm(alice))
 82	id := NewGame(cross(cur), bob)
 83
 84	// Sequence yielding a full board with no three-in-a-row:
 85	// X:0 O:1 X:2 O:4 X:3 O:5 X:7 O:6 X:8
 86	seq := []struct {
 87		who  address
 88		cell int
 89	}{
 90		{alice, 0}, {bob, 1}, {alice, 2},
 91		{bob, 4}, {alice, 3}, {bob, 5},
 92		{alice, 7}, {bob, 6}, {alice, 8},
 93	}
 94	for _, s := range seq {
 95		testing.SetRealm(testing.NewUserRealm(s.who))
 96		Move(cross(cur), id, s.cell)
 97	}
 98
 99	g, err := GetGame(id)
100	uassert.NoError(t, err)
101	uassert.True(t, g.finished, "game should be finished")
102	uassert.True(t, g.draw, "should be a draw")
103	uassert.Equal(t, 0, g.winner)
104}
105
106// The store's labelled MustGet names the game v0's "game not found" left out.
107func TestMoveOnAMissingGameNamesIt(cur realm, t *testing.T) {
108	testing.SetRealm(testing.NewUserRealm(alice))
109	uassert.AbortsWithMessage(t, cur, "game #999999 not found", func() {
110		Move(cross(cur), 999999, 0)
111	})
112}