File size: 36,755 Bytes
61d39e2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
/* eslint-disable */
// TODO: Make these more compatible with eslint
naughtyStrings = [
    "文件.txt",               // Chinese characters
    "файл.txt",              // Cyrillic characters
    "ファイル.txt",           // Japanese characters
    "파일.txt",               // Korean characters
    "ملف.txt",               // Arabic characters
    "फ़ाइल.txt",             // Hindi characters
    "archivo.txt",           // Spanish characters
    "fichier.txt",           // French characters
    "αρχείο.txt",            // Greek characters
    "datei.txt",             // German characters
    "fil.txt",               // Swedish characters
    "קובץ.txt",              // Hebrew characters
    "文件名.txt",             // Chinese characters
    "файлы.txt",             // Russian characters
    "फ़ाइलें.txt",           // Hindi characters
    "📄_emoji.txt",           // Emoji
    "file name with spaces.txt",
    "file-name-with-dashes.txt",
    "file_name_with_underscores.txt",
    "file.name.with.periods.txt",
    "file,name,with,commas.txt",
    "file;name;with;semicolons.txt",
    "file(name)with(parentheses).txt",
    "file[name]with[brackets].txt",
    "file{name}with{braces}.txt",
    "file!name!with!exclamations!.txt",
    "file@name@with@ats.txt",
    "file#name#with#hashes#.txt",
    "file$name$with$dollars$.txt",
    "file%name%with%percentages%.txt",
    "file^name^with^carats^.txt",
    "file&name&with&amps&.txt",
    "file*name*with*asterisks*.txt",
    "file_name_with_long_name_exceeding_255_characters_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.txt",
    "file👍name👍with👍thumbs👍up.txt",
    "invisible\u200Bname.txt",                  // Invisible Unicode character (Zero Width Space)
    "invisible\u200Cname.txt",                  // Invisible Unicode character (Zero Width Non-Joiner)
    "invisible\u200Dname.txt",                  // Invisible Unicode character (Zero Width Joiner)
    "invisible\uFEFFname.txt",                  // Invisible Unicode character (Zero Width No-Break Space)
    "invisible\u180Ename.txt",                  // Invisible Unicode character (Mongolian Vowel Separator)
    "hash#tag.txt",
    "percent%20encoded.txt",
    "plus+sign.txt",
    "ampersand&symbol.txt",
    "at@symbol.txt",
    "parentheses(1).txt",
    "brackets[1].txt",
    "curly{braces}.txt",
    "angle<tags>.txt",
    "exclamation!point.txt",
    "question?mark.txt",
    "colon:separated.txt",
    "semicolon;separated.txt",
    "single'quote.txt",
    "double\"quote.txt",
    "backtick`char.txt",
    "tilde~sign.txt",
    "underscore_character.txt",
    "hyphen-character.txt",
    "equal=sign.txt",
    "plus+sign.txt",
    "asterisk*char.txt",
    "caret^char.txt",
    "percent%sign.txt",
    "dollar$sign.txt",
    "pound#sign.txt",
    "at@sign.txt",
    "exclamation!mark.txt",
    "question?mark.txt",
    "backslash\\char.txt",
    "pipe|char.txt",
    "colon:char.txt",
    "semicolon;char.txt",
    "quote'char.txt",
    "double\"quote.txt",
    "backtick`char.txt",
    "braces{char}.txt",
    "brackets[char].txt",
    "parentheses(char).txt",
    "angle<brackets>.txt",
    "ellipsis….txt",
    "accentué.txt",
    "ümlaut.txt",
    "tildeñ.txt",
    "çedilla.txt",
    "špecial.txt",
    "russianЯ.txt",
    "chinese中文.txt",
    "arabicعربى.txt",
    "hebrewעברית.txt",
    "japanese日本語.txt",
    "korean한국어.txt",
    "vietnameseTiếng Việt.txt",
]

