simple_form 2.0.0 → 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +97 -198
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +572 -296
  5. data/lib/generators/simple_form/install_generator.rb +17 -7
  6. data/lib/generators/simple_form/templates/README +3 -4
  7. data/lib/generators/simple_form/templates/_form.html.erb +1 -0
  8. data/lib/generators/simple_form/templates/_form.html.haml +1 -0
  9. data/lib/generators/simple_form/templates/config/initializers/{simple_form.rb.tt → simple_form.rb} +57 -63
  10. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +155 -0
  11. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +111 -0
  12. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +14 -7
  13. data/lib/simple_form/action_view_extensions/builder.rb +5 -305
  14. data/lib/simple_form/action_view_extensions/form_helper.rb +18 -20
  15. data/lib/simple_form/components/errors.rb +30 -3
  16. data/lib/simple_form/components/hints.rb +10 -3
  17. data/lib/simple_form/components/html5.rb +17 -3
  18. data/lib/simple_form/components/label_input.rb +21 -2
  19. data/lib/simple_form/components/labels.rb +16 -11
  20. data/lib/simple_form/components/maxlength.rb +19 -12
  21. data/lib/simple_form/components/min_max.rb +4 -2
  22. data/lib/simple_form/components/minlength.rb +48 -0
  23. data/lib/simple_form/components/pattern.rb +5 -4
  24. data/lib/simple_form/components/placeholders.rb +3 -2
  25. data/lib/simple_form/components/readonly.rb +3 -2
  26. data/lib/simple_form/components.rb +15 -11
  27. data/lib/simple_form/error_notification.rb +4 -3
  28. data/lib/simple_form/form_builder.rb +283 -105
  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 +4 -3
  34. data/lib/simple_form/helpers.rb +7 -6
  35. data/lib/simple_form/i18n_cache.rb +1 -0
  36. data/lib/simple_form/inputs/base.rb +76 -23
  37. data/lib/simple_form/inputs/block_input.rb +3 -2
  38. data/lib/simple_form/inputs/boolean_input.rb +55 -16
  39. data/lib/simple_form/inputs/collection_check_boxes_input.rb +2 -1
  40. data/lib/simple_form/inputs/collection_input.rb +41 -18
  41. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +11 -19
  42. data/lib/simple_form/inputs/collection_select_input.rb +5 -2
  43. data/lib/simple_form/inputs/date_time_input.rb +23 -12
  44. data/lib/simple_form/inputs/file_input.rb +5 -2
  45. data/lib/simple_form/inputs/grouped_collection_select_input.rb +16 -3
  46. data/lib/simple_form/inputs/hidden_input.rb +5 -2
  47. data/lib/simple_form/inputs/numeric_input.rb +4 -8
  48. data/lib/simple_form/inputs/password_input.rb +6 -4
  49. data/lib/simple_form/inputs/priority_input.rb +5 -2
  50. data/lib/simple_form/inputs/range_input.rb +2 -1
  51. data/lib/simple_form/inputs/string_input.rb +6 -4
  52. data/lib/simple_form/inputs/text_input.rb +6 -3
  53. data/lib/simple_form/inputs.rb +20 -17
  54. data/lib/simple_form/map_type.rb +1 -0
  55. data/lib/simple_form/railtie.rb +15 -0
  56. data/lib/simple_form/tags.rb +69 -0
  57. data/lib/simple_form/version.rb +2 -1
  58. data/lib/simple_form/wrappers/builder.rb +12 -35
  59. data/lib/simple_form/wrappers/leaf.rb +29 -0
  60. data/lib/simple_form/wrappers/many.rb +12 -7
  61. data/lib/simple_form/wrappers/root.rb +7 -4
  62. data/lib/simple_form/wrappers/single.rb +12 -3
  63. data/lib/simple_form/wrappers.rb +3 -1
  64. data/lib/simple_form.rb +118 -63
  65. data/test/action_view_extensions/builder_test.rb +230 -164
  66. data/test/action_view_extensions/form_helper_test.rb +107 -39
  67. data/test/components/label_test.rb +105 -87
  68. data/test/form_builder/association_test.rb +131 -62
  69. data/test/form_builder/button_test.rb +15 -14
  70. data/test/form_builder/error_notification_test.rb +11 -10
  71. data/test/form_builder/error_test.rb +188 -34
  72. data/test/form_builder/general_test.rb +247 -102
  73. data/test/form_builder/hint_test.rb +59 -32
  74. data/test/form_builder/input_field_test.rb +138 -25
  75. data/test/form_builder/label_test.rb +84 -13
  76. data/test/form_builder/wrapper_test.rb +236 -33
  77. data/test/generators/simple_form_generator_test.rb +15 -4
  78. data/test/inputs/boolean_input_test.rb +147 -13
  79. data/test/inputs/collection_check_boxes_input_test.rb +166 -71
  80. data/test/inputs/collection_radio_buttons_input_test.rb +229 -113
  81. data/test/inputs/collection_select_input_test.rb +222 -85
  82. data/test/inputs/datetime_input_test.rb +134 -47
  83. data/test/inputs/disabled_test.rb +62 -21
  84. data/test/inputs/discovery_test.rb +70 -10
  85. data/test/inputs/file_input_test.rb +4 -3
  86. data/test/inputs/general_test.rb +90 -26
  87. data/test/inputs/grouped_collection_select_input_test.rb +88 -23
  88. data/test/inputs/hidden_input_test.rb +7 -5
  89. data/test/inputs/numeric_input_test.rb +56 -46
  90. data/test/inputs/priority_input_test.rb +31 -16
  91. data/test/inputs/readonly_test.rb +68 -27
  92. data/test/inputs/required_test.rb +63 -18
  93. data/test/inputs/string_input_test.rb +76 -51
  94. data/test/inputs/text_input_test.rb +21 -8
  95. data/test/simple_form_test.rb +9 -0
  96. data/test/support/discovery_inputs.rb +39 -2
  97. data/test/support/misc_helpers.rb +176 -20
  98. data/test/support/mock_controller.rb +13 -7
  99. data/test/support/models.rb +187 -71
  100. data/test/test_helper.rb +38 -39
  101. metadata +53 -39
  102. data/lib/simple_form/core_ext/hash.rb +0 -16
  103. data/test/support/mock_response.rb +0 -14
