simple_form 3.0.4 → 5.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +199 -33
  3. data/MIT-LICENSE +2 -1
  4. data/README.md +453 -128
  5. data/lib/generators/simple_form/install_generator.rb +4 -3
  6. data/lib/generators/simple_form/templates/README +3 -5
  7. data/lib/generators/simple_form/templates/_form.html.erb +2 -0
  8. data/lib/generators/simple_form/templates/_form.html.haml +2 -0
  9. data/lib/generators/simple_form/templates/_form.html.slim +1 -0
  10. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +47 -16
  11. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +418 -23
  12. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +101 -5
  13. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -2
  14. data/lib/simple_form/action_view_extensions/builder.rb +2 -0
  15. data/lib/simple_form/action_view_extensions/form_helper.rb +10 -3
  16. data/lib/simple_form/components/errors.rb +39 -6
  17. data/lib/simple_form/components/hints.rb +3 -2
  18. data/lib/simple_form/components/html5.rb +16 -5
  19. data/lib/simple_form/components/label_input.rb +21 -2
  20. data/lib/simple_form/components/labels.rb +22 -11
  21. data/lib/simple_form/components/maxlength.rb +9 -5
  22. data/lib/simple_form/components/min_max.rb +2 -1
  23. data/lib/simple_form/components/minlength.rb +38 -0
  24. data/lib/simple_form/components/pattern.rb +2 -1
  25. data/lib/simple_form/components/placeholders.rb +4 -3
  26. data/lib/simple_form/components/readonly.rb +2 -1
  27. data/lib/simple_form/components.rb +2 -0
  28. data/lib/simple_form/error_notification.rb +1 -0
  29. data/lib/simple_form/form_builder.rb +220 -89
  30. data/lib/simple_form/helpers/autofocus.rb +1 -0
  31. data/lib/simple_form/helpers/disabled.rb +1 -0
  32. data/lib/simple_form/helpers/readonly.rb +1 -0
  33. data/lib/simple_form/helpers/required.rb +1 -0
  34. data/lib/simple_form/helpers/validators.rb +2 -1
  35. data/lib/simple_form/helpers.rb +6 -5
  36. data/lib/simple_form/i18n_cache.rb +1 -0
  37. data/lib/simple_form/inputs/base.rb +62 -16
  38. data/lib/simple_form/inputs/block_input.rb +2 -1
  39. data/lib/simple_form/inputs/boolean_input.rb +40 -16
  40. data/lib/simple_form/inputs/collection_check_boxes_input.rb +3 -2
  41. data/lib/simple_form/inputs/collection_input.rb +37 -14
  42. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +9 -13
  43. data/lib/simple_form/inputs/collection_select_input.rb +5 -2
  44. data/lib/simple_form/inputs/color_input.rb +14 -0
  45. data/lib/simple_form/inputs/date_time_input.rb +24 -9
  46. data/lib/simple_form/inputs/file_input.rb +5 -2
  47. data/lib/simple_form/inputs/grouped_collection_select_input.rb +16 -3
  48. data/lib/simple_form/inputs/hidden_input.rb +5 -2
  49. data/lib/simple_form/inputs/numeric_input.rb +6 -4
  50. data/lib/simple_form/inputs/password_input.rb +6 -3
  51. data/lib/simple_form/inputs/priority_input.rb +5 -6
  52. data/lib/simple_form/inputs/range_input.rb +2 -1
  53. data/lib/simple_form/inputs/rich_text_area_input.rb +12 -0
  54. data/lib/simple_form/inputs/string_input.rb +7 -4
  55. data/lib/simple_form/inputs/text_input.rb +6 -3
  56. data/lib/simple_form/inputs.rb +3 -0
  57. data/lib/simple_form/map_type.rb +1 -0
  58. data/lib/simple_form/railtie.rb +8 -0
  59. data/lib/simple_form/tags.rb +13 -2
  60. data/lib/simple_form/version.rb +2 -1
  61. data/lib/simple_form/wrappers/builder.rb +7 -6
  62. data/lib/simple_form/wrappers/leaf.rb +29 -0
  63. data/lib/simple_form/wrappers/many.rb +7 -6
  64. data/lib/simple_form/wrappers/root.rb +10 -3
  65. data/lib/simple_form/wrappers/single.rb +7 -4
  66. data/lib/simple_form/wrappers.rb +2 -0
  67. data/lib/simple_form.rb +137 -21
  68. data/test/action_view_extensions/builder_test.rb +64 -45
  69. data/test/action_view_extensions/form_helper_test.rb +36 -16
  70. data/test/components/custom_components_test.rb +62 -0
  71. data/test/components/label_test.rb +70 -41
  72. data/test/form_builder/association_test.rb +85 -37
  73. data/test/form_builder/button_test.rb +11 -10
  74. data/test/form_builder/error_notification_test.rb +2 -1
  75. data/test/form_builder/error_test.rb +146 -33
  76. data/test/form_builder/general_test.rb +183 -81
  77. data/test/form_builder/hint_test.rb +24 -18
  78. data/test/form_builder/input_field_test.rb +105 -75
  79. data/test/form_builder/label_test.rb +68 -13
  80. data/test/form_builder/wrapper_test.rb +197 -22
  81. data/test/generators/simple_form_generator_test.rb +8 -7
  82. data/test/inputs/boolean_input_test.rb +97 -6
  83. data/test/inputs/collection_check_boxes_input_test.rb +117 -25
  84. data/test/inputs/collection_radio_buttons_input_test.rb +176 -54
  85. data/test/inputs/collection_select_input_test.rb +189 -77
  86. data/test/inputs/color_input_test.rb +10 -0
  87. data/test/inputs/datetime_input_test.rb +121 -50
  88. data/test/inputs/disabled_test.rb +29 -15
  89. data/test/inputs/discovery_test.rb +79 -6
  90. data/test/inputs/file_input_test.rb +3 -2
  91. data/test/inputs/general_test.rb +23 -22
  92. data/test/inputs/grouped_collection_select_input_test.rb +54 -17
  93. data/test/inputs/hidden_input_test.rb +5 -4
  94. data/test/inputs/numeric_input_test.rb +48 -44
  95. data/test/inputs/priority_input_test.rb +17 -16
  96. data/test/inputs/readonly_test.rb +20 -19
  97. data/test/inputs/required_test.rb +58 -13
  98. data/test/inputs/rich_text_area_input_test.rb +15 -0
  99. data/test/inputs/string_input_test.rb +58 -36
  100. data/test/inputs/text_input_test.rb +20 -7
  101. data/test/simple_form_test.rb +9 -0
  102. data/test/support/discovery_inputs.rb +40 -2
  103. data/test/support/misc_helpers.rb +113 -5
  104. data/test/support/mock_controller.rb +7 -1
  105. data/test/support/models.rb +162 -39
  106. data/test/test_helper.rb +19 -4
  107. metadata +51 -43
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class BuilderTest < ActionView::TestCase
@@ -8,13 +9,13 @@ class BuilderTest < ActionView::TestCase
8
9
  end
