Skip to content

Commit 370776d

Browse files
avriyaciidgh
authored andcommitted
Add RelativePath validating init
1 parent e302bea commit 370776d

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

Sources/Basic/Path.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,16 @@ public struct RelativePath: Hashable {
252252
_impl = PathImpl(string: normalize(relative: string))
253253
}
254254

255+
/// Convenience initializer that verifies that the path is relative.
256+
public init(validating path: String) throws {
257+
switch path.first {
258+
case "/", "~":
259+
throw PathValidationError.invalidRelativePath(path)
260+
default:
261+
self.init(path)
262+
}
263+
}
264+
255265
/// Directory component. For a relative path without any path separators,
256266
/// this is the `.` string instead of the empty string.
257267
public var dirname: String {
@@ -455,15 +465,18 @@ extension PathImpl {
455465
public enum PathValidationError: Error {
456466
case startsWithTilde(String)
457467
case invalidAbsolutePath(String)
468+
case invalidRelativePath(String)
458469
}
459470

460471
extension PathValidationError: CustomStringConvertible {
461472
public var description: String {
462473
switch self {
463474
case .startsWithTilde(let path):
464-
return "invalid absolute path '\(path)'; absolute path must begin with /"
475+
return "invalid absolute path '\(path)'; absolute path must begin with '/'"
465476
case .invalidAbsolutePath(let path):
466477
return "invalid absolute path '\(path)'"
478+
case .invalidRelativePath(let path):
479+
return "invalid relative path '\(path)'; relative path should not begin with '/' or '~'"
467480
}
468481
}
469482
}

Tests/BasicTests/PathTests.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,14 +276,26 @@ class PathTests: XCTestCase {
276276
XCTAssertNoThrow(try AbsolutePath(validating: "/a/b/c/d"))
277277

278278
XCTAssertThrowsError(try AbsolutePath(validating: "~/a/b/d")) { error in
279-
XCTAssertEqual("\(error)", "invalid absolute path '~/a/b/d'; absolute path must begin with /")
279+
XCTAssertEqual("\(error)", "invalid absolute path '~/a/b/d'; absolute path must begin with '/'")
280280
}
281281

282282
XCTAssertThrowsError(try AbsolutePath(validating: "a/b/d")) { error in
283283
XCTAssertEqual("\(error)", "invalid absolute path 'a/b/d'")
284284
}
285285
}
286286

287+
func testRelativePathValidation() {
288+
XCTAssertNoThrow(try RelativePath(validating: "a/b/c/d"))
289+
290+
XCTAssertThrowsError(try RelativePath(validating: "/a/b/d")) { error in
291+
XCTAssertEqual("\(error)", "invalid relative path '/a/b/d'; relative path should not begin with '/' or '~'")
292+
}
293+
294+
XCTAssertThrowsError(try RelativePath(validating: "~/a/b/d")) { error in
295+
XCTAssertEqual("\(error)", "invalid relative path '~/a/b/d'; relative path should not begin with '/' or '~'")
296+
}
297+
}
298+
287299
// FIXME: We also need tests for join() operations.
288300

289301
// FIXME: We also need tests for dirname, basename, suffix, etc.

0 commit comments

Comments
 (0)