File tree Expand file tree Collapse file tree 2 files changed +27
-2
lines changed Expand file tree Collapse file tree 2 files changed +27
-2
lines changed Original file line number Diff line number Diff line change @@ -252,6 +252,16 @@ public struct RelativePath: Hashable {
252
252
_impl = PathImpl ( string: normalize ( relative: string) )
253
253
}
254
254
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
+
255
265
/// Directory component. For a relative path without any path separators,
256
266
/// this is the `.` string instead of the empty string.
257
267
public var dirname : String {
@@ -455,15 +465,18 @@ extension PathImpl {
455
465
public enum PathValidationError : Error {
456
466
case startsWithTilde( String )
457
467
case invalidAbsolutePath( String )
468
+ case invalidRelativePath( String )
458
469
}
459
470
460
471
extension PathValidationError : CustomStringConvertible {
461
472
public var description : String {
462
473
switch self {
463
474
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 '/' "
465
476
case . invalidAbsolutePath( let path) :
466
477
return " invalid absolute path ' \( path) ' "
478
+ case . invalidRelativePath( let path) :
479
+ return " invalid relative path ' \( path) '; relative path should not begin with '/' or '~' "
467
480
}
468
481
}
469
482
}
Original file line number Diff line number Diff line change @@ -276,14 +276,26 @@ class PathTests: XCTestCase {
276
276
XCTAssertNoThrow ( try AbsolutePath ( validating: " /a/b/c/d " ) )
277
277
278
278
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 '/' " )
280
280
}
281
281
282
282
XCTAssertThrowsError ( try AbsolutePath ( validating: " a/b/d " ) ) { error in
283
283
XCTAssertEqual ( " \( error) " , " invalid absolute path 'a/b/d' " )
284
284
}
285
285
}
286
286
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
+
287
299
// FIXME: We also need tests for join() operations.
288
300
289
301
// FIXME: We also need tests for dirname, basename, suffix, etc.
You can’t perform that action at this time.
0 commit comments