9
10
  end
10
11
 
11
- def with_collection_radio_buttons(object, attribute, collection, value_method, text_method, options={}, html_options={}, &block)
12
+ def with_collection_radio_buttons(object, attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)
12
13
  with_concat_form_for(object) do |f|
13
14
  f.collection_radio_buttons attribute, collection, value_method, text_method, options, html_options, &block
14
15
  end
15
16
  end
16
17
 
17
- def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options={}, html_options={}, &block)
18
+ def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)
18
19
  with_concat_form_for(object) do |f|
19
20
  f.collection_check_boxes attribute, collection, value_method, text_method, options, html_options, &block
20
21
  end
@@ -36,16 +37,25 @@ class BuilderTest < ActionView::TestCase
36
37
  end
37
38
 
38
39
  test "collection radio handles camelized collection values for labels correctly" do
39
- with_collection_radio_buttons @user, :active, ['Yes', 'No'], :to_s, :to_s
40
+ with_collection_radio_buttons @user, :active, %w[Yes No], :to_s, :to_s
40
41
 
41
42
  assert_select 'form label.collection_radio_buttons[for=user_active_yes]', 'Yes'
42
43
  assert_select 'form label.collection_radio_buttons[for=user_active_no]', 'No'
43
44
  end
44
45
 
45
- test "collection radio should sanitize collection values for labels correctly" do
46
+ test "collection radio sanitizes collection values for labels correctly" do
46
47
  with_collection_radio_buttons @user, :name, ['$0.99', '$1.99'], :to_s, :to_s
