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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -27
- data/MIT-LICENSE +1 -1
- data/README.md +146 -71
- data/lib/generators/simple_form/install_generator.rb +2 -2
- data/lib/generators/simple_form/templates/README +3 -4
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +19 -3
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +83 -22
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +1 -1
- data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -2
- data/lib/simple_form/action_view_extensions/form_helper.rb +1 -1
- data/lib/simple_form/components/errors.rb +30 -2
- data/lib/simple_form/components/hints.rb +2 -2
- data/lib/simple_form/components/html5.rb +1 -1
- data/lib/simple_form/components/label_input.rb +20 -2
- data/lib/simple_form/components/labels.rb +9 -5
- data/lib/simple_form/components/maxlength.rb +1 -1
- data/lib/simple_form/components/min_max.rb +1 -1
- data/lib/simple_form/components/pattern.rb +1 -1
- data/lib/simple_form/components/placeholders.rb +2 -2
- data/lib/simple_form/components/readonly.rb +1 -1
- data/lib/simple_form/form_builder.rb +92 -57
- data/lib/simple_form/helpers.rb +5 -5
- data/lib/simple_form/inputs/base.rb +33 -11
- data/lib/simple_form/inputs/block_input.rb +1 -1
- data/lib/simple_form/inputs/boolean_input.rb +23 -13
- data/lib/simple_form/inputs/collection_input.rb +32 -9
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +6 -11
- data/lib/simple_form/inputs/collection_select_input.rb +4 -2
- data/lib/simple_form/inputs/date_time_input.rb +12 -2
- data/lib/simple_form/inputs/file_input.rb +4 -2
- data/lib/simple_form/inputs/grouped_collection_select_input.rb +15 -3
- data/lib/simple_form/inputs/hidden_input.rb +4 -2
- data/lib/simple_form/inputs/numeric_input.rb +5 -4
- data/lib/simple_form/inputs/password_input.rb +4 -2
- data/lib/simple_form/inputs/priority_input.rb +4 -2
- data/lib/simple_form/inputs/range_input.rb +1 -1
- data/lib/simple_form/inputs/string_input.rb +4 -2
- data/lib/simple_form/inputs/text_input.rb +4 -2
- data/lib/simple_form/railtie.rb +7 -0
- data/lib/simple_form/tags.rb +7 -0
- data/lib/simple_form/version.rb +1 -1
- data/lib/simple_form/wrappers/builder.rb +5 -5
- data/lib/simple_form/wrappers/leaf.rb +28 -0
- data/lib/simple_form/wrappers/many.rb +5 -6
- data/lib/simple_form/wrappers/root.rb +1 -1
- data/lib/simple_form/wrappers/single.rb +5 -3
- data/lib/simple_form/wrappers.rb +1 -0
- data/lib/simple_form.rb +38 -6
- data/test/action_view_extensions/builder_test.rb +2 -2
- data/test/components/label_test.rb +1 -1
- data/test/form_builder/association_test.rb +17 -0
- data/test/form_builder/error_notification_test.rb +1 -1
- data/test/form_builder/error_test.rb +61 -0
- data/test/form_builder/input_field_test.rb +25 -1
- data/test/form_builder/label_test.rb +24 -1
- data/test/form_builder/wrapper_test.rb +67 -0
- data/test/generators/simple_form_generator_test.rb +2 -2
- data/test/inputs/boolean_input_test.rb +50 -2
- data/test/inputs/collection_check_boxes_input_test.rb +40 -11
- data/test/inputs/collection_radio_buttons_input_test.rb +76 -17
- data/test/inputs/collection_select_input_test.rb +108 -3
- data/test/inputs/datetime_input_test.rb +105 -38
- data/test/inputs/discovery_test.rb +12 -1
- data/test/inputs/grouped_collection_select_input_test.rb +36 -0
- data/test/inputs/string_input_test.rb +20 -0
- data/test/simple_form_test.rb +8 -0
- data/test/support/discovery_inputs.rb +12 -2
- data/test/support/misc_helpers.rb +49 -5
- data/test/support/models.rb +49 -24
- data/test/test_helper.rb +2 -0
- 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 '
|
|
296
|
-
assert_select '
|
|
297
|
-
assert_select '
|
|
298
|
-
assert_select '
|
|
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
|
|
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 '
|
|
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
|
|
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 '
|
|
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 '
|
|
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
|
-
} } }
|
|
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
|
-
} } }
|
|
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
|
|
5
|
-
class
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
data/test/simple_form_test.rb
CHANGED
|
@@ -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
|