simple_form 1.2.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of simple_form might be problematic. Click here for more details.

Files changed (36) hide show
  1. data/README.rdoc +80 -14
  2. data/lib/generators/simple_form/templates/_form.html.erb +1 -11
  3. data/lib/generators/simple_form/templates/simple_form.rb +31 -6
  4. data/lib/simple_form.rb +38 -2
  5. data/lib/simple_form/action_view_extensions/builder.rb +53 -20
  6. data/lib/simple_form/components.rb +6 -5
  7. data/lib/simple_form/components/errors.rb +4 -6
  8. data/lib/simple_form/components/hints.rb +2 -2
  9. data/lib/simple_form/components/labels.rb +3 -5
  10. data/lib/simple_form/components/placeholders.rb +22 -0
  11. data/lib/simple_form/components/wrapper.rb +7 -0
  12. data/lib/simple_form/error_notification.rb +4 -6
  13. data/lib/simple_form/form_builder.rb +61 -55
  14. data/lib/simple_form/has_errors.rb +14 -0
  15. data/lib/simple_form/inputs/base.rb +45 -17
  16. data/lib/simple_form/inputs/block_input.rb +3 -2
  17. data/lib/simple_form/inputs/collection_input.rb +42 -17
  18. data/lib/simple_form/inputs/date_time_input.rb +3 -1
  19. data/lib/simple_form/inputs/hidden_input.rb +11 -2
  20. data/lib/simple_form/inputs/mapping_input.rb +16 -3
  21. data/lib/simple_form/inputs/numeric_input.rb +45 -8
  22. data/lib/simple_form/inputs/string_input.rb +13 -9
  23. data/lib/simple_form/map_type.rb +4 -4
  24. data/lib/simple_form/version.rb +1 -1
  25. data/test/action_view_extensions/builder_test.rb +155 -51
  26. data/test/components/error_test.rb +10 -8
  27. data/test/components/hint_test.rb +4 -8
  28. data/test/components/label_test.rb +22 -9
  29. data/test/components/wrapper_test.rb +16 -7
  30. data/test/error_notification_test.rb +4 -3
  31. data/test/form_builder_test.rb +81 -34
  32. data/test/inputs_test.rb +242 -3
  33. data/test/support/misc_helpers.rb +6 -4
  34. data/test/support/models.rb +26 -3
  35. data/test/test_helper.rb +13 -5
  36. metadata +25 -8
@@ -3,14 +3,10 @@ require 'test_helper'
3
3
  class ErrorTest < ActionView::TestCase
4
4
 
5
5
  def with_error_for(object, attribute_name, type, options={}, &block)
6
- concat(simple_form_for(object) do |f|
7
- f.attribute_name = attribute_name
8
- f.reflection = Association.new(Company, :company, {}) if options.delete(:setup_association)
9
- f.input_type = type
10
- f.options = options
11
-
12
- concat(SimpleForm::Inputs::Base.new(f).error.to_s)
13
- end)
6
+ with_concat_form_for(object) do |f|
7
+ options[:reflection] = Association.new(Company, :company, {}) if options.delete(:setup_association)
8
+ SimpleForm::Inputs::Base.new(f, attribute_name, nil, type, options).error.to_s
9
+ end
14
10
  end
15
11
 
16
12
  test 'error should not generate content for attribute without errors' do
@@ -23,6 +19,12 @@ class ErrorTest < ActionView::TestCase
23
19
  assert_no_select 'span.error'
24
20
  end
25
21
 
22
+ test "error should not generate messages when object doesn't respond to errors method" do
23
+ @user.instance_eval { undef errors }
24
+ with_error_for @user, :name, :string
25
+ assert_no_select 'span.error'
26
+ end
27
+
26
28
  test 'error should generate messages for attribute with single error' do
27
29
  with_error_for @user, :name, :string
28
30
  assert_select 'span.error', "can't be blank"
@@ -3,14 +3,10 @@ require 'test_helper'
3
3
  class HintTest < ActionView::TestCase
4
4
 
5
5
  def with_hint_for(object, attribute_name, type, options={}, &block)
