simple_form 3.0.1 → 3.1.0.rc1

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -27
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +146 -71
  5. data/lib/generators/simple_form/install_generator.rb +2 -2
  6. data/lib/generators/simple_form/templates/README +3 -4
  7. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +19 -3
  8. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +83 -22
  9. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +1 -1
  10. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -2
  11. data/lib/simple_form/action_view_extensions/form_helper.rb +1 -1
  12. data/lib/simple_form/components/errors.rb +30 -2
  13. data/lib/simple_form/components/hints.rb +2 -2
  14. data/lib/simple_form/components/html5.rb +1 -1
  15. data/lib/simple_form/components/label_input.rb +20 -2
  16. data/lib/simple_form/components/labels.rb +9 -5
  17. data/lib/simple_form/components/maxlength.rb +1 -1
  18. data/lib/simple_form/components/min_max.rb +1 -1
  19. data/lib/simple_form/components/pattern.rb +1 -1
  20. data/lib/simple_form/components/placeholders.rb +2 -2
  21. data/lib/simple_form/components/readonly.rb +1 -1
  22. data/lib/simple_form/form_builder.rb +92 -57
  23. data/lib/simple_form/helpers.rb +5 -5
  24. data/lib/simple_form/inputs/base.rb +33 -11
  25. data/lib/simple_form/inputs/block_input.rb +1 -1
  26. data/lib/simple_form/inputs/boolean_input.rb +23 -13
  27. data/lib/simple_form/inputs/collection_input.rb +32 -9
  28. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +6 -11
  29. data/lib/simple_form/inputs/collection_select_input.rb +4 -2
  30. data/lib/simple_form/inputs/date_time_input.rb +12 -2
  31. data/lib/simple_form/inputs/file_input.rb +4 -2
  32. data/lib/simple_form/inputs/grouped_collection_select_input.rb +15 -3
  33. data/lib/simple_form/inputs/hidden_input.rb +4 -2
  34. data/lib/simple_form/inputs/numeric_input.rb +5 -4
  35. data/lib/simple_form/inputs/password_input.rb +4 -2
  36. data/lib/simple_form/inputs/priority_input.rb +4 -2
  37. data/lib/simple_form/inputs/range_input.rb +1 -1
  38. data/lib/simple_form/inputs/string_input.rb +4 -2
  39. data/lib/simple_form/inputs/text_input.rb +4 -2
  40. data/lib/simple_form/railtie.rb +7 -0
  41. data/lib/simple_form/tags.rb +7 -0
  42. data/lib/simple_form/version.rb +1 -1
  43. data/lib/simple_form/wrappers/builder.rb +5 -5
  44. data/lib/simple_form/wrappers/leaf.rb +28 -0
  45. data/lib/simple_form/wrappers/many.rb +5 -6
  46. data/lib/simple_form/wrappers/root.rb +1 -1
  47. data/lib/simple_form/wrappers/single.rb +5 -3
  48. data/lib/simple_form/wrappers.rb +1 -0
  49. data/lib/simple_form.rb +38 -6
  50. data/test/action_view_extensions/builder_test.rb +2 -2
  51. data/test/components/label_test.rb +1 -1
  52. data/test/form_builder/association_test.rb +17 -0
  53. data/test/form_builder/error_notification_test.rb +1 -1
  54. data/test/form_builder/error_test.rb +61 -0
  55. data/test/form_builder/input_field_test.rb +25 -1
  56. data/test/form_builder/label_test.rb +24 -1
  57. data/test/form_builder/wrapper_test.rb +67 -0
  58. data/test/generators/simple_form_generator_test.rb +2 -2
  59. data/test/inputs/boolean_input_test.rb +50 -2
  60. data/test/inputs/collection_check_boxes_input_test.rb +40 -11
  61. data/test/inputs/collection_radio_buttons_input_test.rb +76 -17
  62. data/test/inputs/collection_select_input_test.rb +108 -3
  63. data/test/inputs/datetime_input_test.rb +105 -38
  64. data/test/inputs/discovery_test.rb +12 -1
  65. data/test/inputs/grouped_collection_select_input_test.rb +36 -0
  66. data/test/inputs/string_input_test.rb +20 -0
  67. data/test/simple_form_test.rb +8 -0
  68. data/test/support/discovery_inputs.rb +12 -2
  69. data/test/support/misc_helpers.rb +49 -5
  70. data/test/support/models.rb +49 -24
  71. data/test/test_helper.rb +2 -0
  72. metadata +23 -34
