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.
- data/LICENSE +22 -0
- data/README.md +124 -0
- data/lib/bureaucrat/fields.rb +461 -0
- data/lib/bureaucrat/forms.rb +346 -0
- data/lib/bureaucrat/formsets.rb +256 -0
- data/lib/bureaucrat/quickfields.rb +59 -0
- data/lib/bureaucrat/utils.rb +84 -0
- data/lib/bureaucrat/validation.rb +130 -0
- data/lib/bureaucrat/validation_old.rb +148 -0
- data/lib/bureaucrat/widgets.rb +397 -0
- data/lib/bureaucrat/wizard.rb +220 -0
- data/lib/bureaucrat.rb +10 -0
- data/test/fields_test.rb +577 -0
- data/test/forms_test.rb +131 -0
- data/test/formsets_test.rb +51 -0
- data/test/test_helper.rb +22 -0
- data/test/widgets_test.rb +328 -0
- metadata +71 -0
data/test/fields_test.rb
ADDED
@@ -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
|
data/test/forms_test.rb
ADDED
@@ -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
|