simple_form 3.1.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +148 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +278 -68
  5. data/lib/generators/simple_form/install_generator.rb +1 -0
  6. data/lib/generators/simple_form/templates/README +3 -3
  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 +19 -9
  11. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +367 -63
  12. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +23 -8
  13. data/lib/simple_form/action_view_extensions/builder.rb +1 -0
  14. data/lib/simple_form/action_view_extensions/form_helper.rb +4 -1
  15. data/lib/simple_form/components/errors.rb +15 -2
  16. data/lib/simple_form/components/hints.rb +1 -0
  17. data/lib/simple_form/components/html5.rb +15 -4
  18. data/lib/simple_form/components/label_input.rb +2 -1
  19. data/lib/simple_form/components/labels.rb +12 -5
  20. data/lib/simple_form/components/maxlength.rb +8 -4
  21. data/lib/simple_form/components/min_max.rb +1 -0
  22. data/lib/simple_form/components/minlength.rb +38 -0
  23. data/lib/simple_form/components/pattern.rb +1 -0
  24. data/lib/simple_form/components/placeholders.rb +2 -1
  25. data/lib/simple_form/components/readonly.rb +1 -0
  26. data/lib/simple_form/components.rb +2 -0
  27. data/lib/simple_form/error_notification.rb +1 -0
  28. data/lib/simple_form/form_builder.rb +117 -35
  29. data/lib/simple_form/helpers/autofocus.rb +1 -0
  30. data/lib/simple_form/helpers/disabled.rb +1 -0
  31. data/lib/simple_form/helpers/readonly.rb +1 -0
  32. data/lib/simple_form/helpers/required.rb +1 -0
  33. data/lib/simple_form/helpers/validators.rb +2 -1
  34. data/lib/simple_form/helpers.rb +1 -0
  35. data/lib/simple_form/i18n_cache.rb +1 -0
  36. data/lib/simple_form/inputs/base.rb +36 -12
  37. data/lib/simple_form/inputs/block_input.rb +1 -0
  38. data/lib/simple_form/inputs/boolean_input.rb +14 -3
  39. data/lib/simple_form/inputs/collection_check_boxes_input.rb +2 -1
  40. data/lib/simple_form/inputs/collection_input.rb +7 -5
  41. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +3 -2
  42. data/lib/simple_form/inputs/collection_select_input.rb +1 -0
  43. data/lib/simple_form/inputs/color_input.rb +14 -0
  44. data/lib/simple_form/inputs/date_time_input.rb +13 -8
  45. data/lib/simple_form/inputs/file_input.rb +1 -0
  46. data/lib/simple_form/inputs/grouped_collection_select_input.rb +1 -0
  47. data/lib/simple_form/inputs/hidden_input.rb +1 -0
  48. data/lib/simple_form/inputs/numeric_input.rb +1 -0
  49. data/lib/simple_form/inputs/password_input.rb +2 -1
  50. data/lib/simple_form/inputs/priority_input.rb +1 -4
  51. data/lib/simple_form/inputs/range_input.rb +1 -0
  52. data/lib/simple_form/inputs/string_input.rb +3 -2
  53. data/lib/simple_form/inputs/text_input.rb +2 -1
  54. data/lib/simple_form/inputs.rb +2 -0
  55. data/lib/simple_form/map_type.rb +1 -0
  56. data/lib/simple_form/railtie.rb +1 -0
  57. data/lib/simple_form/tags.rb +7 -2
  58. data/lib/simple_form/version.rb +2 -1
  59. data/lib/simple_form/wrappers/builder.rb +1 -0
  60. data/lib/simple_form/wrappers/leaf.rb +2 -1
  61. data/lib/simple_form/wrappers/many.rb +1 -0
  62. data/lib/simple_form/wrappers/root.rb +2 -0
  63. data/lib/simple_form/wrappers/single.rb +2 -1
  64. data/lib/simple_form/wrappers.rb +1 -0
  65. data/lib/simple_form.rb +79 -14
  66. data/test/action_view_extensions/builder_test.rb +28 -9
  67. data/test/action_view_extensions/form_helper_test.rb +3 -2
  68. data/test/components/custom_components_test.rb +62 -0
  69. data/test/components/label_test.rb +33 -4
  70. data/test/form_builder/association_test.rb +33 -2
  71. data/test/form_builder/button_test.rb +1 -0
  72. data/test/form_builder/error_notification_test.rb +1 -0
  73. data/test/form_builder/error_test.rb +44 -9
  74. data/test/form_builder/general_test.rb +92 -20
  75. data/test/form_builder/hint_test.rb +6 -0
  76. data/test/form_builder/input_field_test.rb +76 -70
  77. data/test/form_builder/label_test.rb +27 -4
  78. data/test/form_builder/wrapper_test.rb +66 -14
  79. data/test/generators/simple_form_generator_test.rb +4 -3
  80. data/test/inputs/boolean_input_test.rb +35 -0
  81. data/test/inputs/collection_check_boxes_input_test.rb +38 -14
  82. data/test/inputs/collection_radio_buttons_input_test.rb +48 -24
  83. data/test/inputs/collection_select_input_test.rb +40 -39
  84. data/test/inputs/color_input_test.rb +10 -0
  85. data/test/inputs/datetime_input_test.rb +12 -8
  86. data/test/inputs/disabled_test.rb +14 -0
  87. data/test/inputs/discovery_test.rb +23 -0
  88. data/test/inputs/file_input_test.rb +1 -0
  89. data/test/inputs/general_test.rb +3 -2
  90. data/test/inputs/grouped_collection_select_input_test.rb +11 -10
  91. data/test/inputs/hidden_input_test.rb +1 -0
  92. data/test/inputs/numeric_input_test.rb +5 -1
  93. data/test/inputs/priority_input_test.rb +7 -6
  94. data/test/inputs/readonly_test.rb +1 -0
  95. data/test/inputs/required_test.rb +45 -0
  96. data/test/inputs/string_input_test.rb +18 -16
  97. data/test/inputs/text_input_test.rb +13 -0
  98. data/test/simple_form_test.rb +1 -0
  99. data/test/support/discovery_inputs.rb +8 -0
  100. data/test/support/misc_helpers.rb +44 -2
  101. data/test/support/mock_controller.rb +7 -1
  102. data/test/support/models.rb +105 -22
  103. data/test/test_helper.rb +14 -3
  104. metadata +42 -36
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class WrapperTest < ActionView::TestCase
@@ -37,6 +38,27 @@ class WrapperTest < ActionView::TestCase
37
38
  assert_select 'div.field_with_errors'
