1package humanize23import (4 "strings"5 "testing"67 "gno.land/p/nt/uassert/v0"8)910func TestBytes(t *testing.T) {11 cases := []struct {12 in int6413 want string14 }{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}3031func TestComma(t *testing.T) {32 cases := []struct {33 in int6434 want string35 }{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}4344// 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 int6448 want string49 }{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}6061func 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}6869func 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}7778// 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-rune86}8788// TestCommaSurvivesTheInt64Minimum pins the defect v0 shipped. -n on89// math.MinInt64 is math.MinInt64, so FormatInt emitted its own sign and the90// neg branch prepended a second: v0 returned91// "--9,223,372,036,854,775,808". Break the mag split and this goes red.92func TestCommaSurvivesTheInt64Minimum(t *testing.T) {93 const minInt64 = -922337203685477580894 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}9798// TestCommaNeverDoublesTheSign is the invariant behind it, stated so a future99// rewrite cannot reintroduce the shape without failing.100func TestCommaNeverDoublesTheSign(t *testing.T) {101 const minInt64 = -9223372036854775808102 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}112Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.