bureaucrat 0.0.1

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.
@@ -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