38
39
  end
39
40
 
41
+ test 'wrapper adds error class to input for attribute with errors' do
42
+ with_form_for @user, :name, wrapper: custom_wrapper_with_input_error_class
43
+ assert_select 'div.field_with_errors'
44
+ assert_select 'input.is-invalid'
45
+ end
46
+
47
+ test 'wrapper does not add error class to input when the attribute is valid' do
48
+ with_form_for @user, :phone_number, wrapper: custom_wrapper_with_input_error_class
49
+ assert_no_select 'div.field_with_errors'
50
+ assert_no_select 'input.is-invalid'
51
+ end
52
+
53
+ test 'wrapper adds valid class for present attribute without errors' do
54
+ @user.instance_eval { undef errors }
55
+ with_form_for @user, :name, wrapper: custom_wrapper_with_input_valid_class
56
+ assert_select 'div.field_without_errors'
57
+ assert_select 'input.is-valid'
58
+ assert_no_select 'div.field_with_errors'
59
+ assert_no_select 'input.is-invalid'
60
+ end
61
+
40
62
  test 'wrapper adds hint class for attribute with a hint' do
41
63
  with_form_for @user, :name, hint: 'hint'
42
64
  assert_select 'div.field_with_hint'
@@ -88,7 +110,7 @@ class WrapperTest < ActionView::TestCase
88
110
  end
89
111
 
90
112
  test 'wrapper skips additional classes when configured' do
91
- swap SimpleForm, generate_additional_classes_for: [:input, :label] do
113
+ swap SimpleForm, generate_additional_classes_for: %i[input label] do
92
114
  with_form_for @user, :name, wrapper_class: :wrapper
