@@ -48,19 +48,57 @@ private func getTestData() -> [Any]? {
48
48
49
49
class TestURL : XCTestCase {
50
50
static var allTests : [ ( String , ( TestURL ) -> ( ) throws -> Void ) ] {
51
- return [
51
+ var tests : [ ( String , ( TestURL ) -> ( ) throws -> Void ) ] = [
52
52
( " test_URLStrings " , test_URLStrings) ,
53
53
( " test_fileURLWithPath_relativeTo " , test_fileURLWithPath_relativeTo ) ,
54
54
// TODO: these tests fail on linux, more investigation is needed
55
55
( " test_fileURLWithPath " , test_fileURLWithPath) ,
56
56
( " test_fileURLWithPath_isDirectory " , test_fileURLWithPath_isDirectory) ,
57
- ( " test_URLByResolvingSymlinksInPath " , test_URLByResolvingSymlinksInPath) ,
57
+ ( " test_URLByResolvingSymlinksInPathShouldRemoveDuplicatedPathSeparators " , test_URLByResolvingSymlinksInPathShouldRemoveDuplicatedPathSeparators) ,
58
+ ( " test_URLByResolvingSymlinksInPathShouldRemoveSingleDotsBetweenSeparators " , test_URLByResolvingSymlinksInPathShouldRemoveSingleDotsBetweenSeparators) ,
59
+ ( " test_URLByResolvingSymlinksInPathShouldCompressDoubleDotsBetweenSeparators " , test_URLByResolvingSymlinksInPathShouldCompressDoubleDotsBetweenSeparators) ,
60
+ ( " test_URLByResolvingSymlinksInPathShouldUseTheCurrentDirectory " , test_URLByResolvingSymlinksInPathShouldUseTheCurrentDirectory) ,
61
+ ( " test_resolvingSymlinksInPathShouldAppendTrailingSlashWhenExistingDirectory " , test_resolvingSymlinksInPathShouldAppendTrailingSlashWhenExistingDirectory) ,
62
+ ( " test_resolvingSymlinksInPathShouldResolvesSymlinks " , test_resolvingSymlinksInPathShouldResolvesSymlinks) ,
63
+ ( " test_resolvingSymlinksInPathShouldNotChangeNonFileURLs " , test_resolvingSymlinksInPathShouldNotChangeNonFileURLs) ,
64
+ ( " test_resolvingSymlinksInPathShouldNotChangePathlessURLs " , test_resolvingSymlinksInPathShouldNotChangePathlessURLs) ,
58
65
( " test_reachable " , test_reachable) ,
59
66
( " test_copy " , test_copy) ,
60
67
( " test_itemNSCoding " , test_itemNSCoding) ,
61
68
( " test_dataRepresentation " , test_dataRepresentation) ,
62
69
( " test_description " , test_description) ,
63
70
]
71
+
72
+ #if canImport(Darwin)
73
+ tests += [
74
+ ( " test_resolvingSymlinksInPathShouldRemovePrivatePrefix " , test_resolvingSymlinksInPathShouldRemovePrivatePrefix) ,
75
+ ( " test_resolvingSymlinksInPathShouldNotRemovePrivatePrefixIfOnlyComponent " , test_resolvingSymlinksInPathShouldNotRemovePrivatePrefixIfOnlyComponent) ,
76
+ ]
77
+ #endif
78
+
79
+ return tests
80
+ }
81
+
82
+ var writableTestDirectoryURL : URL !
83
+
84
+ override func setUp( ) {
85
+ super. setUp ( )
86
+
87
+ let pid = ProcessInfo . processInfo. processIdentifier
88
+ writableTestDirectoryURL = URL ( fileURLWithPath: NSTemporaryDirectory ( ) ) . appendingPathComponent ( " org.swift.TestFoundation.TestURL. \( pid) " )
89
+ }
90
+
91
+ override func tearDown( ) {
92
+ if let directoryURL = writableTestDirectoryURL,
93
+ ( try ? FileManager . default. attributesOfItem ( atPath: directoryURL. path) ) != nil {
94
+ do {
95
+ try FileManager . default. removeItem ( at: directoryURL)
96
+ } catch {
97
+ NSLog ( " Could not remove test directory at URL \( directoryURL) : \( error) " )
98
+ }
99
+ }
100
+
101
+ super. tearDown ( )
64
102
}
65
103
66
104
func test_fileURLWithPath_relativeTo( ) {
@@ -383,58 +421,96 @@ class TestURL : XCTestCase {
383
421
XCTAssertTrue ( strncmp ( TestURL . gFileDoesNotExistName, relativePath, lengthOfRelativePath) == 0 , " fileSystemRepresentation of file path is wrong " )
384
422
}
385
423
386
- func test_URLByResolvingSymlinksInPath( ) {
387
- let files = [
388
- NSTemporaryDirectory ( ) + " ABC/test_URLByResolvingSymlinksInPath "
389
- ]
390
-
391
- guard ensureFiles ( files) else {
392
- XCTAssert ( false , " Could create files for testing. " )
393
- return
394
- }
395
-
396
- // tmp is special because it is symlinked to /private/tmp and this /private prefix should be dropped,
397
- // so tmp is tmp. On Linux tmp is not symlinked so it would be the same.
398
- do {
399
- let url = URL ( fileURLWithPath: " /.//tmp/ABC/.. " )
400
- let result = url. resolvingSymlinksInPath ( ) . absoluteString
401
- XCTAssertEqual ( result, " file:///tmp/ " , " URLByResolvingSymlinksInPath removes extraneous path components and resolve symlinks. " )
402
- }
403
-
404
- do {
405
- let url = URL ( fileURLWithPath: " ~ " )
406
- let result = url. resolvingSymlinksInPath ( ) . absoluteString
407
- let expected = " file:// " + FileManager. default. currentDirectoryPath + " /~ "
408
- XCTAssertEqual ( result, expected, " URLByResolvingSymlinksInPath resolves relative paths using current working directory. " )
409
- }
424
+ func test_URLByResolvingSymlinksInPathShouldRemoveDuplicatedPathSeparators( ) {
425
+ let url = URL ( fileURLWithPath: " //foo///bar////baz/ " )
426
+ let result = url. resolvingSymlinksInPath ( )
427
+ XCTAssertEqual ( result, URL ( fileURLWithPath: " /foo/bar/baz " ) )
428
+ }
410
429
411
- do {
412
- let url = URL ( fileURLWithPath: " anysite.com/search " )
413
- let result = url. resolvingSymlinksInPath ( ) . absoluteString
414
- let expected = " file:// " + FileManager. default. currentDirectoryPath + " /anysite.com/search "
415
- XCTAssertEqual ( result, expected)
416
- }
430
+ func test_URLByResolvingSymlinksInPathShouldRemoveSingleDotsBetweenSeparators( ) {
431
+ let url = URL ( fileURLWithPath: " /./foo/./.bar/./baz/./ " )
432
+ let result = url. resolvingSymlinksInPath ( )
433
+ XCTAssertEqual ( result, URL ( fileURLWithPath: " /foo/.bar/baz " ) )
434
+ }
417
435
418
- // tmp is symlinked on macOS only
419
- #if os(macOS)
420
- do {
421
- let url = URL ( fileURLWithPath: " /tmp/.. " )
422
- let result = url. resolvingSymlinksInPath ( ) . absoluteString
423
- XCTAssertEqual ( result, " file:///private/ " )
424
- }
425
- #else
426
- do {
427
- let url = URL ( fileURLWithPath: " /tmp/ABC/test_URLByResolvingSymlinksInPath " )
428
- let result = url. resolvingSymlinksInPath ( ) . absoluteString
429
- XCTAssertEqual ( result, " file:///tmp/ABC/test_URLByResolvingSymlinksInPath " , " URLByResolvingSymlinksInPath appends trailing slash for existing directories only " )
430
- }
431
- #endif
436
+ func test_URLByResolvingSymlinksInPathShouldCompressDoubleDotsBetweenSeparators( ) {
437
+ let url = URL ( fileURLWithPath: " /foo/../..bar/../baz/ " )
438
+ let result = url. resolvingSymlinksInPath ( )
439
+ XCTAssertEqual ( result, URL ( fileURLWithPath: " /baz " ) )
440
+ }
432
441
433
- do {
434
- let url = URL ( fileURLWithPath: " /tmp/ABC/.. " )
435
- let result = url. resolvingSymlinksInPath ( ) . absoluteString
436
- XCTAssertEqual ( result, " file:///tmp/ " )
442
+ func test_URLByResolvingSymlinksInPathShouldUseTheCurrentDirectory( ) throws {
443
+ let fileManager = FileManager . default
444
+ try fileManager. createDirectory ( at: writableTestDirectoryURL, withIntermediateDirectories: true )
445
+ defer { try ? fileManager. removeItem ( at: writableTestDirectoryURL) }
446
+
447
+ let previousCurrentDirectory = fileManager. currentDirectoryPath
448
+ fileManager. changeCurrentDirectoryPath ( writableTestDirectoryURL. path)
449
+ defer { fileManager. changeCurrentDirectoryPath ( previousCurrentDirectory) }
450
+
451
+ let url = URL ( fileURLWithPath: " foo/bar/baz " )
452
+ let result = url. resolvingSymlinksInPath ( )
453
+ XCTAssertEqual ( result, URL ( fileURLWithPath: writableTestDirectoryURL. path + " /foo/bar/baz " ) )
454
+ }
455
+
456
+ func test_resolvingSymlinksInPathShouldAppendTrailingSlashWhenExistingDirectory( ) throws {
457
+ let fileManager = FileManager . default
458
+ try fileManager. createDirectory ( at: writableTestDirectoryURL, withIntermediateDirectories: true )
459
+ defer { try ? fileManager. removeItem ( at: writableTestDirectoryURL) }
460
+
461
+ var path = writableTestDirectoryURL. path
462
+ if path. hasSuffix ( " / " ) {
463
+ path. remove ( at: path. index ( path. endIndex, offsetBy: - 1 ) )
437
464
}
465
+ let url = URL ( fileURLWithPath: path)
466
+ let result = url. resolvingSymlinksInPath ( )
467
+ XCTAssertEqual ( result, URL ( fileURLWithPath: path + " / " ) )
468
+ }
469
+
470
+ func test_resolvingSymlinksInPathShouldResolvesSymlinks( ) throws {
471
+ // NOTE: this test only works on file systems that support symlinks.
472
+ let fileManager = FileManager . default
473
+ try fileManager. createDirectory ( at: writableTestDirectoryURL, withIntermediateDirectories: true )
474
+ defer { try ? fileManager. removeItem ( at: writableTestDirectoryURL) }
475
+
476
+ let symbolicLink = writableTestDirectoryURL. appendingPathComponent ( " origin " )
477
+ print ( symbolicLink)
478
+ let destination = writableTestDirectoryURL. appendingPathComponent ( " destination " )
479
+ print ( destination)
480
+ try " " . write ( to: destination, atomically: true , encoding: . utf8)
481
+ try fileManager. createSymbolicLink ( at: symbolicLink, withDestinationURL: destination)
482
+
483
+ let result = symbolicLink. resolvingSymlinksInPath ( )
484
+ print ( result)
485
+ XCTAssertEqual ( result, URL ( fileURLWithPath: writableTestDirectoryURL. path + " /destination " ) )
486
+ }
487
+
488
+ func test_resolvingSymlinksInPathShouldRemovePrivatePrefix( ) {
489
+ // NOTE: this test only works on Darwin, since the code that removes
490
+ // /private relies on /private/tmp existing.
491
+ let url = URL ( fileURLWithPath: " /private/tmp " )
492
+ let result = url. resolvingSymlinksInPath ( )
493
+ XCTAssertEqual ( result, URL ( fileURLWithPath: " /tmp " ) )
494
+ }
495
+
496
+ func test_resolvingSymlinksInPathShouldNotRemovePrivatePrefixIfOnlyComponent( ) {
497
+ // NOTE: this test only works on Darwin, since only there /tmp is
498
+ // symlinked to /private/tmp.
499
+ let url = URL ( fileURLWithPath: " /tmp/.. " )
500
+ let result = url. resolvingSymlinksInPath ( )
501
+ XCTAssertEqual ( result, URL ( fileURLWithPath: " /private " ) )
502
+ }
503
+
504
+ func test_resolvingSymlinksInPathShouldNotChangeNonFileURLs( ) {
505
+ let url = URL ( string: " myscheme://server/foo/bar/baz " ) !
506
+ let result = url. resolvingSymlinksInPath ( ) . absoluteString
507
+ XCTAssertEqual ( result, " myscheme://server/foo/bar/baz " )
508
+ }
509
+
510
+ func test_resolvingSymlinksInPathShouldNotChangePathlessURLs( ) {
511
+ let url = URL ( string: " file:// " ) !
512
+ let result = url. resolvingSymlinksInPath ( ) . absoluteString
513
+ XCTAssertEqual ( result, " file:// " )
438
514
}
439
515
440
516
func test_reachable( ) {
0 commit comments