Skip to content

Commit

Permalink
Replace delegate and callbacks with optional return
Browse files Browse the repository at this point in the history
  • Loading branch information
ivnsch committed Jul 26, 2015
1 parent 37c734c commit 5e9e922
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 82 deletions.
35 changes: 11 additions & 24 deletions Validator/Validator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,9 @@
import Foundation
import UIKit

@objc public protocol ValidationDelegate {
func validationSuccessful()
func validationFailed(errors: [UITextField: ValidationError])
}

public class Validator {
// dictionary to handle complex view hierarchies like dynamic tableview cells
public var errors = [UITextField: ValidationError]()
public var lastErrors = [UITextField: ValidationError]?()
public var validations = [UITextField: ValidationRule]()
private var successStyleTransform: ((validationRule:ValidationRule) -> Void)?
private var errorStyleTransform: ((validationError:ValidationError) -> Void)?
Expand All @@ -25,9 +20,9 @@ public class Validator {

// MARK: Private functions

private func validateAllFields() {
private func validateAllFields() -> [UITextField: ValidationError]? {

errors = [:]
var errors: [UITextField: ValidationError] = [:]

for (textField, rule) in validations {
if let error = rule.validateField() {
Expand All @@ -45,6 +40,8 @@ public class Validator {
}
}
}

return errors.isEmpty ? nil : errors
}

// MARK: Using Keys
Expand All @@ -64,24 +61,14 @@ public class Validator {

public func unregisterField(textField: UITextField) {
validations.removeValueForKey(textField)
errors.removeValueForKey(textField)
}

public func validate(delegate: ValidationDelegate) {

self.validateAllFields()

if errors.isEmpty {
delegate.validationSuccessful()
} else {
delegate.validationFailed(errors)
}
}

public func validate(callback:(errors: [UITextField: ValidationError]) -> Void) -> Void {

self.validateAllFields()

callback(errors: errors)
public func validate() -> [UITextField: ValidationError]? {
let errors = self.validateAllFields()
if errors != nil {
self.lastErrors = errors
}
return errors
}
}
41 changes: 18 additions & 23 deletions Validator/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import Foundation
import UIKit


class ViewController: UIViewController , ValidationDelegate, UITextFieldDelegate {

class ViewController: UIViewController, UITextFieldDelegate {
// TextFields
@IBOutlet weak var fullNameTextField: UITextField!
@IBOutlet weak var emailTextField: UITextField!
Expand All @@ -35,11 +35,11 @@ class ViewController: UIViewController , ValidationDelegate, UITextFieldDelegate

validator.styleTransformers(success:{ (validationRule) -> Void in
print("here")
// clear error label
validationRule.errorLabel?.hidden = true
validationRule.errorLabel?.text = ""
validationRule.textField.layer.borderColor = UIColor.greenColor().CGColor
validationRule.textField.layer.borderWidth = 0.5
// clear error label
validationRule.errorLabel?.hidden = true
validationRule.errorLabel?.text = ""
validationRule.textField.layer.borderColor = UIColor.greenColor().CGColor
validationRule.textField.layer.borderWidth = 0.5

}, error:{ (validationError) -> Void in
print("error")
Expand All @@ -55,24 +55,19 @@ class ViewController: UIViewController , ValidationDelegate, UITextFieldDelegate
validator.registerField(phoneNumberTextField, errorLabel: phoneNumberErrorLabel, rules: [RequiredRule(), MinLengthRule(length: 9)])
validator.registerField(zipcodeTextField, errorLabel: zipcodeErrorLabel, rules: [RequiredRule(), ZipCodeRule()])
}

@IBAction func submitTapped(sender: AnyObject) {
print("Validating...")
validator.validate(self)
}

// MARK: ValidationDelegate Methods

func validationSuccessful() {
print("Validation Success!")
let alert = UIAlertController(title: "Success", message: "You are validated!", preferredStyle: UIAlertControllerStyle.Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alert.addAction(defaultAction)
self.presentViewController(alert, animated: true, completion: nil)

}
func validationFailed(errors:[UITextField:ValidationError]) {
print("Validation FAILED!")
if let _ = validator.validate() {
print("Validation FAILED!")

} else {
print("Validation Success!")
let alert = UIAlertController(title: "Success", message: "You are validated!", preferredStyle: UIAlertControllerStyle.Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alert.addAction(defaultAction)
self.presentViewController(alert, animated: true, completion: nil)
}
}

func hideKeyboard() {
Expand Down
52 changes: 17 additions & 35 deletions ValidatorTests/ValidatorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,37 +187,27 @@ class ValidatorTests: XCTestCase {
func testUnregisterError(){
UNREGISTER_ERRORS_VALIDATOR.registerField(UNREGISTER_ERRORS_TXT_FIELD, rules: [EmailRule()])
UNREGISTER_ERRORS_TXT_FIELD.text = INVALID_EMAIL
UNREGISTER_ERRORS_VALIDATOR.validate { (errors) -> Void in
XCTAssert(errors.count == 1, "Should come back with errors")
}
XCTAssert(UNREGISTER_ERRORS_VALIDATOR.validate()?.count == 1, "Should come back with errors")
UNREGISTER_ERRORS_VALIDATOR.unregisterField(UNREGISTER_ERRORS_TXT_FIELD)
UNREGISTER_ERRORS_VALIDATOR.validate { (errors) -> Void in
XCTAssert(errors.count == 0, "Should not come back with errors")
}
XCTAssert(UNREGISTER_ERRORS_VALIDATOR.validate() == nil, "Should not come back with errors")
}

// MARK: Validate Functions

func testValidateWithCallback() {
REGISTER_VALIDATOR.registerField(REGISTER_TXT_FIELD, rules: [EmailRule()])
REGISTER_TXT_FIELD.text = VALID_EMAIL
REGISTER_VALIDATOR.validate { (errors) -> Void in
XCTAssert(errors.count == 0, "Should not come back with errors")
}
XCTAssert(REGISTER_VALIDATOR.validate() == nil, "Should not come back with errors")
REGISTER_TXT_FIELD.text = INVALID_EMAIL
REGISTER_VALIDATOR.validate { (errors) -> Void in
XCTAssert(errors.count == 1, "Should come back with 1 error")
}
XCTAssert(REGISTER_VALIDATOR.validate()?.count == 1, "Should come back with 1 error")
}

// MARK: Validate error field gets it's text set to the error, if supplied

func testNoErrorMessageSet() {
REGISTER_VALIDATOR.registerField(REGISTER_TXT_FIELD, errorLabel: ERROR_LABEL, rules: [EmailRule()])
REGISTER_TXT_FIELD.text = VALID_EMAIL
REGISTER_VALIDATOR.validate { (errors) -> Void in
XCTAssert(errors.count == 0, "Should not come back with errors")
}
XCTAssert(REGISTER_VALIDATOR.validate() == nil, "Should not come back with errors")
}

func testErrorMessageSet() {
Expand All @@ -230,11 +220,9 @@ class ValidatorTests: XCTestCase {
errorCount++
}
REGISTER_TXT_FIELD.text = INVALID_EMAIL
REGISTER_VALIDATOR.validate { (errors) -> Void in
XCTAssert(errors.count == 1, "Should come back with errors")
XCTAssert(errorCount == 1, "Should have called the error style transform once")
XCTAssert(successCount == 0, "Should not have called the success style transform as there are no successful fields")
}
XCTAssert(REGISTER_VALIDATOR.validate()?.count == 1, "Should come back with errors")
XCTAssert(errorCount == 1, "Should have called the error style transform once")
XCTAssert(successCount == 0, "Should not have called the success style transform as there are no successful fields")
}

func testErrorMessageSetAndThenUnset() {
Expand All @@ -249,25 +237,19 @@ class ValidatorTests: XCTestCase {
}

REGISTER_TXT_FIELD.text = INVALID_EMAIL
REGISTER_VALIDATOR.validate { (errors) -> Void in
XCTAssert(errors.count == 1, "Should come back with errors")
XCTAssert(errorCount == 1, "Should have called the error style transform once")
XCTAssert(successCount == 0, "Should not have called the success style transform as there are no successful fields")
self.REGISTER_TXT_FIELD.text = self.VALID_EMAIL
self.REGISTER_VALIDATOR.validate { (errors) -> Void in
XCTAssert(errors.count == 0, "Should not come back with errors: \(errors)")
XCTAssert(successCount == 1, "Should have called the success style transform once")
XCTAssert(errorCount == 1, "Should not have called the error style transform again")
}
}
XCTAssert(REGISTER_VALIDATOR.validate()?.count == 1, "Should come back with errors")
XCTAssert(errorCount == 1, "Should have called the error style transform once")
XCTAssert(successCount == 0, "Should not have called the success style transform as there are no successful fields")
self.REGISTER_TXT_FIELD.text = self.VALID_EMAIL
XCTAssert(REGISTER_VALIDATOR.validate() == nil, "Should not come back with errors")
XCTAssert(successCount == 1, "Should have called the success style transform once")
XCTAssert(errorCount == 1, "Should not have called the error style transform again")
}

func testTextFieldBorderColorNotSet() {
REGISTER_VALIDATOR.registerField(REGISTER_TXT_FIELD, errorLabel: ERROR_LABEL, rules: [EmailRule()])
REGISTER_TXT_FIELD.text = INVALID_EMAIL
REGISTER_VALIDATOR.validate { (errors) -> Void in
XCTAssert(errors.count == 1, "Should come back with errors")
XCTAssert(!CGColorEqualToColor(self.REGISTER_TXT_FIELD.layer.borderColor, UIColor.redColor().CGColor), "Color shouldn't get set at all")
}
XCTAssert(REGISTER_VALIDATOR.validate()?.count == 1, "Should come back with errors")
XCTAssert(!CGColorEqualToColor(self.REGISTER_TXT_FIELD.layer.borderColor, UIColor.redColor().CGColor), "Color shouldn't get set at all")
}
}

0 comments on commit 5e9e922

Please sign in to comment.