@@ -18,6 +18,22 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
18
18
  assert_select 'label[for=user_active_false]', 'No'
19
19
  end
20
20
 
21
+ test 'input as radio should generate internal labels with accurate `for` values with nested boolean style' do
22
+ swap SimpleForm, boolean_style: :nested do
23
+ with_input_for @user, :active, :radio_buttons
24
+ assert_select 'label[for=user_active_true]', 'Yes'
25
+ assert_select 'label[for=user_active_false]', 'No'
26
+ end
27
+ end
28
+
29
+ test 'nested label should not duplicate input id' do
30
+ swap SimpleForm, boolean_style: :nested do
31
+ with_input_for @user, :active, :radio_buttons, id: 'nested_id'
32
+ assert_select 'input#user_active_true'
33
+ assert_no_select 'label#user_active_true'
34
+ end
35
+ end
36
+
21
37
  test 'input as radio should use i18n to translate internal labels' do
22
38
  store_translations(:en, simple_form: { yes: 'Sim', no: 'Não' }) do
23
39
  with_input_for @user, :active, :radio_buttons
@@ -48,8 +64,8 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
48
64
  with_input_for @user, :name, :radio_buttons, collection: ['Jose', 'Carlos']
49
65
  assert_select 'input[type=radio][value=Jose]'
50
66
  assert_select 'input[type=radio][value=Carlos]'
51
- assert_select 'label.collection_radio_buttons', 'Jose'
52
- assert_select 'label.collection_radio_buttons', 'Carlos'
67
+ assert_select 'label.collection_radio_buttons[for=user_name_jose]', 'Jose'
68
+ assert_select 'label.collection_radio_buttons[for=user_name_carlos]', 'Carlos'
53
69
  end
54
70
 
55
71
  test 'input should do automatic collection translation for radio types using defaults key' do
@@ -59,8 +75,8 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
59
75
  with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
60
76
  assert_select 'input[type=radio][value=male]'
61
77
  assert_select 'input[type=radio][value=female]'
62
- assert_select 'label.collection_radio_buttons', 'Male'
63
- assert_select 'label.collection_radio_buttons', 'Female'
78
+ assert_select 'label.collection_radio_buttons[for=user_gender_male]', 'Male'
79
+ assert_select 'label.collection_radio_buttons[for=user_gender_female]', 'Female'
64
80
  end
65
81
  end
66
82
 
@@ -71,8 +87,36 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
71
87
  with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
72
88
  assert_select 'input[type=radio][value=male]'
73
89
  assert_select 'input[type=radio][value=female]'
74
- assert_select 'label.collection_radio_buttons', 'Male'
75
- assert_select 'label.collection_radio_buttons', 'Female'
90
+ assert_select 'label.collection_radio_buttons[for=user_gender_male]', 'Male'
91
+ assert_select 'label.collection_radio_buttons[for=user_gender_female]', 'Female'
92
+ end
93
+ end
94
+
95
+ test 'input should do automatic collection translation and preserve html markup' do
96
+ swap SimpleForm, boolean_style: :nested do
97
+ store_translations(:en, simple_form: { options: { user: {
98
+ gender: { male_html: '<strong>Male</strong>', female_html: '<strong>Female</strong>' }
99
+ } } } ) do
100
+ with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
101
+ assert_select 'input[type=radio][value=male]'
102
+ assert_select 'input[type=radio][value=female]'
103
+ assert_select 'label[for=user_gender_male]', 'Male'
104
+ assert_select 'label[for=user_gender_female]', 'Female'
105
+ end
106
+ end
107
+ end
108
+
109
+ test 'input should do automatic collection translation with keys prefixed with _html and a string value' do
110
+ swap SimpleForm, boolean_style: :nested do
111
+ store_translations(:en, simple_form: { options: { user: {
112
+ gender: { male_html: 'Male', female_html: 'Female' }
113
+ } } } ) do
114
+ with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
115
+ assert_select 'input[type=radio][value=male]'
116
+ assert_select 'input[type=radio][value=female]'
117
+ assert_select 'label[for=user_gender_male]', 'Male'
118
+ assert_select 'label[for=user_gender_female]', 'Female'
119
+ end
76
120
  end