47
- assert_select 'label.collection_radio_buttons[for=user_name_099]', '$0.99'
48
- assert_select 'label.collection_radio_buttons[for=user_name_199]', '$1.99'
48
+
49
+ # Rails 6 changed the way it sanitizes the values
50
+ # https://github.com/rails/rails/blob/6-0-stable/actionview/lib/action_view/helpers/tags/base.rb#L141
51
+ # https://github.com/rails/rails/blob/5-2-stable/actionview/lib/action_view/helpers/tags/base.rb#L141
52
+ if ActionView::VERSION::MAJOR == 5
53
+ assert_select 'label.collection_radio_buttons[for=user_name_099]', '$0.99'
54
+ assert_select 'label.collection_radio_buttons[for=user_name_199]', '$1.99'
55
+ else
56
+ assert_select 'label.collection_radio_buttons[for=user_name_0_99]', '$0.99'
57
+ assert_select 'label.collection_radio_buttons[for=user_name_1_99]', '$1.99'
58
+ end
49
59
  end
50
60
 
51
61
  test "collection radio checks the correct value to local variables" do
@@ -243,7 +253,7 @@ class BuilderTest < ActionView::TestCase
243
253
 
244
254
  test "collection radio with block helpers does not leak the template" do
245
255
  with_concat_form_for(@user) do |f|
246
- collection_input = f.collection_radio_buttons :active, [true, false], :to_s, :to_s do |b|
256
+ collection_input = f.collection_radio_buttons :active, [true, false], :to_s, :to_s do |b|
247
257
  b.label(class: b.object) { b.radio_button + b.text }
248
258
  end
249
259
  concat collection_input
@@ -263,15 +273,15 @@ class BuilderTest < ActionView::TestCase
263
273
  collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
264
274
  with_collection_check_boxes @user, :tag_ids, collection, :id, :name
265
275
 
266
- assert_select 'form input#user_tag_ids_1[type=checkbox][value=1]'
267
- assert_select 'form input#user_tag_ids_2[type=checkbox][value=2]'
276
+ assert_select 'form input#user_tag_ids_1[type=checkbox][value="1"]'
277
+ assert_select 'form input#user_tag_ids_2[type=checkbox][value="2"]'
268
278
  end
269
279
 
270
280
  test "collection check box generates only one hidden field for the entire collection, to ensure something will be sent back to the server when posting an empty collection" do
271
281
  collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
272
282
  with_collection_check_boxes @user, :tag_ids, collection, :id, :name
273
283
 
274
- assert_select "form input[type=hidden][name='user[tag_ids][]'][value=]", count: 1
284
+ assert_select "form input[type=hidden][name='user[tag_ids][]'][value='']", count: 1
275
285
  end
276
286
 
277
287
  test "collection check box accepts a collection and generate a serie of checkboxes with labels for label method" do
@@ -283,16 +293,25 @@ class BuilderTest < ActionView::TestCase
283
293
  end
284
294
 
285
295
  test "collection check box handles camelized collection values for labels correctly" do
286
- with_collection_check_boxes @user, :active, ['Yes', 'No'], :to_s, :to_s
296
+ with_collection_check_boxes @user, :active, %w[Yes No], :to_s, :to_s
287
297
 
288
298
  assert_select 'form label.collection_check_boxes[for=user_active_yes]', 'Yes'
289
299
  assert_select 'form label.collection_check_boxes[for=user_active_no]', 'No'
290
300
  end
291
301
 
292
- test "collection check box should sanitize collection values for labels correctly" do
302
+ test "collection check box sanitizes collection values for labels correctly" do
293
303
  with_collection_check_boxes @user, :name, ['$0.99', '$1.99'], :to_s, :to_s
294
- assert_select 'label.collection_check_boxes[for=user_name_099]', '$0.99'
295
- assert_select 'label.collection_check_boxes[for=user_name_199]', '$1.99'
304
+
305
+ # Rails 6 changed the way it sanitizes the values
306
+ # https://github.com/rails/rails/blob/6-0-stable/actionview/lib/action_view/helpers/tags/base.rb#L141
307
+ # https://github.com/rails/rails/blob/5-2-stable/actionview/lib/action_view/helpers/tags/base.rb#L141
308
+ if ActionView::VERSION::MAJOR == 5
309
+ assert_select 'label.collection_check_boxes[for=user_name_099]', '$0.99'
310
+ assert_select 'label.collection_check_boxes[for=user_name_199]', '$1.99'
311
+ else
312
+ assert_select 'label.collection_check_boxes[for=user_name_0_99]', '$0.99'
313
+ assert_select 'label.collection_check_boxes[for=user_name_1_99]', '$1.99'
314
+ end
296
315
  end
