From eb96a4281a4b869b55598f364b8bf2077a13bd6b Mon Sep 17 00:00:00 2001 From: John Sundell Date: Fri, 5 Apr 2019 18:14:47 +0200 Subject: [PATCH] Add API for computing a path relative to a parent folder This enables an easy way to work with relative paths, for example when dealing with multiple files that are within the same folder structure. --- Sources/Files.swift | 24 ++++++++++++++++++++++++ Tests/FilesTests/FilesTests.swift | 23 +++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/Sources/Files.swift b/Sources/Files.swift index 23b87ab..83ed08c 100644 --- a/Sources/Files.swift +++ b/Sources/Files.swift @@ -237,6 +237,30 @@ public class FileSystem { self.name = pathComponents[pathComponents.count - 2] } } + + /** + * Return this item's path relative to a given parent folder + * + * - parameter folder: The parent folder to return a relative path to + * + * - returns: Either a relative path, if the passed folder is indeed + * a parent (even if it's not a direct one) for this item. Otherwise + * the item's full path is returned. + */ + public func path(relativeTo folder: Folder) -> String { + guard path.hasPrefix(folder.path) else { + return path + } + + let index = path.index(path.startIndex, offsetBy: folder.path.count) + var subpath = path[index...] + + if subpath.hasSuffix("/") { + subpath.removeLast() + } + + return String(subpath) + } /** * Rename the item diff --git a/Tests/FilesTests/FilesTests.swift b/Tests/FilesTests/FilesTests.swift index 6492a4a..e56b621 100644 --- a/Tests/FilesTests/FilesTests.swift +++ b/Tests/FilesTests/FilesTests.swift @@ -589,6 +589,27 @@ class FilesTests: XCTestCase { } } + func testRelativePaths() { + performTest { + let file = try folder.createFile(named: "FileA") + let subfolder = try folder.createSubfolder(named: "Folder") + let fileInSubfolder = try subfolder.createFile(named: "FileB") + + XCTAssertEqual(file.path(relativeTo: folder), "FileA") + XCTAssertEqual(subfolder.path(relativeTo: folder), "Folder") + XCTAssertEqual(fileInSubfolder.path(relativeTo: folder), "Folder/FileB") + } + } + + func testRelativePathIsAbsolutePathForNonParent() { + performTest { + let file = try folder.createFile(named: "FileA") + let subfolder = try folder.createSubfolder(named: "Folder") + + XCTAssertEqual(file.path(relativeTo: subfolder), file.path) + } + } + func testCreatingFileFromFileSystem() { performTest { let fileName = "three" @@ -789,6 +810,8 @@ class FilesTests: XCTestCase { ("testAccessingHomeFolder", testAccessingHomeFolder), ("testAccessingCurrentWorkingDirectory", testAccessingCurrentWorkingDirectory), ("testNameExcludingExtensionWithLongFileName", testNameExcludingExtensionWithLongFileName), + ("testRelativePaths", testRelativePaths), + ("testRelativePathIsAbsolutePathForNonParent", testRelativePathIsAbsolutePathForNonParent), ("testCreatingFileFromFileSystem", testCreatingFileFromFileSystem), ("testCreateFileFromFileSystemIfNeeded", testCreateFileFromFileSystemIfNeeded), ("testCreatingFolderFromFileSystem", testCreatingFolderFromFileSystem),