@ooneex/utils 0.0.6 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +539 -203
- package/dist/index.d.ts +24 -16
- package/dist/index.js +3 -1
- package/dist/index.js.map +25 -0
- package/package.json +22 -14
- package/dist/capitalizeWord.d.ts +0 -2
- package/dist/capitalizeWord.d.ts.map +0 -1
- package/dist/dataURLtoFile.d.ts +0 -2
- package/dist/dataURLtoFile.d.ts.map +0 -1
- package/dist/formatRelativeNumber.d.ts +0 -5
- package/dist/formatRelativeNumber.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/millisecondsToHMS.d.ts +0 -2
- package/dist/millisecondsToHMS.d.ts.map +0 -1
- package/dist/parseEnvVars.d.ts +0 -2
- package/dist/parseEnvVars.d.ts.map +0 -1
- package/dist/parseString.d.ts +0 -2
- package/dist/parseString.d.ts.map +0 -1
- package/dist/random.d.ts +0 -6
- package/dist/random.d.ts.map +0 -1
- package/dist/secondsToHMS.d.ts +0 -2
- package/dist/secondsToHMS.d.ts.map +0 -1
- package/dist/secondsToMS.d.ts +0 -2
- package/dist/secondsToMS.d.ts.map +0 -1
- package/dist/sleep.d.ts +0 -2
- package/dist/sleep.d.ts.map +0 -1
- package/dist/splitToWords.d.ts +0 -2
- package/dist/splitToWords.d.ts.map +0 -1
- package/dist/toCamelCase.d.ts +0 -2
- package/dist/toCamelCase.d.ts.map +0 -1
- package/dist/toKebabCase.d.ts +0 -2
- package/dist/toKebabCase.d.ts.map +0 -1
- package/dist/toPascalCase.d.ts +0 -2
- package/dist/toPascalCase.d.ts.map +0 -1
- package/dist/trim.d.ts +0 -2
- package/dist/trim.d.ts.map +0 -1
- package/src/capitalizeWord.ts +0 -3
- package/src/dataURLtoFile.ts +0 -12
- package/src/formatRelativeNumber.ts +0 -7
- package/src/index.ts +0 -15
- package/src/millisecondsToHMS.ts +0 -16
- package/src/parseEnvVars.ts +0 -14
- package/src/parseString.ts +0 -47
- package/src/random.ts +0 -13
- package/src/secondsToHMS.ts +0 -16
- package/src/secondsToMS.ts +0 -5
- package/src/sleep.ts +0 -3
- package/src/splitToWords.ts +0 -14
- package/src/toCamelCase.ts +0 -8
- package/src/toKebabCase.ts +0 -6
- package/src/toPascalCase.ts +0 -7
- package/src/trim.ts +0 -8
- package/tests/capitalizeWord.spec.ts +0 -163
- package/tests/dataURLtoFile.spec.ts +0 -472
- package/tests/formatRelativeNumber.spec.ts +0 -303
- package/tests/millisecondsToHMS.spec.ts +0 -209
- package/tests/parseEnvVars.spec.ts +0 -468
- package/tests/parseString.spec.ts +0 -377
- package/tests/random.spec.ts +0 -422
- package/tests/secondsToHMS.spec.ts +0 -341
- package/tests/secondsToMS.spec.ts +0 -467
- package/tests/splitToWords.spec.ts +0 -359
- package/tests/toCamelCase.spec.ts +0 -526
- package/tests/toKebabCase.spec.ts +0 -664
- package/tests/toPascalCase.spec.ts +0 -721
- package/tests/trim.spec.ts +0 -486
- package/tsconfig.build.json +0 -14
- package/tsconfig.json +0 -11
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
2
|
-
import { formatRelativeNumber } from "@/index";
|
|
3
|
-
|
|
4
|
-
describe("formatRelativeNumber", () => {
|
|
5
|
-
describe("basic functionality", () => {
|
|
6
|
-
test("should format small numbers without compacting", () => {
|
|
7
|
-
expect(formatRelativeNumber(42)).toBe("42");
|
|
8
|
-
expect(formatRelativeNumber(123)).toBe("123");
|
|
9
|
-
expect(formatRelativeNumber(999)).toBe("999");
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
test("should format thousands with K suffix", () => {
|
|
13
|
-
expect(formatRelativeNumber(1000)).toBe("1K");
|
|
14
|
-
expect(formatRelativeNumber(1500)).toBe("1.5K");
|
|
15
|
-
expect(formatRelativeNumber(2300)).toBe("2.3K");
|
|
16
|
-
expect(formatRelativeNumber(10000)).toBe("10K");
|
|
17
|
-
expect(formatRelativeNumber(50000)).toBe("50K");
|
|
18
|
-
expect(formatRelativeNumber(999000)).toBe("999K");
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
test("should format millions with M suffix", () => {
|
|
22
|
-
expect(formatRelativeNumber(1000000)).toBe("1M");
|
|
23
|
-
expect(formatRelativeNumber(1500000)).toBe("1.5M");
|
|
24
|
-
expect(formatRelativeNumber(2300000)).toBe("2.3M");
|
|
25
|
-
expect(formatRelativeNumber(10000000)).toBe("10M");
|
|
26
|
-
expect(formatRelativeNumber(999000000)).toBe("999M");
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
test("should format billions with B suffix", () => {
|
|
30
|
-
expect(formatRelativeNumber(1000000000)).toBe("1B");
|
|
31
|
-
expect(formatRelativeNumber(1500000000)).toBe("1.5B");
|
|
32
|
-
expect(formatRelativeNumber(2300000000)).toBe("2.3B");
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test("should format trillions with T suffix", () => {
|
|
36
|
-
expect(formatRelativeNumber(1000000000000)).toBe("1T");
|
|
37
|
-
expect(formatRelativeNumber(1500000000000)).toBe("1.5T");
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
describe("precision configuration", () => {
|
|
42
|
-
test("should respect precision 0", () => {
|
|
43
|
-
expect(formatRelativeNumber(1500, { precision: 0 })).toBe("2K");
|
|
44
|
-
expect(formatRelativeNumber(1500000, { precision: 0 })).toBe("2M");
|
|
45
|
-
expect(formatRelativeNumber(2300000, { precision: 0 })).toBe("2M");
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
test("should respect precision 1 (default)", () => {
|
|
49
|
-
expect(formatRelativeNumber(1500)).toBe("1.5K");
|
|
50
|
-
expect(formatRelativeNumber(1500, { precision: 1 })).toBe("1.5K");
|
|
51
|
-
expect(formatRelativeNumber(2300000)).toBe("2.3M");
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
test("should respect precision 2", () => {
|
|
55
|
-
expect(formatRelativeNumber(1234, { precision: 2 })).toBe("1.23K");
|
|
56
|
-
expect(formatRelativeNumber(1234567, { precision: 2 })).toBe("1.23M");
|
|
57
|
-
expect(formatRelativeNumber(9876543, { precision: 2 })).toBe("9.88M");
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test("should respect precision 3", () => {
|
|
61
|
-
expect(formatRelativeNumber(1234, { precision: 3 })).toBe("1.234K");
|
|
62
|
-
expect(formatRelativeNumber(1234567, { precision: 3 })).toBe("1.235M");
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
test("should handle precision 0 with edge cases", () => {
|
|
66
|
-
expect(formatRelativeNumber(1499, { precision: 0 })).toBe("1K");
|
|
67
|
-
expect(formatRelativeNumber(1999, { precision: 0 })).toBe("2K");
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
describe("language configuration", () => {
|
|
72
|
-
test("should use en-GB as default", () => {
|
|
73
|
-
expect(formatRelativeNumber(1500)).toBe("1.5K");
|
|
74
|
-
expect(formatRelativeNumber(1500000)).toBe("1.5M");
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
test("should format with en-US locale", () => {
|
|
78
|
-
expect(formatRelativeNumber(1500, { lang: "en-US" })).toBe("1.5K");
|
|
79
|
-
expect(formatRelativeNumber(1500000, { lang: "en-US" })).toBe("1.5M");
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
test("should format with de-DE locale", () => {
|
|
83
|
-
// German has different compact notation thresholds
|
|
84
|
-
expect(formatRelativeNumber(1500, { lang: "de-DE" })).toBe("1500");
|
|
85
|
-
expect(formatRelativeNumber(1500000, { lang: "de-DE" })).toBe("1,5\u00A0Mio.");
|
|
86
|
-
expect(formatRelativeNumber(10000, { lang: "de-DE" })).toBe("10.000");
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
test("should format with fr-FR locale", () => {
|
|
90
|
-
expect(formatRelativeNumber(1500, { lang: "fr-FR" })).toBe("1,5\u00A0k");
|
|
91
|
-
expect(formatRelativeNumber(1500000, { lang: "fr-FR" })).toBe("1,5\u00A0M");
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
test("should format with es-ES locale", () => {
|
|
95
|
-
expect(formatRelativeNumber(1500, { lang: "es-ES" })).toBe("1,5\u00A0mil");
|
|
96
|
-
expect(formatRelativeNumber(1500000, { lang: "es-ES" })).toBe("1,5\u00A0M");
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
test("should format with ja-JP locale", () => {
|
|
100
|
-
// Japanese has different compact notation behavior for smaller numbers
|
|
101
|
-
expect(formatRelativeNumber(1500, { lang: "ja-JP" })).toBe("1500");
|
|
102
|
-
expect(formatRelativeNumber(1500000, { lang: "ja-JP" })).toBe("150万");
|
|
103
|
-
expect(formatRelativeNumber(10000, { lang: "ja-JP" })).toBe("1万");
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
test("should handle locale-specific compact notation thresholds", () => {
|
|
107
|
-
// Test numbers where compact notation definitely applies across locales
|
|
108
|
-
expect(formatRelativeNumber(100000, { lang: "de-DE" })).toBe("100.000");
|
|
109
|
-
expect(formatRelativeNumber(100000, { lang: "fr-FR" })).toBe("100\u00A0k");
|
|
110
|
-
expect(formatRelativeNumber(100000, { lang: "es-ES" })).toBe("100\u00A0mil");
|
|
111
|
-
expect(formatRelativeNumber(100000, { lang: "ja-JP" })).toBe("10万");
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
describe("combined configuration", () => {
|
|
116
|
-
test("should use both precision and language", () => {
|
|
117
|
-
expect(formatRelativeNumber(1234, { precision: 2, lang: "en-US" })).toBe("1.23K");
|
|
118
|
-
expect(formatRelativeNumber(1234, { precision: 2, lang: "de-DE" })).toBe("1234");
|
|
119
|
-
expect(formatRelativeNumber(1234567, { precision: 0, lang: "fr-FR" })).toBe("1\u00A0M");
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
test("should handle edge cases with configuration", () => {
|
|
123
|
-
expect(formatRelativeNumber(999999, { precision: 3, lang: "en-GB" })).toBe("999.999K");
|
|
124
|
-
expect(formatRelativeNumber(1000000, { precision: 3, lang: "en-GB" })).toBe("1M");
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
describe("edge cases", () => {
|
|
129
|
-
test("should handle zero", () => {
|
|
130
|
-
expect(formatRelativeNumber(0)).toBe("0");
|
|
131
|
-
expect(formatRelativeNumber(0, { precision: 2 })).toBe("0");
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
test("should handle negative numbers", () => {
|
|
135
|
-
expect(formatRelativeNumber(-42)).toBe("-42");
|
|
136
|
-
expect(formatRelativeNumber(-1500)).toBe("-1.5K");
|
|
137
|
-
expect(formatRelativeNumber(-1500000)).toBe("-1.5M");
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
test("should handle decimal inputs", () => {
|
|
141
|
-
expect(formatRelativeNumber(1.5)).toBe("1.5");
|
|
142
|
-
expect(formatRelativeNumber(999.9)).toBe("999.9");
|
|
143
|
-
expect(formatRelativeNumber(1000.5)).toBe("1K");
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
test("should handle very small positive numbers", () => {
|
|
147
|
-
expect(formatRelativeNumber(0.1)).toBe("0.1");
|
|
148
|
-
expect(formatRelativeNumber(0.01)).toBe("0");
|
|
149
|
-
expect(formatRelativeNumber(0.99)).toBe("1");
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
test("should handle very large numbers", () => {
|
|
153
|
-
expect(formatRelativeNumber(1e15)).toBe("1000T");
|
|
154
|
-
expect(formatRelativeNumber(1e18)).toBe("1,000,000T");
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
test("should handle Number.MAX_SAFE_INTEGER", () => {
|
|
158
|
-
const result = formatRelativeNumber(Number.MAX_SAFE_INTEGER);
|
|
159
|
-
expect(typeof result).toBe("string");
|
|
160
|
-
expect(result).toMatch(/\d+(\.\d+)?[KMBT]/);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
test("should handle Number.MIN_SAFE_INTEGER", () => {
|
|
164
|
-
const result = formatRelativeNumber(Number.MIN_SAFE_INTEGER);
|
|
165
|
-
expect(typeof result).toBe("string");
|
|
166
|
-
expect(result).toMatch(/-\d+(\.\d+)?[KMBT]/);
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
describe("parametrized tests", () => {
|
|
171
|
-
test.each([
|
|
172
|
-
[0, "0"],
|
|
173
|
-
[1, "1"],
|
|
174
|
-
[10, "10"],
|
|
175
|
-
[100, "100"],
|
|
176
|
-
[1000, "1K"],
|
|
177
|
-
[10000, "10K"],
|
|
178
|
-
[100000, "100K"],
|
|
179
|
-
[1000000, "1M"],
|
|
180
|
-
[10000000, "10M"],
|
|
181
|
-
[100000000, "100M"],
|
|
182
|
-
[1000000000, "1B"],
|
|
183
|
-
])("formatRelativeNumber(%s) should return %s", (input, expected) => {
|
|
184
|
-
expect(formatRelativeNumber(input)).toBe(expected);
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
test.each([
|
|
188
|
-
[1234, 0, "1K"],
|
|
189
|
-
[1234, 1, "1.2K"],
|
|
190
|
-
[1234, 2, "1.23K"],
|
|
191
|
-
[1234567, 0, "1M"],
|
|
192
|
-
[1234567, 1, "1.2M"],
|
|
193
|
-
[1234567, 2, "1.23M"],
|
|
194
|
-
])("formatRelativeNumber(%s, {precision: %s}) should return %s", (input, precision, expected) => {
|
|
195
|
-
expect(formatRelativeNumber(input, { precision })).toBe(expected);
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
describe("type safety and configuration validation", () => {
|
|
200
|
-
test("should handle undefined config", () => {
|
|
201
|
-
expect(formatRelativeNumber(1500, undefined)).toBe("1.5K");
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
test("should handle empty config object", () => {
|
|
205
|
-
expect(formatRelativeNumber(1500, {})).toBe("1.5K");
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
test("should handle partial config with precision only", () => {
|
|
209
|
-
expect(formatRelativeNumber(1234, { precision: 2 })).toBe("1.23K");
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
test("should handle partial config with lang only", () => {
|
|
213
|
-
expect(formatRelativeNumber(1500, { lang: "de-DE" })).toBe("1500");
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
test("should use defaults when config properties are undefined", () => {
|
|
217
|
-
expect(formatRelativeNumber(1500, { precision: undefined, lang: undefined })).toBe("1.5K");
|
|
218
|
-
});
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
describe("function behavior", () => {
|
|
222
|
-
test("should return string type", () => {
|
|
223
|
-
const result = formatRelativeNumber(1000);
|
|
224
|
-
expect(typeof result).toBe("string");
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
test("should handle consecutive calls consistently", () => {
|
|
228
|
-
const num = 1500;
|
|
229
|
-
const result1 = formatRelativeNumber(num);
|
|
230
|
-
const result2 = formatRelativeNumber(num);
|
|
231
|
-
expect(result1).toBe(result2);
|
|
232
|
-
expect(result1).toBe("1.5K");
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
test("should not mutate config object", () => {
|
|
236
|
-
const config = { precision: 2, lang: "en-US" };
|
|
237
|
-
const originalConfig = { ...config };
|
|
238
|
-
formatRelativeNumber(1000, config);
|
|
239
|
-
expect(config).toEqual(originalConfig);
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
test("should handle different input types that coerce to numbers", () => {
|
|
243
|
-
// These should work as TypeScript allows number type
|
|
244
|
-
expect(formatRelativeNumber(1000)).toBe("1K");
|
|
245
|
-
expect(formatRelativeNumber(1000.0)).toBe("1K");
|
|
246
|
-
expect(formatRelativeNumber(1e3)).toBe("1K");
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
describe("real world examples", () => {
|
|
251
|
-
test("should format social media metrics", () => {
|
|
252
|
-
expect(formatRelativeNumber(1200)).toBe("1.2K"); // followers
|
|
253
|
-
expect(formatRelativeNumber(15000)).toBe("15K"); // likes
|
|
254
|
-
expect(formatRelativeNumber(250000)).toBe("250K"); // views
|
|
255
|
-
expect(formatRelativeNumber(1800000)).toBe("1.8M"); // subscribers
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
test("should format financial numbers", () => {
|
|
259
|
-
expect(formatRelativeNumber(50000)).toBe("50K"); // salary
|
|
260
|
-
expect(formatRelativeNumber(125000)).toBe("125K"); // house price
|
|
261
|
-
expect(formatRelativeNumber(2500000)).toBe("2.5M"); // company value
|
|
262
|
-
expect(formatRelativeNumber(1200000000)).toBe("1.2B"); // market cap
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
test("should format file sizes (as numbers)", () => {
|
|
266
|
-
expect(formatRelativeNumber(1024)).toBe("1K"); // 1KB
|
|
267
|
-
expect(formatRelativeNumber(1048576)).toBe("1M"); // 1MB
|
|
268
|
-
expect(formatRelativeNumber(1073741824)).toBe("1.1B"); // 1GB
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
test("should format population numbers", () => {
|
|
272
|
-
expect(formatRelativeNumber(8500000)).toBe("8.5M"); // NYC population
|
|
273
|
-
expect(formatRelativeNumber(37000000)).toBe("37M"); // California population
|
|
274
|
-
expect(formatRelativeNumber(331000000)).toBe("331M"); // US population
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
describe("browser compatibility", () => {
|
|
279
|
-
test("should work with Intl.NumberFormat", () => {
|
|
280
|
-
// This ensures Intl.NumberFormat is available and working
|
|
281
|
-
expect(() => formatRelativeNumber(1000)).not.toThrow();
|
|
282
|
-
expect(formatRelativeNumber(1000)).toBeTruthy();
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
test("should handle various locales gracefully", () => {
|
|
286
|
-
const locales = ["en-US", "en-GB", "de-DE", "fr-FR", "es-ES", "it-IT", "pt-BR", "ru-RU", "zh-CN", "ja-JP"];
|
|
287
|
-
|
|
288
|
-
for (const locale of locales) {
|
|
289
|
-
expect(() => formatRelativeNumber(1500, { lang: locale })).not.toThrow();
|
|
290
|
-
const result = formatRelativeNumber(1500, { lang: locale });
|
|
291
|
-
expect(typeof result).toBe("string");
|
|
292
|
-
expect(result.length).toBeGreaterThan(0);
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
test("should handle invalid locale gracefully", () => {
|
|
297
|
-
// Invalid locales should fallback gracefully
|
|
298
|
-
expect(() => formatRelativeNumber(1500, { lang: "invalid-locale" })).not.toThrow();
|
|
299
|
-
const result = formatRelativeNumber(1500, { lang: "invalid-locale" });
|
|
300
|
-
expect(typeof result).toBe("string");
|
|
301
|
-
});
|
|
302
|
-
});
|
|
303
|
-
});
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
2
|
-
import { millisecondsToHMS } from "@/index";
|
|
3
|
-
|
|
4
|
-
describe("millisecondsToHMS", () => {
|
|
5
|
-
describe("basic functionality", () => {
|
|
6
|
-
test("should convert seconds only (< 1 minute)", () => {
|
|
7
|
-
expect(millisecondsToHMS(5000)).toBe("5");
|
|
8
|
-
expect(millisecondsToHMS(30000)).toBe("30");
|
|
9
|
-
expect(millisecondsToHMS(59000)).toBe("59");
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
test("should convert minutes and seconds (< 1 hour)", () => {
|
|
13
|
-
expect(millisecondsToHMS(60000)).toBe("1:00");
|
|
14
|
-
expect(millisecondsToHMS(90000)).toBe("1:30");
|
|
15
|
-
expect(millisecondsToHMS(3599000)).toBe("59:59");
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
test("should convert hours, minutes and seconds (>= 1 hour)", () => {
|
|
19
|
-
expect(millisecondsToHMS(3600000)).toBe("1:00:00");
|
|
20
|
-
expect(millisecondsToHMS(3661000)).toBe("1:01:01");
|
|
21
|
-
expect(millisecondsToHMS(7200000)).toBe("2:00:00");
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
test("should handle zero milliseconds", () => {
|
|
25
|
-
expect(millisecondsToHMS(0)).toBe("0");
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
describe("formatting", () => {
|
|
30
|
-
test("should pad minutes with leading zero when hours present", () => {
|
|
31
|
-
expect(millisecondsToHMS(3660000)).toBe("1:01:00");
|
|
32
|
-
expect(millisecondsToHMS(3605000)).toBe("1:00:05");
|
|
33
|
-
expect(millisecondsToHMS(32400000 + 60000 + 5000)).toBe("9:01:05");
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test("should pad seconds with leading zero when minutes present", () => {
|
|
37
|
-
expect(millisecondsToHMS(65000)).toBe("1:05");
|
|
38
|
-
expect(millisecondsToHMS(600000 + 1000)).toBe("10:01");
|
|
39
|
-
expect(millisecondsToHMS(3600000 + 60000 + 1000)).toBe("1:01:01");
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test("should not pad single digits when no higher unit present", () => {
|
|
43
|
-
expect(millisecondsToHMS(1000)).toBe("1");
|
|
44
|
-
expect(millisecondsToHMS(5000)).toBe("5");
|
|
45
|
-
expect(millisecondsToHMS(9000)).toBe("9");
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
test("should handle double-digit values correctly", () => {
|
|
49
|
-
expect(millisecondsToHMS(10000)).toBe("10");
|
|
50
|
-
expect(millisecondsToHMS(600000 + 15000)).toBe("10:15");
|
|
51
|
-
expect(millisecondsToHMS(3600000 + 600000 + 15000)).toBe("1:10:15");
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
describe("edge cases", () => {
|
|
56
|
-
test("should handle milliseconds that don't divide evenly", () => {
|
|
57
|
-
expect(millisecondsToHMS(1500)).toBe("1"); // 1.5 seconds -> 1 second
|
|
58
|
-
expect(millisecondsToHMS(1999)).toBe("1"); // 1.999 seconds -> 1 second
|
|
59
|
-
expect(millisecondsToHMS(61500)).toBe("1:01"); // 61.5 seconds -> 1:01
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
test("should handle very small millisecond values", () => {
|
|
63
|
-
expect(millisecondsToHMS(1)).toBe("0");
|
|
64
|
-
expect(millisecondsToHMS(500)).toBe("0");
|
|
65
|
-
expect(millisecondsToHMS(999)).toBe("0");
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
test("should handle large hour values", () => {
|
|
69
|
-
expect(millisecondsToHMS(24 * 3600000)).toBe("24:00:00"); // 24 hours
|
|
70
|
-
expect(millisecondsToHMS(100 * 3600000)).toBe("100:00:00"); // 100 hours
|
|
71
|
-
expect(millisecondsToHMS(999 * 3600000)).toBe("999:00:00"); // 999 hours
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
test("should handle maximum safe integer values", () => {
|
|
75
|
-
const largeValue = 999999999000; // 999,999,999 seconds
|
|
76
|
-
const result = millisecondsToHMS(largeValue);
|
|
77
|
-
expect(typeof result).toBe("string");
|
|
78
|
-
expect(result).toMatch(/^\d+:\d{2}:\d{2}$/);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
describe("mathematical precision", () => {
|
|
83
|
-
test("should floor milliseconds to seconds", () => {
|
|
84
|
-
expect(millisecondsToHMS(1001)).toBe("1");
|
|
85
|
-
expect(millisecondsToHMS(1999)).toBe("1");
|
|
86
|
-
expect(millisecondsToHMS(2001)).toBe("2");
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
test("should calculate minutes correctly", () => {
|
|
90
|
-
expect(millisecondsToHMS(60000)).toBe("1:00");
|
|
91
|
-
expect(millisecondsToHMS(119000)).toBe("1:59");
|
|
92
|
-
expect(millisecondsToHMS(120000)).toBe("2:00");
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
test("should calculate hours correctly", () => {
|
|
96
|
-
expect(millisecondsToHMS(3600000)).toBe("1:00:00");
|
|
97
|
-
expect(millisecondsToHMS(7199000)).toBe("1:59:59");
|
|
98
|
-
expect(millisecondsToHMS(7200000)).toBe("2:00:00");
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
describe("parametrized tests", () => {
|
|
103
|
-
test.each([
|
|
104
|
-
[0, "0"],
|
|
105
|
-
[1000, "1"],
|
|
106
|
-
[10000, "10"],
|
|
107
|
-
[60000, "1:00"],
|
|
108
|
-
[90000, "1:30"],
|
|
109
|
-
[3600000, "1:00:00"],
|
|
110
|
-
[3661000, "1:01:01"],
|
|
111
|
-
[7200000, "2:00:00"],
|
|
112
|
-
[86400000, "24:00:00"], // 1 day
|
|
113
|
-
[90061000, "25:01:01"], // 25 hours 1 minute 1 second
|
|
114
|
-
])("millisecondsToHMS(%i) should return %s", (input, expected) => {
|
|
115
|
-
expect(millisecondsToHMS(input)).toBe(expected);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
describe("real world examples", () => {
|
|
120
|
-
test("should handle common video durations", () => {
|
|
121
|
-
expect(millisecondsToHMS(30000)).toBe("30"); // 30 second video
|
|
122
|
-
expect(millisecondsToHMS(300000)).toBe("5:00"); // 5 minute video
|
|
123
|
-
expect(millisecondsToHMS(1800000)).toBe("30:00"); // 30 minute video
|
|
124
|
-
expect(millisecondsToHMS(5400000)).toBe("1:30:00"); // 1.5 hour movie
|
|
125
|
-
expect(millisecondsToHMS(7200000)).toBe("2:00:00"); // 2 hour movie
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
test("should handle common music track durations", () => {
|
|
129
|
-
expect(millisecondsToHMS(180000)).toBe("3:00"); // 3 minute song
|
|
130
|
-
expect(millisecondsToHMS(213000)).toBe("3:33"); // 3:33 song
|
|
131
|
-
expect(millisecondsToHMS(267000)).toBe("4:27"); // 4:27 song
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
test("should handle timer/stopwatch use cases", () => {
|
|
135
|
-
expect(millisecondsToHMS(5000)).toBe("5"); // 5 second countdown
|
|
136
|
-
expect(millisecondsToHMS(300000)).toBe("5:00"); // 5 minute timer
|
|
137
|
-
expect(millisecondsToHMS(900000)).toBe("15:00"); // 15 minute timer
|
|
138
|
-
expect(millisecondsToHMS(3600000)).toBe("1:00:00"); // 1 hour timer
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
test("should handle workout/exercise durations", () => {
|
|
142
|
-
expect(millisecondsToHMS(45000)).toBe("45"); // 45 second exercise
|
|
143
|
-
expect(millisecondsToHMS(90000)).toBe("1:30"); // 90 second rest
|
|
144
|
-
expect(millisecondsToHMS(1800000)).toBe("30:00"); // 30 minute workout
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
describe("type safety and consistency", () => {
|
|
149
|
-
test("should always return string type", () => {
|
|
150
|
-
expect(typeof millisecondsToHMS(0)).toBe("string");
|
|
151
|
-
expect(typeof millisecondsToHMS(1000)).toBe("string");
|
|
152
|
-
expect(typeof millisecondsToHMS(3600000)).toBe("string");
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
test("should handle consecutive calls consistently", () => {
|
|
156
|
-
const testValue = 3661000;
|
|
157
|
-
const result1 = millisecondsToHMS(testValue);
|
|
158
|
-
const result2 = millisecondsToHMS(testValue);
|
|
159
|
-
expect(result1).toBe(result2);
|
|
160
|
-
expect(result1).toBe("1:01:01");
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
test("should not mutate input or have side effects", () => {
|
|
164
|
-
const originalValue = 3661000;
|
|
165
|
-
const valueCopy = originalValue;
|
|
166
|
-
const result = millisecondsToHMS(originalValue);
|
|
167
|
-
expect(originalValue).toBe(valueCopy);
|
|
168
|
-
expect(result).toBe("1:01:01");
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
describe("format validation", () => {
|
|
173
|
-
test("seconds only format should be numeric string", () => {
|
|
174
|
-
const result = millisecondsToHMS(5000);
|
|
175
|
-
expect(result).toMatch(/^\d+$/);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
test("minutes format should be M:SS", () => {
|
|
179
|
-
const result = millisecondsToHMS(90000);
|
|
180
|
-
expect(result).toMatch(/^\d+:\d{2}$/);
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
test("hours format should be H:MM:SS", () => {
|
|
184
|
-
const result = millisecondsToHMS(3661000);
|
|
185
|
-
expect(result).toMatch(/^\d+:\d{2}:\d{2}$/);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
test("should never return negative values", () => {
|
|
189
|
-
// Even though function doesn't handle negative input explicitly,
|
|
190
|
-
// we test current behavior
|
|
191
|
-
const results = [
|
|
192
|
-
millisecondsToHMS(0),
|
|
193
|
-
millisecondsToHMS(1000),
|
|
194
|
-
millisecondsToHMS(60000),
|
|
195
|
-
millisecondsToHMS(3600000),
|
|
196
|
-
];
|
|
197
|
-
|
|
198
|
-
results.forEach((result) => {
|
|
199
|
-
expect(result).not.toMatch(/-/);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
test("should maintain consistent padding", () => {
|
|
204
|
-
expect(millisecondsToHMS(3605000)).toBe("1:00:05"); // H:MM:SS
|
|
205
|
-
expect(millisecondsToHMS(3065000)).toBe("51:05"); // M:SS when < 1 hour
|
|
206
|
-
expect(millisecondsToHMS(65000)).toBe("1:05"); // M:SS
|
|
207
|
-
});
|
|
208
|
-
});
|
|
209
|
-
});
|