@@ -1,77 +1,109 @@
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 error class for attribute with errors' do
15
+ test 'wrapper adds the attribute name class' do
16
+ with_form_for @user, :name
17
+ assert_select 'div.user_name'
18
+ end
19
+
20
+ test 'wrapper adds the attribute name class for nested forms' do
21
+ @user.company = Company.new(1, 'Empresa')
22
+ with_concat_form_for @user do |f|
23
+ concat(f.simple_fields_for(:company) do |company_form|
24
+ concat(company_form.input :name)
25
+ end)
26
+ end
27
+
28
+ assert_select 'div.user_company_name'
29
+ end
30
+
31
+ test 'wrapper adds the association name class' do
32
+ with_form_for @user, :company
33
+ assert_select 'div.user_company'
34
+ end
35
+
36
+ test 'wrapper adds error class for attribute with errors' do
15
37
  with_form_for @user, :name
16
38
  assert_select 'div.field_with_errors'
17
39
  end
18
40
 
19
- test 'wrapper should add hint class for attribute with a hint' do
20
- with_form_for @user, :name, :hint => 'hint'
41
+ test 'wrapper adds hint class for attribute with a hint' do
42
+ with_form_for @user, :name, hint: 'hint'
21
43
  assert_select 'div.field_with_hint'
22
44
  end
23
45
 
24
- test 'wrapper should not have disabled class by default' do
46
+ test 'wrapper does not have disabled class by default' do
25
47
  with_form_for @user, :active
26
48
  assert_no_select 'div.disabled'
27
49
  end
28
50
 
29
- test 'wrapper should have disabled class when input is disabled' do
30
- with_form_for @user, :active, :disabled => true
51
+ test 'wrapper has disabled class when input is disabled' do
52
+ with_form_for @user, :active, disabled: true
31
53
  assert_select 'div.disabled'
32
54
  end
33
55
 
