collatz_test.gno
2.14 Kb · 73 lines
1package collatz
2
3import (
4 "strings"
5 "testing"
6
7 "gno.land/p/nt/testutils/v0"
8 "gno.land/p/nt/uassert/v0"
9)
10
11func TestStopping(t *testing.T) {
12 cases := []struct {
13 n int64
14 steps int
15 peak int64
16 }{
17 {1, 0, 1},
18 {2, 1, 2},
19 {6, 8, 16},
20 {7, 16, 52},
21 {27, 111, 9232},
22 }
23 for _, c := range cases {
24 steps, peak, _ := stopping(c.n)
25 uassert.Equal(t, c.steps, steps)
26 uassert.Equal(t, c.peak, peak)
27 }
28}
29
30func TestComputeAndLeaderboard(cur realm, t *testing.T) {
31 addr := testutils.TestAddress("alice")
32 testing.SetRealm(testing.NewUserRealm(addr))
33
34 Compute(cross(cur), 27)
35 Compute(cross(cur), 6)
36
37 out := Render("")
38 uassert.True(t, strings.Contains(out, "Leaderboard"), "has leaderboard")
39 uassert.True(t, strings.Contains(out, "9232"), "shows peak of 27")
40 // 27 has more steps than 6, so it must appear first (rank 1).
41 i27 := strings.Index(out, "[27]")
42 i6 := strings.Index(out, "[6]")
43 uassert.True(t, i27 >= 0 && i6 >= 0, "both rows present")
44 uassert.True(t, i27 < i6, "27 ranked above 6")
45}
46
47func TestComputeRejectsNonPositive(cur realm, t *testing.T) {
48 addr := testutils.TestAddress("bob")
49 testing.SetRealm(testing.NewUserRealm(addr))
50 uassert.AbortsWithMessage(t, cur, "n must be > 0", func() {
51 Compute(cross(cur), 0)
52 })
53}
54
55func TestRenderSequence(t *testing.T) {
56 out := Render("/6")
57 uassert.True(t, strings.Contains(out, "6 → 3 → 10 → 5 → 16 → 8 → 4 → 2 → 1"), "full seq for 6")
58 uassert.True(t, strings.Contains(out, "steps: 8"), "reports 8 steps")
59
60 bad := Render("/abc")
61 uassert.True(t, strings.Contains(bad, "Invalid"), "rejects non-numeric path")
62}
63
64// 3n+1 for this n is exactly 2^64, which wraps to 0. Recording it would put a
65// million-step walk on 0 at the top of the leaderboard, forever.
66func TestComputeRefusesAnOverflowingWalk(cur realm, t *testing.T) {
67 uassert.AbortsContains(t, cur, "overflows int64", func() { Compute(cross(cur), 6148914691236517205) })
68 _, _, ok := stopping(27)
69 uassert.True(t, ok, "an ordinary walk is unaffected")
70 out := Render("/6148914691236517205")
71 uassert.True(t, strings.Contains(out, "would overflow int64"), out)
72 uassert.False(t, strings.Contains(out, "→ 0"), "no wrapped term rendered")
73}