simple_form 3.0.4 → 5.0.3

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.
Files changed (107) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +199 -33
  3. data/MIT-LICENSE +2 -1
  4. data/README.md +453 -128
  5. data/lib/generators/simple_form/install_generator.rb +4 -3
  6. data/lib/generators/simple_form/templates/README +3 -5
  7. data/lib/generators/simple_form/templates/_form.html.erb +2 -0
  8. data/lib/generators/simple_form/templates/_form.html.haml +2 -0
  9. data/lib/generators/simple_form/templates/_form.html.slim +1 -0
  10. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +47 -16
  11. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +418 -23
  12. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +101 -5
  13. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -2
  14. data/lib/simple_form/action_view_extensions/builder.rb +2 -0
  15. data/lib/simple_form/action_view_extensions/form_helper.rb +10 -3
  16. data/lib/simple_form/components/errors.rb +39 -6
  17. data/lib/simple_form/components/hints.rb +3 -2
  18. data/lib/simple_form/components/html5.rb +16 -5
  19. data/lib/simple_form/components/label_input.rb +21 -2
  20. data/lib/simple_form/components/labels.rb +22 -11
  21. data/lib/simple_form/components/maxlength.rb +9 -5
  22. data/lib/simple_form/components/min_max.rb +2 -1
  23. data/lib/simple_form/components/minlength.rb +38 -0
  24. data/lib/simple_form/components/pattern.rb +2 -1
  25. data/lib/simple_form/components/placeholders.rb +4 -3
  26. data/lib/simple_form/components/readonly.rb +2 -1
  27. data/lib/simple_form/components.rb +2 -0
  28. data/lib/simple_form/error_notification.rb +1 -0
  29. data/lib/simple_form/form_builder.rb +220 -89
  30. data/lib/simple_form/helpers/autofocus.rb +1 -0
  31. data/lib/simple_form/helpers/disabled.rb +1 -0
  32. data/lib/simple_form/helpers/readonly.rb +1 -0
  33. data/lib/simple_form/helpers/required.rb +1 -0
  34. data/lib/simple_form/helpers/validators.rb +2 -1
  35. data/lib/simple_form/helpers.rb +6 -5
  36. data/lib/simple_form/i18n_cache.rb +1 -0
  37. data/lib/simple_form/inputs/base.rb +62 -16
  38. data/lib/simple_form/inputs/block_input.rb +2 -1
  39. data/lib/simple_form/inputs/boolean_input.rb +40 -16
  40. data/lib/simple_form/inputs/collection_check_boxes_input.rb +3 -2
  41. data/lib/simple_form/inputs/collection_input.rb +37 -14
  42. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +9 -13
  43. data/lib/simple_form/inputs/collection_select_input.rb +5 -2
  44. data/lib/simple_form/inputs/color_input.rb +14 -0
  45. data/lib/simple_form/inputs/date_time_input.rb +24 -9
  46. data/lib/simple_form/inputs/file_input.rb +5 -2
  47. data/lib/simple_form/inputs/grouped_collection_select_input.rb +16 -3
  48. data/lib/simple_form/inputs/hidden_input.rb +5 -2
  49. data/lib/simple_form/inputs/numeric_input.rb +6 -4
  50. data/lib/simple_form/inputs/password_input.rb +6 -3
  51. data/lib/simple_form/inputs/priority_input.rb +5 -6
  52. data/lib/simple_form/inputs/range_input.rb +2 -1
  53. data/lib/simple_form/inputs/rich_text_area_input.rb +12 -0
  54. data/lib/simple_form/inputs/string_input.rb +7 -4
  55. data/lib/simple_form/inputs/text_input.rb +6 -3
  56. data/lib/simple_form/inputs.rb +3 -0
  57. data/lib/simple_form/map_type.rb +1 -0
  58. data/lib/simple_form/railtie.rb +8 -0
  59. data/lib/simple_form/tags.rb +13 -2
  60. data/lib/simple_form/version.rb +2 -1
  61. data/lib/simple_form/wrappers/builder.rb +7 -6
  62. data/lib/simple_form/wrappers/leaf.rb +29 -0
  63. data/lib/simple_form/wrappers/many.rb +7 -6
  64. data/lib/simple_form/wrappers/root.rb +10 -3
  65. data/lib/simple_form/wrappers/single.rb +7 -4
  66. data/lib/simple_form/wrappers.rb +2 -0
  67. data/lib/simple_form.rb +137 -21
  68. data/test/action_view_extensions/builder_test.rb +64 -45
  69. data/test/action_view_extensions/form_helper_test.rb +36 -16
  70. data/test/components/custom_components_test.rb +62 -0
  71. data/test/components/label_test.rb +70 -41
  72. data/test/form_builder/association_test.rb +85 -37
  73. data/test/form_builder/button_test.rb +11 -10
  74. data/test/form_builder/error_notification_test.rb +2 -1
  75. data/test/form_builder/error_test.rb +146 -33
  76. data/test/form_builder/general_test.rb +183 -81
  77. data/test/form_builder/hint_test.rb +24 -18
  78. data/test/form_builder/input_field_test.rb +105 -75
  79. data/test/form_builder/label_test.rb +68 -13
  80. data/test/form_builder/wrapper_test.rb +197 -22
  81. data/test/generators/simple_form_generator_test.rb +8 -7
  82. data/test/inputs/boolean_input_test.rb +97 -6
  83. data/test/inputs/collection_check_boxes_input_test.rb +117 -25
  84. data/test/inputs/collection_radio_buttons_input_test.rb +176 -54
  85. data/test/inputs/collection_select_input_test.rb +189 -77
  86. data/test/inputs/color_input_test.rb +10 -0
  87. data/test/inputs/datetime_input_test.rb +121 -50
  88. data/test/inputs/disabled_test.rb +29 -15
  89. data/test/inputs/discovery_test.rb +79 -6
  90. data/test/inputs/file_input_test.rb +3 -2
  91. data/test/inputs/general_test.rb +23 -22
  92. data/test/inputs/grouped_collection_select_input_test.rb +54 -17
  93. data/test/inputs/hidden_input_test.rb +5 -4
  94. data/test/inputs/numeric_input_test.rb +48 -44
  95. data/test/inputs/priority_input_test.rb +17 -16
  96. data/test/inputs/readonly_test.rb +20 -19
  97. data/test/inputs/required_test.rb +58 -13
  98. data/test/inputs/rich_text_area_input_test.rb +15 -0
  99. data/test/inputs/string_input_test.rb +58 -36
  100. data/test/inputs/text_input_test.rb +20 -7
  101. data/test/simple_form_test.rb +9 -0
  102. data/test/support/discovery_inputs.rb +40 -2
  103. data/test/support/misc_helpers.rb +113 -5
  104. data/test/support/mock_controller.rb +7 -1
  105. data/test/support/models.rb +162 -39
  106. data/test/test_helper.rb +19 -4
  107. metadata +51 -43
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: UTF-8
2
3
  require 'test_helper'