34
- test 'wrapper should support no wrapping when wrapper is false' do
35
- with_form_for @user, :name, :wrapper => false
56
+ test 'wrapper supports no wrapping when wrapper is false' do
57
+ with_form_for @user, :name, wrapper: false
36
58
  assert_select 'form > label[for=user_name]'
37
59
  assert_select 'form > input#user_name.string'
38
60
  end
39
61
 
40
- test 'wrapper should support no wrapping when wrapper tag is false' do
41
- with_form_for @user, :name, :wrapper => custom_wrapper_without_top_level
62
+ test 'wrapper supports no wrapping when wrapper tag is false' do
63
+ with_form_for @user, :name, wrapper: custom_wrapper_without_top_level
42
64
  assert_select 'form > label[for=user_name]'
43
65
  assert_select 'form > input#user_name.string'
44
66
  end
45
67
 
46
- test 'wrapper should wrapping tag adds required/optional css classes' do
68
+ test 'wrapper wraps tag adds required/optional css classes' do
47
69
  with_form_for @user, :name
48
70
  assert_select 'form div.input.required.string'
49
71
 
50
- with_form_for @user, :age, :required => false
72
+ with_form_for @user, :age, required: false
51
73
  assert_select 'form div.input.optional.integer'
52
74
  end
53
75
 
54
- test 'wrapper should allow custom options to be given' do
55
- with_form_for @user, :name, :wrapper_html => { :id => "super_cool", :class => 'yay' }
76
+ test 'wrapper allows custom options to be given' do
77
+ with_form_for @user, :name, wrapper_html: { id: "super_cool", class: 'yay' }
56
78
  assert_select 'form #super_cool.required.string.yay'
57
79
  end
58
80
 
59
- test 'wrapper should allow tag to be given on demand' do
60
- with_form_for @user, :name, :wrapper_tag => :b
81
+ test 'wrapper allows tag to be given on demand' do
82
+ with_form_for @user, :name, wrapper_tag: :b
61
83
  assert_select 'form b.required.string'
62
84
  end
63
85
 
64
- test 'wrapper should allow wrapper class to be given on demand' do
65
- with_form_for @user, :name, :wrapper_class => :wrapper
86
+ test 'wrapper allows wrapper class to be given on demand' do
87
+ with_form_for @user, :name, wrapper_class: :wrapper
66
88
  assert_select 'form div.wrapper.required.string'
67
89
  end
68
90
 
69
- test 'wrapper should skip additional classes when configured' do
70
- swap SimpleForm, :generate_additional_classes_for => [:input, :label] do
71
- with_form_for @user, :name, :wrapper_class => :wrapper
91
+ test 'wrapper skips additional classes when configured' do
92
+ swap SimpleForm, generate_additional_classes_for: %i[input label] do
93
+ with_form_for @user, :name, wrapper_class: :wrapper
72
94
  assert_select 'form div.wrapper'
73
95
  assert_no_select 'div.required'
74
96
  assert_no_select 'div.string'
97
+ assert_no_select 'div.user_name'
98
+ end
99
+ end
100
+
101
+ test 'wrapper does not generate empty css class' do
102
+ swap SimpleForm, generate_additional_classes_for: %i[input label] do
103
+ swap_wrapper :default, custom_wrapper_without_class do
104
+ with_form_for @user, :name
105
+ assert_no_select 'div#custom_wrapper_without_class[class]'
106
+ end
75
107
  end
76
108
  end
77
109
 
@@ -79,7 +111,7 @@ class WrapperTest < ActionView::TestCase
79
111
 
80
112
  test 'custom wrappers works' do
81
113
  swap_wrapper do
82
- with_form_for @user, :name, :hint => "cool"
114
+ with_form_for @user, :name, hint: "cool"
83
115
  assert_select "section.custom_wrapper div.another_wrapper label"
84
116
  assert_select "section.custom_wrapper div.another_wrapper input.string"
85
117
  assert_no_select "section.custom_wrapper div.another_wrapper span.omg_error"
@@ -90,25 +122,40 @@ class WrapperTest < ActionView::TestCase
90
122
 
91
123
  test 'custom wrappers can be turned off' do
92
124
  swap_wrapper do
93
- with_form_for @user, :name, :another => false
125
+ with_form_for @user, :name, another: false
94
126
  assert_no_select "section.custom_wrapper div.another_wrapper label"
