simple_form 3.0.4 → 3.1.0.rc1

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.

Potentially problematic release.


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

Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -43
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +146 -71
  5. data/lib/generators/simple_form/install_generator.rb +2 -2
  6. data/lib/generators/simple_form/templates/README +3 -4
  7. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +19 -3
  8. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +83 -22
  9. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +1 -1
  10. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -2
  11. data/lib/simple_form.rb +38 -6
  12. data/lib/simple_form/action_view_extensions/form_helper.rb +1 -1
  13. data/lib/simple_form/components/errors.rb +27 -5
  14. data/lib/simple_form/components/hints.rb +2 -2
  15. data/lib/simple_form/components/html5.rb +1 -1
  16. data/lib/simple_form/components/label_input.rb +20 -2
  17. data/lib/simple_form/components/labels.rb +9 -5
  18. data/lib/simple_form/components/maxlength.rb +1 -1
  19. data/lib/simple_form/components/min_max.rb +1 -1
  20. data/lib/simple_form/components/pattern.rb +1 -1
  21. data/lib/simple_form/components/placeholders.rb +2 -2
  22. data/lib/simple_form/components/readonly.rb +1 -1
  23. data/lib/simple_form/form_builder.rb +92 -59
  24. data/lib/simple_form/helpers.rb +5 -5
  25. data/lib/simple_form/inputs/base.rb +34 -12
  26. data/lib/simple_form/inputs/block_input.rb +1 -1
  27. data/lib/simple_form/inputs/boolean_input.rb +23 -13
  28. data/lib/simple_form/inputs/collection_input.rb +32 -9
  29. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +6 -11
  30. data/lib/simple_form/inputs/collection_select_input.rb +4 -2
  31. data/lib/simple_form/inputs/date_time_input.rb +12 -2
  32. data/lib/simple_form/inputs/file_input.rb +4 -2
  33. data/lib/simple_form/inputs/grouped_collection_select_input.rb +15 -3
  34. data/lib/simple_form/inputs/hidden_input.rb +4 -2
  35. data/lib/simple_form/inputs/numeric_input.rb +5 -4
  36. data/lib/simple_form/inputs/password_input.rb +4 -2
  37. data/lib/simple_form/inputs/priority_input.rb +4 -2
  38. data/lib/simple_form/inputs/range_input.rb +1 -1
  39. data/lib/simple_form/inputs/string_input.rb +4 -2
  40. data/lib/simple_form/inputs/text_input.rb +4 -2
  41. data/lib/simple_form/railtie.rb +7 -0
  42. data/lib/simple_form/tags.rb +7 -0
  43. data/lib/simple_form/version.rb +1 -1
  44. data/lib/simple_form/wrappers.rb +1 -0
  45. data/lib/simple_form/wrappers/builder.rb +5 -5
  46. data/lib/simple_form/wrappers/leaf.rb +28 -0
  47. data/lib/simple_form/wrappers/many.rb +5 -6
  48. data/lib/simple_form/wrappers/root.rb +1 -1
  49. data/lib/simple_form/wrappers/single.rb +5 -3
  50. data/test/action_view_extensions/builder_test.rb +2 -2
  51. data/test/components/label_test.rb +1 -1
  52. data/test/form_builder/association_test.rb +17 -0
  53. data/test/form_builder/error_notification_test.rb +1 -1
  54. data/test/form_builder/error_test.rb +51 -32
  55. data/test/form_builder/general_test.rb +2 -2
  56. data/test/form_builder/input_field_test.rb +21 -37
  57. data/test/form_builder/label_test.rb +24 -1
  58. data/test/form_builder/wrapper_test.rb +67 -0
  59. data/test/generators/simple_form_generator_test.rb +2 -2
  60. data/test/inputs/boolean_input_test.rb +50 -2
  61. data/test/inputs/collection_check_boxes_input_test.rb +40 -11
  62. data/test/inputs/collection_radio_buttons_input_test.rb +76 -17
  63. data/test/inputs/collection_select_input_test.rb +108 -3
  64. data/test/inputs/datetime_input_test.rb +105 -38
  65. data/test/inputs/discovery_test.rb +12 -1
  66. data/test/inputs/grouped_collection_select_input_test.rb +36 -0
  67. data/test/inputs/string_input_test.rb +20 -0
  68. data/test/simple_form_test.rb +8 -0
  69. data/test/support/discovery_inputs.rb +12 -2
  70. data/test/support/misc_helpers.rb +46 -8
  71. data/test/support/models.rb +49 -24
  72. metadata +7 -7