3
4
 
@@ -6,34 +7,34 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
6
7
  SimpleForm::Inputs::CollectionCheckBoxesInput.reset_i18n_cache :boolean_collection
7
8
  end
8
9
 
9
- test 'input check boxes should not include for attribute by default' do
10
- with_input_for @user, :gender, :check_boxes, collection: [:male, :female]
10
+ test 'input check boxes does not include for attribute by default' do
11
+ with_input_for @user, :gender, :check_boxes, collection: %i[male female]
11
12
  assert_select 'label'
12
13
  assert_no_select 'label[for=user_gender]'
13
14
  end
14
15
 
15
- test 'input check boxes should include for attribute when giving as html option' do
16
- with_input_for @user, :gender, :check_boxes, collection: [:male, :female], label_html: { for: 'gender' }
16
+ test 'input check boxes includes for attribute when giving as html option' do
17
+ with_input_for @user, :gender, :check_boxes, collection: %i[male female], label_html: { for: 'gender' }
17
18
  assert_select 'label[for=gender]'
18
19
  end
19
20
 
20
- test 'collection input with check_boxes type should not generate required html attribute' do
21
- with_input_for @user, :name, :check_boxes, collection: ['Jose', 'Carlos']
21
+ test 'collection input with check_boxes type does not generate required html attribute' do
22
+ with_input_for @user, :name, :check_boxes, collection: %w[Jose Carlos]
22
23
  assert_select 'input.required'
23
24
  assert_no_select 'input[required]'
