btlqql opened a new pull request, #4679:
URL: https://github.com/apache/rocketmq-dashboard/pull/4679
<!-- Base branch: `rocketmq-studio`, the RocketMQ Studio trunk. -->
### Brief Description
`formatBytes` (`web/src/utils/format.ts:142`) chose the unit by comparing
the **unrounded** byte
count against 1024 and only then rounded the mantissa with `toFixed`, so a
value just below a unit
boundary was rendered with a mantissa of exactly 1024 — the condition the
unit-selection loop exists
to prevent:
- `formatBytes(1048575)` returned `1024.0 KB` instead of `1.0 MB`;
- `formatBytes(1023.96)` returned `1024.0 B` instead of `1.0 KB`;
- `formatBytes(1073741823, 2)` returned `1024.00 MB` instead of `1.00 GB`.
The rounded mantissa is now re-checked and the unit is stepped up while it
still reaches 1024. The
largest unit (`PB`) is deliberately left alone — there is nothing above it
to step into — so
`formatBytes(1024 ** 6)` still renders `1024.0 PB`, which the existing
"clamps to the largest unit"
case already asserts.
The wrong unit is user-visible: the AI assistant's truncated-tool-output
footer
(`web/src/pages/ai/components/blocks/ToolBlock.tsx:201`) and the
test-message body/property size tags
(`web/src/pages/instance/topic.tsx:1361`-`1378`) both render
`formatBytes(...)`.
### How Did You Test This Change?
Added `web/src/utils/format.test.ts > formatBytes > promotes to the next
unit when rounding reaches
the boundary`, pinning the four boundary cases (1 decimal, 0 decimals, 2
decimals) plus the `PB`
ceiling.
Before the fix (red) — the values themselves are wrong, and the new case
fails:
```
$ node --experimental-strip-types --input-type=module -e "const {
formatBytes } = await import('./src/utils/format.ts');
for (const [v, d] of [[1023.96, undefined],[1048575, undefined],[1048575,
0],[1073741823, 2],[1024**6, undefined]]) console.log(v, d ?? 'default', '=>',
formatBytes(v, d));"
1023.96 default => 1024.0 B
1048575 default => 1024.0 KB
1048575 0 => 1024 KB
1073741823 2 => 1024.00 MB
1152921504606847000 default => 1024.0 PB
$ cd web && npx vitest run src/utils/format.test.ts
❯ src/utils/format.test.ts (9 tests | 1 failed) 50ms
× promotes to the next unit when rounding reaches the boundary 8ms
FAIL src/utils/format.test.ts > formatBytes > promotes to the next unit
when rounding reaches the boundary
AssertionError: expected '1024.0 B' to be '1.0 KB' // Object.is equality
Test Files 1 failed (1)
Tests 1 failed | 8 passed (9)
```
After the fix (green):
```
$ node --experimental-strip-types ... (same command as above)
1023.96 default => 1.0 KB
1048575 default => 1.0 MB
1048575 0 => 1 MB
1073741823 2 => 1.00 GB
1152921504606847000 default => 1024.0 PB
$ cd web && npx vitest run src/utils
✓ src/utils/format.test.ts (9 tests) 36ms
Test Files 19 passed (19)
Tests 125 passed (125)
Start at 14:17:22
Duration 5.73s
$ npx tsc -b # exit 0
$ npx eslint src/utils/format.ts src/utils/format.test.ts # exit 0
```
Scoping note on the suite: the whole `vitest` suite was **not** run —
`web/node_modules` in the
campaign clone was concurrently being reinstalled by another agent while
this change was verified
(imports of `jsdom`/`@adobe/css-tools` failed there from an unrelated,
half-installed tree), so the
change was verified in an isolated worktree with its own `npm install`. The
dependency of this change
is `formatBytes`, whose only other consumer is covered by the neighbouring
`src/utils` suite above
(19 files, 125 tests, all green); `tsc -b` and `eslint` cover the type and
lint surfaces. No `server/`
code is touched.
### Checklist
- [x] One coherent change; unrelated modifications are not bundled in
- [x] Commit subject follows Conventional Commits (`fix:`)
- [x] Tests added or updated for non-trivial changes, test methods named
`...Test` (web case is a `vitest` `it(...)` in `web/src/utils/format.test.ts`;
the Java `...Test` rule does not apply here)
- [x] New UI text has both Chinese and English entries under `web/src/i18n/`
(no UI text in this change)
- [x] Architecture constraints stay green (`mvn test` runs the ArchUnit
checks; no Java touched)
- [x] New source files carry the ASF license header (no new files)
- [x] Documentation touched where behaviour changed (JSDoc of `formatBytes`
still describes `1536 → '1.5 KB'`; the boundary case now matches it instead of
contradicting it)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]