humanize_test.gno
3.17 Kb · 111 lines
1package humanize
2
3import (
4 "strings"
5 "testing"
6
7 "gno.land/p/nt/uassert/v0"
8)
9
10func TestBytes(t *testing.T) {
11 cases := []struct {
12 in int64
13 want string
14 }{
15 {0, "0 B"},
16 {999, "999 B"},
17 {1023, "1023 B"},
18 {1024, "1 KiB"},
19 {1536, "1.5 KiB"},
20 {1048576, "1 MiB"},
21 {1572864, "1.5 MiB"},
22 {1073741824, "1 GiB"},
23 {-1536, "-1.5 KiB"},
24 {-10, "-10 B"},
25 }
26 for _, c := range cases {
27 uassert.Equal(t, c.want, Bytes(c.in))
28 }
29}
30
31func TestComma(t *testing.T) {
32 cases := []struct {
33 in int64
34 want string
35 }{
36 {0, "0"}, {1, "1"}, {999, "999"}, {1000, "1,000"},
37 {1234567, "1,234,567"}, {-1234567, "-1,234,567"},
38 }
39 for _, c := range cases {
40 uassert.Equal(t, c.want, Comma(c.in))
41 }
42}
43
44// The teens are the trap: 11/12/13 take "th" despite ending in 1/2/3.
45func TestOrdinalTeens(t *testing.T) {
46 cases := []struct {
47 in int64
48 want string
49 }{
50 {1, "1st"}, {2, "2nd"}, {3, "3rd"}, {4, "4th"},
51 {11, "11th"}, {12, "12th"}, {13, "13th"},
52 {21, "21st"}, {22, "22nd"}, {23, "23rd"},
53 {111, "111th"}, {112, "112th"}, {113, "113th"},
54 {101, "101st"}, {0, "0th"},
55 }
56 for _, c := range cases {
57 uassert.Equal(t, c.want, Ordinal(c.in))
58 }
59}
60
61func TestPlural(t *testing.T) {
62 uassert.Equal(t, "1 block", Plural(1, "block", ""))
63 uassert.Equal(t, "2 blocks", Plural(2, "block", ""))
64 uassert.Equal(t, "0 blocks", Plural(0, "block", ""))
65 uassert.Equal(t, "2 mice", Plural(2, "mouse", "mice"))
66 uassert.Equal(t, "-1 block", Plural(-1, "block", ""))
67}
68
69func TestBlocks(t *testing.T) {
70 uassert.Equal(t, "now", Blocks(0))
71 uassert.Equal(t, "1 block", Blocks(1))
72 uassert.Equal(t, "9 blocks", Blocks(9))
73 uassert.Equal(t, "~10 blocks", Blocks(15))
74 uassert.Equal(t, "~1,200 blocks", Blocks(1234))
75 uassert.Equal(t, "in the past", Blocks(-5))
76}
77
78// Truncate counts runes, so multi-byte text is never cut mid-character.
79func TestTruncateCountsRunes(t *testing.T) {
80 uassert.Equal(t, "hello", Truncate("hello", 10))
81 uassert.Equal(t, "hell…", Truncate("hello!", 5))
82 uassert.Equal(t, "…", Truncate("hello", 1))
83 uassert.Equal(t, "", Truncate("hello", 0))
84 uassert.Equal(t, "éé", Truncate("éé", 2))
85 uassert.Equal(t, "é…", Truncate("ééé", 2)) // not sliced mid-rune
86}
87
88// TestCommaSurvivesTheInt64Minimum pins the defect v0 shipped. -n on
89// math.MinInt64 is math.MinInt64, so FormatInt emitted its own sign and the
90// neg branch prepended a second: v0 returned
91// "--9,223,372,036,854,775,808". Break the mag split and this goes red.
92func TestCommaSurvivesTheInt64Minimum(t *testing.T) {
93 const minInt64 = -9223372036854775808
94 uassert.Equal(t, "-9,223,372,036,854,775,808", Comma(minInt64))
95 uassert.Equal(t, "9,223,372,036,854,775,807", Comma(9223372036854775807))
96}
97
98// TestCommaNeverDoublesTheSign is the invariant behind it, stated so a future
99// rewrite cannot reintroduce the shape without failing.
100func TestCommaNeverDoublesTheSign(t *testing.T) {
101 const minInt64 = -9223372036854775808
102 for _, n := range []int64{0, 1, -1, 999, -1000, 1234567, -1234567, minInt64} {
103 s := Comma(n)
104 if strings.HasPrefix(s, "--") || strings.Contains(s, "-,") {
105 t.Errorf("Comma(%d) = %q", n, s)
106 }
107 if (n < 0) != strings.HasPrefix(s, "-") {
108 t.Errorf("Comma(%d) = %q, sign disagrees with the input", n, s)
109 }
110 }
111}