24
25
  end
25
26
 
26
- test 'collection input with check_boxes type should not generate aria-required html attribute' do
27
- with_input_for @user, :name, :check_boxes, collection: ['Jose', 'Carlos']
27
+ test 'collection input with check_boxes type does not generate aria-required html attribute' do
28
+ with_input_for @user, :name, :check_boxes, collection: %w[Jose Carlos]
28
29
  assert_select 'input.required'
29
30
  assert_no_select 'input[aria-required]'
30
31
  end
31
32
 
32
- test 'input should do automatic collection translation for check_box types using defaults key' do
33
+ test 'input does automatic collection translation for check_box types using defaults key' do
33
34
  store_translations(:en, simple_form: { options: { defaults: {
34
- gender: { male: 'Male', female: 'Female'}
35
+ gender: { male: 'Male', female: 'Female' }
35
36
  } } } ) do
36
- with_input_for @user, :gender, :check_boxes, collection: [:male, :female]
37
+ with_input_for @user, :gender, :check_boxes, collection: %i[male female]
37
38
  assert_select 'input[type=checkbox][value=male]'
38
39
  assert_select 'input[type=checkbox][value=female]'
39
40
  assert_select 'label.collection_check_boxes', 'Male'
@@ -41,11 +42,11 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
41
42
  end
42
43
  end
43
44
 
44
- test 'input should do automatic collection translation for check_box types using specific object key' do
45
+ test 'input does automatic collection translation for check_box types using specific object key' do
45
46
  store_translations(:en, simple_form: { options: { user: {
46
- gender: { male: 'Male', female: 'Female'}
47
+ gender: { male: 'Male', female: 'Female' }
47
48
  } } } ) do
48
- with_input_for @user, :gender, :check_boxes, collection: [:male, :female]
49
+ with_input_for @user, :gender, :check_boxes, collection: %i[male female]
49
50
  assert_select 'input[type=checkbox][value=male]'
50
51
  assert_select 'input[type=checkbox][value=female]'
51
52
  assert_select 'label.collection_check_boxes', 'Male'
@@ -53,6 +54,20 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
53
54
  end
54
55
  end
55
56
 
57
+ test 'input that uses automatic collection translation for check_boxes properly sets checked values' do
58
+ store_translations(:en, simple_form: { options: { defaults: {
59
+ gender: { male: 'Male', female: 'Female' }
60
+ } } } ) do
61
+ @user.gender = 'male'
62
+
63
+ with_input_for @user, :gender, :check_boxes, collection: %i[male female]
64
+ assert_select 'input[type=checkbox][value=male][checked=checked]'
65
+ assert_select 'input[type=checkbox][value=female]'
66
+ assert_select 'label.collection_check_boxes', 'Male'
67
+ assert_select 'label.collection_check_boxes', 'Female'
68
+ end
69
+ end
70
+
56
71
  test 'input check boxes does not wrap the collection by default' do
57
72
  with_input_for @user, :active, :check_boxes
58
73
 
@@ -199,29 +214,27 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
199
214
  swap SimpleForm, boolean_style: :nested do
200
215
  with_input_for @user, :active, :check_boxes
201
216
 
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'
217
+ assert_select 'span.checkbox > label > input#user_active_true[type=checkbox]'
218
+ assert_select 'span.checkbox > label', 'Yes'
219
+ assert_select 'span.checkbox > label > input#user_active_false[type=checkbox]'
220
+ assert_select 'span.checkbox > label', 'No'
206
221
  assert_no_select 'label.collection_radio_buttons'
207
222
  end
208
223
  end
209
224
 
210
- test 'input check boxes with nested style overrides configured item wrapper tag, forcing the :label' do
225
+ test 'input check boxes with nested style does not overrides configured item wrapper tag' do
211
226
  swap SimpleForm, boolean_style: :nested, item_wrapper_tag: :li do
212
227
  with_input_for @user, :active, :check_boxes
213
228
 
214
- assert_select 'label.checkbox > input'
215
- assert_no_select 'li'
229
+ assert_select 'li.checkbox > label > input'
216
230
  end
217
231
  end
218
232
 
219
- test 'input check boxes with nested style overrides given item wrapper tag, forcing the :label' do
233
+ test 'input check boxes with nested style does not overrides given item wrapper tag' do
220
234
  swap SimpleForm, boolean_style: :nested do