6
- concat(simple_form_for(object) do |f|
7
- f.attribute_name = attribute_name
8
- f.reflection = Association.new(Company, :company, {}) if options.delete(:setup_association)
9
- f.input_type = type
10
- f.options = options
11
-
12
- concat(SimpleForm::Inputs::Base.new(f).hint.to_s)
13
- end)
6
+ with_concat_form_for(object) do |f|
7
+ options[:reflection] = Association.new(Company, :company, {}) if options.delete(:setup_association)
8
+ SimpleForm::Inputs::Base.new(f, attribute_name, nil, type, options).hint.to_s
9
+ end
14
10
  end
15
11
 
16
12
  test 'hint should not be generated by default' do
@@ -2,20 +2,15 @@
2
2
  require 'test_helper'
3
3
 
4
4
  class LabelTest < ActionView::TestCase
5
-
6
5
  setup do
7
6
  SimpleForm::Inputs::Base.reset_i18n_cache :translate_required_html
8
7
  end
9
8
 
10
9
  def with_label_for(object, attribute_name, type, options={})
11
- concat(simple_form_for(object) do |f|
12
- f.attribute_name = attribute_name
13
- f.reflection = Association.new(Company, :company, {}) if options.delete(:setup_association)
14
- f.input_type = type
15
- f.options = options
16
-
17
- concat(SimpleForm::Inputs::Base.new(f).label)
18
- end)
10
+ with_concat_form_for(object) do |f|
11
+ options[:reflection] = Association.new(Company, :company, {}) if options.delete(:setup_association)
12
+ SimpleForm::Inputs::Base.new(f, attribute_name, nil, type, options).label
13
+ end
19
14
  end
20
15
 
21
16
  test 'label should generate a default humanized description' do
@@ -58,6 +53,15 @@ class LabelTest < ActionView::TestCase
58
53
  end
59
54
  end
60
55
 
56
+ test 'label should not explode while looking for i18n translation when action is not set' do
57
+ def @controller.action_name; nil; end
58
+
59
+ assert_nothing_raised do
60
+ with_label_for @user, :description, :text
61
+ end
62
+ assert_select 'label[for=user_description]'
63
+ end
64
+
61
65
  test 'label should use i18n based on model and attribute to lookup translation' do
