Skip to content
This repository was archived by the owner on Nov 16, 2020. It is now read-only.

Commit c5a34b3

Browse files
committed
Use better error messages for RangeValidator and CountValidator
"is not larger than X" is replaced with: * "is less than X" * "is shorter than X characters" * "is shorter than X items" "is larger than X" is replaced with: * "is greater than X" * "is longer than X characters" * "is longer than X items"
1 parent 156f8ad commit c5a34b3

File tree

3 files changed

+49
-19
lines changed

3 files changed

+49
-19
lines changed

Sources/Validation/Validators/CountValidator.swift

+13-12
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,12 @@ extension Validator where T: Collection {
3838
fileprivate struct CountValidator<T>: ValidatorType where T: Collection {
3939
/// See `ValidatorType`.
4040
var validatorReadable: String {
41-
let x: String
42-
if T.self is String.Type {
43-
x = "characters"
44-
} else {
45-
x = "items"
46-
}
47-
4841
if let min = self.min, let max = self.max {
49-
return "between \(min) and \(max) \(x)"
42+
return "between \(min) and \(elementDescription(count: max))"
5043
} else if let min = self.min {
51-
return "at least \(min) \(x)"
44+
return "at least \(elementDescription(count: min))"
5245
} else if let max = self.max {
53-
return "at most \(max) \(x)"
46+
return "at most \(elementDescription(count: max))"
5447
} else {
5548
return "valid"
5649
}
@@ -75,14 +68,22 @@ fileprivate struct CountValidator<T>: ValidatorType where T: Collection {
7568
func validate(_ data: T) throws {
7669
if let min = self.min {
7770
guard data.count >= min else {
78-
throw BasicValidationError("is not larger than \(min)")
71+
throw BasicValidationError("is shorter than \(elementDescription(count: min))")
7972
}
8073
}
8174

8275
if let max = self.max {
8376
guard data.count <= max else {
84-
throw BasicValidationError("is larger than \(max)")
77+
throw BasicValidationError("is longer than \(elementDescription(count: max))")
8578
}
8679
}
8780
}
81+
82+
private func elementDescription(count: Int) -> String {
83+
if T.Element.self is Character.Type {
84+
return count == 1 ? "1 character" : "\(count) characters"
85+
} else {
86+
return count == 1 ? "1 item" : "\(count) items"
87+
}
88+
}
8889
}

Sources/Validation/Validators/RangeValidator.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,13 @@ fileprivate struct RangeValidator<T>: ValidatorType where T: Comparable {
7070
func validate(_ data: T) throws {
7171
if let min = self.min {
7272
guard data >= min else {
73-
throw BasicValidationError("is not larger than \(min)")
73+
throw BasicValidationError("is less than \(min)")
7474
}
7575
}
7676

7777
if let max = self.max {
7878
guard data <= max else {
79-
throw BasicValidationError("is larger than \(max)")
79+
throw BasicValidationError("is greater than \(max)")
8080
}
8181
}
8282
}

Tests/ValidationTests/ValidationTests.swift

+34-5
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,48 @@ class ValidationTests: XCTestCase {
5050
try Validator<Int>.range(-5...5).validate(4)
5151
try Validator<Int>.range(-5...5).validate(5)
5252
try Validator<Int>.range(-5...5).validate(-5)
53-
XCTAssertThrowsError(try Validator<Int>.range(-5...5).validate(6))
54-
XCTAssertThrowsError(try Validator<Int>.range(-5...5).validate(-6))
53+
XCTAssertThrowsError(try Validator<Int>.range(-5...5).validate(6)) { error in
54+
XCTAssertEqual((error as? ValidationError)?.reason, "data is greater than 5")
55+
}
56+
XCTAssertThrowsError(try Validator<Int>.range(-5...5).validate(-6)) { error in
57+
XCTAssertEqual((error as? ValidationError)?.reason, "data is less than -5")
58+
}
5559

5660
try Validator<Int>.range(5...).validate(.max)
5761

58-
try Validator<Int>.range(-5...5).validate(4)
59-
XCTAssertThrowsError(try Validator<Int>.range(-5...5).validate(6))
60-
6162
try Validator<Int>.range(-5..<6).validate(-5)
6263
try Validator<Int>.range(-5..<6).validate(-4)
6364
try Validator<Int>.range(-5..<6).validate(5)
6465
XCTAssertThrowsError(try Validator<Int>.range(-5..<6).validate(-6))
6566
XCTAssertThrowsError(try Validator<Int>.range(-5..<6).validate(6))
6667
}
6768

69+
func testCountCharacters() throws {
70+
let validator = Validator<String>.count(1...6)
71+
try validator.validate("1")
72+
try validator.validate("123")
73+
try validator.validate("123456")
74+
XCTAssertThrowsError(try validator.validate("")) { error in
75+
XCTAssertEqual((error as? ValidationError)?.reason, "data is shorter than 1 character")
76+
}
77+
XCTAssertThrowsError(try validator.validate("1234567")) { error in
78+
XCTAssertEqual((error as? ValidationError)?.reason, "data is longer than 6 characters")
79+
}
80+
}
81+
82+
func testCountItems() throws {
83+
let validator = Validator<[Int]>.count(1...6)
84+
try validator.validate([1])
85+
try validator.validate([1, 2, 3])
86+
try validator.validate([1, 2, 3, 4, 5, 6])
87+
XCTAssertThrowsError(try validator.validate([])) { error in
88+
XCTAssertEqual((error as? ValidationError)?.reason, "data is shorter than 1 item")
89+
}
90+
XCTAssertThrowsError(try validator.validate([1, 2, 3, 4, 5, 6, 7])) { error in
91+
XCTAssertEqual((error as? ValidationError)?.reason, "data is longer than 6 items")
92+
}
93+
}
94+
6895
func testURL() throws {
6996
try Validator<String>.url.validate("https://www.somedomain.com/somepath.png")
7097
try Validator<String>.url.validate("https://www.somedomain.com/")
@@ -80,6 +107,8 @@ class ValidationTests: XCTestCase {
80107
("testEmpty", testEmpty),
81108
("testEmail", testEmail),
82109
("testRange", testRange),
110+
("testCountCharacters", testCountCharacters),
111+
("testCountItems", testCountItems),
83112
("testURL", testURL),
84113
]
85114
}

0 commit comments

Comments
 (0)