77
121
  end
78
122
 
@@ -292,29 +336,27 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
292
336
  swap SimpleForm, boolean_style: :nested do
293
337
  with_input_for @user, :active, :radio_buttons
294
338
 
295
- assert_select 'label.radio > input#user_active_true[type=radio]'
296
- assert_select 'label.radio', 'Yes'
297
- assert_select 'label.radio > input#user_active_false[type=radio]'
298
- assert_select 'label.radio', 'No'
339
+ assert_select 'span.radio > label > input#user_active_true[type=radio]'
340
+ assert_select 'span.radio > label', 'Yes'
341
+ assert_select 'span.radio > label > input#user_active_false[type=radio]'
342
+ assert_select 'span.radio > label', 'No'
299
343
  assert_no_select 'label.collection_radio_buttons'
300
344
  end
301
345
  end
302
346
 
303
- test 'input radio with nested style overrides configured item wrapper tag, forcing the :label' do
347
+ test 'input radio with nested style does not overrides configured item wrapper tag' do
304
348
  swap SimpleForm, boolean_style: :nested, item_wrapper_tag: :li do
305
349
  with_input_for @user, :active, :radio_buttons
306
350
 
307
- assert_select 'label.radio > input'
308
- assert_no_select 'li'
351
+ assert_select 'li.radio > label > input'
309
352
  end
310
353
  end
311
354
 
312
- test 'input radio with nested style overrides given item wrapper tag, forcing the :label' do
355
+ test 'input radio with nested style does not overrides given item wrapper tag' do
313
356
  swap SimpleForm, boolean_style: :nested do
314
357
  with_input_for @user, :active, :radio_buttons, item_wrapper_tag: :li
315
358
 
316
- assert_select 'label.radio > input'
317
- assert_no_select 'li'
359
+ assert_select 'li.radio > label > input'
318
360
  end
319
361
  end
320
362
 
@@ -322,7 +364,24 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
322
364
  swap SimpleForm, boolean_style: :nested do
323
365
  with_input_for @user, :active, :radio_buttons, item_wrapper_class: "inline"
324
366
 
325
- assert_select 'label.radio.inline > input'
367
+ assert_select 'span.radio.inline > label > input'
368
+ end
369
+ end
370
+
371
+ test 'input radio wrapper class are not included when set to falsey' do
372
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
373
+ with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
374
+
375
+ assert_no_select 'label.radio'
376
+ end
377
+ end
378
+
379
+ test 'input check boxes custom wrapper class is included when include input wrapper class is falsey' do
380
+ swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
381
+ with_input_for @user, :gender, :radio_buttons, collection: [:male, :female], item_wrapper_class: 'custom'
382
+
383
+ assert_no_select 'label.radio'
384
+ assert_select 'span.custom'
326
385
  end
327
386
  end
328
387
  end
@@ -31,7 +31,7 @@ class CollectionSelectInputTest < ActionView::TestCase
31
31
  test 'input should do automatic collection translation for select types using defaults key' do
32
32
  store_translations(:en, simple_form: { options: { defaults: {
33
33
  gender: { male: 'Male', female: 'Female'}
34
- } } } ) do
34
+ } } }) do
35
35
  with_input_for @user, :gender, :select, collection: [:male, :female]
36
36
  assert_select 'select.select#user_gender'
37
37
  assert_select 'select option', 'Male'
@@ -42,7 +42,7 @@ class CollectionSelectInputTest < ActionView::TestCase
42
42
  test 'input should do automatic collection translation for select types using specific object key' do
43
43
  store_translations(:en, simple_form: { options: { user: {
44
44
  gender: { male: 'Male', female: 'Female'}
45
- } } } ) do
45
+ } } }) do
46
46
  with_input_for @user, :gender, :select, collection: [:male, :female]
47
47
  assert_select 'select.select#user_gender'
48
48
  assert_select 'select option', 'Male'