221
235
  with_input_for @user, :active, :check_boxes, item_wrapper_tag: :li
222
236
 
223
- assert_select 'label.checkbox > input'
224
- assert_no_select 'li'
237
+ assert_select 'li.checkbox > label > input'
225
238
  end
226
239
  end
227
240
 
@@ -229,7 +242,86 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
229
242
  swap SimpleForm, boolean_style: :nested do
230
243
  with_input_for @user, :active, :check_boxes, item_wrapper_class: "inline"
231
244
 
232
- assert_select 'label.checkbox.inline > input'
245
+ assert_select 'span.checkbox.inline > label > input'
246
+ end
247
+ end
248
+
249
+ test 'input check boxes with nested style renders item labels with specified class' do
250
+ swap SimpleForm, boolean_style: :nested do
251
+ with_input_for @user, :active, :check_boxes, item_label_class: "test"
252
+
253
+ assert_select 'span.checkbox > label.test > input'
254
+ end
255
+ end
256
+
257
+ test 'input check boxes with nested style and falsey input wrapper renders item labels with specified class' do
258
+ swap SimpleForm, boolean_style: :nested, item_wrapper_tag: false do
259
+ with_input_for @user, :active, :check_boxes, item_label_class: "checkbox-inline"
260
+
261
+ assert_select 'label.checkbox-inline > input'
262
+ assert_no_select 'span.checkbox'
263
+ end
264
+ end
265
+
266
+ test 'input check boxes wrapper class are not included when set to falsey' do
267
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
268
+ with_input_for @user, :gender, :check_boxes, collection: %i[male female]
269
+
270
+ assert_no_select 'label.checkbox'
271
+ end
272
+ end
273
+
274
+ test 'input check boxes custom wrapper class is included when include input wrapper class is falsey' do
275
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
276
+ with_input_for @user, :gender, :check_boxes, collection: %i[male female], item_wrapper_class: 'custom'
277
+
278
+ assert_no_select 'label.checkbox'
279
+ assert_select 'span.custom'
280
+ end
281
+ end
282
+
283
+ test 'input check boxes with nested style and namespace uses the right for attribute' do
284
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
285
+ with_concat_form_for @user, namespace: :foo do |f|
286
+ concat f.input :gender, as: :check_boxes, collection: %i[male female]
287
+ end
288
+
289
+ assert_select 'label[for=foo_user_gender_male]'
290
+ assert_select 'label[for=foo_user_gender_female]'
291
+ end
292
+ end
293
+
294
+ test 'input check boxes with nested style and index uses the right for attribute' do
295
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
296
+ with_concat_form_for @user, index: 1 do |f|
297
+ concat f.input :gender, as: :check_boxes, collection: %i[male female]
298
+ end
299
+
300
+ assert_select 'label[for=user_1_gender_male]'
301
+ assert_select 'label[for=user_1_gender_female]'
302
+ end
303
+ end
304
+
305
+ test 'input check boxes with nested style accepts non-string attribute as label' do
306
+ swap SimpleForm, boolean_style: :nested do
307
+ with_input_for @user, :amount,
308
+ :check_boxes,
309
+ collection: { 100 => 'hundred', 200 => 'two_hundred' },
310
+ label_method: :first,
311
+ value_method: :second
312
+
313
+ assert_select 'input[type=checkbox][value=hundred]'
314
+ assert_select 'input[type=checkbox][value=two_hundred]'
315
+ assert_select 'span.checkbox > label', '100'
316
+ assert_select 'span.checkbox > label', '200'
317
+ end
318
+ end
319
+
320
+ test 'input check boxes with inline style support label custom classes' do
321
+ swap SimpleForm, boolean_style: :inline do
322
+ with_input_for @user, :gender, :check_boxes, collection: %i[male female], item_label_class: 'beautiful-label'
323
+
324
+ assert_select 'label.beautiful-label', count: 2
233
325
  end
234
326
  end
235
327
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: UTF-8
2
3
  require 'test_helper'
3
4
 
@@ -6,19 +7,35 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
6
7
  SimpleForm::Inputs::CollectionRadioButtonsInput.reset_i18n_cache :boolean_collection
7
8
  end
8
9
 