95
127
  assert_no_select "section.custom_wrapper div.another_wrapper input.string"
96
128
  assert_select "section.custom_wrapper div.error_wrapper span.omg_error"
97
129
  end
98
130
  end
99
131
 
132
+ test 'custom wrappers can have additional attributes' do
133
+ swap_wrapper :default, custom_wrapper_with_additional_attributes do
134
+ with_form_for @user, :name
135
+
136
+ assert_select "div.custom_wrapper[title='some title'][data-wrapper='test']"
137
+ end
138
+ end
139
+
140
+ test 'custom wrappers can have full error message on attributes' do
141
+ swap_wrapper :default, custom_wrapper_with_full_error do
142
+ with_form_for @user, :name
143
+ assert_select 'span.error', "Name cannot be blank"
144
+ end
145
+ end
146
+
100
147
  test 'custom wrappers on a form basis' do
101
148
  swap_wrapper :another do
102
- concat simple_form_for(@user) { |f|
149
+ with_concat_form_for(@user) do |f|
103
150
  f.input :name
104
- }
151
+ end
105
152
 
106
153
  assert_no_select "section.custom_wrapper div.another_wrapper label"
107
154
  assert_no_select "section.custom_wrapper div.another_wrapper input.string"
108
155
 
109
- concat simple_form_for(@user, :wrapper => :another) { |f|
156
+ with_concat_form_for(@user, wrapper: :another) do |f|
110
157
  f.input :name
111
- }
158
+ end
112
159
 
113
160
  assert_select "section.custom_wrapper div.another_wrapper label"
114
161
  assert_select "section.custom_wrapper div.another_wrapper input.string"
@@ -122,28 +169,184 @@ class WrapperTest < ActionView::TestCase
122
169
  assert_no_select "section.custom_wrapper div.another_wrapper input.string"
123
170
  output_buffer.replace ""
124
171
 
125
- with_form_for @user, :name, :wrapper => :another
172
+ with_form_for @user, :name, wrapper: :another
126
173
  assert_select "section.custom_wrapper div.another_wrapper label"
127
174
  assert_select "section.custom_wrapper div.another_wrapper input.string"
128
175
  output_buffer.replace ""
129
176
  end
130
177
 
131
- with_form_for @user, :name, :wrapper => custom_wrapper
178
+ with_form_for @user, :name, wrapper: custom_wrapper
132
179
  assert_select "section.custom_wrapper div.another_wrapper label"
133
180
  assert_select "section.custom_wrapper div.another_wrapper input.string"
134
181
  end
135
182
 
136
183
  test 'access wrappers with indifferent access' do
137
184
  swap_wrapper :another do
138
- with_form_for @user, :name, :wrapper => "another"
185
+ with_form_for @user, :name, wrapper: "another"
139
186
  assert_select "section.custom_wrapper div.another_wrapper label"
140
187
  assert_select "section.custom_wrapper div.another_wrapper input.string"
141
188
  end
142
189
  end
143
190
 
191
+ test 'does not duplicate label classes for different inputs' do
192
+ swap_wrapper :default, custom_wrapper_with_label_html_option do
193
+ with_concat_form_for(@user) do |f|
194
+ concat f.input :name, required: false
195
+ concat f.input :email, as: :email, required: true
196
+ end
197
+
198
+ assert_select "label.string.optional.extra-label-class[for='user_name']"
199
+ assert_select "label.email.required.extra-label-class[for='user_email']"
200
+ assert_no_select "label.string.optional.extra-label-class[for='user_email']"
201
+ end
202
+ end
203
+
144
204
  test 'raise error when wrapper not found' do
145
205
  assert_raise SimpleForm::WrapperNotFound do
