Created
November 29, 2016 01:18
-
-
Save mikekavouras/4d9f6936582a42488aa73b76abe9985f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: Playground - noun: a place where people can play | |
import Foundation | |
enum ValidatorResult { | |
case valid | |
case invalid(error: Error) | |
} | |
protocol Validator { | |
func validateValue(_ value: String) -> ValidatorResult | |
} | |
enum EmailValidatorError: Error { | |
case empty | |
case invalidFormat | |
} | |
enum PasswordValidatorError: Error { | |
case empty | |
case tooShort | |
case noUppercaseLetter | |
case noLowercaseLetter | |
case noNumber | |
} | |
struct EmptyStringValidator: Validator { | |
private let invalidError: Error | |
init(invalidError: Error) { | |
self.invalidError = invalidError | |
} | |
func validateValue(_ value: String) -> ValidatorResult { | |
return value.isEmpty ? .invalid(error: invalidError) : .valid | |
} | |
} | |
struct PasswordLengthValidator: Validator { | |
func validateValue(_ value: String) -> ValidatorResult { | |
if value.characters.count >= 8 { | |
return .valid | |
} else { | |
return .invalid(error: PasswordValidatorError.tooShort) | |
} | |
} | |
} | |
struct UppercaseLetterValidator: Validator { | |
func validateValue(_ value: String) -> ValidatorResult { | |
let uppercaseRegex = ".*[A-Z]+.*" | |
let uppercaseLetterTest = NSPredicate(format: "SELF MATCHES %@", uppercaseRegex) | |
if uppercaseLetterTest.evaluate(with: value){ | |
return .valid | |
} else { | |
return .invalid(error: PasswordValidatorError.noUppercaseLetter) | |
} | |
} | |
} | |
struct CompositeValidator: Validator { | |
private let validators: [Validator] | |
init(validators: [Validator]) { | |
self.validators = validators | |
} | |
func validateValue(_ value: String) -> ValidatorResult { | |
for validator in validators { | |
switch validator.validateValue(value) { | |
case .valid: break | |
case .invalid(let error): | |
return .invalid(error: error) | |
} | |
} | |
return .valid | |
} | |
} | |
let emailValidator: Validator = { | |
let validator = EmptyStringValidator(invalidError: EmailValidatorError.empty) | |
return CompositeValidator(validators: [validator]) | |
}() | |
let passwordValidator: Validator = { | |
let emptyValidator = EmptyStringValidator(invalidError: PasswordValidatorError.empty) | |
let lengthValidator = PasswordLengthValidator() | |
let uppercaseValidator = UppercaseLetterValidator() | |
let strengthValidator = CompositeValidator(validators: [lengthValidator, uppercaseValidator]) | |
return CompositeValidator(validators: [emptyValidator, strengthValidator]) | |
}() | |
emailValidator.validateValue("") | |
emailValidator.validateValue("[email protected]") | |
passwordValidator.validateValue("") | |
passwordValidator.validateValue("pudge") | |
passwordValidator.validateValue("thisismypassword") | |
passwordValidator.validateValue("thisIsMyPassword!") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment