diff --git a/README.md b/README.md index ce8eaec..275eedd 100644 --- a/README.md +++ b/README.md @@ -310,6 +310,7 @@ struct RegistrationView: View { | `CharactersValidationRule` | Validates that a string contains only characters from the allowed CharacterSet | `CharactersValidationRule(characterSet: .letters, error: "Invalid characters")` | | `NilValidationRule` | Validates that value is nil | `NilValidationRule(error: "Value must be nil")` | `PositiveNumberValidationRule` | Validates that value is positive | `PositiveNumberValidationRule(error: "Value must be positive")` +| `NoWhitespaceValidationRule` | Validates that a string does not contain any whitespace characters | `NoWhitespaceValidationRule(error: "Spaces are not allowed")` ## Custom Validators diff --git a/Sources/ValidatorCore/Classes/Rules/NoWhitespaceValidationRule.swift b/Sources/ValidatorCore/Classes/Rules/NoWhitespaceValidationRule.swift new file mode 100644 index 0000000..c6aa207 --- /dev/null +++ b/Sources/ValidatorCore/Classes/Rules/NoWhitespaceValidationRule.swift @@ -0,0 +1,39 @@ +// +// Validator +// Copyright © 2025 Space Code. All rights reserved. +// + +/// Validates that a string does not contain any whitespace characters. +/// +/// # Example: +/// ```swift +/// let rule = NoWhitespaceValidationRule(error: "Spaces are not allowed") +/// rule.validate(input: "lorem lorem") // false +/// rule.validate(input: "Text") // true +/// ``` +public struct NoWhitespaceValidationRule: IValidationRule { + // MARK: Types + + public typealias Input = String + + // MARK: Properties + + /// The validation error. + public let error: IValidationError + + // MARK: Initialization + + /// Initializes a characters validation rule. + /// + /// - Parameters: + /// - error: The validation error to return if input fails validation. + public init(error: IValidationError) { + self.error = error + } + + // MARK: IValidationRule + + public func validate(input: String) -> Bool { + input.rangeOfCharacter(from: .whitespacesAndNewlines) == nil + } +} diff --git a/Sources/ValidatorCore/Validator.docc/Overview.md b/Sources/ValidatorCore/Validator.docc/Overview.md index 48b8e11..9cb8d66 100644 --- a/Sources/ValidatorCore/Validator.docc/Overview.md +++ b/Sources/ValidatorCore/Validator.docc/Overview.md @@ -33,6 +33,7 @@ ValidatorCore contains all core validation rules, utilities, and mechanisms for - ``URLValidationRule`` - ``NilValidationRule`` - ``PositiveNumberValidationRule`` +- ``NoWhitespaceValidationRuleTests`` ### Articles diff --git a/Tests/ValidatorCoreTests/UnitTests/Rules/NoWhitespaceValidationRuleTests.swift b/Tests/ValidatorCoreTests/UnitTests/Rules/NoWhitespaceValidationRuleTests.swift new file mode 100644 index 0000000..6d6a590 --- /dev/null +++ b/Tests/ValidatorCoreTests/UnitTests/Rules/NoWhitespaceValidationRuleTests.swift @@ -0,0 +1,96 @@ +// +// Validator +// Copyright © 2025 Space Code. All rights reserved. +// + +import ValidatorCore +import XCTest + +// MARK: - NoWhitespaceValidationRuleTests + +final class NoWhitespaceValidationRuleTests: XCTestCase { + // MARK: Properties + + private var sut: NoWhitespaceValidationRule! + + // MARK: XCTestCase + + override func setUp() { + super.setUp() + sut = NoWhitespaceValidationRule(error: String.error) + } + + override func tearDown() { + sut = nil + super.tearDown() + } + + // MARK: Tests + + func test_thatNoWhitespaceValidationRuleSetsProperties() { + // then + XCTAssertEqual(sut.error.message, .error) + } + + func test_thatNoWhitespaceValidationRuleValidatesInput_whenInputIsCorrectValue() { + // when + let result = sut.validate(input: "text") + + // then + XCTAssertTrue(result) + } + + func test_thatNoWhitespaceValidationRuleValidatesInput_whenInputIsIncorrectValue() { + // when + let result = sut.validate(input: .error) + + // then + XCTAssertFalse(result) + } + + func test_thatNoWhitespaceValidationRuleFails_whenInputContainsSpace() { + // when + let result = sut.validate(input: "hello world") + + // then + XCTAssertFalse(result) + } + + func test_thatNoWhitespaceValidationRuleFails_whenInputContainsTab() { + // when + let result = sut.validate(input: "hello\tworld") + + // then + XCTAssertFalse(result) + } + + func test_thatNoWhitespaceValidationRuleFails_whenInputContainsNewline() { + // when + let result = sut.validate(input: "hello\nworld") + + // then + XCTAssertFalse(result) + } + + func test_thatNoWhitespaceValidationRulePasses_whenInputIsEmptyString() { + // when + let result = sut.validate(input: "") + + // then + XCTAssertTrue(result) + } + + func test_thatNoWhitespaceValidationRulePasses_whenInputContainsSymbolsOnly() { + // when + let result = sut.validate(input: "!@#$%^&*()") + + // then + XCTAssertTrue(result) + } +} + +// MARK: - Constants + +private extension String { + static let error = "Spaces are not allowed" +}