-
-
Notifications
You must be signed in to change notification settings - Fork 177
/
Copy pathtest.py
2017 lines (1627 loc) · 76.1 KB
/
test.py
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
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# coding: utf-8
"""Base class for tests.
All Filesystems should be able to pass these.
"""
from __future__ import absolute_import, unicode_literals
import io
import itertools
import json
import os
import six
import time
import unittest
import warnings
from datetime import datetime
from six import text_type
import fs.copy
import fs.move
from fs import ResourceType, Seek, errors, glob, walk
from fs.opener import open_fs
from fs.subfs import ClosingSubFS, SubFS
if six.PY2:
import collections as collections_abc
else:
import collections.abc as collections_abc
try:
from datetime import timezone
except ImportError:
from ._tzcompat import timezone # type: ignore
UNICODE_TEXT = """
UTF-8 encoded sample plain-text file
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
Markus Kuhn [ˈmaʳkʊs kuːn] <[email protected]> — 1999-08-20
The ASCII compatible UTF-8 encoding of ISO 10646 and Unicode
plain-text files is defined in RFC 2279 and in ISO 10646-1 Annex R.
Using Unicode/UTF-8, you can write in emails and source code things such as
Mathematics and Sciences:
∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β),
ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (A ⇔ B),
2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm
Linguistics and dictionaries:
ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn
Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ]
APL:
((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈
Nicer typography in plain text files:
╔══════════════════════════════════════════╗
║ ║
║ • ‘single’ and “double” quotes ║
║ ║
║ • Curly apostrophes: “We’ve been here” ║
║ ║
║ • Latin-1 apostrophe and accents: '´` ║
║ ║
║ • ‚deutsche‘ „Anführungszeichen“ ║
║ ║
║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║
║ ║
║ • ASCII safety test: 1lI|, 0OD, 8B ║
║ ╭─────────╮ ║
║ • the euro symbol: │ 14.95 € │ ║
║ ╰─────────╯ ║
╚══════════════════════════════════════════╝
Greek (in Polytonic):
The Greek anthem:
Σὲ γνωρίζω ἀπὸ τὴν κόψη
τοῦ σπαθιοῦ τὴν τρομερή,
σὲ γνωρίζω ἀπὸ τὴν ὄψη
ποὺ μὲ βία μετράει τὴ γῆ.
᾿Απ᾿ τὰ κόκκαλα βγαλμένη
τῶν ῾Ελλήνων τὰ ἱερά
καὶ σὰν πρῶτα ἀνδρειωμένη
χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά!
From a speech of Demosthenes in the 4th century BC:
Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι,
ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς
λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ
τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿
εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ
πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν
οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι,
οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν
ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον
τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι
γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν
προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους
σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ
τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ
τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς
τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον.
Δημοσθένους, Γ´ ᾿Ολυνθιακὸς
Georgian:
From a Unicode conference invitation:
გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო
კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს,
ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს
ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი,
ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება
ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში,
ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში.
Russian:
From a Unicode conference invitation:
Зарегистрируйтесь сейчас на Десятую Международную Конференцию по
Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии.
Конференция соберет широкий круг экспертов по вопросам глобального
Интернета и Unicode, локализации и интернационализации, воплощению и
применению Unicode в различных операционных системах и программных
приложениях, шрифтах, верстке и многоязычных компьютерных системах.
Thai (UCS Level 2):
Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese
classic 'San Gua'):
[----------------------------|------------------------]
๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่
สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา
ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา
โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ
เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ
ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ
พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้
ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ
(The above is a two-column text. If combining characters are handled
correctly, the lines of the second column should be aligned with the
| character above.)
Ethiopian:
Proverbs in the Amharic language:
ሰማይ አይታረስ ንጉሥ አይከሰስ።
ብላ ካለኝ እንደአባቴ በቆመጠኝ።
ጌጥ ያለቤቱ ቁምጥና ነው።
ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው።
የአፍ ወለምታ በቅቤ አይታሽም።
አይጥ በበላ ዳዋ ተመታ።
ሲተረጉሙ ይደረግሙ።
ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል።
ድር ቢያብር አንበሳ ያስር።
ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም።
እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም።
የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ።
ሥራ ከመፍታት ልጄን ላፋታት።
ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል።
የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ።
ተንጋሎ ቢተፉ ተመልሶ ባፉ።
ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው።
እግርህን በፍራሽህ ልክ ዘርጋ።
Runes:
ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ
(Old English, which transcribed into Latin reads 'He cwaeth that he
bude thaem lande northweardum with tha Westsae.' and means 'He said
that he lived in the northern land near the Western Sea.')
Braille:
⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌
⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞
⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎
⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂
⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙
⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑
⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲
⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹
⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞
⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕
⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹
⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎
⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎
⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳
⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞
⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
(The first couple of paragraphs of "A Christmas Carol" by Dickens)
Compact font selection example text:
ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789
abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ
–—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд
∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა
Greetings in various languages:
Hello world, Καλημέρα κόσμε, コンニチハ
Box drawing alignment tests: █
▉
╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
"""
class FSTestCases(object):
"""Basic FS tests."""
data1 = b"foo" * 256 * 1024
data2 = b"bar" * 2 * 256 * 1024
data3 = b"baz" * 3 * 256 * 1024
data4 = b"egg" * 7 * 256 * 1024
def make_fs(self):
"""Return an FS instance."""
raise NotImplementedError("implement me")
def destroy_fs(self, fs):
"""Destroy a FS instance.
Arguments:
fs (FS): A filesystem instance previously opened
by `~fs.test.FSTestCases.make_fs`.
"""
fs.close()
def setUp(self):
self.fs = self.make_fs()
def tearDown(self):
self.destroy_fs(self.fs)
del self.fs
def assert_exists(self, path):
"""Assert a path exists.
Arguments:
path (str): A path on the filesystem.
"""
self.assertTrue(self.fs.exists(path))
def assert_not_exists(self, path):
"""Assert a path does not exist.
Arguments:
path (str): A path on the filesystem.
"""
self.assertFalse(self.fs.exists(path))
def assert_isempty(self, path):
"""Assert a path is an empty directory.
Arguments:
path (str): A path on the filesystem.
"""
self.assertTrue(self.fs.isempty(path))
def assert_isfile(self, path):
"""Assert a path is a file.
Arguments:
path (str): A path on the filesystem.
"""
self.assertTrue(self.fs.isfile(path))
def assert_isdir(self, path):
"""Assert a path is a directory.
Arguments:
path (str): A path on the filesystem.
"""
self.assertTrue(self.fs.isdir(path))
def assert_bytes(self, path, contents):
"""Assert a file contains the given bytes.
Arguments:
path (str): A path on the filesystem.
contents (bytes): Bytes to compare.
"""
assert isinstance(contents, bytes)
data = self.fs.readbytes(path)
self.assertEqual(data, contents)
self.assertIsInstance(data, bytes)
def assert_text(self, path, contents):
"""Assert a file contains the given text.
Arguments:
path (str): A path on the filesystem.
contents (str): Text to compare.
"""
assert isinstance(contents, text_type)
with self.fs.open(path, "rt") as f:
data = f.read()
self.assertEqual(data, contents)
self.assertIsInstance(data, text_type)
def test_root_dir(self):
with self.assertRaises(errors.FileExpected):
self.fs.open("/")
with self.assertRaises(errors.FileExpected):
self.fs.openbin("/")
def test_appendbytes(self):
with self.assertRaises(TypeError):
self.fs.appendbytes("foo", "bar")
self.fs.appendbytes("foo", b"bar")
self.assert_bytes("foo", b"bar")
self.fs.appendbytes("foo", b"baz")
self.assert_bytes("foo", b"barbaz")
def test_appendtext(self):
with self.assertRaises(TypeError):
self.fs.appendtext("foo", b"bar")
self.fs.appendtext("foo", "bar")
self.assert_text("foo", "bar")
self.fs.appendtext("foo", "baz")
self.assert_text("foo", "barbaz")
def test_basic(self):
# Check str and repr don't break
repr(self.fs)
self.assertIsInstance(six.text_type(self.fs), six.text_type)
def test_getmeta(self):
# Get the meta dict
meta = self.fs.getmeta()
# Check default namespace
self.assertEqual(meta, self.fs.getmeta(namespace="standard"))
# Must be a dict
self.assertTrue(isinstance(meta, dict))
no_meta = self.fs.getmeta("__nosuchnamespace__")
self.assertIsInstance(no_meta, dict)
self.assertFalse(no_meta)
def test_isfile(self):
self.assertFalse(self.fs.isfile("foo.txt"))
self.fs.create("foo.txt")
self.assertTrue(self.fs.isfile("foo.txt"))
self.fs.makedir("bar")
self.assertFalse(self.fs.isfile("bar"))
def test_isdir(self):
self.assertFalse(self.fs.isdir("foo"))
self.fs.create("bar")
self.fs.makedir("foo")
self.assertTrue(self.fs.isdir("foo"))
self.assertFalse(self.fs.isdir("bar"))
def test_islink(self):
self.fs.touch("foo")
self.assertFalse(self.fs.islink("foo"))
with self.assertRaises(errors.ResourceNotFound):
self.fs.islink("bar")
def test_getsize(self):
self.fs.writebytes("empty", b"")
self.fs.writebytes("one", b"a")
self.fs.writebytes("onethousand", ("b" * 1000).encode("ascii"))
self.assertEqual(self.fs.getsize("empty"), 0)
self.assertEqual(self.fs.getsize("one"), 1)
self.assertEqual(self.fs.getsize("onethousand"), 1000)
with self.assertRaises(errors.ResourceNotFound):
self.fs.getsize("doesnotexist")
def test_getsyspath(self):
self.fs.create("foo")
try:
syspath = self.fs.getsyspath("foo")
except errors.NoSysPath:
self.assertFalse(self.fs.hassyspath("foo"))
else:
self.assertIsInstance(syspath, text_type)
self.assertIsInstance(self.fs.getospath("foo"), bytes)
self.assertTrue(self.fs.hassyspath("foo"))
# Should not throw an error
self.fs.hassyspath("a/b/c/foo/bar")
def test_geturl(self):
self.fs.create("foo")
try:
self.fs.geturl("foo")
except errors.NoURL:
self.assertFalse(self.fs.hasurl("foo"))
else:
self.assertTrue(self.fs.hasurl("foo"))
# Should not throw an error
self.fs.hasurl("a/b/c/foo/bar")
def test_geturl_purpose(self):
"""Check an unknown purpose raises a NoURL error."""
self.fs.create("foo")
with self.assertRaises(errors.NoURL):
self.fs.geturl("foo", purpose="__nosuchpurpose__")
def test_validatepath(self):
"""Check validatepath returns an absolute path."""
path = self.fs.validatepath("foo")
self.assertEqual(path, "/foo")
def test_invalid_chars(self):
# Test invalid path method.
with self.assertRaises(errors.InvalidCharsInPath):
self.fs.open("invalid\0file", "wb")
with self.assertRaises(errors.InvalidCharsInPath):
self.fs.validatepath("invalid\0file")
def test_getinfo(self):
# Test special case of root directory
# Root directory has a name of ''
root_info = self.fs.getinfo("/")
self.assertEqual(root_info.name, "")
self.assertTrue(root_info.is_dir)
self.assertIn("basic", root_info.namespaces)
# Make a file of known size
self.fs.writebytes("foo", b"bar")
self.fs.makedir("dir")
# Check basic namespace
info = self.fs.getinfo("foo").raw
self.assertIn("basic", info)
self.assertIsInstance(info["basic"]["name"], text_type)
self.assertEqual(info["basic"]["name"], "foo")
self.assertFalse(info["basic"]["is_dir"])
# Check basic namespace dir
info = self.fs.getinfo("dir").raw
self.assertIn("basic", info)
self.assertEqual(info["basic"]["name"], "dir")
self.assertTrue(info["basic"]["is_dir"])
# Get the info
info = self.fs.getinfo("foo", namespaces=["details"]).raw
self.assertIn("basic", info)
self.assertIsInstance(info, dict)
self.assertEqual(info["details"]["size"], 3)
self.assertEqual(info["details"]["type"], int(ResourceType.file))
# Test getdetails
self.assertEqual(info, self.fs.getdetails("foo").raw)
# Raw info should be serializable
try:
json.dumps(info)
except (TypeError, ValueError):
raise AssertionError("info should be JSON serializable")
# Non existant namespace is not an error
no_info = self.fs.getinfo("foo", "__nosuchnamespace__").raw
self.assertIsInstance(no_info, dict)
self.assertEqual(no_info["basic"], {"name": "foo", "is_dir": False})
# Check a number of standard namespaces
# FS objects may not support all these, but we can at least
# invoke the code
info = self.fs.getinfo("foo", namespaces=["access", "stat", "details"])
# Check that if the details namespace is present, times are
# of valid types.
if "details" in info.namespaces:
details = info.raw["details"]
self.assertIsInstance(details.get("accessed"), (type(None), int, float))
self.assertIsInstance(details.get("modified"), (type(None), int, float))
self.assertIsInstance(details.get("created"), (type(None), int, float))
self.assertIsInstance(
details.get("metadata_changed"), (type(None), int, float)
)
def test_exists(self):
# Test exists method.
# Check root directory always exists
self.assertTrue(self.fs.exists("/"))
self.assertTrue(self.fs.exists(""))
# Check files don't exist
self.assertFalse(self.fs.exists("foo"))
self.assertFalse(self.fs.exists("foo/bar"))
self.assertFalse(self.fs.exists("foo/bar/baz"))
self.assertFalse(self.fs.exists("egg"))
# make some files and directories
self.fs.makedirs("foo/bar")
self.fs.writebytes("foo/bar/baz", b"test")
# Check files exists
self.assertTrue(self.fs.exists("foo"))
self.assertTrue(self.fs.exists("foo/bar"))
self.assertTrue(self.fs.exists("foo/bar/baz"))
self.assertFalse(self.fs.exists("egg"))
self.assert_exists("foo")
self.assert_exists("foo/bar")
self.assert_exists("foo/bar/baz")
self.assert_not_exists("egg")
# Delete a file
self.fs.remove("foo/bar/baz")
# Check it no longer exists
self.assert_not_exists("foo/bar/baz")
self.assertFalse(self.fs.exists("foo/bar/baz"))
self.assert_not_exists("foo/bar/baz")
# Check root directory always exists
self.assertTrue(self.fs.exists("/"))
self.assertTrue(self.fs.exists(""))
def test_listdir(self):
# Check listing directory that doesn't exist
with self.assertRaises(errors.ResourceNotFound):
self.fs.listdir("foobar")
# Check aliases for root
self.assertEqual(self.fs.listdir("/"), [])
self.assertEqual(self.fs.listdir("."), [])
self.assertEqual(self.fs.listdir("./"), [])
# Make a few objects
self.fs.writebytes("foo", b"egg")
self.fs.writebytes("bar", b"egg")
self.fs.makedir("baz")
# This should not be listed
self.fs.writebytes("baz/egg", b"egg")
# Check list works
six.assertCountEqual(self, self.fs.listdir("/"), ["foo", "bar", "baz"])
six.assertCountEqual(self, self.fs.listdir("."), ["foo", "bar", "baz"])
six.assertCountEqual(self, self.fs.listdir("./"), ["foo", "bar", "baz"])
# Check paths are unicode strings
for name in self.fs.listdir("/"):
self.assertIsInstance(name, text_type)
# Create a subdirectory
self.fs.makedir("dir")
# Should start empty
self.assertEqual(self.fs.listdir("/dir"), [])
# Write some files
self.fs.writebytes("dir/foofoo", b"egg")
self.fs.writebytes("dir/barbar", b"egg")
# Check listing subdirectory
six.assertCountEqual(self, self.fs.listdir("dir"), ["foofoo", "barbar"])
# Make sure they are unicode stringd
for name in self.fs.listdir("dir"):
self.assertIsInstance(name, text_type)
self.fs.create("notadir")
with self.assertRaises(errors.DirectoryExpected):
self.fs.listdir("notadir")
def test_move(self):
# Make a file
self.fs.writebytes("foo", b"egg")
self.assert_isfile("foo")
# Move it
self.fs.move("foo", "bar")
# Check it has gone from original location
self.assert_not_exists("foo")
# Check it exists in the new location, and contents match
self.assert_exists("bar")
self.assert_bytes("bar", b"egg")
# Check moving to existing file fails
self.fs.writebytes("foo2", b"eggegg")
with self.assertRaises(errors.DestinationExists):
self.fs.move("foo2", "bar")
# Check move with overwrite=True
self.fs.move("foo2", "bar", overwrite=True)
self.assert_not_exists("foo2")
# Check moving to a non-existant directory
with self.assertRaises(errors.ResourceNotFound):
self.fs.move("bar", "egg/bar")
# Check moving an unexisting source
with self.assertRaises(errors.ResourceNotFound):
self.fs.move("egg", "spam")
# Check moving between different directories
self.fs.makedir("baz")
self.fs.writebytes("baz/bazbaz", b"bazbaz")
self.fs.makedir("baz2")
self.fs.move("baz/bazbaz", "baz2/bazbaz")
self.assert_not_exists("baz/bazbaz")
self.assert_bytes("baz2/bazbaz", b"bazbaz")
# Check moving a directory raises an error
self.assert_isdir("baz2")
self.assert_not_exists("yolk")
with self.assertRaises(errors.FileExpected):
self.fs.move("baz2", "yolk")
def test_makedir(self):
# Check edge case of root
with self.assertRaises(errors.DirectoryExists):
self.fs.makedir("/")
# Making root is a null op with recreate
slash_fs = self.fs.makedir("/", recreate=True)
self.assertIsInstance(slash_fs, SubFS)
self.assertEqual(self.fs.listdir("/"), [])
self.assert_not_exists("foo")
self.fs.makedir("foo")
self.assert_isdir("foo")
self.assertEqual(self.fs.gettype("foo"), ResourceType.directory)
self.fs.writebytes("foo/bar.txt", b"egg")
self.assert_bytes("foo/bar.txt", b"egg")
# Directory exists
with self.assertRaises(errors.DirectoryExists):
self.fs.makedir("foo")
# Parent directory doesn't exist
with self.assertRaises(errors.ResourceNotFound):
self.fs.makedir("/foo/bar/baz")
self.fs.makedir("/foo/bar")
self.fs.makedir("/foo/bar/baz")
with self.assertRaises(errors.DirectoryExists):
self.fs.makedir("foo/bar/baz")
with self.assertRaises(errors.DirectoryExists):
self.fs.makedir("foo/bar.txt")
def test_makedirs(self):
self.assertFalse(self.fs.exists("foo"))
self.fs.makedirs("foo")
self.assertEqual(self.fs.gettype("foo"), ResourceType.directory)
self.fs.makedirs("foo/bar/baz")
self.assertTrue(self.fs.isdir("foo/bar"))
self.assertTrue(self.fs.isdir("foo/bar/baz"))
with self.assertRaises(errors.DirectoryExists):
self.fs.makedirs("foo/bar/baz")
self.fs.makedirs("foo/bar/baz", recreate=True)
self.fs.writebytes("foo.bin", b"test")
with self.assertRaises(errors.DirectoryExpected):
self.fs.makedirs("foo.bin/bar")
with self.assertRaises(errors.DirectoryExpected):
self.fs.makedirs("foo.bin/bar/baz/egg")
def test_repeat_dir(self):
# Catches bug with directories contain repeated names,
# discovered in s3fs
self.fs.makedirs("foo/foo/foo")
self.assertEqual(self.fs.listdir(""), ["foo"])
self.assertEqual(self.fs.listdir("foo"), ["foo"])
self.assertEqual(self.fs.listdir("foo/foo"), ["foo"])
self.assertEqual(self.fs.listdir("foo/foo/foo"), [])
scan = list(self.fs.scandir("foo"))
self.assertEqual(len(scan), 1)
self.assertEqual(scan[0].name, "foo")
def test_open(self):
# Open a file that doesn't exist
with self.assertRaises(errors.ResourceNotFound):
self.fs.open("doesnotexist", "r")
self.fs.makedir("foo")
# Create a new text file
text = "Hello, World"
with self.fs.open("foo/hello", "wt") as f:
repr(f)
self.assertIsInstance(f, io.IOBase)
self.assertTrue(f.writable())
self.assertFalse(f.readable())
self.assertFalse(f.closed)
f.write(text)
self.assertTrue(f.closed)
# Read it back
with self.fs.open("foo/hello", "rt") as f:
self.assertIsInstance(f, io.IOBase)
self.assertTrue(f.readable())
self.assertFalse(f.writable())
self.assertFalse(f.closed)
hello = f.read()
self.assertTrue(f.closed)
self.assertEqual(hello, text)
self.assert_text("foo/hello", text)
# Test overwrite
text = "Goodbye, World"
with self.fs.open("foo/hello", "wt") as f:
f.write(text)
self.assert_text("foo/hello", text)
# Open from missing dir
with self.assertRaises(errors.ResourceNotFound):
self.fs.open("/foo/bar/test.txt")
# Test fileno returns a file number, if supported by the file.
with self.fs.open("foo/hello") as f:
try:
fn = f.fileno()
except io.UnsupportedOperation:
pass
else:
self.assertEqual(os.read(fn, 7), b"Goodbye")
# Test text files are proper iterators over themselves
lines = os.linesep.join(["Line 1", "Line 2", "Line 3"])
self.fs.writetext("iter.txt", lines)
with self.fs.open("iter.txt") as f:
for actual, expected in zip(f, lines.splitlines(1)):
self.assertEqual(actual, expected)
def test_openbin_rw(self):
# Open a file that doesn't exist
with self.assertRaises(errors.ResourceNotFound):
self.fs.openbin("doesnotexist", "r")
self.fs.makedir("foo")
# Create a new text file
text = b"Hello, World\n"
with self.fs.openbin("foo/hello", "w") as f:
repr(f)
self.assertIn("b", f.mode)
self.assertIsInstance(f, io.IOBase)
self.assertTrue(f.writable())
self.assertFalse(f.readable())
self.assertEqual(len(text), f.write(text))
self.assertFalse(f.closed)
self.assertTrue(f.closed)
with self.assertRaises(errors.FileExists):
with self.fs.openbin("foo/hello", "x") as f:
pass
# Read it back
with self.fs.openbin("foo/hello", "r") as f:
self.assertIn("b", f.mode)
self.assertIsInstance(f, io.IOBase)
self.assertTrue(f.readable())
self.assertFalse(f.writable())
hello = f.read()
self.assertFalse(f.closed)
self.assertTrue(f.closed)
self.assertEqual(hello, text)
self.assert_bytes("foo/hello", text)
# Test overwrite
text = b"Goodbye, World"
with self.fs.openbin("foo/hello", "w") as f:
self.assertEqual(len(text), f.write(text))
self.assert_bytes("foo/hello", text)
# Test FileExpected raised
with self.assertRaises(errors.FileExpected):
self.fs.openbin("foo") # directory
# Open from missing dir
with self.assertRaises(errors.ResourceNotFound):
self.fs.openbin("/foo/bar/test.txt")
# Test fileno returns a file number, if supported by the file.
with self.fs.openbin("foo/hello") as f:
try:
fn = f.fileno()
except io.UnsupportedOperation:
pass
else:
self.assertEqual(os.read(fn, 7), b"Goodbye")
# Test binary files are proper iterators over themselves
lines = b"\n".join([b"Line 1", b"Line 2", b"Line 3"])
self.fs.writebytes("iter.bin", lines)
with self.fs.openbin("iter.bin") as f:
for actual, expected in zip(f, lines.splitlines(1)):
self.assertEqual(actual, expected)
def test_open_files(self):
# Test file-like objects work as expected.
with self.fs.open("text", "w") as f:
repr(f)
text_type(f)
self.assertIsInstance(f, io.IOBase)
self.assertTrue(f.writable())
self.assertFalse(f.readable())
self.assertFalse(f.closed)
self.assertEqual(f.tell(), 0)
f.write("Hello\nWorld\n")
self.assertEqual(f.tell(), 12)
f.writelines(["foo\n", "bar\n", "baz\n"])
with self.assertRaises(IOError):
f.read(1)
self.assertTrue(f.closed)
with self.fs.open("bin", "wb") as f:
with self.assertRaises(IOError):
f.read(1)
with self.fs.open("text", "r") as f:
repr(f)
text_type(f)
self.assertIsInstance(f, io.IOBase)
self.assertFalse(f.writable())
self.assertTrue(f.readable())
self.assertFalse(f.closed)
self.assertEqual(
f.readlines(), ["Hello\n", "World\n", "foo\n", "bar\n", "baz\n"]
)
with self.assertRaises(IOError):
f.write("no")
self.assertTrue(f.closed)
with self.fs.open("text", "rb") as f:
self.assertIsInstance(f, io.IOBase)
self.assertFalse(f.writable())
self.assertTrue(f.readable())
self.assertFalse(f.closed)
self.assertEqual(f.readlines(8), [b"Hello\n", b"World\n"])
self.assertEqual(f.tell(), 12)
buffer = bytearray(4)
self.assertEqual(f.readinto(buffer), 4)
self.assertEqual(f.tell(), 16)
self.assertEqual(buffer, b"foo\n")
with self.assertRaises(IOError):
f.write(b"no")
self.assertTrue(f.closed)
with self.fs.open("text", "r") as f:
self.assertEqual(list(f), ["Hello\n", "World\n", "foo\n", "bar\n", "baz\n"])
self.assertFalse(f.closed)
self.assertTrue(f.closed)
with self.fs.open("text") as f:
iter_lines = iter(f)
self.assertEqual(next(iter_lines), "Hello\n")
with self.fs.open("unicode", "w") as f:
self.assertEqual(12, f.write("Héllo\nWörld\n"))
with self.fs.open("text", "rb") as f:
self.assertIsInstance(f, io.IOBase)
self.assertFalse(f.writable())
self.assertTrue(f.readable())
self.assertTrue(f.seekable())
self.assertFalse(f.closed)
self.assertEqual(f.read(1), b"H")
self.assertEqual(3, f.seek(3, Seek.set))
self.assertEqual(f.read(1), b"l")
self.assertEqual(6, f.seek(2, Seek.current))
self.assertEqual(f.read(1), b"W")
self.assertEqual(22, f.seek(-2, Seek.end))
self.assertEqual(f.read(1), b"z")
with self.assertRaises(ValueError):
f.seek(10, 77)
self.assertTrue(f.closed)
with self.fs.open("text", "r+b") as f:
self.assertIsInstance(f, io.IOBase)
self.assertTrue(f.readable())
self.assertTrue(f.writable())
self.assertTrue(f.seekable())
self.assertFalse(f.closed)
self.assertEqual(5, f.seek(5))
self.assertEqual(5, f.truncate())
self.assertEqual(0, f.seek(0))
self.assertEqual(f.read(), b"Hello")
self.assertEqual(10, f.truncate(10))
self.assertEqual(5, f.tell())
self.assertEqual(0, f.seek(0))
print(repr(self.fs))
print(repr(f))
self.assertEqual(f.read(), b"Hello\0\0\0\0\0")
self.assertEqual(4, f.seek(4))
f.write(b"O")
self.assertEqual(4, f.seek(4))
self.assertEqual(f.read(1), b"O")
self.assertTrue(f.closed)
def test_openbin(self):
# Write a binary file
with self.fs.openbin("file.bin", "wb") as write_file:
repr(write_file)
text_type(write_file)
self.assertIn("b", write_file.mode)
self.assertIsInstance(write_file, io.IOBase)
self.assertTrue(write_file.writable())
self.assertFalse(write_file.readable())
self.assertFalse(write_file.closed)
self.assertEqual(3, write_file.write(b"\0\1\2"))
self.assertTrue(write_file.closed)
# Read a binary file
with self.fs.openbin("file.bin", "rb") as read_file:
repr(write_file)
text_type(write_file)
self.assertIn("b", read_file.mode)
self.assertIsInstance(read_file, io.IOBase)
self.assertTrue(read_file.readable())
self.assertFalse(read_file.writable())
self.assertFalse(read_file.closed)
data = read_file.read()
self.assertEqual(data, b"\0\1\2")
self.assertTrue(read_file.closed)
# Check disallow text mode
with self.assertRaises(ValueError):
with self.fs.openbin("file.bin", "rt") as read_file:
pass
# Check errors
with self.assertRaises(errors.ResourceNotFound):
self.fs.openbin("foo.bin")
# Open from missing dir
with self.assertRaises(errors.ResourceNotFound):
self.fs.openbin("/foo/bar/test.txt")
self.fs.makedir("foo")
# Attempt to open a directory
with self.assertRaises(errors.FileExpected):
self.fs.openbin("/foo")
# Attempt to write to a directory
with self.assertRaises(errors.FileExpected):
self.fs.openbin("/foo", "w")
# Opening a file in a directory which doesn't exist
with self.assertRaises(errors.ResourceNotFound):
self.fs.openbin("/egg/bar")
# Opening a file in a directory which doesn't exist
with self.assertRaises(errors.ResourceNotFound):
self.fs.openbin("/egg/bar", "w")