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

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

render_test.gno

3.11 Kb · 94 lines
 1package bullscows
 2
 3import (
 4	"strings"
 5	"testing"
 6
 7	"gno.land/p/nt/uassert/v0"
 8)
 9
10// clear restores the globals to their init() state so assertions do not depend
11// on which tests ran first. Realm globals live for the whole test binary.
12func clear() {
13	round = 1
14	attempts = 0
15	history = nil
16	records = nil
17	secret = newSecret(seedFor(round))
18}
19
20// ExampleRender pins the fresh-round view: no guesses, empty leaderboard.
21func ExampleRender() {
22	clear()
23	print(Render(""))
24	// Output:
25	// # Bulls & Cows
26	//
27	// One shared secret 4-digit code (no repeated digits). Call `Guess("1972")` to get **bulls** (right digit, right spot) and **cows** (right digit, wrong spot). First to 4 bulls wins the round; `GiveUp()` reveals the code and starts over.
28	//
29	// ## Round 1
30	//
31	// Attempts so far: **0**
32	//
33	// _No guesses yet this round — be the first._
34	//
35	// ## Leaderboard (fastest solves)
36	//
37	// _Nobody has cracked a code yet._
38}
39
40// TestRenderHistoryNewestFirst checks the guess table is reverse-chronological.
41func TestRenderHistoryNewestFirst(t *testing.T) {
42	clear()
43	addHistory(guessLog{player: "alice", guess: "1234", bulls: 1, cows: 2})
44	addHistory(guessLog{player: "bob", guess: "5678", bulls: 0, cows: 1})
45
46	out := Render("")
47	uassert.True(t, strings.Contains(out, "### Recent guesses"), "history section should appear")
48	uassert.True(t, strings.Contains(out, "| bob | 5678 | 0 | 1 |\n| alice | 1234 | 1 | 2 |\n"),
49		"newest guess should be listed first")
50	uassert.False(t, strings.Contains(out, "_No guesses yet"), "empty-history notice should be gone")
51}
52
53// TestRenderLeaderboard checks solved records render in rank order.
54func TestRenderLeaderboard(t *testing.T) {
55	clear()
56	addRecord(record{player: "carol", attempts: 3, round: 1})
57	addRecord(record{player: "dave", attempts: 7, round: 2})
58
59	out := Render("")
60	uassert.True(t, strings.Contains(out, "| 1 | carol | 3 | 1 |\n| 2 | dave | 7 | 2 |\n"),
61		"leaderboard should rank fastest first")
62	uassert.False(t, strings.Contains(out, "_Nobody has cracked a code yet._"),
63		"empty-leaderboard notice should be gone")
64}
65
66// TestRenderShortensLongAddresses checks the bech32 addresses players actually
67// have get elided rather than blowing out the table.
68func TestRenderShortensLongAddresses(t *testing.T) {
69	clear()
70	long := "g1manfred47kzduec920z88wfr64ylksmdcedlf5"
71	addHistory(guessLog{player: long, guess: "1234", bulls: 0, cows: 0})
72
73	out := Render("")
74	uassert.False(t, strings.Contains(out, long), "full address should not be rendered")
75	uassert.True(t, strings.Contains(out, "| "+long[:6]+"…"+long[len(long)-4:]+" | 1234 |"),
76		"address should be shortened to prefix…suffix")
77}
78
79// TestRenderTracksRoundAndAttempts checks the counters reach the page.
80func TestRenderTracksRoundAndAttempts(t *testing.T) {
81	clear()
82	round = 4
83	attempts = 11
84
85	out := Render("")
86	uassert.True(t, strings.Contains(out, "## Round 4\n"), "round should be shown")
87	uassert.True(t, strings.Contains(out, "Attempts so far: **11**"), "attempts should be shown")
88}
89
90// TestRenderIgnoresPath documents that Render has no sub-routes.
91func TestRenderIgnoresPath(t *testing.T) {
92	clear()
93	uassert.Equal(t, Render(""), Render("/anything"))
94}