From de34556d424b56ffcf085242fcb4e0fc9e4e1d40 Mon Sep 17 00:00:00 2001 From: kevin <5299031+kevin9327@users.noreply.github.com> Date: Sun, 1 Nov 2026 12:01:31 +0900 Subject: [PATCH] fix(size): move byte sizes to the next unit when rounding reaches 1024 --- internal/frontend/cli/upgrade.go | 4 +++- internal/frontend/cli/upgrade_test.go | 6 +++++ internal/tools/builtin/bgjobs.go | 4 +++- .../tools/builtin/bgjobs_bytecount_test.go | 22 +++++++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 internal/tools/builtin/bgjobs_bytecount_test.go diff --git a/internal/frontend/cli/upgrade.go b/internal/frontend/cli/upgrade.go index 73c878fb96..165955f25d 100644 --- a/internal/frontend/cli/upgrade.go +++ b/internal/frontend/cli/upgrade.go @@ -775,7 +775,9 @@ func humanSize(b int64) string { _MiB = 1024 * _KiB ) switch { - case b >= _MiB: + // From _MiB-51 bytes up, the KiB figure rounds to "1024.0" at one decimal + // place, so show it as MiB instead. + case b >= _MiB-51: return fmt.Sprintf("%.1f MiB", float64(b)/float64(_MiB)) case b >= _KiB: return fmt.Sprintf("%.1f KiB", float64(b)/float64(_KiB)) diff --git a/internal/frontend/cli/upgrade_test.go b/internal/frontend/cli/upgrade_test.go index ef4894f05c..149393df73 100644 --- a/internal/frontend/cli/upgrade_test.go +++ b/internal/frontend/cli/upgrade_test.go @@ -206,6 +206,12 @@ func TestHumanSize(t *testing.T) { {500, "500 B"}, {2048, "2.0 KiB"}, {19_000_000, "18.1 MiB"}, + // Sizes just under the next unit round up to it: show "1.0 MiB", + // never "1024.0 KiB". + {1_048_524, "1023.9 KiB"}, + {1_048_525, "1.0 MiB"}, + {1_048_575, "1.0 MiB"}, + {1_023, "1023 B"}, } for _, tt := range tests { if got := humanSize(tt.bytes); got != tt.want { diff --git a/internal/tools/builtin/bgjobs.go b/internal/tools/builtin/bgjobs.go index 1e2dc924eb..48125b571a 100644 --- a/internal/tools/builtin/bgjobs.go +++ b/internal/tools/builtin/bgjobs.go @@ -339,7 +339,9 @@ func stillRunning(p *jobs.Progress) string { func byteCount(n int64) string { switch { - case n >= 1<<20: + // From 1<<20 - 51 bytes up, the KB figure rounds to "1024.0" at one + // decimal place, so show it as MB instead. + case n >= 1<<20-51: return fmt.Sprintf("%.1f MB", float64(n)/(1<<20)) case n >= 1<<10: return fmt.Sprintf("%.1f KB", float64(n)/(1<<10)) diff --git a/internal/tools/builtin/bgjobs_bytecount_test.go b/internal/tools/builtin/bgjobs_bytecount_test.go new file mode 100644 index 0000000000..3e25e2bff0 --- /dev/null +++ b/internal/tools/builtin/bgjobs_bytecount_test.go @@ -0,0 +1,22 @@ +package builtin + +import "testing" + +func TestByteCountMovesToNextUnitWhenRoundingReachesIt(t *testing.T) { + tests := []struct { + n int64 + want string + }{ + {1023, "1023 B"}, + {1024, "1.0 KB"}, + {1_048_524, "1023.9 KB"}, + {1_048_525, "1.0 MB"}, + {1_048_575, "1.0 MB"}, + {1 << 20, "1.0 MB"}, + } + for _, tt := range tests { + if got := byteCount(tt.n); got != tt.want { + t.Errorf("byteCount(%d) = %q, want %q", tt.n, got, tt.want) + } + } +}