@@ -73,9 +73,32 @@ class LabelTest < ActionView::TestCase
73
73
  end
74
74
 
75
75
  test 'builder allows label order to be changed' do
76
- swap SimpleForm, label_text: lambda { |l, r| "#{l}:" } do
76
+ swap SimpleForm, label_text: proc { |l, r| "#{l}:" } do
77
77
  with_label_for @user, :age
78
78
  assert_select 'label.integer[for=user_age]', "Age:"
79
79
  end
80
80
  end
81
+
82
+ test 'configuration allow set label text for wrappers' do
83
+ swap_wrapper :default, self.custom_wrapper_with_label_text do
84
+ with_concat_form_for(@user) do |f|
85
+ concat f.input :age
86
+ end
87
+ assert_select "label.integer[for=user_age]", "**Age**"
88
+ end
89
+ end
90
+
91
+ test 'builder should allow custom formatting when label is explicitly specified' do
92
+ swap SimpleForm, label_text: lambda { |l, r, explicit_label| explicit_label ? l : "#{l.titleize}:" } do
93
+ with_label_for @user, :time_zone, 'What is your home time zone?'
94
+ assert_select 'label[for=user_time_zone]', 'What is your home time zone?'
95
+ end
96
+ end
97
+
98
+ test 'builder should allow custom formatting when label is generated' do
99
+ swap SimpleForm, label_text: lambda { |l, r, explicit_label| explicit_label ? l : "#{l.titleize}:" } do
100
+ with_label_for @user, :time_zone
101
+ assert_select 'label[for=user_time_zone]', 'Time Zone:'
102
+ end
103
+ end
81
104
  end
@@ -128,6 +128,21 @@ class WrapperTest < ActionView::TestCase
128
128
  end
129
129
  end
130
130
 
131
+ test 'custom wrappers can have additional attributes' do
132
+ swap_wrapper :default, self.custom_wrapper_with_additional_attributes do
133
+ with_form_for @user, :name
134
+
135
+ assert_select "div.custom_wrapper[title='some title'][data-wrapper='test']"
136
+ end
137
+ end
138
+
139
+ test 'custom wrappers can have full error message on attributes' do
140
+ swap_wrapper :default, self.custom_wrapper_with_full_error do
141
+ with_form_for @user, :name
142
+ assert_select 'span.error', "Name can't be blank"
143
+ end
144
+ end
145
+
131
146
  test 'custom wrappers on a form basis' do
132
147
  swap_wrapper :another do
133
148
  with_concat_form_for(@user) do |f|
@@ -200,4 +215,56 @@ class WrapperTest < ActionView::TestCase
200
215
  end
201
216
  end
202
217
  end
