@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.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +539 -203
  3. package/dist/index.d.ts +24 -16
  4. package/dist/index.js +3 -1
  5. package/dist/index.js.map +25 -0
  6. package/package.json +22 -14
  7. package/dist/capitalizeWord.d.ts +0 -2
  8. package/dist/capitalizeWord.d.ts.map +0 -1
  9. package/dist/dataURLtoFile.d.ts +0 -2
  10. package/dist/dataURLtoFile.d.ts.map +0 -1
  11. package/dist/formatRelativeNumber.d.ts +0 -5
  12. package/dist/formatRelativeNumber.d.ts.map +0 -1
  13. package/dist/index.d.ts.map +0 -1
  14. package/dist/millisecondsToHMS.d.ts +0 -2
  15. package/dist/millisecondsToHMS.d.ts.map +0 -1
  16. package/dist/parseEnvVars.d.ts +0 -2
  17. package/dist/parseEnvVars.d.ts.map +0 -1
  18. package/dist/parseString.d.ts +0 -2
  19. package/dist/parseString.d.ts.map +0 -1
  20. package/dist/random.d.ts +0 -6
  21. package/dist/random.d.ts.map +0 -1
  22. package/dist/secondsToHMS.d.ts +0 -2
  23. package/dist/secondsToHMS.d.ts.map +0 -1
  24. package/dist/secondsToMS.d.ts +0 -2
  25. package/dist/secondsToMS.d.ts.map +0 -1
  26. package/dist/sleep.d.ts +0 -2
  27. package/dist/sleep.d.ts.map +0 -1
  28. package/dist/splitToWords.d.ts +0 -2
  29. package/dist/splitToWords.d.ts.map +0 -1
  30. package/dist/toCamelCase.d.ts +0 -2
  31. package/dist/toCamelCase.d.ts.map +0 -1
  32. package/dist/toKebabCase.d.ts +0 -2
  33. package/dist/toKebabCase.d.ts.map +0 -1
  34. package/dist/toPascalCase.d.ts +0 -2
  35. package/dist/toPascalCase.d.ts.map +0 -1
  36. package/dist/trim.d.ts +0 -2
  37. package/dist/trim.d.ts.map +0 -1
  38. package/src/capitalizeWord.ts +0 -3
  39. package/src/dataURLtoFile.ts +0 -12
  40. package/src/formatRelativeNumber.ts +0 -7
  41. package/src/index.ts +0 -15
  42. package/src/millisecondsToHMS.ts +0 -16
  43. package/src/parseEnvVars.ts +0 -14
  44. package/src/parseString.ts +0 -47
  45. package/src/random.ts +0 -13
  46. package/src/secondsToHMS.ts +0 -16
  47. package/src/secondsToMS.ts +0 -5
  48. package/src/sleep.ts +0 -3
  49. package/src/splitToWords.ts +0 -14
  50. package/src/toCamelCase.ts +0 -8
  51. package/src/toKebabCase.ts +0 -6
  52. package/src/toPascalCase.ts +0 -7
  53. package/src/trim.ts +0 -8
  54. package/tests/capitalizeWord.spec.ts +0 -163
  55. package/tests/dataURLtoFile.spec.ts +0 -472
  56. package/tests/formatRelativeNumber.spec.ts +0 -303
  57. package/tests/millisecondsToHMS.spec.ts +0 -209
  58. package/tests/parseEnvVars.spec.ts +0 -468
  59. package/tests/parseString.spec.ts +0 -377
  60. package/tests/random.spec.ts +0 -422
  61. package/tests/secondsToHMS.spec.ts +0 -341
  62. package/tests/secondsToMS.spec.ts +0 -467
  63. package/tests/splitToWords.spec.ts +0 -359
  64. package/tests/toCamelCase.spec.ts +0 -526
  65. package/tests/toKebabCase.spec.ts +0 -664
  66. package/tests/toPascalCase.spec.ts +0 -721
  67. package/tests/trim.spec.ts +0 -486
  68. package/tsconfig.build.json +0 -14
  69. 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
- });