93
115
  assert_select 'form div.wrapper'
94
116
  assert_no_select 'div.required'
@@ -98,7 +120,7 @@ class WrapperTest < ActionView::TestCase
98
120
  end
99
121
 
100
122
  test 'wrapper does not generate empty css class' do
101
- swap SimpleForm, generate_additional_classes_for: [:input, :label] do
123
+ swap SimpleForm, generate_additional_classes_for: %i[input label] do
102
124
  swap_wrapper :default, custom_wrapper_without_class do
103
125
  with_form_for @user, :name
104
126
  assert_no_select 'div#custom_wrapper_without_class[class]'
@@ -129,7 +151,7 @@ class WrapperTest < ActionView::TestCase
129
151
  end
130
152
 
131
153
  test 'custom wrappers can have additional attributes' do
132
- swap_wrapper :default, self.custom_wrapper_with_additional_attributes do
154
+ swap_wrapper :default, custom_wrapper_with_additional_attributes do
133
155
  with_form_for @user, :name
134
156
 
135
157
  assert_select "div.custom_wrapper[title='some title'][data-wrapper='test']"
@@ -137,9 +159,9 @@ class WrapperTest < ActionView::TestCase
137
159
  end
138
160
 
139
161
  test 'custom wrappers can have full error message on attributes' do
140
- swap_wrapper :default, self.custom_wrapper_with_full_error do
162
+ swap_wrapper :default, custom_wrapper_with_full_error do
141
163
  with_form_for @user, :name
142
- assert_select 'span.error', "Name cannot be blank"
164
+ assert_select 'span.error', "Super User Name! cannot be blank"
143
165
  end
144
166
  end
145
167
 
@@ -188,7 +210,7 @@ class WrapperTest < ActionView::TestCase
188
210
  end
189
211
 
190
212
  test 'does not duplicate label classes for different inputs' do
191
- swap_wrapper :default, self.custom_wrapper_with_label_html_option do
213
+ swap_wrapper :default, custom_wrapper_with_label_html_option do
192
214
  with_concat_form_for(@user) do |f|
193
215
  concat f.input :name, required: false
194
216
  concat f.input :email, as: :email, required: true
@@ -242,8 +264,38 @@ class WrapperTest < ActionView::TestCase
242
264
  assert_select "section.custom_wrapper div.another_wrapper input.string"
243
265
  end
244
266
 
267
+ test "input attributes class will merge with wrapper_options' classes" do
268
+ swap_wrapper :default, custom_wrapper_with_input_class do
269
+ with_concat_form_for @user do |f|
270
+ concat f.input :name, input_html: { class: 'another-class' }
271
+ end
272
+ end
273
+
274
+ assert_select "div.custom_wrapper input.string.inline-class.another-class"
275
+ end
276
+
277
+ test "input with data attributes will merge with wrapper_options' data" do
278
+ swap_wrapper :default, custom_wrapper_with_input_data_modal do
279
+ with_concat_form_for @user do |f|
280
+ concat f.input :name, input_html: { data: { modal: 'another-data', target: 'merge-data' } }
281
+ end
282
+ end
283
+
284
+ assert_select "input[data-wrapper='data-wrapper'][data-modal='another-data'][data-target='merge-data']"
285
+ end
286
+
287
+ test "input with aria attributes will merge with wrapper_options' aria" do
288
+ swap_wrapper :default, custom_wrapper_with_input_aria_modal do
289
+ with_concat_form_for @user do |f|
290
+ concat f.input :name, input_html: { aria: { modal: 'another-aria', target: 'merge-aria' } }
291
+ end
292
+ end
293
+
294
+ assert_select "input[aria-wrapper='aria-wrapper'][aria-modal='another-aria'][aria-target='merge-aria']"
295
+ end
296
+
245
297
  test 'input accepts attributes in the DSL' do
246
- swap_wrapper :default, self.custom_wrapper_with_input_class do
298
+ swap_wrapper :default, custom_wrapper_with_input_class do
247
299
  with_concat_form_for @user do |f|
248
300
  concat f.input :name
249
301
  end
@@ -253,7 +305,7 @@ class WrapperTest < ActionView::TestCase
253
305
  end
