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

connect4_test.gno

3.35 Kb Β· 130 lines
  1package connect4
  2
  3import (
  4	"strings"
  5	"testing"
  6
  7	"gno.land/p/moul/kit/store/v0"
  8	"gno.land/p/nt/testutils/v0"
  9	"gno.land/p/nt/uassert/v0"
 10)
 11
 12var (
 13	alice = testutils.TestAddress("alice") // πŸ”΄
 14	bob   = testutils.TestAddress("bob")   // 🟑
 15	carol = testutils.TestAddress("carol")
 16)
 17
 18func resetState() {
 19	games = store.Named("game")
 20}
 21
 22// TestVerticalWin plays πŸ”΄ stacking column 0 four high while 🟑 plays column 1.
 23func TestVerticalWin(cur realm, t *testing.T) {
 24	resetState()
 25
 26	testing.SetRealm(testing.NewUserRealm(alice))
 27	id := NewGame(cross(cur), bob)
 28	uassert.Equal(t, int64(1), id)
 29
 30	for i := 0; i < 3; i++ {
 31		testing.SetRealm(testing.NewUserRealm(alice))
 32		Drop(cross(cur), id,0)
 33		testing.SetRealm(testing.NewUserRealm(bob))
 34		Drop(cross(cur), id,1)
 35	}
 36	// alice's 4th disc in column 0 -> vertical win
 37	testing.SetRealm(testing.NewUserRealm(alice))
 38	Drop(cross(cur), id,0)
 39
 40	g, err := getGame(id)
 41	uassert.NoError(t, err)
 42	uassert.True(t, g.Finished)
 43	uassert.Equal(t, red, g.Winner)
 44
 45	out := Render("1")
 46	uassert.True(t, strings.Contains(out, "πŸ”΄ Red wins!"))
 47}
 48
 49// TestTurnOrderAndErrors covers turn enforcement, non-player, full-column and range checks.
 50func TestTurnOrderAndErrors(cur realm, t *testing.T) {
 51	resetState()
 52
 53	testing.SetRealm(testing.NewUserRealm(alice))
 54	id := NewGame(cross(cur), bob)
 55
 56	// bob cannot move first (red starts)
 57	testing.SetRealm(testing.NewUserRealm(bob))
 58	uassert.AbortsWithMessage(t, cur,"not your turn", func() {
 59		Drop(cross(cur), id,0)
 60	})
 61
 62	// stranger cannot play
 63	testing.SetRealm(testing.NewUserRealm(carol))
 64	uassert.AbortsWithMessage(t, cur,"caller is not a player in this game", func() {
 65		Drop(cross(cur), id,0)
 66	})
 67
 68	// out-of-range column
 69	testing.SetRealm(testing.NewUserRealm(alice))
 70	uassert.AbortsWithMessage(t, cur,"column out of range (0-6)", func() {
 71		Drop(cross(cur), id,7)
 72	})
 73
 74	// fill column 3: alice & bob alternate, 6 discs total
 75	col := 3
 76	for i := 0; i < 3; i++ {
 77		testing.SetRealm(testing.NewUserRealm(alice))
 78		Drop(cross(cur), id,col)
 79		testing.SetRealm(testing.NewUserRealm(bob))
 80		Drop(cross(cur), id,col)
 81	}
 82	// column now full; whoever is on turn overflows it
 83	g, _ := getGame(id)
 84	var mover address
 85	if g.Turn == red {
 86		mover = alice
 87	} else {
 88		mover = bob
 89	}
 90	testing.SetRealm(testing.NewUserRealm(mover))
 91	uassert.AbortsWithMessage(t, cur,"column is full", func() {
 92		Drop(cross(cur), id,col)
 93	})
 94}
 95
 96// TestHorizontalWin: πŸ”΄ across columns 0-3 on the bottom row.
 97func TestHorizontalWin(cur realm, t *testing.T) {
 98	resetState()
 99
100	testing.SetRealm(testing.NewUserRealm(alice))
101	id := NewGame(cross(cur), bob)
102
103	// alice drops cols 0,1,2 ; bob answers on row above (col 0,1,2)
104	for c := 0; c < 3; c++ {
105		testing.SetRealm(testing.NewUserRealm(alice))
106		Drop(cross(cur), id,c)
107		testing.SetRealm(testing.NewUserRealm(bob))
108		Drop(cross(cur), id,c)
109	}
110	// alice completes col 3 on bottom row -> 0,1,2,3 horizontal
111	testing.SetRealm(testing.NewUserRealm(alice))
112	Drop(cross(cur), id,3)
113
114	g, err := getGame(id)
115	uassert.NoError(t, err)
116	uassert.True(t, g.Finished)
117	uassert.Equal(t, red, g.Winner)
118}
119
120// TestRenderList checks the listing view renders created games.
121func TestRenderList(cur realm, t *testing.T) {
122	resetState()
123
124	testing.SetRealm(testing.NewUserRealm(alice))
125	NewGame(cross(cur), bob)
126
127	out := Render("")
128	uassert.True(t, strings.Contains(out, "Connect Four"))
129	uassert.True(t, strings.Contains(out, "to move"))
130}