146
- with_form_for @user, :name, :wrapper => :not_found
206
+ with_form_for @user, :name, wrapper: :not_found
207
+ end
208
+ end
209
+
210
+ test 'uses wrapper for specified in config mapping' do
211
+ swap_wrapper :another do
212
+ swap SimpleForm, wrapper_mappings: { string: :another } do
213
+ with_form_for @user, :name
214
+ assert_select "section.custom_wrapper div.another_wrapper label"
215
+ assert_select "section.custom_wrapper div.another_wrapper input.string"
216
+ end
217
+ end
218
+ end
219
+
220
+ test 'uses custom wrapper mapping per form basis' do
221
+ swap_wrapper :another do
222
+ with_concat_form_for @user, wrapper_mappings: { string: :another } do |f|
223
+ concat f.input :name
224
+ end
225
+ end
226
+
227
+ assert_select "section.custom_wrapper div.another_wrapper label"
228
+ assert_select "section.custom_wrapper div.another_wrapper input.string"
229
+ end
230
+
231
+ test 'simple_fields_form reuses custom wrapper mapping per form basis' do
232
+ @user.company = Company.new(1, 'Empresa')
233
+
234
+ swap_wrapper :another do
235
+ with_concat_form_for @user, wrapper_mappings: { string: :another } do |f|
236
+ concat(f.simple_fields_for(:company) do |company_form|
237
+ concat(company_form.input(:name))
238
+ end)
239
+ end
240
+ end
241
+
242
+ assert_select "section.custom_wrapper div.another_wrapper label"
243
+ assert_select "section.custom_wrapper div.another_wrapper input.string"
244
+ end
245
+
246
+ test "input attributes class will merge with wrapper_options' classes" do
247
+ swap_wrapper :default, custom_wrapper_with_input_class do
248
+ with_concat_form_for @user do |f|
249
+ concat f.input :name, input_html: { class: 'another-class' }
250
+ end
251
+ end
252
+
253
+ assert_select "div.custom_wrapper input.string.inline-class.another-class"
254
+ end
255
+
256
+ test "input with data attributes will merge with wrapper_options' data" do
257
+ swap_wrapper :default, custom_wrapper_with_input_data_modal do
258
+ with_concat_form_for @user do |f|
259
+ concat f.input :name, input_html: { data: { modal: 'another-data', target: 'merge-data' } }
260
+ end
261
+ end
262
+
263
+ assert_select "input[data-wrapper='data-wrapper'][data-modal='another-data'][data-target='merge-data']"
264
+ end
265
+
266
+ test "input with aria attributes will merge with wrapper_options' aria" do
267
+ skip unless ActionPack::VERSION::MAJOR == '4' && ActionPack::VERSION::MINOR >= '2'
268
+
269
+ swap_wrapper :default, custom_wrapper_with_input_aria_modal do
270
+ with_concat_form_for @user do |f|
271
+ concat f.input :name, input_html: { aria: { modal: 'another-aria', target: 'merge-aria' } }
272
+ end
273
+ end
274
+
275
+ assert_select "input[aria-wrapper='aria-wrapper'][aria-modal='another-aria'][aria-target='merge-aria']"
276
+ end
277
+
278
+ test 'input accepts attributes in the DSL' do
279
+ swap_wrapper :default, custom_wrapper_with_input_class do
280
+ with_concat_form_for @user do |f|
281
+ concat f.input :name
282
+ end
283
+ end
284
+
285
+ assert_select "div.custom_wrapper input.string.inline-class"
286
+ end
287
+
288
+ test 'label accepts attributes in the DSL' do
289
+ swap_wrapper :default, custom_wrapper_with_label_class do
290
+ with_concat_form_for @user do |f|
291
+ concat f.input :name
292
+ end
293
+ end
294
+
295
+ assert_select "div.custom_wrapper label.string.inline-class"
296
+ end
297
+
298
+ test 'label_input accepts attributes in the DSL' do
299
+ swap_wrapper :default, custom_wrapper_with_label_input_class do
300
+ with_concat_form_for @user do |f|
301
+ concat f.input :name
302
+ end
303
+ end
304
+
305
+ assert_select "div.custom_wrapper label.string.inline-class"
306
+ assert_select "div.custom_wrapper input.string.inline-class"
307
+ end
308
+
309
+ test 'input accepts data attributes in the DSL' do
310
+ swap_wrapper :default, custom_wrapper_with_input_attributes do
311
+ with_concat_form_for @user do |f|
312
+ concat f.input :name
313
+ end
314
+ end
315
+
316
+ assert_select "div.custom_wrapper input.string[data-modal=true]"
317
+ end
318
+
319
+ test 'inline wrapper displays when there is content' do
320
+ swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do
321
+ with_form_for @user, :name, hint: "cannot be blank"
322
+ assert_select 'section.custom_wrapper div.no_output_wrapper p.omg_hint', "cannot be blank"
323
+ assert_select 'p.omg_hint'
324
+ end
325
+ end
326
+
327
+ test 'inline wrapper does not display when there is no content' do
328
+ swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do
329
+ with_form_for @user, :name
330
+ assert_select 'section.custom_wrapper div.no_output_wrapper'
331
+ assert_no_select 'p.omg_hint'
332
+ end
333
+ end
334
+
335
+ test 'optional wrapper does not display when there is content' do
336
+ swap_wrapper :default, custom_wrapper_with_unless_blank do
337
+ with_form_for @user, :name, hint: "can't be blank"
338
+ assert_select 'section.custom_wrapper div.no_output_wrapper'
339
+ assert_select 'div.no_output_wrapper'
340
+ assert_select 'p.omg_hint'
341
+ end
342
+ end
343
+
344
+ test 'optional wrapper does not display when there is no content' do
345
+ swap_wrapper :default, custom_wrapper_with_unless_blank do
346
+ with_form_for @user, :name
347
+ assert_no_select 'section.custom_wrapper div.no_output_wrapper'
348
+ assert_no_select 'div.no_output_wrapper'
349
+ assert_no_select 'p.omg_hint'
147
350
  end
