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,22 +1,23 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class WrapperTest < ActionView::TestCase
4
- test 'wrapper should not have error class for attribute without errors' do
5
+ test 'wrapper does not have error class for attribute without errors' do
5
6
  with_form_for @user, :active
6
7
  assert_no_select 'div.field_with_errors'
7
8
  end
8
9
 
9
- test 'wrapper should not have error class when object is not present' do
10
+ test 'wrapper does not have error class when object is not present' do
10
11
  with_form_for :project, :name
11
12
  assert_no_select 'div.field_with_errors'
12
13
  end
13
14
 
14
- test 'wrapper should add the attribute name class' do
15
+ test 'wrapper adds the attribute name class' do
15
16
  with_form_for @user, :name
16
17
  assert_select 'div.user_name'
17
18
  end
18
19
 
19
- test 'wrapper should add the attribute name class for nested forms' do
20
+ test 'wrapper adds the attribute name class for nested forms' do
20
21
  @user.company = Company.new(1, 'Empresa')
21
22
  with_concat_form_for @user do |f|
22
23
  concat(f.simple_fields_for(:company) do |company_form|
@@ -27,44 +28,72 @@ class WrapperTest < ActionView::TestCase
27
28
  assert_select 'div.user_company_name'
28
29
  end
29
30
 
30
- test 'wrapper should add the association name class' do
31
+ test 'wrapper adds the association name class' do
31
32
  with_form_for @user, :company
32
33
  assert_select 'div.user_company'
33
34
  end
34
35
 
35
- test 'wrapper should add error class for attribute with errors' do
36
+ test 'wrapper adds error class for attribute with errors' do
36
37
  with_form_for @user, :name
37
38
  assert_select 'div.field_with_errors'
38
39
  end
39
40
 
40
- test 'wrapper should add hint class for attribute with a hint' do
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
+
62
+ test 'wrapper does not determine if valid class is needed when it is set to nil' do
63
+ @user.instance_eval { undef errors }
64
+ with_form_for @user, :name, wrapper: custom_wrapper_with_input_valid_class(valid_class: nil)
65
+
66
+ assert_no_select 'div.field_without_errors'
67
+ end
68
+
69
+ test 'wrapper adds hint class for attribute with a hint' do
41
70
  with_form_for @user, :name, hint: 'hint'
42
71
  assert_select 'div.field_with_hint'
43
72
  end
44
73
 
45
- test 'wrapper should not have disabled class by default' do
74
+ test 'wrapper does not have disabled class by default' do
46
75
  with_form_for @user, :active
47
76
  assert_no_select 'div.disabled'
48
77
  end
49
78
 
50
- test 'wrapper should have disabled class when input is disabled' do
79
+ test 'wrapper has disabled class when input is disabled' do
51
80
  with_form_for @user, :active, disabled: true
52
81
  assert_select 'div.disabled'
53
82
  end
54
83
 
55
- test 'wrapper should support no wrapping when wrapper is false' do
84
+ test 'wrapper supports no wrapping when wrapper is false' do
56
85
  with_form_for @user, :name, wrapper: false
57
86
  assert_select 'form > label[for=user_name]'
58
87
  assert_select 'form > input#user_name.string'
59
88
  end
60
89
 
61
- test 'wrapper should support no wrapping when wrapper tag is false' do
90
+ test 'wrapper supports no wrapping when wrapper tag is false' do
62
91
  with_form_for @user, :name, wrapper: custom_wrapper_without_top_level
63
92
  assert_select 'form > label[for=user_name]'
64
93
  assert_select 'form > input#user_name.string'
65
94
  end
66
95
 
67
- test 'wrapper should wrapping tag adds required/optional css classes' do
96
+ test 'wrapper wraps tag adds required/optional css classes' do
68
97
  with_form_for @user, :name
69
98
  assert_select 'form div.input.required.string'
70
99
 
@@ -72,23 +101,23 @@ class WrapperTest < ActionView::TestCase
72
101
  assert_select 'form div.input.optional.integer'
73
102
  end
74
103
 
75
- test 'wrapper should allow custom options to be given' do
104
+ test 'wrapper allows custom options to be given' do
76
105
  with_form_for @user, :name, wrapper_html: { id: "super_cool", class: 'yay' }
77
106
  assert_select 'form #super_cool.required.string.yay'
78
107
  end
79
108
 
80
- test 'wrapper should allow tag to be given on demand' do
109
+ test 'wrapper allows tag to be given on demand' do
81
110
  with_form_for @user, :name, wrapper_tag: :b
82
111
  assert_select 'form b.required.string'
83
112
  end
84
113
 
85
- test 'wrapper should allow wrapper class to be given on demand' do
114
+ test 'wrapper allows wrapper class to be given on demand' do
86
115
  with_form_for @user, :name, wrapper_class: :wrapper
87
116
  assert_select 'form div.wrapper.required.string'
88
117
  end
89
118
 
90
- test 'wrapper should skip additional classes when configured' do
91
- swap SimpleForm, generate_additional_classes_for: [:input, :label] do
119
+ test 'wrapper skips additional classes when configured' do
120
+ swap SimpleForm, generate_additional_classes_for: %i[input label] do
92
121
  with_form_for @user, :name, wrapper_class: :wrapper
93
122
  assert_select 'form div.wrapper'
94
123
  assert_no_select 'div.required'
@@ -97,8 +126,8 @@ class WrapperTest < ActionView::TestCase
97
126
  end
98
127
  end
99
128
 
100
- test 'wrapper should not generate empty css class' do
101
- swap SimpleForm, generate_additional_classes_for: [:input, :label] do
129
+ test 'wrapper does not generate empty css class' do
130
+ swap SimpleForm, generate_additional_classes_for: %i[input label] do
102
131
  swap_wrapper :default, custom_wrapper_without_class do
103
132
  with_form_for @user, :name
104
133
  assert_no_select 'div#custom_wrapper_without_class[class]'
@@ -128,6 +157,21 @@ class WrapperTest < ActionView::TestCase
128
157
  end
129
158
  end
130
159
 
160
+ test 'custom wrappers can have additional attributes' do
161
+ swap_wrapper :default, custom_wrapper_with_additional_attributes do
162
+ with_form_for @user, :name
163
+
164
+ assert_select "div.custom_wrapper[title='some title'][data-wrapper='test']"
165
+ end
166
+ end
167
+
168
+ test 'custom wrappers can have full error message on attributes' do
169
+ swap_wrapper :default, custom_wrapper_with_full_error do
170
+ with_form_for @user, :name
171
+ assert_select 'span.error', "Super User Name! cannot be blank"
172
+ end
173
+ end
174
+
131
175
  test 'custom wrappers on a form basis' do
132
176
  swap_wrapper :another do
133
177
  with_concat_form_for(@user) do |f|
@@ -172,8 +216,8 @@ class WrapperTest < ActionView::TestCase
172
216
  end
173
217
  end
174
218
 
175
- test 'do not duplicate label classes for different inputs' do
176
- swap_wrapper :default, self.custom_wrapper_with_label_html_option do
219
+ test 'does not duplicate label classes for different inputs' do
220
+ swap_wrapper :default, custom_wrapper_with_label_html_option do
177
221
  with_concat_form_for(@user) do |f|
178
222
  concat f.input :name, required: false
179
223
  concat f.input :email, as: :email, required: true
@@ -191,7 +235,7 @@ class WrapperTest < ActionView::TestCase
191
235
  end
192
236
  end
193
237
 
194
- test 'use wrapper for specified in config mapping' do
238
+ test 'uses wrapper for specified in config mapping' do
195
239
  swap_wrapper :another do
196
240
  swap SimpleForm, wrapper_mappings: { string: :another } do
197
241
  with_form_for @user, :name
@@ -200,4 +244,135 @@ class WrapperTest < ActionView::TestCase
200
244
  end
201
245
  end
202
246
  end
247
+
248
+ test 'uses custom wrapper mapping per form basis' do
249
+ swap_wrapper :another do
250
+ with_concat_form_for @user, wrapper_mappings: { string: :another } do |f|
251
+ concat f.input :name
252
+ end
253
+ end
254
+
255
+ assert_select "section.custom_wrapper div.another_wrapper label"
256
+ assert_select "section.custom_wrapper div.another_wrapper input.string"
257
+ end
258
+
259
+ test 'simple_fields_form reuses custom wrapper mapping per form basis' do
260
+ @user.company = Company.new(1, 'Empresa')
261
+
262
+ swap_wrapper :another do
263
+ with_concat_form_for @user, wrapper_mappings: { string: :another } do |f|
264
+ concat(f.simple_fields_for(:company) do |company_form|
265
+ concat(company_form.input(:name))
266
+ end)
267
+ end
268
+ end
269
+
270
+ assert_select "section.custom_wrapper div.another_wrapper label"
271
+ assert_select "section.custom_wrapper div.another_wrapper input.string"
272
+ end
273
+
274
+ test "input attributes class will merge with wrapper_options' classes" do
275
+ swap_wrapper :default, custom_wrapper_with_input_class do
276
+ with_concat_form_for @user do |f|
277
+ concat f.input :name, input_html: { class: 'another-class' }
278
+ end
279
+ end
280
+
281
+ assert_select "div.custom_wrapper input.string.inline-class.another-class"
282
+ end
283
+
284
+ test "input with data attributes will merge with wrapper_options' data" do
285
+ swap_wrapper :default, custom_wrapper_with_input_data_modal do
286
+ with_concat_form_for @user do |f|
287
+ concat f.input :name, input_html: { data: { modal: 'another-data', target: 'merge-data' } }
288
+ end
289
+ end
290
+
291
+ assert_select "input[data-wrapper='data-wrapper'][data-modal='another-data'][data-target='merge-data']"
292
+ end
293
+
294
+ test "input with aria attributes will merge with wrapper_options' aria" do
295
+ swap_wrapper :default, custom_wrapper_with_input_aria_modal do
296
+ with_concat_form_for @user do |f|
297
+ concat f.input :name, input_html: { aria: { modal: 'another-aria', target: 'merge-aria' } }
298
+ end
299
+ end
300
+
301
+ assert_select "input[aria-wrapper='aria-wrapper'][aria-modal='another-aria'][aria-target='merge-aria']"
302
+ end
303
+
304
+ test 'input accepts attributes in the DSL' do
305
+ swap_wrapper :default, custom_wrapper_with_input_class do
306
+ with_concat_form_for @user do |f|
307
+ concat f.input :name
308
+ end
309
+ end
310
+
311
+ assert_select "div.custom_wrapper input.string.inline-class"
312
+ end
313
+
314
+ test 'label accepts attributes in the DSL' do
315
+ swap_wrapper :default, custom_wrapper_with_label_class do
316
+ with_concat_form_for @user do |f|
317
+ concat f.input :name
318
+ end
319
+ end
320
+
321
+ assert_select "div.custom_wrapper label.string.inline-class"
322
+ end
323
+
324
+ test 'label_input accepts attributes in the DSL' do
325
+ swap_wrapper :default, custom_wrapper_with_label_input_class do
326
+ with_concat_form_for @user do |f|
327
+ concat f.input :name
328
+ end
329
+ end
330
+
331
+ assert_select "div.custom_wrapper label.string.inline-class"
332
+ assert_select "div.custom_wrapper input.string.inline-class"
333
+ end
334
+
335
+ test 'input accepts data attributes in the DSL' do
336
+ swap_wrapper :default, custom_wrapper_with_input_attributes do
337
+ with_concat_form_for @user do |f|
338
+ concat f.input :name
339
+ end
340
+ end
341
+
342
+ assert_select "div.custom_wrapper input.string[data-modal=true]"
343
+ end
344
+
345
+ test 'inline wrapper displays when there is content' do
346
+ swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do
347
+ with_form_for @user, :name, hint: "cannot be blank"
348
+ assert_select 'section.custom_wrapper div.no_output_wrapper p.omg_hint', "cannot be blank"
349
+ assert_select 'p.omg_hint'
350
+ end
351
+ end
352
+
353
+ test 'inline wrapper does not display when there is no content' do
354
+ swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do
355
+ with_form_for @user, :name
356
+ assert_select 'section.custom_wrapper div.no_output_wrapper'
357
+ assert_no_select 'p.omg_hint'
358
+ end
359
+ end
360
+
361
+ test 'optional wrapper does not display when there is content' do
362
+ swap_wrapper :default, custom_wrapper_with_unless_blank do
363
+ with_form_for @user, :name, hint: "can't be blank"
364
+ assert_select 'section.custom_wrapper div.no_output_wrapper'
365
+ assert_select 'div.no_output_wrapper'
366
+ assert_select 'p.omg_hint'
367
+ end
368
+ end
369
+
370
+ test 'optional wrapper does not display when there is no content' do
371
+ swap_wrapper :default, custom_wrapper_with_unless_blank do
372
+ with_form_for @user, :name
373
+ assert_no_select 'section.custom_wrapper div.no_output_wrapper'
374
+ assert_no_select 'div.no_output_wrapper'
375
+ assert_no_select 'p.omg_hint'
376
+ end
377
+ end
203
378
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class SimpleFormGeneratorTest < Rails::Generators::TestCase
@@ -18,22 +19,22 @@ 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
- assert_file 'config/initializers/simple_form_bootstrap.rb', /config\.wrappers :bootstrap/,
25
- /config\.default_wrapper = :bootstrap/
25
+ assert_file 'config/initializers/simple_form_bootstrap.rb', /config\.wrappers :vertical_form/,
26
+ /config\.wrappers :horizontal_form/, /config\.default_wrapper = :vertical_form/
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
- assert_file 'config/initializers/simple_form_foundation.rb', /config\.wrappers :foundation/,
33
- /config\.default_wrapper = :foundation/
33
+ assert_file 'config/initializers/simple_form_foundation.rb', /config\.wrappers :vertical_form/,
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,8 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: UTF-8
2
3
  require 'test_helper'
3
4
 
4
5
  class BooleanInputTest < ActionView::TestCase
5
- test 'input should generate a checkbox by default for boolean attributes' do
6
+ test 'input generates a checkbox by default for boolean attributes' do
6
7
  with_input_for @user, :active, :boolean
7
8
  assert_select 'input[type=checkbox].boolean#user_active'
8
9
  assert_select 'label.boolean.optional', 'Active'
@@ -49,15 +50,43 @@ class BooleanInputTest < ActionView::TestCase
49
50
 
50
51
  test 'input boolean with nested allows :inline_label' do
51
52
  swap SimpleForm, boolean_style: :nested do
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
+ with_input_for @user, :active, :boolean, inline_label: 'I am so inline.'
54
+ assert_select 'label.checkbox', text: ' I am so inline.'
55
+ end
56
+ end
57
+
58
+ test 'input boolean with nested escapes :inline_label with HTML' do
59
+ swap SimpleForm, boolean_style: :nested do
60
+ with_input_for @user, :active, :boolean, inline_label: '<b>I am so inline.</b>'
61
+ assert_no_select 'label.checkbox b'
62
+ end
63
+ end
64
+
65
+ test 'input boolean with nested allows :inline_label with HTML when safe' do
66
+ swap SimpleForm, boolean_style: :nested do
67
+ with_input_for @user, :active, :boolean, inline_label: '<b>I am so inline.</b>'.html_safe
68
+ assert_select 'label.checkbox b', text: 'I am so inline.'
54
69
  end
55
70
  end
56
71
 
57
72
  test 'input boolean with nested style creates an inline label using the default label text when inline_label option set to true' do
58
73
  swap SimpleForm, boolean_style: :nested do
59
- with_input_for @user, :active, :boolean, label: false, inline_label: true
60
- assert_select 'label.checkbox', text: 'Active'
74
+ with_input_for @user, :active, :boolean, inline_label: true
75
+ assert_select 'label.checkbox', text: ' Active'
76
+ end
77
+ end
78
+
79
+ test 'input boolean with nested style creates an inline label using the label text when inline_label option set to true' do
80
+ swap SimpleForm, boolean_style: :nested do
81
+ with_input_for @user, :active, :boolean, inline_label: true, label_text: proc { 'New Active' }
82
+ assert_select 'label.checkbox', text: ' New Active'
83
+ end
84
+ end
85
+
86
+ test 'input boolean with nested style creates an inline label using the label html when inline_label option set to true' do
87
+ swap SimpleForm, boolean_style: :nested do
88
+ with_input_for @user, :active, :boolean, inline_label: true, label_text: proc { '<b>New Active</b>' }
89
+ assert_select 'label.checkbox', text: ' New Active'
61
90
  end
62
91
  end
63
92
 
@@ -78,6 +107,14 @@ class BooleanInputTest < ActionView::TestCase
78
107
  end
79
108
  end
80
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
+
81
118
  test 'input accepts changing boolean style to nested through given options' do
82
119
  with_input_for @user, :active, :boolean, boolean_style: :nested
83
120
  assert_select 'label[for=user_active]', 'Active'
@@ -109,6 +146,22 @@ class BooleanInputTest < ActionView::TestCase
109
146
  end
110
147
  end
111
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
+
112
165
  test 'input boolean works using :input only in wrapper config (no label_input)' do
113
166
  swap_wrapper do
114
167
  with_input_for @user, :active, :boolean
@@ -128,6 +181,26 @@ class BooleanInputTest < ActionView::TestCase
128
181
  end
129
182
  end
130
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
+
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
195
+ swap_wrapper do
196
+ swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
197
+ with_input_for @user, :active, :boolean
198
+
199
+ assert_select 'label.boolean + input[type=hidden] + label.foo > input.boolean'
200
+ end
201
+ end
202
+ end
203
+
131
204
  test 'input boolean with nested style works using :label_input in wrapper config, adding "checkbox" class to label' do
132
205
  swap_wrapper :default, self.custom_wrapper_without_top_level do
133
206
  swap SimpleForm, boolean_style: :nested do
@@ -138,7 +211,17 @@ class BooleanInputTest < ActionView::TestCase
138
211
  end
139
212
  end
140
213
 
141
- test 'input boolean without additional classes should add "checkbox" class to label' do
214
+ test 'input boolean with nested style works using :label_input in wrapper config, adding custom class to label' do
215
+ swap_wrapper :default, self.custom_wrapper_without_top_level do
216
+ swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
217
+ with_input_for @user, :active, :boolean
218
+
219
+ assert_select 'input[type=hidden] + label.boolean.foo > input.boolean'
220
+ end
221
+ end
222
+ end
223
+
224
+ test 'input boolean without additional classes adds "checkbox" class to label' do
142
225
  swap_wrapper :default, self.custom_wrapper_without_top_level do
143
226
  swap SimpleForm, boolean_style: :nested, generate_additional_classes_for: [:input] do
144
227
  with_input_for @user, :active, :boolean
@@ -149,4 +232,12 @@ class BooleanInputTest < ActionView::TestCase
149
232
  end
150
233
  end
151
234
  end
235
+
236
+ test 'input boolean works with wrapper config defining a class for the input' do
237
+ swap_wrapper :default, self.custom_wrapper_with_input_class do
238
+ with_input_for @user, :active, :boolean
239
+
240
+ assert_select 'input.boolean.inline-class'
241
+ end
242
+ end
152
243
  end