297
316
 
298
317
  test "collection check box checks the correct value to local variables" do
@@ -301,36 +320,36 @@ class BuilderTest < ActionView::TestCase
301
320
 
302
321
  with_collection_check_boxes user, :tag_ids, collection, :first, :last
303
322
 
304
- assert_select 'form input[type=checkbox][value=1][checked=checked]'
305
- assert_select 'form input[type=checkbox][value=3][checked=checked]'
306
- assert_no_select 'form input[type=checkbox][value=2][checked=checked]'
323
+ assert_select 'form input[type=checkbox][value="1"][checked=checked]'
324
+ assert_select 'form input[type=checkbox][value="3"][checked=checked]'
325
+ assert_no_select 'form input[type=checkbox][value="2"][checked=checked]'
307
326
  end
308
327
 
309
328
  test "collection check box accepts selected values as :checked option" do
310
329
  collection = (1..3).map { |i| [i, "Tag #{i}"] }
311
330
  with_collection_check_boxes @user, :tag_ids, collection, :first, :last, checked: [1, 3]
312
331
 
313
- assert_select 'form input[type=checkbox][value=1][checked=checked]'
314
- assert_select 'form input[type=checkbox][value=3][checked=checked]'
315
- assert_no_select 'form input[type=checkbox][value=2][checked=checked]'
332
+ assert_select 'form input[type=checkbox][value="1"][checked=checked]'
333
+ assert_select 'form input[type=checkbox][value="3"][checked=checked]'
334
+ assert_no_select 'form input[type=checkbox][value="2"][checked=checked]'
316
335
  end
317
336
 
318
337
  test "collection check boxes accepts selected string values as :checked option" do
319
338
  collection = (1..3).map { |i| [i, "Category #{i}"] }
320
- with_collection_check_boxes :user, :category_ids, collection, :first, :last, checked: ['1', '3']
339
+ with_collection_check_boxes :user, :category_ids, collection, :first, :last, checked: %w[1 3]
321
340
 
322
- assert_select 'input[type=checkbox][value=1][checked=checked]'
323
- assert_select 'input[type=checkbox][value=3][checked=checked]'
324
- assert_no_select 'input[type=checkbox][value=2][checked=checked]'
341
+ assert_select 'input[type=checkbox][value="1"][checked=checked]'
342
+ assert_select 'input[type=checkbox][value="3"][checked=checked]'
343
+ assert_no_select 'input[type=checkbox][value="2"][checked=checked]'
325
344
  end
326
345
 
327
346
  test "collection check box accepts a single checked value" do
328
347
  collection = (1..3).map { |i| [i, "Tag #{i}"] }
329
348
  with_collection_check_boxes @user, :tag_ids, collection, :first, :last, checked: 3
330
349
 
331
- assert_select 'form input[type=checkbox][value=3][checked=checked]'
332
- assert_no_select 'form input[type=checkbox][value=1][checked=checked]'
333
- assert_no_select 'form input[type=checkbox][value=2][checked=checked]'
350
+ assert_select 'form input[type=checkbox][value="3"][checked=checked]'
351
+ assert_no_select 'form input[type=checkbox][value="1"][checked=checked]'
352
+ assert_no_select 'form input[type=checkbox][value="2"][checked=checked]'
334
353
  end
335
354
 
336
355
  test "collection check box accepts selected values as :checked option and override the model values" do
@@ -338,44 +357,44 @@ class BuilderTest < ActionView::TestCase
338
357
  @user.tag_ids = [2]
339
358
  with_collection_check_boxes @user, :tag_ids, collection, :first, :last, checked: [1, 3]
340
359
 
341
- assert_select 'form input[type=checkbox][value=1][checked=checked]'
342
- assert_select 'form input[type=checkbox][value=3][checked=checked]'
343
- assert_no_select 'form input[type=checkbox][value=2][checked=checked]'
360
+ assert_select 'form input[type=checkbox][value="1"][checked=checked]'
361
+ assert_select 'form input[type=checkbox][value="3"][checked=checked]'
362
+ assert_no_select 'form input[type=checkbox][value="2"][checked=checked]'
344
363
  end
345
364
 
346
365
  test "collection check box accepts multiple disabled items" do
347
366
  collection = (1..3).map { |i| [i, "Tag #{i}"] }
