git-lfs/tools/humanize/humanize_test.go

281 lines
13 KiB
Go

package humanize_test
import (
"math"
"testing"
"time"
"github.com/git-lfs/git-lfs/tools/humanize"
"github.com/stretchr/testify/assert"
)
type ParseBytesTestCase struct {
Given string
Expected uint64
Err error
}
func (c *ParseBytesTestCase) Assert(t *testing.T) {
got, err := humanize.ParseBytes(c.Given)
if c.Err == nil {
assert.NoError(t, err, "unexpected error: %s", err)
assert.EqualValues(t, c.Expected, got)
} else {
assert.Equal(t, c.Err, err)
}
}
type FormatBytesTestCase struct {
Given uint64
Expected string
}
func (c *FormatBytesTestCase) Assert(t *testing.T) {
assert.Equal(t, c.Expected, humanize.FormatBytes(c.Given))
}
type ParseByteUnitTestCase struct {
Given string
Expected uint64
Err string
}
func (c *ParseByteUnitTestCase) Assert(t *testing.T) {
got, err := humanize.ParseByteUnit(c.Given)
if len(c.Err) == 0 {
assert.NoError(t, err, "unexpected error: %s", err)
assert.EqualValues(t, c.Expected, got)
} else {
assert.EqualError(t, err, c.Err)
}
}
type FormatBytesUnitTestCase struct {
Given uint64
Unit uint64
Expected string
}
func (c *FormatBytesUnitTestCase) Assert(t *testing.T) {
assert.Equal(t, c.Expected, humanize.FormatBytesUnit(c.Given, c.Unit))
}
type FormatByteRateTestCase struct {
Given uint64
Over time.Duration
Expected string
}
func (c *FormatByteRateTestCase) Assert(t *testing.T) {
assert.Equal(t, c.Expected, humanize.FormatByteRate(c.Given, c.Over))
}
func TestParseBytes(t *testing.T) {
for desc, c := range map[string]*ParseBytesTestCase{
"parse byte (zero, empty)": {"", uint64(0), nil},
"parse byte (empty)": {"10", uint64(10 * math.Pow(2, 0)), nil},
"parse byte": {"10B", uint64(10 * math.Pow(2, 0)), nil},
"parse kibibyte": {"20KIB", uint64(20 * math.Pow(2, 10)), nil},
"parse mebibyte": {"30MIB", uint64(30 * math.Pow(2, 20)), nil},
"parse gibibyte": {"40GIB", uint64(40 * math.Pow(2, 30)), nil},
"parse tebibyte": {"50TIB", uint64(50 * math.Pow(2, 40)), nil},
"parse pebibyte": {"60PIB", uint64(60 * math.Pow(2, 50)), nil},
"parse byte (lowercase)": {"10b", uint64(10 * math.Pow(2, 0)), nil},
"parse kibibyte (lowercase)": {"20kib", uint64(20 * math.Pow(2, 10)), nil},
"parse mebibyte (lowercase)": {"30mib", uint64(30 * math.Pow(2, 20)), nil},
"parse gibibyte (lowercase)": {"40gib", uint64(40 * math.Pow(2, 30)), nil},
"parse tebibyte (lowercase)": {"50tib", uint64(50 * math.Pow(2, 40)), nil},
"parse pebibyte (lowercase)": {"60pib", uint64(60 * math.Pow(2, 50)), nil},
"parse byte (with space)": {"10 B", uint64(10 * math.Pow(2, 0)), nil},
"parse kibibyte (with space)": {"20 KIB", uint64(20 * math.Pow(2, 10)), nil},
"parse mebibyte (with space)": {"30 MIB", uint64(30 * math.Pow(2, 20)), nil},
"parse gibibyte (with space)": {"40 GIB", uint64(40 * math.Pow(2, 30)), nil},
"parse tebibyte (with space)": {"50 TIB", uint64(50 * math.Pow(2, 40)), nil},
"parse pebibyte (with space)": {"60 PIB", uint64(60 * math.Pow(2, 50)), nil},
"parse byte (with space, lowercase)": {"10 b", uint64(10 * math.Pow(2, 0)), nil},
"parse kibibyte (with space, lowercase)": {"20 kib", uint64(20 * math.Pow(2, 10)), nil},
"parse mebibyte (with space, lowercase)": {"30 mib", uint64(30 * math.Pow(2, 20)), nil},
"parse gibibyte (with space, lowercase)": {"40 gib", uint64(40 * math.Pow(2, 30)), nil},
"parse tebibyte (with space, lowercase)": {"50 tib", uint64(50 * math.Pow(2, 40)), nil},
"parse pebibyte (with space, lowercase)": {"60 pib", uint64(60 * math.Pow(2, 50)), nil},
"parse kilobyte": {"20KB", uint64(20 * math.Pow(10, 3)), nil},
"parse megabyte": {"30MB", uint64(30 * math.Pow(10, 6)), nil},
"parse gigabyte": {"40GB", uint64(40 * math.Pow(10, 9)), nil},
"parse terabyte": {"50TB", uint64(50 * math.Pow(10, 12)), nil},
"parse petabyte": {"60PB", uint64(60 * math.Pow(10, 15)), nil},
"parse kilobyte (lowercase)": {"20kb", uint64(20 * math.Pow(10, 3)), nil},
"parse megabyte (lowercase)": {"30mb", uint64(30 * math.Pow(10, 6)), nil},
"parse gigabyte (lowercase)": {"40gb", uint64(40 * math.Pow(10, 9)), nil},
"parse terabyte (lowercase)": {"50tb", uint64(50 * math.Pow(10, 12)), nil},
"parse petabyte (lowercase)": {"60pb", uint64(60 * math.Pow(10, 15)), nil},
"parse kilobyte (with space)": {"20 KB", uint64(20 * math.Pow(10, 3)), nil},
"parse megabyte (with space)": {"30 MB", uint64(30 * math.Pow(10, 6)), nil},
"parse gigabyte (with space)": {"40 GB", uint64(40 * math.Pow(10, 9)), nil},
"parse terabyte (with space)": {"50 TB", uint64(50 * math.Pow(10, 12)), nil},
"parse petabyte (with space)": {"60 PB", uint64(60 * math.Pow(10, 15)), nil},
"parse kilobyte (with space, lowercase)": {"20 kb", uint64(20 * math.Pow(10, 3)), nil},
"parse megabyte (with space, lowercase)": {"30 mb", uint64(30 * math.Pow(10, 6)), nil},
"parse gigabyte (with space, lowercase)": {"40 gb", uint64(40 * math.Pow(10, 9)), nil},
"parse terabyte (with space, lowercase)": {"50 tb", uint64(50 * math.Pow(10, 12)), nil},
"parse petabyte (with space, lowercase)": {"60 pb", uint64(60 * math.Pow(10, 15)), nil},
} {
t.Run(desc, c.Assert)
}
}
func TestFormatBytes(t *testing.T) {
for desc, c := range map[string]*FormatBytesTestCase{
"format bytes": {uint64(1 * math.Pow(10, 0)), "1 B"},
"format kilobytes": {uint64(1 * math.Pow(10, 3)), "1.0 KB"},
"format megabytes": {uint64(1 * math.Pow(10, 6)), "1.0 MB"},
"format gigabytes": {uint64(1 * math.Pow(10, 9)), "1.0 GB"},
"format petabytes": {uint64(1 * math.Pow(10, 12)), "1.0 TB"},
"format terabytes": {uint64(1 * math.Pow(10, 15)), "1.0 PB"},
"format kilobytes under": {uint64(1.49 * math.Pow(10, 3)), "1.5 KB"},
"format megabytes under": {uint64(1.49 * math.Pow(10, 6)), "1.5 MB"},
"format gigabytes under": {uint64(1.49 * math.Pow(10, 9)), "1.5 GB"},
"format petabytes under": {uint64(1.49 * math.Pow(10, 12)), "1.5 TB"},
"format terabytes under": {uint64(1.49 * math.Pow(10, 15)), "1.5 PB"},
"format kilobytes over": {uint64(1.51 * math.Pow(10, 3)), "1.5 KB"},
"format megabytes over": {uint64(1.51 * math.Pow(10, 6)), "1.5 MB"},
"format gigabytes over": {uint64(1.51 * math.Pow(10, 9)), "1.5 GB"},
"format petabytes over": {uint64(1.51 * math.Pow(10, 12)), "1.5 TB"},
"format terabytes over": {uint64(1.51 * math.Pow(10, 15)), "1.5 PB"},
"format kilobytes exact": {uint64(1.3 * math.Pow(10, 3)), "1.3 KB"},
"format megabytes exact": {uint64(1.3 * math.Pow(10, 6)), "1.3 MB"},
"format gigabytes exact": {uint64(1.3 * math.Pow(10, 9)), "1.3 GB"},
"format petabytes exact": {uint64(1.3 * math.Pow(10, 12)), "1.3 TB"},
"format terabytes exact": {uint64(1.3 * math.Pow(10, 15)), "1.3 PB"},
} {
t.Run(desc, c.Assert)
}
}
func TestParseByteUnit(t *testing.T) {
for desc, c := range map[string]*ParseByteUnitTestCase{
"parse byte": {"B", uint64(math.Pow(2, 0)), ""},
"parse kibibyte": {"KIB", uint64(math.Pow(2, 10)), ""},
"parse mebibyte": {"MIB", uint64(math.Pow(2, 20)), ""},
"parse gibibyte": {"GIB", uint64(math.Pow(2, 30)), ""},
"parse tebibyte": {"TIB", uint64(math.Pow(2, 40)), ""},
"parse pebibyte": {"PIB", uint64(math.Pow(2, 50)), ""},
"parse byte (lowercase)": {"b", uint64(math.Pow(2, 0)), ""},
"parse kibibyte (lowercase)": {"kib", uint64(math.Pow(2, 10)), ""},
"parse mebibyte (lowercase)": {"mib", uint64(math.Pow(2, 20)), ""},
"parse gibibyte (lowercase)": {"gib", uint64(math.Pow(2, 30)), ""},
"parse tebibyte (lowercase)": {"tib", uint64(math.Pow(2, 40)), ""},
"parse pebibyte (lowercase)": {"pib", uint64(math.Pow(2, 50)), ""},
"parse byte (with space)": {" B", uint64(math.Pow(2, 0)), ""},
"parse kibibyte (with space)": {" KIB", uint64(math.Pow(2, 10)), ""},
"parse mebibyte (with space)": {" MIB", uint64(math.Pow(2, 20)), ""},
"parse gibibyte (with space)": {" GIB", uint64(math.Pow(2, 30)), ""},
"parse tebibyte (with space)": {" TIB", uint64(math.Pow(2, 40)), ""},
"parse pebibyte (with space)": {" PIB", uint64(math.Pow(2, 50)), ""},
"parse byte (with space, lowercase)": {" b", uint64(math.Pow(2, 0)), ""},
"parse kibibyte (with space, lowercase)": {" kib", uint64(math.Pow(2, 10)), ""},
"parse mebibyte (with space, lowercase)": {" mib", uint64(math.Pow(2, 20)), ""},
"parse gibibyte (with space, lowercase)": {" gib", uint64(math.Pow(2, 30)), ""},
"parse tebibyte (with space, lowercase)": {" tib", uint64(math.Pow(2, 40)), ""},
"parse pebibyte (with space, lowercase)": {" pib", uint64(math.Pow(2, 50)), ""},
"parse kilobyte": {"KB", uint64(math.Pow(10, 3)), ""},
"parse megabyte": {"MB", uint64(math.Pow(10, 6)), ""},
"parse gigabyte": {"GB", uint64(math.Pow(10, 9)), ""},
"parse terabyte": {"TB", uint64(math.Pow(10, 12)), ""},
"parse petabyte": {"PB", uint64(math.Pow(10, 15)), ""},
"parse kilobyte (lowercase)": {"kb", uint64(math.Pow(10, 3)), ""},
"parse megabyte (lowercase)": {"mb", uint64(math.Pow(10, 6)), ""},
"parse gigabyte (lowercase)": {"gb", uint64(math.Pow(10, 9)), ""},
"parse terabyte (lowercase)": {"tb", uint64(math.Pow(10, 12)), ""},
"parse petabyte (lowercase)": {"pb", uint64(math.Pow(10, 15)), ""},
"parse kilobyte (with space)": {" KB", uint64(math.Pow(10, 3)), ""},
"parse megabyte (with space)": {" MB", uint64(math.Pow(10, 6)), ""},
"parse gigabyte (with space)": {" GB", uint64(math.Pow(10, 9)), ""},
"parse terabyte (with space)": {" TB", uint64(math.Pow(10, 12)), ""},
"parse petabyte (with space)": {" PB", uint64(math.Pow(10, 15)), ""},
"parse kilobyte (with space, lowercase)": {"kb", uint64(math.Pow(10, 3)), ""},
"parse megabyte (with space, lowercase)": {"mb", uint64(math.Pow(10, 6)), ""},
"parse gigabyte (with space, lowercase)": {"gb", uint64(math.Pow(10, 9)), ""},
"parse terabyte (with space, lowercase)": {"tb", uint64(math.Pow(10, 12)), ""},
"parse petabyte (with space, lowercase)": {"pb", uint64(math.Pow(10, 15)), ""},
"parse unknown unit": {"imag", 0, "unknown unit: \"imag\""},
} {
t.Run(desc, c.Assert)
}
}
func TestFormatBytesUnit(t *testing.T) {
for desc, c := range map[string]*FormatBytesUnitTestCase{
"format bytes": {uint64(1 * math.Pow(10, 0)), humanize.Byte, "1"},
"format kilobytes": {uint64(1 * math.Pow(10, 3)), humanize.Byte, "1000"},
"format megabytes": {uint64(1 * math.Pow(10, 6)), humanize.Byte, "1000000"},
"format gigabytes": {uint64(1 * math.Pow(10, 9)), humanize.Byte, "1000000000"},
"format petabytes": {uint64(1 * math.Pow(10, 12)), humanize.Byte, "1000000000000"},
"format terabytes": {uint64(1 * math.Pow(10, 15)), humanize.Byte, "1000000000000000"},
"format kilobytes under": {uint64(1.49 * math.Pow(10, 3)), humanize.Byte, "1490"},
"format megabytes under": {uint64(1.49 * math.Pow(10, 6)), humanize.Byte, "1490000"},
"format gigabytes under": {uint64(1.49 * math.Pow(10, 9)), humanize.Byte, "1490000000"},
"format petabytes under": {uint64(1.49 * math.Pow(10, 12)), humanize.Byte, "1490000000000"},
"format terabytes under": {uint64(1.49 * math.Pow(10, 15)), humanize.Byte, "1490000000000000"},
"format kilobytes over": {uint64(1.51 * math.Pow(10, 3)), humanize.Byte, "1510"},
"format megabytes over": {uint64(1.51 * math.Pow(10, 6)), humanize.Byte, "1510000"},
"format gigabytes over": {uint64(1.51 * math.Pow(10, 9)), humanize.Byte, "1510000000"},
"format petabytes over": {uint64(1.51 * math.Pow(10, 12)), humanize.Byte, "1510000000000"},
"format terabytes over": {uint64(1.51 * math.Pow(10, 15)), humanize.Byte, "1510000000000000"},
} {
t.Run(desc, c.Assert)
}
}
func TestFormateByteRate(t *testing.T) {
for desc, c := range map[string]*FormatByteRateTestCase{
"format bytes": {uint64(1 * math.Pow(10, 0)), time.Second, "1 B/s"},
"format kilobytes": {uint64(1 * math.Pow(10, 3)), time.Second, "1.0 KB/s"},
"format megabytes": {uint64(1 * math.Pow(10, 6)), time.Second, "1.0 MB/s"},
"format gigabytes": {uint64(1 * math.Pow(10, 9)), time.Second, "1.0 GB/s"},
"format petabytes": {uint64(1 * math.Pow(10, 12)), time.Second, "1.0 TB/s"},
"format terabytes": {uint64(1 * math.Pow(10, 15)), time.Second, "1.0 PB/s"},
"format kilobytes under": {uint64(1.49 * math.Pow(10, 3)), time.Second, "1.5 KB/s"},
"format megabytes under": {uint64(1.49 * math.Pow(10, 6)), time.Second, "1.5 MB/s"},
"format gigabytes under": {uint64(1.49 * math.Pow(10, 9)), time.Second, "1.5 GB/s"},
"format petabytes under": {uint64(1.49 * math.Pow(10, 12)), time.Second, "1.5 TB/s"},
"format terabytes under": {uint64(1.49 * math.Pow(10, 15)), time.Second, "1.5 PB/s"},
"format kilobytes over": {uint64(1.51 * math.Pow(10, 3)), time.Second, "1.5 KB/s"},
"format megabytes over": {uint64(1.51 * math.Pow(10, 6)), time.Second, "1.5 MB/s"},
"format gigabytes over": {uint64(1.51 * math.Pow(10, 9)), time.Second, "1.5 GB/s"},
"format petabytes over": {uint64(1.51 * math.Pow(10, 12)), time.Second, "1.5 TB/s"},
"format terabytes over": {uint64(1.51 * math.Pow(10, 15)), time.Second, "1.5 PB/s"},
"format kilobytes exact": {uint64(1.3 * math.Pow(10, 3)), time.Second, "1.3 KB/s"},
"format megabytes exact": {uint64(1.3 * math.Pow(10, 6)), time.Second, "1.3 MB/s"},
"format gigabytes exact": {uint64(1.3 * math.Pow(10, 9)), time.Second, "1.3 GB/s"},
"format petabytes exact": {uint64(1.3 * math.Pow(10, 12)), time.Second, "1.3 TB/s"},
"format terabytes exact": {uint64(1.3 * math.Pow(10, 15)), time.Second, "1.3 PB/s"},
"format bytes (non-second)": {uint64(10 * math.Pow(10, 0)), 2 * time.Second, "5 B/s"},
} {
t.Run(desc, c.Assert)
}
}