218
+
219
+ test 'use custom wrapper mapping per form basis' do
220
+ swap_wrapper :another do
221
+ with_concat_form_for @user, wrapper_mappings: { string: :another } do |f|
222
+ concat f.input :name
223
+ end
224
+ end
225
+
226
+ assert_select "section.custom_wrapper div.another_wrapper label"
227
+ assert_select "section.custom_wrapper div.another_wrapper input.string"
228
+ end
229
+
230
+ test 'input accepts attributes in the DSL' do
231
+ swap_wrapper :default, self.custom_wrapper_with_input_class do
232
+ with_concat_form_for @user do |f|
233
+ concat f.input :name
234
+ end
235
+ end
236
+
237
+ assert_select "div.custom_wrapper input.string.inline-class"
238
+ end
239
+
240
+ test 'label accepts attributes in the DSL' do
241
+ swap_wrapper :default, self.custom_wrapper_with_label_class do
242
+ with_concat_form_for @user do |f|
243
+ concat f.input :name
244
+ end
245
+ end
246
+
247
+ assert_select "div.custom_wrapper label.string.inline-class"
248
+ end
249
+
250
+ test 'label_input accepts attributes in the DSL' do
251
+ swap_wrapper :default, self.custom_wrapper_with_label_input_class do
252
+ with_concat_form_for @user do |f|
253
+ concat f.input :name
254
+ end
255
+ end
256
+
257
+ assert_select "div.custom_wrapper label.string.inline-class"
258
+ assert_select "div.custom_wrapper input.string.inline-class"
259
+ end
260
+
261
+ test 'input accepts data attributes in the DSL' do
262
+ swap_wrapper :default, self.custom_wrapper_with_input_attributes do
263
+ with_concat_form_for @user do |f|
264
+ concat f.input :name
265
+ end
266
+ end
267
+
268
+ assert_select "div.custom_wrapper input.string[data-modal=true]"
269
+ end
203
270
  end
@@ -21,8 +21,8 @@ class SimpleFormGeneratorTest < Rails::Generators::TestCase
21
21
  run_generator %w(--bootstrap)
22
22
  assert_file 'config/initializers/simple_form.rb',
23
23
  /config\.default_wrapper = :default/, /config\.boolean_style = :nested/
24
- assert_file 'config/initializers/simple_form_bootstrap.rb', /config\.wrappers :bootstrap/,
25
- /config\.default_wrapper = :bootstrap/
24
+ assert_file 'config/initializers/simple_form_bootstrap.rb', /config\.wrappers :vertical_form/,
25
+ /config\.wrappers :horizontal_form/, /config\.default_wrapper = :vertical_form/
26
26
  end
27
27
 
28
28
  test 'generates the simple_form initializer with the foundation wrappers' do
@@ -50,14 +50,42 @@ class BooleanInputTest < ActionView::TestCase
50
50
  test 'input boolean with nested allows :inline_label' do
51
51
  swap SimpleForm, boolean_style: :nested do
52
52
  with_input_for @user, :active, :boolean, label: false, inline_label: 'I am so inline.'
53
- assert_select 'label.checkbox', text: 'I am so inline.'
53
+ assert_select 'label.checkbox', text: ' I am so inline.'
54
+ end
55
+ end
56
+
57
+ test 'input boolean with nested escapes :inline_label with HTML' do
58
+ swap SimpleForm, boolean_style: :nested do
59
+ with_input_for @user, :active, :boolean, label: false, inline_label: '<b>I am so inline.</b>'
60
+ assert_select 'label.checkbox', text: ' &lt;b&gt;I am so inline.&lt;/b&gt;'
61
+ end
62
+ end
63
+
64
+ test 'input boolean with nested allows :inline_label with HTML when safe' do
65
+ swap SimpleForm, boolean_style: :nested do
66
+ with_input_for @user, :active, :boolean, label: false, inline_label: '<b>I am so inline.</b>'.html_safe
67
+ assert_select 'label.checkbox b', text: 'I am so inline.'
54
68
  end
55
69
  end
56
70
 
57
71
  test 'input boolean with nested style creates an inline label using the default label text when inline_label option set to true' do
58
72
  swap SimpleForm, boolean_style: :nested do
59
73
  with_input_for @user, :active, :boolean, label: false, inline_label: true
