@@ -34,7 +34,8 @@ class TestFileManager : XCTestCase {
34
34
( " test_homedirectoryForUser " , test_homedirectoryForUser) ,
35
35
( " test_temporaryDirectoryForUser " , test_temporaryDirectoryForUser) ,
36
36
( " test_creatingDirectoryWithShortIntermediatePath " , test_creatingDirectoryWithShortIntermediatePath) ,
37
- ( " test_mountedVolumeURLs " , test_mountedVolumeURLs)
37
+ ( " test_mountedVolumeURLs " , test_mountedVolumeURLs) ,
38
+ ( " test_contentsEqual " , test_contentsEqual)
38
39
]
39
40
}
40
41
@@ -620,4 +621,83 @@ class TestFileManager : XCTestCase {
620
621
XCTAssertTrue ( visibleVolumes. count < volumes. count)
621
622
#endif
622
623
}
624
+
625
+ func test_contentsEqual( ) {
626
+ let fm = FileManager . default
627
+ let tmpParentDirURL = URL ( fileURLWithPath: NSTemporaryDirectory ( ) + " test_contentsEqualdir " , isDirectory: true )
628
+ let testDir1 = tmpParentDirURL. appendingPathComponent ( " testDir1 " )
629
+ let testDir2 = tmpParentDirURL. appendingPathComponent ( " testDir2 " )
630
+ let testDir3 = testDir1. appendingPathComponent ( " subDir " )
631
+
632
+ defer { try ? fm. removeItem ( atPath: tmpParentDirURL. path) }
633
+
634
+ func testFileURL( _ name: String , _ ext: String ) -> URL ? {
635
+ guard let url = testBundle ( ) . url ( forResource: name, withExtension: ext) else {
636
+ XCTFail ( " Cant open \( name) . \( ext) " )
637
+ return nil
638
+ }
639
+ return url
640
+ }
641
+
642
+ guard let testFile1URL = testFileURL ( " NSStringTestData " , " txt " ) else { return }
643
+ guard let testFile2URL = testFileURL ( " NSURLTestData " , " plist " ) else { return }
644
+ guard let testFile3URL = testFileURL ( " NSString-UTF32-BE-data " , " txt " ) else { return }
645
+ guard let testFile4URL = testFileURL ( " NSString-UTF32-LE-data " , " txt " ) else { return }
646
+ let symlink = testDir1. appendingPathComponent ( " testlink " ) . path
647
+
648
+ // Setup test directories
649
+ do {
650
+ // Clean out and leftover test data
651
+ try ? fm. removeItem ( atPath: tmpParentDirURL. path)
652
+
653
+ // testDir1
654
+ try fm. createDirectory ( atPath: testDir1. path, withIntermediateDirectories: true )
655
+ try fm. createSymbolicLink ( atPath: testDir1. appendingPathComponent ( " null1 " ) . path, withDestinationPath: " /dev/null " )
656
+ try fm. createSymbolicLink ( atPath: testDir1. appendingPathComponent ( " zero1 " ) . path, withDestinationPath: " /dev/zero " )
657
+ try " foo " . write ( toFile: testDir1. appendingPathComponent ( " foo.txt " ) . path, atomically: false , encoding: . ascii)
658
+ try fm. createSymbolicLink ( atPath: testDir1. appendingPathComponent ( " foo1 " ) . path, withDestinationPath: " foo.txt " )
659
+ try fm. createSymbolicLink ( atPath: testDir1. appendingPathComponent ( " bar2 " ) . path, withDestinationPath: " foo1 " )
660
+ let unreadable = testDir1. appendingPathComponent ( " unreadable_file " ) . path
661
+ try " unreadable " . write ( toFile: unreadable, atomically: false , encoding: . ascii)
662
+ try fm. setAttributes ( [ . posixPermissions: NSNumber ( value: 0 ) ] , ofItemAtPath: unreadable)
663
+ try Data ( ) . write ( to: testDir1. appendingPathComponent ( " empty_file " ) )
664
+ try fm. createSymbolicLink ( atPath: symlink, withDestinationPath: testFile1URL. path)
665
+
666
+ // testDir2
667
+ try fm. createDirectory ( atPath: testDir2. path, withIntermediateDirectories: true )
668
+ try fm. createSymbolicLink ( atPath: testDir2. appendingPathComponent ( " bar2 " ) . path, withDestinationPath: " foo1 " )
669
+ try fm. createSymbolicLink ( atPath: testDir2. appendingPathComponent ( " foo2 " ) . path, withDestinationPath: " ../testDir1/foo.txt " )
670
+
671
+ // testDir3
672
+ try fm. createDirectory ( atPath: testDir3. path, withIntermediateDirectories: true )
673
+ try fm. createSymbolicLink ( atPath: testDir3. appendingPathComponent ( " bar2 " ) . path, withDestinationPath: " foo1 " )
674
+ try fm. createSymbolicLink ( atPath: testDir3. appendingPathComponent ( " foo2 " ) . path, withDestinationPath: " ../testDir1/foo.txt " )
675
+ } catch {
676
+ XCTFail ( String ( describing: error) )
677
+ }
678
+
679
+ XCTAssertTrue ( fm. contentsEqual ( atPath: " /dev/null " , andPath: " /dev/null " ) )
680
+ XCTAssertTrue ( fm. contentsEqual ( atPath: " /dev/urandom " , andPath: " /dev/urandom " ) )
681
+ XCTAssertFalse ( fm. contentsEqual ( atPath: " /dev/null " , andPath: " /dev/zero " ) )
682
+ XCTAssertFalse ( fm. contentsEqual ( atPath: testDir1. appendingPathComponent ( " null1 " ) . path, andPath: " /dev/null " ) )
683
+ XCTAssertFalse ( fm. contentsEqual ( atPath: testDir1. appendingPathComponent ( " zero " ) . path, andPath: " /dev/zero " ) )
684
+ XCTAssertFalse ( fm. contentsEqual ( atPath: testDir1. appendingPathComponent ( " foo.txt " ) . path, andPath: testDir1. appendingPathComponent ( " foo1 " ) . path) )
685
+ XCTAssertFalse ( fm. contentsEqual ( atPath: testDir1. appendingPathComponent ( " foo.txt " ) . path, andPath: testDir1. appendingPathComponent ( " foo2 " ) . path) )
686
+ XCTAssertTrue ( fm. contentsEqual ( atPath: testDir1. appendingPathComponent ( " bar2 " ) . path, andPath: testDir2. appendingPathComponent ( " bar2 " ) . path) )
687
+ XCTAssertFalse ( fm. contentsEqual ( atPath: testDir1. appendingPathComponent ( " foo1 " ) . path, andPath: testDir2. appendingPathComponent ( " foo2 " ) . path) )
688
+ XCTAssertFalse ( fm. contentsEqual ( atPath: " /non_existant_file " , andPath: " /non_existant_file " ) )
689
+
690
+ let emptyFile = testDir1. appendingPathComponent ( " empty_file " )
691
+ XCTAssertFalse ( fm. contentsEqual ( atPath: emptyFile. path, andPath: " /dev/null " ) )
692
+ XCTAssertFalse ( fm. contentsEqual ( atPath: emptyFile. path, andPath: testDir1. appendingPathComponent ( " null1 " ) . path) )
693
+ XCTAssertFalse ( fm. contentsEqual ( atPath: emptyFile. path, andPath: testDir1. appendingPathComponent ( " unreadable_file " ) . path) )
694
+
695
+ XCTAssertTrue ( fm. contentsEqual ( atPath: testFile1URL. path, andPath: testFile1URL. path) )
696
+ XCTAssertFalse ( fm. contentsEqual ( atPath: testFile1URL. path, andPath: testFile2URL. path) )
697
+ XCTAssertFalse ( fm. contentsEqual ( atPath: testFile3URL. path, andPath: testFile4URL. path) )
698
+ XCTAssertFalse ( fm. contentsEqual ( atPath: symlink, andPath: testFile1URL. path) )
699
+ XCTAssertTrue ( fm. contentsEqual ( atPath: testDir1. path, andPath: testDir1. path) )
700
+ XCTAssertTrue ( fm. contentsEqual ( atPath: testDir2. path, andPath: testDir3. path) )
701
+ XCTAssertFalse ( fm. contentsEqual ( atPath: testDir1. path, andPath: testDir2. path) )
702
+ }
623
703
}
0 commit comments