From 8d9d4c98439bdfbfccaba28357944b6d866867bf Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" <lukeshu@lukeshu.com> Date: Mon, 19 Feb 2024 14:46:33 -0700 Subject: textui: Fix Metric() and IEC(), add tests, accept math/big values --- lib/textui/text_test.go | 138 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 1 deletion(-) (limited to 'lib/textui/text_test.go') diff --git a/lib/textui/text_test.go b/lib/textui/text_test.go index 4b93683..6494b36 100644 --- a/lib/textui/text_test.go +++ b/lib/textui/text_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com> +// Copyright (C) 2022-2024 Luke Shumaker <lukeshu@lukeshu.com> // // SPDX-License-Identifier: GPL-2.0-or-later @@ -6,6 +6,8 @@ package textui_test import ( "fmt" + "math" + "math/big" "strings" "testing" @@ -40,3 +42,137 @@ func TestPortion(t *testing.T) { assert.Equal(t, "100% (0/0)", fmt.Sprint(textui.Portion[btrfsvol.PhysicalAddr]{})) assert.Equal(t, "0% (1/12,345)", fmt.Sprint(textui.Portion[btrfsvol.PhysicalAddr]{N: 1, D: 12345})) } + +func TestMetric(t *testing.T) { + t.Parallel() + + // _1e(n) returns `1e{n}` + _1e := func(n int64) *big.Int { + return new(big.Int).Exp(big.NewInt(10), big.NewInt(n), nil) + } + + // _1e(n) returns `1e-{n}` + _1em := func(n int64) *big.Rat { + ret := new(big.Rat).SetInt(_1e(n)) + ret.Inv(ret) + return ret + } + + // I've flipped the "actual" end "expected" fields for these + // tests, so that it's more readable as a table. + + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(33), "s")), "1,000Qs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(32), "s")), "100Qs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(31), "s")), "10Qs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(30), "s")), "1Qs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(29), "s")), "100Rs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(28), "s")), "10Rs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(27), "s")), "1Rs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(26), "s")), "100Ys") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(25), "s")), "10Ys") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(24), "s")), "1Ys") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(23), "s")), "100Zs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(22), "s")), "10Zs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(21), "s")), "1Zs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Int](_1e(20), "s")), "100Es") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e19, "s")), "10Es") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e18, "s")), "1Es") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e17, "s")), "100Ps") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e16, "s")), "10Ps") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e15, "s")), "1Ps") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e14, "s")), "100Ts") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e13, "s")), "10Ts") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e12, "s")), "1Ts") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e11, "s")), "100Gs") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e10, "s")), "10Gs") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e9, "s")), "1Gs") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e8, "s")), "100Ms") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e7, "s")), "10Ms") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e6, "s")), "1Ms") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e5, "s")), "100ks") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e4, "s")), "10ks") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e3, "s")), "1ks") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e2, "s")), "100s") + assert.Equal(t, fmt.Sprint(textui.Metric[uint64](1e1, "s")), "10s") + + assert.Equal(t, fmt.Sprint(textui.Metric(1e0, "s")), "1s") + + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(1), "s")), "100ms") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(2), "s")), "10ms") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(3), "s")), "1ms") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(4), "s")), "100μs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(5), "s")), "10μs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(6), "s")), "1μs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(7), "s")), "100ns") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(8), "s")), "10ns") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(9), "s")), "1ns") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(10), "s")), "100ps") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(11), "s")), "10ps") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(12), "s")), "1ps") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(13), "s")), "100fs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(14), "s")), "10fs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(15), "s")), "1fs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(16), "s")), "100as") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(17), "s")), "10as") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(18), "s")), "1as") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(19), "s")), "100zs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(20), "s")), "10zs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(21), "s")), "1zs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(22), "s")), "100ys") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(23), "s")), "10ys") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(24), "s")), "1ys") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(25), "s")), "100rs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(26), "s")), "10rs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(27), "s")), "1rs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(28), "s")), "100qs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(29), "s")), "10qs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(30), "s")), "1qs") + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(31), "s")), "0.1qs") + + assert.Equal(t, fmt.Sprint(textui.Metric[*big.Rat](_1em(31), "s")), "0.1qs") + + assert.Equal(t, fmt.Sprint(textui.Metric(math.NaN(), "s")), "NaNs") + assert.Equal(t, fmt.Sprintf("%5.f", textui.Metric(1, "s")), " 1s") + assert.Equal(t, fmt.Sprintf("%5.f", textui.Metric(1000, "s")), " 1ks") + assert.Equal(t, fmt.Sprintf("%5.f", textui.Metric(_1em(6), "s")), " 1μs") + +} + +func TestIEC(t *testing.T) { + t.Parallel() + + // _1ll(n) returns `1<<{n}` + _1ll := func(n int) *big.Int { + bs := make([]byte, 1+(n/8)) // = ⌈(n+1)/8⌉ = ((n+1)+(8-1))/8 = (n+8)/8 = 1+(n/8) + bs[0] = 1 << (n % 8) + return new(big.Int).SetBytes(bs) + } + + // I've flipped the "actual" end "expected" fields for these + // tests, so that it's more readable as a table. + + assert.Equal(t, fmt.Sprint(textui.IEC[*big.Int](_1ll(90), "B")), "1,024YiB") + assert.Equal(t, fmt.Sprint(textui.IEC[*big.Int](_1ll(85), "B")), "32YiB") + assert.Equal(t, fmt.Sprint(textui.IEC[*big.Int](_1ll(80), "B")), "1YiB") + assert.Equal(t, fmt.Sprint(textui.IEC[*big.Int](_1ll(75), "B")), "32ZiB") + assert.Equal(t, fmt.Sprint(textui.IEC[*big.Int](_1ll(70), "B")), "1ZiB") + assert.Equal(t, fmt.Sprint(textui.IEC[*big.Int](_1ll(65), "B")), "32EiB") + assert.Equal(t, fmt.Sprint(textui.IEC[uint64](1<<60, "B")), "1EiB") + assert.Equal(t, fmt.Sprint(textui.IEC[uint64](1<<55, "B")), "32PiB") + assert.Equal(t, fmt.Sprint(textui.IEC[uint64](1<<50, "B")), "1PiB") + assert.Equal(t, fmt.Sprint(textui.IEC[uint64](1<<45, "B")), "32TiB") + assert.Equal(t, fmt.Sprint(textui.IEC[uint64](1<<40, "B")), "1TiB") + assert.Equal(t, fmt.Sprint(textui.IEC[uint64](1<<35, "B")), "32GiB") + assert.Equal(t, fmt.Sprint(textui.IEC[uint64](1<<30, "B")), "1GiB") + assert.Equal(t, fmt.Sprint(textui.IEC[uint64](1<<25, "B")), "32MiB") + assert.Equal(t, fmt.Sprint(textui.IEC[uint64](1<<20, "B")), "1MiB") + assert.Equal(t, fmt.Sprint(textui.IEC[uint64](1<<15, "B")), "32KiB") + assert.Equal(t, fmt.Sprint(textui.IEC[uint64](1<<10, "B")), "1KiB") + assert.Equal(t, fmt.Sprint(textui.IEC[uint64](1<<5, "B")), "32B") + + assert.Equal(t, fmt.Sprint(textui.IEC(1<<0, "B")), "1B") + + assert.Equal(t, fmt.Sprint(textui.IEC(math.NaN(), "B")), "NaNB") + assert.Equal(t, fmt.Sprintf("%5.f", textui.IEC(1, "B")), " 1B") + assert.Equal(t, fmt.Sprintf("%5.f", textui.IEC(1024, "B")), " 1KiB") +} -- cgit v1.2.3-2-g168b