window.fsTests = [
    {
        name: "testFSWrite",
        description: "Test writing text content to a new file and verify it returns a valid UID",
        test: async function() {
            try {
                let randName = puter.randName();
                const result = await puter.fs.write(randName, 'testValue');
                assert(result.uid, "Failed to write to file");
                pass("testFSWrite passed");
                // delete the file
                try {
                    await puter.fs.delete(randName);
                } catch (error) {
                    throw("testFSWrite failed to delete file:", error);
                }
            } catch (error) {
                if(puter.debugMode)
                    console.log(error);
                throw("testFSWrite failed:", error);
            }    
        }
    },
    {
        name: "testFSRead",
        description: "Test reading text content from a file and verify it matches the written content",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.write(randName, 'testValue');
                const result = await (await puter.fs.read(randName)).text();
                assert(result === 'testValue', "Failed to read from file");
                pass("testFSRead passed");
                // delete the file
                try {
                    await puter.fs.delete(randName);
                } catch (error) {
                    fail("testFSRead failed to delete file:", error);
                }
            } catch (error) {
                fail("testFSRead failed:", error);
            }    
        }
    },
    {
        name: "testFSWriteWithoutData",
        description: "Test creating an empty file without providing content data",
        test: async function() {
            try {
                let randName = puter.randName();
                const result = await puter.fs.write(randName);
                assert(result.uid, "Failed to write to file");
                pass("testFSWriteWithoutData passed");
                if(randName !== result.name) {
                    fail(`testFSWriteWithoutData failed: Names do not match ${randName} ${result.name}`);
                }
                // delete the file
                try {
                    await puter.fs.delete(randName);
                } catch (error) {
                    fail("testFSWriteWithoutData failed to delete file:", error);
                }
            } catch (error) {
                fail("testFSWriteWithoutData failed:", error);
            }    
        }
    },
    {
        name: "testFSReadWithoutData",
        description: "Test reading from an empty file and verify it returns an empty string",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.write(randName);
                const result = await (await puter.fs.read(randName)).text();
                assert(result === '', "Failed to read from file");
                pass("testFSReadWithoutData passed");
                // delete the file
                try {
                    await puter.fs.delete(randName);
                } catch (error) {
                    fail("testFSReadWithoutData failed to delete file:", error);
                }
            } catch (error) {
                fail("testFSReadWithoutData failed:", error);
            }    
        }
    },
    {
        name: "testFSWriteToExistingFile",
        description: "Test overwriting an existing file with new content",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.write(randName, 'testValue');
                const result = await puter.fs.write(randName, 'updatedValue');
                assert(result.uid, "Failed to write to file");
                pass("testFSWriteToExistingFile passed");
                // delete the file
                try {
                    await puter.fs.delete(randName);
                } catch (error) {
                    fail("testFSWriteToExistingFile failed to delete file:", error);
                }
            } catch (error) {
                fail("testFSWriteToExistingFile failed:", error);
            }    
        }
    },
    {
        name: "testFSWriteToExistingFileWithoutOverwriteAndDedupe",
        description: "Test writing to an existing file with overwrite and dedupe disabled - should fail",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.write(randName, 'testValue');
                const result = await puter.fs.write(randName, 'updatedValue', { overwrite: false, dedupeName: false });
                assert(!result.uid, "Failed to write to file");
                fail("testFSWriteToExistingFileWithoutOverwriteAndDedupe failed");
                // delete the file
                try {
                    await puter.fs.delete(randName);
                } catch (error) {
                    fail("testFSWriteToExistingFileWithoutOverwriteAndDedupe failed to delete file:", error);
                }
            } catch (error) {
                pass("testFSWriteToExistingFileWithoutOverwriteAndDedupe passed");
            }
        }
    },
    {
        name: "testFSWriteToExistingFileWithoutOverwriteButWithDedupe",
        description: "Test writing to an existing file with overwrite disabled but dedupe enabled - should create new file",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.write(randName, 'testValue');
                const result = await puter.fs.write(randName, 'updatedValue', { overwrite: false, dedupeName: true });
                assert(result.uid, "Failed to write to file");
                pass("testFSWriteToExistingFileWithoutOverwriteButWithDedupe passed");
                // delete the file
                try {
                    await puter.fs.delete(randName);
                } catch (error) {
                    fail("testFSWriteToExistingFileWithoutOverwriteButWithDedupe failed to delete file:", error);
                }
            } catch (error) {
                fail("testFSWriteToExistingFileWithoutOverwriteButWithDedupe failed:", error);
            }    
        }
    },
    {
        name: "testFSWriteToExistingFileWithOverwriteButWithoutDedupe",
        description: "Test writing to an existing file with overwrite enabled but dedupe disabled - should overwrite",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.write(randName, 'testValue');
                const result = await puter.fs.write(randName, 'updatedValue', { overwrite: true, dedupeName: false });
                assert(result.uid, "Failed to write to file");
                pass("testFSWriteToExistingFileWithOverwriteButWithoutDedupe passed");
                // delete the file
                try {
                    await puter.fs.delete(randName);
                } catch (error) {
                    fail("testFSWriteToExistingFileWithOverwriteButWithoutDedupe failed to delete file:", error);
                }
            } catch (error) {
                fail("testFSWriteToExistingFileWithOverwriteButWithoutDedupe failed:", error);
            }    
        }
    },
    {
        name: "testFSCreateDir",
        description: "Test creating a new directory and verify it returns a valid UID",
        test: async function() {
            try {
                let randName = puter.randName();
                const result = await puter.fs.mkdir(randName);
                assert(result.uid, "Failed to create directory");
                pass("testFSCreateDir passed");
            } catch (error) {
                fail("testFSCreateDir failed:", error);
            }    
        }
    },
    {
        name: "testFSReadDir",
        description: "Test reading directory contents after creating multiple files within it",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.mkdir(randName);
                await puter.fs.write(randName + '/file1', 'testValue');
                await puter.fs.write(randName + '/file2', 'testValue');
                await puter.fs.write(randName + '/file3', 'testValue');
                const result = await puter.fs.readdir(randName);
                assert(result.length === 3, "Failed to read directory");
                pass("testFSReadDir passed");
            } catch (error) {
                fail("testFSReadDir failed:", error);
            }    
        }
    },
    {
        name: "testFSDelete",
        description: "Test deleting a file and verify it no longer exists",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.write(randName, 'testValue');
                const result = await puter.fs.delete(randName);
                assert(!result.uid, "Failed to delete file");
                pass("testFSDelete passed");
            } catch (error) {
                fail("testFSDelete failed:", error);
            }    
        }
    },
    {
        name: "testFSDeleteDir",
        description: "Test deleting a directory containing multiple files",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.mkdir(randName);
                await puter.fs.write(randName + '/file1', 'testValue');
                await puter.fs.write(randName + '/file2', 'testValue');
                await puter.fs.write(randName + '/file3', 'testValue');
                const result = await puter.fs.delete(randName);
                assert(!result.uid, "Failed to delete directory");
                pass("testFSDeleteDir passed");
            } catch (error) {
                fail("testFSDeleteDir failed:", error);
            }    
        }
    },
    {
        name: "testFSDeleteNonExistentFile",
        description: "Test attempting to delete a non-existent file and verify it returns a valid response",
        test: async function() {
            try {
                let randName = puter.randName();
                const result = await puter.fs.delete(randName);
                assert(!result.uid, "Failed to delete non-existent file");
                pass("testFSDeleteNonExistentFile passed");
            } catch (error) {
                if(error.code !== "subject_does_not_exist")
                    fail("testFSDeleteNonExistentFile failed:", error);
                else
                    pass("testFSDeleteNonExistentFile passed");
            }    
        }
    },
    {
        name: "testFSReadNonExistentFile",
        description: "Test attempting to read from a non-existent file and verify it returns a valid response",
        test: async function() {
            try {
                let randName = puter.randName();
                const result = await puter.fs.read(randName);
                fail("testFSReadNonExistentFile failed");
            } catch (error) {
                if(error.code !== "subject_does_not_exist")
                    fail("testFSReadNonExistentFile failed:", error);
                else
                    pass("testFSReadNonExistentFile passed");
            }    
        }
    },
    {
        name: "testFSWriteWithSpecialCharacters",
        description: "Test writing text content to a file with special characters and verify it returns a valid UID",
        test: async function() {
            let randName
            try {
                randName = 'testFileWithSpecialCharacte rs!@#$%^&*()_+{}|:"<>?`~'
                const result = await puter.fs.write(randName, 'testValue', { specialCharacters: true });
                assert(result.uid, "Failed to write to file");
                pass("testFSWriteWithSpecialCharacters passed");
            } catch (error) {
                fail("testFSWriteWithSpecialCharacters failed:", error);
            }    

            // delete the file
            try {
                await puter.fs.delete(randName);
            } catch (error) {
                fail("testFSWriteWithSpecialCharacters failed to delete file:", error);
            }
        }
    },
    {
        name: "testFSReadWithSpecialCharacters",
        description: "Test reading text content from a file with special characters and verify it matches the written content",
        test: async function() {
            try {
                let randName = 'testFileWithSpecialCharacte rs!@#$%^&*()_+{}|:"<>?`~'
                await puter.fs.write(randName, 'testValue');
                const result = await (await puter.fs.read(randName)).text();
                assert(result === 'testValue', "Failed to read from file");
                pass("testFSReadWithSpecialCharacters passed");
            } catch (error) {
                fail("testFSReadWithSpecialCharacters failed:", error);
            }    
        }
    },
    {
        name: "testFSWriteLargeFile",
        description: "Test writing large text content to a file and verify it returns a valid UID",
        test: async function() {
            try {
                let randName = puter.randName();
                const result = await puter.fs.write(randName, 'testValue'.repeat(100000));
                assert(result.uid, "Failed to write to file");
                pass("testFSWriteLargeFile passed");
            } catch (error) {
                fail("testFSWriteLargeFile failed:", error);
            }    
        }
    },
    {
        name: "testFSReadLargeFile",
        description: "Test reading large text content from a file and verify it matches the written content",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.write(randName, 'testValue'.repeat(100000));
                const result = await (await puter.fs.read(randName)).text();
                assert(result === 'testValue'.repeat(100000), "Failed to read from file");
                pass("testFSReadLargeFile passed");
            } catch (error) {
                fail("testFSReadLargeFile failed:", error);
            }    
        }
    },
    {
        name: "testFSRenameFile",
        description: "Test renaming a file and verify the old file is gone",
        test: async function() {
            try {
                let randName = puter.randName();
                let randName2 = puter.randName();
                await puter.fs.write(randName, 'testValue');
                const result = await puter.fs.rename(randName, randName2);
                assert(result.name, "Failed to rename file");
                pass("testFSRenameFile passed");
                // check that the old file is gone
                try {
                    await puter.fs.read(randName);
                    fail("testFSRenameFile failed to delete old file");
                } catch (error) {
                    if(error.code !== "subject_does_not_exist")
                        fail("testFSRenameFile failed to delete old file:", error);
                    else
                        pass("testFSRenameFile passed");
                }
            } catch (error) {
                fail("testFSRenameFile failed:", error);
            }    
        }
    },
    {
        name: "testFSMoveFile",
        description: "Test moving a file to a new directory and verify the old file is gone",
        test: async function() {
            try {
                let randName = puter.randName();
                let randName2 = puter.randName();
                await puter.fs.write(randName, 'testValue');
                await puter.fs.mkdir(randName2);
                let result = await puter.fs.move(randName, randName2);
                assert(result.moved, "Failed to move file");
                // check that the old file is gone
                try {
                    await puter.fs.read(randName);
                    fail("testFSMoveFile failed to delete old file");
                } catch (error) {
                    if(error.code !== "subject_does_not_exist")
                        fail("testFSMoveFile failed to delete old file:", error);
                    else
                        pass("testFSMoveFile passed");
                }
            } catch (error) {
                fail("testFSMoveFile failed:", error);
            }    
        }
    },
    {
        name: "testFSCopyFile",
        description: "Test copying a file to a new directory and verify the old file is still there",
        test: async function() {
            try {
                let randName = puter.randName();
                let randName2 = puter.randName();
                await puter.fs.write(randName, 'testValue');
                await puter.fs.mkdir(randName2);
                let result = await puter.fs.copy(randName, randName2);
                assert(Array.isArray(result) && result[0].copied.uid, "Failed to copy file");
                // check that the old file is still there
                try {
                    await puter.fs.read(randName);
                    pass("testFSCopyFile passed");
                } catch (error) {
                    fail("testFSCopyFile failed to keep old file:", error);
                }
            } catch (error) {
                fail("testFSCopyFile failed:", error);
            }    
        }
    },
    {
        name: "testFSCopyFileWithNewName",
        description: "Test copying a file to a new directory with a new name and verify the old file is still there",
        test: async function() {
            try {
                let randName = puter.randName();
                let randName2 = puter.randName();
                await puter.fs.write(randName, 'testValue');
                await puter.fs.mkdir(randName2);
                let result = await puter.fs.copy(randName, randName2, { newName: 'newName' });
                assert(Array.isArray(result) && result[0].copied.uid, "Failed to copy file");
                // check file name
                assert(result[0].copied.name === 'newName', "Failed to copy file with new name");
                // check that the old file is still there
                try {
                    await puter.fs.read(randName);
                    pass("testFSCopyFileWithNewName passed");
                } catch (error) {
                    fail("testFSCopyFileWithNewName failed to keep old file:", error);
                }
            } catch (error) {
                fail("testFSCopyFileWithNewName failed:", error);
            }    
        }
    },
    {
        name: "testFSStat",
        description: "Test getting file metadata and verify it returns a valid UID",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.write(randName, 'testValue');
                let result = await puter.fs.stat(randName);
                assert(result.uid, "Failed to stat file");
                pass("testFSStat passed");
            } catch (error) {
                fail("testFSStat failed:", error);
            }    
        }
    },
    {
        name: "testFSStatDir",
        description: "Test getting directory metadata and verify it returns a valid UID",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.mkdir(randName);
                let result = await puter.fs.stat(randName);
                assert(result.uid, "Failed to stat directory");
                pass("testFSStatDir passed");
            } catch (error) {
                fail("testFSStatDir failed:", error);
            }    
        }
    },
    {
        name: "testFSStatNonExistent",
        description: "Test attempting to get metadata from a non-existent file or directory and verify it returns a valid response",
        test: async function() {
            try {
                let randName = puter.randName();
                let result = await puter.fs.stat(randName);
                fail("testFSStatNonExistent failed");
            } catch (error) {
                if(error.code !== "subject_does_not_exist")
                    fail("testFSStatNonExistent failed:", error);
                else
                    pass("testFSStatNonExistent passed");
            }    
        }
    },
    {
        name: "testFSDeleteDirWithFiles",
        description: "Test deleting a directory containing multiple files and verify it no longer exists",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.mkdir(randName);
                await puter.fs.write(randName + '/file1', 'testValue');
                await puter.fs.write(randName + '/file2', 'testValue');
                await puter.fs.write(randName + '/file3', 'testValue');
                const result = await puter.fs.delete(randName, { recursive: true });
                assert(!result.uid, "Failed to delete directory");
                pass("testFSDeleteDirWithFiles passed");
            } catch (error) {
                fail("testFSDeleteDirWithFiles failed:", error);
            }    
        }
    },
    {
        name: "testFSStatDirReturnsAttrs",
        description: "Test getting directory metadata and verifying it returns the expected attributes",
        test: async function() {
            try {
                let randName = puter.randName();
                await puter.fs.mkdir(randName);
                let result = await puter.fs.stat(randName);
                assert(result.name && typeof result.name === 'string', "Failed to stat directory (name)");
                assert(result.path && typeof result.path === 'string', "Failed to stat directory (path)");
                assert(result.immutable !== undefined, "Failed to stat directory (immutable)");
                assert(result.metadata !== undefined, "Failed to stat directory (metadata)");
                assert(result.modified !== undefined, "Failed to stat directory (modified)");
                assert(result.created !== undefined, "Failed to stat directory (created)");
                assert(result.accessed !== undefined, "Failed to stat directory (accessed)");
                assert(result.size !== undefined, "Failed to stat directory (size)");
                assert(result.layout !== undefined, "Failed to stat directory (layout)");
                assert(result.owner !== undefined && typeof result.owner === 'object', "Failed to stat directory (owner)");
                assert(result.dirname !== undefined && typeof result.dirname === 'string', "Failed to stat directory (dirname)");
                assert(result.parent_id !== undefined && typeof result.parent_id === 'string', "Failed to stat directory (parent_id)");
                // todo this will fail for now until is_dir is turned into boolean
                assert(result.is_dir !== undefined && typeof result.is_dir === 'boolean' && result.is_dir === true, "Failed to stat directory (is_dir)");
                assert(result.is_empty !== undefined && typeof result.is_empty === 'boolean', "Failed to stat directory (is_empty)");
                pass("testFSStatDirReturnsAttrs passed");
            } catch (error) {
                throw("testFSStatDirReturnsAttrs failed:", error);
            }    
        }
    },
    {
        name: "testFSReadWithWriteResult",
        description: "Test reading text content from a file using the object returned by write()",
        test: async function() {
            try {
                let randName = puter.randName();
                let writeResult = await puter.fs.write(randName, 'testValue');
                let result = await (await puter.fs.read(writeResult)).text();
                assert(result === 'testValue', "Failed to read from file");
                pass("testFSReadWithWriteResult passed");
                // delete the file
                try {
                    await puter.fs.delete(randName);
                } catch (error) {
                    fail("testFSReadWithWriteResult failed to delete file:", error);
                }
            } catch (error) {
                fail("testFSReadWithWriteResult failed:", error);
            }    
        }
    },
    {
        name: "testFSStatWithWriteResult",
        description: "Test getting file metadata using the object returned by write()",
        test: async function() {
            try {
                let randName = puter.randName();
                let writeResult = await puter.fs.write(randName, 'testValue');
                let result = await puter.fs.stat(writeResult);
                assert(result.uid, "Failed to stat file");
                pass("testFSStatWithWriteResult passed");
                // delete the file
                try {
                    await puter.fs.delete(randName);
                } catch (error) {
                    fail("testFSStatWithWriteResult failed to delete file:", error);
                }
            } catch (error) {
                fail("testFSStatWithWriteResult failed:", error);
            }    
        }
    },
    {
        name: "testFSWriteWithNaughtyStrings",
        description: "Test writing text content to files with names from naughtyStrings and verify it returns a valid UID",
        test: async function() {
            try {
                let randName = puter.randName();
                for(let i = 0; i < naughtyStrings.length; i++) {
                    let filename = randName + naughtyStrings[i];
                    let result = await puter.fs.write(filename, 'testValue');
                    assert(result.uid, "Failed to write to file");
                    // check name
                    assert(result.name === filename, "Failed to write to file with naughty name: " + filename);
                    // delete the file
                    try {
                        await puter.fs.delete(filename);
                    } catch (error) {
                        fail("testFSWriteWithNaughtyStrings failed to delete file: " + filename, error);
                    }
                }
                pass("testFSWriteWithNaughtyStrings passed");
            } catch (error) {
                console.log(error);
                fail("testFSWriteWithNaughtyStrings failed:", error);
            }    
        }
    },
    {
        name: "testFSWriteReadBinaryFile",
        description: "Test writing and reading binary file data and verify it remains intact",
        test: async function() {
            try {
                let randName = puter.randName() + '.webp';
                
                // Create some binary data - a simple byte array representing a small binary file
                const binaryData = new Uint8Array([
                    0x52, 0x49, 0x46, 0x46, 0x24, 0x00, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50, 0x56, 0x50, 0x38, 0x20,
                    0x18, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x9D, 0x01, 0x2A, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00,
                    0x34, 0x25, 0xA4, 0x00, 0x03, 0x70, 0x00, 0xFE, 0xFB, 0xFD, 0x50, 0x00
                ]);
                
                // Write the binary data to a file
                const writeResult = await puter.fs.write(randName, binaryData);
                assert(writeResult.uid, "Failed to write binary file");
                
                // Read the binary data back
                const readResult = await puter.fs.read(randName);
                const readBinaryData = new Uint8Array(await readResult.arrayBuffer());
                
                // Verify the binary data is identical
                assert(readBinaryData.length === binaryData.length, "Binary data length mismatch");
                for (let i = 0; i < binaryData.length; i++) {
                    assert(readBinaryData[i] === binaryData[i], `Binary data mismatch at byte ${i}: expected ${binaryData[i]}, got ${readBinaryData[i]}`);
                }
                
                pass("testFSWriteReadBinaryFile passed");
                
                // Clean up - delete the test file
                try {
                    await puter.fs.delete(randName);
                } catch (error) {
                    fail("testFSWriteReadBinaryFile failed to delete file:", error);
                }
            } catch (error) {
                fail("testFSWriteReadBinaryFile failed:", error);
            }    
        }
    },
    {
        name: "testFSAppDirectoryIsolation",
        description: "Test that filesystem operations are properly sandboxed to the app directory and cannot access files outside of it",
        test: async function() {
            try {
                // Test 1: Try to access parent directory with ../
                try {
                    await puter.fs.readdir('~/Desktop');
                    fail("testFSAppDirectoryIsolation failed: Should not be able to read Desktop directory");
                } catch (error) {
                    if (error.code !== "subject_does_not_exist") {
                        fail("testFSAppDirectoryIsolation failed: Wrong error code for Desktop directory access: " + error.code);
                    }
                }
                
                // Test 2: Try to access absolute path outside app directory
                try {
                    await puter.fs.read('/some/absolute/path.txt');
                    fail("testFSAppDirectoryIsolation failed: Should not be able to read absolute paths");
                } catch (error) {
                    if (error.code !== "access_denied" && error.code !== "invalid_path" && error.code !== "subject_does_not_exist") {
                        fail("testFSAppDirectoryIsolation failed: Wrong error code for absolute path access: " + error.code);
                    }
                }
                
                // Test 3: Try to write outside app directory
                try {
                    await puter.fs.write('../escape_file.txt', 'should not work');
                    fail("testFSAppDirectoryIsolation failed: Should not be able to write outside app directory");
                } catch (error) {
                    if (error.code !== "subject_does_not_exist") {
                        fail("testFSAppDirectoryIsolation failed: Wrong error code for writing outside directory: " + error.code);
                    }
                }
                
                // Test 4: Try to create directory outside app directory
                try {
                    await puter.fs.mkdir('../escape_dir');
                    fail("testFSAppDirectoryIsolation failed: Should not be able to create directory outside app directory");
                } catch (error) {
                        if (error.code !== "subject_does_not_exist") {
                            fail("testFSAppDirectoryIsolation failed: Wrong error code for creating directory outside: " + error.code);
                    }
                }
                
                // Test 5: Try to access home directory directly
                try {
                    await puter.fs.read('~/some_file.txt');
                    fail("testFSAppDirectoryIsolation failed: Should not be able to read from home directory");
                } catch (error) {
                    if (error.code !== "access_denied" && error.code !== "invalid_path" && error.code !== "subject_does_not_exist") {
                        fail("testFSAppDirectoryIsolation failed: Wrong error code for home directory access: " + error.code);
                    }
                }
                
                pass("testFSAppDirectoryIsolation passed");
            } catch (error) {
                fail("testFSAppDirectoryIsolation failed:", error);
            }
        }
    },
];