348
367
  with_collection_check_boxes @user, :tag_ids, collection, :first, :last, disabled: [1, 3]
349
368
 
350
- assert_select 'form input[type=checkbox][value=1][disabled=disabled]'
351
- assert_select 'form input[type=checkbox][value=3][disabled=disabled]'
352
- assert_no_select 'form input[type=checkbox][value=2][disabled=disabled]'
369
+ assert_select 'form input[type=checkbox][value="1"][disabled=disabled]'
370
+ assert_select 'form input[type=checkbox][value="3"][disabled=disabled]'
371
+ assert_no_select 'form input[type=checkbox][value="2"][disabled=disabled]'
353
372
  end
354
373
 
355
374
  test "collection check box accepts single disable item" do
356
375
  collection = (1..3).map { |i| [i, "Tag #{i}"] }
357
376
  with_collection_check_boxes @user, :tag_ids, collection, :first, :last, disabled: 1
358
377
 
359
- assert_select 'form input[type=checkbox][value=1][disabled=disabled]'
360
- assert_no_select 'form input[type=checkbox][value=3][disabled=disabled]'
361
- assert_no_select 'form input[type=checkbox][value=2][disabled=disabled]'
378
+ assert_select 'form input[type=checkbox][value="1"][disabled=disabled]'
379
+ assert_no_select 'form input[type=checkbox][value="3"][disabled=disabled]'
380
+ assert_no_select 'form input[type=checkbox][value="2"][disabled=disabled]'
362
381
  end
363
382
 
364
383
  test "collection check box accepts a proc to disabled items" do
365
384
  collection = (1..3).map { |i| [i, "Tag #{i}"] }
366
385
  with_collection_check_boxes @user, :tag_ids, collection, :first, :last, disabled: proc { |i| i.first == 1 }
367
386
 
368
- assert_select 'form input[type=checkbox][value=1][disabled=disabled]'
369
- assert_no_select 'form input[type=checkbox][value=3][disabled=disabled]'
370
- assert_no_select 'form input[type=checkbox][value=2][disabled=disabled]'
387
+ assert_select 'form input[type=checkbox][value="1"][disabled=disabled]'
388
+ assert_no_select 'form input[type=checkbox][value="3"][disabled=disabled]'
389
+ assert_no_select 'form input[type=checkbox][value="2"][disabled=disabled]'
371
390
  end
372
391
 
373
392
  test "collection check box accepts html options" do
374
393
  collection = [[1, 'Tag 1'], [2, 'Tag 2']]
375
394
  with_collection_check_boxes @user, :tag_ids, collection, :first, :last, {}, class: 'check'
376
395
 
377
- assert_select 'form input.check[type=checkbox][value=1]'
378
- assert_select 'form input.check[type=checkbox][value=2]'
396
+ assert_select 'form input.check[type=checkbox][value="1"]'
397
+ assert_select 'form input.check[type=checkbox][value="2"]'
379
398
  end
380
399
 
381
400
  test "collection check box with fields for" do
@@ -386,8 +405,8 @@ class BuilderTest < ActionView::TestCase
386
405
  end
387
406
  end
388
407
 
389
- assert_select 'form input#user_post_tag_ids_1[type=checkbox][value=1]'
390
- assert_select 'form input#user_post_tag_ids_2[type=checkbox][value=2]'
408
+ assert_select 'form input#user_post_tag_ids_1[type=checkbox][value="1"]'
409
+ assert_select 'form input#user_post_tag_ids_2[type=checkbox][value="2"]'
391
410
 
392
411
  assert_select 'form label.collection_check_boxes[for=user_post_tag_ids_1]', 'Tag 1'
393
412
  assert_select 'form label.collection_check_boxes[for=user_post_tag_ids_2]', 'Tag 2'
@@ -541,7 +560,7 @@ class BuilderTest < ActionView::TestCase
541
560
 
542
561
  test "collection check boxes with block helpers does not leak the template" do
543
562
  with_concat_form_for(@user) do |f|
544
- collection_input = f.collection_check_boxes :active, [true, false], :to_s, :to_s do |b|
563
+ collection_input = f.collection_check_boxes :active, [true, false], :to_s, :to_s do |b|
545
564
  b.label(class: b.object) { b.check_box + b.text }
546
565
  end
547
566
  concat collection_input
@@ -593,7 +612,7 @@ class BuilderTest < ActionView::TestCase
593
612
  end