@@ -102,9 +102,63 @@ class CollectionSelectInputTest < ActionView::TestCase
102
102
  assert_select 'select option[value=]', ''
103
103
  end
104
104
 
105
+ test 'input should translate include blank when set to :translate' do
106
+ store_translations(:en, simple_form: { include_blanks: { user: {
107
+ age: 'Rather not say'
108
+ } } }) do
109
+ with_input_for @user, :age, :select, collection: 18..30, include_blank: :translate
110
+ assert_select 'select option[value=]', 'Rather not say'
111
+ end
112
+ end
113
+
114
+ test 'input should translate include blank with a default' do
115
+ store_translations(:en, simple_form: { include_blanks: { defaults: {
116
+ age: 'Rather not say',
117
+ } } }) do
118
+ with_input_for @user, :age, :select, collection: 18..30, include_blank: :translate
119
+ assert_select 'select option[value=]', 'Rather not say'
120
+ end
121
+ end
122
+
123
+ test 'input should not translate include blank when set to a string' do
124
+ store_translations(:en, simple_form: { include_blanks: { user: {
125
+ age: 'Rather not say'
126
+ } } }) do
127
+ with_input_for @user, :age, :select, collection: 18..30, include_blank: 'Young at heart'
128
+ assert_select 'select option[value=]', 'Young at heart'
129
+ end
130
+ end
131
+
132
+ test 'input should not translate include blank when automatically set' do
133
+ store_translations(:en, simple_form: { include_blanks: { user: {
134
+ age: 'Rather not say'
135
+ } } }) do
136
+ with_input_for @user, :age, :select, collection: 18..30
137
+ assert_select 'select option[value=]', ''
138
+ end
139
+ end
140
+
141
+ test 'input should not translate include blank when set to true' do
142
+ store_translations(:en, simple_form: { include_blanks: { user: {
143
+ age: 'Rather not say'
144
+ } } }) do
145
+ with_input_for @user, :age, :select, collection: 18..30, include_blank: true
146
+ assert_select 'select option[value=]', ''
147
+ end
148
+ end
149
+
150
+ test 'input should not translate include blank when set to false' do
151
+ store_translations(:en, simple_form: { include_blanks: { user: {
152
+ age: 'Rather not say'
153
+ } } }) do
154
+ with_input_for @user, :age, :select, collection: 18..30, include_blank: false
155
+ assert_no_select 'select option[value=]'
156
+ end
157
+ end
158
+
105
159
  test 'input should not set include blank if otherwise is told' do
106
160
  with_input_for @user, :age, :select, collection: 18..30, include_blank: false
107
- assert_no_select 'select option[value=]', ''
161
+ assert_no_select 'select option[value=]'
108
162
  end
109
163
 
110
164
  test 'input should not set include blank if prompt is given' do
@@ -117,6 +171,51 @@ class CollectionSelectInputTest < ActionView::TestCase
117
171
  assert_no_select 'select option[value=]', ''
118
172
  end
119
173
 
174
+ test 'input should translate prompt when set to :translate' do
175
+ store_translations(:en, simple_form: { prompts: { user: {
176
+ age: 'Select age:'
177
+ } } }) do
178
+ with_input_for @user, :age, :select, collection: 18..30, prompt: :translate
179
+ assert_select 'select option[value=]', 'Select age:'
180
+ end
181
+ end
182
+
183
+ test 'input should translate prompt with a default' do
184
+ store_translations(:en, simple_form: { prompts: { defaults: {
185
+ age: 'Select age:',
186
+ } } }) do
187
+ with_input_for @user, :age, :select, collection: 18..30, prompt: :translate
188
+ assert_select 'select option[value=]', 'Select age:'
189
+ end
190
+ end
191
+
192
+ test 'input should not translate prompt when set to a string' do
193
+ store_translations(:en, simple_form: { prompts: { user: {
194
+ age: 'Select age:'
195
+ } } }) do
196
+ with_input_for @user, :age, :select, collection: 18..30, prompt: 'Do it:'
197
+ assert_select 'select option[value=]', 'Do it:'
198
+ end
199
+ end
200
+
201
+ test 'input should not translate prompt when set to false' do
202
+ store_translations(:en, simple_form: { prompts: { user: {
203
+ age: 'Select age:'
204
+ } } }) do
205
+ with_input_for @user, :age, :select, collection: 18..30, prompt: false
206
+ assert_no_select 'select option[value=]'
207
+ end
208
+ end
209
+
210
+ test 'input should use Rails prompt translation as a fallback' do
211
+ store_translations(:en, helpers: { select: {
212
+ prompt: 'Select value:'
213
+ } }) do
214
+ with_input_for @user, :age, :select, collection: 18..30, prompt: :translate
215
+ assert_select 'select option[value=]', "Select value:"
216
+ end
217
+ end
218
+
120
219
  test 'input should detect label and value on collections' do