148
351
  end
149
352
  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,12 +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
- assert_file 'config/initializers/simple_form.rb', /config\.wrappers :bootstrap/,
23
- /config\.default_wrapper = :bootstrap/
22
+ run_generator %w[--bootstrap]
23
+ assert_file 'config/initializers/simple_form.rb',
24
+ /config\.default_wrapper = :default/, /config\.boolean_style = :nested/
25
+ assert_file 'config/initializers/simple_form_bootstrap.rb', /config\.wrappers :vertical_form/,
26
+ /config\.wrappers :horizontal_form/, /config\.default_wrapper = :vertical_form/
27
+ end
28
+
29
+ test 'generates the simple_form initializer with the foundation wrappers' do
30
+ run_generator %w[--foundation]
31
+ assert_file 'config/initializers/simple_form.rb',
32
+ /config\.default_wrapper = :default/, /config\.boolean_style = :nested/
33
+ assert_file 'config/initializers/simple_form_foundation.rb', /config\.wrappers :vertical_form/,
34
+ /config\.default_wrapper = :vertical_form/, /config\.item_wrapper_tag = :div/
24
35
  end
25
36
 
26
- %W(erb haml slim).each do |engine|
37
+ %w[erb haml slim].each do |engine|
27
38
  test "generates the scaffold template when using #{engine}" do
28
39
  run_generator ['-e', engine]
29
40
  assert_file "lib/templates/#{engine}/scaffold/_form.html.#{engine}"
@@ -1,19 +1,38 @@
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'
9
10
  end
10
11
 
11
12
  test 'input does not generate the label with the checkbox when label option is false' do
12
- with_input_for @user, :active, :boolean, :label => false
13
+ with_input_for @user, :active, :boolean, label: false
13
14
  assert_select 'input[type=checkbox].boolean#user_active'
14
15
  assert_no_select 'label'
15
16
  end
16
17
 
18
+ test 'input uses custom checked value' do
19
+ @user.action = 'on'
20
+ with_input_for @user, :action, :boolean, checked_value: 'on', unchecked_value: 'off'
21
+ assert_select 'input[type=checkbox][value=on][checked=checked]'
22
+ end
23
+
24
+ test 'input uses custom unchecked value' do
25
+ @user.action = 'off'
26
+ with_input_for @user, :action, :boolean, checked_value: 'on', unchecked_value: 'off'
27
+ assert_select 'input[type=checkbox][value=on]'
28
+ assert_no_select 'input[checked=checked][value=on]'
29
+ end
30
+
31
+ test 'input generates hidden input with custom unchecked value' do
32
+ with_input_for @user, :action, :boolean, checked_value: 'on', unchecked_value: 'off'
33
+ assert_select 'input[type=hidden][value=off]'
34
+ end
35
+
17
36
  test 'input uses inline boolean style by default' do
