import Spectre import PathKit import XCTest import XcodeGenCore import TestSupport class PathExtensionsTests: XCTestCase { func testPathRelativeToPath() { func relativePath(to path: String, from base: String) throws -> String { try Path(path).relativePath(from: Path(base)).string } // These are based on ruby's tests for Pathname#relative_path_from: // https://github.com/ruby/ruby/blob/7c2bbd1c7d40a30583844d649045824161772e36/test/pathname/test_pathname.rb#L297 describe { $0.it("resolves single-level paths") { try expect(relativePath(to: "a", from: "b")) == "../a" try expect(relativePath(to: "a", from: "b/")) == "../a" try expect(relativePath(to: "a/", from: "b")) == "../a" try expect(relativePath(to: "a/", from: "b/")) == "../a" try expect(relativePath(to: "/a", from: "/b")) == "../a" try expect(relativePath(to: "/a", from: "/b/")) == "../a" try expect(relativePath(to: "/a/", from: "/b")) == "../a" try expect(relativePath(to: "/a/", from: "/b/")) == "../a" } $0.it("resolves paths with a common parent") { try expect(relativePath(to: "a/b", from: "a/c")) == "../b" try expect(relativePath(to: "../a", from: "../b")) == "../a" } $0.it("resolves dot paths") { try expect(relativePath(to: "a", from: ".")) == "a" try expect(relativePath(to: ".", from: "a")) == ".." try expect(relativePath(to: ".", from: ".")) == "." try expect(relativePath(to: "..", from: "..")) == "." try expect(relativePath(to: "..", from: ".")) == ".." } $0.it("resolves multi-level paths") { try expect(relativePath(to: "/a/b/c/d", from: "/a/b")) == "c/d" try expect(relativePath(to: "/a/b", from: "/a/b/c/d")) == "../.." try expect(relativePath(to: "/e", from: "/a/b/c/d")) == "../../../../e" try expect(relativePath(to: "a/b/c", from: "a/d")) == "../b/c" try expect(relativePath(to: "/../a", from: "/b")) == "../a" try expect(relativePath(to: "../a", from: "b")) == "../../a" try expect(relativePath(to: "/a/../../b", from: "/b")) == "." try expect(relativePath(to: "a/..", from: "a")) == ".." try expect(relativePath(to: "a/../b", from: "b")) == "." try expect(relativePath(to: "/a/c", from: "/a/b/c")) == "../../c" } $0.it("backtracks on a non-normalized base path") { try expect(relativePath(to: "a", from: "b/..")) == "a" try expect(relativePath(to: "b/c", from: "b/..")) == "b/c" } $0.it("throws when given unresolvable paths") { try expect(relativePath(to: "/", from: ".")).toThrow() try expect(relativePath(to: ".", from: "/")).toThrow() try expect(relativePath(to: "a", from: "..")).toThrow() try expect(relativePath(to: ".", from: "..")).toThrow() try expect(relativePath(to: "a", from: "b/../..")).toThrow() } } } }