9
- test 'input should generate boolean radio buttons by default for radio types' do
10
+ test 'input generates boolean radio buttons by default for radio types' do
10
11
  with_input_for @user, :active, :radio_buttons
11
12
  assert_select 'input[type=radio][value=true].radio_buttons#user_active_true'
12
13
  assert_select 'input[type=radio][value=false].radio_buttons#user_active_false'
13
14
  end
14
15
 
15
- test 'input as radio should generate internal labels by default' do
16
+ test 'input as radio generates internal labels by default' do
16
17
  with_input_for @user, :active, :radio_buttons
17
18
  assert_select 'label[for=user_active_true]', 'Yes'
18
19
  assert_select 'label[for=user_active_false]', 'No'
19
20
  end
20
21
 
21
- test 'input as radio should use i18n to translate internal labels' do
22
+ test 'input as radio generates internal labels with accurate `for` values with nested boolean style' do
23
+ swap SimpleForm, boolean_style: :nested do
24
+ with_input_for @user, :active, :radio_buttons
25
+ assert_select 'label[for=user_active_true]', 'Yes'
26
+ assert_select 'label[for=user_active_false]', 'No'
27
+ end
28
+ end
29
+
30
+ test 'nested label does not duplicate input id' do
31
+ swap SimpleForm, boolean_style: :nested do
32
+ with_input_for @user, :active, :radio_buttons, id: 'nested_id'
33
+ assert_select 'input#user_active_true'
34
+ assert_no_select 'label#user_active_true'
35
+ end
36
+ end
37
+
38
+ test 'input as radio uses i18n to translate internal labels' do
22
39
  store_translations(:en, simple_form: { yes: 'Sim', no: 'Não' }) do
23
40
  with_input_for @user, :active, :radio_buttons
24
41
  assert_select 'label[for=user_active_true]', 'Sim'
@@ -26,100 +43,128 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
26
43
  end
27
44
  end
28
45
 
29
- test 'input radio should not include for attribute by default' do
30
- with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
46
+ test 'input radio does not include for attribute by default' do
47
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female]
31
48
  assert_select 'label'
32
49
  assert_no_select 'label[for=user_gender]'
33
50
  end
34
51
 
35
- test 'input radio should include for attribute when giving as html option' do
36
- with_input_for @user, :gender, :radio_buttons, collection: [:male, :female], label_html: { for: 'gender' }
52
+ test 'input radio includes for attribute when giving as html option' do
53
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female], label_html: { for: 'gender' }
37
54
  assert_select 'label[for=gender]'
38
55
  end
39
56
 
40
- test 'input should mark the checked value when using boolean and radios' do
57
+ test 'input marks the checked value when using boolean and radios' do
41
58
  @user.active = false
42
59
  with_input_for @user, :active, :radio_buttons
43
60
  assert_no_select 'input[type=radio][value=true][checked]'
44
61
  assert_select 'input[type=radio][value=false][checked]'
45
62
  end
46
63
 
47
- test 'input should allow overriding collection for radio types' do
48
- with_input_for @user, :name, :radio_buttons, collection: ['Jose', 'Carlos']
64
+ test 'input allows overriding collection for radio types' do
65
+ with_input_for @user, :name, :radio_buttons, collection: %w[Jose Carlos]
49
66
  assert_select 'input[type=radio][value=Jose]'
50
67
  assert_select 'input[type=radio][value=Carlos]'
51
- assert_select 'label.collection_radio_buttons', 'Jose'
52
- assert_select 'label.collection_radio_buttons', 'Carlos'
68
+ assert_select 'label.collection_radio_buttons[for=user_name_jose]', 'Jose'
69
+ assert_select 'label.collection_radio_buttons[for=user_name_carlos]', 'Carlos'
53
70
  end
54
71
 
55
- test 'input should do automatic collection translation for radio types using defaults key' do
72
+ test 'input does automatic collection translation for radio types using defaults key' do
56
73
  store_translations(:en, simple_form: { options: { defaults: {
57
- gender: { male: 'Male', female: 'Female'}
74
+ gender: { male: 'Male', female: 'Female' }
58
75
  } } } ) do
59
- with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
76
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female]
60
77
  assert_select 'input[type=radio][value=male]'
61
78
  assert_select 'input[type=radio][value=female]'
