@@ -34,7 +34,8 @@ class TestFileManager : XCTestCase {
3434 ( " test_homedirectoryForUser " , test_homedirectoryForUser) ,
3535 ( " test_temporaryDirectoryForUser " , test_temporaryDirectoryForUser) ,
3636 ( " test_creatingDirectoryWithShortIntermediatePath " , test_creatingDirectoryWithShortIntermediatePath) ,
37- ( " test_mountedVolumeURLs " , test_mountedVolumeURLs)
37+ ( " test_mountedVolumeURLs " , test_mountedVolumeURLs) ,
38+ ( " test_contentsEqual " , test_contentsEqual)
3839 ]
3940 }
4041
@@ -620,4 +621,83 @@ class TestFileManager : XCTestCase {
620621 XCTAssertTrue ( visibleVolumes. count < volumes. count)
621622#endif
622623 }
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+ }
623703}
0 commit comments