60
- assert_select 'label.checkbox', text: 'Active'
74
+ assert_select 'label.checkbox', text: ' Active'
75
+ end
76
+ end
77
+
78
+ test 'input boolean with nested style creates an inline label using the label text when inline_label option set to true' do
79
+ swap SimpleForm, boolean_style: :nested do
80
+ with_input_for @user, :active, :boolean, label: false, inline_label: true, label_text: proc { 'New Active' }
81
+ assert_select 'label.checkbox', text: ' New Active'
82
+ end
83
+ end
84
+
85
+ test 'input boolean with nested style creates an inline label using the label html when inline_label option set to true' do
86
+ swap SimpleForm, boolean_style: :nested do
87
+ with_input_for @user, :active, :boolean, label: false, inline_label: true, label_text: proc { '<b>New Active</b>' }
88
+ assert_select 'label.checkbox', text: ' New Active'
61
89
  end
62
90
  end
63
91
 
@@ -128,6 +156,16 @@ class BooleanInputTest < ActionView::TestCase
128
156
  end
129
157
  end
130
158
 
159
+ test 'input boolean with nested style works using :input only in wrapper config (no label_input), adding the extra label wrapper with custom class' do
160
+ swap_wrapper do
161
+ swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
162
+ with_input_for @user, :active, :boolean
163
+
164
+ assert_select 'label.boolean + input[type=hidden] + label.foo > input.boolean'
165
+ end
166
+ end
167
+ end
168
+
131
169
  test 'input boolean with nested style works using :label_input in wrapper config, adding "checkbox" class to label' do
132
170
  swap_wrapper :default, self.custom_wrapper_without_top_level do
133
171
  swap SimpleForm, boolean_style: :nested do
@@ -138,6 +176,16 @@ class BooleanInputTest < ActionView::TestCase
138
176
  end
139
177
  end
140
178
 
179
+ test 'input boolean with nested style works using :label_input in wrapper config, adding custom class to label' do
180
+ swap_wrapper :default, self.custom_wrapper_without_top_level do
181
+ swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
182
+ with_input_for @user, :active, :boolean
183
+
184
+ assert_select 'input[type=hidden] + label.boolean.foo > input.boolean'
185
+ end
186
+ end
187
+ end
188
+
141
189
  test 'input boolean without additional classes should add "checkbox" class to label' do
142
190
  swap_wrapper :default, self.custom_wrapper_without_top_level do
143
191
  swap SimpleForm, boolean_style: :nested, generate_additional_classes_for: [:input] do
@@ -53,6 +53,20 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
53
53
  end
54
54
  end
55
55
 
56
+ test 'input that uses automatic collection translation for check_boxes should properly set checked values' do
57
+ store_translations(:en, simple_form: { options: { defaults: {
58
+ gender: { male: 'Male', female: 'Female'}
59
+ } } } ) do
60
+ @user.gender = 'male'
61
+
62
+ with_input_for @user, :gender, :check_boxes, collection: [:male, :female]
63
+ assert_select 'input[type=checkbox][value=male][checked=checked]'
64
+ assert_select 'input[type=checkbox][value=female]'
65
+ assert_select 'label.collection_check_boxes', 'Male'
66
+ assert_select 'label.collection_check_boxes', 'Female'
67
+ end
68
+ end
69
+
56
70
  test 'input check boxes does not wrap the collection by default' do
57
71
  with_input_for @user, :active, :check_boxes
58
72
 
@@ -199,29 +213,27 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
199
213
  swap SimpleForm, boolean_style: :nested do
200
214
  with_input_for @user, :active, :check_boxes
201
215
 
202
- assert_select 'label.checkbox > input#user_active_true[type=checkbox]'
203
- assert_select 'label.checkbox', 'Yes'
204
- assert_select 'label.checkbox > input#user_active_false[type=checkbox]'
205
- assert_select 'label.checkbox', 'No'
216
+ assert_select 'span.checkbox > label > input#user_active_true[type=checkbox]'
217
+ assert_select 'span.checkbox > label', 'Yes'
218
+ assert_select 'span.checkbox > label > input#user_active_false[type=checkbox]'
219
+ assert_select 'span.checkbox > label', 'No'
206
220
  assert_no_select 'label.collection_radio_buttons'
207
221
  end
208
222
  end
209
223
 