254
306
 
255
307
  test 'label accepts attributes in the DSL' do
256
- swap_wrapper :default, self.custom_wrapper_with_label_class do
308
+ swap_wrapper :default, custom_wrapper_with_label_class do
257
309
  with_concat_form_for @user do |f|
258
310
  concat f.input :name
259
311
  end
@@ -263,7 +315,7 @@ class WrapperTest < ActionView::TestCase
263
315
  end
264
316
 
265
317
  test 'label_input accepts attributes in the DSL' do
266
- swap_wrapper :default, self.custom_wrapper_with_label_input_class do
318
+ swap_wrapper :default, custom_wrapper_with_label_input_class do
267
319
  with_concat_form_for @user do |f|
268
320
  concat f.input :name
269
321
  end
@@ -274,7 +326,7 @@ class WrapperTest < ActionView::TestCase
274
326
  end
275
327
 
276
328
  test 'input accepts data attributes in the DSL' do
277
- swap_wrapper :default, self.custom_wrapper_with_input_attributes do
329
+ swap_wrapper :default, custom_wrapper_with_input_attributes do
278
330
  with_concat_form_for @user do |f|
279
331
  concat f.input :name
280
332
  end
@@ -284,7 +336,7 @@ class WrapperTest < ActionView::TestCase
284
336
  end
285
337
 
286
338
  test 'inline wrapper displays when there is content' do
287
- swap_wrapper :default, self.custom_wrapper_with_wrapped_optional_component do
339
+ swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do
288
340
  with_form_for @user, :name, hint: "cannot be blank"
289
341
  assert_select 'section.custom_wrapper div.no_output_wrapper p.omg_hint', "cannot be blank"
290
342
  assert_select 'p.omg_hint'
@@ -292,7 +344,7 @@ class WrapperTest < ActionView::TestCase
292
344
  end
293
345
 
294
346
  test 'inline wrapper does not display when there is no content' do
295
- swap_wrapper :default, self.custom_wrapper_with_wrapped_optional_component do
347
+ swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do
296
348
  with_form_for @user, :name
297
349
  assert_select 'section.custom_wrapper div.no_output_wrapper'
298
350
  assert_no_select 'p.omg_hint'
@@ -300,7 +352,7 @@ class WrapperTest < ActionView::TestCase
300
352
  end
301
353
 
302
354
  test 'optional wrapper does not display when there is content' do
303
- swap_wrapper :default, self.custom_wrapper_with_unless_blank do
355
+ swap_wrapper :default, custom_wrapper_with_unless_blank do
304
356
  with_form_for @user, :name, hint: "can't be blank"
305
357
  assert_select 'section.custom_wrapper div.no_output_wrapper'
306
358
  assert_select 'div.no_output_wrapper'
@@ -309,7 +361,7 @@ class WrapperTest < ActionView::TestCase
309
361
  end
310
362
 
311
363
  test 'optional wrapper does not display when there is no content' do
312
- swap_wrapper :default, self.custom_wrapper_with_unless_blank do
364
+ swap_wrapper :default, custom_wrapper_with_unless_blank do
313
365
  with_form_for @user, :name
314
366
  assert_no_select 'section.custom_wrapper div.no_output_wrapper'
315
367
  assert_no_select 'div.no_output_wrapper'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class SimpleFormGeneratorTest < Rails::Generators::TestCase
@@ -18,7 +19,7 @@ class SimpleFormGeneratorTest < Rails::Generators::TestCase
18
19
  end
19
20
 
20
21
  test 'generates the simple_form initializer with the bootstrap wrappers' do
21
- run_generator %w(--bootstrap)
22
+ run_generator %w[--bootstrap]
22
23
  assert_file 'config/initializers/simple_form.rb',
23
24
  /config\.default_wrapper = :default/, /config\.boolean_style = :nested/
24
25
  assert_file 'config/initializers/simple_form_bootstrap.rb', /config\.wrappers :vertical_form/,
@@ -26,14 +27,14 @@ class SimpleFormGeneratorTest < Rails::Generators::TestCase
26
27
  end
27
28
 