62
66
  store_translations(:en, :simple_form => { :labels => { :user => {
63
67
  :description => 'Descrição'
@@ -74,6 +78,15 @@ class LabelTest < ActionView::TestCase
74
78
  end
75
79
  end
76
80
 
81
+ test 'input should not use i18n label if translate is false' do
82
+ swap SimpleForm, :translate => false do
83
+ store_translations(:en, :simple_form => { :labels => { :age => 'Idade' } } ) do
84
+ with_label_for @user, :age, :integer
85
+ assert_select 'label[for=user_age]', /Age/
86
+ end
87
+ end
88
+ end
89
+
77
90
  test 'label should use i18n with lookup for association name' do
78
91
  store_translations(:en, :simple_form => { :labels => {
79
92
  :user => { :company => 'My company!' }
@@ -1,17 +1,16 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class WrapperTest < ActionView::TestCase
4
- def with_error_for(object, attribute_name, options={}, &block)
5
- concat(simple_form_for(object) do |f|
6
- f.options = options
4
+ def with_error_for(object, attribute_name, &block)
5
+ with_concat_form_for(object) do |f|
7
6
  f.input attribute_name
8
- end)
7
+ end
9
8
  end
10
9
 
11
10
  def with_form_for(object, *args, &block)
12
- concat(simple_form_for(object) do |f|
13
- concat f.input(*args, &block)
14
- end)
11
+ with_concat_form_for(object) do |f|
12
+ f.input(*args, &block)
13
+ end
15
14
  end
16
15
 
17
16
  test 'wrapper should not have error class for attribute without errors' do
@@ -51,4 +50,14 @@ class WrapperTest < ActionView::TestCase
51
50
  assert_no_select 'div.input'
52
51
  end
53
52
  end
53
+
54
+ test 'wrapper should not have disabled class by default' do
55
+ with_form_for @user, :active
56
+ assert_no_select 'div.disabled'
57
+ end
58
+
59
+ test 'wrapper should add disabled class when the input is disabled' do
60
+ with_form_for @user, :active, :disabled => true
61
+ assert_select 'div.disabled'
62
+ end
54
63
  end
@@ -1,11 +1,12 @@
1
+ # encoding: UTF-8
1
2
  require 'test_helper'
2
3
 
3
4
  class ErrorNotificationTest < ActionView::TestCase
4
5
 
5
6
  def with_error_notification_for(object, options={}, &block)
6
- concat(simple_form_for(object) do |f|
7
- concat(f.error_notification(options))
8
- end)
7
+ with_concat_form_for(object) do |f|
8
+ f.error_notification(options)
9
+ end
9
10
  end
10
11
 
11
12
  test 'error notification is not generated when the object has no error' do
@@ -4,39 +4,39 @@ require 'test_helper'
4
4
  class FormBuilderTest < ActionView::TestCase
5
5
 
6
6
  def with_form_for(object, *args, &block)
7
- concat(simple_form_for(object) do |f|
8
- concat f.input(*args, &block)
9
- end)
7
+ with_concat_form_for(object) do |f|
8
+ f.input(*args, &block)
9
+ end
10
10
  end
11
11
 
12
12
  def with_button_for(object, *args)
13
- concat(simple_form_for(object) do |f|
14
- concat f.button(*args)
15
- end)
13
+ with_concat_form_for(object) do |f|
14
+ f.button(*args)
15
+ end
16
16
  end
17
17
 
18
18
  def with_error_for(object, *args)
19
- concat(simple_form_for(object) do |f|
20
- concat f.error(*args)
21
- end)
19
+ with_concat_form_for(object) do |f|
20
+ f.error(*args)
21
+ end
22
22
  end
23
23
 
24
24
  def with_hint_for(object, *args)
25
- concat(simple_form_for(object) do |f|
26
- concat f.hint(*args)
27
- end)
25
+ with_concat_form_for(object) do |f|
26
+ f.hint(*args)
27
+ end
28
28
  end
29
29
 
30
30
  def with_label_for(object, *args)
31
- concat(simple_form_for(object) do |f|
32
- concat f.label(*args)
33
- end)
31
+ with_concat_form_for(object) do |f|
32
+ f.label(*args)
33
+ end
34
34
  end
35
35
 
36
36
  def with_association_for(object, *args)
37
- concat(simple_form_for(object) do |f|
38
- concat f.association(*args)
39
- end)
37
+ with_concat_form_for(object) do |f|
38
+ f.association(*args)
39
+ end
40
40
  end
41
41
 
42
42
  # All
@@ -56,12 +56,28 @@ class FormBuilderTest < ActionView::TestCase
56
56
 
57
57
  test 'builder input should allow a block to configure input' do
58
58
  with_form_for @user, :name do
59
- concat text_field_tag :foo, :bar, :id => :cool
59
+ text_field_tag :foo, :bar, :id => :cool
60
60
  end
61
61
  assert_no_select 'input.string'
62
62
  assert_select 'input#cool'
63
63
  end
64
64
 
65
+ test 'builder should allow adding custom input mappings for default input types' do
66
+ swap SimpleForm, :input_mappings => { /count$/ => :integer } do
67
+ with_form_for @user, :post_count
68
+ assert_no_select 'form input#user_post_count.string'
69
+ assert_select 'form input#user_post_count.numeric.integer'
70
+ end
71
+ end
72
+
73
+ test 'builder uses the first matching custom input map when more than one match' do
74
+ swap SimpleForm, :input_mappings => { /count$/ => :integer, /^post_/ => :password } do
75
+ with_form_for @user, :post_count
76
+ assert_no_select 'form input#user_post_count.password'
77
+ assert_select 'form input#user_post_count.numeric.integer'
78
+ end
79
+ end
80
+
65
81
  # INPUT TYPES
66
82
  test 'builder should generate text fields for string columns' do
67
83
  with_form_for @user, :name
@@ -108,6 +124,11 @@ class FormBuilderTest < ActionView::TestCase
108
124
  assert_select 'form input#user_email.string.email'
109
125
  end
110
126
 
127
+ test 'builder should generate tel fields for columns that matches phone' do
128
+ with_form_for @user, :phone_number
129
+ assert_select 'form input#user_phone_number.string.tel'
130
+ end
131
+
111
132
  test 'builder should generate url fields for columns that matches url' do
112
133
  with_form_for @user, :url
113
134
  assert_select 'form input#user_url.string.url'
@@ -230,10 +251,19 @@ class FormBuilderTest < ActionView::TestCase
230
251
  assert_select 'span.error#cool', "can't be blank"
231
252
  end
232
253
 
254
+ test 'placeholder should not be generated when set to false' do
255
+ store_translations(:en, :simple_form => { :placeholders => { :user => {
256
+ :name => 'Name goes here'
257
+ } } }) do
258
+ with_form_for @user, :name, :placeholder => false
259
+ assert_no_select 'input[placeholder]'
260
+ end
261
+ end
262
+
233
263
  # REQUIRED AND PRESENCE VALIDATION
234
264
  test 'builder input should obtain required from ActiveModel::Validations when it is included' do
235
265
  with_form_for @validating_user, :name
236
- assert_select 'input.required#validating_user_name'
266
+ assert_select 'input.required[required]#validating_user_name'
237
267
  with_form_for @validating_user, :status
238
268
  assert_select 'input.optional#validating_user_status'
239
269
  end
@@ -242,24 +272,26 @@ class FormBuilderTest < ActionView::TestCase
242
272
  with_form_for @validating_user, :name, :required => false
243
273
  assert_select 'input.optional#validating_user_name'
244
274
  with_form_for @validating_user, :status, :required => true
245
- assert_select 'input.required#validating_user_status'
275
+ assert_select 'input.required[required]#validating_user_status'
246
276
  end
247
277
 
248
278
  test 'builder input should be required by default when ActiveModel::Validations is not included' do
249
279
  with_form_for @user, :name
250
- assert_select 'input.required#user_name'
280
+ assert_select 'input.required[required]#user_name'
251
281
  end
252
282
 
253
283
  test 'builder input should not be required by default when ActiveModel::Validations is not included if option is set to false' do
254
284
  swap SimpleForm, :required_by_default => false do
255
285
  with_form_for @user, :name
256
286
  assert_select 'input.optional#user_name'
287
+ assert_no_select 'input[required]'
257
288
  end
258
289
  end
259
290
 
260
291
  test 'builder input should allow disabling required when ActiveModel::Validations is not included' do
261
292
  with_form_for @user, :name, :required => false
262
293
  assert_no_select 'input.required'
294
+ assert_no_select 'input[required]'
263
295
  assert_select 'input.optional#user_name'
264
296
  end
265
297
 
@@ -290,16 +322,16 @@ class FormBuilderTest < ActionView::TestCase
290
322
  end
291
323
 
292
324
  test 'builder allows wrapper tag to be given on demand' do
293
- concat(simple_form_for(@user) do |f|
294
- concat f.input :name, :wrapper_tag => :b
295
- end)
325
+ with_concat_form_for(@user) do |f|
326
+ f.input :name, :wrapper_tag => :b
327
+ end
296
328
  assert_select 'form b.required.string'
297
329
  end
298
330
 
299
331
  test 'builder allows wrapper class to be given on demand' do
300
- concat(simple_form_for(@user) do |f|
301
- concat f.input :name, :wrapper_class => :wrapper
302
- end)
332
+ with_concat_form_for(@user) do |f|
333
+ f.input :name, :wrapper_class => :wrapper
334
+ end
303
335
  assert_select 'form div.wrapper.required.string'
304
336
  end
305
337
 
@@ -353,9 +385,9 @@ class FormBuilderTest < ActionView::TestCase
353
385
  end
354
386
 
355
387
  test 'builder should generate a hint component tag for the given text' do
356
- with_hint_for @user, 'Hello World!'
357
- assert_select 'span.hint', 'Hello World!'
358
- end
388
+ with_hint_for @user, 'Hello World!'
389
+ assert_select 'span.hint', 'Hello World!'
390
+ end
359
391
 
360
392
  test 'builder should allow passing options to hint tag' do
361
393
  with_hint_for @user, :name, :hint => 'Hello World!', :id => 'name_hint'
@@ -370,7 +402,7 @@ class FormBuilderTest < ActionView::TestCase
370
402
 
371
403
  test 'builder should add a required class to label if the attribute is required' do
372
404
  with_label_for @validating_user, :name
373
- assert_select 'label.string[for=validating_user_name]', /Name/
405
+ assert_select 'label.string.required[for=validating_user_name]', /Name/
374
406
  end
375
407
 
376
408
  test 'builder should allow passing options to label tag' do
@@ -394,13 +426,13 @@ class FormBuilderTest < ActionView::TestCase
394
426
  # BUTTONS
395
427
  test 'builder should create buttons' do
396
428
  with_button_for :post, :submit
397
- assert_select 'form input[type=submit][value=Save Post]'
429
+ assert_select 'form input.button[type=submit][value=Save Post]'
398
430
  end
399
431
 
400
432
  test 'builder should create buttons for records' do
401
433
  @user.new_record!
402
434
  with_button_for @user, :submit
403
- assert_select 'form input[type=submit][value=Create User]'
435
+ assert_select 'form input.button[type=submit][value=Create User]'
404
436
  end
405
437
 
406
438
  # ASSOCIATIONS
@@ -429,6 +461,13 @@ class FormBuilderTest < ActionView::TestCase
429
461
  assert_equal 3, calls
430
462
  end
431
463
 
464
+ test 'builder association mark input as required based both association and attribute' do
465
+ swap SimpleForm, :required_by_default => false do
466
+ with_association_for @validating_user, :company, :collection => []
467
+ assert_select 'label.required'
468
+ end
469
+ end
470
+
432
471
  # ASSOCIATIONS - BELONGS TO
433
472
  test 'builder creates a select for belongs_to associations' do
434
473
  with_association_for @user, :company
@@ -515,4 +554,12 @@ class FormBuilderTest < ActionView::TestCase
515
554
  assert_select 'form input[type=checkbox][value=2][checked=checked]'
516
555
  assert_no_select 'form input[type=checkbox][value=3][checked=checked]'
517
556
  end
557
+
558
+ test 'builder with collection support giving collection and item wrapper tags' do
559
+ with_association_for @user, :tags, :as => :check_boxes,
560
+ :collection_wrapper_tag => :ul, :item_wrapper_tag => :li
561
+
562
+ assert_select 'form ul', :count => 1
563
+ assert_select 'form ul li', :count => 3
564
+ end
518
565
  end
data/test/inputs_test.rb CHANGED
@@ -8,9 +8,9 @@ class InputTest < ActionView::TestCase
8
8
  end
9
9
 
10
10
  def with_input_for(object, attribute_name, type, options={})
11
- concat(simple_form_for(object) do |f|
12
- concat f.input(attribute_name, options.merge(:as => type))
13
- end)
11
+ with_concat_form_for(object) do |f|
12
+ f.input(attribute_name, options.merge(:as => type))
13
+ end
14
14
  end
15
15
 
16
16
  # ALL
@@ -27,6 +27,67 @@ class InputTest < ActionView::TestCase
27
27
  assert_select 'select.datetime'
28
28
  end
29
29
 
30
+ test 'input should generate disabled elements based on the disabled option' do
31
+ with_input_for @user, :name, :string, :disabled => true
32
+ assert_select 'input.string[disabled]'
33
+ with_input_for @user, :description, :text, :disabled => true
34
+ assert_select 'textarea.text[disabled]'
35
+ with_input_for @user, :age, :integer, :disabled => true
36
+ assert_select 'input.integer[disabled]'
37
+ with_input_for @user, :born_at, :date, :disabled => true
38
+ assert_select 'select.date[disabled]'
39
+ with_input_for @user, :created_at, :datetime, :disabled => true
40
+ assert_select 'select.datetime[disabled]'
41
+
42
+ with_input_for @user, :name, :string, :disabled => false
43
+ assert_select 'input.string:not([disabled])'
44
+ with_input_for @user, :description, :text, :disabled => false
45
+ assert_select 'textarea.text:not([disabled])'
46
+ with_input_for @user, :age, :integer, :disabled => false
47
+ assert_select 'input.integer:not([disabled])'
48
+ with_input_for @user, :born_at, :date, :disabled => false
49
+ assert_select 'select.date:not([disabled])'
50
+ with_input_for @user, :created_at, :datetime, :disabled => false
51
+ assert_select 'select.datetime:not([disabled])'
52
+
53
+ with_input_for @user, :name, :string
54
+ assert_select 'input.string:not([disabled])'
55
+ with_input_for @user, :description, :text
56
+ assert_select 'textarea.text:not([disabled])'
57
+ with_input_for @user, :age, :integer
58
+ assert_select 'input.integer:not([disabled])'
59
+ with_input_for @user, :born_at, :date
60
+ assert_select 'select.date:not([disabled])'
61
+ with_input_for @user, :created_at, :datetime
62
+ assert_select 'select.datetime:not([disabled])'
63
+ end
64
+
65
+ test 'input should render components according to an optional :components option' do
66
+ with_input_for @user, :name, :string, :components => [:input, :label]
67
+ assert_select 'input + label'
68
+
69
+ with_input_for @user, :age, :integer, :components => [:input, :label]
70
+ assert_select 'input + label'
71
+
72
+ with_input_for @user, :active, :boolean, :components => [:label, :input]
73
+ assert_select 'label + input'
74
+
75
+ with_input_for @user, :description, :text, :components => [:input, :label]
76
+ assert_select 'textarea + label'
77
+
78
+ with_input_for @user, :password, :password, :components => [:input, :label]
79
+ assert_select 'input + label'
80
+
81
+ with_input_for @user, :name, :file, :components => [:input, :label]
82
+ assert_select 'input + label'
83
+
84
+ with_input_for @user, :country, :country, :components => [:input, :label]
85
+ assert_select 'select + label'
86
+
87
+ with_input_for @user, :time_zone, :time_zone, :components => [:input, :label]
88
+ assert_select 'select + label'
89
+ end
90
+
30
91
  # StringInput
31
92
  test 'input should map text field to string attribute' do
32
93
  with_input_for @user, :name, :string
@@ -48,6 +109,32 @@ class InputTest < ActionView::TestCase
48
109
  assert_select 'input.string[size=50]'
49
110
  end
50
111
 
112
+ test 'input should not generate placeholder by default' do
113
+ with_input_for @user, :name, :string
114
+ assert_no_select 'input[placeholder]'
115
+ end
116
+
117
+ test 'input should accept the placeholder option' do
118
+ with_input_for @user, :name, :string, :placeholder => 'Put in some text'
119
+ assert_select 'input.string[placeholder=Put in some text]'
120
+ end
121
+
122
+ test 'input should use i18n to translate placeholder text' do
123
+ store_translations(:en, :simple_form => { :placeholders => { :user => {
124
+ :name => 'Name goes here'
125
+ } } }) do
126
+ with_input_for @user, :name, :string
127
+ assert_select 'input.string[placeholder=Name goes here]'
128
+ end
129
+ end
130
+
131
+ [:email, :url, :search, :tel].each do |type|
132
+ test "input should allow type #{type}" do
133
+ with_input_for @user, :name, type
134
+ assert_select "input.string.#{type}"
135
+ end
136
+ end
137
+
51
138
  # NumericInput
52
139
  test 'input should generate an integer text field for integer attributes ' do
53
140
  with_input_for @user, :age, :integer
@@ -64,6 +151,71 @@ class InputTest < ActionView::TestCase
64
151
  assert_select 'input[type=number].decimal#user_age'
65
152
  end
66
153
 
154
+ test 'input should not generate min attribute by default' do
155
+ with_input_for @user, :age, :integer
156
+ assert_no_select 'input[min]'
157
+ end
158
+
159
+ test 'input should not generate max attribute by default' do
160
+ with_input_for @user, :age, :integer
161
+ assert_no_select 'input[max]'
162
+ end
163
+
164
+ test 'input should infer min value from integer attributes with greater than validation' do
165
+ with_input_for @other_validating_user, :age, :float
166
+ assert_no_select 'input[min]'
167
+
168
+ with_input_for @other_validating_user, :age, :integer
169
+ assert_select 'input[min=18]'
170
+ end
171
+
172
+ test 'input should infer max value from attributes with less than validation' do
173
+ with_input_for @other_validating_user, :age, :float
174
+ assert_no_select 'input[max]'
175
+
176
+ with_input_for @other_validating_user, :age, :integer
177
+ assert_select 'input[max=99]'
178
+ end
179
+
180
+ test 'input should infer step value only from integer attribute' do
181
+ with_input_for @validating_user, :age, :float
182
+ assert_no_select 'input[step]'
183
+
184
+ with_input_for @validating_user, :age, :integer
185
+ assert_select 'input[step=1]'
186
+ end
187
+
188
+ test 'numeric input should not generate placeholder by default' do
189
+ with_input_for @user, :age, :integer
190
+ assert_no_select 'input[placeholder]'
191
+ end
192
+
193
+ test 'numeric input should accept the placeholder option' do
194
+ with_input_for @user, :age, :integer, :placeholder => 'Put in your age'
195
+ assert_select 'input.integer[placeholder=Put in your age]'
196
+ end
197
+
198
+ test 'numeric input should use i18n to translate placeholder text' do
199
+ store_translations(:en, :simple_form => { :placeholders => { :user => {
200
+ :age => 'Age goes here'
201
+ } } }) do
202
+ with_input_for @user, :age, :integer
203
+ assert_select 'input.integer[placeholder=Age goes here]'
204
+ end
205
+ end
206
+
207
+ [:integer, :float, :decimal].each do |type|
208
+ test "#{type} input should infer min value from attributes with greater than or equal validation" do
209
+ with_input_for @validating_user, :age, type
210
+ assert_select 'input[min=18]'
211
+ end
212
+
213
+ test "#{type} input should infer the max value from attributes with less than or equal to validation" do
214
+ with_input_for @validating_user, :age, type
215
+ assert_select 'input[max=99]'
216
+ end
217
+ end
218
+
67
219
  # BooleanInput
68
220
  test 'input should generate a checkbox by default for boolean attributes' do
69
221
  with_input_for @user, :active, :boolean
@@ -77,16 +229,39 @@ class InputTest < ActionView::TestCase
77
229
  assert_select 'textarea.text#user_description'
78
230
  end
79
231
 
232
+ test 'input should generate a text area for text attributes that accept placeholder' do
233
+ with_input_for @user, :description, :text, :placeholder => 'Put in some text'
234
+ assert_select 'textarea.text[placeholder=Put in some text]'
235
+ end
236
+
80
237
  test 'input should generate a password field for password attributes' do
81
238
  with_input_for @user, :password, :password
82
239
  assert_select 'input[type=password].password#user_password'
83
240
  end
84
241
 
242
+ test 'input should generate a password field for password attributes that accept placeholder' do
243
+ with_input_for @user, :password, :password, :placeholder => 'Password Confirmation'
244
+ assert_select 'input[type=password].password[placeholder=Password Confirmation]#user_password'
245
+ end
246
+
85
247
  test 'input should generate a file field' do
86
248
  with_input_for @user, :name, :file
87
249
  assert_select 'input#user_name[type=file]'
88
250
  end
89
251
 
252
+ test "input should generate a file field that don't accept placeholder" do
253
+ with_input_for @user, :name, :file, :placeholder => 'Put in some text'
254
+ assert_no_select 'input[placeholder]'
255
+ end
256
+
257
+ test 'mapping input should generate an error if type is not found' do
258
+ with_concat_form_for(@user) do |f|
259
+ assert_raise(RuntimeError, "Could not find method for nil") do
260
+ SimpleForm::Inputs::MappingInput.new(f, "unknown", nil, nil, {}).input
261
+ end
262
+ end
263
+ end
264
+
90
265
  # HiddenInput
91
266
  test 'input should generate a hidden field' do
92
267
  with_input_for @user, :name, :hidden
@@ -104,6 +279,14 @@ class InputTest < ActionView::TestCase
104
279
  assert_no_select 'label'
105
280
  end
106
281
 
282
+ test 'required/optional options should not be generated for hidden inputs' do
283
+ with_input_for @user, :name, :hidden
284
+ assert_no_select 'input.required'
285
+ assert_no_select 'input[required]'
286
+ assert_no_select 'input.optional'
287
+ assert_select 'input.hidden#user_name'
288
+ end
289
+
107
290
  # PriorityInput
108
291
  test 'input should generate a country select field' do
109
292
  with_input_for @user, :country, :country
@@ -267,6 +450,28 @@ class InputTest < ActionView::TestCase
267
450
  assert_select 'select option[selected=selected]', '18'
268
451
  end
269
452
 
453
+ test 'input should set the correct value when using a collection that includes floats' do
454
+ with_input_for @user, :age, :select, :collection => [2.0, 2.5, 3.0, 3.5, 4.0, 4.5]
455
+ assert_select 'select option[value="2.0"]'
456
+ assert_select 'select option[value="2.5"]'
457
+ end
458
+
459
+ test 'input should set the correct values when using a collection that uses mixed values' do
460
+ with_input_for @user, :age, :select, :collection => ["Hello Kitty", 2, 4.5, :johnny, nil, true, false]
461
+ assert_select 'select option[value="Hello Kitty"]'
462
+ assert_select 'select option[value="2"]'
463
+ assert_select 'select option[value="4.5"]'
464
+ assert_select 'select option[value="johnny"]'
465
+ assert_select 'select option[value=""]'
466
+ assert_select 'select option[value="true"]'
467
+ assert_select 'select option[value="false"]'
468
+ end
469
+
470
+ test 'input should include a blank option even if :include_blank is set to false if the collection includes a nil value' do
471
+ with_input_for @user, :age, :select, :collection => [nil], :include_blank => false
472
+ assert_select 'select option[value=""]'
473
+ end
474
+
270
475
  test 'input should automatically set include blank' do
271
476
  with_input_for @user, :age, :select, :collection => 18..30
272
477
  assert_select 'select option[value=]', ''
@@ -316,6 +521,22 @@ class InputTest < ActionView::TestCase
316
521
  assert_select 'label.collection_radio', 'Carlos'
317
522
  end
318
523
 
524
+ test 'input should allow overriding only label method for collections' do
525
+ with_input_for @user, :name, :radio,
526
+ :collection => ['Jose' , 'Carlos'],
527
+ :label_method => :upcase
528
+ assert_select 'label.collection_radio', 'JOSE'
529
+ assert_select 'label.collection_radio', 'CARLOS'
530
+ end
531
+
532
+ test 'input should allow overriding only value method for collections' do
533
+ with_input_for @user, :name, :radio,
534
+ :collection => ['Jose' , 'Carlos'],
535
+ :value_method => :upcase
536
+ assert_select 'input[type=radio][value=JOSE]'
537
+ assert_select 'input[type=radio][value=CARLOS]'
538
+ end
539
+
319
540
  test 'input should allow overriding label and value method for collections' do
320
541
  with_input_for @user, :name, :radio,
321
542
  :collection => ['Jose' , 'Carlos'],
@@ -327,6 +548,24 @@ class InputTest < ActionView::TestCase
327
548
  assert_select 'label.collection_radio', 'CARLOS'
328
549
  end
329
550
 
551
+ test 'input should allow overriding label and value method using a lambda for collections' do
552
+ with_input_for @user, :name, :radio,
553
+ :collection => ['Jose' , 'Carlos'],
554
+ :label_method => lambda { |i| i.upcase },
555
+ :value_method => lambda { |i| i.downcase }
556
+ assert_select 'input[type=radio][value=jose]'
557
+ assert_select 'input[type=radio][value=carlos]'
558
+ assert_select 'label.collection_radio', 'JOSE'
559
+ assert_select 'label.collection_radio', 'CARLOS'
560
+ end
561
+
562
+ test 'input should allow symbols for collections' do
563
+ with_input_for @user, :name, :select, :collection => [:jose, :carlos]
564
+ assert_select 'select.select#user_name'
565
+ assert_select 'select option[value=jose]', 'jose'
566
+ assert_select 'select option[value=carlos]', 'carlos'
567
+ end
568
+
330
569
  # With no object
331
570
  test 'input should be generated properly when object is not present' do
332
571
  with_input_for :project, :name, :string