210
- test 'input check boxes with nested style overrides configured item wrapper tag, forcing the :label' do
224
+ test 'input check boxes with nested style does not overrides configured item wrapper tag' do
211
225
  swap SimpleForm, boolean_style: :nested, item_wrapper_tag: :li do
212
226
  with_input_for @user, :active, :check_boxes
213
227
 
214
- assert_select 'label.checkbox > input'
215
- assert_no_select 'li'
228
+ assert_select 'li.checkbox > label > input'
216
229
  end
217
230
  end
218
231
 
219
- test 'input check boxes with nested style overrides given item wrapper tag, forcing the :label' do
232
+ test 'input check boxes with nested style does not overrides given item wrapper tag' do
220
233
  swap SimpleForm, boolean_style: :nested do
221
234
  with_input_for @user, :active, :check_boxes, item_wrapper_tag: :li
222
235
 
223
- assert_select 'label.checkbox > input'
224
- assert_no_select 'li'
236
+ assert_select 'li.checkbox > label > input'
225
237
  end
226
238
  end
227
239
 
@@ -229,7 +241,24 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
229
241
  swap SimpleForm, boolean_style: :nested do
230
242
  with_input_for @user, :active, :check_boxes, item_wrapper_class: "inline"
231
243
 
232
- assert_select 'label.checkbox.inline > input'
244
+ assert_select 'span.checkbox.inline > label > input'
245
+ end
246
+ end
247
+
248
+ test 'input check boxes wrapper class are not included when set to falsey' do
249
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
250
+ with_input_for @user, :gender, :check_boxes, collection: [:male, :female]
251
+
252
+ assert_no_select 'label.checkbox'
253
+ end
254
+ end
255
+
256
+ test 'input check boxes custom wrapper class is included when include input wrapper class is falsey' do
257
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
258
+ with_input_for @user, :gender, :check_boxes, collection: [:male, :female], item_wrapper_class: 'custom'
259
+
260
+ assert_no_select 'label.checkbox'
261
+ assert_select 'span.custom'
233
262
  end
234
263
  end
235
264
  end
@@ -18,6 +18,22 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
18
18
  assert_select 'label[for=user_active_false]', 'No'
19
19
  end
20
20
 
21
+ test 'input as radio should generate internal labels with accurate `for` values with nested boolean style' do
22
+ swap SimpleForm, boolean_style: :nested do
23
+ with_input_for @user, :active, :radio_buttons
24
+ assert_select 'label[for=user_active_true]', 'Yes'
25
+ assert_select 'label[for=user_active_false]', 'No'
26
+ end
27
+ end
28
+
29
+ test 'nested label should not duplicate input id' do
30
+ swap SimpleForm, boolean_style: :nested do
31
+ with_input_for @user, :active, :radio_buttons, id: 'nested_id'
32
+ assert_select 'input#user_active_true'
33
+ assert_no_select 'label#user_active_true'
34
+ end
35
+ end
36
+
21
37
  test 'input as radio should use i18n to translate internal labels' do
22
38
  store_translations(:en, simple_form: { yes: 'Sim', no: 'Não' }) do
23
39
  with_input_for @user, :active, :radio_buttons
@@ -48,8 +64,8 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
48
64
  with_input_for @user, :name, :radio_buttons, collection: ['Jose', 'Carlos']
49
65
  assert_select 'input[type=radio][value=Jose]'
50
66
  assert_select 'input[type=radio][value=Carlos]'
51
- assert_select 'label.collection_radio_buttons', 'Jose'
52
- assert_select 'label.collection_radio_buttons', 'Carlos'
67
+ assert_select 'label.collection_radio_buttons[for=user_name_jose]', 'Jose'
68
+ assert_select 'label.collection_radio_buttons[for=user_name_carlos]', 'Carlos'
53
69
  end
54
70
 
55
71
  test 'input should do automatic collection translation for radio types using defaults key' do
@@ -59,8 +75,8 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
59
75
  with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
60
76
  assert_select 'input[type=radio][value=male]'