121
220
  users = [User.build(id: 1, name: "Jose"), User.build(id: 2, name: "Carlos")]
122
221
  with_input_for @user, :description, :select, collection: users
@@ -178,6 +277,12 @@ class CollectionSelectInputTest < ActionView::TestCase
178
277
  assert_select 'select[required]'
179
278
  end
180
279
 
280
+ test 'collection input with select type should generate required html attribute only with blank option or prompt' do
281
+ with_input_for @user, :name, :select, prompt: 'Name...', collection: ['Jose', 'Carlos']
282
+ assert_select 'select.required'
283
+ assert_select 'select[required]'
284
+ end
285
+
181
286
  test 'collection input with select type should not generate required html attribute without blank option' do
182
287
  with_input_for @user, :name, :select, include_blank: false, collection: ['Jose', 'Carlos']
183
288
  assert_select 'select.required'
@@ -1,18 +1,69 @@
1
1
  # encoding: UTF-8
2
2
  require 'test_helper'
3
3
 
4
- # Tests for all different kinds of inputs.
5
- class DateTimeInputTest < ActionView::TestCase
6
- # DateTime input
7
- test 'input should generate a datetime select by default for datetime attributes' do
4
+ # Tests for datetime, date and time inputs when HTML5 compatibility is enabled in the wrapper.
5
+ class DateTimeInputWithHtml5Test < ActionView::TestCase
6
+ test 'input should generate a datetime input for datetime attributes if HTML5 compatibility is explicitly enbled' do
7
+ with_input_for @user, :created_at, :datetime, html5: true
8
+
9
+ assert_select 'input[type="datetime"]'
10
+ end
11
+
12
+ test 'input should generate a datetime select for datetime attributes' do
8
13
  with_input_for @user, :created_at, :datetime
9
- 1.upto(5) do |i|
10
- assert_select "form select.datetime#user_created_at_#{i}i"
14
+
15
+ assert_select 'select.datetime'
16
+ end
17
+
18
+ test 'input should generate a date input for date attributes if HTML5 compatibility is explicitly enbled' do
19
+ with_input_for @user, :born_at, :date, html5: true
20
+
21
+ assert_select 'input[type="date"]'
22
+ end
23
+
24
+ test 'input should generate a date select for date attributes' do
25
+ with_input_for @user, :born_at, :date
26
+
27
+ assert_select 'select.date'
28
+ end
29
+
30
+ test 'input should generate a time input for time attributes if HTML5 compatibility is explicitly enbled' do
31
+ with_input_for @user, :delivery_time, :time, html5: true
32
+
33
+ assert_select 'input[type="time"]'
34
+ end
35
+
36
+ test 'input should generate a time select for time attributes' do
37
+ with_input_for @user, :delivery_time, :time
38
+
39
+ assert_select 'select.time'
40
+ end
41
+
42
+ test 'input should generate required html attribute' do
43
+ with_input_for @user, :delivery_time, :time, required: true, html5: true
44
+ assert_select 'input.required'
45
+ assert_select 'input[required]'
46
+ end
47
+
48
+ test 'input should have an aria-required html attribute' do
49
+ with_input_for @user, :delivery_time, :time, required: true, html5: true
50
+ assert_select 'input[aria-required=true]'
51
+ end
52
+ end
53
+
54
+ # Tests for datetime, date and time inputs when HTML5 compatibility is enabled in the wrapper.
55
+ class DateTimeInputWithoutHtml5Test < ActionView::TestCase
56
+ test 'input should generate a datetime select by default for datetime attributes' do
57
+ swap_wrapper do
58
+ with_input_for @user, :created_at, :datetime
59
+ 1.upto(5) do |i|
60
+ assert_select "form select.datetime#user_created_at_#{i}i"
61
+ end
11
62
  end
