@ooneex/utils 0.0.6 → 0.0.8

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 (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +539 -203
  3. package/dist/index.d.ts +23 -16
  4. package/dist/index.js +3 -1
  5. package/dist/index.js.map +24 -0
  6. package/dist/ooneex-utils-0.0.8.tgz +0 -0
  7. package/package.json +23 -13
  8. package/dist/capitalizeWord.d.ts +0 -2
  9. package/dist/capitalizeWord.d.ts.map +0 -1
  10. package/dist/dataURLtoFile.d.ts +0 -2
  11. package/dist/dataURLtoFile.d.ts.map +0 -1
  12. package/dist/formatRelativeNumber.d.ts +0 -5
  13. package/dist/formatRelativeNumber.d.ts.map +0 -1
  14. package/dist/index.d.ts.map +0 -1
  15. package/dist/millisecondsToHMS.d.ts +0 -2
  16. package/dist/millisecondsToHMS.d.ts.map +0 -1
  17. package/dist/parseEnvVars.d.ts +0 -2
  18. package/dist/parseEnvVars.d.ts.map +0 -1
  19. package/dist/parseString.d.ts +0 -2
  20. package/dist/parseString.d.ts.map +0 -1
  21. package/dist/random.d.ts +0 -6
  22. package/dist/random.d.ts.map +0 -1
  23. package/dist/secondsToHMS.d.ts +0 -2
  24. package/dist/secondsToHMS.d.ts.map +0 -1
  25. package/dist/secondsToMS.d.ts +0 -2
  26. package/dist/secondsToMS.d.ts.map +0 -1
  27. package/dist/sleep.d.ts +0 -2
  28. package/dist/sleep.d.ts.map +0 -1
  29. package/dist/splitToWords.d.ts +0 -2
  30. package/dist/splitToWords.d.ts.map +0 -1
  31. package/dist/toCamelCase.d.ts +0 -2
  32. package/dist/toCamelCase.d.ts.map +0 -1
  33. package/dist/toKebabCase.d.ts +0 -2
  34. package/dist/toKebabCase.d.ts.map +0 -1
  35. package/dist/toPascalCase.d.ts +0 -2
  36. package/dist/toPascalCase.d.ts.map +0 -1
  37. package/dist/trim.d.ts +0 -2
  38. package/dist/trim.d.ts.map +0 -1
  39. package/src/capitalizeWord.ts +0 -3
  40. package/src/dataURLtoFile.ts +0 -12
  41. package/src/formatRelativeNumber.ts +0 -7
  42. package/src/index.ts +0 -15
  43. package/src/millisecondsToHMS.ts +0 -16
  44. package/src/parseEnvVars.ts +0 -14
  45. package/src/parseString.ts +0 -47
  46. package/src/random.ts +0 -13
  47. package/src/secondsToHMS.ts +0 -16
  48. package/src/secondsToMS.ts +0 -5
  49. package/src/sleep.ts +0 -3
  50. package/src/splitToWords.ts +0 -14
  51. package/src/toCamelCase.ts +0 -8
  52. package/src/toKebabCase.ts +0 -6
  53. package/src/toPascalCase.ts +0 -7
  54. package/src/trim.ts +0 -8
  55. package/tests/capitalizeWord.spec.ts +0 -163
  56. package/tests/dataURLtoFile.spec.ts +0 -472
  57. package/tests/formatRelativeNumber.spec.ts +0 -303
  58. package/tests/millisecondsToHMS.spec.ts +0 -209
  59. package/tests/parseEnvVars.spec.ts +0 -468
  60. package/tests/parseString.spec.ts +0 -377
  61. package/tests/random.spec.ts +0 -422
  62. package/tests/secondsToHMS.spec.ts +0 -341
  63. package/tests/secondsToMS.spec.ts +0 -467
  64. package/tests/splitToWords.spec.ts +0 -359
  65. package/tests/toCamelCase.spec.ts +0 -526
  66. package/tests/toKebabCase.spec.ts +0 -664
  67. package/tests/toPascalCase.spec.ts +0 -721
  68. package/tests/trim.spec.ts +0 -486
  69. package/tsconfig.build.json +0 -14
  70. package/tsconfig.json +0 -11
@@ -1,163 +0,0 @@
1
- import { describe, expect, test } from "bun:test";
2
- import { capitalizeWord } from "@/index";
3
-
4
- describe("capitalizeWord", () => {
5
- describe("basic functionality", () => {
6
- test("should capitalize first letter of lowercase word", () => {
7
- expect(capitalizeWord("hello")).toBe("Hello");
8
- });
9
-
10
- test("should capitalize first letter and lowercase the rest", () => {
11
- expect(capitalizeWord("hELLO")).toBe("Hello");
12
- });
13
-
14
- test("should handle single character", () => {
15
- expect(capitalizeWord("a")).toBe("A");
16
- });
17
-
18
- test("should handle uppercase single character", () => {
19
- expect(capitalizeWord("A")).toBe("A");
20
- });
21
-
22
- test("should handle already capitalized word", () => {
23
- expect(capitalizeWord("Hello")).toBe("Hello");
24
- });
25
-
26
- test("should handle mixed case word", () => {
27
- expect(capitalizeWord("hElLo")).toBe("Hello");
28
- });
29
- });
30
-
31
- describe("edge cases", () => {
32
- test("should return empty string when input is empty", () => {
33
- expect(capitalizeWord("")).toBe("");
34
- });
35
-
36
- test("should handle words with numbers", () => {
37
- expect(capitalizeWord("hello123")).toBe("Hello123");
38
- });
39
-
40
- test("should handle words starting with numbers", () => {
41
- expect(capitalizeWord("123hello")).toBe("123hello");
42
- });
43
-
44
- test("should handle special characters", () => {
45
- expect(capitalizeWord("!hello")).toBe("!hello");
46
- });
47
-
48
- test("should handle words with special characters", () => {
49
- expect(capitalizeWord("hello-world")).toBe("Hello-world");
50
- });
51
-
52
- test("should handle accented characters", () => {
53
- expect(capitalizeWord("école")).toBe("École");
54
- });
55
-
56
- test("should handle non-latin characters", () => {
57
- expect(capitalizeWord("привет")).toBe("Привет");
58
- });
59
- });
60
-
61
- describe("whitespace handling", () => {
62
- test("should handle words with leading spaces", () => {
63
- expect(capitalizeWord(" hello")).toBe(" hello");
64
- });
65
-
66
- test("should handle words with trailing spaces", () => {
67
- expect(capitalizeWord("hello ")).toBe("Hello ");
68
- });
69
-
70
- test("should handle single space", () => {
71
- expect(capitalizeWord(" ")).toBe(" ");
72
- });
73
-
74
- test("should handle multiple spaces", () => {
75
- expect(capitalizeWord(" ")).toBe(" ");
76
- });
77
-
78
- test("should handle tab character", () => {
79
- expect(capitalizeWord("\t")).toBe("\t");
80
- });
81
-
82
- test("should handle newline character", () => {
83
- expect(capitalizeWord("\n")).toBe("\n");
84
- });
85
- });
86
-
87
- describe("parametrized tests", () => {
88
- test.each([
89
- ["word", "Word"],
90
- ["WORD", "Word"],
91
- ["wORD", "Word"],
92
- ["test", "Test"],
93
- ["javascript", "Javascript"],
94
- ["typescript", "Typescript"],
95
- ["react", "React"],
96
- ])("capitalizeWord(%s) should return %s", (input, expected) => {
97
- expect(capitalizeWord(input)).toBe(expected);
98
- });
99
- });
100
-
101
- describe("type safety", () => {
102
- test("should handle very long strings", () => {
103
- const longString = "a".repeat(1000);
104
- const result = capitalizeWord(longString);
105
- expect(result).toHaveLength(1000);
106
- expect(result[0]).toBe("A");
107
- expect(result.slice(1)).toBe("a".repeat(999));
108
- });
109
-
110
- test("should handle unicode characters", () => {
111
- expect(capitalizeWord("émile")).toBe("Émile");
112
- expect(capitalizeWord("ñoño")).toBe("Ñoño");
113
- expect(capitalizeWord("café")).toBe("Café");
114
- });
115
-
116
- test("should handle emoji", () => {
117
- expect(capitalizeWord("😀hello")).toBe("😀hello");
118
- expect(capitalizeWord("hello😀")).toBe("Hello😀");
119
- });
120
- });
121
-
122
- describe("function behavior", () => {
123
- test("should not mutate original string", () => {
124
- const original = "hello";
125
- const result = capitalizeWord(original);
126
- expect(original).toBe("hello");
127
- expect(result).toBe("Hello");
128
- });
129
-
130
- test("should return string type", () => {
131
- const result = capitalizeWord("test");
132
- expect(typeof result).toBe("string");
133
- });
134
-
135
- test("should handle consecutive calls consistently", () => {
136
- const word = "hello";
137
- const result1 = capitalizeWord(word);
138
- const result2 = capitalizeWord(word);
139
- expect(result1).toBe(result2);
140
- expect(result1).toBe("Hello");
141
- });
142
- });
143
-
144
- describe("real world examples", () => {
145
- test("should capitalize common names", () => {
146
- expect(capitalizeWord("john")).toBe("John");
147
- expect(capitalizeWord("mary")).toBe("Mary");
148
- expect(capitalizeWord("david")).toBe("David");
149
- });
150
-
151
- test("should handle programming terms", () => {
152
- expect(capitalizeWord("function")).toBe("Function");
153
- expect(capitalizeWord("variable")).toBe("Variable");
154
- expect(capitalizeWord("method")).toBe("Method");
155
- });
156
-
157
- test("should handle common words", () => {
158
- expect(capitalizeWord("the")).toBe("The");
159
- expect(capitalizeWord("and")).toBe("And");
160
- expect(capitalizeWord("but")).toBe("But");
161
- });
162
- });
163
- });
@@ -1,472 +0,0 @@
1
- import { describe, expect, test } from "bun:test";
2
- import { dataURLtoFile } from "@/index";
3
-
4
- describe("dataURLtoFile", () => {
5
- describe("basic functionality", () => {
6
- test("should convert a simple text data URL to a File", () => {
7
- const dataUrl = "data:text/plain;base64,SGVsbG8gV29ybGQ=";
8
- const filename = "test.txt";
9
-
10
- const file = dataURLtoFile(dataUrl, filename);
11
-
12
- expect(file).toBeInstanceOf(File);
13
- expect(file.name).toBe(filename);
14
- expect(file.type).toMatch(/^text\/plain(;.*)?$/);
15
- expect(file.size).toBe(11); // "Hello World" is 11 bytes
16
- });
17
-
18
- test("should convert an image data URL to a File", () => {
19
- // Simple 1x1 red pixel PNG
20
- const dataUrl =
21
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
22
- const filename = "pixel.png";
23
-
24
- const file = dataURLtoFile(dataUrl, filename);
25
-
26
- expect(file).toBeInstanceOf(File);
27
- expect(file.name).toBe(filename);
28
- expect(file.type).toBe("image/png");
29
- expect(file.size).toBeGreaterThan(0);
30
- });
31
-
32
- test("should convert a JSON data URL to a File", () => {
33
- const jsonData = JSON.stringify({ message: "test", value: 123 });
34
- const base64Data = btoa(jsonData);
35
- const dataUrl = `data:application/json;base64,${base64Data}`;
36
- const filename = "data.json";
37
-
38
- const file = dataURLtoFile(dataUrl, filename);
39
-
40
- expect(file).toBeInstanceOf(File);
41
- expect(file.name).toBe(filename);
42
- expect(file.type).toMatch(/^application\/json(;.*)?$/);
43
- expect(file.size).toBe(jsonData.length);
44
- });
45
-
46
- test("should preserve the original filename", () => {
47
- const dataUrl = "data:text/plain;base64,dGVzdA==";
48
- const filename = "custom-filename.txt";
49
-
50
- const file = dataURLtoFile(dataUrl, filename);
51
-
52
- expect(file.name).toBe(filename);
53
- });
54
- });
55
-
56
- describe("mime type handling", () => {
57
- test("should extract correct mime type from data URL", () => {
58
- const testCases = [
59
- { dataUrl: "data:image/jpeg;base64,/9j/4AAQ", expectedType: "image/jpeg" },
60
- { dataUrl: "data:application/pdf;base64,JVBERi0x", expectedType: "application/pdf" },
61
- { dataUrl: "data:video/mp4;base64,AAAAIGZ0eXA=", expectedType: "video/mp4" },
62
- { dataUrl: "data:audio/mpeg;base64,SUQzAwAAAAA=", expectedType: "audio/mpeg" },
63
- { dataUrl: "data:text/html;base64,PGh0bWw+", expectedType: "text/html" },
64
- { dataUrl: "data:text/css;base64,Ym9keSB7", expectedType: "text/css" },
65
- { dataUrl: "data:text/javascript;base64,Y29uc29sZS5sb2c=", expectedType: "text/javascript" },
66
- ];
67
-
68
- testCases.forEach(({ dataUrl, expectedType }) => {
69
- const file = dataURLtoFile(dataUrl, "test");
70
- expect(file.type).toMatch(new RegExp(`^${expectedType.replace(/[+/]/g, "\\$&")}(;.*)?$`));
71
- });
72
- });
73
-
74
- test("should handle data URL with charset parameter", () => {
75
- const dataUrl = "data:text/plain;charset=utf-8;base64,SGVsbG8gV29ybGQ=";
76
- const filename = "test.txt";
77
-
78
- const file = dataURLtoFile(dataUrl, filename);
79
-
80
- expect(file.type).toMatch(/^text\/plain(;.*)?$/);
81
- });
82
-
83
- test("should handle malformed mime type gracefully", () => {
84
- const dataUrl = "data:invalid-mime-type;base64,dGVzdA==";
85
- const filename = "test";
86
-
87
- const file = dataURLtoFile(dataUrl, filename);
88
-
89
- expect(file).toBeInstanceOf(File);
90
- expect(file.type).toBe("invalid-mime-type");
91
- });
92
-
93
- test("should handle data URL without explicit mime type", () => {
94
- const dataUrl = "data:;base64,dGVzdA==";
95
- const filename = "test.txt";
96
-
97
- const file = dataURLtoFile(dataUrl, filename);
98
-
99
- expect(file).toBeInstanceOf(File);
100
- expect(file.name).toBe(filename);
101
- expect(file.type).toBe("");
102
- });
103
- });
104
-
105
- describe("base64 decoding", () => {
106
- test("should correctly decode base64 data", async () => {
107
- const originalText = "Hello, World! This is a test string.";
108
- const base64Data = btoa(originalText);
109
- const dataUrl = `data:text/plain;base64,${base64Data}`;
110
- const filename = "test.txt";
111
-
112
- const file = dataURLtoFile(dataUrl, filename);
113
- const decodedText = await file.text();
114
-
115
- expect(decodedText).toBe(originalText);
116
- });
117
-
118
- test("should handle empty base64 data", () => {
119
- const dataUrl = "data:text/plain;base64,";
120
- const filename = "empty.txt";
121
-
122
- const file = dataURLtoFile(dataUrl, filename);
123
-
124
- expect(file).toBeInstanceOf(File);
125
- expect(file.size).toBe(0);
126
- });
127
-
128
- test("should handle base64 data with padding", () => {
129
- const testCases = [
130
- { data: "YQ==", expected: "a" }, // 1 char with padding
131
- { data: "YWI=", expected: "ab" }, // 2 chars with padding
132
- { data: "YWJj", expected: "abc" }, // 3 chars no padding
133
- { data: "YWJjZA==", expected: "abcd" }, // 4 chars with padding
134
- ];
135
-
136
- testCases.forEach(({ data, expected }) => {
137
- const dataUrl = `data:text/plain;base64,${data}`;
138
- const file = dataURLtoFile(dataUrl, "test.txt");
139
- expect(file.size).toBe(expected.length);
140
- });
141
- });
142
-
143
- test("should handle Unicode characters properly when base64 encoded", async () => {
144
- // Use a simple ASCII string first to avoid btoa Unicode issues
145
- const asciiText = "Hello World 123!";
146
- const base64Data = btoa(asciiText);
147
- const dataUrl = `data:text/plain;base64,${base64Data}`;
148
- const filename = "ascii.txt";
149
-
150
- const file = dataURLtoFile(dataUrl, filename);
151
- const decodedText = await file.text();
152
-
153
- expect(decodedText).toBe(asciiText);
154
- });
155
- });
156
-
157
- describe("edge cases", () => {
158
- test("should handle very long filenames", () => {
159
- const dataUrl = "data:text/plain;base64,dGVzdA==";
160
- const longFilename = `${"a".repeat(255)}.txt`;
161
-
162
- const file = dataURLtoFile(dataUrl, longFilename);
163
-
164
- expect(file.name).toBe(longFilename);
165
- });
166
-
167
- test("should handle special characters in filename", () => {
168
- const dataUrl = "data:text/plain;base64,dGVzdA==";
169
- const specialFilename = "test file with spaces & symbols!@#$%^&*()_+.txt";
170
-
171
- const file = dataURLtoFile(dataUrl, specialFilename);
172
-
173
- expect(file.name).toBe(specialFilename);
174
- });
175
-
176
- test("should handle binary data correctly", () => {
177
- // Create a simple binary data string that works with btoa
178
- const binaryData = String.fromCharCode(0, 1, 2, 3, 127, 126, 125);
179
- const base64Data = btoa(binaryData);
180
- const dataUrl = `data:application/octet-stream;base64,${base64Data}`;
181
- const filename = "binary.dat";
182
-
183
- const file = dataURLtoFile(dataUrl, filename);
184
-
185
- expect(file).toBeInstanceOf(File);
186
- expect(file.type).toBe("application/octet-stream");
187
- expect(file.size).toBe(binaryData.length);
188
- });
189
-
190
- test("should handle data URL with multiple parameters", () => {
191
- const dataUrl = "data:text/plain;charset=utf-8;boundary=something;base64,dGVzdA==";
192
- const filename = "test.txt";
193
-
194
- const file = dataURLtoFile(dataUrl, filename);
195
-
196
- expect(file).toBeInstanceOf(File);
197
- expect(file.type).toMatch(/^text\/plain(;.*)?$/);
198
- });
199
- });
200
-
201
- describe("malformed input handling", () => {
202
- test("should handle data URL with only header", () => {
203
- const dataUrl = "data:text/plain;base64,";
204
- const filename = "test.txt";
205
-
206
- const file = dataURLtoFile(dataUrl, filename);
207
-
208
- expect(file).toBeInstanceOf(File);
209
- expect(file.size).toBe(0);
210
- });
211
-
212
- test("should handle data URL with missing parts", () => {
213
- const dataUrl = "data:text/plain";
214
- const filename = "test.txt";
215
-
216
- // This will likely fail due to invalid base64, but shouldn't crash the function structure
217
- expect(() => {
218
- dataURLtoFile(dataUrl, filename);
219
- }).toThrow();
220
- });
221
-
222
- test("should handle invalid base64 data", () => {
223
- const dataUrl = "data:text/plain;base64,invalid!!!base64!!!";
224
- const filename = "test.txt";
225
-
226
- expect(() => {
227
- dataURLtoFile(dataUrl, filename);
228
- }).toThrow();
229
- });
230
- });
231
-
232
- describe("file properties validation", () => {
233
- test("should create file with correct properties", () => {
234
- const dataUrl =
235
- "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8A8A";
236
- const filename = "image.jpg";
237
-
238
- const file = dataURLtoFile(dataUrl, filename);
239
-
240
- expect(file.name).toBe(filename);
241
- expect(file.type).toBe("image/jpeg");
242
- expect(file.size).toBeGreaterThan(0);
243
- expect(file.lastModified).toBeTypeOf("number");
244
- expect(Math.abs(file.lastModified - Date.now())).toBeLessThan(1000);
245
- });
246
-
247
- test("should create file with ArrayBuffer content", async () => {
248
- const dataUrl = "data:application/octet-stream;base64,AAECAw=="; // [0, 1, 2, 3]
249
- const filename = "test.bin";
250
-
251
- const file = dataURLtoFile(dataUrl, filename);
252
- const arrayBuffer = await file.arrayBuffer();
253
- const uint8Array = new Uint8Array(arrayBuffer);
254
-
255
- expect(Array.from(uint8Array)).toEqual([0, 1, 2, 3]);
256
- });
257
-
258
- test("should allow reading file as different types", async () => {
259
- const originalText = "Hello, World!";
260
- const base64Data = btoa(originalText);
261
- const dataUrl = `data:text/plain;base64,${base64Data}`;
262
- const filename = "test.txt";
263
-
264
- const file = dataURLtoFile(dataUrl, filename);
265
-
266
- // Test reading as text
267
- const text = await file.text();
268
- expect(text).toBe(originalText);
269
-
270
- // Test reading as array buffer
271
- const arrayBuffer = await file.arrayBuffer();
272
- expect(arrayBuffer).toBeInstanceOf(ArrayBuffer);
273
- expect(arrayBuffer.byteLength).toBe(originalText.length);
274
-
275
- // Test creating blob URL
276
- const blobUrl = URL.createObjectURL(file);
277
- expect(typeof blobUrl).toBe("string");
278
- expect(blobUrl.startsWith("blob:")).toBe(true);
279
-
280
- // Clean up
281
- URL.revokeObjectURL(blobUrl);
282
- });
283
- });
284
-
285
- describe("real world scenarios", () => {
286
- test("should handle typical image upload scenario", () => {
287
- // Simulate a small PNG image data URL
288
- const dataUrl =
289
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
290
- const filename = "profile-picture.png";
291
-
292
- const file = dataURLtoFile(dataUrl, filename);
293
-
294
- expect(file.name).toBe(filename);
295
- expect(file.type).toBe("image/png");
296
- expect(file.size).toBeGreaterThan(0);
297
- });
298
-
299
- test("should handle PDF document conversion", () => {
300
- // Simple PDF header
301
- const pdfData = btoa("%PDF-1.4");
302
- const dataUrl = `data:application/pdf;base64,${pdfData}`;
303
- const filename = "document.pdf";
304
-
305
- const file = dataURLtoFile(dataUrl, filename);
306
-
307
- expect(file.name).toBe(filename);
308
- expect(file.type).toBe("application/pdf");
309
- expect(file.size).toBe(8); // "%PDF-1.4" is 8 characters
310
- });
311
-
312
- test("should handle CSV data export", () => {
313
- const csvData = "Name,Age,Email\nJohn,30,john@example.com\nJane,25,jane@example.com";
314
- const base64Data = btoa(csvData);
315
- const dataUrl = `data:text/csv;base64,${base64Data}`;
316
- const filename = "export.csv";
317
-
318
- const file = dataURLtoFile(dataUrl, filename);
319
-
320
- expect(file.name).toBe(filename);
321
- expect(file.type).toBe("text/csv");
322
- expect(file.size).toBe(csvData.length);
323
- });
324
-
325
- test("should handle canvas image export", () => {
326
- // Simulate canvas.toDataURL() result
327
- const canvasDataUrl =
328
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFYSURBVBiVY/z//z8DJQAggJiYmBj+//8PJv7//w9WB+aD2WA+iA3mg9lgPpgN5oPZYD6YDeaD2WA+mA3mg9lgPpgN5oPZYD6YDeaD2WA+mA3mg9lgPpgN5oPZYD6YDeaD2WA+mA3mg9lgPpgN5oPZYD6YDeaD2WA+mA3mg9lgPpgN5oPZYD6YDeaD2WA+mA3mg9lgPpgN5oPZYD6YDeaD2WA+mA3mg9lgPpgN5oPZYD6YDeaD2WA+mA3mg9lgPpgN5oPZYD6YDeaD2WA+mA3mg9lgPpgN5oPZYD6YDeaD2WA+mA3mg9lgPpgN5oPZYD6YDeaD2WA+mA3mg9lgPpgN5oPZYD6YDeaD2WA+mA3mg9lgPpgN5oPZYD6YDeaD2WA+mA3mg9lgPpgN5oPZYD6YDeaD2WA+mA3mg9lg/n8AAwMDAAAAAElFTkSuQmCC";
329
- const filename = "drawing.png";
330
-
331
- const file = dataURLtoFile(canvasDataUrl, filename);
332
-
333
- expect(file.name).toBe(filename);
334
- expect(file.type).toBe("image/png");
335
- expect(file.size).toBeGreaterThan(100); // Should be a reasonable size for an image
336
- });
337
- });
338
-
339
- describe("parametrized tests", () => {
340
- test.each([
341
- ["text/plain", "SGVsbG8=", "Hello"],
342
- ["text/html", "PGh0bWw+PC9odG1sPg==", "<html></html>"],
343
- ["application/json", "eyJrZXkiOiJ2YWx1ZSJ9", '{"key":"value"}'],
344
- ["image/svg+xml", "PHN2Zz48L3N2Zz4=", "<svg></svg>"],
345
- ])("should handle %s mime type correctly", async (mimeType, base64Data, expectedContent) => {
346
- const dataUrl = `data:${mimeType};base64,${base64Data}`;
347
- const filename = `test.${mimeType.split("/")[1]}`;
348
-
349
- const file = dataURLtoFile(dataUrl, filename);
350
- const content = await file.text();
351
-
352
- expect(file.type).toMatch(new RegExp(`^${mimeType.replace(/[+/]/g, "\\$&")}(;.*)?$`));
353
- expect(content).toBe(expectedContent);
354
- });
355
-
356
- test.each([
357
- ["test.txt"],
358
- ["my-file.pdf"],
359
- ["image_01.jpg"],
360
- ["document with spaces.docx"],
361
- ["file.with.multiple.dots.txt"],
362
- ["🎉emoji-filename.txt"],
363
- ])("should preserve filename: %s", (filename) => {
364
- const dataUrl = "data:text/plain;base64,dGVzdA==";
365
- const file = dataURLtoFile(dataUrl, filename);
366
- expect(file.name).toBe(filename);
367
- });
368
- });
369
-
370
- describe("integration with File API", () => {
371
- test("should work with FormData", () => {
372
- const dataUrl = "data:text/plain;base64,SGVsbG8gV29ybGQ=";
373
- const filename = "test.txt";
374
- const file = dataURLtoFile(dataUrl, filename);
375
-
376
- const formData = new FormData();
377
- formData.append("file", file);
378
-
379
- const retrievedFile = formData.get("file") as File;
380
- expect(retrievedFile).toBeInstanceOf(File);
381
- expect(retrievedFile.name).toBe(filename);
382
- });
383
-
384
- test("should be compatible with URL.createObjectURL", () => {
385
- const dataUrl =
386
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
387
- const filename = "pixel.png";
388
- const file = dataURLtoFile(dataUrl, filename);
389
-
390
- const objectUrl = URL.createObjectURL(file);
391
-
392
- expect(typeof objectUrl).toBe("string");
393
- expect(objectUrl.startsWith("blob:")).toBe(true);
394
-
395
- // Clean up
396
- URL.revokeObjectURL(objectUrl);
397
- });
398
-
399
- test("should work with file size limits", () => {
400
- const dataUrl = "data:text/plain;base64,dGVzdA=="; // "test" = 4 bytes
401
- const filename = "small.txt";
402
- const file = dataURLtoFile(dataUrl, filename);
403
-
404
- const maxSize = 10;
405
- expect(file.size <= maxSize).toBe(true);
406
- });
407
- });
408
-
409
- describe("performance considerations", () => {
410
- test("should handle reasonably large files", () => {
411
- // Create a larger base64 string (about 1KB)
412
- const largeText = "A".repeat(1000);
413
- const base64Data = btoa(largeText);
414
- const dataUrl = `data:text/plain;base64,${base64Data}`;
415
- const filename = "large.txt";
416
-
417
- const startTime = performance.now();
418
- const file = dataURLtoFile(dataUrl, filename);
419
- const endTime = performance.now();
420
-
421
- expect(file).toBeInstanceOf(File);
422
- expect(file.size).toBe(1000);
423
- expect(endTime - startTime).toBeLessThan(100); // Should be fast
424
- });
425
-
426
- test("should create independent files from same data", () => {
427
- const dataUrl = "data:text/plain;base64,SGVsbG8=";
428
-
429
- const file1 = dataURLtoFile(dataUrl, "file1.txt");
430
- const file2 = dataURLtoFile(dataUrl, "file2.txt");
431
-
432
- expect(file1).not.toBe(file2); // Different objects
433
- expect(file1.name).toBe("file1.txt");
434
- expect(file2.name).toBe("file2.txt");
435
- expect(file1.size).toBe(file2.size);
436
- expect(file1.type).toBe(file2.type);
437
- });
438
- });
439
-
440
- describe("limitations and constraints", () => {
441
- test("should document base64 requirement", () => {
442
- // This function specifically requires base64 encoded data
443
- const validDataUrl = "data:text/plain;base64,SGVsbG8=";
444
-
445
- expect(() => {
446
- dataURLtoFile(validDataUrl, "test.txt");
447
- }).not.toThrow();
448
- });
449
-
450
- test("should handle mime type extraction correctly", () => {
451
- // The function uses a regex to extract mime type between : and ;
452
- const dataUrl = "data:custom/type;param=value;base64,dGVzdA==";
453
- const file = dataURLtoFile(dataUrl, "test");
454
-
455
- expect(file.type).toBe("custom/type");
456
- });
457
-
458
- test("should create Uint8Array internally", async () => {
459
- const dataUrl = "data:application/octet-stream;base64,AAECAw==";
460
- const file = dataURLtoFile(dataUrl, "test.bin");
461
-
462
- const buffer = await file.arrayBuffer();
463
- const uint8Array = new Uint8Array(buffer);
464
-
465
- // Verify the internal Uint8Array was created correctly
466
- expect(uint8Array[0]).toBe(0);
467
- expect(uint8Array[1]).toBe(1);
468
- expect(uint8Array[2]).toBe(2);
469
- expect(uint8Array[3]).toBe(3);
470
- });
471
- });
472
- });