61
77
  assert_select 'input[type=radio][value=female]'
62
- assert_select 'label.collection_radio_buttons', 'Male'
63
- assert_select 'label.collection_radio_buttons', 'Female'
78
+ assert_select 'label.collection_radio_buttons[for=user_gender_male]', 'Male'
79
+ assert_select 'label.collection_radio_buttons[for=user_gender_female]', 'Female'
64
80
  end
65
81
  end
66
82
 
@@ -71,8 +87,36 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
71
87
  with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
72
88
  assert_select 'input[type=radio][value=male]'
73
89
  assert_select 'input[type=radio][value=female]'
74
- assert_select 'label.collection_radio_buttons', 'Male'
75
- assert_select 'label.collection_radio_buttons', 'Female'
90
+ assert_select 'label.collection_radio_buttons[for=user_gender_male]', 'Male'
91
+ assert_select 'label.collection_radio_buttons[for=user_gender_female]', 'Female'
92
+ end
93
+ end
94
+
95
+ test 'input should do automatic collection translation and preserve html markup' do
96
+ swap SimpleForm, boolean_style: :nested do
97
+ store_translations(:en, simple_form: { options: { user: {
98
+ gender: { male_html: '<strong>Male</strong>', female_html: '<strong>Female</strong>' }
99
+ } } } ) do
100
+ with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
101
+ assert_select 'input[type=radio][value=male]'
102
+ assert_select 'input[type=radio][value=female]'
103
+ assert_select 'label[for=user_gender_male]', 'Male'
104
+ assert_select 'label[for=user_gender_female]', 'Female'
105
+ end
106
+ end
107
+ end
108
+
109
+ test 'input should do automatic collection translation with keys prefixed with _html and a string value' do
110
+ swap SimpleForm, boolean_style: :nested do
111
+ store_translations(:en, simple_form: { options: { user: {
112
+ gender: { male_html: 'Male', female_html: 'Female' }
113
+ } } } ) do
114
+ with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
115
+ assert_select 'input[type=radio][value=male]'
116
+ assert_select 'input[type=radio][value=female]'
117
+ assert_select 'label[for=user_gender_male]', 'Male'
118
+ assert_select 'label[for=user_gender_female]', 'Female'
119
+ end
76
120
  end
77
121
  end
78
122
 
@@ -292,29 +336,27 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
292
336
  swap SimpleForm, boolean_style: :nested do
293
337
  with_input_for @user, :active, :radio_buttons
294
338
 
295
- assert_select 'label.radio > input#user_active_true[type=radio]'
296
- assert_select 'label.radio', 'Yes'
297
- assert_select 'label.radio > input#user_active_false[type=radio]'
298
- assert_select 'label.radio', 'No'
339
+ assert_select 'span.radio > label > input#user_active_true[type=radio]'
340
+ assert_select 'span.radio > label', 'Yes'
341
+ assert_select 'span.radio > label > input#user_active_false[type=radio]'
342
+ assert_select 'span.radio > label', 'No'
299
343
  assert_no_select 'label.collection_radio_buttons'
300
344
  end
301
345
  end
302
346
 
303
- test 'input radio with nested style overrides configured item wrapper tag, forcing the :label' do
347
+ test 'input radio with nested style does not overrides configured item wrapper tag' do
304
348
  swap SimpleForm, boolean_style: :nested, item_wrapper_tag: :li do
305
349
  with_input_for @user, :active, :radio_buttons
306
350
 
307
- assert_select 'label.radio > input'
308
- assert_no_select 'li'
351
+ assert_select 'li.radio > label > input'
309
352
  end
310
353
  end
311
354
 
312
- test 'input radio with nested style overrides given item wrapper tag, forcing the :label' do
355
+ test 'input radio with nested style does not overrides given item wrapper tag' do
313
356
  swap SimpleForm, boolean_style: :nested do
314
357
  with_input_for @user, :active, :radio_buttons, item_wrapper_tag: :li
315
358
 