12
63
  end
13
64
 
14
65
  test 'input should be able to pass options to datetime select' do
15
- with_input_for @user, :created_at, :datetime,
66
+ with_input_for @user, :created_at, :datetime, html5: false,
16
67
  disabled: true, prompt: { year: 'ano', month: 'mês', day: 'dia' }
17
68
 
18
69
  assert_select 'select.datetime[disabled=disabled]'
@@ -21,16 +72,26 @@ class DateTimeInputTest < ActionView::TestCase
21
72
  assert_select 'select.datetime option', 'dia'
22
73
  end
23
74
 
75
+ test 'input should generate a datetime input for datetime attributes if HTML5 compatibility is explicitly enabled' do
76
+ swap_wrapper do
77
+ with_input_for @user, :created_at, :datetime, html5: true
78
+
79
+ assert_select 'input[type="datetime"]'
80
+ end
81
+ end
82
+
24
83
  test 'input should generate a date select for date attributes' do
25
- with_input_for @user, :born_at, :date
26
- assert_select 'select.date#user_born_at_1i'
27
- assert_select 'select.date#user_born_at_2i'
28
- assert_select 'select.date#user_born_at_3i'
29
- assert_no_select 'select.date#user_born_at_4i'
84
+ swap_wrapper do
85
+ with_input_for @user, :born_at, :date
86
+ assert_select 'select.date#user_born_at_1i'
87
+ assert_select 'select.date#user_born_at_2i'
88
+ assert_select 'select.date#user_born_at_3i'
89
+ assert_no_select 'select.date#user_born_at_4i'
90
+ end
30
91
  end
31
92
 
32
93
  test 'input should be able to pass options to date select' do
33
- with_input_for @user, :born_at, :date, as: :date,
94
+ with_input_for @user, :born_at, :date, as: :date, html5: false,
34
95
  disabled: true, prompt: { year: 'ano', month: 'mês', day: 'dia' }
35
96
 
36
97
  assert_select 'select.date[disabled=disabled]'
@@ -40,21 +101,31 @@ class DateTimeInputTest < ActionView::TestCase
40
101
  end
41
102
 
42
103
  test 'input should be able to pass :default to date select' do
43
- with_input_for @user, :born_at, :date, default: Date.today
104
+ with_input_for @user, :born_at, :date, default: Date.today, html5: false
44
105
  assert_select "select.date option[value=#{Date.today.year}][selected=selected]"
45
106
  end
46
107
 
108
+ test 'input should generate a date input for date attributes if HTML5 compatibility is explicitly enabled' do
109
+ swap_wrapper do
110
+ with_input_for @user, :born_at, :date, html5: true
111
+
112
+ assert_select 'input[type="date"]'
113
+ end
114
+ end
115
+
47
116
  test 'input should generate a time select for time attributes' do
48
- with_input_for @user, :delivery_time, :time
49
- assert_select 'input[type=hidden]#user_delivery_time_1i'
50
- assert_select 'input[type=hidden]#user_delivery_time_2i'
51
- assert_select 'input[type=hidden]#user_delivery_time_3i'
52
- assert_select 'select.time#user_delivery_time_4i'
53
- assert_select 'select.time#user_delivery_time_5i'
117
+ swap_wrapper do
118
+ with_input_for @user, :delivery_time, :time
119
+ assert_select 'input[type=hidden]#user_delivery_time_1i'
120
+ assert_select 'input[type=hidden]#user_delivery_time_2i'
121
+ assert_select 'input[type=hidden]#user_delivery_time_3i'
122
+ assert_select 'select.time#user_delivery_time_4i'
123
+ assert_select 'select.time#user_delivery_time_5i'
124
+ end
54
125
  end
55
126
 
56
127
  test 'input should be able to pass options to time select' do
57
- with_input_for @user, :delivery_time, :time, required: true,
128
+ with_input_for @user, :delivery_time, :time, required: true, html5: false,
58
129
  disabled: true, prompt: { hour: 'hora', minute: 'minuto' }
