Skip to content

Commit e687dcd

Browse files
authored
feat: add characters validation rule (#67)
* feat: add characters validation rule * test: add unit tests for the characters validation rule * docs: update `README.md`
1 parent 37278bc commit e687dcd

File tree

3 files changed

+134
-0
lines changed

3 files changed

+134
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ struct RegistrationView: View {
303303
| `URLValidationRule` | Validates URL format | `URLValidationRule(error: "Please enter a valid URL")` |
304304
| `CreditCardValidationRule` | Validates credit card numbers (Luhn algorithm) | `CreditCardValidationRule(error: "Invalid card number")` |
305305
| `EmailValidationRule` | Validates email format | `EmailValidationRule(error: "Please enter a valid email")` |
306+
| `CharactersValidationRule` | Validates that a string contains only characters from the allowed CharacterSet | `CharactersValidationRule(characterSet: .letters, error: "Invalid characters")` |
306307

307308
## Custom Validators
308309

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// Validator
3+
// Copyright © 2025 Space Code. All rights reserved.
4+
//
5+
6+
import Foundation
7+
8+
/// A characters validation rule.
9+
public struct CharactersValidationRule: IValidationRule {
10+
// MARK: Types
11+
12+
public typealias Input = String
13+
14+
// MARK: Properties
15+
16+
public let characterSet: CharacterSet
17+
18+
/// The validation error.
19+
public let error: IValidationError
20+
21+
// MARK: Initialization
22+
23+
public init(characterSet: CharacterSet, error: IValidationError) {
24+
self.characterSet = characterSet
25+
self.error = error
26+
}
27+
28+
// MARK: IValidationRule
29+
30+
public func validate(input: String) -> Bool {
31+
input.rangeOfCharacter(from: characterSet.inverted) == .none
32+
}
33+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//
2+
// Validator
3+
// Copyright © 2025 Space Code. All rights reserved.
4+
//
5+
6+
@testable import ValidatorCore
7+
import XCTest
8+
9+
// MARK: - CharactersValidationRuleTests
10+
11+
final class CharactersValidationRuleTests: XCTestCase {
12+
// MARK: - Properties
13+
14+
private var sut: CharactersValidationRule!
15+
16+
// MARK: - Setup / Teardown
17+
18+
override func setUp() {
19+
super.setUp()
20+
sut = CharactersValidationRule(characterSet: .letters, error: String.error)
21+
}
22+
23+
override func tearDown() {
24+
sut = nil
25+
super.tearDown()
26+
}
27+
28+
// MARK: - Valid Input Tests
29+
30+
func testValidate_WithOnlyAllowedCharacters_ReturnsTrue() {
31+
// Given
32+
let input = "HelloWorld"
33+
34+
// When
35+
let result = sut.validate(input: input)
36+
37+
// Then
38+
XCTAssertTrue(result)
39+
}
40+
41+
// MARK: - Invalid Input Tests
42+
43+
func testValidate_WithDisallowedCharacters_ReturnsFalse() {
44+
// Given
45+
let input = "Hello123"
46+
47+
// When
48+
let result = sut.validate(input: input)
49+
50+
// Then
51+
XCTAssertFalse(result)
52+
}
53+
54+
func testValidate_WithSpecialCharacters_ReturnsFalse() {
55+
// Given
56+
let input = "Hi!"
57+
58+
// When
59+
let result = sut.validate(input: input)
60+
61+
// Then
62+
XCTAssertFalse(result)
63+
}
64+
65+
// MARK: - Edge Cases
66+
67+
func testValidate_EmptyString_ReturnsTrue() {
68+
// Given
69+
let input = ""
70+
71+
// When
72+
let result = sut.validate(input: input)
73+
74+
// Then
75+
XCTAssertTrue(result)
76+
}
77+
78+
func testValidate_UnicodeCharacters_WhenNotAllowed_ReturnsTrue() {
79+
// Given
80+
let input = "Привет"
81+
82+
// When
83+
let result = sut.validate(input: input)
84+
85+
// Then
86+
XCTAssertTrue(result)
87+
}
88+
89+
// MARK: - Error Property
90+
91+
func testErrorProperty_ReturnsProvidedError() {
92+
XCTAssertEqual(sut.error as? String, String.error)
93+
}
94+
}
95+
96+
// MARK: Constants
97+
98+
private extension String {
99+
static let error = "Invalid characters"
100+
}

0 commit comments

Comments
 (0)