316
- assert_select 'label.radio > input'
317
- assert_no_select 'li'
359
+ assert_select 'li.radio > label > input'
318
360
  end
319
361
  end
320
362
 
@@ -322,7 +364,24 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
322
364
  swap SimpleForm, boolean_style: :nested do
323
365
  with_input_for @user, :active, :radio_buttons, item_wrapper_class: "inline"
324
366
 
325
- assert_select 'label.radio.inline > input'
367
+ assert_select 'span.radio.inline > label > input'
368
+ end
369
+ end
370
+
371
+ test 'input radio wrapper class are not included when set to falsey' do
372
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
373
+ with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
374
+
375
+ assert_no_select 'label.radio'
376
+ end
377
+ end
378
+
379
+ test 'input check boxes custom wrapper class is included when include input wrapper class is falsey' do
380
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
381
+ with_input_for @user, :gender, :radio_buttons, collection: [:male, :female], item_wrapper_class: 'custom'
382
+
383
+ assert_no_select 'label.radio'
384
+ assert_select 'span.custom'
326
385
  end
327
386
  end
328
387
  end
@@ -31,7 +31,7 @@ class CollectionSelectInputTest < ActionView::TestCase
31
31
  test 'input should do automatic collection translation for select types using defaults key' do
32
32
  store_translations(:en, simple_form: { options: { defaults: {
33
33
  gender: { male: 'Male', female: 'Female'}
34
- } } } ) do
34
+ } } }) do
35
35
  with_input_for @user, :gender, :select, collection: [:male, :female]
36
36
  assert_select 'select.select#user_gender'
37
37
  assert_select 'select option', 'Male'
@@ -42,7 +42,7 @@ class CollectionSelectInputTest < ActionView::TestCase
42
42
  test 'input should do automatic collection translation for select types using specific object key' do
43
43
  store_translations(:en, simple_form: { options: { user: {
44
44
  gender: { male: 'Male', female: 'Female'}
45
- } } } ) do
45
+ } } }) do
46
46
  with_input_for @user, :gender, :select, collection: [:male, :female]
47
47
  assert_select 'select.select#user_gender'
48
48
  assert_select 'select option', 'Male'
@@ -102,9 +102,63 @@ class CollectionSelectInputTest < ActionView::TestCase
102
102
  assert_select 'select option[value=]', ''
103
103
  end
104
104
 
105
+ test 'input should translate include blank when set to :translate' do
106
+ store_translations(:en, simple_form: { include_blanks: { user: {
107
+ age: 'Rather not say'
108
+ } } }) do
109
+ with_input_for @user, :age, :select, collection: 18..30, include_blank: :translate
110
+ assert_select 'select option[value=]', 'Rather not say'
111
+ end
112
+ end
113
+
114
+ test 'input should translate include blank with a default' do
115
+ store_translations(:en, simple_form: { include_blanks: { defaults: {
116
+ age: 'Rather not say',
117
+ } } }) do
118
+ with_input_for @user, :age, :select, collection: 18..30, include_blank: :translate
119
+ assert_select 'select option[value=]', 'Rather not say'
120
+ end
121
+ end
122
+
123
+ test 'input should not translate include blank when set to a string' do
124
+ store_translations(:en, simple_form: { include_blanks: { user: {
125
+ age: 'Rather not say'
126
+ } } }) do
127
+ with_input_for @user, :age, :select, collection: 18..30, include_blank: 'Young at heart'
128
+ assert_select 'select option[value=]', 'Young at heart'
129
+ end
130
+ end
131
+
132
+ test 'input should not translate include blank when automatically set' do
133
+ store_translations(:en, simple_form: { include_blanks: { user: {
134
+ age: 'Rather not say'
135
+ } } }) do
136
+ with_input_for @user, :age, :select, collection: 18..30
137
+ assert_select 'select option[value=]', ''
138
+ end
139
+ end
140
+
141
+ test 'input should not translate include blank when set to true' do
142
+ store_translations(:en, simple_form: { include_blanks: { user: {
143
+ age: 'Rather not say'
144
+ } } }) do
145
+ with_input_for @user, :age, :select, collection: 18..30, include_blank: true
146
+ assert_select 'select option[value=]', ''
147
+ end
148
+ end
149
+
150
+ test 'input should not translate include blank when set to false' do
151
+ store_translations(:en, simple_form: { include_blanks: { user: {
152
+ age: 'Rather not say'
153
+ } } }) do
154
+ with_input_for @user, :age, :select, collection: 18..30, include_blank: false
155
+ assert_no_select 'select option[value=]'
156
+ end
157
+ end
158
+
105
159
  test 'input should not set include blank if otherwise is told' do
