fflash: Fix unit formatting for values in [999.5, 1000)

Fixes progress output like `[rootfs 1.00e+03MB/1.93GB]`, which should be
1.00GB instead.

FIXED=b:245213472
TEST=bazel test //...

Change-Id: I9fdba8f34dcf231aea1d72b60efb41f8bca86455
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/5681260
Reviewed-by: Li-Yu Yu <aaronyu@google.com>
Auto-Submit: Shik Chen <shik@chromium.org>
Commit-Queue: Shik Chen <shik@chromium.org>
Tested-by: Shik Chen <shik@chromium.org>
diff --git a/contrib/fflash/internal/progress/BUILD.bazel b/contrib/fflash/internal/progress/BUILD.bazel
index 841e78d..10e6ff3 100644
--- a/contrib/fflash/internal/progress/BUILD.bazel
+++ b/contrib/fflash/internal/progress/BUILD.bazel
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-load("@rules_go//go:def.bzl", "go_library")
+load("@rules_go//go:def.bzl", "go_library", "go_test")
 
 go_library(
     name = "progress",
@@ -11,3 +11,10 @@
     visibility = ["//:__subpackages__"],
     deps = ["//internal/rate"],
 )
+
+go_test(
+    name = "progress_test",
+    srcs = ["progress_test.go"],
+    embed = [":progress"],
+    deps = ["@com_github_frankban_quicktest//:quicktest"],
+)
diff --git a/contrib/fflash/internal/progress/progress.go b/contrib/fflash/internal/progress/progress.go
index d0472d0..bd3ab17 100644
--- a/contrib/fflash/internal/progress/progress.go
+++ b/contrib/fflash/internal/progress/progress.go
@@ -22,7 +22,11 @@
 func formatUnit(n float64) string {
 	var unit string
 	for _, unit = range []string{"", "K", "M", "G", "T"} {
-		if n < 1000 {
+		// Cap at 999.5 to ensure values in [999.5, 1000) are formatted using the
+		// next unit as "1.00" instead of 1000. Otherwise they will be printed as
+		// "1.00+03" because it is too long for "%.3g".
+		// For example, 999500 should be "1.00M" instead of "1.00e+03K".
+		if n < 999.5 {
 			break
 		}
 		n /= 1000
diff --git a/contrib/fflash/internal/progress/progress_test.go b/contrib/fflash/internal/progress/progress_test.go
new file mode 100644
index 0000000..faafd40
--- /dev/null
+++ b/contrib/fflash/internal/progress/progress_test.go
@@ -0,0 +1,32 @@
+// Copyright 2024 The ChromiumOS Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package progress
+
+import (
+	qt "github.com/frankban/quicktest"
+	"math"
+	"testing"
+)
+
+func TestFormatUnit(t *testing.T) {
+	tests := []struct {
+		input    float64
+		expected string
+	}{
+		{987654, "988K"},
+		{999499, "999K"},
+		{math.Nextafter(999500, 0), "999K"},
+		{999500, "1.00M"},
+		{999999, "1.00M"},
+		{1000000, "1.00M"},
+		{1000001, "1.00M"},
+		{1234567, "1.23M"},
+	}
+
+	c := qt.New(t)
+	for _, test := range tests {
+		c.Check(formatUnit(test.input), qt.Equals, test.expected)
+	}
+}