Skip to content

Commit 2a590f4

Browse files
committed
feat: add contains substring validation rule
1 parent f8330a9 commit 2a590f4

File tree

4 files changed

+118
-0
lines changed

4 files changed

+118
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ struct RegistrationView: View {
311311
| `NilValidationRule` | Validates that value is nil | `NilValidationRule(error: "Value must be nil")`
312312
| `PositiveNumberValidationRule` | Validates that value is positive | `PositiveNumberValidationRule(error: "Value must be positive")`
313313
| `NoWhitespaceValidationRule` | Validates that a string does not contain any whitespace characters | `NoWhitespaceValidationRule(error: "Spaces are not allowed")`
314+
| `ContainsValidationRule` | Validates that a string contains a specific substring | `ContainsValidationRule(substring: "@", error: "Must contain @")`
314315

315316
## Custom Validators
316317

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//
2+
// Validator
3+
// Copyright © 2025 Space Code. All rights reserved.
4+
//
5+
6+
/// Validates that a string contains a specific substring.
7+
///
8+
/// # Example:
9+
/// ```swift
10+
/// let rule = ContainsValidationRule(substring: "@", error: "Must contain @")
11+
/// rule.validate(input: "user@example.com") // true
12+
/// ```
13+
public struct ContainsValidationRule: IValidationRule {
14+
// MARK: Types
15+
16+
public typealias Input = String
17+
18+
// MARK: Properties
19+
20+
/// The substring that the input must contain.
21+
public let substring: String
22+
23+
/// The validation error.
24+
public let error: IValidationError
25+
26+
// MARK: Initialization
27+
28+
/// Creates a validation rule that checks whether the input contains a required substring.
29+
///
30+
/// - Parameters:
31+
/// - substring: The string the input must contain.
32+
/// - error: The validation error associated with failed validation.
33+
public init(substring: String, error: IValidationError) {
34+
self.substring = substring
35+
self.error = error
36+
}
37+
38+
// MARK: IValidationRule
39+
40+
public func validate(input: String) -> Bool {
41+
input.contains(substring)
42+
}
43+
}

Sources/ValidatorCore/Validator.docc/Overview.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ ValidatorCore contains all core validation rules, utilities, and mechanisms for
3434
- ``NilValidationRule``
3535
- ``PositiveNumberValidationRule``
3636
- ``NoWhitespaceValidationRuleTests``
37+
- ``ContainsValidationRule``
3738

3839
### Articles
3940

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//
2+
// Validator
3+
// Copyright © 2025 Space Code. All rights reserved.
4+
//
5+
6+
@testable import ValidatorCore
7+
import XCTest
8+
9+
// MARK: - ContainsValidationRuleTests
10+
11+
final class ContainsValidationRuleTests: XCTestCase {
12+
// MARK: Properties
13+
14+
private var sut: ContainsValidationRule!
15+
16+
// MARK: XCTestCase
17+
18+
override func setUp() {
19+
super.setUp()
20+
sut = ContainsValidationRule(substring: "@", error: String.error)
21+
}
22+
23+
override func tearDown() {
24+
sut = nil
25+
super.tearDown()
26+
}
27+
28+
// MARK: Tests
29+
30+
func test_thatContainsValidationRuleSetsProperties() {
31+
// then
32+
XCTAssertEqual(sut.substring, "@")
33+
XCTAssertEqual(sut.error.message, .error)
34+
}
35+
36+
func test_thatRuleReturnsTrue_whenInputContainsSubstring() {
37+
// when
38+
let result = sut.validate(input: "user@example.com")
39+
40+
// then
41+
XCTAssertTrue(result)
42+
}
43+
44+
func test_thatRuleReturnsFalse_whenInputDoesNotContainSubstring() {
45+
// when
46+
let result = sut.validate(input: "userexample.com")
47+
48+
// then
49+
XCTAssertFalse(result)
50+
}
51+
52+
func test_thatRuleReturnsFalse_whenInputIsEmpty() {
53+
// when
54+
let result = sut.validate(input: "")
55+
56+
// then
57+
XCTAssertFalse(result)
58+
}
59+
60+
func test_thatRuleReturnsTrue_whenSubstringAppearsMultipleTimes() {
61+
// when
62+
let result = sut.validate(input: "@user@domain.com")
63+
64+
// then
65+
XCTAssertTrue(result)
66+
}
67+
}
68+
69+
// MARK: - Constants
70+
71+
private extension String {
72+
static let error = "Must contain @"
73+
}

0 commit comments

Comments
 (0)