18
37
  with_input_for @user, :active, :boolean
19
38
  assert_select 'input.boolean + label.boolean.optional'
@@ -21,7 +40,7 @@ class BooleanInputTest < ActionView::TestCase
21
40
  end
22
41
 
23
42
  test 'input allows changing default boolean style config to nested, generating a default label and a manual hidden field for checkbox' do
24
- swap SimpleForm, :boolean_style => :nested do
43
+ swap SimpleForm, boolean_style: :nested do
25
44
  with_input_for @user, :active, :boolean
26
45
  assert_select 'label[for=user_active]', 'Active'
27
46
  assert_select 'label.boolean > input.boolean'
@@ -29,8 +48,50 @@ class BooleanInputTest < ActionView::TestCase
29
48
  end
30
49
  end
31
50
 
51
+ test 'input boolean with nested allows :inline_label' do
52
+ swap SimpleForm, boolean_style: :nested do
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.'
69
+ end
70
+ end
71
+
72
+ test 'input boolean with nested style creates an inline label using the default label text when inline_label option set to true' do
73
+ swap SimpleForm, boolean_style: :nested do
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'
90
+ end
91
+ end
92
+
32
93
  test 'input boolean with nested generates a manual hidden field for checkbox outside the label, to recreate Rails functionality with valid html5' do
33
- swap SimpleForm, :boolean_style => :nested do
94
+ swap SimpleForm, boolean_style: :nested do
34
95
  with_input_for @user, :active, :boolean
35
96
 
36
97
  assert_select "input[type=hidden][name='user[active]'] + label.boolean > input.boolean"
@@ -39,23 +100,23 @@ class BooleanInputTest < ActionView::TestCase
39
100
  end
40
101
 
41
102
  test 'input boolean with nested generates a disabled hidden field for checkbox outside the label, if the field is disabled' do
42
- swap SimpleForm, :boolean_style => :nested do
43
- with_input_for @user, :active, :boolean, :disabled => true
103
+ swap SimpleForm, boolean_style: :nested do
104
+ with_input_for @user, :active, :boolean, disabled: true
44
105
 
45
106
  assert_select "input[type=hidden][name='user[active]'][disabled] + label.boolean > input.boolean[disabled]"
46
107
  end
47
108
  end
48
109
 
49
110
  test 'input accepts changing boolean style to nested through given options' do
50
- with_input_for @user, :active, :boolean, :boolean_style => :nested
111
+ with_input_for @user, :active, :boolean, boolean_style: :nested
51
112
  assert_select 'label[for=user_active]', 'Active'
52
113
  assert_select 'label.boolean > input.boolean'
53
114
  assert_no_select 'input[type=checkbox] + label'
54
115
  end
55
116
 
56
117
  test 'input accepts changing boolean style to inline through given options, when default is nested' do
57
- swap SimpleForm, :boolean_style => :nested do
58
- with_input_for @user, :active, :boolean, :boolean_style => :inline
118
+ swap SimpleForm, boolean_style: :nested do
119
+ with_input_for @user, :active, :boolean, boolean_style: :inline
59
120
  assert_select 'label[for=user_active]', 'Active'
60
121
  assert_select 'input.boolean + label.boolean'
61
122
  assert_no_select 'label > input'
@@ -63,13 +124,36 @@ class BooleanInputTest < ActionView::TestCase
63
124
  end
64
125
 
65
126
  test 'input with nested style allows disabling label' do
66
- swap SimpleForm, :boolean_style => :nested do
67
- with_input_for @user, :active, :boolean, :label => false
127
+ swap SimpleForm, boolean_style: :nested do
128
+ with_input_for @user, :active, :boolean, label: false
68
129
  assert_select 'input.boolean'
69
130
  assert_no_select 'label.boolean'
70
131
  end
71
132
  end
72
133
 