28
29
  test 'generates the simple_form initializer with the foundation wrappers' do
29
- run_generator %w(--foundation)
30
+ run_generator %w[--foundation]
30
31
  assert_file 'config/initializers/simple_form.rb',
31
32
  /config\.default_wrapper = :default/, /config\.boolean_style = :nested/
32
33
  assert_file 'config/initializers/simple_form_foundation.rb', /config\.wrappers :vertical_form/,
33
34
  /config\.default_wrapper = :vertical_form/, /config\.item_wrapper_tag = :div/
34
35
  end
35
36
 
36
- %W(erb haml slim).each do |engine|
37
+ %w[erb haml slim].each do |engine|
37
38
  test "generates the scaffold template when using #{engine}" do
38
39
  run_generator ['-e', engine]
39
40
  assert_file "lib/templates/#{engine}/scaffold/_form.html.#{engine}"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: UTF-8
2
3
  require 'test_helper'
3
4
 
@@ -106,6 +107,14 @@ class BooleanInputTest < ActionView::TestCase
106
107
  end
107
108
  end
108
109
 
110
+ test 'input boolean with nested generates a disabled hidden field with the form attribute when it is given' do
111
+ swap SimpleForm, boolean_style: :nested do
112
+ with_input_for @user, :active, :boolean, input_html: { form: 'form_id' }
113
+
114
+ assert_select "input[type=hidden][form=form_id]+ label.boolean > input.boolean"
115
+ end
116
+ end
117
+
109
118
  test 'input accepts changing boolean style to nested through given options' do
110
119
  with_input_for @user, :active, :boolean, boolean_style: :nested
111
120
  assert_select 'label[for=user_active]', 'Active'
@@ -137,6 +146,22 @@ class BooleanInputTest < ActionView::TestCase
137
146
  end
138
147
  end
139
148
 
149
+ test 'input with nested style allows disabling hidden field' do
150
+ swap SimpleForm, boolean_style: :nested do
151
+ with_input_for @user, :active, :boolean, include_hidden: false
152
+ assert_select "label.boolean > input.boolean"
153
+ assert_no_select "input[type=hidden] + label.boolean"
154
+ end
155
+ end
156
+
157
+ test 'input with nested style does not include hidden field when unchecked_value is false' do
158
+ swap SimpleForm, boolean_style: :nested do
159
+ with_input_for @user, :active, :boolean, unchecked_value: false
160
+ assert_select "label.boolean > input.boolean"
161
+ assert_no_select "input[type=hidden] + label.boolean"
162
+ end
163
+ end
164
+
140
165
  test 'input boolean works using :input only in wrapper config (no label_input)' do
141
166
  swap_wrapper do
142
167
  with_input_for @user, :active, :boolean
@@ -156,6 +181,16 @@ class BooleanInputTest < ActionView::TestCase
156
181
  end
157
182
  end
158
183
 
184
+ test 'input boolean allows specifying boolean_label_class on a per-input basis' do
185
+ swap_wrapper do
186
+ swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
187
+ with_input_for @user, :active, :boolean, boolean_label_class: 'baz'
188
+
189
+ assert_select 'label.boolean + input[type=hidden] + label.baz > input.boolean'
190
+ end
191
+ end
192
+ end
193
+
159
194
  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
195
  swap_wrapper do
161
196
  swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: UTF-8
2
3
  require 'test_helper'
3
4
 
@@ -7,33 +8,33 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
7
8
  end
8
9
 
9
10
  test 'input check boxes does not include for attribute by default' do
10
- with_input_for @user, :gender, :check_boxes, collection: [:male, :female]
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
16
  test 'input check boxes includes for attribute when giving as html option' do
16
- with_input_for @user, :gender, :check_boxes, collection: [:male, :female], label_html: { for: 'gender' }
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
21
  test 'collection input with check_boxes type does not generate required html attribute' do
21
- with_input_for @user, :name, :check_boxes, collection: ['Jose', 'Carlos']
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
27
  test 'collection input with check_boxes type does not generate aria-required html attribute' do
27
- with_input_for @user, :name, :check_boxes, collection: ['Jose', 'Carlos']
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
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'
@@ -43,9 +44,9 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
43
44
 