594
613
  end
595
614
 
596
- test "fields inherites wrapper option from the parent form" do
615
+ test "fields inherits wrapper option from the parent form" do
597
616
  swap_wrapper :another do
598
617
  simple_form_for(:user, wrapper: :another) do |f|
599
618
  f.simple_fields_for(:company) do |company|
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class FormHelperTest < ActionView::TestCase
@@ -8,17 +9,36 @@ class FormHelperTest < ActionView::TestCase
8
9
  end
9
10
  end
10
11
 
11
- test 'SimpleForm should add default class to form' do
12
+ test 'SimpleForm adds default class to form' do
12
13
  with_concat_form_for(:user)
13
14
  assert_select 'form.simple_form'
14
15
  end
15
16
 
16
- test 'SimpleForm should use default browser validations by default' do
17
+ test 'SimpleForm allows overriding default form class' do
18
+ swap SimpleForm, default_form_class: "my_custom_class" do
19
+ with_concat_form_for :user, html: { class: "override_class" }
20
+ assert_no_select 'form.my_custom_class'
21
+ assert_select 'form.override_class'
22
+ end
23
+ end
24
+
25
+ # Remove this test when SimpleForm.form_class is removed in 4.x
26
+ test 'SimpleForm allows overriding default form class, but not form class' do
27
+ ActiveSupport::Deprecation.silence do
28
+ swap SimpleForm, form_class: "fixed_class", default_form_class: "my_custom_class" do
29
+ with_concat_form_for :user, html: { class: "override_class" }
30
+ assert_no_select 'form.my_custom_class'
31
+ assert_select 'form.fixed_class.override_class'
32
+ end
33
+ end
34
+ end
35
+
36
+ test 'SimpleForm uses default browser validations by default' do
17
37
  with_concat_form_for(:user)
18
38
  assert_no_select 'form[novalidate]'
19
39
  end
20
40
 
21
- test 'SimpleForm should not use default browser validations if specified in the configuration options' do
41
+ test 'SimpleForm does not use default browser validations if specified in the configuration options' do
22
42
  swap SimpleForm, browser_validations: false do
23
43
  with_concat_form_for(:user)
24
44
  assert_select 'form[novalidate="novalidate"]'
@@ -37,57 +57,57 @@ class FormHelperTest < ActionView::TestCase
37
57
  end
38
58
  end
39
59
 
40
- test 'SimpleForm should add object name as css class to form when object is not present' do
60
+ test 'SimpleForm adds object name as css class to form when object is not present' do
41
61
  with_concat_form_for(:user, html: { novalidate: true })
42
62
  assert_select 'form.simple_form.user'
43
63
  end
44
64
 
45
- test 'SimpleForm should add :as option as css class to form when object is not present' do
65
+ test 'SimpleForm adds :as option as css class to form when object is not present' do
46
66
  with_concat_form_for(:user, as: 'superuser')
47
67
  assert_select 'form.simple_form.superuser'
48
68
  end
49
69
 
50
- test 'SimpleForm should add object class name with new prefix as css class to form if record is not persisted' do
70
+ test 'SimpleForm adds object class name with new prefix as css class to form if record is not persisted' do
51
71
  @user.new_record!
52
72
  with_concat_form_for(@user)
53
73
  assert_select 'form.simple_form.new_user'
54
74
  end
55
75
 
56
- test 'SimpleForm should add :as option with new prefix as css class to form if record is not persisted' do
76
+ test 'SimpleForm adds :as option with new prefix as css class to form if record is not persisted' do
57
77
  @user.new_record!
58
78
  with_concat_form_for(@user, as: 'superuser')
59
79
  assert_select 'form.simple_form.new_superuser'
60
80
  end
61
81
 
62
- test 'SimpleForm should add edit class prefix as css class to form if record is persisted' do
82
+ test 'SimpleForm adds edit class prefix as css class to form if record is persisted' do
63
83
  with_concat_form_for(@user)
64
84
  assert_select 'form.simple_form.edit_user'
65
85
  end
66
86
 
67
- test 'SimpleForm should add :as options with edit prefix as css class to form if record is persisted' do
87
+ test 'SimpleForm adds :as options with edit prefix as css class to form if record is persisted' do
68
88
  with_concat_form_for(@user, as: 'superuser')
69
89
  assert_select 'form.simple_form.edit_superuser'
70
90
  end
71
91
 
