Skip to content

Commit 2b8442d

Browse files
authored
Merge pull request #43 from easyops-cn/alex/fix-byte-unit-conversion-bug
fix(unitFormat): 修复单位换算bug
2 parents 290ad22 + 60d4425 commit 2b8442d

File tree

10 files changed

+6502
-124
lines changed

10 files changed

+6502
-124
lines changed

src/utils/unitFormat/constants/bytes.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,31 +31,31 @@ export const bytes: Unit[] = [
3131
{
3232
id: BytesUnitId.Kilobytes,
3333
alias: ["KB", "kilobytes(KB)"],
34-
divisor: 1024,
34+
divisor: 1000,
3535
display: "KB",
3636
},
3737
{
3838
id: BytesUnitId.Megabytes,
3939
alias: ["MB", "megabytes(MB)"],
40-
divisor: 1024 * 1024,
40+
divisor: 1000 ** 2,
4141
display: "MB",
4242
},
4343
{
4444
id: BytesUnitId.Gigabytes,
4545
alias: ["GB", "gigabytes(GB)"],
46-
divisor: 1024 * 1024 * 1024,
46+
divisor: 1000 ** 3,
4747
display: "GB",
4848
},
4949
{
5050
id: BytesUnitId.Terabytes,
5151
alias: ["TB", "terabytes(TB)"],
52-
divisor: 1024 * 1024 * 1024 * 1024,
52+
divisor: 1000 ** 4,
5353
display: "TB",
5454
},
5555
{
5656
id: BytesUnitId.Petabytes,
5757
alias: ["PB", "petabytes(PB)"],
58-
divisor: 1024 * 1024 * 1024 * 1024 * 1024,
58+
divisor: 1000 ** 5,
5959
display: "PB",
6060
},
6161
];
@@ -70,31 +70,31 @@ export const bibytes: Unit[] = [
7070
{
7171
id: BytesUnitId.Kibibytes,
7272
alias: ["KiB", "kibibytes(KiB)"],
73-
divisor: 1000,
73+
divisor: 1024,
7474
display: "KiB",
7575
},
7676
{
7777
id: BytesUnitId.Mebibytes,
7878
alias: ["MiB", "mebibytes(MiB)"],
79-
divisor: 1000 * 1000,
79+
divisor: 1024 ** 2,
8080
display: "MiB",
8181
},
8282
{
8383
id: BytesUnitId.Gibibytes,
8484
alias: ["GiB", "gibibytes(GiB)"],
85-
divisor: 1000 * 1000 * 1000,
85+
divisor: 1024 ** 3,
8686
display: "GiB",
8787
},
8888
{
8989
id: BytesUnitId.Tebibytes,
9090
alias: ["TiB", "tebibytes(TiB)"],
91-
divisor: 1000 * 1000 * 1000 * 1000,
91+
divisor: 1024 ** 4,
9292
display: "TiB",
9393
},
9494
{
9595
id: BytesUnitId.Pebibytes,
9696
alias: ["PiB", "pebibytes(PiB)"],
97-
divisor: 1000 * 1000 * 1000 * 1000 * 1000,
97+
divisor: 1024 ** 5,
9898
display: "PiB",
9999
},
100100
];
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import { humanizeDataValue } from "./data";
2+
import { BytesUnitId, BytesUnitId as DataFormatUnitId } from "../constants";
3+
4+
describe("data", () => {
5+
it("should humanize data value correctly", () => {
6+
expect(humanizeDataValue(8)).toEqual([1, "B"]);
7+
expect(humanizeDataValue(8, "bytes" as DataFormatUnitId)).toEqual([8, "B"]);
8+
expect(humanizeDataValue(-8)).toEqual([-1, "B"]);
9+
expect(humanizeDataValue(-8, "bytes" as DataFormatUnitId)).toEqual([
10+
-8,
11+
"B",
12+
]);
13+
14+
expect(humanizeDataValue(1000, "bytes(B)" as BytesUnitId)).toEqual([
15+
1,
16+
"KB",
17+
]);
18+
19+
expect(humanizeDataValue(1000, "kilobytes(KB)" as BytesUnitId)).toEqual([
20+
1,
21+
"MB",
22+
]);
23+
24+
expect(humanizeDataValue(1000, "megabytes(MB)" as BytesUnitId)).toEqual([
25+
1,
26+
"GB",
27+
]);
28+
29+
expect(humanizeDataValue(1000, "gigabytes(GB)" as BytesUnitId)).toEqual([
30+
1,
31+
"TB",
32+
]);
33+
34+
expect(humanizeDataValue(1000, "terabytes(TB)" as BytesUnitId)).toEqual([
35+
1,
36+
"PB",
37+
]);
38+
39+
expect(humanizeDataValue(1000, "petabytes(PB)" as BytesUnitId)).toEqual([
40+
1000,
41+
"PB",
42+
]);
43+
44+
expect(humanizeDataValue(1, "bibytes(B)" as BytesUnitId)).toEqual([1, "B"]);
45+
46+
expect(humanizeDataValue(1024, "bibytes(B)" as BytesUnitId)).toEqual([
47+
1,
48+
"KiB",
49+
]);
50+
51+
expect(humanizeDataValue(1024, "kibibytes(KiB)" as BytesUnitId)).toEqual([
52+
1,
53+
"MiB",
54+
]);
55+
56+
expect(humanizeDataValue(1024, "mebibytes(MiB)" as BytesUnitId)).toEqual([
57+
1,
58+
"GiB",
59+
]);
60+
61+
expect(humanizeDataValue(1024, "gibibytes(GiB)" as BytesUnitId)).toEqual([
62+
1,
63+
"TiB",
64+
]);
65+
66+
expect(humanizeDataValue(1024, "tebibytes(TiB)" as BytesUnitId)).toEqual([
67+
1,
68+
"PiB",
69+
]);
70+
71+
expect(humanizeDataValue(1024, "pebibytes(PiB)" as BytesUnitId)).toEqual([
72+
1024,
73+
"PiB",
74+
]);
75+
76+
expect(humanizeDataValue(-1000, "bytes(B)" as BytesUnitId)).toEqual([
77+
-1,
78+
"KB",
79+
]);
80+
81+
expect(humanizeDataValue(-1000, "kilobytes(KB)" as BytesUnitId)).toEqual([
82+
-1,
83+
"MB",
84+
]);
85+
86+
expect(humanizeDataValue(-1000, "megabytes(MB)" as BytesUnitId)).toEqual([
87+
-1,
88+
"GB",
89+
]);
90+
91+
expect(humanizeDataValue(-1000, "gigabytes(GB)" as BytesUnitId)).toEqual([
92+
-1,
93+
"TB",
94+
]);
95+
96+
expect(humanizeDataValue(-1000, "terabytes(TB)" as BytesUnitId)).toEqual([
97+
-1,
98+
"PB",
99+
]);
100+
101+
expect(humanizeDataValue(-1000, "petabytes(PB)" as BytesUnitId)).toEqual([
102+
-1000,
103+
"PB",
104+
]);
105+
106+
expect(humanizeDataValue(-1, "bibytes(B)" as BytesUnitId)).toEqual([
107+
-1,
108+
"B",
109+
]);
110+
111+
expect(humanizeDataValue(-1024, "bibytes(B)" as BytesUnitId)).toEqual([
112+
-1,
113+
"KiB",
114+
]);
115+
116+
expect(humanizeDataValue(-1024, "bibytes(B)" as BytesUnitId)).toEqual([
117+
-1,
118+
"KiB",
119+
]);
120+
121+
expect(humanizeDataValue(-1024, "kibibytes(KiB)" as BytesUnitId)).toEqual([
122+
-1,
123+
"MiB",
124+
]);
125+
126+
expect(humanizeDataValue(-1024, "mebibytes(MiB)" as BytesUnitId)).toEqual([
127+
-1,
128+
"GiB",
129+
]);
130+
131+
expect(humanizeDataValue(-1024, "gibibytes(GiB)" as BytesUnitId)).toEqual([
132+
-1,
133+
"TiB",
134+
]);
135+
136+
expect(humanizeDataValue(-1024, "tebibytes(TiB)" as BytesUnitId)).toEqual([
137+
-1,
138+
"PiB",
139+
]);
140+
141+
expect(humanizeDataValue(-1024, "pebibytes(PiB)" as BytesUnitId)).toEqual([
142+
-1024,
143+
"PiB",
144+
]);
145+
});
146+
});