62
- assert_select 'label.collection_radio_buttons', 'Male'
63
- assert_select 'label.collection_radio_buttons', 'Female'
79
+ assert_select 'label.collection_radio_buttons[for=user_gender_male]', 'Male'
80
+ assert_select 'label.collection_radio_buttons[for=user_gender_female]', 'Female'
64
81
  end
65
82
  end
66
83
 
67
- test 'input should do automatic collection translation for radio types using specific object key' do
84
+ test 'input does automatic collection translation for radio types using specific object key' do
68
85
  store_translations(:en, simple_form: { options: { user: {
69
- gender: { male: 'Male', female: 'Female'}
86
+ gender: { male: 'Male', female: 'Female' }
70
87
  } } } ) do
71
- with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
88
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female]
72
89
  assert_select 'input[type=radio][value=male]'
73
90
  assert_select 'input[type=radio][value=female]'
74
- assert_select 'label.collection_radio_buttons', 'Male'
75
- assert_select 'label.collection_radio_buttons', 'Female'
91
+ assert_select 'label.collection_radio_buttons[for=user_gender_male]', 'Male'
92
+ assert_select 'label.collection_radio_buttons[for=user_gender_female]', 'Female'
93
+ end
94
+ end
95
+
96
+ test 'input does automatic collection translation and preserve html markup' do
97
+ swap SimpleForm, boolean_style: :nested do
98
+ store_translations(:en, simple_form: { options: { user: {
99
+ gender: { male_html: '<strong>Male</strong>', female_html: '<strong>Female</strong>' }
100
+ } } } ) do
101
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female]
102
+ assert_select 'input[type=radio][value=male]'
103
+ assert_select 'input[type=radio][value=female]'
104
+ assert_select 'label[for=user_gender_male] strong', 'Male'
105
+ assert_select 'label[for=user_gender_female] strong', 'Female'
106
+ end
76
107
  end
77
108
  end
78
109
 
79
- test 'input should mark the current radio value by default' do
110
+ test 'input does automatic collection translation with keys prefixed with _html and a string value' do
111
+ swap SimpleForm, boolean_style: :nested do
112
+ store_translations(:en, simple_form: { options: { user: {
113
+ gender: { male_html: 'Male', female_html: 'Female' }
114
+ } } } ) do
115
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female]
116
+ assert_select 'input[type=radio][value=male]'
117
+ assert_select 'input[type=radio][value=female]'
118
+ assert_select 'label[for=user_gender_male]', 'Male'
119
+ assert_select 'label[for=user_gender_female]', 'Female'
120
+ end
121
+ end
122
+ end
123
+
124
+ test 'input marks the current radio value by default' do
80
125
  @user.name = "Carlos"
81
- with_input_for @user, :name, :radio_buttons, collection: ['Jose', 'Carlos']
126
+ with_input_for @user, :name, :radio_buttons, collection: %w[Jose Carlos]
82
127
  assert_select 'input[type=radio][value=Carlos][checked=checked]'
83
128
  end
84
129
 
85
- test 'input should accept html options as the last element of collection' do
130
+ test 'input accepts html options as the last element of collection' do
86
131
  with_input_for @user, :name, :radio_buttons, collection: [['Jose', 'jose', class: 'foo']]
87
132
  assert_select 'input.foo[type=radio][value=jose]'
88
133
  end
89
134
 
90
- test 'input should allow using a collection with text/value arrays' do
91
- with_input_for @user, :name, :radio_buttons, collection: [['Jose', 'jose'], ['Carlos', 'carlos']]
135
+ test 'input allows using a collection with text/value arrays' do
136
+ with_input_for @user, :name, :radio_buttons, collection: [%w[Jose jose], %w[Carlos carlos]]
92
137
  assert_select 'input[type=radio][value=jose]'
93
138
  assert_select 'input[type=radio][value=carlos]'
94
139
  assert_select 'label.collection_radio_buttons', 'Jose'
95
140
  assert_select 'label.collection_radio_buttons', 'Carlos'
96
141
  end
97
142
 
98
- test 'input should allow using a collection with a Proc' do
99
- with_input_for @user, :name, :radio_buttons, collection: Proc.new { ['Jose', 'Carlos' ] }
143
+ test 'input allows using a collection with a Proc' do
144
+ with_input_for @user, :name, :radio_buttons, collection: proc { %w[Jose Carlos] }
100
145
  assert_select 'label.collection_radio_buttons', 'Jose'