72
- test 'SimpleForm should add last object name as css class to form when there is array of objects' do
92
+ test 'SimpleForm adds last object name as css class to form when there is array of objects' do
73
93
  with_concat_form_for([Company.new, @user])
74
94
  assert_select 'form.simple_form.edit_user'
75
95
  end
76
96
 
77
- test 'SimpleForm should not add object class to form if css_class is specified' do
97
+ test 'SimpleForm does not add object class to form if css_class is specified' do
78
98
  with_concat_form_for(:user, html: { class: nil })
79
99
  assert_no_select 'form.user'
80
100
  end
81
101
 
82
- test 'SimpleForm should add custom class to form if css_class is specified' do
102
+ test 'SimpleForm adds custom class to form if css_class is specified' do
83
103
  with_concat_form_for(:user, html: { class: 'my_class' })
84
104
  assert_select 'form.my_class'
85
105
  end
86
106
 
87
- test 'pass options to SimpleForm' do
107
+ test 'passes options to SimpleForm' do
88
108
  with_concat_form_for(:user, url: '/account', html: { id: 'my_form' })
89
109
  assert_select 'form#my_form'
90
- assert_select 'form[action=/account]'
110
+ assert_select 'form[action="/account"]'
91
111
  end
92
112
 
93
113
  test 'form_for yields an instance of FormBuilder' do
@@ -132,7 +152,7 @@ class FormHelperTest < ActionView::TestCase
132
152
  end
133
153
 
134
154
  test 'SimpleForm for swaps default action view field_error_proc' do
135
- expected_error_proc = lambda {}
155
+ expected_error_proc = -> {}
136
156
  swap SimpleForm, field_error_proc: expected_error_proc do
137
157
  simple_form_for :user do |f|
138
158
  assert_equal expected_error_proc, ::ActionView::Base.field_error_proc
@@ -142,7 +162,7 @@ class FormHelperTest < ActionView::TestCase
142
162
 
143
163
  private
144
164
 
145
- def swap_field_error_proc(expected_error_proc = lambda {})
165
+ def swap_field_error_proc(expected_error_proc = -> {})
146
166
  swap ActionView::Base, field_error_proc: expected_error_proc do
147
167
  yield
148
168
 
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ # Module that represents a custom component.
6
+ module Numbers
7
+ def number(wrapper_options = nil)
8
+ @number ||= options[:number].to_s.html_safe
9
+ end
10
+ end
11
+
12
+ # Module that represents a custom component.
13
+ module InputGroup
14
+ def prepend(wrapper_options = nil)
15
+ span_tag = content_tag(:span, options[:prepend], class: 'input-group-text')
16
+ template.content_tag(:div, span_tag, class: 'input-group-prepend')
17
+ end
18
+
19
+ def append(wrapper_options = nil)
20
+ span_tag = content_tag(:span, options[:append], class: 'input-group-text')
21
+ template.content_tag(:div, span_tag, class: 'input-group-append')
22
+ end
23
+ end
24
+
25
+ class CustomComponentsTest < ActionView::TestCase
26
+ test 'includes the custom components' do
27
+ SimpleForm.include_component Numbers
28
+
29
+ custom_wrapper = SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
30
+ b.use :number, wrap_with: { tag: 'div', class: 'number' }
31
+ end
32
+
33
+ with_form_for @user, :name, number: 1, wrapper: custom_wrapper
34
+
35
+ assert_select 'div.number', text: '1'
36
+ end
37
+
38
+ test 'includes custom components and use it as optional in the wrapper' do
39
+ SimpleForm.include_component InputGroup
40
+
41
+ custom_wrapper = SimpleForm.build tag: :div, class: 'custom_wrapper' do |b|
42
+ b.use :label
43
+ b.optional :prepend
44
+ b.use :input
45
+ b.use :append
46
+ end
47
+
48
+ with_form_for @user, :name, prepend: true, wrapper: custom_wrapper
49
+
50
+ assert_select 'div.input-group-prepend > span.input-group-text'
51
+ assert_select 'div.input-group-append > span.input-group-text'
52
+ end
53
+
54
+ test 'raises a TypeError when the component is not a Module' do
55
+ component = 'MyComponent'
56
+
57
+ exception = assert_raises TypeError do
58
+ SimpleForm.include_component(component)
59
+ end
60
+ assert_equal exception.message, "SimpleForm.include_component expects a module but got: String"
61
+ end
62
+ end