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.

quizstreak_test.gno

3.39 Kb · 130 lines
  1package quizstreak
  2
  3import (
  4	"strings"
  5	"testing"
  6
  7	"gno.land/p/nt/avl/v0"
  8	"gno.land/p/nt/testutils/v0"
  9)
 10
 11// resetGame re-initializes package globals so each test starts clean.
 12func resetGame() {
 13	players = avl.NewTree()
 14}
 15
 16func TestStartIndexDeterministicAndInRange(t *testing.T) {
 17	n := len(questions)
 18	for _, tc := range []struct {
 19		addr   string
 20		height int64
 21	}{
 22		{"g1aaaa", 0},
 23		{"g1bbbb", 42},
 24		{"g1cccc", -7},
 25	} {
 26		idx := startIndex(tc.addr, tc.height)
 27		if idx < 0 || idx >= n {
 28			t.Errorf("startIndex(%q, %d) = %d, want in 0..%d", tc.addr, tc.height, idx, n-1)
 29		}
 30		if again := startIndex(tc.addr, tc.height); again != idx {
 31			t.Errorf("startIndex(%q, %d) non-deterministic: %d != %d", tc.addr, tc.height, again, idx)
 32		}
 33	}
 34}
 35
 36func TestNextIndexWrapsAround(t *testing.T) {
 37	n := 5
 38	if got := nextIndex(4, 0, n); got != 0 {
 39		t.Errorf("nextIndex(4, 0, 5) = %d, want 0", got)
 40	}
 41	if got := nextIndex(2, 3, n); got != 1 {
 42		t.Errorf("nextIndex(2, 3, 5) = %d, want 1", got)
 43	}
 44}
 45
 46// TestAnswerCorrectAndWrong exercises the crossing Answer function, so it
 47// takes cur realm and calls through cross(cur).
 48func TestAnswerCorrectAndWrong(cur realm, t *testing.T) {
 49	resetGame()
 50
 51	alice := testutils.TestAddress("alice")
 52	testing.SetRealm(testing.NewUserRealm(alice))
 53
 54	addr := alice.String()
 55	p := getPlayer(addr)
 56	q := questions[p.qIdx]
 57
 58	// wrong answer first: pick any index that isn't correct
 59	wrong := (q.correctIdx + 1) % len(q.choices)
 60	got := Answer(cross(cur), wrong)
 61	if !strings.HasPrefix(got, "Wrong") {
 62		t.Errorf("Answer(wrong) = %q, want it to start with Wrong", got)
 63	}
 64	if p.streak != 0 {
 65		t.Errorf("streak after wrong answer = %d, want 0", p.streak)
 66	}
 67	if p.qIdx != questionIndexOf(q) {
 68		t.Errorf("question changed after a wrong answer, want it to stay the same")
 69	}
 70
 71	got = Answer(cross(cur), q.correctIdx)
 72	if !strings.HasPrefix(got, "Correct!") {
 73		t.Errorf("Answer(correct) = %q, want it to start with Correct!", got)
 74	}
 75	if p.streak != 1 {
 76		t.Errorf("streak after correct answer = %d, want 1", p.streak)
 77	}
 78	if p.best != 1 {
 79		t.Errorf("best after first correct answer = %d, want 1", p.best)
 80	}
 81	if p.correct != 1 || p.wrong != 1 {
 82		t.Errorf("correct/wrong = %d/%d, want 1/1", p.correct, p.wrong)
 83	}
 84	if len(leaderboard()) != 1 {
 85		t.Errorf("leaderboard len = %d, want 1", len(leaderboard()))
 86	}
 87}
 88
 89// questionIndexOf is a small test helper to find a question's index.
 90func questionIndexOf(q question) int {
 91	for i, cand := range questions {
 92		if cand.text == q.text {
 93			return i
 94		}
 95	}
 96	return -1
 97}
 98
 99func TestRenderShowsRulesAndLeaderboard(t *testing.T) {
100	resetGame()
101	out := Render("")
102	for _, want := range []string{"Quiz Streak", "leaderboard", "How to play"} {
103		if !strings.Contains(strings.ToLower(out), strings.ToLower(want)) {
104			t.Errorf("Render(\"\") missing %q", want)
105		}
106	}
107	if !strings.Contains(out, "No one has played yet") {
108		t.Errorf("Render(\"\") should note an empty leaderboard")
109	}
110}
111
112func TestRenderShowsPlayerDashboard(cur realm, t *testing.T) {
113	resetGame()
114
115	bob := testutils.TestAddress("bob")
116	testing.SetRealm(testing.NewUserRealm(bob))
117	addr := bob.String()
118
119	p := getPlayer(addr)
120	q := questions[p.qIdx]
121	Answer(cross(cur), q.correctIdx)
122
123	out := Render(addr)
124	if !strings.Contains(out, "Your question") {
125		t.Errorf("Render(addr) missing player dashboard section")
126	}
127	if !strings.Contains(out, "Current streak: 1") {
128		t.Errorf("Render(addr) missing updated streak, got:\n%s", out)
129	}
130}