44
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'
@@ -55,11 +56,11 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
55
56
 
56
57
  test 'input that uses automatic collection translation for check_boxes properly sets checked values' do
57
58
  store_translations(:en, simple_form: { options: { defaults: {
58
- gender: { male: 'Male', female: 'Female'}
59
+ gender: { male: 'Male', female: 'Female' }
59
60
  } } } ) do
60
61
  @user.gender = 'male'
61
62
 
62
- with_input_for @user, :gender, :check_boxes, collection: [:male, :female]
63
+ with_input_for @user, :gender, :check_boxes, collection: %i[male female]
63
64
  assert_select 'input[type=checkbox][value=male][checked=checked]'
64
65
  assert_select 'input[type=checkbox][value=female]'
65
66
  assert_select 'label.collection_check_boxes', 'Male'
@@ -264,7 +265,7 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
264
265
 
265
266
  test 'input check boxes wrapper class are not included when set to falsey' do
266
267
  swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
267
- with_input_for @user, :gender, :check_boxes, collection: [:male, :female]
268
+ with_input_for @user, :gender, :check_boxes, collection: %i[male female]
268
269
 
269
270
  assert_no_select 'label.checkbox'
270
271
  end
@@ -272,7 +273,7 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
272
273
 
273
274
  test 'input check boxes custom wrapper class is included when include input wrapper class is falsey' do
274
275
  swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
275
- with_input_for @user, :gender, :check_boxes, collection: [:male, :female], item_wrapper_class: 'custom'
276
+ with_input_for @user, :gender, :check_boxes, collection: %i[male female], item_wrapper_class: 'custom'
276
277
 
277
278
  assert_no_select 'label.checkbox'
278
279
  assert_select 'span.custom'
@@ -282,7 +283,7 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
282
283
  test 'input check boxes with nested style and namespace uses the right for attribute' do
283
284
  swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
284
285
  with_concat_form_for @user, namespace: :foo do |f|
285
- concat f.input :gender, as: :check_boxes, collection: [:male, :female]
286
+ concat f.input :gender, as: :check_boxes, collection: %i[male female]
286
287
  end
287
288
 
288
289
  assert_select 'label[for=foo_user_gender_male]'
@@ -293,11 +294,34 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
293
294
  test 'input check boxes with nested style and index uses the right for attribute' do
294
295
  swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
295
296
  with_concat_form_for @user, index: 1 do |f|
296
- concat f.input :gender, as: :check_boxes, collection: [:male, :female]
297
+ concat f.input :gender, as: :check_boxes, collection: %i[male female]
297
298
  end
298
299
 
299
300
  assert_select 'label[for=user_1_gender_male]'
300
301
  assert_select 'label[for=user_1_gender_female]'
301
302
  end
302
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
325
+ end
326
+ end
303
327
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: UTF-8
2
3
  require 'test_helper'
3
4
 
@@ -43,13 +44,13 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
43
44
  end
44
45
 
45
46
  test 'input radio does not include for attribute by default' do
46
- with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
47
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female]
47
48
  assert_select 'label'
48
49
  assert_no_select 'label[for=user_gender]'
49
50
  end
50
51
 
51
52
  test 'input radio includes for attribute when giving as html option' do
52
- with_input_for @user, :gender, :radio_buttons, collection: [:male, :female], label_html: { for: 'gender' }
53
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female], label_html: { for: 'gender' }
53
54
  assert_select 'label[for=gender]'
54
55
  end
55
56
 
@@ -61,7 +62,7 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
61
62
  end
62
63
 
63
64
  test 'input allows overriding collection for radio types' do
64
- with_input_for @user, :name, :radio_buttons, collection: ['Jose', 'Carlos']
65
+ with_input_for @user, :name, :radio_buttons, collection: %w[Jose Carlos]
65
66
  assert_select 'input[type=radio][value=Jose]'
66
67
  assert_select 'input[type=radio][value=Carlos]'
67
68
  assert_select 'label.collection_radio_buttons[for=user_name_jose]', 'Jose'
@@ -70,9 +71,9 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
70
71
 