src/utils/unitFormat/func/data.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export function humanizeDataValue(
3232
): [number, string] {
3333
let baseDataUnitGroupIndex = dataFormatUnits.length - 1;
3434
let baseDataUnitIndex = 0;
35+
const sign = Math.sign(value);
36+
const positiveValue = Math.abs(value);
3537

3638
if (unit) {
3739
for (let i = 0; i < dataFormatUnits.length; ++i) {
@@ -40,10 +42,9 @@ export function humanizeDataValue(
4042
dataUnit.id.toLocaleLowerCase() === unit.toLocaleLowerCase() ||
4143
(dataUnit.alias &&
4244
dataUnit.alias
43-
.map((alias) => alias.toLocaleLowerCase())
45+
// .map((alias) => alias.toLocaleLowerCase())
4446
.includes(unit))
4547
);
46-
// istanbul ignore else
4748
if (dataUnitIndex !== -1) {
4849
baseDataUnitGroupIndex = i;
4950
baseDataUnitIndex = dataUnitIndex;
@@ -56,7 +57,7 @@ export function humanizeDataValue(
5657
let dataFormatUnit = dataFormatUnitGroup[baseDataUnitIndex];
5758
for (let i = baseDataUnitIndex + 1; i < dataFormatUnitGroup.length; ++i) {
5859
if (
59-
value /
60+
positiveValue /
6061
(dataFormatUnitGroup[i].divisor /
6162
dataFormatUnitGroup[baseDataUnitIndex].divisor) >=
6263
1
@@ -68,8 +69,10 @@ export function humanizeDataValue(
6869
}
6970

7071
return [
71-
value /
72-
(dataFormatUnit.divisor / dataFormatUnitGroup[baseDataUnitIndex].divisor),
72+
(positiveValue /
73+
(dataFormatUnit.divisor /
74+
dataFormatUnitGroup[baseDataUnitIndex].divisor)) *
75+
sign,
7376
dataFormatUnit.display,
7477
];
7578
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { humanizeDataRateValue } from "./dataRate";
2+
import { ByteRatesUnitId as DataRateFormatUnitId } from "../constants";
3+
4+
describe("dateRate", () => {
5+
it("should humanize data rate value correctly", () => {
6+
expect(humanizeDataRateValue(8)).toEqual([1, "Bps"]);
7+
expect(humanizeDataRateValue(8 * 1024)).toEqual([1, "KBps"]);
8+
expect(humanizeDataRateValue(1024, DataRateFormatUnitId.KBps)).toEqual([
9+
1,
10+
"MBps",
11+
]);
12+
13+
expect(humanizeDataRateValue(-8)).toEqual([-1, "Bps"]);
14+
expect(humanizeDataRateValue(-8 * 1024)).toEqual([-1, "KBps"]);
15+
expect(humanizeDataRateValue(-1024, DataRateFormatUnitId.KBps)).toEqual([
16+
-1,
17+
"MBps",
18+
]);
19+
});
20+
});

src/utils/unitFormat/func/dataRate.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ export function humanizeDataRateValue(
3434
): [number, string] {
3535
let baseDataRateUnitGroupIndex = dataRateFormatUnits.length - 1;
3636
let baseDataRateUnitIndex = 0;
37+
const sign = Math.sign(value);
38+
const positiveValue = Math.abs(value);
3739

3840
if (unit) {
3941
for (let i = 0; i < dataRateFormatUnits.length; ++i) {
@@ -62,7 +64,7 @@ export function humanizeDataRateValue(
6264
++i
6365
) {
6466
if (
65-
value /
67+
positiveValue /
6668
(dataRateFormatUnitGroup[i].divisor /
6769
dataRateFormatUnitGroup[baseDataRateUnitIndex].divisor) >=
6870
1
@@ -74,9 +76,10 @@ export function humanizeDataRateValue(
7476
}
7577

7678
return [
77-
value /
79+
(positiveValue /
7880
(dataRateFormatUnit.divisor /
79-
dataRateFormatUnitGroup[baseDataRateUnitIndex].divisor),
81+
dataRateFormatUnitGroup[baseDataRateUnitIndex].divisor)) *
82+
sign,
8083
dataRateFormatUnit.display,
8184
];
8285
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { humanizeNumberValue } from "./number";
2+
import { ShortUnitId } from "../constants";
3+
4+
describe("dateRate", () => {
5+
it("should humanize data rate value correctly", () => {
6+
expect(humanizeNumberValue(8)).toEqual("8.00");
7+
expect(humanizeNumberValue(8000)).toEqual("8.00K");
8+
expect(humanizeNumberValue(8000000)).toEqual("8.00M");
9+
expect(humanizeNumberValue(8000000000)).toEqual("8.00B");
10+
expect(humanizeNumberValue(8000000000000)).toEqual("8.00T");
11+
expect(humanizeNumberValue(8000, ShortUnitId.K)).toEqual("8.00M");
12+
expect(humanizeNumberValue(8000, ShortUnitId.M, 1)).toEqual("8.0B");
13+
14+
expect(humanizeNumberValue(-8)).toEqual("-8.00");
15+
expect(humanizeNumberValue(-8000)).toEqual("-8.00K");
16+
expect(humanizeNumberValue(-8000000)).toEqual("-8.00M");
17+
expect(humanizeNumberValue(-8000000000)).toEqual("-8.00B");
18+
expect(humanizeNumberValue(-8000000000000)).toEqual("-8.00T");
19+
expect(humanizeNumberValue(-8000, ShortUnitId.K)).toEqual("-8.00M");
20+
expect(humanizeNumberValue(-8000, ShortUnitId.M, 1)).toEqual("-8.0B");
21+
});
22+
});

src/utils/unitFormat/func/number.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ export const humanizeNumberValue = (
66
precision?: number
77
): string => {
88
let baseNumberUnitIndex = 0;
9+
const sign = Math.sign(value);
10+
const positiveValue = Math.abs(value);
911
if (unit) {
1012
const numberUnitIndex = numberFormatUnits.findIndex(
1113
(numberUnit) =>
@@ -19,7 +21,7 @@ export const humanizeNumberValue = (
1921
let numberFormatUnit = numberFormatUnits[baseNumberUnitIndex];
2022
for (let i = baseNumberUnitIndex + 1; i < numberFormatUnits.length; ++i) {
2123
if (
22-
value /
24+
positiveValue /
2325
(numberFormatUnits[i].divisor /
2426
numberFormatUnits[baseNumberUnitIndex].divisor) >=
2527
1
@@ -31,13 +33,14 @@ export const humanizeNumberValue = (
3133
}
3234

3335
if (numberFormatUnit.id === ShortUnitId.None) {
34-
return value.toFixed(precision ?? 2);
36+
return (sign * positiveValue).toFixed(precision ?? 2);
3537
} else {
3638
return (
3739
(
38-
value /
39-
(numberFormatUnit.divisor /
40-
numberFormatUnits[baseNumberUnitIndex].divisor)
40+
(positiveValue /
41+
(numberFormatUnit.divisor /
42+
numberFormatUnits[baseNumberUnitIndex].divisor)) *
43+
sign
4144
).toFixed(precision ?? 2) + numberFormatUnit.display
4245
);
4346
}

0 commit comments

Comments
 (0)