59
130
 
60
131
  assert_select 'select.time[disabled=disabled]'
@@ -62,44 +133,40 @@ class DateTimeInputTest < ActionView::TestCase
62
133
  assert_select 'select.time option', 'minuto'
63
134
  end
64
135
 
136
+ test 'input should generate a time input for time attributes if HTML5 compatibility is explicitly enabled' do
137
+ swap_wrapper do
138
+ with_input_for @user, :delivery_time, :time, html5: true
139
+
140
+ assert_select 'input[type="time"]'
141
+ end
142
+ end
143
+
65
144
  test 'label should use i18n to get target for date input type' do
66
145
  store_translations(:en, date: { order: ['month', 'day', 'year'] }) do
67
- with_input_for :project, :created_at, :date
146
+ with_input_for :project, :created_at, :date, html5: false
68
147
  assert_select 'label[for=project_created_at_2i]'
69
148
  end
70
149
  end
71
150
 
72
151
  test 'label should use i18n to get target for datetime input type' do
73
152
  store_translations(:en, date: { order: ['month', 'day', 'year'] }) do
74
- with_input_for :project, :created_at, :datetime
153
+ with_input_for :project, :created_at, :datetime, html5: false
75
154
  assert_select 'label[for=project_created_at_2i]'
76
155
  end
77
156
  end
78
157
 
79
158
  test 'label should use order to get target when date input type' do
80
- with_input_for :project, :created_at, :date, order: ['month', 'year', 'day']
159
+ with_input_for :project, :created_at, :date, order: ['month', 'year', 'day'], html5: false
81
160
  assert_select 'label[for=project_created_at_2i]'
82
161
  end
83
162
 
84
163
  test 'label should use order to get target when datetime input type' do
85
- with_input_for :project, :created_at, :datetime, order: ['month', 'year', 'day']
164
+ with_input_for :project, :created_at, :datetime, order: ['month', 'year', 'day'], html5: false
86
165
  assert_select 'label[for=project_created_at_2i]'
87
166
  end
88
167
 
89
168
  test 'label should point to first option when time input type' do
90
- with_input_for :project, :created_at, :time
169
+ with_input_for :project, :created_at, :time, html5: false
91
170
  assert_select 'label[for=project_created_at_4i]'
92
171
  end
93
-
94
- test 'date time input should generate required html attribute' do
95
- with_input_for @user, :delivery_time, :time, required: true
96
- assert_select 'select.required'
97
- assert_select 'select[required]'
98
- end
99
-
100
- test 'date time input has an aria-required html attribute' do
101
- with_input_for @user, :delivery_time, :time, required: true
102
- assert_select 'select.required'
103
- assert_select 'select[aria-required=true]'
104
- end
105
172
  end
@@ -2,7 +2,7 @@ require 'test_helper'
2
2
 
3
3
  class DiscoveryTest < ActionView::TestCase
4
4
  # Setup new inputs and remove them after the test.
5
- def discovery(value=false)
5
+ def discovery(value = false)
6
6
  swap SimpleForm, cache_discovery: value do
7
7
  begin
8
8
  load "support/discovery_inputs.rb"
@@ -12,6 +12,7 @@ class DiscoveryTest < ActionView::TestCase
12
12
  Object.send :remove_const, :StringInput
13
13
  Object.send :remove_const, :NumericInput
14
14
  Object.send :remove_const, :CustomizedInput
15
+ Object.send :remove_const, :DeprecatedInput
15
16
  Object.send :remove_const, :CollectionSelectInput
16
17
  end
17
18
  end
@@ -66,4 +67,14 @@ class DiscoveryTest < ActionView::TestCase
66
67
  assert_select 'form select#user_active.select.chosen'
67
68
  end
68
69
  end
70
+
71
+ test 'inputs method without wrapper_options are deprecated' do
72
+ discovery do
73
+ assert_deprecated do
74
+ with_form_for @user, :name, as: :deprecated
75
+ end
76
+
77
+ assert_select 'form section input#user_name.string'
78
+ end
79
+ end
69
80
  end
@@ -79,6 +79,42 @@ class GroupedCollectionSelectInputTest < ActionView::TestCase
79
79
  end
