formeze 2.1.0 → 4.0.0

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.
@@ -1,8 +0,0 @@
1
- require 'rake/testtask'
2
-
3
- task :default => :spec
4
-
5
- Rake::TestTask.new(:spec) do |t|
6
- t.test_files = FileList['spec/*_spec.rb']
7
- t.warning = true
8
- end
@@ -1,776 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'formeze'
3
- require 'i18n'
4
-
5
- class FormWithField < Formeze::Form
6
- field :title
7
- end
8
-
9
- describe 'FormWithField' do
10
- before do
11
- @form = FormWithField.new
12
- end
13
-
14
- describe 'title method' do
15
- it 'returns nil' do
16
- @form.title.must_be_nil
17
- end
18
- end
19
-
20
- describe 'title equals method' do
21
- it 'sets the value of the title attribute' do
22
- @form.title = 'Untitled'
23
- @form.title.must_equal('Untitled')
24
- end
25
- end
26
-
27
- describe 'parse method' do
28
- it 'sets the value of the title attribute' do
29
- @form.parse('title=Untitled')
30
- @form.title.must_equal('Untitled')
31
- end
32
-
33
- it 'raises an exception when the key is missing' do
34
- proc { @form.parse('') }.must_raise(Formeze::KeyError)
35
- end
36
-
37
- it 'raises an exception when there are multiple values for the key' do
38
- proc { @form.parse('title=foo&title=bar') }.must_raise(Formeze::ValueError)
39
- end
40
-
41
- it 'raises an exception when the data contains unexpected keys' do
42
- exception = proc { @form.parse('title=Untitled&foo=bar&baz=') }.must_raise(Formeze::KeyError)
43
-
44
- exception.message.must_equal('unexpected form keys: baz, foo')
45
- end
46
- end
47
-
48
- describe 'fill method' do
49
- it 'sets the value of the title attribute when given a hash with symbol keys' do
50
- @form.fill({:title => 'Untitled'})
51
- @form.title.must_equal('Untitled')
52
- end
53
-
54
- it 'sets the value of the title attribute when given an object with a title attribute' do
55
- object = Object.new
56
-
57
- def object.title; 'Untitled' end
58
-
59
- @form.fill(object)
60
- @form.title.must_equal('Untitled')
61
- end
62
- end
63
- end
64
-
65
- describe 'FormWithField after parsing valid input' do
66
- before do
67
- @form = FormWithField.new
68
- @form.parse('title=Untitled')
69
- end
70
-
71
- describe 'title method' do
72
- it 'returns the value of the field' do
73
- @form.title.must_equal('Untitled')
74
- end
75
- end
76
-
77
- describe 'valid query method' do
78
- it 'returns true' do
79
- @form.valid?.must_equal(true)
80
- end
81
- end
82
-
83
- describe 'errors query method' do
84
- it 'returns false' do
85
- @form.errors?.must_equal(false)
86
- end
87
- end
88
-
89
- describe 'errors method' do
90
- it 'returns an empty array' do
91
- @form.errors.must_be_instance_of(Array)
92
- @form.errors.must_be_empty
93
- end
94
- end
95
-
96
- describe 'errors_on query method' do
97
- it 'returns false when given the title field name' do
98
- @form.errors_on?(:title).must_equal(false)
99
- end
100
- end
101
-
102
- describe 'errors_on method' do
103
- it 'returns an empty array when given the title field name' do
104
- errors = @form.errors_on(:title)
105
- errors.must_be_instance_of(Array)
106
- errors.must_be_empty
107
- end
108
- end
109
-
110
- describe 'to_h method' do
111
- it 'returns a hash containing the field name and its value' do
112
- @form.to_h.must_equal({:title => 'Untitled'})
113
- end
114
- end
115
-
116
- describe 'to_hash method' do
117
- it 'returns a hash containing the field name and its value' do
118
- @form.to_hash.must_equal({:title => 'Untitled'})
119
- end
120
- end
121
- end
122
-
123
- describe 'FormWithField after parsing blank input' do
124
- before do
125
- @form = FormWithField.new
126
- @form.parse('title=')
127
- end
128
-
129
- describe 'valid query method' do
130
- it 'returns false' do
131
- @form.valid?.must_equal(false)
132
- end
133
- end
134
-
135
- describe 'errors query method' do
136
- it 'returns true' do
137
- @form.errors?.must_equal(true)
138
- end
139
- end
140
-
141
- describe 'errors method' do
142
- it 'returns an array containing a single error message' do
143
- @form.errors.must_be_instance_of(Array)
144
- @form.errors.length.must_equal(1)
145
- @form.errors.first.to_s.must_equal('Title is required')
146
- end
147
- end
148
-
149
- describe 'errors_on query method' do
150
- it 'returns true when given the title field name' do
151
- @form.errors_on?(:title).must_equal(true)
152
- end
153
- end
154
-
155
- describe 'errors_on method' do
156
- it 'returns an array containing a single error message when given the title field name' do
157
- errors = @form.errors_on(:title)
158
- errors.must_be_instance_of(Array)
159
- errors.length.must_equal(1)
160
- errors.first.to_s.must_equal('Title is required')
161
- end
162
- end
163
- end
164
-
165
- describe 'FormWithField after parsing input containing newlines' do
166
- before do
167
- @form = FormWithField.new
168
- @form.parse('title=This+is+a+product.%0AIt+is+very+lovely.')
169
- end
170
-
171
- describe 'valid query method' do
172
- it 'returns false' do
173
- @form.valid?.must_equal(false)
174
- end
175
- end
176
- end
177
-
178
- describe 'FormWithField parse class method' do
179
- it 'creates a new instance of the class and calls the parse instance method' do
180
- form = FormWithField.parse('title=Untitled')
181
- form.must_be_instance_of(FormWithField)
182
- form.valid?.must_equal(true)
183
- form.title.must_equal('Untitled')
184
- end
185
- end
186
-
187
- class FormWithOptionalField < Formeze::Form
188
- field :title, :required => false
189
- end
190
-
191
- describe 'FormWithOptionalField after parsing blank input' do
192
- before do
193
- @form = FormWithOptionalField.new
194
- @form.parse('title=')
195
- end
196
-
197
- describe 'valid query method' do
198
- it 'returns true' do
199
- @form.valid?.must_equal(true)
200
- end
201
- end
202
- end
203
-
204
- class FormWithOptionalFieldUsingBlankOption < Formeze::Form
205
- field :title, :required => false, :blank => 42
206
- end
207
-
208
- describe 'FormWithOptionalFieldUsingBlankOption after parsing blank input' do
209
- before do
210
- @form = FormWithOptionalFieldUsingBlankOption.new
211
- @form.parse('title=')
212
- end
213
-
214
- describe 'title method' do
215
- it 'returns the value specified by the blank option' do
216
- @form.title.must_equal(42)
217
- end
218
- end
219
- end
220
-
221
- class FormWithFieldThatCanHaveMultipleLines < Formeze::Form
222
- field :description, :multiline => true
223
- end
224
-
225
- describe 'FormWithFieldThatCanHaveMultipleLines after parsing input containing newlines' do
226
- before do
227
- @form = FormWithFieldThatCanHaveMultipleLines.new
228
- @form.parse('description=This+is+a+product.%0AIt+is+very+lovely.')
229
- end
230
-
231
- describe 'valid query method' do
232
- it 'returns true' do
233
- @form.valid?.must_equal(true)
234
- end
235
- end
236
- end
237
-
238
- class FormWithMaxLengthField < Formeze::Form
239
- field :title, :maxlength => 16
240
- end
241
-
242
- describe 'FormWithMaxLengthField after parsing input with too many characters' do
243
- before do
244
- @form = FormWithMaxLengthField.new
245
- @form.parse('title=This+Title+Will+Be+Too+Long')
246
- end
247
-
248
- describe 'valid query method' do
249
- it 'returns false' do
250
- @form.valid?.must_equal(false)
251
- end
252
- end
253
- end
254
-
255
- class FormWithMinLengthField < Formeze::Form
256
- field :title, :minlength => 8
257
- end
258
-
259
- describe 'FormWithMinLengthField after parsing input with too few characters' do
260
- before do
261
- @form = FormWithMinLengthField.new
262
- @form.parse('title=Hello')
263
- end
264
-
265
- describe 'valid query method' do
266
- it 'returns false' do
267
- @form.valid?.must_equal(false)
268
- end
269
- end
270
- end
271
-
272
- class FormWithFieldThatMustMatchPattern < Formeze::Form
273
- field :number, :pattern => /\A\d+\z/
274
- end
275
-
276
- describe 'FormWithFieldThatMustMatchPattern after parsing input that matches the pattern' do
277
- before do
278
- @form = FormWithFieldThatMustMatchPattern.new
279
- @form.parse('number=12345')
280
- end
281
-
282
- describe 'valid query method' do
283
- it 'returns true' do
284
- @form.valid?.must_equal(true)
285
- end
286
- end
287
- end
288
-
289
- describe 'FormWithFieldThatMustMatchPattern after parsing input that does not match the pattern' do
290
- before do
291
- @form = FormWithFieldThatMustMatchPattern.new
292
- @form.parse('number=notanumber')
293
- end
294
-
295
- describe 'valid query method' do
296
- it 'returns false' do
297
- @form.valid?.must_equal(false)
298
- end
299
- end
300
- end
301
-
302
- class FormWithFieldThatCanHaveMultipleValues < Formeze::Form
303
- field :colour, :multiple => true
304
- end
305
-
306
- describe 'FormWithFieldThatCanHaveMultipleValues' do
307
- before do
308
- @form = FormWithFieldThatCanHaveMultipleValues.new
309
- end
310
-
311
- describe 'colour method' do
312
- it 'returns an empty array' do
313
- @form.colour.must_be_instance_of(Array)
314
- @form.colour.must_be_empty
315
- end
316
- end
317
-
318
- describe 'colour equals method' do
319
- it 'adds the argument to the colour attribute array' do
320
- @form.colour = 'black'
321
- @form.colour.must_include('black')
322
- end
323
- end
324
-
325
- describe 'parse method' do
326
- it 'adds the value to the colour attribute array' do
327
- @form.parse('colour=black')
328
- @form.colour.must_include('black')
329
- end
330
-
331
- it 'does not raise an exception when there are multiple values for the key' do
332
- @form.parse('colour=black&colour=white')
333
- end
334
-
335
- it 'does not raise an exception when the key is missing' do
336
- @form.parse('')
337
- end
338
- end
339
- end
340
-
341
- describe 'FormWithFieldThatCanHaveMultipleValues after parsing input with multiple values' do
342
- before do
343
- @form = FormWithFieldThatCanHaveMultipleValues.new
344
- @form.parse('colour=black&colour=white')
345
- end
346
-
347
- describe 'colour method' do
348
- it 'returns an array containing the values' do
349
- @form.colour.must_be_instance_of(Array)
350
- @form.colour.must_include('black')
351
- @form.colour.must_include('white')
352
- end
353
- end
354
-
355
- describe 'valid query method' do
356
- it 'returns true' do
357
- @form.valid?.must_equal(true)
358
- end
359
- end
360
-
361
- describe 'to_hash method' do
362
- it 'returns a hash containing the field name and its array value' do
363
- @form.to_hash.must_equal({:colour => %w(black white)})
364
- end
365
- end
366
- end
367
-
368
- describe 'FormWithFieldThatCanHaveMultipleValues after parsing input with no values' do
369
- before do
370
- @form = FormWithFieldThatCanHaveMultipleValues.new
371
- @form.parse('')
372
- end
373
-
374
- describe 'colour method' do
375
- it 'returns an empty array' do
376
- @form.colour.must_be_instance_of(Array)
377
- @form.colour.must_be_empty
378
- end
379
- end
380
-
381
- describe 'valid query method' do
382
- it 'returns true' do
383
- @form.valid?.must_equal(true)
384
- end
385
- end
386
- end
387
-
388
- class FormWithFieldThatCanOnlyHaveSpecifiedValues < Formeze::Form
389
- field :answer, :values => %w(yes no)
390
- end
391
-
392
- describe 'FormWithFieldThatCanOnlyHaveSpecifiedValues after parsing input with an invalid value' do
393
- before do
394
- @form = FormWithFieldThatCanOnlyHaveSpecifiedValues.new
395
- @form.parse('answer=maybe')
396
- end
397
-
398
- describe 'valid query method' do
399
- it 'returns false' do
400
- @form.valid?.must_equal(false)
401
- end
402
- end
403
- end
404
-
405
- class FormWithGuardCondition < Formeze::Form
406
- field :account_name
407
- field :account_vat_number, :defined_if => proc { @business_account }
408
-
409
- def initialize(business_account)
410
- @business_account = business_account
411
- end
412
- end
413
-
414
- describe 'FormWithGuardCondition with business_account set to false' do
415
- before do
416
- @form = FormWithGuardCondition.new(false)
417
- end
418
-
419
- describe 'parse method' do
420
- it 'raises an exception when the account_vat_number key is present' do
421
- proc { @form.parse('account_name=Something&account_vat_number=123456789') }.must_raise(Formeze::KeyError)
422
- end
423
- end
424
- end
425
-
426
- describe 'FormWithGuardCondition with business_account set to true' do
427
- before do
428
- @form = FormWithGuardCondition.new(true)
429
- end
430
-
431
- describe 'parse method' do
432
- it 'raises an exception when the account_vat_number key is missing' do
433
- proc { @form.parse('account_name=Something') }.must_raise(Formeze::KeyError)
434
- end
435
- end
436
- end
437
-
438
- describe 'FormWithGuardCondition with business_account set to false after parsing valid input' do
439
- before do
440
- @form = FormWithGuardCondition.new(false)
441
- @form.parse('account_name=Something')
442
- end
443
-
444
- describe 'valid query method' do
445
- it 'returns true' do
446
- @form.valid?.must_equal(true)
447
- end
448
- end
449
- end
450
-
451
- class FormWithHaltingCondition < Formeze::Form
452
- field :delivery_address
453
- field :same_address, :values => %w(yes no)
454
- field :billing_address, :defined_unless => :same_address?
455
-
456
- def same_address?
457
- same_address == 'yes'
458
- end
459
- end
460
-
461
- describe 'FormWithHaltingCondition' do
462
- before do
463
- @form = FormWithHaltingCondition.new
464
- end
465
-
466
- describe 'parse method' do
467
- it 'raises an exception when there is an unexpected key' do
468
- proc { @form.parse('delivery_address=123+Main+St&same_address=yes&foo=bar') }.must_raise(Formeze::KeyError)
469
- end
470
- end
471
- end
472
-
473
- describe 'FormWithHaltingCondition after parsing input with same_address set and no billing address' do
474
- before do
475
- @form = FormWithHaltingCondition.new
476
- @form.parse('delivery_address=123+Main+St&same_address=yes')
477
- end
478
-
479
- describe 'valid query method' do
480
- it 'returns true' do
481
- @form.valid?.must_equal(true)
482
- end
483
- end
484
- end
485
-
486
- class FormWithOptionalKey < Formeze::Form
487
- field :accept_terms, :values => %w(true), :key_required => false
488
- end
489
-
490
- describe 'FormWithOptionalKey after parsing input without the key' do
491
- before do
492
- @form = FormWithOptionalKey.new
493
- @form.parse('')
494
- end
495
-
496
- describe 'valid query method' do
497
- it 'returns true' do
498
- @form.valid?.must_equal(true)
499
- end
500
- end
501
- end
502
-
503
- class FormWithOptionalFieldThatCanOnlyHaveSpecifiedValues < Formeze::Form
504
- field :size, :required => false, :values => %w(S M L XL)
505
- end
506
-
507
- describe 'FormWithOptionalFieldThatCanOnlyHaveSpecifiedValues after parsing blank input' do
508
- before do
509
- @form = FormWithOptionalFieldThatCanOnlyHaveSpecifiedValues.new
510
- @form.parse('size=')
511
- end
512
-
513
- describe 'valid query method' do
514
- it 'returns true' do
515
- @form.valid?.must_equal(true)
516
- end
517
- end
518
- end
519
-
520
- module EmailAddress
521
- def self.valid?(address)
522
- address.include?('@')
523
- end
524
- end
525
-
526
- class FormWithCustomEmailValidation < Formeze::Form
527
- field :email
528
-
529
- validates :email, &EmailAddress.method(:valid?)
530
- end
531
-
532
- describe 'FormWithCustomEmailValidation after parsing invalid input' do
533
- before do
534
- @form = FormWithCustomEmailValidation.new
535
- @form.parse('email=alice')
536
- end
537
-
538
- describe 'valid query method' do
539
- it 'returns false' do
540
- @form.valid?.must_equal(false)
541
- end
542
- end
543
-
544
- describe 'errors method' do
545
- it 'includes a generic error message for the named field' do
546
- @form.errors.map(&:to_s).must_include('Email is invalid')
547
- end
548
- end
549
-
550
- describe 'errors_on query method' do
551
- it 'returns true when given the field name' do
552
- @form.errors_on?(:email).must_equal(true)
553
- end
554
- end
555
- end
556
-
557
- describe 'FormWithCustomEmailValidation after parsing blank input' do
558
- before do
559
- @form = FormWithCustomEmailValidation.new
560
- @form.parse('email=')
561
- end
562
-
563
- describe 'errors method' do
564
- it 'will not include the custom validation error message' do
565
- @form.errors.map(&:to_s).wont_include('Email is invalid')
566
- end
567
- end
568
- end
569
-
570
- class FormWithCustomPasswordConfirmationCheck < Formeze::Form
571
- field :password
572
- field :password_confirmation
573
-
574
- validates :password_confirmation, :error => :does_not_match do
575
- password_confirmation == password
576
- end
577
- end
578
-
579
- describe 'FormWithCustomPasswordConfirmationCheck after parsing invalid input' do
580
- before do
581
- @form = FormWithCustomPasswordConfirmationCheck.new
582
- @form.parse('password=foo&password_confirmation=bar')
583
- end
584
-
585
- describe 'valid query method' do
586
- it 'returns false' do
587
- @form.valid?.must_equal(false)
588
- end
589
- end
590
-
591
- describe 'errors method' do
592
- it 'includes a generic error message for the named field' do
593
- @form.errors.map(&:to_s).must_include('Password confirmation is invalid')
594
- end
595
- end
596
-
597
- describe 'errors_on query method' do
598
- it 'returns true when given the field name' do
599
- @form.errors_on?(:password_confirmation).must_equal(true)
600
- end
601
- end
602
- end
603
-
604
- class FormWithCustomMinimumSpendValidation < Formeze::Form
605
- field :minimum_spend
606
-
607
- field :fixed_discount, :required => false, :blank => nil
608
-
609
- validates :minimum_spend, :when => :fixed_discount? do
610
- minimum_spend.to_f > 0
611
- end
612
-
613
- def fixed_discount?
614
- !fixed_discount.nil?
615
- end
616
- end
617
-
618
- describe 'FormWithCustomMinimumSpendValidation after parsing valid input' do
619
- before do
620
- @form = FormWithCustomMinimumSpendValidation.new
621
- @form.parse('minimum_spend=0.00&fixed_discount=')
622
- end
623
-
624
- describe 'valid query method' do
625
- it 'returns true' do
626
- @form.valid?.must_equal(true)
627
- end
628
- end
629
-
630
- describe 'errors method' do
631
- it 'returns an empty array' do
632
- @form.errors.must_be_empty
633
- end
634
- end
635
-
636
- describe 'errors_on query method' do
637
- it 'returns false when given the field name' do
638
- @form.errors_on?(:minimum_spend).must_equal(false)
639
- end
640
- end
641
- end
642
-
643
- describe 'FormWithCustomMinimumSpendValidation after parsing invalid input' do
644
- before do
645
- @form = FormWithCustomMinimumSpendValidation.new
646
- @form.parse('minimum_spend=0.00&fixed_discount=10%')
647
- end
648
-
649
- describe 'valid query method' do
650
- it 'returns false' do
651
- @form.valid?.must_equal(false)
652
- end
653
- end
654
-
655
- describe 'errors method' do
656
- it 'includes a generic error message for the named field' do
657
- @form.errors.map(&:to_s).must_include('Minimum spend is invalid')
658
- end
659
- end
660
-
661
- describe 'errors_on query method' do
662
- it 'returns true when given the field name' do
663
- @form.errors_on?(:minimum_spend).must_equal(true)
664
- end
665
- end
666
- end
667
-
668
- describe 'FormWithField on Rails' do
669
- before do
670
- @form = FormWithField.new
671
-
672
- Object.const_set(:Rails, Object.new)
673
- end
674
-
675
- after do
676
- Object.send(:remove_const, :Rails)
677
- end
678
-
679
- describe 'parse method' do
680
- it 'silently ignores the utf8 and authenticity_token parameters' do
681
- @form.parse('utf8=%E2%9C%93&authenticity_token=5RMc3sPZdR%2BZz4onNS8NfK&title=Test')
682
- @form.wont_respond_to(:utf8)
683
- @form.wont_respond_to(:authenticity_token)
684
- @form.to_hash.must_equal({:title => 'Test'})
685
- end
686
- end
687
- end
688
-
689
- describe 'I18n integration' do
690
- before do
691
- I18n.backend = I18n::Backend::Simple.new
692
- end
693
-
694
- after do
695
- I18n.backend = I18n::Backend::Simple.new
696
- end
697
-
698
- it 'provides i18n support for overriding the default error messages' do
699
- I18n.backend.store_translations :en, {:formeze => {:errors => {:required => 'cannot be blank'}}}
700
-
701
- form = FormWithField.new
702
- form.parse('title=')
703
- form.errors.first.to_s.must_equal('Title cannot be blank')
704
- end
705
-
706
- it 'provides i18n support for overriding the default custom validation error message' do
707
- I18n.backend.store_translations :en, {:formeze => {:errors => {:invalid => 'is not valid'}}}
708
-
709
- form = FormWithCustomEmailValidation.new
710
- form.parse('email=alice')
711
- form.errors.first.to_s.must_equal('Email is not valid')
712
- end
713
-
714
- it 'provides i18n support for specifying custom validation error messages' do
715
- I18n.backend.store_translations :en, {:formeze => {:errors => {:does_not_match => 'does not match'}}}
716
-
717
- form = FormWithCustomPasswordConfirmationCheck.new
718
- form.parse('password=foo&password_confirmation=bar')
719
- form.errors.first.to_s.must_equal('Password confirmation does not match')
720
- end
721
-
722
- it 'provides i18n support for specifying field labels globally' do
723
- I18n.backend.store_translations :en, {:formeze => {:labels => {:title => 'TITLE'}}}
724
-
725
- form = FormWithField.new
726
- form.parse('title=')
727
- form.errors.first.to_s.must_equal('TITLE is required')
728
- end
729
- end
730
-
731
- class FormWithScrubbedFields < Formeze::Form
732
- field :postcode, :scrub => [:strip, :squeeze, :upcase], :pattern => /\A[A-Z0-9]{2,4} [A-Z0-9]{3}\z/
733
- field :bio, :scrub => [:strip, :squeeze_lines], :multiline => true
734
- end
735
-
736
- describe 'FormWithScrubbedFields' do
737
- describe 'parse method' do
738
- it 'applies the scrub methods to the input before validation' do
739
- form = FormWithScrubbedFields.new
740
- form.parse('postcode=++sw1a+++1aa&bio=My+name+is+Cookie+Monster.%0A%0A%0A%0AI+LOVE+COOKIES!!!!%0A%0A%0A%0A')
741
- form.postcode.must_equal('SW1A 1AA')
742
- form.bio.count("\n").must_equal(2)
743
- form.valid?.must_equal(true)
744
- end
745
- end
746
- end
747
-
748
- describe 'Formeze' do
749
- describe 'scrub module method' do
750
- it 'applies the scrub methods to the given input' do
751
- Formeze.scrub("word\n\n", [:strip, :upcase]).must_equal('WORD')
752
- end
753
- end
754
- end
755
-
756
- class FormClassWithExplicitSetupCall
757
- Formeze.setup(self)
758
- end
759
-
760
- describe 'FormClassWithExplicitSetupCall' do
761
- before do
762
- @form_class = FormClassWithExplicitSetupCall
763
- end
764
-
765
- it 'includes the formeze class methods and instance methods' do
766
- singleton_class = if @form_class.respond_to?(:singleton_class)
767
- @form_class.singleton_class
768
- else
769
- (class << @form_class; self; end)
770
- end
771
-
772
- singleton_class.must_include(Formeze::ClassMethods)
773
-
774
- @form_class.must_include(Formeze::InstanceMethods)
775
- end
776
- end