1package eightball23import (4 "testing"56 "gno.land/p/nt/uassert/v0"7)89func TestAnswerIndexInRange(t *testing.T) {10 cases := []struct {11 height int6412 n int13 }{14 {0, 0}, {1, 0}, {19, 0}, {20, 0}, {21, 5},15 {999999, 3}, {-1, 0}, {-1000, 7},16 }17 for _, c := range cases {18 idx := answerIndex(c.height, c.n)19 uassert.True(t, idx >= 0 && idx < len(answers),20 "index out of range for height="+itoa(c.height))21 }22}2324func TestAnswerIndexDeterministic(t *testing.T) {25 uassert.Equal(t, answerIndex(42, 3), answerIndex(42, 3), "same inputs, same slot")26}2728func TestRenderEmpty(t *testing.T) {29 out := Render("")30 uassert.NotEmpty(t, out, "render must not be empty")31 uassert.True(t, len(answers) == 20, "classic 8-ball has 20 answers")32}3334func itoa(n int64) string {35 neg := n < 036 if neg {37 n = -n38 }39 if n == 0 {40 return "0"41 }42 var b [24]byte43 i := len(b)44 for n > 0 {45 i--46 b[i] = byte('0' + n%10)47 n /= 1048 }49 if neg {50 i--51 b[i] = '-'52 }53 return string(b[i:])54}55Ask(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, question string) string
Asked() int
Render(path string) string
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.