101
146
  assert_select 'label.collection_radio_buttons', 'Carlos'
102
147
  end
103
148
 
104
- test 'input should allow overriding only label method for collections' do
149
+ test 'input allows overriding only label method for collections' do
105
150
  with_input_for @user, :name, :radio_buttons,
106
- collection: ['Jose', 'Carlos'],
151
+ collection: %w[Jose Carlos],
107
152
  label_method: :upcase
108
153
  assert_select 'label.collection_radio_buttons', 'JOSE'
109
154
  assert_select 'label.collection_radio_buttons', 'CARLOS'
110
155
  end
111
156
 
112
- test 'input should allow overriding only value method for collections' do
157
+ test 'input allows overriding only value method for collections' do
113
158
  with_input_for @user, :name, :radio_buttons,
114
- collection: ['Jose', 'Carlos'],
159
+ collection: %w[Jose Carlos],
115
160
  value_method: :upcase
116
161
  assert_select 'input[type=radio][value=JOSE]'
117
162
  assert_select 'input[type=radio][value=CARLOS]'
118
163
  end
119
164
 
120
- test 'input should allow overriding label and value method for collections' do
165
+ test 'input allows overriding label and value method for collections' do
121
166
  with_input_for @user, :name, :radio_buttons,
122
- collection: ['Jose', 'Carlos'],
167
+ collection: %w[Jose Carlos],
123
168
  label_method: :upcase,
124
169
  value_method: :downcase
125
170
  assert_select 'input[type=radio][value=jose]'
@@ -128,25 +173,25 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
128
173
  assert_select 'label.collection_radio_buttons', 'CARLOS'
129
174
  end
130
175
 
131
- test 'input should allow overriding label and value method using a lambda for collections' do
176
+ test 'input allows overriding label and value method using a lambda for collections' do
132
177
  with_input_for @user, :name, :radio_buttons,
133
- collection: ['Jose', 'Carlos'],
134
- label_method: lambda { |i| i.upcase },
135
- value_method: lambda { |i| i.downcase }
178
+ collection: %w[Jose Carlos],
179
+ label_method: ->(i) { i.upcase },
180
+ value_method: ->(i) { i.downcase }
136
181
  assert_select 'input[type=radio][value=jose]'
137
182
  assert_select 'input[type=radio][value=carlos]'
138
183
  assert_select 'label.collection_radio_buttons', 'JOSE'
139
184
  assert_select 'label.collection_radio_buttons', 'CARLOS'
140
185
  end
141
186
 
142
- test 'collection input with radio type should generate required html attribute' do
143
- with_input_for @user, :name, :radio_buttons, collection: ['Jose', 'Carlos']
187
+ test 'collection input with radio type generates required html attribute' do
188
+ with_input_for @user, :name, :radio_buttons, collection: %w[Jose Carlos]
144
189
  assert_select 'input[type=radio].required'
145
190
  assert_select 'input[type=radio][required]'
146
191
  end
147
192
 
148
- test 'collection input with radio type should generate aria-required html attribute' do
149
- with_input_for @user, :name, :radio_buttons, collection: ['Jose', 'Carlos']
193
+ test 'collection input with radio type generates aria-required html attribute' do
194
+ with_input_for @user, :name, :radio_buttons, collection: %w[Jose Carlos]
150
195
  assert_select 'input[type=radio].required'
151
196
  assert_select 'input[type=radio][aria-required=true]'
152
197
  end
@@ -292,29 +337,27 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
292
337
  swap SimpleForm, boolean_style: :nested do
293
338
  with_input_for @user, :active, :radio_buttons
294
339
 
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'
340
+ assert_select 'span.radio > label > input#user_active_true[type=radio]'
341
+ assert_select 'span.radio > label', 'Yes'
342
+ assert_select 'span.radio > label > input#user_active_false[type=radio]'
343
+ assert_select 'span.radio > label', 'No'
299
344
  assert_no_select 'label.collection_radio_buttons'
300
345
  end
301
346
  end
302
347
 
