-
Notifications
You must be signed in to change notification settings - Fork 374
/
Copy pathSwiftValidatorTests.swift
486 lines (379 loc) · 16.8 KB
/
SwiftValidatorTests.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
//
// SwiftValidatorTests.swift
// SwiftValidatorTests
//
// Created by Jeff Potter on 11/20/14.
// Copyright (c) 2014 jpotts18. All rights reserved.
//
import UIKit
import XCTest
import Validator // example app
import SwiftValidator // framework
class SwiftValidatorTests: XCTestCase {
let USERNAME_REGEX = "^[a-z0-9_-]{3,16}$"
let VALID_ZIP = "12345"
let INVALID_ZIP = "1234"
let VALID_EMAIL = "jiggy@gmail.com"
let INVALID_EMAIL = "This is not a valid email"
let CONFIRM_TXT_FIELD = UITextField()
let CONFIRM_TEXT = "Confirm this!"
let CONFIRM_TEXT_DIFF = "I am not the same as the string above"
let VALID_PASSWORD = "Super$ecret"
let INVALID_PASSWORD = "abc"
let VALID_FLOAT = "1234.444"
let INVALID_FLOAT = "1234.44.44"
let VALID_CARD_EXPIRY_MONTH = "10"
let INVALID_CARD_EXPIRY_MONTH = "13"
let VALID_CARD_EXPIRY_YEAR = "2018"
let INVALID_CARD_EXPIRY_YEAR = "2016"
let LEN_3 = "hey"
let LEN_5 = "Howdy"
let LEN_20 = "Paint the cat orange"
let REGISTER_TXT_VIEW = UITextView()
let REGISTER_TXT_FIELD = UITextField()
let REGISTER_VALIDATOR = Validator()
let REGISTER_RULES = [Rule]()
let UNREGISTER_TXT_FIELD = UITextField()
let UNREGISTER_VALIDATOR = Validator()
let UNREGISTER_RULES = [Rule]()
let UNREGISTER_ERRORS_TXT_FIELD = UITextField()
let UNREGISTER_ERRORS_VALIDATOR = Validator()
let ERROR_LABEL = UILabel()
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
// MARK: Expiry Month
func testCardExpiryMonthValid() {
XCTAssertTrue(CardExpiryMonthRule().validate(VALID_CARD_EXPIRY_MONTH), "Expiry month Should be valid")
}
func testCardExpiryMonthInvalid() {
XCTAssertFalse(CardExpiryMonthRule().validate(INVALID_CARD_EXPIRY_MONTH), "Expiry month Should be invalid")
}
func testCardExpiryMonthmessage() {
XCTAssertNotNil(CardExpiryMonthRule().errorMessage())
}
// MARK: Expiry Year
func testCardExpiryYearValid() {
XCTAssertTrue(CardExpiryYearRule().validate(VALID_CARD_EXPIRY_YEAR), "Expiry year Should be valid")
}
func testCardExpiryYearInvalid() {
XCTAssertFalse(CardExpiryYearRule().validate(INVALID_CARD_EXPIRY_YEAR), "Expiry year Should be invalid")
}
func testCardExpiryYearmessage() {
XCTAssertNotNil(CardExpiryYearRule().errorMessage())
}
// MARK: Required
func testRequired() {
XCTAssertTrue(RequiredRule().validate("Something"), "Required should be valid")
}
func testRequiredInvalid() {
XCTAssertFalse(RequiredRule().validate(""), "Required should be invalid")
}
func testRequiredMessage() {
XCTAssertNotNil(RequiredRule().errorMessage())
}
// MARK: Regex
func testRegex(){
XCTAssertTrue(RegexRule(regex: USERNAME_REGEX).validate("darth_vader8"), "RegexRule should be valid")
}
func testRegexInvalid(){
XCTAssertFalse(RegexRule(regex: USERNAME_REGEX).validate("DarthVader"), "RegexRule should be invalid")
}
func testRegexMessage() {
XCTAssertNotNil(RegexRule(regex: USERNAME_REGEX).errorMessage())
}
// MARK: Zipcode
func testZipCode() {
XCTAssertTrue(ZipCodeRule().validate(VALID_ZIP), "Zipcode should be valid")
}
func testZipCodeInvalid() {
XCTAssertFalse(ZipCodeRule().validate(INVALID_ZIP), "Zipcode should be invalid")
}
func testZipCodeMessage() {
XCTAssertNotNil(ZipCodeRule().errorMessage())
}
// MARK: Email
func testEmail() {
XCTAssertTrue(EmailRule().validate(VALID_EMAIL), "Email should be valid")
}
func testEmailInvalid() {
XCTAssertFalse(EmailRule().validate(INVALID_EMAIL), "Email should be invalid")
}
func testEmailMessage() {
XCTAssertNotNil(EmailRule().errorMessage())
}
// MARK: Float
func testFloat() {
XCTAssert(FloatRule().validate(VALID_FLOAT), "Float should be valid")
}
func testFloatInvalid() {
XCTAssert(!FloatRule().validate(INVALID_FLOAT), "Float should be invalid")
XCTAssert(!FloatRule().validate(VALID_EMAIL), "Float should be invalid")
}
func testFloatMessage() {
XCTAssertNotNil(FloatRule().errorMessage())
}
// MARK: Confirm against field
func testConfirmSame(){
CONFIRM_TXT_FIELD.text = CONFIRM_TEXT
XCTAssertTrue(ConfirmationRule(confirmField: CONFIRM_TXT_FIELD).validate(CONFIRM_TEXT), "Should confirm successfully")
}
func testConfirmDifferent() {
CONFIRM_TXT_FIELD.text = CONFIRM_TEXT
XCTAssertFalse(ConfirmationRule(confirmField: CONFIRM_TXT_FIELD).validate(CONFIRM_TEXT_DIFF), "Should fail confirm")
}
func testConfirmMessage() {
CONFIRM_TXT_FIELD.text = CONFIRM_TEXT
XCTAssertNotNil(ConfirmationRule(confirmField: CONFIRM_TXT_FIELD).errorMessage())
}
// MARK: Password
func testPassword() {
XCTAssertTrue(PasswordRule().validate(VALID_PASSWORD), "Password should be valid")
}
func testPasswordInvalid(){
XCTAssertFalse(PasswordRule().validate(INVALID_PASSWORD), "Password is invalid")
}
func testPasswordMessage() {
XCTAssertNotNil(PasswordRule().errorMessage())
}
func testPhoneNumber() {
XCTAssertTrue(PhoneNumberRule().validate("1234567890"), "Phone number should valid")
}
func testPhoneNumberInvalid() {
XCTAssertFalse(PhoneNumberRule().validate("12345678901"), "Phone number should be invalid")
}
func testPhoneNumberMessage() {
XCTAssertNotNil(PhoneNumberRule().errorMessage())
}
// MARK: Max Length
func testMaxLength(){
XCTAssertTrue(MaxLengthRule().validate(LEN_3),"Max Length should be valid")
}
func testMaxLengthInvalid(){
XCTAssertFalse(MaxLengthRule().validate(LEN_20),"Max Length should be invalid")
}
func testMaxLengthParameterAndGreaterThan(){
XCTAssertTrue(MaxLengthRule(length: 20).validate(LEN_20), "Max Length should be 20 and <= length")
}
func testMaxLengthMessage() {
XCTAssertNotNil(MaxLengthRule(length: 20).errorMessage())
}
// MARK: Min Length
func testMinLength(){
XCTAssertTrue(MinLengthRule().validate(LEN_3),"Min Length should be valid")
}
func testMinLengthInvalid(){
XCTAssertFalse(MinLengthRule().validate("no"),"Min Length should be Invalid")
}
func testMinLengthWithParameter(){
XCTAssertTrue(MinLengthRule(length: 5).validate(LEN_5), "Min Len should be set to 5 and >= length")
}
func testMinLengthMessage() {
XCTAssertNotNil(MinLengthRule(length: 5).errorMessage())
}
func testExactLength(){
XCTAssertTrue(ExactLengthRule(length: 5).validate(LEN_5), "Exact Len should be exactly 5")
}
func testExactLengthInvalidGreaterThan(){
XCTAssertFalse(ExactLengthRule(length: 6).validate(LEN_5), "Exact Len should be Invalid")
}
func testExactLengthInvalidLessThan(){
XCTAssertFalse(ExactLengthRule(length: 4).validate(LEN_5), "Exact Len should be Invalid")
}
func testExactLengthMessage() {
XCTAssertNotNil(ExactLengthRule(length: 4).errorMessage())
}
// MARK: Full Name
func testFullName(){
XCTAssertTrue(FullNameRule().validate("Jeff Potter"), "Full Name should be valid")
}
func testFullNameWith3Names(){
XCTAssertTrue(FullNameRule().validate("Jeff Van Buren"), "Full Name should be valid")
}
func testFullNameInvalid(){
XCTAssertFalse(FullNameRule().validate("Carl"), "Full Name should be invalid")
}
// MARK: ISBN
func testValidISBN10() {
let validISBN10 = ["3836221195", "3-8362-2119-5", "3 8362 2119 5" , "1617290858", "1-61729-085-8", "1 61729 085-8" , "0007269706", "0-00-726970-6", "0 00 726970 6" , "3423214120", "3-423-21412-0", "3 423 21412 0", "340101319X", "3-401-01319-X", "3 401 01319 X"]
for ISBN10 in validISBN10 {
XCTAssertTrue(ISBNRule().validate(ISBN10), "\(ISBN10) should be valid")
}
}
func testInvalidISBN10() {
let invalidISBN10 = ["3423214121", "3-423-21412-1", "3 423 21412 1"]
for ISBN10 in invalidISBN10 {
XCTAssertFalse(ISBNRule().validate(ISBN10), "\(ISBN10) should be invalid")
}
}
// MARK: HexColor
func testValidHexColors() {
let validHexes = ["#ff0034", "#CCCCCC", "fff", "#f00"]
for hex in validHexes {
XCTAssertTrue(HexColorRule().validate(hex), "\(hex) should be a valid Hex")
}
}
func testInvalidHexColors() {
let validHexes = ["#ff", "fff0", "#ff12FG", ""]
for hex in validHexes {
XCTAssertFalse(HexColorRule().validate(hex), "\(hex) should be invalid Hex")
}
}
//MARK: IPV4
func testValidIPV4() {
let validIPV4 = ["127.0.0.1" , "0.0.0.0" , "255.255.255.255" , "1.2.3.4"]
for ipv4 in validIPV4 {
XCTAssertTrue(IPV4Rule().validate(ipv4), "\(ipv4) should be a valid IPV4 address")
}
}
func testInvalidIPV4() {
let invalidIPV4 = ["::1" , "2001:db8:0000:1:1:1:1:1" , "::ffff:127.0.0.1"]
for ipv4 in invalidIPV4 {
XCTAssertFalse(IPV4Rule().validate(ipv4), "\(ipv4) should be invalid IPV4 address")
}
}
//MARK: AlphaNumeric
func testValidAlphaNumeric() {
let validAlphaNumeric = ["abc123", "A1B2C35555"]
for alphaNum in validAlphaNumeric {
XCTAssertTrue(AlphaNumericRule().validate(alphaNum), "\(alphaNum) should be a valid alpha numeric string")
}
}
func testInvalidAlphaNumeric() {
let invalidAlphaNumeric = ["abc ", "!!!!!", "ABC@DAGQW%!^$@%"]
for alphaNum in invalidAlphaNumeric {
XCTAssertFalse(AlphaNumericRule().validate(alphaNum), "\(alphaNum) should be invalid alpha numeric string")
}
}
//MARK: Alpha
func testValidAlpha() {
let validAlphaStrings = ["abc", "ABCDEFG", "AabeVsDvaW"]
for alpha in validAlphaStrings {
XCTAssertTrue(AlphaRule().validate(alpha), "\(alpha) should be valid alpha string")
}
}
func testInvalidAlpha() {
let invalidAlphaStrings = ["abc1", " foo "]
for alpha in invalidAlphaStrings {
XCTAssertFalse(AlphaRule().validate(alpha), "\(alpha) should be invalid alpha string")
}
}
// MARK: Register Field
func testRegisterTextView(){
REGISTER_VALIDATOR.registerField(REGISTER_TXT_VIEW, rules: REGISTER_RULES)
XCTAssert(REGISTER_VALIDATOR.validations[REGISTER_TXT_VIEW] != nil, "Textfield should register")
}
func testRegisterTextField(){
REGISTER_VALIDATOR.registerField(REGISTER_TXT_FIELD, rules: REGISTER_RULES)
XCTAssert(REGISTER_VALIDATOR.validations[REGISTER_TXT_FIELD] != nil, "Textfield should register")
}
func testUnregisterTextField(){
UNREGISTER_VALIDATOR.registerField(UNREGISTER_TXT_FIELD, rules: UNREGISTER_RULES)
UNREGISTER_VALIDATOR.unregisterField(UNREGISTER_TXT_FIELD)
XCTAssert(UNREGISTER_VALIDATOR.validations[UNREGISTER_TXT_FIELD] == nil, "Textfield should unregister")
}
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")
}
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")
}
}
// 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")
}
REGISTER_TXT_FIELD.text = INVALID_EMAIL
REGISTER_VALIDATOR.validate { (errors) -> Void in
XCTAssert(errors.count == 1, "Should come back with 1 error")
}
}
func testValidateSingleField() {
REGISTER_VALIDATOR.registerField(REGISTER_TXT_FIELD, rules: [EmailRule()])
REGISTER_TXT_FIELD.text = VALID_EMAIL
REGISTER_VALIDATOR.validateField(REGISTER_TXT_FIELD) { error in
XCTAssert(error == nil, "Should not present error")
}
REGISTER_TXT_FIELD.text = INVALID_EMAIL
REGISTER_VALIDATOR.validateField(REGISTER_TXT_FIELD) { error in
XCTAssert(error?.errorMessage.characters.count ?? 0 > 0, "Should state 'invalid email'")
}
}
func testValidateTextViewField() {
REGISTER_VALIDATOR.registerField(REGISTER_TXT_VIEW, rules: [RequiredRule()])
REGISTER_TXT_VIEW.text = "Some notes"
REGISTER_VALIDATOR.validateField(REGISTER_TXT_VIEW) { error in
XCTAssert(error == nil, "Should not present error")
}
REGISTER_TXT_VIEW.text = nil
REGISTER_VALIDATOR.validateField(REGISTER_TXT_VIEW) { error in
XCTAssert(error!.errorMessage == "This field is required")
}
}
// 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")
}
}
func testErrorMessageSet() {
REGISTER_VALIDATOR.registerField(REGISTER_TXT_FIELD, errorLabel: ERROR_LABEL, rules: [EmailRule()])
var successCount = 0
var errorCount = 0
REGISTER_VALIDATOR.styleTransformers(success: { (validationRule) -> Void in
successCount+=1
}) { (validationError) -> Void in
errorCount+=1
}
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")
}
}
func testErrorMessageSetAndThenUnset() {
REGISTER_VALIDATOR.registerField(REGISTER_TXT_FIELD, errorLabel: ERROR_LABEL, rules: [EmailRule()])
var successCount = 0
var errorCount = 0
REGISTER_VALIDATOR.styleTransformers(success: { (validationRule) -> Void in
successCount+=1
}) { (validationError) -> Void in
errorCount+=1
}
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")
}
}
}
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(!(self.REGISTER_TXT_FIELD.layer.borderColor! == UIColor.red.cgColor), "Color shouldn't get set at all")
}
}
}