71
72
  test 'input does automatic collection translation for radio types using defaults key' do
72
73
  store_translations(:en, simple_form: { options: { defaults: {
73
- gender: { male: 'Male', female: 'Female'}
74
+ gender: { male: 'Male', female: 'Female' }
74
75
  } } } ) do
75
- with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
76
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female]
76
77
  assert_select 'input[type=radio][value=male]'
77
78
  assert_select 'input[type=radio][value=female]'
78
79
  assert_select 'label.collection_radio_buttons[for=user_gender_male]', 'Male'
@@ -82,9 +83,9 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
82
83
 
83
84
  test 'input does automatic collection translation for radio types using specific object key' do
84
85
  store_translations(:en, simple_form: { options: { user: {
85
- gender: { male: 'Male', female: 'Female'}
86
+ gender: { male: 'Male', female: 'Female' }
86
87
  } } } ) do
87
- with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
88
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female]
88
89
  assert_select 'input[type=radio][value=male]'
89
90
  assert_select 'input[type=radio][value=female]'
90
91
  assert_select 'label.collection_radio_buttons[for=user_gender_male]', 'Male'
@@ -97,7 +98,7 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
97
98
  store_translations(:en, simple_form: { options: { user: {
98
99
  gender: { male_html: '<strong>Male</strong>', female_html: '<strong>Female</strong>' }
99
100
  } } } ) do
100
- with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
101
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female]
101
102
  assert_select 'input[type=radio][value=male]'
102
103
  assert_select 'input[type=radio][value=female]'
103
104
  assert_select 'label[for=user_gender_male] strong', 'Male'
@@ -111,7 +112,7 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
111
112
  store_translations(:en, simple_form: { options: { user: {
112
113
  gender: { male_html: 'Male', female_html: 'Female' }
113
114
  } } } ) do
114
- with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
115
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female]
115
116
  assert_select 'input[type=radio][value=male]'
116
117
  assert_select 'input[type=radio][value=female]'
117
118
  assert_select 'label[for=user_gender_male]', 'Male'
@@ -122,7 +123,7 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
122
123
 
123
124
  test 'input marks the current radio value by default' do
124
125
  @user.name = "Carlos"
125
- with_input_for @user, :name, :radio_buttons, collection: ['Jose', 'Carlos']
126
+ with_input_for @user, :name, :radio_buttons, collection: %w[Jose Carlos]
126
127
  assert_select 'input[type=radio][value=Carlos][checked=checked]'
127
128
  end
128
129
 
@@ -132,7 +133,7 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
132
133
  end
133
134
 
134
135
  test 'input allows using a collection with text/value arrays' do
135
- with_input_for @user, :name, :radio_buttons, collection: [['Jose', 'jose'], ['Carlos', 'carlos']]
136
+ with_input_for @user, :name, :radio_buttons, collection: [%w[Jose jose], %w[Carlos carlos]]
136
137
  assert_select 'input[type=radio][value=jose]'
137
138
  assert_select 'input[type=radio][value=carlos]'
138
139
  assert_select 'label.collection_radio_buttons', 'Jose'
@@ -140,14 +141,14 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
140
141
  end
141
142
 
142
143
  test 'input allows using a collection with a Proc' do
143
- with_input_for @user, :name, :radio_buttons, collection: Proc.new { ['Jose', 'Carlos' ] }
144
+ with_input_for @user, :name, :radio_buttons, collection: proc { %w[Jose Carlos] }
144
145
  assert_select 'label.collection_radio_buttons', 'Jose'
145
146
  assert_select 'label.collection_radio_buttons', 'Carlos'
146
147
  end
147
148
 
148
149
  test 'input allows overriding only label method for collections' do
149
150
  with_input_for @user, :name, :radio_buttons,
150
- collection: ['Jose', 'Carlos'],
151
+ collection: %w[Jose Carlos],
151
152
  label_method: :upcase
152
153
  assert_select 'label.collection_radio_buttons', 'JOSE'
153
154
  assert_select 'label.collection_radio_buttons', 'CARLOS'
@@ -155,7 +156,7 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
155
156
 
156
157
  test 'input allows overriding only value method for collections' do
