Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

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}