80
80
  end
81
81
 
82
+ test 'grouped collection finds default label methods on the group objects' do
83
+ option_list = ['Jose', 'Carlos']
84
+
85
+ GroupedClass = Struct.new(:to_label, :options)
86
+ group = GroupedClass.new("Authors", option_list)
87
+
88
+ with_input_for @user, :tag_ids, :grouped_select,
89
+ collection: [group],
90
+ group_method: :options
91
+
92
+ assert_select 'select.grouped_select#user_tag_ids' do
93
+ assert_select 'optgroup[label=Authors]' do
94
+ assert_select 'option', 'Jose'
95
+ assert_select 'option', 'Carlos'
96
+ end
97
+ end
98
+ end
99
+
100
+ test 'grouped collections finds the default label method from the first non-empty object' do
101
+ Agent = Struct.new(:id, :name)
102
+ agents = [["First", []], ["Second", [Agent.new(7, 'Bond'), Agent.new(47, 'Hitman')]]]
103
+
104
+ with_input_for @user, :tag_ids, :grouped_select,
105
+ collection: agents,
106
+ group_label_method: :first,
107
+ group_method: :last,
108
+ include_blank: false
109
+
110
+ assert_select 'select.grouped_select#user_tag_ids' do
111
+ assert_select 'optgroup[label=Second]' do
112
+ assert_select 'option[value=7]', 'Bond'
113
+ assert_select 'option[value=47]', 'Hitman'
114
+ end
115
+ end
116
+ end
117
+
82
118
  test 'grouped collection accepts label and value methods options' do
83
119
  with_input_for @user, :tag_ids, :grouped_select,
84
120
  collection: { 'Authors' => ['Jose', 'Carlos'] },
@@ -104,6 +104,26 @@ class StringInputTest < ActionView::TestCase
104
104
  end
105
105
  end
106
106
 
107
+ test 'input should use custom i18n scope to translate placeholder text' do
108
+ store_translations(:en, my_scope: { placeholders: { user: {
109
+ name: 'Name goes here'
110
+ } } }) do
111
+ swap SimpleForm, i18n_scope: :my_scope do
112
+ with_input_for @user, :name, :string
113
+ assert_select 'input.string[placeholder=Name goes here]'
114
+ end
115
+ end
116
+ end
117
+
118
+ test 'input should translate a key prefixed with _html and return the html markup' do
119
+ store_translations(:en, simple_form: { labels: { user: {
120
+ name_html: '<b>Name</b>'
121
+ } } }) do
122
+ with_input_for @user, :name, :string
123
+ assert_select 'label b', 'Name'
124
+ end
125
+ end
126
+
107
127
  [:email, :url, :search, :tel].each do |type|
108
128
  test "input should allow type #{type}" do
109
129
  with_input_for @user, :name, type
@@ -6,4 +6,12 @@ class SimpleFormTest < ActiveSupport::TestCase
6
6
  assert_equal SimpleForm, config
7
7
  end
8
8
  end
9
+
10
+ test 'setup block configure Simple Form' do
11
+ SimpleForm.setup do |config|
12
+ assert_equal SimpleForm, config
13
+ end
14
+
15
+ assert_equal true, SimpleForm.configured?
16
+ end
9
17
  end
@@ -1,16 +1,26 @@
1
1
  class StringInput < SimpleForm::Inputs::StringInput
2
- def input
2
+ def input(wrapper_options = nil)
3
3
  "<section>#{super}</section>".html_safe
4
4
  end
5
5
  end
6
6
 
7
7
  class NumericInput < SimpleForm::Inputs::NumericInput
8
- def input
8
+ def input(wrapper_options = nil)
9
9
  "<section>#{super}</section>".html_safe
10
10
  end
11
11
  end
12
12
 
13
13
  class CustomizedInput < SimpleForm::Inputs::StringInput
14
+ def input(wrapper_options = nil)
15
+ "<section>#{super}</section>".html_safe
16
+ end
17
+
18
+ def input_method
19
+ :text_field
20
+ end
21
+ end
22
+
23
+ class DeprecatedInput < SimpleForm::Inputs::StringInput
14
24
  def input
15
25
  "<section>#{super}</section>".html_safe
16
26
  end