157
158
  with_input_for @user, :name, :radio_buttons,
158
- collection: ['Jose', 'Carlos'],
159
+ collection: %w[Jose Carlos],
159
160
  value_method: :upcase
160
161
  assert_select 'input[type=radio][value=JOSE]'
161
162
  assert_select 'input[type=radio][value=CARLOS]'
@@ -163,7 +164,7 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
163
164
 
164
165
  test 'input allows overriding label and value method for collections' do
165
166
  with_input_for @user, :name, :radio_buttons,
166
- collection: ['Jose', 'Carlos'],
167
+ collection: %w[Jose Carlos],
167
168
  label_method: :upcase,
168
169
  value_method: :downcase
169
170
  assert_select 'input[type=radio][value=jose]'
@@ -174,9 +175,9 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
174
175
 
175
176
  test 'input allows overriding label and value method using a lambda for collections' do
176
177
  with_input_for @user, :name, :radio_buttons,
177
- collection: ['Jose', 'Carlos'],
178
- label_method: lambda { |i| i.upcase },
179
- value_method: lambda { |i| i.downcase }
178
+ collection: %w[Jose Carlos],
179
+ label_method: ->(i) { i.upcase },
180
+ value_method: ->(i) { i.downcase }
180
181
  assert_select 'input[type=radio][value=jose]'
181
182
  assert_select 'input[type=radio][value=carlos]'
182
183
  assert_select 'label.collection_radio_buttons', 'JOSE'
@@ -184,13 +185,13 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
184
185
  end
185
186
 
186
187
  test 'collection input with radio type generates required html attribute' do
187
- with_input_for @user, :name, :radio_buttons, collection: ['Jose', 'Carlos']
188
+ with_input_for @user, :name, :radio_buttons, collection: %w[Jose Carlos]
188
189
  assert_select 'input[type=radio].required'
189
190
  assert_select 'input[type=radio][required]'
190
191
  end
191
192
 
192
193
  test 'collection input with radio type generates aria-required html attribute' do
193
- with_input_for @user, :name, :radio_buttons, collection: ['Jose', 'Carlos']
194
+ with_input_for @user, :name, :radio_buttons, collection: %w[Jose Carlos]
194
195
  assert_select 'input[type=radio].required'
195
196
  assert_select 'input[type=radio][aria-required=true]'
196
197
  end
@@ -387,7 +388,7 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
387
388
 
388
389
  test 'input radio wrapper class are not included when set to falsey' do
389
390
  swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
390
- with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
391
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female]
391
392
 
392
393
  assert_no_select 'label.radio'
393
394
  end
@@ -395,7 +396,7 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
395
396
 
396
397
  test 'input radio custom wrapper class is included when include input wrapper class is falsey' do
397
398
  swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
398
- with_input_for @user, :gender, :radio_buttons, collection: [:male, :female], item_wrapper_class: 'custom'
399
+ with_input_for @user, :gender, :radio_buttons, collection: %i[male female], item_wrapper_class: 'custom'
399
400
 
400
401
  assert_no_select 'label.radio'
401
402
  assert_select 'span.custom'
@@ -405,7 +406,7 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
405
406
  test 'input radio with nested style and namespace uses the right for attribute' do
406
407
  swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
407
408
  with_concat_form_for @user, namespace: :foo do |f|
408
- concat f.input :gender, as: :radio_buttons, collection: [:male, :female]
409
+ concat f.input :gender, as: :radio_buttons, collection: %i[male female]
409
410
  end
410
411
 
411
412
  assert_select 'label[for=foo_user_gender_male]'
@@ -416,11 +417,34 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
416
417
  test 'input radio with nested style and index uses the right for attribute' do
417
418
  swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
418
419
  with_concat_form_for @user, index: 1 do |f|
419
- concat f.input :gender, as: :radio_buttons, collection: [:male, :female]
420
+ concat f.input :gender, as: :radio_buttons, collection: %i[male female]
420
421
  end
421
422
 
422
423
  assert_select 'label[for=user_1_gender_male]'
423
424
  assert_select 'label[for=user_1_gender_female]'
424
425
  end
425
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
448
+ end
449
+ end
426
450
  end