From ef323119ac66d135f3b6684d58b181a081f85a6c Mon Sep 17 00:00:00 2001 From: kcieplak Date: Tue, 20 May 2025 11:41:06 -0400 Subject: [PATCH] Revert "Resolves #505 - Fix handling for Windows long paths (#506)" This reverts commit eb4c83d081118097bef00764bb1f0047b1805a04. --- Sources/TSCBasic/CMakeLists.txt | 3 +- Sources/TSCBasic/Path.swift | 160 +------ Sources/TSCBasic/Win32Error.swift | 37 -- Tests/TSCBasicTests/PathTests.swift | 660 +++------------------------- 4 files changed, 67 insertions(+), 793 deletions(-) delete mode 100644 Sources/TSCBasic/Win32Error.swift diff --git a/Sources/TSCBasic/CMakeLists.txt b/Sources/TSCBasic/CMakeLists.txt index 2fb5a8a3..d8b85eaa 100644 --- a/Sources/TSCBasic/CMakeLists.txt +++ b/Sources/TSCBasic/CMakeLists.txt @@ -49,8 +49,7 @@ add_library(TSCBasic TerminalController.swift Thread.swift Tuple.swift - misc.swift - Win32Error.swift) + misc.swift) target_compile_options(TSCBasic PUBLIC # Ignore secure function warnings on Windows. diff --git a/Sources/TSCBasic/Path.swift b/Sources/TSCBasic/Path.swift index 70020951..208f9819 100644 --- a/Sources/TSCBasic/Path.swift +++ b/Sources/TSCBasic/Path.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift.org open source project - Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors + Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information @@ -32,7 +32,6 @@ import var Foundation.NSLocalizedDescriptionKey /// - Removing `.` path components /// - Removing any trailing path separator /// - Removing any redundant path separators -/// - Converting the disk designator to uppercase (Windows) i.e. c:\ to C:\ /// /// This string manipulation may change the meaning of a path if any of the /// path components are symbolic links on disk. However, the file system is @@ -507,13 +506,8 @@ private struct WindowsPath: Path, Sendable { var components: [String] { let normalized: UnsafePointer = string.fileSystemRepresentation defer { normalized.deallocate() } - // Remove prefix from the components, allowing for comparison across normalized paths. - var prefixStrippedPath = PathCchStripPrefix(String(cString: normalized)) - // The '\\.\'' prefix is not removed by PathCchStripPrefix do this manually. - if prefixStrippedPath.starts(with: #"\\.\"#) { - prefixStrippedPath = String(prefixStrippedPath.dropFirst(4)) - } - return prefixStrippedPath.components(separatedBy: #"\"#).filter { !$0.isEmpty } + + return String(cString: normalized).components(separatedBy: "\\").filter { !$0.isEmpty } } var parentDirectory: Self { @@ -521,16 +515,12 @@ private struct WindowsPath: Path, Sendable { } init(string: String) { - let noPrefixPath = PathCchStripPrefix(string) - let prefix = string.replacingOccurrences(of: noPrefixPath, with: "") // Just the prefix or empty - - // Perform drive designator normalization i.e. 'c:\' to 'C:\' on string. - if noPrefixPath.first?.isASCII ?? false, noPrefixPath.first?.isLetter ?? false, noPrefixPath.first?.isLowercase ?? false, - noPrefixPath.count > 1, noPrefixPath[noPrefixPath.index(noPrefixPath.startIndex, offsetBy: 1)] == ":" + if string.first?.isASCII ?? false, string.first?.isLetter ?? false, string.first?.isLowercase ?? false, + string.count > 1, string[string.index(string.startIndex, offsetBy: 1)] == ":" { - self.string = "\(prefix)\(noPrefixPath.first!.uppercased())\(noPrefixPath.dropFirst(1))" + self.string = "\(string.first!.uppercased())\(string.dropFirst(1))" } else { - self.string = prefix + noPrefixPath + self.string = string } } @@ -546,13 +536,7 @@ private struct WindowsPath: Path, Sendable { if !Self.isAbsolutePath(realpath) { throw PathValidationError.invalidAbsolutePath(path) } - do { - let canonicalizedPath = try canonicalPathRepresentation(realpath) - let normalizedPath = PathCchRemoveBackslash(canonicalizedPath) // AbsolutePath states paths have no trailing separator. - self.init(string: normalizedPath) - } catch { - throw PathValidationError.invalidAbsolutePath("\(path): \(error)") - } + self.init(string: realpath) } init(validatingRelativePath path: String) throws { @@ -570,20 +554,12 @@ private struct WindowsPath: Path, Sendable { func suffix(withDot: Bool) -> String? { return self.string.withCString(encodedAs: UTF16.self) { - if let dotPointer = PathFindExtensionW($0) { - // If the dotPointer is the same as the full path, there are no components before - // the suffix and therefore there is no suffix. - if dotPointer == $0 { - return nil - } - let substring = String(decodingCString: dotPointer, as: UTF16.self) - // Substring must have a dot and one more character to be considered a suffix - guard substring.length > 1 else { - return nil - } - return withDot ? substring : String(substring.dropFirst(1)) - } - return nil + if let pointer = PathFindExtensionW($0) { + let substring = String(decodingCString: pointer, as: UTF16.self) + guard substring.length > 0 else { return nil } + return withDot ? substring : String(substring.dropFirst(1)) + } + return nil } } @@ -609,111 +585,6 @@ private struct WindowsPath: Path, Sendable { return Self(string: String(decodingCString: result!, as: UTF16.self)) } } - -fileprivate func HRESULT_CODE(_ hr: HRESULT) -> DWORD { - DWORD(hr) & 0xFFFF -} - -@inline(__always) -fileprivate func HRESULT_FACILITY(_ hr: HRESULT) -> DWORD { - DWORD(hr << 16) & 0x1FFF -} - -@inline(__always) -fileprivate func SUCCEEDED(_ hr: HRESULT) -> Bool { - hr >= 0 -} - -// This is a non-standard extension to the Windows SDK that allows us to convert -// an HRESULT to a Win32 error code. -@inline(__always) -fileprivate func WIN32_FROM_HRESULT(_ hr: HRESULT) -> DWORD { - if SUCCEEDED(hr) { return DWORD(ERROR_SUCCESS) } - if HRESULT_FACILITY(hr) == FACILITY_WIN32 { - return HRESULT_CODE(hr) - } - return DWORD(hr) -} - -/// Create a canonicalized path representation for Windows. -/// Returns a potentially `\\?\`-prefixed version of the path, -/// to ensure long paths greater than MAX_PATH (260) characters are handled correctly. -/// -/// - seealso: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation -fileprivate func canonicalPathRepresentation(_ path: String) throws -> String { - return try path.withCString(encodedAs: UTF16.self) { pwszPlatformPath in - // 1. Normalize the path first. - // Contrary to the documentation, this works on long paths independently - // of the registry or process setting to enable long paths (but it will also - // not add the \\?\ prefix required by other functions under these conditions). - let dwLength: DWORD = GetFullPathNameW(pwszPlatformPath, 0, nil, nil) - - return try withUnsafeTemporaryAllocation(of: WCHAR.self, capacity: Int(dwLength)) { pwszFullPath in - guard (1 ..< dwLength).contains(GetFullPathNameW(pwszPlatformPath, DWORD(pwszFullPath.count), pwszFullPath.baseAddress, nil)) else { - throw Win32Error(GetLastError()) - } - // 1.5 Leave \\.\ prefixed paths alone since device paths are already an exact representation and PathCchCanonicalizeEx will mangle these. - if pwszFullPath.count >= 4 { - if let base = pwszFullPath.baseAddress, - base[0] == UInt8(ascii: "\\"), - base[1] == UInt8(ascii: "\\"), - base[2] == UInt8(ascii: "."), - base[3] == UInt8(ascii: "\\") - { - return String(decodingCString: base, as: UTF16.self) - } - } - // 2. Canonicalize the path. - // This will add the \\?\ prefix if needed based on the path's length. - var pwszCanonicalPath: LPWSTR? - let flags: ULONG = numericCast(PATHCCH_ALLOW_LONG_PATHS.rawValue) - let result = PathAllocCanonicalize(pwszFullPath.baseAddress, flags, &pwszCanonicalPath) - if let pwszCanonicalPath { - defer { LocalFree(pwszCanonicalPath) } - if result == S_OK { - // 3. Perform the operation on the normalized path. - return String(decodingCString: pwszCanonicalPath, as: UTF16.self) - } - } - throw Win32Error(WIN32_FROM_HRESULT(result)) - } - } -} - -/// Removes the "\\?\" prefix, if present, from a file path. When this function returns successfully, -/// the same path string will have the prefix removed,if the prefix was present. -/// If no prefix was present,the string will be unchanged. -fileprivate func PathCchStripPrefix(_ path: String) -> String { - return path.withCString(encodedAs: UTF16.self) { cStringPtr in - withUnsafeTemporaryAllocation(of: WCHAR.self, capacity: path.utf16.count + 1) { buffer in - buffer.initialize(from: UnsafeBufferPointer(start: cStringPtr, count: path.utf16.count + 1)) - let result = PathCchStripPrefix(buffer.baseAddress!, buffer.count) - if result == S_OK { - return String(decodingCString: buffer.baseAddress!, as: UTF16.self) - } - return path - } - } -} - -/// Remove a trailing backslash from a path if the following conditions -/// are true: -/// * Path is not a root path -/// * Pash has a trailing backslash -/// If conditions are not met then the string is returned unchanged. -fileprivate func PathCchRemoveBackslash(_ path: String) -> String { - return path.withCString(encodedAs: UTF16.self) { cStringPtr in - return withUnsafeTemporaryAllocation(of: WCHAR.self, capacity: path.utf16.count + 1) { buffer in - buffer.initialize(from: UnsafeBufferPointer(start: cStringPtr, count: path.utf16.count + 1)) - let result = PathCchRemoveBackslash(buffer.baseAddress!, path.utf16.count + 1) - if result == S_OK { - return String(decodingCString: buffer.baseAddress!, as: UTF16.self) - } - return path - } - return path - } -} #else private struct UNIXPath: Path, Sendable { let string: String @@ -1095,8 +966,7 @@ extension AbsolutePath { } } - assert(AbsolutePath(base, result) == self, "base:\(base) result:\(result) self: \(self)") - + assert(AbsolutePath(base, result) == self) return result } diff --git a/Sources/TSCBasic/Win32Error.swift b/Sources/TSCBasic/Win32Error.swift deleted file mode 100644 index ac091f54..00000000 --- a/Sources/TSCBasic/Win32Error.swift +++ /dev/null @@ -1,37 +0,0 @@ -/* - This source file is part of the Swift.org open source project - - Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for Swift project authors - */ - -#if os(Windows) -public import WinSDK -import Foundation - -public struct Win32Error: Error, CustomStringConvertible { - public let error: DWORD - - public init(_ error: DWORD) { - self.error = error - } - - public var description: String { - let flags: DWORD = DWORD(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS) - var buffer: UnsafeMutablePointer? - let length: DWORD = withUnsafeMutablePointer(to: &buffer) { - $0.withMemoryRebound(to: WCHAR.self, capacity: 2) { - FormatMessageW(flags, nil, error, 0, $0, 0, nil) - } - } - guard let buffer, length > 0 else { - return "Win32 Error Code \(error)" - } - defer { LocalFree(buffer) } - return String(decodingCString: buffer, as: UTF16.self).trimmingCharacters(in: .whitespacesAndNewlines) - } -} -#endif \ No newline at end of file diff --git a/Tests/TSCBasicTests/PathTests.swift b/Tests/TSCBasicTests/PathTests.swift index 25c5e73c..d18ce814 100644 --- a/Tests/TSCBasicTests/PathTests.swift +++ b/Tests/TSCBasicTests/PathTests.swift @@ -1,100 +1,31 @@ /* This source file is part of the Swift.org open source project - Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors + Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for Swift project authors - */ +*/ import Foundation import TSCBasic import TSCTestSupport import XCTest -func generatePath(_ length: Int, absolute: Bool = true, duplicateSeparators: Bool = false, useUnparsedPrefix: Bool=false, useDevicePrefix: Bool=false) -> String { - #if !os(Windows) - var path = absolute ? "/" : "" - let separator = duplicateSeparators ? "//" : "/" - #else - var path = absolute ? #"C:"# : "" - if useUnparsedPrefix && !useDevicePrefix { - path = #"\\?\"# + path - } - if useDevicePrefix && !useUnparsedPrefix { - path = #"\\.\"# + path - } - let separator = duplicateSeparators ? #"\\"# : #"\"# - #endif - var currentPathLength = path.count - var dirNameCount = 0 - while currentPathLength < length { - let dirName = String(dirNameCount) - assert(!(dirName.count > 255), "Path component of \(dirName) exceeds 255 characters") // Windows has path component limits of 255 - path.append("\(path.count != 0 ? separator : "")\(dirName)") - dirNameCount += 1 - currentPathLength += separator.count + dirName.count - } - return path -} - class PathTests: XCTestCase { - // The implementation of RelativePath on Windows does not do any path canonicalization/normalization". - // Canonicalization is only done on AbsolutePaths, so all tests need to handle this difference. func testBasics() { - #if !os(Windows) XCTAssertEqual(AbsolutePath("/").pathString, "/") XCTAssertEqual(AbsolutePath("/a").pathString, "/a") XCTAssertEqual(AbsolutePath("/a/b/c").pathString, "/a/b/c") XCTAssertEqual(RelativePath(".").pathString, ".") XCTAssertEqual(RelativePath("a").pathString, "a") XCTAssertEqual(RelativePath("a/b/c").pathString, "a/b/c") - XCTAssertEqual(RelativePath("~").pathString, "~") // `~` is not special - #else - // Backslash is considered an absolute path by 'PathIsRelativeW', however after canonicalization the drive designator - // of current working drive will be added to the path. - XCTAssert(try #/[A-Z]:\\/#.wholeMatch(in: AbsolutePath(#"\"#).pathString) != nil) - XCTAssert(try #/[A-Z]:\\foo/#.wholeMatch(in: AbsolutePath(#"\foo"#).pathString) != nil) - XCTAssertEqual(AbsolutePath(#"C:\"#).pathString, #"C:\"#) - XCTAssertEqual(RelativePath(".").pathString, ".") - XCTAssertEqual(RelativePath("a").pathString, "a") - XCTAssertEqual(RelativePath(#"a\b\c"#).pathString, #"a\b\c"#) - - // Unparsed prefix '\\?\'' < PATH_MAX - XCTAssertEqual(AbsolutePath(#"\\?\C:\"#).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"\\?\C:"#).pathString, #"C:\"#) - XCTAssert(try #/[A-Z]:foo/#.wholeMatch(in: AbsolutePath(#"\\?\C:foo"#).pathString) != nil, "Got: \(AbsolutePath(#"\\?\C:foo"#).pathString)") - XCTAssert(try #/[A-Z]:\\foo/#.wholeMatch(in: AbsolutePath(#"\\?\C:\foo"#).pathString) != nil, "Got: \(AbsolutePath(#"\\?\C:\foo"#).pathString)") - - // Unparsed prefix > PATH_MAX - let longAbsolutePathUnderPathMax = generatePath(200) - XCTAssertEqual(AbsolutePath(longAbsolutePathUnderPathMax).pathString, longAbsolutePathUnderPathMax) - let longAbsolutePathOverPathMax = generatePath(260) - XCTAssertEqual(AbsolutePath(longAbsolutePathOverPathMax).pathString, #"\\?\"# + longAbsolutePathOverPathMax) - let unParsedLongAbsolutePathUnderPathMax = generatePath(265, useUnparsedPrefix: true) - XCTAssertEqual(AbsolutePath(unParsedLongAbsolutePathUnderPathMax).pathString, unParsedLongAbsolutePathUnderPathMax) - - // Device prefix < PATH_MAX - XCTAssertEqual(AbsolutePath(#"\\.\C:\"#).pathString, #"\\.\C:"#) - XCTAssertEqual(AbsolutePath(#"\\.\C:\foo"#).pathString, #"\\.\C:\foo"#) - let deviceLongAbsolutePathUnderPathMax = generatePath(265, useDevicePrefix: true) - XCTAssertEqual(AbsolutePath(deviceLongAbsolutePathUnderPathMax).pathString, deviceLongAbsolutePathUnderPathMax) - #endif - } - - func testMixedSeperators() { - #if os(Windows) - XCTAssertEqual(AbsolutePath(#"C:\foo/bar"#).pathString, #"C:\foo\bar"#) - XCTAssertEqual(AbsolutePath(#"C:\foo/bar"#).pathString, #"C:\foo\bar"#) - XCTAssertEqual(AbsolutePath(#"\\?\C:\foo/bar"#).pathString, #"C:\foo\bar"#) - XCTAssertEqual(AbsolutePath(#"\\.\C:\foo/bar"#).pathString, #"\\.\C:\foo\bar"#) - #endif + XCTAssertEqual(RelativePath("~").pathString, "~") // `~` is not special } func testStringInitialization() throws { - #if !os(Windows) let abs1 = AbsolutePath("/") let abs2 = AbsolutePath(abs1, ".") XCTAssertEqual(abs1, abs2) @@ -106,135 +37,41 @@ class PathTests: XCTestCase { XCTAssertEqual(abs4, AbsolutePath("/a/b/c")) let abs5 = AbsolutePath("./a/b/c", relativeTo: base) XCTAssertEqual(abs5, AbsolutePath("/base/path/a/b/c")) - let abs6 = AbsolutePath("~/bla", relativeTo: base) // `~` isn't special + let abs6 = AbsolutePath("~/bla", relativeTo: base) // `~` isn't special XCTAssertEqual(abs6, AbsolutePath("/base/path/~/bla")) - #else - let abs1 = AbsolutePath(#"C:\"#) - let abs2 = AbsolutePath(abs1, ".") - XCTAssertEqual(abs1, abs2) - let rel3 = "." - let abs3 = try AbsolutePath(abs2, validating: rel3) - XCTAssertEqual(abs2, abs3) - let base = AbsolutePath(#"C:\base\path"#) - let abs4 = AbsolutePath(#"\a\b\c"#, relativeTo: base) - XCTAssertEqual(abs4, AbsolutePath(#"C:\a\b\c"#)) - let abs5 = AbsolutePath(#".\a\b\c"#, relativeTo: base) - XCTAssertEqual(abs5, AbsolutePath(#"C:\base\path\a\b\c"#)) - #endif } func testStringLiteralInitialization() { - #if !os(Windows) let abs = AbsolutePath("/") XCTAssertEqual(abs.pathString, "/") let rel1 = RelativePath(".") XCTAssertEqual(rel1.pathString, ".") let rel2 = RelativePath("~") - XCTAssertEqual(rel2.pathString, "~") // `~` is not special - #else - let abs = AbsolutePath(#"C:\"#) - XCTAssertEqual(abs.pathString, #"C:\"#) - let rel1 = RelativePath(".") - XCTAssertEqual(rel1.pathString, ".") - #endif + XCTAssertEqual(rel2.pathString, "~") // `~` is not special } func testRepeatedPathSeparators() { - #if !os(Windows) XCTAssertEqual(AbsolutePath("/ab//cd//ef").pathString, "/ab/cd/ef") XCTAssertEqual(AbsolutePath("/ab///cd//ef").pathString, "/ab/cd/ef") XCTAssertEqual(RelativePath("ab//cd//ef").pathString, "ab/cd/ef") XCTAssertEqual(RelativePath("ab//cd///ef").pathString, "ab/cd/ef") - #else - XCTAssertEqual(AbsolutePath(#"C:\ab\\cd\\ef"#).pathString, #"C:\ab\cd\ef"#) - XCTAssertEqual(AbsolutePath(#"C:\ab\\cd\\ef"#).pathString, #"C:\ab\cd\ef"#) - XCTAssertEqual(AbsolutePath(#"\\?\C:\ab\\cd\\ef"#).pathString, #"C:\ab\cd\ef"#) - XCTAssertEqual(AbsolutePath(#"\\.\C:\ab\\cd\\ef"#).pathString, #"\\.\C:\ab\cd\ef"#) - XCTAssertEqual(RelativePath(#"ab\\cd\\ef"#).pathString, #"ab\\cd\\ef"#) - XCTAssertEqual(RelativePath(#"ab\\cd\\\ef"#).pathString, #"ab\\cd\\\ef"#) - - // Duplicate backslashes will be squashed, so needs to be more that PATH_MAX - let longAbsolutePathOverPathMax = generatePath(2 * 260, duplicateSeparators: true) - XCTAssertEqual(AbsolutePath(longAbsolutePathOverPathMax).pathString, - #"\\?\"# + longAbsolutePathOverPathMax.replacingOccurrences(of: #"\\"#, with: #"\"#)) - - // Note: .replacingOccurrences() will squash the leading double backslash, add one extra to the start of comparision string for the \\? or \\. - let unParsedLongAbsolutePathOverPathMax = generatePath(2 * 260, duplicateSeparators: true, useUnparsedPrefix: true) - XCTAssertEqual(AbsolutePath(unParsedLongAbsolutePathOverPathMax).pathString, - #"\"# + unParsedLongAbsolutePathOverPathMax.replacingOccurrences(of: #"\\"#, with: #"\"#)) - let deviceLongAbsolutePathOverPathMax = generatePath(2 * 260, duplicateSeparators: true, useDevicePrefix: true) - XCTAssertEqual(AbsolutePath(deviceLongAbsolutePathOverPathMax).pathString, - #"\"# + deviceLongAbsolutePathOverPathMax.replacingOccurrences(of: #"\\"#, with: #"\"#)) - - - #endif } func testTrailingPathSeparators() { - #if !os(Windows) XCTAssertEqual(AbsolutePath("/ab/cd/ef/").pathString, "/ab/cd/ef") XCTAssertEqual(AbsolutePath("/ab/cd/ef//").pathString, "/ab/cd/ef") XCTAssertEqual(RelativePath("ab/cd/ef/").pathString, "ab/cd/ef") XCTAssertEqual(RelativePath("ab/cd/ef//").pathString, "ab/cd/ef") - #else - XCTAssertEqual(AbsolutePath(#"C:\"#).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\ab\cd\ef\"#).pathString, #"C:\ab\cd\ef"#) - XCTAssertEqual(AbsolutePath(#"C:\ab\cd\ef\\"#).pathString, #"C:\ab\cd\ef"#) - XCTAssertEqual(AbsolutePath(#"\\?\C:\"#).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"\\?\C:\ab\cd\ef\"#).pathString, #"C:\ab\cd\ef"#) - XCTAssertEqual(AbsolutePath(#"\\?\C:\ab\cd\ef\\"#).pathString, #"C:\ab\cd\ef"#) - XCTAssertEqual(AbsolutePath(#"\\.\C:\"#).pathString, #"\\.\C:"#) - XCTAssertEqual(AbsolutePath(#"\\.\C:\ab\cd\ef\"#).pathString, #"\\.\C:\ab\cd\ef"#) - XCTAssertEqual(AbsolutePath(#"\\.\C:\ab\cd\ef\\"#).pathString, #"\\.\C:\ab\cd\ef"#) - - XCTAssertEqual(RelativePath(#"ab\cd\ef\"#).pathString, #"ab\cd\ef\"#) - XCTAssertEqual(RelativePath(#"ab\cd\ef\\"#).pathString, #"ab\cd\ef\\"#) - - let longAbsolutePathOverPathMax = generatePath(280) - XCTAssertEqual(AbsolutePath(longAbsolutePathOverPathMax + #"\"#).pathString, #"\\?\"# + longAbsolutePathOverPathMax) - - let unParsedLongAbsolutePathOverPathMax = generatePath(265, useUnparsedPrefix: true) - XCTAssertEqual(AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\"# ).pathString, - unParsedLongAbsolutePathOverPathMax) - let deviceLongAbsolutePathOverPathMax = generatePath(265, useDevicePrefix: true) - XCTAssertEqual(AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\"#).pathString, - deviceLongAbsolutePathOverPathMax) - #endif } func testDotPathComponents() { - #if !os(Windows) XCTAssertEqual(AbsolutePath("/ab/././cd//ef").pathString, "/ab/cd/ef") XCTAssertEqual(AbsolutePath("/ab/./cd//ef/.").pathString, "/ab/cd/ef") XCTAssertEqual(RelativePath("ab/./cd/././ef").pathString, "ab/cd/ef") XCTAssertEqual(RelativePath("ab/./cd/ef/.").pathString, "ab/cd/ef") - #else - XCTAssertEqual(AbsolutePath(#"C:\ab\.\.\cd\\ef"#).pathString, #"C:\ab\cd\ef"#) - XCTAssertEqual(AbsolutePath(#"C:\ab\.\cd\\ef\."#).pathString, #"C:\ab\cd\ef"#) - XCTAssertEqual(AbsolutePath(#"\\?\C:\ab\.\.\cd\\ef"#).pathString, #"C:\ab\cd\ef"#) - XCTAssertEqual(AbsolutePath(#"\\.\C:\ab\.\cd\\ef\."#).pathString, #"\\.\C:\ab\cd\ef"#) - XCTAssertEqual(RelativePath(#"ab\.\cd\.\.\ef"#).pathString, #"ab\.\cd\.\.\ef"#) - XCTAssertEqual(RelativePath(#"ab\.\cd\ef\."#).pathString, #"ab\.\cd\ef\."#) - - let longAbsolutePathOverPathMax = generatePath(260) - let longAbsolutePathOverPathMaxWithDotComponents = longAbsolutePathOverPathMax + #"\.\foo\.\bar\"# - XCTAssertEqual(AbsolutePath(longAbsolutePathOverPathMaxWithDotComponents).pathString, - #"\\?\"# + longAbsolutePathOverPathMax + #"\foo\bar"#) - - let unParsedLongAbsolutePathOverPathMax = generatePath(265, useUnparsedPrefix: true) - let unParsedLongAbsolutePathOverPathMaxWithDotComponents = unParsedLongAbsolutePathOverPathMax + #"\.\foo\.\bar\"# - XCTAssertEqual(AbsolutePath(unParsedLongAbsolutePathOverPathMaxWithDotComponents).pathString, - unParsedLongAbsolutePathOverPathMax + #"\foo\bar"#) - - let deviceLongAbsolutePathOverPathMax = generatePath(265, useDevicePrefix: true) - let deviceLongAbsolutePathOverPathMaxWithDotComponents = deviceLongAbsolutePathOverPathMax + #"\.\foo\.\bar\"# - XCTAssertEqual(AbsolutePath(deviceLongAbsolutePathOverPathMaxWithDotComponents).pathString, - deviceLongAbsolutePathOverPathMax + #"\foo\bar"#) - #endif } func testDotDotPathComponents() { - #if !os(Windows) XCTAssertEqual(AbsolutePath("/..").pathString, "/") XCTAssertEqual(AbsolutePath("/../../../../..").pathString, "/") XCTAssertEqual(AbsolutePath("/abc/..").pathString, "/") @@ -248,33 +85,9 @@ class PathTests: XCTestCase { XCTAssertEqual(RelativePath("../abc/..").pathString, "..") XCTAssertEqual(RelativePath("../abc/.././").pathString, "..") XCTAssertEqual(RelativePath("abc/..").pathString, ".") - #else - XCTAssertEqual(AbsolutePath(#"C:\.."#).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\..\..\..\..\.."#).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\abc\.."#).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\abc\..\.."#).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\..\abc"#).pathString, #"C:\abc"#) - XCTAssertEqual(AbsolutePath(#"C:\..\abc\.."#).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\..\abc\..\def"#).pathString, #"C:\def"#) - - XCTAssertEqual(RelativePath(#".."#).pathString, #".."#) - XCTAssertEqual(RelativePath(#"..\.."#).pathString, #"..\.."#) - XCTAssertEqual(RelativePath(#"..\.\.."#).pathString, #"..\.\.."#) - XCTAssertEqual(RelativePath(#"..\abc\.."#).pathString, #"..\abc\.."#) - XCTAssertEqual(RelativePath(#"..\abc\..\.\"#).pathString, #"..\abc\..\.\"#) - XCTAssertEqual(RelativePath(#"abc\.."#).pathString, #"abc\.."#) - let longAbsolutePathOverPathMax = generatePath(280) - XCTAssertEqual(AbsolutePath(longAbsolutePathOverPathMax + #"\abc\..\"#).pathString, #"\\?\"# + longAbsolutePathOverPathMax) - let unParsedLongAbsolutePathOverPathMax = generatePath(280, useUnparsedPrefix: true) - XCTAssertEqual(AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\abc\..\"#).pathString, unParsedLongAbsolutePathOverPathMax) - let deviceLongAbsolutePathOverPathMax = generatePath(280, useDevicePrefix: true) - XCTAssertEqual(AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\abc\..\"#).pathString, deviceLongAbsolutePathOverPathMax) - - #endif } func testCombinationsAndEdgeCases() { - #if !os(Windows) XCTAssertEqual(AbsolutePath("///").pathString, "/") XCTAssertEqual(AbsolutePath("/./").pathString, "/") XCTAssertEqual(RelativePath("").pathString, ".") @@ -301,38 +114,9 @@ class PathTests: XCTestCase { XCTAssertEqual(RelativePath("../a/..").pathString, "..") XCTAssertEqual(RelativePath("a/..").pathString, ".") XCTAssertEqual(RelativePath("a/../////../////./////").pathString, "..") - #else - XCTAssertEqual(AbsolutePath(#"C:\\\"#).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\.\"#).pathString, #"C:\"#) - XCTAssertEqual(RelativePath("").pathString, ".") - XCTAssertEqual(RelativePath(".").pathString, ".") - XCTAssertEqual(RelativePath(#".\abc"#).pathString, #".\abc"#) - XCTAssertEqual(RelativePath(#".\abc\"#).pathString, #".\abc\"#) - XCTAssertEqual(RelativePath(#".\abc\..\bar"#).pathString, #".\abc\..\bar"#) - XCTAssertEqual(RelativePath(#"foo\..\bar"#).pathString, #"foo\..\bar"#) - XCTAssertEqual(RelativePath(#"foo\\\..\\\bar\\\baz"#).pathString, #"foo\\\..\\\bar\\\baz"#) - XCTAssertEqual(RelativePath(#"foo\..\bar\.\"#).pathString, #"foo\..\bar\.\"#) - XCTAssertEqual(RelativePath(#"..\abc\def\"#).pathString, #"..\abc\def\"#) - XCTAssertEqual(RelativePath(#".\.\.\.\."#).pathString, #".\.\.\.\."#) - XCTAssertEqual(RelativePath(#".\.\.\..\."#).pathString, #".\.\.\..\."#) - XCTAssertEqual(RelativePath(#".\"#).pathString, #".\"#) - XCTAssertEqual(RelativePath(#".\\"#).pathString, #".\\"#) - XCTAssertEqual(RelativePath(#".\."#).pathString, #".\."#) - XCTAssertEqual(RelativePath(#".\.\"#).pathString, #".\.\"#) - XCTAssertEqual(RelativePath(#"..\"#).pathString, #"..\"#) - XCTAssertEqual(RelativePath(#"..\."#).pathString, #"..\."#) - XCTAssertEqual(RelativePath(#".\.."#).pathString, #".\.."#) - XCTAssertEqual(RelativePath(#".\..\."#).pathString, #".\..\."#) - XCTAssertEqual(RelativePath(#".\\\\\..\\\\\.\\\\\"#).pathString, #".\\\\\..\\\\\.\\\\\"#) - XCTAssertEqual(RelativePath(#"..\a"#).pathString, #"..\a"#) - XCTAssertEqual(RelativePath(#"..\a\.."#).pathString, #"..\a\.."#) - XCTAssertEqual(RelativePath(#"a\.."#).pathString, #"a\.."#) - XCTAssertEqual(RelativePath(#"a\..\\\\\..\\\\\.\\\\\"#).pathString, #"a\..\\\\\..\\\\\.\\\\\"#) - #endif } func testDirectoryNameExtraction() { - #if !os(Windows) XCTAssertEqual(AbsolutePath("/").dirname, "/") XCTAssertEqual(AbsolutePath("/a").dirname, "/") XCTAssertEqual(AbsolutePath("/./a").dirname, "/") @@ -347,42 +131,18 @@ class PathTests: XCTestCase { XCTAssertEqual(RelativePath("abc").dirname, ".") XCTAssertEqual(RelativePath("").dirname, ".") XCTAssertEqual(RelativePath(".").dirname, ".") - #else - XCTAssertEqual(AbsolutePath(#"C:\a\b"#).dirname, #"C:\a"#) - XCTAssertEqual(AbsolutePath(#"C:\"#).dirname, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\\"#).dirname, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\\\"#).dirname, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\a\b\"#).dirname, #"C:\a"#) - XCTAssertEqual(AbsolutePath(#"C:\a\b\\"#).dirname, #"C:\a"#) - XCTAssertEqual(AbsolutePath(#"C:\a\"#).dirname, #"C:\"#) - - XCTAssertEqual(AbsolutePath(#"\\?\C:\a\b"#).dirname, #"C:\a"#) - XCTAssertEqual(AbsolutePath(#"\\?\C:\"#).dirname, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"\\?\C:\\"#).dirname, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"\\?\C:\\\"#).dirname, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"\\?\C:\a\b\"#).dirname, #"C:\a"#) - XCTAssertEqual(AbsolutePath(#"\\?\C:\a\b\\"#).dirname, #"C:\a"#) - XCTAssertEqual(AbsolutePath(#"\\?\C:\a\"#).dirname, #"C:\"#) - - XCTAssertEqual(AbsolutePath(#"\\.\C:\a\b"#).dirname, #"\\.\C:\a"#) - XCTAssertEqual(AbsolutePath(#"\\.\C:\"#).dirname, #"\\.\C:"#) - XCTAssertEqual(AbsolutePath(#"\\.\C:\\"#).dirname, #"\\.\C:"#) - XCTAssertEqual(AbsolutePath(#"\\.\C:\\\"#).dirname, #"\\.\C:"#) - XCTAssertEqual(AbsolutePath(#"\\.\C:\a\b\"#).dirname, #"\\.\C:\a"#) - XCTAssertEqual(AbsolutePath(#"\\.\C:\a\b\\"#).dirname, #"\\.\C:\a"#) - XCTAssertEqual(AbsolutePath(#"\\.\C:\a\"#).dirname, #"\\.\C:"#) - - let longAbsolutePathOverPathMax = generatePath(280) - XCTAssertEqual(AbsolutePath(longAbsolutePathOverPathMax + #"\a.txt"#).dirname, #"\\?\"# + longAbsolutePathOverPathMax) - let unParsedLongAbsolutePathOverPathMax = generatePath(280, useUnparsedPrefix: true) - XCTAssertEqual(AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\a.txt"#).dirname, unParsedLongAbsolutePathOverPathMax) - let deviceLongAbsolutePathOverPathMax = generatePath(280, useDevicePrefix: true) - XCTAssertEqual(AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\a.txt"#).dirname, deviceLongAbsolutePathOverPathMax) - #endif +#if os(Windows) + XCTAssertEqual(AbsolutePath("C:\\a\\b").dirname, "C:\\a") + XCTAssertEqual(AbsolutePath("C:\\").dirname, "C:\\") + XCTAssertEqual(AbsolutePath("C:\\\\").dirname, "C:\\") + XCTAssertEqual(AbsolutePath("C:\\\\\\").dirname, "C:\\") + XCTAssertEqual(AbsolutePath("C:\\a\\b\\").dirname, "C:\\a") + XCTAssertEqual(AbsolutePath("C:\\a\\b\\\\").dirname, "C:\\a") + XCTAssertEqual(AbsolutePath("C:\\a\\").dirname, "C:\\") +#endif } func testBaseNameExtraction() { - #if !os(Windows) XCTAssertEqual(AbsolutePath("/").basename, "/") XCTAssertEqual(AbsolutePath("/a").basename, "a") XCTAssertEqual(AbsolutePath("/./a").basename, "a") @@ -396,31 +156,9 @@ class PathTests: XCTestCase { XCTAssertEqual(RelativePath("abc").basename, "abc") XCTAssertEqual(RelativePath("").basename, ".") XCTAssertEqual(RelativePath(".").basename, ".") - #else - XCTAssertEqual(AbsolutePath(#"C:\"#).basename, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\a"#).basename, #"a"#) - XCTAssertEqual(AbsolutePath(#"C:\.\a"#).basename, #"a"#) - XCTAssertEqual(AbsolutePath(#"C:\..\.."#).basename, #"C:\"#) - XCTAssertEqual(RelativePath(#"..\.."#).basename, #".."#) - XCTAssertEqual(RelativePath(#"..\a"#).basename, #"a"#) - XCTAssertEqual(RelativePath(#"..\a\.."#).basename, #".."#) - XCTAssertEqual(RelativePath(#"a\.."#).basename, #".."#) - XCTAssertEqual(RelativePath(#".\.."#).basename, #".."#) - XCTAssertEqual(RelativePath(#"a\..\\\\..\\\\.\\\\"#).basename, #".\\\\"#) - XCTAssertEqual(RelativePath(#"abc"#).basename, #"abc"#) - XCTAssertEqual(RelativePath(#""#).basename, #"."#) - XCTAssertEqual(RelativePath(#"."#).basename, #"."#) - let longAbsolutePathOverPathMax = generatePath(280) - XCTAssertEqual(AbsolutePath(longAbsolutePathOverPathMax + #"\a.txt"#).basename, #"a.txt"#) - let unParsedLongAbsolutePathOverPathMax = generatePath(280, useUnparsedPrefix: true) - XCTAssertEqual(AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\a.txt"#).basename, #"a.txt"#) - let deviceLongAbsolutePathOverPathMax = generatePath(280, useDevicePrefix: true) - XCTAssertEqual(AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\a.txt"#).basename, #"a.txt"#) - #endif } func testBaseNameWithoutExt() { - #if !os(Windows) XCTAssertEqual(AbsolutePath("/").basenameWithoutExt, "/") XCTAssertEqual(AbsolutePath("/a").basenameWithoutExt, "a") XCTAssertEqual(AbsolutePath("/./a").basenameWithoutExt, "a") @@ -441,35 +179,6 @@ class PathTests: XCTestCase { XCTAssertEqual(RelativePath("abc.swift").basenameWithoutExt, "abc") XCTAssertEqual(RelativePath("../a.b.c").basenameWithoutExt, "a.b") XCTAssertEqual(RelativePath("abc.xyz.123").basenameWithoutExt, "abc.xyz") - #else - XCTAssertEqual(AbsolutePath(#"C:\"#).basenameWithoutExt, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\a"#).basenameWithoutExt, #"a"#) - XCTAssertEqual(AbsolutePath(#"C:\.\a"#).basenameWithoutExt, #"a"#) - XCTAssertEqual(AbsolutePath(#"C:\..\.."#).basenameWithoutExt, #"C:\"#) - XCTAssertEqual(RelativePath(#"..\.."#).basenameWithoutExt, #".."#) - XCTAssertEqual(RelativePath(#"..\a"#).basenameWithoutExt, #"a"#) - XCTAssertEqual(RelativePath(#"..\a\.."#).basenameWithoutExt, #".."#) - XCTAssertEqual(RelativePath(#"a\.."#).basenameWithoutExt, #".."#) - XCTAssertEqual(RelativePath(#".\.."#).basenameWithoutExt, #".."#) - XCTAssertEqual(RelativePath(#"a\..\\\\..\\\\.\\\\"#).basenameWithoutExt, #".\\\\"#) - XCTAssertEqual(RelativePath(#"abc"#).basenameWithoutExt, #"abc"#) - XCTAssertEqual(RelativePath(#""#).basenameWithoutExt, #"."#) - XCTAssertEqual(RelativePath(#"."#).basenameWithoutExt, #"."#) - - XCTAssertEqual(AbsolutePath(#"C:\a.txt"#).basenameWithoutExt, #"a"#) - XCTAssertEqual(AbsolutePath(#"C:\.\a.txt"#).basenameWithoutExt, #"a"#) - XCTAssertEqual(RelativePath(#"..\a.bc"#).basenameWithoutExt, #"a"#) - XCTAssertEqual(RelativePath(#"abc.swift"#).basenameWithoutExt, #"abc"#) - XCTAssertEqual(RelativePath(#"..\a.b.c"#).basenameWithoutExt, #"a.b"#) - XCTAssertEqual(RelativePath(#"abc.xyz.123"#).basenameWithoutExt, #"abc.xyz"#) - - let longAbsolutePathOverPathMax = generatePath(280) - XCTAssertEqual(AbsolutePath(longAbsolutePathOverPathMax + #"\a.txt"#).basenameWithoutExt, #"a"#) - let unParsedLongAbsolutePathOverPathMax = generatePath(280, useUnparsedPrefix: true) - XCTAssertEqual(AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\a.txt"#).basenameWithoutExt, #"a"#) - let deviceLongAbsolutePathOverPathMax = generatePath(280, useDevicePrefix: true) - XCTAssertEqual(AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\a.txt"#).basenameWithoutExt, #"a"#) - #endif } func testSuffixExtraction() { @@ -498,30 +207,15 @@ class PathTests: XCTestCase { } func testParentDirectory() { - #if !os(Windows) XCTAssertEqual(AbsolutePath("/").parentDirectory, AbsolutePath("/")) XCTAssertEqual(AbsolutePath("/").parentDirectory.parentDirectory, AbsolutePath("/")) XCTAssertEqual(AbsolutePath("/bar").parentDirectory, AbsolutePath("/")) XCTAssertEqual(AbsolutePath("/bar/../foo/..//").parentDirectory.parentDirectory, AbsolutePath("/")) XCTAssertEqual(AbsolutePath("/bar/../foo/..//yabba/a/b").parentDirectory.parentDirectory, AbsolutePath("/yabba")) - #else - XCTAssertEqual(AbsolutePath(#"C:\"#).parentDirectory, AbsolutePath(#"C:\"#)) - XCTAssertEqual(AbsolutePath(#"C:\"#).parentDirectory.parentDirectory, AbsolutePath(#"C:\"#)) - XCTAssertEqual(AbsolutePath(#"C:\bar"#).parentDirectory, AbsolutePath(#"C:\"#)) - XCTAssertEqual(AbsolutePath(#"C:\bar\..\foo\..\\"#).parentDirectory.parentDirectory, AbsolutePath(#"C:\"#)) - XCTAssertEqual(AbsolutePath(#"C:\bar\..\foo\..\\yabba\a\b"#).parentDirectory.parentDirectory, AbsolutePath(#"C:\yabba"#)) - let longAbsolutePathOverPathMax = generatePath(280) - XCTAssertEqual(AbsolutePath(longAbsolutePathOverPathMax).parentDirectory, AbsolutePath(longAbsolutePathOverPathMax.replacingOccurrences(of: #"\95"#, with: ""))) - let unParsedLongAbsolutePathOverPathMax = generatePath(280, useUnparsedPrefix: true) - XCTAssertEqual(AbsolutePath(unParsedLongAbsolutePathOverPathMax).parentDirectory, AbsolutePath(unParsedLongAbsolutePathOverPathMax.replacingOccurrences(of: #"\94"#, with: ""))) - let deviceLongAbsolutePathOverPathMax = generatePath(280, useDevicePrefix: true) - XCTAssertEqual(AbsolutePath(deviceLongAbsolutePathOverPathMax).parentDirectory, AbsolutePath(deviceLongAbsolutePathOverPathMax.replacingOccurrences(of: #"\94"#, with: ""))) - #endif } @available(*, deprecated) func testConcatenation() { - #if !os(Windows) XCTAssertEqual(AbsolutePath(AbsolutePath("/"), RelativePath("")).pathString, "/") XCTAssertEqual(AbsolutePath(AbsolutePath("/"), RelativePath(".")).pathString, "/") XCTAssertEqual(AbsolutePath(AbsolutePath("/"), RelativePath("..")).pathString, "/") @@ -556,53 +250,9 @@ class PathTests: XCTestCase { XCTAssertEqual(RelativePath("hello").appending(components: "a", "b", "c", "..").pathString, "hello/a/b") XCTAssertEqual(RelativePath("hello").appending(RelativePath("a/b/../c/d")).pathString, "hello/a/c/d") - #else - XCTAssertEqual(AbsolutePath(AbsolutePath(#"C:\"#), RelativePath("")).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(AbsolutePath(#"C:\"#), RelativePath(".")).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(AbsolutePath(#"C:\"#), RelativePath("..")).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(AbsolutePath(#"C:\"#), RelativePath("bar")).pathString, #"C:\bar"#) - XCTAssertEqual(AbsolutePath(AbsolutePath(#"C:\foo\bar"#), RelativePath("..")).pathString, #"C:\foo"#) - XCTAssertEqual(AbsolutePath(AbsolutePath(#"C:\bar"#), RelativePath(#"..\foo"#)).pathString, #"C:\foo"#) - XCTAssertEqual(AbsolutePath(AbsolutePath(#"C:\bar"#), RelativePath(#"..\foo\..\\"#)).pathString, #"C:\\"#) - XCTAssertEqual(AbsolutePath(AbsolutePath(#"C:\bar\..\foo\..\\yabba\"#), RelativePath("a/b")).pathString, #"C:\yabba\a\b"#) - - XCTAssertEqual(AbsolutePath(#"C:\"#).appending(RelativePath("")).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\"#).appending(RelativePath(".")).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\"#).appending(RelativePath("..")).pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\"#).appending(RelativePath("bar")).pathString, #"C:\bar"#) - XCTAssertEqual(AbsolutePath(#"C:\foo\bar"#).appending(RelativePath("..")).pathString, #"C:\foo"#) - XCTAssertEqual(AbsolutePath(#"C:\bar"#).appending(RelativePath(#"..\foo"#)).pathString, #"C:\foo"#) - XCTAssertEqual(AbsolutePath(#"C:\bar"#).appending(RelativePath(#"..\foo\..\\"#)).pathString, #"C:\\"#) - XCTAssertEqual(AbsolutePath(#"C:\bar\..\foo\..\\yabba\"#).appending(RelativePath(#"a\b"#)).pathString, #"C:\yabba\a\b"#) - - XCTAssertEqual(AbsolutePath(#"C:\"#).appending(component: "a").pathString, #"C:\a"#) - XCTAssertEqual(AbsolutePath(#"C:\a"#).appending(component: "b").pathString, #"C:\a\b"#) - XCTAssertEqual(AbsolutePath(#"C:\"#).appending(components: "a", "b").pathString, #"C:\a\b"#) - XCTAssertEqual(AbsolutePath(#"C:\a"#).appending(components: "b", "c").pathString, #"C:\a\b\c"#) - - XCTAssertEqual(AbsolutePath(#"C:\a\b\c"#).appending(components: "", "c").pathString, #"C:\a\b\c\c"#) - XCTAssertEqual(AbsolutePath(#"C:\a\b\c"#).appending(components: "").pathString, #"C:\a\b\c"#) - XCTAssertEqual(AbsolutePath(#"C:\a\b\c"#).appending(components: ".").pathString, #"C:\a\b\c"#) - XCTAssertEqual(AbsolutePath(#"C:\a\b\c"#).appending(components: "..").pathString, #"C:\a\b"#) - XCTAssertEqual(AbsolutePath(#"C:\a\b\c"#).appending(components: "..", "d").pathString, #"C:\a\b\d"#) - XCTAssertEqual(AbsolutePath(#"C:\"#).appending(components: "..").pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\"#).appending(components: ".").pathString, #"C:\"#) - XCTAssertEqual(AbsolutePath(#"C:\"#).appending(components: "..", "a").pathString, #"C:\a"#) - - XCTAssertEqual(RelativePath("hello").appending(components: "a", "b", "c", "..").pathString, #"hello\a\b"#) - XCTAssertEqual(RelativePath("hello").appending(RelativePath(#"a\b\..\c\d"#)).pathString, #"hello\a\c\d"#) - - var longAbsolutePathUnderPathMax = generatePath(255) - XCTAssertEqual(AbsolutePath(longAbsolutePathUnderPathMax).appending(components: "a", "b", "c", "d", "e").pathString, - #"\\?\"# + longAbsolutePathUnderPathMax + #"\a\b\c\d\e"#) - longAbsolutePathUnderPathMax = generatePath(255) - XCTAssertEqual(AbsolutePath(longAbsolutePathUnderPathMax).appending(RelativePath(#"a\b\..\c\d"#)).pathString, - #"\\?\"# + longAbsolutePathUnderPathMax + #"\a\c\d"#) - #endif } func testPathComponents() { - #if !os(Windows) XCTAssertEqual(AbsolutePath("/").components, ["/"]) XCTAssertEqual(AbsolutePath("/.").components, ["/"]) XCTAssertEqual(AbsolutePath("/..").components, ["/"]) @@ -628,139 +278,28 @@ class PathTests: XCTestCase { XCTAssertEqual(RelativePath("./..").components, [".."]) XCTAssertEqual(RelativePath("a/../////../////./////").components, [".."]) XCTAssertEqual(RelativePath("abc").components, ["abc"]) - #else - XCTAssertEqual(AbsolutePath(#"C:\"#).components, ["C:"]) - XCTAssertEqual(AbsolutePath(#"C:\."#).components, ["C:"]) - XCTAssertEqual(AbsolutePath(#"C:\.."#).components, ["C:"]) - XCTAssertEqual(AbsolutePath(#"C:\bar"#).components, ["C:", "bar"]) - XCTAssertEqual(AbsolutePath(#"C:\foo/bar/.."#).components, ["C:", "foo"]) - XCTAssertEqual(AbsolutePath(#"C:\bar/../foo"#).components, ["C:", "foo"]) - XCTAssertEqual(AbsolutePath(#"C:\bar/../foo/..//"#).components, ["C:"]) - XCTAssertEqual(AbsolutePath(#"C:\bar/../foo/..//yabba/a/b/"#).components, ["C:", "yabba", "a", "b"]) - - XCTAssertEqual(AbsolutePath(#"\\?\C:\"#).components, ["C:"]) - XCTAssertEqual(AbsolutePath(#"\\?\C:\."#).components, ["C:"]) - XCTAssertEqual(AbsolutePath(#"\\?\C:\bar"#).components, ["C:", "bar"]) - XCTAssertEqual(AbsolutePath(#"\\?\C:\foo/bar/.."#).components, ["C:", "foo"]) - XCTAssertEqual(AbsolutePath(#"\\?\C:\bar/../foo"#).components, ["C:", "foo"]) - XCTAssertEqual(AbsolutePath(#"\\?\C:\bar/../foo/..//"#).components, ["C:"]) - XCTAssertEqual(AbsolutePath(#"\\?\C:\bar/../foo/..//yabba/a/b/"#).components, ["C:", "yabba", "a", "b"]) - - XCTAssertEqual(AbsolutePath(#"\\.\C:\"#).components, ["C:"]) - XCTAssertEqual(AbsolutePath(#"\\.\C:\."#).components, ["C:"]) - XCTAssertEqual(AbsolutePath(#"\\.\C:\bar"#).components, ["C:", "bar"]) - XCTAssertEqual(AbsolutePath(#"\\.\C:\foo/bar/.."#).components, ["C:", "foo"]) - XCTAssertEqual(AbsolutePath(#"\\.\C:\bar/../foo"#).components, ["C:", "foo"]) - XCTAssertEqual(AbsolutePath(#"\\.\C:\bar/../foo/..//"#).components, ["C:"]) - XCTAssertEqual(AbsolutePath(#"\\.\C:\bar/../foo/..//yabba/a/b/"#).components, ["C:", "yabba", "a", "b"]) - - XCTAssertEqual(RelativePath(#""#).components, ["."]) - XCTAssertEqual(RelativePath(#"."#).components, ["."]) - XCTAssertEqual(RelativePath(#".."#).components, [".."]) - XCTAssertEqual(RelativePath(#"bar"#).components, ["bar"]) - XCTAssertEqual(RelativePath(#"foo/bar/.."#).components, ["foo", "bar", ".."]) - XCTAssertEqual(RelativePath(#"bar/../foo"#).components, ["bar", "..", "foo"]) - XCTAssertEqual(RelativePath(#"bar/../foo/..//"#).components, ["bar", "..", "foo", ".."]) - XCTAssertEqual(RelativePath(#"bar/../foo/..//yabba/a/b/"#).components, ["bar", "..", "foo", "..", "yabba", "a", "b"]) - XCTAssertEqual(RelativePath(#"../.."#).components, ["..", ".."]) - XCTAssertEqual(RelativePath(#".././/.."#).components, ["..", ".", ".."]) - XCTAssertEqual(RelativePath(#"../a"#).components, ["..", "a"]) - XCTAssertEqual(RelativePath(#"../a/.."#).components, ["..", "a", ".."]) - XCTAssertEqual(RelativePath(#"a/.."#).components, ["a", ".."]) - XCTAssertEqual(RelativePath(#"./.."#).components, [".", ".."]) - XCTAssertEqual(RelativePath(#"a/../////../////./////"#).components, ["a", "..", "..", "."]) - XCTAssertEqual(RelativePath(#"abc"#).components, ["abc"]) - #endif } func testRelativePathFromAbsolutePaths() { - #if !os(Windows) - XCTAssertEqual(AbsolutePath("/").relative(to: AbsolutePath("/")), RelativePath(".")) - XCTAssertEqual(AbsolutePath("/a/b/c/d").relative(to: AbsolutePath("/")), RelativePath("a/b/c/d")) - XCTAssertEqual(AbsolutePath("/").relative(to: AbsolutePath("/a/b/c")), RelativePath("../../..")) - XCTAssertEqual(AbsolutePath("/a/b/c/d").relative(to: AbsolutePath("/a/b")), RelativePath("c/d")) - XCTAssertEqual(AbsolutePath("/a/b/c/d").relative(to: AbsolutePath("/a/b/c")), RelativePath("d")) - XCTAssertEqual(AbsolutePath("/a/b/c/d").relative(to: AbsolutePath("/a/c/d")), RelativePath("../../b/c/d")) - XCTAssertEqual(AbsolutePath("/a/b/c/d").relative(to: AbsolutePath("/b/c/d")), RelativePath("../../../a/b/c/d")) - #else - XCTAssertEqual(AbsolutePath(#"C:\"#).relative(to: AbsolutePath(#"C:\"#)), RelativePath(".")) - XCTAssertEqual(AbsolutePath(#"C:\a/b/c/d"#).relative(to: AbsolutePath(#"C:\"#)), RelativePath(#"a\b\c\d"#)) - XCTAssertEqual(AbsolutePath(#"C:\"#).relative(to: AbsolutePath(#"C:\a\b\c"#)), RelativePath(#"..\..\.."#)) - XCTAssertEqual(AbsolutePath(#"C:\a\b\c\d"#).relative(to: AbsolutePath(#"C:\a\b"#)), RelativePath(#"c\d"#)) - XCTAssertEqual(AbsolutePath(#"C:\a\b\c\d"#).relative(to: AbsolutePath(#"C:\a\b\c"#)), RelativePath(#"d"#)) - XCTAssertEqual(AbsolutePath(#"C:\a\b\c\d"#).relative(to: AbsolutePath(#"C:\a\c\d"#)), RelativePath(#"..\..\b\c\d"#)) - XCTAssertEqual(AbsolutePath(#"C:\a\b\c\d"#).relative(to: AbsolutePath(#"C:\b\c\d"#)), RelativePath(#"..\..\..\a\b\c\d"#)) - - XCTAssertEqual(AbsolutePath(#"\\?\C:\"#).relative(to: AbsolutePath(#"C:\"#)), RelativePath(".")) - XCTAssertEqual(AbsolutePath(#"\\?\C:\a/b/c/d"#).relative(to: AbsolutePath(#"C:\"#)), RelativePath(#"a\b\c\d"#)) - XCTAssertEqual(AbsolutePath(#"\\?\C:\"#).relative(to: AbsolutePath(#"C:\a\b\c"#)), RelativePath(#"..\..\.."#)) - XCTAssertEqual(AbsolutePath(#"\\?\C:\a\b\c\d"#).relative(to: AbsolutePath(#"C:\a\b"#)), RelativePath(#"c\d"#)) - XCTAssertEqual(AbsolutePath(#"\\?\C:\a\b\c\d"#).relative(to: AbsolutePath(#"C:\a\b\c"#)), RelativePath(#"d"#)) - XCTAssertEqual(AbsolutePath(#"\\?\C:\a\b\c\d"#).relative(to: AbsolutePath(#"C:\a\c\d"#)), RelativePath(#"..\..\b\c\d"#)) - XCTAssertEqual(AbsolutePath(#"\\?\C:\a\b\c\d"#).relative(to: AbsolutePath(#"C:\b\c\d"#)), RelativePath(#"..\..\..\a\b\c\d"#)) - - var longAbsolutePathOverPathMax = generatePath(264) - XCTAssertEqual( - AbsolutePath(longAbsolutePathOverPathMax).relative(to: AbsolutePath(longAbsolutePathOverPathMax.replacingOccurrences(of: #"\85\86\87\88\89\90"#, with: ""))), - RelativePath(#"85\86\87\88\89\90"#) - ) - var unParsedLongAbsolutePathOverPathMax = generatePath(264, useUnparsedPrefix: true) - XCTAssertEqual( - AbsolutePath(unParsedLongAbsolutePathOverPathMax).relative(to: AbsolutePath(unParsedLongAbsolutePathOverPathMax.replacingOccurrences(of: #"\85\86\87\88\89"#, with: ""))), - RelativePath(#"85\86\87\88\89"#) - ) - var deviceLongAbsolutePathOverPathMax = generatePath(264, useDevicePrefix: true) - XCTAssertEqual( - AbsolutePath(unParsedLongAbsolutePathOverPathMax).relative(to: AbsolutePath(unParsedLongAbsolutePathOverPathMax.replacingOccurrences(of: #"\85\86\87\88\89"#, with: ""))), - RelativePath(#"85\86\87\88\89"#) - ) - - #endif + XCTAssertEqual(AbsolutePath("/").relative(to: AbsolutePath("/")), RelativePath(".")); + XCTAssertEqual(AbsolutePath("/a/b/c/d").relative(to: AbsolutePath("/")), RelativePath("a/b/c/d")); + XCTAssertEqual(AbsolutePath("/").relative(to: AbsolutePath("/a/b/c")), RelativePath("../../..")); + XCTAssertEqual(AbsolutePath("/a/b/c/d").relative(to: AbsolutePath("/a/b")), RelativePath("c/d")); + XCTAssertEqual(AbsolutePath("/a/b/c/d").relative(to: AbsolutePath("/a/b/c")), RelativePath("d")); + XCTAssertEqual(AbsolutePath("/a/b/c/d").relative(to: AbsolutePath("/a/c/d")), RelativePath("../../b/c/d")); + XCTAssertEqual(AbsolutePath("/a/b/c/d").relative(to: AbsolutePath("/b/c/d")), RelativePath("../../../a/b/c/d")); } func testComparison() { - #if !os(Windows) - XCTAssertTrue(AbsolutePath("/") <= AbsolutePath("/")) - XCTAssertTrue(AbsolutePath("/abc") < AbsolutePath("/def")) - XCTAssertTrue(AbsolutePath("/2") <= AbsolutePath("/2.1")) - XCTAssertTrue(AbsolutePath("/3.1") > AbsolutePath("/2")) - XCTAssertTrue(AbsolutePath("/2") >= AbsolutePath("/2")) - XCTAssertTrue(AbsolutePath("/2.1") >= AbsolutePath("/2")) - #else - XCTAssertTrue(AbsolutePath(#"C:\"#) <= AbsolutePath(#"C:\"#)) - XCTAssertTrue(AbsolutePath(#"C:\abc"#) < AbsolutePath(#"C:\def"#)) - XCTAssertTrue(AbsolutePath(#"C:\2"#) <= AbsolutePath(#"C:\2.1"#)) - XCTAssertTrue(AbsolutePath(#"C:\3.1"#) > AbsolutePath(#"C:\2"#)) - XCTAssertTrue(AbsolutePath(#"C:\2"#) >= AbsolutePath(#"C:\2"#)) - XCTAssertTrue(AbsolutePath(#"C:\2.1"#) >= AbsolutePath(#"C:\2"#)) - - let longAbsolutePathOverPathMax = generatePath(260) - XCTAssertTrue(AbsolutePath(longAbsolutePathOverPathMax + #"\abc"#) < AbsolutePath(longAbsolutePathOverPathMax + #"\def"#)) - XCTAssertTrue(AbsolutePath(longAbsolutePathOverPathMax + #"\2"#) <= AbsolutePath(longAbsolutePathOverPathMax + #"\2.1"#)) - XCTAssertTrue(AbsolutePath(longAbsolutePathOverPathMax + #"\3.1"#) > AbsolutePath(longAbsolutePathOverPathMax + #"\2"#)) - XCTAssertTrue(AbsolutePath(longAbsolutePathOverPathMax + #"\2"#) >= AbsolutePath(longAbsolutePathOverPathMax + #"\2"#)) - XCTAssertTrue(AbsolutePath(longAbsolutePathOverPathMax + #"\2.1"#) >= AbsolutePath(longAbsolutePathOverPathMax + #"\2"#)) - - let unParsedLongAbsolutePathOverPathMax = generatePath(260, useUnparsedPrefix: true) - XCTAssertTrue(AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\abc"#) < AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\def"#)) - XCTAssertTrue(AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\2"#) <= AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\2.1"#)) - XCTAssertTrue(AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\3.1"#) > AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\2"#)) - XCTAssertTrue(AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\2"#) >= AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\2"#)) - XCTAssertTrue(AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\2.1"#) >= AbsolutePath(unParsedLongAbsolutePathOverPathMax + #"\2"#)) - - let deviceLongAbsolutePathOverPathMax = generatePath(260, useDevicePrefix: true) - XCTAssertTrue(AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\abc"#) < AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\def"#)) - XCTAssertTrue(AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\2"#) <= AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\2.1"#)) - XCTAssertTrue(AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\3.1"#) > AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\2"#)) - XCTAssertTrue(AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\2"#) >= AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\2"#)) - XCTAssertTrue(AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\2.1"#) >= AbsolutePath(deviceLongAbsolutePathOverPathMax + #"\2"#)) - - - #endif + XCTAssertTrue(AbsolutePath("/") <= AbsolutePath("/")); + XCTAssertTrue(AbsolutePath("/abc") < AbsolutePath("/def")); + XCTAssertTrue(AbsolutePath("/2") <= AbsolutePath("/2.1")); + XCTAssertTrue(AbsolutePath("/3.1") > AbsolutePath("/2")); + XCTAssertTrue(AbsolutePath("/2") >= AbsolutePath("/2")); + XCTAssertTrue(AbsolutePath("/2.1") >= AbsolutePath("/2")); } func testAncestry() { - #if !os(Windows) XCTAssertTrue(AbsolutePath("/a/b/c/d/e/f").isDescendantOfOrEqual(to: AbsolutePath("/a/b/c/d"))) XCTAssertTrue(AbsolutePath("/a/b/c/d/e/f.swift").isDescendantOfOrEqual(to: AbsolutePath("/a/b/c"))) XCTAssertTrue(AbsolutePath("/").isDescendantOfOrEqual(to: AbsolutePath("/"))) @@ -780,70 +319,9 @@ class PathTests: XCTestCase { XCTAssertFalse(AbsolutePath("/foo/bar").isAncestor(of: AbsolutePath("/foo/bar"))) XCTAssertTrue(AbsolutePath("/foo").isAncestor(of: AbsolutePath("/foo/bar"))) - #else - XCTAssertTrue(AbsolutePath(#"C:\a\b\c\d\e\f"#).isDescendantOfOrEqual(to: AbsolutePath(#"C:\a\b\c\d"#))) - XCTAssertTrue(AbsolutePath(#"C:\a\b\c\d\e\f.swift"#).isDescendantOfOrEqual(to: AbsolutePath(#"C:\a\b\c"#))) - XCTAssertTrue(AbsolutePath(#"C:\"#).isDescendantOfOrEqual(to: AbsolutePath(#"C:\"#))) - XCTAssertTrue(AbsolutePath(#"C:\foo\bar"#).isDescendantOfOrEqual(to: AbsolutePath(#"C:\"#))) - XCTAssertFalse(AbsolutePath(#"C:\foo\bar"#).isDescendantOfOrEqual(to: AbsolutePath(#"C:\foo\bar\baz"#))) - XCTAssertFalse(AbsolutePath(#"C:\foo\bar"#).isDescendantOfOrEqual(to: AbsolutePath(#"C:\bar"#))) - - XCTAssertTrue(AbsolutePath(#"\\?\C:\a\b\c\d\e\f"#).isDescendantOfOrEqual(to: AbsolutePath(#"C:\a\b\c\d"#))) - XCTAssertTrue(AbsolutePath(#"\\?\C:\a\b\c\d\e\f.swift"#).isDescendantOfOrEqual(to: AbsolutePath(#"C:\a\b\c"#))) - XCTAssertTrue(AbsolutePath(#"\\?\C:\"#).isDescendantOfOrEqual(to: AbsolutePath(#"C:\"#))) - XCTAssertTrue(AbsolutePath(#"\\?\C:\foo\bar"#).isDescendantOfOrEqual(to: AbsolutePath(#"C:\"#))) - XCTAssertFalse(AbsolutePath(#"\\?\C:\foo\bar"#).isDescendantOfOrEqual(to: AbsolutePath(#"C:\foo\bar\baz"#))) - XCTAssertFalse(AbsolutePath(#"\\?\C:\foo\bar"#).isDescendantOfOrEqual(to: AbsolutePath(#"C:\bar"#))) - - XCTAssertFalse(AbsolutePath(#"C:\foo\bar"#).isDescendant(of: AbsolutePath(#"C:\foo\bar"#))) - XCTAssertTrue(AbsolutePath(#"C:\foo\bar"#).isDescendant(of: AbsolutePath(#"C:\foo"#))) - - XCTAssertFalse(AbsolutePath(#"\\?\C:\foo\bar"#).isDescendant(of: AbsolutePath(#"C:\foo\bar"#))) - XCTAssertTrue(AbsolutePath(#"\\?\C:\foo\bar"#).isDescendant(of: AbsolutePath(#"C:\foo"#))) - - XCTAssertTrue(AbsolutePath(#"C:\a\b\c\d"#).isAncestorOfOrEqual(to: AbsolutePath(#"C:\a\b\c\d\e\f"#))) - XCTAssertTrue(AbsolutePath(#"C:\a\b\c"#).isAncestorOfOrEqual(to: AbsolutePath(#"C:\a\b\c\d\e\f.swift"#))) - XCTAssertTrue(AbsolutePath(#"C:\"#).isAncestorOfOrEqual(to: AbsolutePath(#"C:\"#))) - XCTAssertTrue(AbsolutePath(#"C:\"#).isAncestorOfOrEqual(to: AbsolutePath(#"C:\foo\bar"#))) - XCTAssertFalse(AbsolutePath(#"C:\foo\bar\baz"#).isAncestorOfOrEqual(to: AbsolutePath(#"C:\foo\bar"#))) - XCTAssertFalse(AbsolutePath(#"C:\bar"#).isAncestorOfOrEqual(to: AbsolutePath(#"C:\foo\bar"#))) - - XCTAssertTrue(AbsolutePath(#"\\?\C:\a\b\c\d"#).isAncestorOfOrEqual(to: AbsolutePath(#"C:\a\b\c\d\e\f"#))) - XCTAssertTrue(AbsolutePath(#"\\?\C:\a\b\c"#).isAncestorOfOrEqual(to: AbsolutePath(#"C:\a\b\c\d\e\f.swift"#))) - XCTAssertTrue(AbsolutePath(#"\\?\C:\"#).isAncestorOfOrEqual(to: AbsolutePath(#"C:\"#))) - XCTAssertTrue(AbsolutePath(#"\\?\C:\"#).isAncestorOfOrEqual(to: AbsolutePath(#"C:\foo\bar"#))) - XCTAssertFalse(AbsolutePath(#"\\?\C:\foo\bar\baz"#).isAncestorOfOrEqual(to: AbsolutePath(#"C:\foo\bar"#))) - XCTAssertFalse(AbsolutePath(#"\\?\C:\bar"#).isAncestorOfOrEqual(to: AbsolutePath(#"C:\foo\bar"#))) - - XCTAssertFalse(AbsolutePath(#"C:\foo\bar"#).isAncestor(of: AbsolutePath(#"C:\foo\bar"#))) - XCTAssertTrue(AbsolutePath(#"C:\foo"#).isAncestor(of: AbsolutePath(#"C:\foo\bar"#))) - - XCTAssertFalse(AbsolutePath(#"\\?\C:\foo\bar"#).isAncestor(of: AbsolutePath(#"\\?\C:\foo\bar"#))) - XCTAssertTrue(AbsolutePath(#"\\?\C:\foo"#).isAncestor(of: AbsolutePath(#"\\?\C:\foo\bar"#))) - - // Long/Long Ancestry - let longAbsolutePathOverPathMax = generatePath(265) - let longerAbsolutePathOverPathMax = generatePath(300) - XCTAssertTrue(AbsolutePath(longerAbsolutePathOverPathMax).isDescendant(of: AbsolutePath(longAbsolutePathOverPathMax))) - XCTAssertTrue(AbsolutePath(longerAbsolutePathOverPathMax).isDescendantOfOrEqual(to: AbsolutePath(longAbsolutePathOverPathMax))) - XCTAssertTrue(AbsolutePath(longAbsolutePathOverPathMax).isAncestorOfOrEqual(to: AbsolutePath(longerAbsolutePathOverPathMax))) - XCTAssertTrue(AbsolutePath(longAbsolutePathOverPathMax).isAncestor(of: AbsolutePath(longerAbsolutePathOverPathMax))) - - XCTAssertFalse(AbsolutePath(longerAbsolutePathOverPathMax).isAncestor(of: AbsolutePath(longAbsolutePathOverPathMax))) - XCTAssertFalse(AbsolutePath(longAbsolutePathOverPathMax).isAncestor(of: AbsolutePath(longAbsolutePathOverPathMax))) - XCTAssertFalse(AbsolutePath(longAbsolutePathOverPathMax + #"\baz"#).isAncestorOfOrEqual(to: AbsolutePath(longAbsolutePathOverPathMax))) - - // Long/Short to Long Ancestry - XCTAssertTrue(AbsolutePath(longAbsolutePathOverPathMax).isDescendant(of: AbsolutePath(#"C:\0\1\2"#))) - XCTAssertTrue(AbsolutePath(longAbsolutePathOverPathMax).isDescendantOfOrEqual(to: AbsolutePath(#"C:\0\1\2"#))) - XCTAssertTrue(AbsolutePath(#"C:\0\1\2"#).isAncestorOfOrEqual(to: AbsolutePath(longAbsolutePathOverPathMax))) - XCTAssertTrue(AbsolutePath(#"C:\0\1\2"#).isAncestor(of: AbsolutePath(longAbsolutePathOverPathMax))) - - #endif } func testAbsolutePathValidation() { - #if !os(Windows) XCTAssertNoThrow(try AbsolutePath(validating: "/a/b/c/d")) XCTAssertThrowsError(try AbsolutePath(validating: "~/a/b/d")) { error in @@ -853,47 +331,19 @@ class PathTests: XCTestCase { XCTAssertThrowsError(try AbsolutePath(validating: "a/b/d")) { error in XCTAssertEqual("\(error)", "invalid absolute path 'a/b/d'") } - #else - XCTAssertNoThrow(try AbsolutePath(validating: #"C:\a\b\c\d"#)) - - XCTAssertThrowsError(try AbsolutePath(validating: #"~\a\b\d"#)) { error in - XCTAssertEqual("\(error)", #"invalid absolute path '~\a\b\d'"#) - } - - XCTAssertThrowsError(try AbsolutePath(validating: #"a\b\d"#)) { error in - XCTAssertEqual("\(error)", #"invalid absolute path 'a\b\d'"#) - } - - XCTAssertNoThrow(try AbsolutePath(validating: #"\\?\C:\a\b\c\d"#)) - XCTAssertNoThrow(try AbsolutePath(validating: #"\\.\C:\a\b\c\d"#)) - - let relativeLongPath = generatePath(265, absolute: false) - XCTAssertThrowsError(try AbsolutePath(validating: relativeLongPath)) { error in - XCTAssertEqual("\(error)", "invalid absolute path '\(relativeLongPath)'") - } - - #endif } func testRelativePathValidation() { - #if !os(Windows) XCTAssertNoThrow(try RelativePath(validating: "a/b/c/d")) XCTAssertThrowsError(try RelativePath(validating: "/a/b/d")) { error in XCTAssertEqual("\(error)", "invalid relative path '/a/b/d'; relative path should not begin with '/'") + //XCTAssertEqual("\(error)", "invalid relative path '/a/b/d'; relative path should not begin with '/' or '~'") } - #else - XCTAssertNoThrow(try RelativePath(validating: #"a\b\c\d"#)) - XCTAssertThrowsError(try RelativePath(validating: #"\a\b\d"#)) { error in - XCTAssertEqual("\(error)", #"invalid relative path '\a\b\d'; relative path should not begin with '\'"#) - } - - let absoluteLongPath = generatePath(265, absolute: true) - XCTAssertThrowsError(try RelativePath(validating: absoluteLongPath)) { error in - XCTAssertEqual("\(error)", "invalid relative path '\(absoluteLongPath)'; relative path should not begin with '\\'") - } - #endif + /*XCTAssertThrowsError(try RelativePath(validating: "~/a/b/d")) { error in + XCTAssertEqual("\(error)", "invalid relative path '~/a/b/d'; relative path should not begin with '/' or '~'") + }*/ } func testCodable() throws { @@ -909,42 +359,36 @@ class PathTests: XCTestCase { var path: String } - #if os(Windows) - let isWindowsOS = true - #else - let isWindowsOS = false - #endif - do { - let foo = Foo(path: !isWindowsOS ? "/path/to/foo" : #"\path\to\foo"#) + let foo = Foo(path: "/path/to/foo") let data = try JSONEncoder().encode(foo) let decodedFoo = try JSONDecoder().decode(Foo.self, from: data) XCTAssertEqual(foo, decodedFoo) } do { - let foo = Foo(path: !isWindowsOS ? "/path/to/../to/foo" : #"C:\path\to\..\to\foo"#) + let foo = Foo(path: "/path/to/../to/foo") let data = try JSONEncoder().encode(foo) let decodedFoo = try JSONDecoder().decode(Foo.self, from: data) XCTAssertEqual(foo, decodedFoo) - XCTAssertEqual(foo.path.pathString, !isWindowsOS ? "/path/to/foo" : #"C:\path\to\foo"#) - XCTAssertEqual(decodedFoo.path.pathString, !isWindowsOS ? "/path/to/foo" : #"C:\path\to\foo"#) + XCTAssertEqual(foo.path.pathString, "/path/to/foo") + XCTAssertEqual(decodedFoo.path.pathString, "/path/to/foo") } do { - let bar = Bar(path: !isWindowsOS ? "path/to/bar" : #"path/to/bar"#) + let bar = Bar(path: "path/to/bar") let data = try JSONEncoder().encode(bar) let decodedBar = try JSONDecoder().decode(Bar.self, from: data) XCTAssertEqual(bar, decodedBar) } do { - let bar = Bar(path: !isWindowsOS ? "path/to/../to/bar" : #"path\to\..\to\bar"#) + let bar = Bar(path: "path/to/../to/bar") let data = try JSONEncoder().encode(bar) let decodedBar = try JSONDecoder().decode(Bar.self, from: data) XCTAssertEqual(bar, decodedBar) - XCTAssertEqual(bar.path.pathString, !isWindowsOS ? "path/to/bar" : #"path\to\..\to\bar"#) - XCTAssertEqual(decodedBar.path.pathString, !isWindowsOS ? "path/to/bar" : #"path\to\..\to\bar"#) + XCTAssertEqual(bar.path.pathString, "path/to/bar") + XCTAssertEqual(decodedBar.path.pathString, "path/to/bar") } do { @@ -959,31 +403,29 @@ class PathTests: XCTestCase { } do { - let data = try JSONEncoder().encode(Baz(path: !isWindowsOS ? "/foo" : #"C:\foo"#)) + let data = try JSONEncoder().encode(Baz(path: "/foo")) XCTAssertThrowsError(try JSONDecoder().decode(Bar.self, from: data)) } } + // FIXME: We also need tests for join() operations. + + // FIXME: We also need tests for dirname, basename, suffix, etc. + + // FIXME: We also need test for stat() operations. + #if os(Windows) - func testDiskDesignatorNormalization() { + func testNormalization() { XCTAssertEqual( - AbsolutePath(#"C:\Users\compnerd\AppData\Local\Programs\Swift\Toolchains\0.0.0+Asserts\usr\bin\swiftc.exe"#).pathString, + AbsolutePath(#"C:\Users\compnerd\AppData\Local\Programs\Swift\Toolchains\0.0.0+Asserts\usr\bin\swiftc.exe"#) + .pathString, #"C:\Users\compnerd\AppData\Local\Programs\Swift\Toolchains\0.0.0+Asserts\usr\bin\swiftc.exe"# ) XCTAssertEqual( - AbsolutePath(#"c:\Users\compnerd\AppData\Local\Programs\Swift\Toolchains\0.0.0+Asserts\usr\bin\swiftc.exe"#).pathString, + AbsolutePath(#"c:\Users\compnerd\AppData\Local\Programs\Swift\Toolchains\0.0.0+Asserts\usr\bin\swiftc.exe"#) + .pathString, #"C:\Users\compnerd\AppData\Local\Programs\Swift\Toolchains\0.0.0+Asserts\usr\bin\swiftc.exe"# ) - - let absoluteLongPath = generatePath(265) - XCTAssertEqual( - AbsolutePath(absoluteLongPath).pathString, - #"\\?\"# + absoluteLongPath - ) - XCTAssertEqual( - AbsolutePath(absoluteLongPath.replacingOccurrences(of: "C:", with: "c:")).pathString, - #"\\?\"# + absoluteLongPath - ) } #endif }