formvalidator 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +1 -0
- data/CHANGELOG +28 -0
- data/README +24 -0
- data/README.rdoc +120 -0
- data/TODO +5 -0
- data/examples/README +10 -0
- data/examples/extend.rb +9 -0
- data/examples/file.rb +24 -0
- data/examples/profiles/extension.rb +12 -0
- data/examples/profiles/my_profile.rb +30 -0
- data/examples/simple.rb +32 -0
- data/examples/standard.rb +52 -0
- data/formvalidator.gemspec +16 -0
- data/formvalidator.rb +888 -0
- data/install.rb +9 -0
- data/tests/regress.rb +518 -0
- data/tests/testprofile.rb +30 -0
- metadata +59 -0
data/install.rb
ADDED
data/tests/regress.rb
ADDED
@@ -0,0 +1,518 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "../formvalidator"
|
3
|
+
|
4
|
+
class TestValidator < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@form = {
|
7
|
+
"first_name" => "Travis",
|
8
|
+
"last_name" => "whitton",
|
9
|
+
"age" => "22",
|
10
|
+
"home_phone" => "home phone: (123) 456-7890",
|
11
|
+
"fax" => "some bogus fax",
|
12
|
+
"street" => "111 NW 1st Street",
|
13
|
+
"city" => "fakeville",
|
14
|
+
"state" => "FL",
|
15
|
+
"zipcode" => "32608-1234",
|
16
|
+
"email" => "whitton@atlantic.net",
|
17
|
+
"password" => "foo123",
|
18
|
+
"paytype" => "Check",
|
19
|
+
"check_no" => "123456789"
|
20
|
+
}
|
21
|
+
@fv = FormValidator.new("testprofile.rb")
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_valid
|
25
|
+
res = @fv.validate(@form, :customer)
|
26
|
+
assert_equal(
|
27
|
+
["age", "check_no", "city", "country", "email", "first_name",
|
28
|
+
"home_phone", "last_name", "password", "paytype", "state",
|
29
|
+
"street", "zipcode"],
|
30
|
+
@fv.valid.keys.sort
|
31
|
+
)
|
32
|
+
assert_equal(false, res)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_invalid
|
36
|
+
@fv.validate(@form, :customer)
|
37
|
+
assert_equal({"fax"=>["american_phone"]}, @fv.invalid)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_missing
|
41
|
+
@fv.validate(@form, :customer)
|
42
|
+
assert_equal(["password_confirmation"], @fv.missing)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_unknown
|
46
|
+
@fv.validate(@form, :customer)
|
47
|
+
assert_equal([], @fv.unknown)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_optional
|
51
|
+
fakecgi = {}
|
52
|
+
def fakecgi.[](somevar)
|
53
|
+
[]
|
54
|
+
end
|
55
|
+
profile = {
|
56
|
+
:optional => :somefield,
|
57
|
+
:constraints => {
|
58
|
+
:somefield => :phone
|
59
|
+
}
|
60
|
+
}
|
61
|
+
@fv.validate(fakecgi, profile)
|
62
|
+
assert_equal({}, @fv.invalid)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_required
|
66
|
+
# define a profile with mixed strings and symbols
|
67
|
+
profile = {
|
68
|
+
:required => [:first_name, "last_name", "age"]
|
69
|
+
}
|
70
|
+
@fv.validate(@form, profile)
|
71
|
+
assert_equal(["age", "first_name", "last_name"], @fv.valid.keys.sort)
|
72
|
+
assert_equal([], @fv.missing)
|
73
|
+
# define a profile with only a string
|
74
|
+
profile = {
|
75
|
+
:required => "ssn"
|
76
|
+
}
|
77
|
+
@fv.validate(@form, profile)
|
78
|
+
assert_equal(["ssn"], @fv.missing)
|
79
|
+
# define a profile with only a symbol
|
80
|
+
profile = {
|
81
|
+
:required => "ssn"
|
82
|
+
}
|
83
|
+
@fv.validate(@form, profile)
|
84
|
+
assert_equal(["ssn"], @fv.missing)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_required_regexp
|
88
|
+
profile = {
|
89
|
+
:required_regexp => /name/
|
90
|
+
}
|
91
|
+
@fv.validate(@form, profile)
|
92
|
+
assert_equal([], @fv.missing)
|
93
|
+
form = {
|
94
|
+
"my_name" => ""
|
95
|
+
}
|
96
|
+
@fv.validate(form, profile)
|
97
|
+
assert_equal(["my_name"], @fv.missing)
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_require_some
|
101
|
+
form = {
|
102
|
+
"city" => "Gainesville",
|
103
|
+
"state" => "Fl",
|
104
|
+
"zip" => "",
|
105
|
+
"first_name" => "Travis",
|
106
|
+
"last_name" => "Whitton"
|
107
|
+
}
|
108
|
+
profile = {
|
109
|
+
:require_some => {
|
110
|
+
:location => [3, %w{city state zip}],
|
111
|
+
:name => [2, %w{first_name last_name}]
|
112
|
+
}
|
113
|
+
}
|
114
|
+
@fv.validate(form, profile)
|
115
|
+
assert_equal(["location"], @fv.missing)
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_defaults
|
119
|
+
form = {
|
120
|
+
"name" => "Travis"
|
121
|
+
}
|
122
|
+
# test symbols
|
123
|
+
profile = {
|
124
|
+
:defaults => { :country => "USA" }
|
125
|
+
}
|
126
|
+
@fv.validate(form, profile)
|
127
|
+
assert_equal("USA", form["country"])
|
128
|
+
# test strings
|
129
|
+
profile = {
|
130
|
+
:defaults => { "country" => "USA" }
|
131
|
+
}
|
132
|
+
@fv.validate(form, profile)
|
133
|
+
assert_equal("USA", form["country"])
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_dependencies
|
137
|
+
form = {
|
138
|
+
"city" => "gainesville",
|
139
|
+
"state" => "FL",
|
140
|
+
"zipcode" => "32608"
|
141
|
+
}
|
142
|
+
profile = {
|
143
|
+
:optional => [:city, :state, :zipcode, :street],
|
144
|
+
:dependencies => { :city => [:state, :zipcode] }
|
145
|
+
}
|
146
|
+
@fv.validate(form, profile)
|
147
|
+
assert_equal([], @fv.missing)
|
148
|
+
profile = {
|
149
|
+
:optional => [:city, :state, :zipcode],
|
150
|
+
:dependencies => { :city => [:state, :zipcode, :street] }
|
151
|
+
}
|
152
|
+
@fv.validate(form, profile)
|
153
|
+
assert_equal(["street"], @fv.missing)
|
154
|
+
form = {}
|
155
|
+
@fv.validate(form, profile)
|
156
|
+
assert_equal([], @fv.missing)
|
157
|
+
form = {
|
158
|
+
"paytype" => "CC",
|
159
|
+
"cc_type" => "VISA",
|
160
|
+
"cc_exp" => "02/04",
|
161
|
+
"cc_num" => "123456789",
|
162
|
+
}
|
163
|
+
profile = {
|
164
|
+
:optional => [:paytype, :cc_type, :cc_exp, :cc_num],
|
165
|
+
:dependencies => {
|
166
|
+
:paytype => { :CC => [:cc_type, :cc_exp, :cc_num],
|
167
|
+
:Check => :check_no }
|
168
|
+
}
|
169
|
+
}
|
170
|
+
@fv.validate(form, profile)
|
171
|
+
assert_equal([], @fv.missing)
|
172
|
+
form = {
|
173
|
+
"paytype" => "Check"
|
174
|
+
}
|
175
|
+
@fv.validate(form, profile)
|
176
|
+
assert_equal(["check_no"], @fv.missing)
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_dependency_groups
|
180
|
+
form = {
|
181
|
+
"username" => "travis",
|
182
|
+
"password" => "foo123"
|
183
|
+
}
|
184
|
+
profile = {
|
185
|
+
:optional => [:username, :password],
|
186
|
+
:dependency_groups => {
|
187
|
+
:password_group => %w{username password}
|
188
|
+
}
|
189
|
+
}
|
190
|
+
@fv.validate(form, profile)
|
191
|
+
assert_equal([], @fv.missing)
|
192
|
+
form = {
|
193
|
+
"username" => "travis"
|
194
|
+
}
|
195
|
+
@fv.validate(form, profile)
|
196
|
+
assert_equal(["password"], @fv.missing)
|
197
|
+
form = {
|
198
|
+
"password" => "foo123"
|
199
|
+
}
|
200
|
+
@fv.validate(form, profile)
|
201
|
+
assert_equal(["username"], @fv.missing)
|
202
|
+
form = {}
|
203
|
+
@fv.validate(form, profile)
|
204
|
+
assert_equal([], @fv.missing)
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_filters
|
208
|
+
form = {
|
209
|
+
"first_name" => " Travis ",
|
210
|
+
"last_name" => " whitton ",
|
211
|
+
}
|
212
|
+
profile = {
|
213
|
+
:optional => [:first_name, "last_name"],
|
214
|
+
:filters => [:strip, :capitalize]
|
215
|
+
}
|
216
|
+
@fv.validate(form, profile)
|
217
|
+
assert_equal("Travis", form["first_name"])
|
218
|
+
assert_equal("Whitton", form["last_name"])
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_field_filters
|
222
|
+
form = {
|
223
|
+
"first_name" => " travis ",
|
224
|
+
"last_name" => " whitton "
|
225
|
+
}
|
226
|
+
profile = {
|
227
|
+
:optional => [:first_name, :last_name],
|
228
|
+
:field_filters => {
|
229
|
+
"first_name" => [:strip, :capitalize]
|
230
|
+
}
|
231
|
+
}
|
232
|
+
@fv.validate(form, profile)
|
233
|
+
assert_equal("Travis", form["first_name"])
|
234
|
+
assert_equal(" whitton ", form["last_name"])
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_field_filter_regexp_map
|
238
|
+
form = {
|
239
|
+
"first_name" => " travis ",
|
240
|
+
"last_name" => " whitton ",
|
241
|
+
"handle" => " dr_foo "
|
242
|
+
}
|
243
|
+
profile = {
|
244
|
+
:optional => [:first_name, :last_name, "handle"],
|
245
|
+
:field_filter_regexp_map => {
|
246
|
+
/name/ => [:strip, :capitalize]
|
247
|
+
}
|
248
|
+
}
|
249
|
+
@fv.validate(form, profile)
|
250
|
+
assert_equal("Travis", form["first_name"])
|
251
|
+
assert_equal("Whitton", form["last_name"])
|
252
|
+
assert_equal(" dr_foo ", form["handle"])
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_untaint_all_constraints
|
256
|
+
form = {
|
257
|
+
"ip" => "192.168.1.1"
|
258
|
+
}
|
259
|
+
form["ip"].taint
|
260
|
+
profile = {
|
261
|
+
:optional => :ip,
|
262
|
+
:constraints => {
|
263
|
+
:ip => :ip_address
|
264
|
+
}
|
265
|
+
}
|
266
|
+
@fv.validate(form, profile)
|
267
|
+
assert_equal(true, form["ip"].tainted?)
|
268
|
+
form["ip"].taint
|
269
|
+
profile = {
|
270
|
+
:optional => :ip,
|
271
|
+
:untaint_all_constraints => true,
|
272
|
+
:constraints => {
|
273
|
+
:ip => :ip_address
|
274
|
+
}
|
275
|
+
}
|
276
|
+
@fv.validate(form, profile)
|
277
|
+
assert_equal(false, form["ip"].tainted?)
|
278
|
+
end
|
279
|
+
|
280
|
+
def test_untaint_constraint_fields
|
281
|
+
form = {
|
282
|
+
"ip" => "192.168.1.1"
|
283
|
+
}
|
284
|
+
form["ip"].taint
|
285
|
+
assert_equal(true, form["ip"].tainted?)
|
286
|
+
profile = {
|
287
|
+
:optional => :ip,
|
288
|
+
:untaint_constraint_fields => :ip,
|
289
|
+
:constraints => {
|
290
|
+
:ip => :ip_address
|
291
|
+
}
|
292
|
+
}
|
293
|
+
@fv.validate(form, profile)
|
294
|
+
assert_equal(false, form["ip"].tainted?)
|
295
|
+
end
|
296
|
+
|
297
|
+
def test_constraint_regexp_map
|
298
|
+
form = {
|
299
|
+
"zipcode" => "32608"
|
300
|
+
}
|
301
|
+
profile = {
|
302
|
+
:optional => :zipcode,
|
303
|
+
:constraint_regexp_map => {
|
304
|
+
/code/ => :zip
|
305
|
+
}
|
306
|
+
}
|
307
|
+
@fv.validate(form, profile)
|
308
|
+
assert_equal({}, @fv.invalid)
|
309
|
+
form = {
|
310
|
+
"zipcode" => "abcdef"
|
311
|
+
}
|
312
|
+
@fv.validate(form, profile)
|
313
|
+
assert_equal({"zipcode" => ["zip"]}, @fv.invalid)
|
314
|
+
end
|
315
|
+
|
316
|
+
def test_constraints
|
317
|
+
year = Time.new.year
|
318
|
+
month = Time.new.month
|
319
|
+
|
320
|
+
# CC num below is not real. It simply passes the checksum.
|
321
|
+
form = {
|
322
|
+
"cc_no" => "378282246310005",
|
323
|
+
"cc_type" => "AMEX",
|
324
|
+
"cc_exp" => "#{month}/#{year}"
|
325
|
+
}
|
326
|
+
|
327
|
+
profile = {
|
328
|
+
:optional => %w{cc_no cc_type cc_exp},
|
329
|
+
:constraints => {
|
330
|
+
:cc_no => {
|
331
|
+
:name => "cc_test",
|
332
|
+
:constraint => :cc_number,
|
333
|
+
:params => [:cc_no, :cc_type]
|
334
|
+
}
|
335
|
+
}
|
336
|
+
}
|
337
|
+
|
338
|
+
@fv.validate(form, profile)
|
339
|
+
assert_equal({}, @fv.invalid)
|
340
|
+
|
341
|
+
form = {
|
342
|
+
"zip" => "32608-1234"
|
343
|
+
}
|
344
|
+
|
345
|
+
profile = {
|
346
|
+
:optional => :zip,
|
347
|
+
:constraints => {
|
348
|
+
:zip => [
|
349
|
+
:zip,
|
350
|
+
{
|
351
|
+
:name => "all_digits",
|
352
|
+
:constraint => /^\d+$/
|
353
|
+
}
|
354
|
+
]
|
355
|
+
}
|
356
|
+
}
|
357
|
+
@fv.validate(form, profile)
|
358
|
+
assert_equal({"zip"=>["all_digits"]}, @fv.invalid)
|
359
|
+
|
360
|
+
form = {
|
361
|
+
"num1" => "2",
|
362
|
+
"num2" => "3"
|
363
|
+
}
|
364
|
+
|
365
|
+
even = proc{|n| n.to_i[0].zero?}
|
366
|
+
|
367
|
+
profile = {
|
368
|
+
:optional => [:num1, :num2],
|
369
|
+
:constraints => {
|
370
|
+
:num1 => even,
|
371
|
+
:num2 => even
|
372
|
+
}
|
373
|
+
}
|
374
|
+
|
375
|
+
@fv.validate(form, profile)
|
376
|
+
assert_equal(["num2"], @fv.invalid.keys)
|
377
|
+
assert_equal(["num1"], @fv.valid.keys)
|
378
|
+
end
|
379
|
+
|
380
|
+
def test_filter_strip()
|
381
|
+
assert_equal("testing", @fv.filter_strip(" testing "))
|
382
|
+
end
|
383
|
+
|
384
|
+
def test_filter_squeeze()
|
385
|
+
assert_equal(" two spaces ", @fv.filter_squeeze(" two spaces "))
|
386
|
+
end
|
387
|
+
|
388
|
+
def test_filter_digit()
|
389
|
+
assert_equal("123", @fv.filter_digit("abc123abc"))
|
390
|
+
end
|
391
|
+
|
392
|
+
def test_filter_alphanum()
|
393
|
+
assert_equal("somewords", @fv.filter_alphanum("@$some words%$#"))
|
394
|
+
end
|
395
|
+
|
396
|
+
def test_filter_integer()
|
397
|
+
assert_equal("+123", @fv.filter_integer("num = +123"))
|
398
|
+
end
|
399
|
+
|
400
|
+
def test_filter_pos_integer()
|
401
|
+
assert_equal("+123", @fv.filter_pos_integer("num = +123"))
|
402
|
+
end
|
403
|
+
|
404
|
+
def test_filter_neg_integer()
|
405
|
+
assert_equal("-123", @fv.filter_neg_integer("num = -123"))
|
406
|
+
end
|
407
|
+
|
408
|
+
def test_filter_decimal()
|
409
|
+
assert_equal("+1.123", @fv.filter_decimal("float = +1.123!"))
|
410
|
+
end
|
411
|
+
|
412
|
+
def test_filter_pos_decimal()
|
413
|
+
assert_equal("+1.23", @fv.filter_pos_decimal("float = +1.23!"))
|
414
|
+
end
|
415
|
+
|
416
|
+
def test_filter_neg_decimal()
|
417
|
+
assert_equal("-1.23", @fv.filter_neg_decimal("float = -1.23!"))
|
418
|
+
end
|
419
|
+
|
420
|
+
def test_filter_dollars()
|
421
|
+
assert_equal("20.00", @fv.filter_dollars("my worth = 20.00"))
|
422
|
+
end
|
423
|
+
|
424
|
+
def test_filter_phone()
|
425
|
+
assert_equal("(123) 123-4567", @fv.filter_phone("number=(123) 123-4567"))
|
426
|
+
end
|
427
|
+
|
428
|
+
def test_filter_sql_wildcard()
|
429
|
+
assert_equal("SOME SQL LIKE %", @fv.filter_sql_wildcard("SOME SQL LIKE *"))
|
430
|
+
end
|
431
|
+
|
432
|
+
def test_filter_quote()
|
433
|
+
assert_equal('foo@bar\.com', @fv.filter_quote("foo@bar.com"))
|
434
|
+
end
|
435
|
+
|
436
|
+
def test_filter_downcase()
|
437
|
+
assert_equal("i like ruby", @fv.filter_downcase("I LIKE RUBY"))
|
438
|
+
end
|
439
|
+
|
440
|
+
def test_filter_upcase()
|
441
|
+
assert_equal("I LIKE RUBY", @fv.filter_upcase("i like ruby"))
|
442
|
+
end
|
443
|
+
|
444
|
+
def test_filter_capitalize()
|
445
|
+
assert_equal("I like ruby", @fv.filter_capitalize("i like ruby"))
|
446
|
+
end
|
447
|
+
|
448
|
+
def test_match_email()
|
449
|
+
assert_equal("whitton@atlantic.net", @fv.match_email("whitton@atlantic.net"))
|
450
|
+
assert_nil(@fv.match_email("whitton"))
|
451
|
+
end
|
452
|
+
|
453
|
+
def test_match_state_or_province()
|
454
|
+
assert_equal("FL", @fv.match_state_or_province(:FL))
|
455
|
+
assert_equal("AB", @fv.match_state_or_province(:AB))
|
456
|
+
assert_nil(@fv.match_state_or_province(:ABC))
|
457
|
+
end
|
458
|
+
|
459
|
+
def test_match_state()
|
460
|
+
assert_equal("CA", @fv.match_state(:CA))
|
461
|
+
assert_nil(@fv.match_state(:CAR))
|
462
|
+
end
|
463
|
+
|
464
|
+
def test_match_province()
|
465
|
+
assert_equal("YK", @fv.match_province(:YK))
|
466
|
+
assert_nil(@fv.match_state(:YKK))
|
467
|
+
end
|
468
|
+
|
469
|
+
def test_match_zip_or_postcode()
|
470
|
+
assert_equal("32608", @fv.match_zip_or_postcode("32608"))
|
471
|
+
assert_equal("G1K 6Z9", @fv.match_zip_or_postcode("G1K 6Z9"))
|
472
|
+
assert_nil(@fv.match_zip_or_postcode("123"))
|
473
|
+
end
|
474
|
+
|
475
|
+
def test_match_postcode()
|
476
|
+
assert_equal("G1K 6Z9", @fv.match_postcode("G1K 6Z9"))
|
477
|
+
assert_nil(@fv.match_postcode("ABCDEFG"))
|
478
|
+
end
|
479
|
+
|
480
|
+
def test_match_zip()
|
481
|
+
assert_equal("32609-1234", @fv.match_zip("32609-1234"))
|
482
|
+
assert_nil(@fv.match_zip("ABCDEFG"))
|
483
|
+
end
|
484
|
+
|
485
|
+
def test_match_phone()
|
486
|
+
assert_equal("123-4567", @fv.match_phone("123-4567"))
|
487
|
+
assert_nil(@fv.match_phone("abc-defg"))
|
488
|
+
end
|
489
|
+
|
490
|
+
def test_match_american_phone()
|
491
|
+
assert_equal("(123) 123-4567", @fv.match_american_phone("(123) 123-4567"))
|
492
|
+
assert_nil(@fv.match_american_phone("(abc) abc-defg"))
|
493
|
+
end
|
494
|
+
|
495
|
+
def test_match_cc_number()
|
496
|
+
# Not a real credit card number! It simply matches the checksum.
|
497
|
+
assert_equal("378282246310005",
|
498
|
+
@fv.match_cc_number("378282246310005", :AMEX))
|
499
|
+
assert_nil(@fv.match_cc_number("378282256310005", :AMEX))
|
500
|
+
end
|
501
|
+
|
502
|
+
def test_match_cc_exp()
|
503
|
+
year = Time.new.year
|
504
|
+
month = Time.new.month
|
505
|
+
assert_equal("#{month}/#{year+1}", @fv.match_cc_exp("#{month}/#{year+1}"))
|
506
|
+
assert_nil(@fv.match_cc_exp("#{month}/#{year}"))
|
507
|
+
end
|
508
|
+
|
509
|
+
def test_match_cc_type()
|
510
|
+
assert_equal("Mastercard", @fv.match_cc_type("Mastercard"))
|
511
|
+
assert_nil(@fv.match_cc_type("Foocard"))
|
512
|
+
end
|
513
|
+
|
514
|
+
def test_match_ip_address()
|
515
|
+
assert_equal("192.168.1.1", @fv.match_ip_address("192.168.1.1"))
|
516
|
+
assert_nil(@fv.match_ip_address("abc.def.ghi.jkl"))
|
517
|
+
end
|
518
|
+
end
|