simple_form 1.4.0 → 1.5.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.
- data/.gitignore +1 -0
- data/.travis.yml +10 -1
- data/CHANGELOG.rdoc +36 -0
- data/Gemfile +6 -5
- data/README.rdoc +25 -4
- data/Rakefile +1 -1
- data/lib/generators/simple_form/install_generator.rb +2 -6
- data/lib/generators/simple_form/templates/{simple_form.rb → config/initializers/simple_form.rb} +2 -2
- data/lib/simple_form/action_view_extensions/builder.rb +12 -5
- data/lib/simple_form/action_view_extensions/form_helper.rb +29 -18
- data/lib/simple_form/components/errors.rb +10 -2
- data/lib/simple_form/components/hints.rb +10 -0
- data/lib/simple_form/components/label_input.rb +5 -3
- data/lib/simple_form/components/labels.rb +10 -4
- data/lib/simple_form/components/placeholders.rb +10 -4
- data/lib/simple_form/components.rb +1 -1
- data/lib/simple_form/error_notification.rb +1 -1
- data/lib/simple_form/form_builder.rb +13 -10
- data/lib/simple_form/helpers/has_errors.rb +15 -0
- data/lib/simple_form/helpers/maxlength.rb +24 -0
- data/lib/simple_form/helpers/pattern.rb +28 -0
- data/lib/simple_form/helpers/required.rb +36 -0
- data/lib/simple_form/helpers/validators.rb +44 -0
- data/lib/simple_form/helpers.rb +9 -0
- data/lib/simple_form/inputs/base.rb +30 -45
- data/lib/simple_form/inputs/boolean_input.rb +1 -1
- data/lib/simple_form/inputs/collection_input.rb +1 -1
- data/lib/simple_form/inputs/date_time_input.rb +1 -1
- data/lib/simple_form/inputs/file_input.rb +9 -0
- data/lib/simple_form/inputs/hidden_input.rb +1 -1
- data/lib/simple_form/inputs/numeric_input.rb +20 -13
- data/lib/simple_form/inputs/password_input.rb +13 -0
- data/lib/simple_form/inputs/range_input.rb +16 -0
- data/lib/simple_form/inputs/string_input.rb +7 -24
- data/lib/simple_form/inputs/text_input.rb +12 -0
- data/lib/simple_form/inputs.rb +5 -2
- data/lib/simple_form/version.rb +1 -1
- data/lib/simple_form.rb +1 -1
- data/simple_form.gemspec +3 -0
- data/test/action_view_extensions/builder_test.rb +59 -0
- data/test/action_view_extensions/form_helper_test.rb +33 -0
- data/test/components/label_test.rb +19 -0
- data/test/discovery_inputs.rb +2 -2
- data/test/form_builder_test.rb +100 -6
- data/test/inputs_test.rb +193 -20
- data/test/support/mock_controller.rb +9 -0
- data/test/support/models.rb +28 -2
- data/test/test_helper.rb +1 -0
- metadata +47 -12
- data/Gemfile.lock +0 -82
- data/init.rb +0 -1
- data/lib/simple_form/has_errors.rb +0 -14
- data/lib/simple_form/inputs/mapping_input.rb +0 -29
- /data/lib/generators/simple_form/templates/{en.yml → config/locales/simple_form.en.yml} +0 -0
data/test/form_builder_test.rb
CHANGED
|
@@ -52,7 +52,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
# All
|
|
55
|
-
test 'nested simple fields should
|
|
55
|
+
test 'nested simple fields should yield an instance of FormBuilder' do
|
|
56
56
|
simple_form_for :user do |f|
|
|
57
57
|
f.simple_fields_for :posts do |posts_form|
|
|
58
58
|
assert posts_form.instance_of?(SimpleForm::FormBuilder)
|
|
@@ -90,7 +90,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
90
90
|
end
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
test 'builder uses the first matching custom input map when more than one
|
|
93
|
+
test 'builder uses the first matching custom input map when more than one matches' do
|
|
94
94
|
swap SimpleForm, :input_mappings => { /count$/ => :integer, /^post_/ => :password } do
|
|
95
95
|
with_form_for @user, :post_count
|
|
96
96
|
assert_no_select 'form input#user_post_count.password'
|
|
@@ -338,7 +338,69 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
338
338
|
assert_select 'input.optional#user_name'
|
|
339
339
|
end
|
|
340
340
|
|
|
341
|
+
# VALIDATORS :if :unless
|
|
342
|
+
|
|
343
|
+
test 'builder input should not be required when ActiveModel::Validations is included and if option is present' do
|
|
344
|
+
with_form_for @validating_user, :age
|
|
345
|
+
assert_no_select 'input.required'
|
|
346
|
+
assert_no_select 'input[required]'
|
|
347
|
+
assert_select 'input.optional#validating_user_age'
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
test 'builder input should not be required when ActiveModel::Validations is included and unless option is present' do
|
|
351
|
+
with_form_for @validating_user, :amount
|
|
352
|
+
assert_no_select 'input.required'
|
|
353
|
+
assert_no_select 'input[required]'
|
|
354
|
+
assert_select 'input.optional#validating_user_amount'
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# VALIDATORS :on
|
|
358
|
+
|
|
359
|
+
test 'builder input should be required when validation is on create and is not persisted' do
|
|
360
|
+
@validating_user.new_record!
|
|
361
|
+
with_form_for @validating_user, :action
|
|
362
|
+
assert_select 'input.required'
|
|
363
|
+
assert_select 'input[required]'
|
|
364
|
+
assert_select 'input.required[required]#validating_user_action'
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
test 'builder input should not be required when validation is on create and is persisted' do
|
|
368
|
+
with_form_for @validating_user, :action
|
|
369
|
+
assert_no_select 'input.required'
|
|
370
|
+
assert_no_select 'input[required]'
|
|
371
|
+
assert_select 'input.optional#validating_user_action'
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
test 'builder input should be required when validation is on save' do
|
|
375
|
+
with_form_for @validating_user, :credit_limit
|
|
376
|
+
assert_select 'input.required'
|
|
377
|
+
assert_select 'input[required]'
|
|
378
|
+
assert_select 'input.required[required]#validating_user_credit_limit'
|
|
379
|
+
|
|
380
|
+
@validating_user.new_record!
|
|
381
|
+
with_form_for @validating_user, :credit_limit
|
|
382
|
+
assert_select 'input.required'
|
|
383
|
+
assert_select 'input[required]'
|
|
384
|
+
assert_select 'input.required[required]#validating_user_credit_limit'
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
test 'builder input should be required when validation is on update and is persisted' do
|
|
388
|
+
with_form_for @validating_user, :phone_number
|
|
389
|
+
assert_select 'input.required'
|
|
390
|
+
assert_select 'input[required]'
|
|
391
|
+
assert_select 'input.required[required]#validating_user_phone_number'
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
test 'builder input should not be required when validation is on update and is not persisted' do
|
|
395
|
+
@validating_user.new_record!
|
|
396
|
+
with_form_for @validating_user, :phone_number
|
|
397
|
+
assert_no_select 'input.required'
|
|
398
|
+
assert_no_select 'input[required]'
|
|
399
|
+
assert_select 'input.optional#validating_user_phone_number'
|
|
400
|
+
end
|
|
401
|
+
|
|
341
402
|
# WRAPPERS
|
|
403
|
+
|
|
342
404
|
test 'builder support wrapping around an specific tag' do
|
|
343
405
|
swap SimpleForm, :wrapper_tag => :p do
|
|
344
406
|
with_form_for @user, :name
|
|
@@ -347,6 +409,12 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
347
409
|
end
|
|
348
410
|
end
|
|
349
411
|
|
|
412
|
+
test 'builder support no wrapping when wrapper is false' do
|
|
413
|
+
with_form_for @user, :name, :wrapper => false
|
|
414
|
+
assert_select 'form > label[for=user_name]'
|
|
415
|
+
assert_select 'form > input#user_name.string'
|
|
416
|
+
end
|
|
417
|
+
|
|
350
418
|
test 'builder wrapping tag adds default css classes' do
|
|
351
419
|
swap SimpleForm, :wrapper_tag => :p do
|
|
352
420
|
with_form_for @user, :name
|
|
@@ -420,6 +488,17 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
420
488
|
assert_no_select 'input.integer[as]'
|
|
421
489
|
end
|
|
422
490
|
|
|
491
|
+
test 'builder collection input_field should generate input tag with a clean HTML' do
|
|
492
|
+
with_concat_form_for(@user) do |f|
|
|
493
|
+
f.input_field :status, :collection => ['Open', 'Closed'], :class => 'status', :label_method => :to_s, :value_method => :to_s
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
assert_no_select 'select.status[input_html]'
|
|
497
|
+
assert_no_select 'select.status[collection]'
|
|
498
|
+
assert_no_select 'select.status[label_method]'
|
|
499
|
+
assert_no_select 'select.status[value_method]'
|
|
500
|
+
end
|
|
501
|
+
|
|
423
502
|
# WITHOUT OBJECT
|
|
424
503
|
test 'builder should generate properly when object is not present' do
|
|
425
504
|
with_form_for :project, :name
|
|
@@ -456,6 +535,14 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
456
535
|
assert_no_select 'span.error[error_html]'
|
|
457
536
|
end
|
|
458
537
|
|
|
538
|
+
test 'builder should generate an error tag with a clean HTML when errors options are present' do
|
|
539
|
+
with_error_for @user, :name, :error_tag => :p, :error_prefix => 'Name', :error_method => :first
|
|
540
|
+
assert_no_select 'p.error[error_html]'
|
|
541
|
+
assert_no_select 'p.error[error_tag]'
|
|
542
|
+
assert_no_select 'p.error[error_prefix]'
|
|
543
|
+
assert_no_select 'p.error[error_method]'
|
|
544
|
+
end
|
|
545
|
+
|
|
459
546
|
test 'builder should allow passing options to error tag' do
|
|
460
547
|
with_error_for @user, :name, :id => 'name_error'
|
|
461
548
|
assert_select 'span.error#name_error', "can't be blank"
|
|
@@ -501,6 +588,13 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
501
588
|
assert_no_select 'span.hint[hint_html]'
|
|
502
589
|
end
|
|
503
590
|
|
|
591
|
+
test 'builder should generate a hint componet tag with a clean HTML when hint_tag option is present' do
|
|
592
|
+
with_hint_for @user, 'Hello World!', :hint_tag => :p
|
|
593
|
+
assert_no_select 'p.hint[hint]'
|
|
594
|
+
assert_no_select 'p.hint[hint_html]'
|
|
595
|
+
assert_no_select 'p.hint[hint_tag]'
|
|
596
|
+
end
|
|
597
|
+
|
|
504
598
|
test 'builder should allow passing options to hint tag' do
|
|
505
599
|
with_hint_for @user, :name, :hint => 'Hello World!', :id => 'name_hint'
|
|
506
600
|
assert_select 'span.hint#name_hint', 'Hello World!'
|
|
@@ -559,7 +653,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
559
653
|
end
|
|
560
654
|
end
|
|
561
655
|
|
|
562
|
-
test 'builder association with a block
|
|
656
|
+
test 'builder association with a block calls simple_fields_for' do
|
|
563
657
|
simple_form_for @user do |f|
|
|
564
658
|
f.association :posts do |posts_form|
|
|
565
659
|
assert posts_form.instance_of?(SimpleForm::FormBuilder)
|
|
@@ -578,7 +672,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
578
672
|
assert_equal 3, calls
|
|
579
673
|
end
|
|
580
674
|
|
|
581
|
-
test 'builder association
|
|
675
|
+
test 'builder association marks input as required based on both association and attribute' do
|
|
582
676
|
swap SimpleForm, :required_by_default => false do
|
|
583
677
|
with_association_for @validating_user, :company, :collection => []
|
|
584
678
|
assert_select 'label.required'
|
|
@@ -595,7 +689,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
595
689
|
assert_select 'form select option[value=3]', 'Tag 3'
|
|
596
690
|
end
|
|
597
691
|
|
|
598
|
-
test 'builder does not preload collection association if preload false' do
|
|
692
|
+
test 'builder does not preload collection association if preload is false' do
|
|
599
693
|
value = @user.company
|
|
600
694
|
value.expects(:to_a).never
|
|
601
695
|
with_association_for @user, :company, :preload => false
|
|
@@ -605,7 +699,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
605
699
|
assert_select 'form select option[value=3]', 'Company 3'
|
|
606
700
|
end
|
|
607
701
|
|
|
608
|
-
test 'builder does not preload non
|
|
702
|
+
test 'builder does not preload non-collection association' do
|
|
609
703
|
value = @user.company
|
|
610
704
|
value.expects(:to_a).never
|
|
611
705
|
with_association_for @user, :company, :preload => false
|
data/test/inputs_test.rb
CHANGED
|
@@ -141,9 +141,9 @@ class InputTest < ActionView::TestCase
|
|
|
141
141
|
assert_select "input#user_password.password[type=password][name='user[password]']"
|
|
142
142
|
end
|
|
143
143
|
|
|
144
|
-
test 'input should use
|
|
144
|
+
test 'input should not use size attribute for decimal attributes' do
|
|
145
145
|
with_input_for @user, :credit_limit, :decimal
|
|
146
|
-
|
|
146
|
+
assert_no_select 'input.decimal[size]'
|
|
147
147
|
end
|
|
148
148
|
|
|
149
149
|
test 'input should get maxlength from column definition for string attributes' do
|
|
@@ -151,6 +151,11 @@ class InputTest < ActionView::TestCase
|
|
|
151
151
|
assert_select 'input.string[maxlength=100]'
|
|
152
152
|
end
|
|
153
153
|
|
|
154
|
+
test 'input should not get maxlength from column without size definition for string attributes' do
|
|
155
|
+
with_input_for @user, :action, :string
|
|
156
|
+
assert_no_select 'input.string[maxlength]'
|
|
157
|
+
end
|
|
158
|
+
|
|
154
159
|
test 'input should get size from column definition for string attributes respecting maximum value' do
|
|
155
160
|
with_input_for @user, :name, :string
|
|
156
161
|
assert_select 'input.string[size=50]'
|
|
@@ -166,6 +171,11 @@ class InputTest < ActionView::TestCase
|
|
|
166
171
|
assert_select 'input.password[type=password][maxlength=100]'
|
|
167
172
|
end
|
|
168
173
|
|
|
174
|
+
test 'input should infer maxlength column definition from validation when present' do
|
|
175
|
+
with_input_for @validating_user, :name, :string
|
|
176
|
+
assert_select 'input.string[maxlength=25]'
|
|
177
|
+
end
|
|
178
|
+
|
|
169
179
|
test 'when not using HTML5, does not show maxlength attribute' do
|
|
170
180
|
swap SimpleForm, :html5 => false do
|
|
171
181
|
with_input_for @user, :password, :password
|
|
@@ -173,6 +183,13 @@ class InputTest < ActionView::TestCase
|
|
|
173
183
|
end
|
|
174
184
|
end
|
|
175
185
|
|
|
186
|
+
test 'when not using HTML5, does not show maxlength attribute with validating lenght attribute' do
|
|
187
|
+
swap SimpleForm, :html5 => false do
|
|
188
|
+
with_input_for @validating_user, :name, :string
|
|
189
|
+
assert_no_select 'input.string[maxlength]'
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
176
193
|
test 'input should not generate placeholder by default' do
|
|
177
194
|
with_input_for @user, :name, :string
|
|
178
195
|
assert_no_select 'input[placeholder]'
|
|
@@ -212,6 +229,22 @@ class InputTest < ActionView::TestCase
|
|
|
212
229
|
end
|
|
213
230
|
end
|
|
214
231
|
|
|
232
|
+
test 'input should infer pattern from attributes when pattern is true' do
|
|
233
|
+
with_input_for @other_validating_user, :country, :string, :pattern => true
|
|
234
|
+
assert_select 'input[pattern="\w+"]'
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
test 'input should use given pattern from attributes' do
|
|
238
|
+
with_input_for @other_validating_user, :country, :string, :pattern => "\\d+"
|
|
239
|
+
assert_select 'input[pattern="\d+"]'
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
test 'input should fail if pattern is true but no pattern exists' do
|
|
243
|
+
assert_raise RuntimeError do
|
|
244
|
+
with_input_for @other_validating_user, :name, :string, :pattern => true
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
215
248
|
# NumericInput
|
|
216
249
|
test 'input should generate an integer text field for integer attributes ' do
|
|
217
250
|
with_input_for @user, :age, :integer
|
|
@@ -345,16 +378,28 @@ class InputTest < ActionView::TestCase
|
|
|
345
378
|
end
|
|
346
379
|
end
|
|
347
380
|
|
|
381
|
+
[:integer, :float, :decimal].each do |type|
|
|
382
|
+
test "#{type} input should infer min value from attributes with greater than or equal validation" do
|
|
383
|
+
with_input_for @validating_user, :age, type
|
|
384
|
+
assert_select 'input[min=18]'
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
test "#{type} input should infer the max value from attributes with less than or equal to validation" do
|
|
388
|
+
with_input_for @validating_user, :age, type
|
|
389
|
+
assert_select 'input[max=99]'
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
|
|
348
393
|
# Numeric input but HTML5 disabled
|
|
349
|
-
test '
|
|
394
|
+
test 'when not using HTML5 input should not generate field with type number and use text instead' do
|
|
350
395
|
swap SimpleForm, :html5 => false do
|
|
351
396
|
with_input_for @user, :age, :integer
|
|
352
397
|
assert_no_select "input[type=number]"
|
|
353
|
-
|
|
398
|
+
assert_select "input#user_age[type=text]"
|
|
354
399
|
end
|
|
355
400
|
end
|
|
356
401
|
|
|
357
|
-
test 'when not using HTML5 input should not use min or max or step attributes' do
|
|
402
|
+
test 'when not using HTML5 input should not use min or max or step attributes for numeric type' do
|
|
358
403
|
swap SimpleForm, :html5 => false do
|
|
359
404
|
with_input_for @validating_user, :age, :integer
|
|
360
405
|
assert_no_select "input[min]"
|
|
@@ -363,15 +408,63 @@ class InputTest < ActionView::TestCase
|
|
|
363
408
|
end
|
|
364
409
|
end
|
|
365
410
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
411
|
+
# RangeInput
|
|
412
|
+
test 'range input generates a input type range, based on numeric input' do
|
|
413
|
+
with_input_for @user, :age, :range
|
|
414
|
+
assert_select "input#user_age.range[type=range]"
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
test 'range input does not generate placeholder' do
|
|
418
|
+
with_input_for @user, :age, :range, :placeholder => "Select your age"
|
|
419
|
+
assert_select "input[type=range]"
|
|
420
|
+
assert_no_select "input[placeholder]"
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
test 'range input allows givin min and max attributes' do
|
|
424
|
+
with_input_for @user, :age, :range, :input_html => { :min => 10, :max => 50 }
|
|
425
|
+
assert_select "input[type=range][min=10][max=50]"
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
test 'range input infers min and max attributes from validations' do
|
|
429
|
+
with_input_for @validating_user, :age, :range
|
|
430
|
+
assert_select "input[type=range][min=18][max=99]"
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
test 'range input add default step attribute' do
|
|
434
|
+
with_input_for @validating_user, :age, :range
|
|
435
|
+
assert_select "input[type=range][step=1]"
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
test 'range input allows givin a step through input html options' do
|
|
439
|
+
with_input_for @validating_user, :age, :range, :input_html => { :step => 2 }
|
|
440
|
+
assert_select "input[type=range][step=2]"
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
test 'range input should not generate min attribute by default' do
|
|
444
|
+
with_input_for @user, :age, :range
|
|
445
|
+
assert_no_select 'input[min]'
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
test 'range input should not generate max attribute by default' do
|
|
449
|
+
with_input_for @user, :age, :range
|
|
450
|
+
assert_no_select 'input[max]'
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
# RangeInput iwth HTML5 disabled
|
|
454
|
+
test 'when not using HTML5, range input does not generate field with range type, and use text instead' do
|
|
455
|
+
swap SimpleForm, :html5 => false do
|
|
456
|
+
with_input_for @user, :age, :range
|
|
457
|
+
assert_no_select "input[type=number]"
|
|
458
|
+
assert_select "input[type=text]"
|
|
370
459
|
end
|
|
460
|
+
end
|
|
371
461
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
462
|
+
test 'when not using HTML5, range input should not use min or max or step attributes' do
|
|
463
|
+
swap SimpleForm, :html5 => false do
|
|
464
|
+
with_input_for @validating_user, :age, :range
|
|
465
|
+
assert_no_select "input[min]"
|
|
466
|
+
assert_no_select "input[max]"
|
|
467
|
+
assert_no_select "input[step]"
|
|
375
468
|
end
|
|
376
469
|
end
|
|
377
470
|
|
|
@@ -393,6 +486,30 @@ class InputTest < ActionView::TestCase
|
|
|
393
486
|
assert_select 'textarea.text[placeholder=Put in some text]'
|
|
394
487
|
end
|
|
395
488
|
|
|
489
|
+
test 'input should get maxlength from column definition for text attributes' do
|
|
490
|
+
with_input_for @user, :description, :text
|
|
491
|
+
assert_select 'textarea.text[maxlength=200]'
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
test 'input should infer maxlength column definition from validation when present for text attributes' do
|
|
495
|
+
with_input_for @validating_user, :description, :text
|
|
496
|
+
assert_select 'textarea.text[maxlength=50]'
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
test 'when not using HTML5, does not show maxlength attribute for text attributes' do
|
|
500
|
+
swap SimpleForm, :html5 => false do
|
|
501
|
+
with_input_for @user, :description, :text
|
|
502
|
+
assert_no_select 'textarea.text[maxlength]'
|
|
503
|
+
end
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
test 'when not using HTML5, does not show maxlength attribute with validating lenght text attribute' do
|
|
507
|
+
swap SimpleForm, :html5 => false do
|
|
508
|
+
with_input_for @validating_user, :name, :string
|
|
509
|
+
assert_no_select 'input.string[maxlength]'
|
|
510
|
+
end
|
|
511
|
+
end
|
|
512
|
+
|
|
396
513
|
test 'input should generate a file field' do
|
|
397
514
|
with_input_for @user, :name, :file
|
|
398
515
|
assert_select 'input#user_name[type=file]'
|
|
@@ -403,14 +520,6 @@ class InputTest < ActionView::TestCase
|
|
|
403
520
|
assert_no_select 'input[placeholder]'
|
|
404
521
|
end
|
|
405
522
|
|
|
406
|
-
test 'mapping input should generate an error if type is not found' do
|
|
407
|
-
with_concat_form_for(@user) do |f|
|
|
408
|
-
assert_raise(RuntimeError, "Could not find method for nil") do
|
|
409
|
-
SimpleForm::Inputs::MappingInput.new(f, "unknown", nil, nil, {}).input
|
|
410
|
-
end
|
|
411
|
-
end
|
|
412
|
-
end
|
|
413
|
-
|
|
414
523
|
# HiddenInput
|
|
415
524
|
test 'input should generate a hidden field' do
|
|
416
525
|
with_input_for @user, :name, :hidden
|
|
@@ -674,6 +783,62 @@ class InputTest < ActionView::TestCase
|
|
|
674
783
|
assert_select 'select option[value=2]', 'Carlos'
|
|
675
784
|
end
|
|
676
785
|
|
|
786
|
+
test 'input should disable the anothers components when the option is a object' do
|
|
787
|
+
with_input_for @user, :description, :select, :collection => ["Jose", "Carlos"], :disabled => true
|
|
788
|
+
assert_no_select 'select option[value=Jose][disabled=disabled]', 'Jose'
|
|
789
|
+
assert_no_select 'select option[value=Carlos][disabled=disabled]', 'Carlos'
|
|
790
|
+
assert_select 'select[disabled=disabled]'
|
|
791
|
+
assert_select 'div.disabled'
|
|
792
|
+
end
|
|
793
|
+
|
|
794
|
+
test 'input should not disable the anothers components when the option is a object' do
|
|
795
|
+
with_input_for @user, :description, :select, :collection => ["Jose", "Carlos"], :disabled => 'Jose'
|
|
796
|
+
assert_select 'select option[value=Jose][disabled=disabled]', 'Jose'
|
|
797
|
+
assert_no_select 'select option[value=Carlos][disabled=disabled]', 'Carlos'
|
|
798
|
+
assert_no_select 'select[disabled=disabled]'
|
|
799
|
+
assert_no_select 'div.disabled'
|
|
800
|
+
end
|
|
801
|
+
|
|
802
|
+
test 'input should allow disabled options with a lambda for collection select' do
|
|
803
|
+
with_input_for @user, :name, :select, :collection => ["Carlos", "Antonio"],
|
|
804
|
+
:disabled => lambda { |x| x == "Carlos" }
|
|
805
|
+
assert_select 'select option[value=Carlos][disabled=disabled]', 'Carlos'
|
|
806
|
+
assert_select 'select option[value=Antonio]', 'Antonio'
|
|
807
|
+
assert_no_select 'select option[value=Antonio][disabled]'
|
|
808
|
+
end
|
|
809
|
+
|
|
810
|
+
test 'input should allow disabled and label method with lambdas for collection select' do
|
|
811
|
+
with_input_for @user, :name, :select, :collection => ["Carlos", "Antonio"],
|
|
812
|
+
:disabled => lambda { |x| x == "Carlos" }, :label_method => lambda { |x| x.upcase }
|
|
813
|
+
assert_select 'select option[value=Carlos][disabled=disabled]', 'CARLOS'
|
|
814
|
+
assert_select 'select option[value=Antonio]', 'ANTONIO'
|
|
815
|
+
assert_no_select 'select option[value=Antonio][disabled]'
|
|
816
|
+
end
|
|
817
|
+
|
|
818
|
+
test 'input should allow a non lambda disabled option with lambda label method for collections' do
|
|
819
|
+
with_input_for @user, :name, :select, :collection => ["Carlos", "Antonio"],
|
|
820
|
+
:disabled => "Carlos", :label_method => lambda { |x| x.upcase }
|
|
821
|
+
assert_select 'select option[value=Carlos][disabled=disabled]', 'CARLOS'
|
|
822
|
+
assert_select 'select option[value=Antonio]', 'ANTONIO'
|
|
823
|
+
assert_no_select 'select option[value=Antonio][disabled]'
|
|
824
|
+
end
|
|
825
|
+
|
|
826
|
+
test 'input should allow selected and label method with lambdas for collection select' do
|
|
827
|
+
with_input_for @user, :name, :select, :collection => ["Carlos", "Antonio"],
|
|
828
|
+
:selected => lambda { |x| x == "Carlos" }, :label_method => lambda { |x| x.upcase }
|
|
829
|
+
assert_select 'select option[value=Carlos][selected=selected]', 'CARLOS'
|
|
830
|
+
assert_select 'select option[value=Antonio]', 'ANTONIO'
|
|
831
|
+
assert_no_select 'select option[value=Antonio][selected]'
|
|
832
|
+
end
|
|
833
|
+
|
|
834
|
+
test 'input should allow a non lambda selected option with lambda label method for collection select' do
|
|
835
|
+
with_input_for @user, :name, :select, :collection => ["Carlos", "Antonio"],
|
|
836
|
+
:selected => "Carlos", :label_method => lambda { |x| x.upcase }
|
|
837
|
+
assert_select 'select option[value=Carlos][selected=selected]', 'CARLOS'
|
|
838
|
+
assert_select 'select option[value=Antonio]', 'ANTONIO'
|
|
839
|
+
assert_no_select 'select option[value=Antonio][selected]'
|
|
840
|
+
end
|
|
841
|
+
|
|
677
842
|
test 'input should allow overriding collection for radio types' do
|
|
678
843
|
with_input_for @user, :name, :radio, :collection => ['Jose', 'Carlos']
|
|
679
844
|
assert_select 'input[type=radio][value=Jose]'
|
|
@@ -780,6 +945,14 @@ class InputTest < ActionView::TestCase
|
|
|
780
945
|
end
|
|
781
946
|
end
|
|
782
947
|
|
|
948
|
+
test 'when not using browser validations, input should not generate required html attribute' do
|
|
949
|
+
swap SimpleForm, :browser_validations => false do
|
|
950
|
+
with_input_for @user, :name, :string
|
|
951
|
+
assert_select 'input[type=text].required'
|
|
952
|
+
assert_no_select 'input[type=text][required]'
|
|
953
|
+
end
|
|
954
|
+
end
|
|
955
|
+
|
|
783
956
|
test 'collection input with select type should not generate invalid required html attribute' do
|
|
784
957
|
with_input_for @user, :name, :select, :collection => ['Jose' , 'Carlos']
|
|
785
958
|
assert_select 'select.required'
|
|
@@ -12,4 +12,13 @@ class MockController
|
|
|
12
12
|
def url_for(*args)
|
|
13
13
|
"http://example.com"
|
|
14
14
|
end
|
|
15
|
+
|
|
16
|
+
def url_helpers
|
|
17
|
+
self
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def hash_for_user_path(*args); end
|
|
21
|
+
def hash_for_validating_user_path(*args); end
|
|
22
|
+
def hash_for_other_validating_user_path(*args); end
|
|
23
|
+
def hash_for_users_path(*args); end
|
|
15
24
|
end
|
data/test/support/models.rb
CHANGED
|
@@ -42,7 +42,7 @@ class User
|
|
|
42
42
|
:description, :created_at, :updated_at, :credit_limit, :password, :url,
|
|
43
43
|
:delivery_time, :born_at, :special_company_id, :country, :tags, :tag_ids,
|
|
44
44
|
:avatar, :home_picture, :email, :status, :residence_country, :phone_number,
|
|
45
|
-
:post_count, :lock_version, :amount, :attempts
|
|
45
|
+
:post_count, :lock_version, :amount, :attempts, :action
|
|
46
46
|
|
|
47
47
|
def initialize(options={})
|
|
48
48
|
options.each do |key, value|
|
|
@@ -61,10 +61,13 @@ class User
|
|
|
61
61
|
def company_attributes=(*)
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
+
def tags_attributes=(*)
|
|
65
|
+
end
|
|
66
|
+
|
|
64
67
|
def column_for_attribute(attribute)
|
|
65
68
|
column_type, limit = case attribute.to_sym
|
|
66
69
|
when :name, :status, :password then [:string, 100]
|
|
67
|
-
when :description then :text
|
|
70
|
+
when :description then [:text, 200]
|
|
68
71
|
when :age then :integer
|
|
69
72
|
when :credit_limit then [:decimal, 15]
|
|
70
73
|
when :active then :boolean
|
|
@@ -76,6 +79,7 @@ class User
|
|
|
76
79
|
when :home_picture then :string
|
|
77
80
|
when :amount then :integer
|
|
78
81
|
when :attempts then :integer
|
|
82
|
+
when :action then :string
|
|
79
83
|
end
|
|
80
84
|
Column.new(attribute, column_type, limit)
|
|
81
85
|
end
|
|
@@ -124,6 +128,13 @@ class ValidatingUser < User
|
|
|
124
128
|
include ActiveModel::Validations
|
|
125
129
|
validates :name, :presence => true
|
|
126
130
|
validates :company, :presence => true
|
|
131
|
+
validates :age, :presence => true, :if => Proc.new { |user| user.name }
|
|
132
|
+
validates :amount, :presence => true, :unless => Proc.new { |user| user.age }
|
|
133
|
+
|
|
134
|
+
validates :action, :presence => true, :on => :create
|
|
135
|
+
validates :credit_limit, :presence => true, :on => :save
|
|
136
|
+
validates :phone_number, :presence => true, :on => :update
|
|
137
|
+
|
|
127
138
|
validates_numericality_of :age,
|
|
128
139
|
:greater_than_or_equal_to => 18,
|
|
129
140
|
:less_than_or_equal_to => 99,
|
|
@@ -136,6 +147,8 @@ class ValidatingUser < User
|
|
|
136
147
|
:greater_than_or_equal_to => :min_attempts,
|
|
137
148
|
:less_than_or_equal_to => :max_attempts,
|
|
138
149
|
:only_integer => true
|
|
150
|
+
validates_length_of :name, :maximum => 25
|
|
151
|
+
validates_length_of :description, :maximum => 50
|
|
139
152
|
|
|
140
153
|
def min_amount
|
|
141
154
|
10
|
|
@@ -168,4 +181,17 @@ class OtherValidatingUser < User
|
|
|
168
181
|
:greater_than_or_equal_to => Proc.new { |user| user.age },
|
|
169
182
|
:less_than_or_equal_to => Proc.new { |user| user.age + 100},
|
|
170
183
|
:only_integer => true
|
|
184
|
+
|
|
185
|
+
validates_format_of :country, :with => /\w+/
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
class HashBackedAuthor < Hash
|
|
189
|
+
extend ActiveModel::Naming
|
|
190
|
+
include ActiveModel::Conversion
|
|
191
|
+
|
|
192
|
+
def persisted?; false; end
|
|
193
|
+
|
|
194
|
+
def name
|
|
195
|
+
'hash backed author'
|
|
196
|
+
end
|
|
171
197
|
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: simple_form
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 3
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 1
|
|
8
|
-
-
|
|
8
|
+
- 5
|
|
9
9
|
- 0
|
|
10
|
-
version: 1.
|
|
10
|
+
version: 1.5.0
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- "Jos\xC3\xA9 Valim"
|
|
@@ -16,10 +16,39 @@ autorequire:
|
|
|
16
16
|
bindir: bin
|
|
17
17
|
cert_chain: []
|
|
18
18
|
|
|
19
|
-
date: 2011-
|
|
19
|
+
date: 2011-09-08 00:00:00 -03:00
|
|
20
20
|
default_executable:
|
|
21
|
-
dependencies:
|
|
22
|
-
|
|
21
|
+
dependencies:
|
|
22
|
+
- !ruby/object:Gem::Dependency
|
|
23
|
+
name: activemodel
|
|
24
|
+
prerelease: false
|
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
26
|
+
none: false
|
|
27
|
+
requirements:
|
|
28
|
+
- - ~>
|
|
29
|
+
- !ruby/object:Gem::Version
|
|
30
|
+
hash: 7
|
|
31
|
+
segments:
|
|
32
|
+
- 3
|
|
33
|
+
- 0
|
|
34
|
+
version: "3.0"
|
|
35
|
+
type: :runtime
|
|
36
|
+
version_requirements: *id001
|
|
37
|
+
- !ruby/object:Gem::Dependency
|
|
38
|
+
name: actionpack
|
|
39
|
+
prerelease: false
|
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ~>
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
hash: 7
|
|
46
|
+
segments:
|
|
47
|
+
- 3
|
|
48
|
+
- 0
|
|
49
|
+
version: "3.0"
|
|
50
|
+
type: :runtime
|
|
51
|
+
version_requirements: *id002
|
|
23
52
|
description: Forms made easy!
|
|
24
53
|
email: contact@plataformatec.com.br
|
|
25
54
|
executables: []
|
|
@@ -34,18 +63,16 @@ files:
|
|
|
34
63
|
- .travis.yml
|
|
35
64
|
- CHANGELOG.rdoc
|
|
36
65
|
- Gemfile
|
|
37
|
-
- Gemfile.lock
|
|
38
66
|
- MIT-LICENSE
|
|
39
67
|
- README.rdoc
|
|
40
68
|
- Rakefile
|
|
41
|
-
- init.rb
|
|
42
69
|
- lib/generators/simple_form/USAGE
|
|
43
70
|
- lib/generators/simple_form/install_generator.rb
|
|
44
71
|
- lib/generators/simple_form/templates/_form.html.erb
|
|
45
72
|
- lib/generators/simple_form/templates/_form.html.haml
|
|
46
73
|
- lib/generators/simple_form/templates/_form.html.slim
|
|
47
|
-
- lib/generators/simple_form/templates/
|
|
48
|
-
- lib/generators/simple_form/templates/simple_form.
|
|
74
|
+
- lib/generators/simple_form/templates/config/initializers/simple_form.rb
|
|
75
|
+
- lib/generators/simple_form/templates/config/locales/simple_form.en.yml
|
|
49
76
|
- lib/simple_form.rb
|
|
50
77
|
- lib/simple_form/action_view_extensions/builder.rb
|
|
51
78
|
- lib/simple_form/action_view_extensions/form_helper.rb
|
|
@@ -58,7 +85,12 @@ files:
|
|
|
58
85
|
- lib/simple_form/components/wrapper.rb
|
|
59
86
|
- lib/simple_form/error_notification.rb
|
|
60
87
|
- lib/simple_form/form_builder.rb
|
|
61
|
-
- lib/simple_form/
|
|
88
|
+
- lib/simple_form/helpers.rb
|
|
89
|
+
- lib/simple_form/helpers/has_errors.rb
|
|
90
|
+
- lib/simple_form/helpers/maxlength.rb
|
|
91
|
+
- lib/simple_form/helpers/pattern.rb
|
|
92
|
+
- lib/simple_form/helpers/required.rb
|
|
93
|
+
- lib/simple_form/helpers/validators.rb
|
|
62
94
|
- lib/simple_form/i18n_cache.rb
|
|
63
95
|
- lib/simple_form/inputs.rb
|
|
64
96
|
- lib/simple_form/inputs/base.rb
|
|
@@ -66,11 +98,14 @@ files:
|
|
|
66
98
|
- lib/simple_form/inputs/boolean_input.rb
|
|
67
99
|
- lib/simple_form/inputs/collection_input.rb
|
|
68
100
|
- lib/simple_form/inputs/date_time_input.rb
|
|
101
|
+
- lib/simple_form/inputs/file_input.rb
|
|
69
102
|
- lib/simple_form/inputs/hidden_input.rb
|
|
70
|
-
- lib/simple_form/inputs/mapping_input.rb
|
|
71
103
|
- lib/simple_form/inputs/numeric_input.rb
|
|
104
|
+
- lib/simple_form/inputs/password_input.rb
|
|
72
105
|
- lib/simple_form/inputs/priority_input.rb
|
|
106
|
+
- lib/simple_form/inputs/range_input.rb
|
|
73
107
|
- lib/simple_form/inputs/string_input.rb
|
|
108
|
+
- lib/simple_form/inputs/text_input.rb
|
|
74
109
|
- lib/simple_form/map_type.rb
|
|
75
110
|
- lib/simple_form/version.rb
|
|
76
111
|
- simple_form.gemspec
|