106
160
  with_input_for @user, :age, :select, collection: 18..30, include_blank: false
107
- assert_no_select 'select option[value=]', ''
161
+ assert_no_select 'select option[value=]'
108
162
  end
109
163
 
110
164
  test 'input should not set include blank if prompt is given' do
@@ -117,6 +171,51 @@ class CollectionSelectInputTest < ActionView::TestCase
117
171
  assert_no_select 'select option[value=]', ''
118
172
  end
119
173
 
174
+ test 'input should translate prompt when set to :translate' do
175
+ store_translations(:en, simple_form: { prompts: { user: {
176
+ age: 'Select age:'
177
+ } } }) do
178
+ with_input_for @user, :age, :select, collection: 18..30, prompt: :translate
179
+ assert_select 'select option[value=]', 'Select age:'
180
+ end
181
+ end
182
+
183
+ test 'input should translate prompt with a default' do
184
+ store_translations(:en, simple_form: { prompts: { defaults: {
185
+ age: 'Select age:',
186
+ } } }) do
187
+ with_input_for @user, :age, :select, collection: 18..30, prompt: :translate
188
+ assert_select 'select option[value=]', 'Select age:'
189
+ end
190
+ end
191
+
192
+ test 'input should not translate prompt when set to a string' do
193
+ store_translations(:en, simple_form: { prompts: { user: {
194
+ age: 'Select age:'
195
+ } } }) do
196
+ with_input_for @user, :age, :select, collection: 18..30, prompt: 'Do it:'
197
+ assert_select 'select option[value=]', 'Do it:'
198
+ end
199
+ end
200
+
201
+ test 'input should not translate prompt when set to false' do
202
+ store_translations(:en, simple_form: { prompts: { user: {
203
+ age: 'Select age:'
204
+ } } }) do
205
+ with_input_for @user, :age, :select, collection: 18..30, prompt: false
206
+ assert_no_select 'select option[value=]'
207
+ end
208
+ end
209
+
210
+ test 'input should use Rails prompt translation as a fallback' do
211
+ store_translations(:en, helpers: { select: {
212
+ prompt: 'Select value:'
213
+ } }) do
214
+ with_input_for @user, :age, :select, collection: 18..30, prompt: :translate
215
+ assert_select 'select option[value=]', "Select value:"
216
+ end
217
+ end
218
+
120
219
  test 'input should detect label and value on collections' do
121
220
  users = [User.build(id: 1, name: "Jose"), User.build(id: 2, name: "Carlos")]
122
221
  with_input_for @user, :description, :select, collection: users
@@ -178,6 +277,12 @@ class CollectionSelectInputTest < ActionView::TestCase
178
277
  assert_select 'select[required]'
179
278
  end
180
279
 
280
+ test 'collection input with select type should generate required html attribute only with blank option or prompt' do
281
+ with_input_for @user, :name, :select, prompt: 'Name...', collection: ['Jose', 'Carlos']
282
+ assert_select 'select.required'
283
+ assert_select 'select[required]'
284
+ end
285
+
181
286
  test 'collection input with select type should not generate required html attribute without blank option' do
182
287
  with_input_for @user, :name, :select, include_blank: false, collection: ['Jose', 'Carlos']
183
288
  assert_select 'select.required'