303
- test 'input radio with nested style overrides configured item wrapper tag, forcing the :label' do
348
+ test 'input radio with nested style does not overrides configured item wrapper tag' do
304
349
  swap SimpleForm, boolean_style: :nested, item_wrapper_tag: :li do
305
350
  with_input_for @user, :active, :radio_buttons
306
351
 
307
- assert_select 'label.radio > input'
308
- assert_no_select 'li'
352
+ assert_select 'li.radio > label > input'
309
353
  end
310
354
  end
311
355
 
312
- test 'input radio with nested style overrides given item wrapper tag, forcing the :label' do
356
+ test 'input radio with nested style does not overrides given item wrapper tag' do
313
357
  swap SimpleForm, boolean_style: :nested do
314
358
  with_input_for @user, :active, :radio_buttons, item_wrapper_tag: :li
315
359
 
316
- assert_select 'label.radio > input'
317
- assert_no_select 'li'
360
+ assert_select 'li.radio > label > input'
318
361
  end
319
362
  end
320
363
 
@@ -322,7 +365,86 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
322
365
  swap SimpleForm, boolean_style: :nested do
323
366
  with_input_for @user, :active, :radio_buttons, item_wrapper_class: "inline"
324
367
 
325
- assert_select 'label.radio.inline > input'
368
+ assert_select 'span.radio.inline > label > input'
369
+ end
370
+ end
371
+
372
+ test 'input radio with nested style renders item labels with specified class' do
373
+ swap SimpleForm, boolean_style: :nested do
374
+ with_input_for @user, :active, :radio_buttons, item_label_class: "test"
375
+
376
+ assert_select 'span.radio > label.test > input'
377
+ end
378
+ end
379
+
380
+ test 'input radio with nested style and falsey input wrapper renders item labels with specified class' do
381
+ swap SimpleForm, boolean_style: :nested, item_wrapper_tag: false do
382
+ with_input_for @user, :active, :radio_buttons, item_label_class: "radio-inline"
383
+
384
+ assert_select 'label.radio-inline > input'
385
+ assert_no_select 'span.radio'
386
+ end
387
+ end
388
+
389
+ test 'input radio wrapper class are not included when set to falsey' do
390
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
391
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female]
392
+
393
+ assert_no_select 'label.radio'
394
+ end
395
+ end
396
+
397
+ test 'input radio custom wrapper class is included when include input wrapper class is falsey' do
398
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
399
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female], item_wrapper_class: 'custom'
400
+
401
+ assert_no_select 'label.radio'
402
+ assert_select 'span.custom'
403
+ end
404
+ end
405
+
406
+ test 'input radio with nested style and namespace uses the right for attribute' do
407
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
408
+ with_concat_form_for @user, namespace: :foo do |f|
409
+ concat f.input :gender, as: :radio_buttons, collection: %i[male female]
410
+ end
411
+
412
+ assert_select 'label[for=foo_user_gender_male]'
413
+ assert_select 'label[for=foo_user_gender_female]'
414
+ end
415
+ end
416
+
417
+ test 'input radio with nested style and index uses the right for attribute' do
418
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
419
+ with_concat_form_for @user, index: 1 do |f|
420
+ concat f.input :gender, as: :radio_buttons, collection: %i[male female]
421
+ end
422
+
423
+ assert_select 'label[for=user_1_gender_male]'
424
+ assert_select 'label[for=user_1_gender_female]'
425
+ end
426
+ end
427
+
428
+ test 'input radio with nested style accetps non-string attribute as label' do
429
+ swap SimpleForm, boolean_style: :nested do
430
+ with_input_for @user, :amount,
431
+ :radio_buttons,
432
+ collection: { 100 => 'hundred', 200 => 'two_hundred' },
433
+ label_method: :first,
434
+ value_method: :second
435
+
436
+ assert_select 'input[type=radio][value=hundred]'
437
+ assert_select 'input[type=radio][value=two_hundred]'
438
+ assert_select 'span.radio > label', '100'
439
+ assert_select 'span.radio > label', '200'
440
+ end
441
+ end
442
+
443
+ test 'input check boxes with inline style support label custom classes' do
444
+ swap SimpleForm, boolean_style: :inline do
445
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female], item_label_class: 'beautiful-label'
446
+
447
+ assert_select 'label.beautiful-label', count: 2
326
448
  end
327
449
  end
328
450
  end