134
+ test 'input with nested style allows customizing input_html' do
135
+ swap SimpleForm, boolean_style: :nested do
136
+ with_input_for @user, :active, :boolean, input_html: { name: 'active_user' }
137
+ assert_select "input[type=hidden][name=active_user] + label.boolean > input.boolean[name=active_user]"
138
+ end
139
+ end
140
+
141
+ test 'input with nested style allows disabling hidden field' do
142
+ swap SimpleForm, boolean_style: :nested do
143
+ with_input_for @user, :active, :boolean, include_hidden: false
144
+ assert_select "label.boolean > input.boolean"
145
+ assert_no_select "input[type=hidden] + label.boolean"
146
+ end
147
+ end
148
+
149
+ test 'input with nested style does not include hidden field when unchecked_value is false' do
150
+ swap SimpleForm, boolean_style: :nested do
151
+ with_input_for @user, :active, :boolean, unchecked_value: false
152
+ assert_select "label.boolean > input.boolean"
153
+ assert_no_select "input[type=hidden] + label.boolean"
154
+ end
155
+ end
156
+
73
157
  test 'input boolean works using :input only in wrapper config (no label_input)' do
74
158
  swap_wrapper do
75
159
  with_input_for @user, :active, :boolean
@@ -81,7 +165,7 @@ class BooleanInputTest < ActionView::TestCase
81
165
 
82
166
  test 'input boolean with nested style works using :input only in wrapper config (no label_input), adding the extra "checkbox" label wrapper' do
83
167
  swap_wrapper do
84
- swap SimpleForm, :boolean_style => :nested do
168
+ swap SimpleForm, boolean_style: :nested do
85
169
  with_input_for @user, :active, :boolean
86
170
 
87
171
  assert_select 'label.boolean + input[type=hidden] + label.checkbox > input.boolean'
@@ -89,13 +173,63 @@ class BooleanInputTest < ActionView::TestCase
89
173
  end
90
174
  end
91
175
 
176
+ test 'input boolean allows specifying boolean_label_class on a per-input basis' do
177
+ swap_wrapper do
178
+ swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
179
+ with_input_for @user, :active, :boolean, boolean_label_class: 'baz'
180
+
181
+ assert_select 'label.boolean + input[type=hidden] + label.baz > input.boolean'
182
+ end
183
+ end
184
+ end
185
+
186
+ 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
187
+ swap_wrapper do
188
+ swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
189
+ with_input_for @user, :active, :boolean
190
+
191
+ assert_select 'label.boolean + input[type=hidden] + label.foo > input.boolean'
192
+ end
193
+ end
194
+ end
195
+
92
196
  test 'input boolean with nested style works using :label_input in wrapper config, adding "checkbox" class to label' do
93
197
  swap_wrapper :default, self.custom_wrapper_without_top_level do
94
- swap SimpleForm, :boolean_style => :nested do
198
+ swap SimpleForm, boolean_style: :nested do
95
199
  with_input_for @user, :active, :boolean
96
200
 
97
201
  assert_select 'input[type=hidden] + label.boolean.checkbox > input.boolean'
98
202
  end
99
203
  end
100
204
  end
205
+
206
+ test 'input boolean with nested style works using :label_input in wrapper config, adding custom class to label' do
207
+ swap_wrapper :default, self.custom_wrapper_without_top_level do
208
+ swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
209
+ with_input_for @user, :active, :boolean
210
+
211
+ assert_select 'input[type=hidden] + label.boolean.foo > input.boolean'
212
+ end
213
+ end
214
+ end
215
+
216
+ test 'input boolean without additional classes adds "checkbox" class to label' do
217
+ swap_wrapper :default, self.custom_wrapper_without_top_level do
218
+ swap SimpleForm, boolean_style: :nested, generate_additional_classes_for: [:input] do
219
+ with_input_for @user, :active, :boolean
220
+
221
+ assert_select 'label'
222
+ assert_select 'label.checkbox'
223
+ assert_no_select 'label.boolean'
224
+ end
225
+ end
226
+ end
227
+
228
+ test 'input boolean works with wrapper config defining a class for the input' do
229
+ swap_wrapper :default, self.custom_wrapper_with_input_class do
230
+ with_input_for @user, :active, :boolean
231
+
232
+ assert_select 'input.boolean.inline-class'
233
+ end
234
+ end
101
235
  end