bureaucrat 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,577 @@
1
+ require File.dirname(__FILE__) + "/test_helper"
2
+
3
+ class TestFields < BureaucratTestCase
4
+ describe 'Field' do
5
+ describe 'with empty options' do
6
+ setup do
7
+ @field = Fields::Field.new
8
+ end
9
+
10
+ should 'be required' do
11
+ blank_value = ''
12
+ assert_raise(Fields::FieldValidationError) do
13
+ @field.clean(blank_value)
14
+ end
15
+ end
16
+ end
17
+
18
+ describe 'with required as false' do
19
+ setup do
20
+ @field = Fields::Field.new(:required => false)
21
+ end
22
+
23
+ should 'not be required' do
24
+ blank_value = ''
25
+ assert_nothing_raised do
26
+ @field.clean(blank_value)
27
+ end
28
+ end
29
+ end
30
+
31
+ describe 'on clean' do
32
+ setup do
33
+ @field = Fields::Field.new
34
+ end
35
+
36
+ should 'return the original value if valid' do
37
+ value = 'test'
38
+ assert_equal(value, @field.clean(value))
39
+ end
40
+ end
41
+
42
+ describe 'when copied' do
43
+ setup do
44
+ @field = Fields::Field.new(:initial => 'initial',
45
+ :label => 'label')
46
+ @field_copy = @field.dup
47
+ end
48
+
49
+ should 'have its own copy of initial value' do
50
+ assert_not_equal(@field.initial.object_id, @field_copy.initial.object_id)
51
+ end
52
+
53
+ should 'have its own copy of the label' do
54
+ assert_not_equal(@field.label.object_id, @field_copy.label.object_id)
55
+ end
56
+
57
+ should 'have its own copy of the error messaes' do
58
+ assert_not_equal(@field.error_messages.object_id, @field_copy.error_messages.object_id)
59
+ end
60
+ end
61
+ end
62
+
63
+ describe 'CharField' do
64
+ describe 'with empty options' do
65
+ setup do
66
+ @field = Fields::CharField.new
67
+ end
68
+
69
+ should 'not validate max length' do
70
+ assert_nothing_raised do
71
+ @field.clean("string" * 1000)
72
+ end
73
+ end
74
+
75
+ should 'not validate min length' do
76
+ assert_nothing_raised do
77
+ @field.clean("1")
78
+ end
79
+ end
80
+ end
81
+
82
+ describe 'with max length of 10' do
83
+ setup do
84
+ @field = Fields::CharField.new(:max_length => 10)
85
+ end
86
+
87
+ should 'allow values with length <= 10' do
88
+ assert_nothing_raised do
89
+ @field.clean('a' * 10)
90
+ end
91
+ end
92
+
93
+ should 'not allow values with length > 10' do
94
+ assert_raise(Fields::FieldValidationError) do
95
+ @field.clean('a' * 11)
96
+ end
97
+ end
98
+ end
99
+
100
+ describe 'with min length of 10' do
101
+ setup do
102
+ @field = Fields::CharField.new(:min_length => 10)
103
+ end
104
+
105
+ should 'allow values with length >= 10' do
106
+ assert_nothing_raised do
107
+ @field.clean('a' * 10)
108
+ end
109
+ end
110
+
111
+ should 'not allow values with length < 10' do
112
+ assert_raise(Fields::FieldValidationError) do
113
+ @field.clean('a' * 9)
114
+ end
115
+ end
116
+ end
117
+
118
+ describe 'on clean' do
119
+ setup do
120
+ @field = Fields::CharField.new
121
+ end
122
+
123
+ should 'return the original value if valid' do
124
+ valid_value = 'test'
125
+ assert_equal(valid_value, @field.clean(valid_value))
126
+ end
127
+
128
+ should 'return a blank string if value is nil and required is false' do
129
+ @field.required = false
130
+ nil_value = nil
131
+ assert_equal('', @field.clean(nil_value))
132
+ end
133
+
134
+ should 'return a blank string if value is empty and required is false' do
135
+ @field.required = false
136
+ empty_value = ''
137
+ assert_equal('', @field.clean(empty_value))
138
+ end
139
+ end
140
+
141
+ end
142
+
143
+ describe 'IntegerField' do
144
+ describe 'with max value of 10' do
145
+ setup do
146
+ @field = Fields::IntegerField.new(:max_value => 10)
147
+ end
148
+
149
+ should 'allow values <= 10' do
150
+ assert_nothing_raised do
151
+ @field.clean('10')
152
+ end
153
+ end
154
+
155
+ should 'not allow values > 10' do
156
+ assert_raise(Fields::FieldValidationError) do
157
+ @field.clean('11')
158
+ end
159
+ end
160
+ end
161
+
162
+ describe 'with min value of 10' do
163
+ setup do
164
+ @field = Fields::IntegerField.new(:min_value => 10)
165
+ end
166
+
167
+ should 'allow values >= 10' do
168
+ assert_nothing_raised do
169
+ @field.clean('10')
170
+ end
171
+ end
172
+
173
+ should 'not allow values < 10' do
174
+ assert_raise(Fields::FieldValidationError) do
175
+ @field.clean('9')
176
+ end
177
+ end
178
+
179
+ end
180
+
181
+ describe 'on clean' do
182
+ setup do
183
+ @field = Fields::IntegerField.new
184
+ end
185
+
186
+ should 'return an integer if valid' do
187
+ valid_value = '123'
188
+ assert_equal(123, @field.clean(valid_value))
189
+ end
190
+
191
+ should 'return nil if value is nil and required is false' do
192
+ @field.required = false
193
+ assert_nil(@field.clean(nil))
194
+ end
195
+
196
+ should 'return nil if value is empty and required is false' do
197
+ @field.required = false
198
+ empty_value = ''
199
+ assert_nil(@field.clean(empty_value))
200
+ end
201
+
202
+ should 'not validate invalid formats' do
203
+ invalid_formats = ['a', 'hello', '23eeee', '.', 'hi323',
204
+ 'joe@example.com', '___3232___323',
205
+ '123.0', '123..4']
206
+
207
+ invalid_formats.each do |invalid|
208
+ assert_raise(Fields::FieldValidationError) do
209
+ @field.clean(invalid)
210
+ end
211
+ end
212
+ end
213
+
214
+ should 'validate valid formats' do
215
+ valid_formats = ['3', '100', '-100', '0', '-0']
216
+
217
+ assert_nothing_raised do
218
+ valid_formats.each do |valid|
219
+ @field.clean(valid)
220
+ end
221
+ end
222
+ end
223
+
224
+ should 'return an instance of Integer if valid' do
225
+ result = @field.clean('7')
226
+ assert_kind_of(Integer, result)
227
+ end
228
+ end
229
+
230
+ end
231
+
232
+ describe 'FloatField' do
233
+ describe 'with max value of 10.5' do
234
+ setup do
235
+ @field = Fields::FloatField.new(:max_value => 10.5)
236
+ end
237
+
238
+ should 'allow values <= 10.5' do
239
+ assert_nothing_raised do
240
+ @field.clean('10.5')
241
+ end
242
+ end
243
+
244
+ should 'not allow values > 10.5' do
245
+ assert_raise(Fields::FieldValidationError) do
246
+ @field.clean('10.55')
247
+ end
248
+ end
249
+ end
250
+
251
+ describe 'with min value of 10.5' do
252
+ setup do
253
+ @field = Fields::FloatField.new(:min_value => 10.5)
254
+ end
255
+
256
+ should 'allow values >= 10.5' do
257
+ assert_nothing_raised do
258
+ @field.clean('10.5')
259
+ end
260
+ end
261
+
262
+ should 'not allow values < 10.5' do
263
+ assert_raise(Fields::FieldValidationError) do
264
+ @field.clean('10.49')
265
+ end
266
+ end
267
+ end
268
+
269
+ describe 'on clean' do
270
+ setup do
271
+ @field = Fields::FloatField.new
272
+ end
273
+
274
+ should 'return nil if value is nil and required is false' do
275
+ @field.required = false
276
+ assert_nil(@field.clean(nil))
277
+ end
278
+
279
+ should 'return nil if value is empty and required is false' do
280
+ @field.required = false
281
+ empty_value = ''
282
+ assert_nil(@field.clean(empty_value))
283
+ end
284
+
285
+ should 'not validate invalid formats' do
286
+ invalid_formats = ['a', 'hello', '23eeee', '.', 'hi323',
287
+ 'joe@example.com', '___3232___323',
288
+ '123..', '123..4']
289
+
290
+ invalid_formats.each do |invalid|
291
+ assert_raise(Fields::FieldValidationError) do
292
+ @field.clean(invalid)
293
+ end
294
+ end
295
+ end
296
+
297
+ should 'validate valid formats' do
298
+ valid_formats = ['3.14', "100", "1233.", ".3333", "0.434", "0.0"]
299
+
300
+ assert_nothing_raised do
301
+ valid_formats.each do |valid|
302
+ @field.clean(valid)
303
+ end
304
+ end
305
+ end
306
+
307
+ should 'return an instance of Float if valid' do
308
+ result = @field.clean('3.14')
309
+ assert_instance_of(Float, result)
310
+ end
311
+ end
312
+ end
313
+
314
+ describe 'BigDecimalField' do
315
+ describe 'with max value of 10.5' do
316
+ setup do
317
+ @field = Fields::BigDecimalField.new(:max_value => 10.5)
318
+ end
319
+
320
+ should 'allow values <= 10.5' do
321
+ assert_nothing_raised do
322
+ @field.clean('10.5')
323
+ end
324
+ end
325
+
326
+ should 'not allow values > 10.5' do
327
+ assert_raise(Fields::FieldValidationError) do
328
+ @field.clean('10.55')
329
+ end
330
+ end
331
+ end
332
+
333
+ describe 'with min value of 10.5' do
334
+ setup do
335
+ @field = Fields::BigDecimalField.new(:min_value => 10.5)
336
+ end
337
+
338
+ should 'allow values >= 10.5' do
339
+ assert_nothing_raised do
340
+ @field.clean('10.5')
341
+ end
342
+ end
343
+
344
+ should 'not allow values < 10.5' do
345
+ assert_raise(Fields::FieldValidationError) do
346
+ @field.clean('10.49')
347
+ end
348
+ end
349
+ end
350
+
351
+ describe 'on clean' do
352
+ setup do
353
+ @field = Fields::BigDecimalField.new
354
+ end
355
+
356
+ should 'return nil if value is nil and required is false' do
357
+ @field.required = false
358
+ assert_nil(@field.clean(nil))
359
+ end
360
+
361
+ should 'return nil if value is empty and required is false' do
362
+ @field.required = false
363
+ empty_value = ''
364
+ assert_nil(@field.clean(empty_value))
365
+ end
366
+
367
+ should 'not validate invalid formats' do
368
+ invalid_formats = ['a', 'hello', '23eeee', '.', 'hi323',
369
+ 'joe@example.com', '___3232___323',
370
+ '123..', '123..4']
371
+
372
+ invalid_formats.each do |invalid|
373
+ assert_raise(Fields::FieldValidationError) do
374
+ @field.clean(invalid)
375
+ end
376
+ end
377
+ end
378
+
379
+ should 'validate valid formats' do
380
+ valid_formats = ['3.14', "100", "1233.", ".3333", "0.434", "0.0"]
381
+
382
+ assert_nothing_raised do
383
+ valid_formats.each do |valid|
384
+ @field.clean(valid)
385
+ end
386
+ end
387
+ end
388
+
389
+ should 'return an instance of BigDecimal if valid' do
390
+ result = @field.clean('3.14')
391
+ assert_instance_of(BigDecimal, result)
392
+ end
393
+ end
394
+ end
395
+
396
+ describe 'RegexField' do
397
+ setup do
398
+ @field = Fields::RegexField.new(/ba(na){2,}/)
399
+ end
400
+
401
+ describe 'on clean' do
402
+ should 'validate matching values' do
403
+ valid_values = ['banana', 'bananananana']
404
+ valid_values.each do |valid|
405
+ assert_nothing_raised do
406
+ @field.clean(valid)
407
+ end
408
+ end
409
+ end
410
+
411
+ should 'not validate non-matching values' do
412
+ invalid_values = ['bana', 'spoon']
413
+ assert_raise(Fields::FieldValidationError) do
414
+ invalid_values.each do |invalid|
415
+ @field.clean(invalid)
416
+ end
417
+ end
418
+ end
419
+
420
+ should 'return a blank string if value is empty and required is false' do
421
+ @field.required = false
422
+ empty_value = ''
423
+ assert_equal('', @field.clean(empty_value))
424
+ end
425
+ end
426
+ end
427
+
428
+ describe 'EmailField' do
429
+ setup do
430
+ @field = Fields::EmailField.new
431
+ end
432
+
433
+ describe 'on clean' do
434
+ should 'validate email-matching values' do
435
+ valid_values = ['email@domain.com', 'email+extra@domain.com',
436
+ 'email@domain.fm', 'email@domain.co.uk']
437
+ valid_values.each do |valid|
438
+ assert_nothing_raised do
439
+ @field.clean(valid)
440
+ end
441
+ end
442
+ end
443
+
444
+ should 'not validate non-email-matching values' do
445
+ invalid_values = ['banana', 'spoon', 'invalid#bla@domain.com',
446
+ 'invalid@@domain.com', 'invalid@domain',
447
+ 'invalid@.com']
448
+ assert_raise(Fields::FieldValidationError) do
449
+ invalid_values.each do |invalid|
450
+ @field.clean(invalid)
451
+ end
452
+ end
453
+ end
454
+ end
455
+ end
456
+
457
+ describe 'BooleanField' do
458
+ setup do
459
+ @true_values = [1, true, 'true', '1']
460
+ @false_values = [nil, 0, false, 'false', '0']
461
+ @field = Fields::BooleanField.new
462
+ end
463
+
464
+ describe 'on clean' do
465
+ should 'return true for true values' do
466
+ @true_values.each do |true_value|
467
+ assert_equal(true, @field.clean(true_value))
468
+ end
469
+ end
470
+
471
+ should 'return false for false values' do
472
+ @field.required = false
473
+ @false_values.each do |false_value|
474
+ assert_equal(false, @field.clean(false_value))
475
+ end
476
+ end
477
+
478
+ should 'validate on true values when required' do
479
+ assert_nothing_raised do
480
+ @true_values.each do |true_value|
481
+ @field.clean(true_value)
482
+ end
483
+ end
484
+ end
485
+
486
+ should 'not validate on false values when required' do
487
+ @false_values.each do |false_value|
488
+ assert_raise(Fields::FieldValidationError) do
489
+ @field.clean(false_value)
490
+ end
491
+ end
492
+ end
493
+
494
+ should 'validate on false values when not required' do
495
+ @field.required = false
496
+ assert_nothing_raised do
497
+ @false_values.each do |false_value|
498
+ @field.clean(false_value)
499
+ end
500
+ end
501
+ end
502
+ end
503
+ end
504
+
505
+ describe 'NullBooleanField' do
506
+ setup do
507
+ @true_values = [true, 'true', '1']
508
+ @false_values = [false, 'false', '0']
509
+ @null_values = [nil, '', 'banana']
510
+ @field = Fields::NullBooleanField.new
511
+ end
512
+
513
+ describe 'on clean' do
514
+ should 'return true for true values' do
515
+ @true_values.each do |true_value|
516
+ assert_equal(true, @field.clean(true_value))
517
+ end
518
+ end
519
+
520
+ should 'return false for false values' do
521
+ @false_values.each do |false_value|
522
+ assert_equal(false, @field.clean(false_value))
523
+ end
524
+ end
525
+
526
+ should 'return nil for null values' do
527
+ @null_values.each do |null_value|
528
+ assert_equal(nil, @field.clean(null_value))
529
+ end
530
+ end
531
+
532
+ should 'validate on all values' do
533
+ all_values = @true_values + @false_values + @null_values
534
+ assert_nothing_raised do
535
+ all_values.each do |value|
536
+ @field.clean(value)
537
+ end
538
+ end
539
+ end
540
+ end
541
+ end
542
+
543
+ describe 'ChoiceField' do
544
+ setup do
545
+ @choices = [['tea', 'Tea'], ['milk', 'Milk']]
546
+ @field = Fields::ChoiceField.new(@choices)
547
+ end
548
+
549
+ describe 'on clean' do
550
+ should 'validate all values in choices list' do
551
+ assert_nothing_raised do
552
+ @choices.collect(&:first).each do |valid|
553
+ @field.clean(valid)
554
+ end
555
+ end
556
+ end
557
+
558
+ should 'not validate a value not in choices list' do
559
+ assert_raise(Fields::FieldValidationError) do
560
+ @field.clean('not_in_choices')
561
+ end
562
+ end
563
+
564
+ should 'return the original value if valid' do
565
+ value = 'tea'
566
+ result = @field.clean(value)
567
+ assert_equal(value, result)
568
+ end
569
+
570
+ should 'return an empty string if value is empty and not required' do
571
+ @field.required = false
572
+ result = @field.clean('')
573
+ assert_equal('', result)
574
+ end
575
+ end
576
+ end
577
+ end
@@ -0,0 +1,131 @@
1
+ require File.dirname(__FILE__) + "/test_helper"
2
+
3
+ class TestForm < BureaucratTestCase
4
+ describe 'inherited form with a CharField' do
5
+ class OneForm < Forms::Form
6
+ include Bureaucrat::Fields
7
+
8
+ field :name, CharField.new
9
+ end
10
+
11
+ should 'return an instance of Media when calling #media' do
12
+ form = OneForm.new
13
+ assert_kind_of(Widgets::Media, form.media)
14
+ end
15
+
16
+ should 'have a BoundField in [:name]' do
17
+ form = OneForm.new
18
+ assert_kind_of(Forms::BoundField, form[:name])
19
+ end
20
+
21
+ should 'be bound when data is provided' do
22
+ form = OneForm.new(:name => 'name')
23
+ assert_equal(true, form.bound?)
24
+ end
25
+
26
+ describe 'when calling #valid?' do
27
+ should 'return false when data isn\'t valid' do
28
+ form = OneForm.new(:name => nil)
29
+ assert_equal(false, form.valid?)
30
+ end
31
+
32
+ should 'return true when data is valid' do
33
+ form = OneForm.new(:name => 'valid')
34
+ assert_equal(true, form.valid?)
35
+ end
36
+ end
37
+
38
+ describe 'when calling #errors' do
39
+ should 'have errors when invalid' do
40
+ form = OneForm.new(:name => nil)
41
+ assert_operator(form.errors.size, :>, 0)
42
+ end
43
+
44
+ should 'not have errors when valid' do
45
+ form = OneForm.new(:name => 'valid')
46
+ assert_equal(form.errors.size, 0)
47
+ end
48
+ end
49
+
50
+ describe 'when calling #changed_data' do
51
+ should 'return an empty list if no field was changed' do
52
+ form = OneForm.new
53
+ assert_equal([], form.changed_data)
54
+ end
55
+
56
+ should 'return a list of changed fields when modified' do
57
+ form = OneForm.new(:name => 'changed')
58
+ assert_equal([:name], form.changed_data)
59
+ end
60
+ end
61
+ end
62
+
63
+ describe 'form with custom clean proc on field' do
64
+ class CustomCleanForm < Forms::Form
65
+ include Bureaucrat::Fields
66
+
67
+ field :name, CharField.new
68
+
69
+ def clean_name
70
+ value = cleaned_data[:name]
71
+ raise FieldValidationError.new("Invalid name") unless value == 'valid_name'
72
+ value.upcase
73
+ end
74
+ end
75
+
76
+ should 'not be valid if clean method fails' do
77
+ form = CustomCleanForm.new(:name => 'other')
78
+ assert_equal(false, form.valid?)
79
+ end
80
+
81
+ should 'be valid if clean method passes' do
82
+ form = CustomCleanForm.new(:name => 'valid_name')
83
+ assert_equal(true, form.valid?)
84
+ end
85
+
86
+ should 'set the value to the one returned by the custom clean method' do
87
+ form = CustomCleanForm.new(:name => 'valid_name')
88
+ form.valid?
89
+ assert_equal('VALID_NAME', form.cleaned_data[:name])
90
+ end
91
+
92
+ end
93
+
94
+ describe 'inherited form with two charfields when rendered' do
95
+ class TwoForm < Forms::Form
96
+ include Bureaucrat::Fields
97
+
98
+ field :name, CharField.new(:label => 'Name')
99
+ field :color, CharField.new
100
+ end
101
+
102
+ def setup
103
+ @form = TwoForm.new(:name => 'name')
104
+ @unbound_form = TwoForm.new
105
+ end
106
+
107
+ should 'should correctly render as table' do
108
+ expected = normalize_html("<tr><th><label for='id_name'>Name:</label></th><td><input name='name' id='id_name' type='text' value='name'/></td></tr>\n<tr><th><label for='id_color'>Color:</label></th><td><ul class='errorlist'><li>This field is required</li></ul><input name='color' id='id_color' type='text'/></td></tr>")
109
+ rendered = normalize_html(@form.as_table)
110
+ assert_equal(expected, rendered)
111
+ end
112
+
113
+ should 'should correctly render as ul' do
114
+ expected = normalize_html("<li><label for='id_name'>Name:</label> <input name='name' id='id_name' type='text' value='name'/></li>\n<li><ul class='errorlist'><li>This field is required</li></ul><label for='id_color'>Color:</label> <input name='color' id='id_color' type='text'/></li>")
115
+ rendered = normalize_html(@form.as_ul)
116
+ assert_equal(expected, rendered)
117
+ end
118
+
119
+ should 'should correctly render as p' do
120
+ expected = normalize_html("<p><label for='id_name'>Name:</label> <input name='name' id='id_name' type='text' value='name'/></p>\nThis field is required\n<p><label for='id_color'>Color:</label> <input name='color' id='id_color' type='text'/></p>")
121
+ rendered = normalize_html(@form.as_p)
122
+ assert_equal(expected, rendered)
123
+ end
124
+
125
+ should 'correctly render as p when not bound' do
126
+ expected = normalize_html("<p><label for='id_name'>Name:</label> <input name='name' id='id_name' type='text'/></p>\n<p><label for='id_color'>Color:</label> <input name='color' id='id_color' type='text'/></p>")
127
+ rendered = normalize_html(@unbound_form.as_p)
128
+ assert_equal(expected, rendered)
129
+ end
130
+ end
131
+ end