simple_form 3.1.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of simple_form might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +67 -0
- data/MIT-LICENSE +1 -1
- data/README.md +70 -31
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +5 -2
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +19 -1
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +5 -2
- data/lib/simple_form/action_view_extensions/form_helper.rb +3 -1
- data/lib/simple_form/components/html5.rb +14 -4
- data/lib/simple_form/components/labels.rb +1 -1
- data/lib/simple_form/components/maxlength.rb +17 -4
- data/lib/simple_form/components/minlength.rb +47 -0
- data/lib/simple_form/components.rb +1 -0
- data/lib/simple_form/form_builder.rb +17 -9
- data/lib/simple_form/inputs/base.rb +12 -10
- data/lib/simple_form/inputs/boolean_input.rb +11 -2
- data/lib/simple_form/inputs/collection_input.rb +4 -3
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +1 -1
- data/lib/simple_form/inputs/date_time_input.rb +12 -8
- data/lib/simple_form/inputs/password_input.rb +1 -1
- data/lib/simple_form/inputs/string_input.rb +1 -1
- data/lib/simple_form/inputs/text_input.rb +1 -1
- data/lib/simple_form/version.rb +1 -1
- data/lib/simple_form.rb +1 -4
- data/test/form_builder/error_test.rb +32 -9
- data/test/form_builder/general_test.rb +40 -8
- data/test/form_builder/input_field_test.rb +53 -67
- data/test/form_builder/label_test.rb +19 -2
- data/test/form_builder/wrapper_test.rb +43 -11
- data/test/inputs/boolean_input_test.rb +18 -0
- data/test/inputs/datetime_input_test.rb +15 -2
- data/test/inputs/discovery_test.rb +1 -0
- data/test/inputs/numeric_input_test.rb +3 -0
- data/test/inputs/priority_input_test.rb +10 -2
- data/test/inputs/required_test.rb +44 -0
- data/test/inputs/string_input_test.rb +20 -12
- data/test/inputs/text_input_test.rb +12 -0
- data/test/support/misc_helpers.rb +22 -1
- data/test/support/mock_controller.rb +3 -1
- data/test/support/models.rb +41 -7
- data/test/test_helper.rb +6 -0
- metadata +24 -11
@@ -2,10 +2,15 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
# Tests for f.input_field
|
4
4
|
class InputFieldTest < ActionView::TestCase
|
5
|
-
|
6
|
-
with_concat_form_for(
|
7
|
-
f.input_field
|
5
|
+
def with_input_field_for(object, *args)
|
6
|
+
with_concat_form_for(object) do |f|
|
7
|
+
f.input_field(*args)
|
8
8
|
end
|
9
|
+
end
|
10
|
+
|
11
|
+
test "builder input_field only renders the input tag, nothing else" do
|
12
|
+
with_input_field_for @user, :name
|
13
|
+
|
9
14
|
assert_select 'form > input.required.string'
|
10
15
|
assert_no_select 'div.string'
|
11
16
|
assert_no_select 'label'
|
@@ -13,45 +18,34 @@ class InputFieldTest < ActionView::TestCase
|
|
13
18
|
end
|
14
19
|
|
15
20
|
test 'builder input_field allows overriding default input type' do
|
16
|
-
|
17
|
-
f.input_field :name, as: :text
|
18
|
-
end
|
21
|
+
with_input_field_for @user, :name, as: :text
|
19
22
|
|
20
23
|
assert_no_select 'input#user_name'
|
21
24
|
assert_select 'textarea#user_name.text'
|
22
25
|
end
|
23
26
|
|
24
27
|
test 'builder input_field generates input type based on column type' do
|
25
|
-
|
26
|
-
f.input_field :age
|
27
|
-
end
|
28
|
+
with_input_field_for @user, :age
|
28
29
|
|
29
30
|
assert_select 'input[type=number].integer#user_age'
|
30
31
|
end
|
31
32
|
|
32
33
|
test 'builder input_field is able to disable any component' do
|
33
|
-
|
34
|
-
f.input_field :age, html5: false
|
35
|
-
end
|
34
|
+
with_input_field_for @user, :age, html5: false
|
36
35
|
|
37
36
|
assert_no_select 'input[html5=false]#user_age'
|
38
37
|
assert_select 'input[type=text].integer#user_age'
|
39
38
|
end
|
40
39
|
|
41
40
|
test 'builder input_field allows passing options to input tag' do
|
42
|
-
|
43
|
-
f.input_field :name, id: 'name_input', class: 'name'
|
44
|
-
end
|
41
|
+
with_input_field_for @user, :name, id: 'name_input', class: 'name'
|
45
42
|
|
46
43
|
assert_select 'input.string.name#name_input'
|
47
44
|
end
|
48
45
|
|
49
46
|
test 'builder input_field does not modify the options hash' do
|
50
47
|
options = { id: 'name_input', class: 'name' }
|
51
|
-
|
52
|
-
with_concat_form_for(@user) do |f|
|
53
|
-
f.input_field :name, options
|
54
|
-
end
|
48
|
+
with_input_field_for @user, :name, options
|
55
49
|
|
56
50
|
assert_select 'input.string.name#name_input'
|
57
51
|
assert_equal({ id: 'name_input', class: 'name' }, options)
|
@@ -59,9 +53,7 @@ class InputFieldTest < ActionView::TestCase
|
|
59
53
|
|
60
54
|
|
61
55
|
test 'builder input_field generates an input tag with a clean HTML' do
|
62
|
-
|
63
|
-
f.input_field :name, as: :integer, class: 'name'
|
64
|
-
end
|
56
|
+
with_input_field_for @user, :name, as: :integer, class: 'name'
|
65
57
|
|
66
58
|
assert_no_select 'input.integer[input_html]'
|
67
59
|
assert_no_select 'input.integer[as]'
|
@@ -71,67 +63,57 @@ class InputFieldTest < ActionView::TestCase
|
|
71
63
|
store_translations(:en, simple_form: { placeholders: { user: {
|
72
64
|
name: 'Name goes here'
|
73
65
|
} } }) do
|
74
|
-
|
75
|
-
with_concat_form_for(@user) do |f|
|
76
|
-
f.input_field :name
|
77
|
-
end
|
66
|
+
with_input_field_for @user, :name
|
78
67
|
|
79
68
|
assert_select 'input.string[placeholder="Name goes here"]'
|
80
69
|
end
|
81
70
|
end
|
82
71
|
|
83
72
|
test 'builder input_field uses min_max component' do
|
84
|
-
|
85
|
-
f.input_field :age, as: :integer
|
86
|
-
end
|
73
|
+
with_input_field_for @other_validating_user, :age, as: :integer
|
87
74
|
|
88
75
|
assert_select 'input[min="18"]'
|
89
76
|
end
|
90
77
|
|
91
78
|
test 'builder input_field does not use pattern component by default' do
|
92
|
-
|
93
|
-
f.input_field :country, as: :string
|
94
|
-
end
|
79
|
+
with_input_field_for @other_validating_user, :country, as: :string
|
95
80
|
|
96
81
|
assert_no_select 'input[pattern="\w+"]'
|
97
82
|
end
|
98
83
|
|
99
84
|
test 'builder input_field infers pattern from attributes' do
|
100
|
-
|
101
|
-
f.input_field :country, as: :string, pattern: true
|
102
|
-
end
|
85
|
+
with_input_field_for @other_validating_user, :country, as: :string, pattern: true
|
103
86
|
|
104
87
|
assert_select 'input[pattern="\w+"]'
|
105
88
|
end
|
106
89
|
|
107
|
-
test 'builder input_field accepts custom
|
108
|
-
|
109
|
-
f.input_field :country, as: :string, pattern: '\d+'
|
110
|
-
end
|
90
|
+
test 'builder input_field accepts custom pattern' do
|
91
|
+
with_input_field_for @other_validating_user, :country, as: :string, pattern: '\d+'
|
111
92
|
|
112
93
|
assert_select 'input[pattern="\d+"]'
|
113
94
|
end
|
114
95
|
|
115
96
|
test 'builder input_field uses readonly component' do
|
116
|
-
|
117
|
-
f.input_field :age, as: :integer, readonly: true
|
118
|
-
end
|
97
|
+
with_input_field_for @other_validating_user, :age, as: :integer, readonly: true
|
119
98
|
|
120
99
|
assert_select 'input.integer.readonly[readonly]'
|
121
100
|
end
|
122
101
|
|
123
102
|
test 'builder input_field uses maxlength component' do
|
124
|
-
|
125
|
-
f.input_field :name, as: :string
|
126
|
-
end
|
103
|
+
with_input_field_for @validating_user, :name, as: :string
|
127
104
|
|
128
105
|
assert_select 'input.string[maxlength="25"]'
|
129
106
|
end
|
130
107
|
|
108
|
+
test 'builder input_field uses minlength component' do
|
109
|
+
with_input_field_for @validating_user, :name, as: :string
|
110
|
+
|
111
|
+
assert_select 'input.string[minlength="5"]'
|
112
|
+
end
|
113
|
+
|
131
114
|
test 'builder collection input_field generates input tag with a clean HTML' do
|
132
|
-
|
133
|
-
|
134
|
-
end
|
115
|
+
with_input_field_for @user, :status, collection: ['Open', 'Closed'],
|
116
|
+
class: 'status', label_method: :to_s, value_method: :to_s
|
135
117
|
|
136
118
|
assert_no_select 'select.status[input_html]'
|
137
119
|
assert_no_select 'select.status[collection]'
|
@@ -140,48 +122,52 @@ class InputFieldTest < ActionView::TestCase
|
|
140
122
|
end
|
141
123
|
|
142
124
|
test 'build input_field does not treat "boolean_style" as a HTML attribute' do
|
143
|
-
|
144
|
-
f.input_field :active, boolean_style: :nested
|
145
|
-
end
|
125
|
+
with_input_field_for @user, :active, boolean_style: :nested
|
146
126
|
|
147
127
|
assert_no_select 'input.boolean[boolean_style]'
|
148
128
|
end
|
149
129
|
|
130
|
+
test 'build input_field does not treat "prompt" as a HTML attribute' do
|
131
|
+
with_input_field_for @user, :attempts, collection: [1,2,3,4,5], prompt: :translate
|
132
|
+
|
133
|
+
assert_no_select 'select[prompt]'
|
134
|
+
end
|
135
|
+
|
150
136
|
test 'build input_field without pattern component use the pattern string' do
|
151
|
-
swap_wrapper :default,
|
152
|
-
|
153
|
-
f.input_field :name, pattern: '\w+'
|
154
|
-
end
|
137
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
138
|
+
with_input_field_for @user, :name, pattern: '\w+'
|
155
139
|
|
156
140
|
assert_select 'input[pattern="\w+"]'
|
157
141
|
end
|
158
142
|
end
|
159
143
|
|
160
144
|
test 'build input_field without placeholder component use the placeholder string' do
|
161
|
-
swap_wrapper :default,
|
162
|
-
|
163
|
-
f.input_field :name, placeholder: 'Placeholder'
|
164
|
-
end
|
145
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
146
|
+
with_input_field_for @user, :name, placeholder: 'Placeholder'
|
165
147
|
|
166
148
|
assert_select 'input[placeholder="Placeholder"]'
|
167
149
|
end
|
168
150
|
end
|
169
151
|
|
170
152
|
test 'build input_field without maxlength component use the maxlength string' do
|
171
|
-
swap_wrapper :default,
|
172
|
-
|
173
|
-
f.input_field :name, maxlength: 5
|
174
|
-
end
|
153
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
154
|
+
with_input_field_for @user, :name, maxlength: 5
|
175
155
|
|
176
156
|
assert_select 'input[maxlength="5"]'
|
177
157
|
end
|
178
158
|
end
|
179
159
|
|
160
|
+
test 'build input_field without minlength component use the minlength string' do
|
161
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
162
|
+
with_input_field_for @user, :name, minlength: 5
|
163
|
+
|
164
|
+
assert_select 'input[minlength="5"]'
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
180
168
|
test 'build input_field without readonly component use the readonly string' do
|
181
|
-
swap_wrapper :default,
|
182
|
-
|
183
|
-
f.input_field :name, readonly: true
|
184
|
-
end
|
169
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
170
|
+
with_input_field_for @user, :name, readonly: true
|
185
171
|
|
186
172
|
assert_select 'input[readonly="readonly"]'
|
187
173
|
end
|
@@ -29,6 +29,16 @@ class LabelTest < ActionView::TestCase
|
|
29
29
|
assert_select 'label.string.required[for=validating_user_name]', /Name/
|
30
30
|
end
|
31
31
|
|
32
|
+
test 'builder adds a disabled class to label if the attribute is disabled' do
|
33
|
+
with_label_for @validating_user, :name, disabled: true
|
34
|
+
assert_select 'label.string.disabled[for=validating_user_name]', /Name/
|
35
|
+
end
|
36
|
+
|
37
|
+
test 'builder does not add a disabled class to label if the attribute is not disabled' do
|
38
|
+
with_label_for @validating_user, :name, disabled: false
|
39
|
+
assert_no_select 'label.string.disabled[for=validating_user_name]', /Name/
|
40
|
+
end
|
41
|
+
|
32
42
|
test 'builder escapes label text' do
|
33
43
|
with_label_for @user, :name, label: '<script>alert(1337)</script>', required: false
|
34
44
|
assert_no_select 'label.string script'
|
@@ -80,7 +90,7 @@ class LabelTest < ActionView::TestCase
|
|
80
90
|
end
|
81
91
|
|
82
92
|
test 'configuration allow set label text for wrappers' do
|
83
|
-
swap_wrapper :default,
|
93
|
+
swap_wrapper :default, custom_wrapper_with_label_text do
|
84
94
|
with_concat_form_for(@user) do |f|
|
85
95
|
concat f.input :age
|
86
96
|
end
|
@@ -89,7 +99,7 @@ class LabelTest < ActionView::TestCase
|
|
89
99
|
end
|
90
100
|
|
91
101
|
test 'configuration allow set rewrited label tag for wrappers' do
|
92
|
-
swap_wrapper :default,
|
102
|
+
swap_wrapper :default, custom_wrapper_with_custom_label_component do
|
93
103
|
with_concat_form_for(@user) do |f|
|
94
104
|
concat f.input :age
|
95
105
|
end
|
@@ -110,4 +120,11 @@ class LabelTest < ActionView::TestCase
|
|
110
120
|
assert_select 'label[for=user_time_zone]', 'Time Zone:'
|
111
121
|
end
|
112
122
|
end
|
123
|
+
|
124
|
+
test 'builder allows label specific `label_text` option' do
|
125
|
+
with_label_for @user, :time_zone, label_text: lambda { |l, _, _| "#{l.titleize}:" }
|
126
|
+
|
127
|
+
assert_no_select 'label[label_text]'
|
128
|
+
assert_select 'label[for=user_time_zone]', 'Time Zone:'
|
129
|
+
end
|
113
130
|
end
|
@@ -129,7 +129,7 @@ class WrapperTest < ActionView::TestCase
|
|
129
129
|
end
|
130
130
|
|
131
131
|
test 'custom wrappers can have additional attributes' do
|
132
|
-
swap_wrapper :default,
|
132
|
+
swap_wrapper :default, custom_wrapper_with_additional_attributes do
|
133
133
|
with_form_for @user, :name
|
134
134
|
|
135
135
|
assert_select "div.custom_wrapper[title='some title'][data-wrapper='test']"
|
@@ -137,7 +137,7 @@ class WrapperTest < ActionView::TestCase
|
|
137
137
|
end
|
138
138
|
|
139
139
|
test 'custom wrappers can have full error message on attributes' do
|
140
|
-
swap_wrapper :default,
|
140
|
+
swap_wrapper :default, custom_wrapper_with_full_error do
|
141
141
|
with_form_for @user, :name
|
142
142
|
assert_select 'span.error', "Name cannot be blank"
|
143
143
|
end
|
@@ -188,7 +188,7 @@ class WrapperTest < ActionView::TestCase
|
|
188
188
|
end
|
189
189
|
|
190
190
|
test 'does not duplicate label classes for different inputs' do
|
191
|
-
swap_wrapper :default,
|
191
|
+
swap_wrapper :default, custom_wrapper_with_label_html_option do
|
192
192
|
with_concat_form_for(@user) do |f|
|
193
193
|
concat f.input :name, required: false
|
194
194
|
concat f.input :email, as: :email, required: true
|
@@ -242,8 +242,40 @@ class WrapperTest < ActionView::TestCase
|
|
242
242
|
assert_select "section.custom_wrapper div.another_wrapper input.string"
|
243
243
|
end
|
244
244
|
|
245
|
+
test "input attributes class will merge with wrapper_options' classes" do
|
246
|
+
swap_wrapper :default, custom_wrapper_with_input_class do
|
247
|
+
with_concat_form_for @user do |f|
|
248
|
+
concat f.input :name, input_html: { class: 'another-class' }
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
assert_select "div.custom_wrapper input.string.inline-class.another-class"
|
253
|
+
end
|
254
|
+
|
255
|
+
test "input with data attributes will merge with wrapper_options' data" do
|
256
|
+
swap_wrapper :default, custom_wrapper_with_input_data_modal do
|
257
|
+
with_concat_form_for @user do |f|
|
258
|
+
concat f.input :name, input_html: { data: { modal: 'another-data', target: 'merge-data' } }
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
assert_select "input[data-wrapper='data-wrapper'][data-modal='another-data'][data-target='merge-data']"
|
263
|
+
end
|
264
|
+
|
265
|
+
test "input with aria attributes will merge with wrapper_options' aria" do
|
266
|
+
skip unless ActionPack::VERSION::MAJOR == '4' && ActionPack::VERSION::MINOR >= '2'
|
267
|
+
|
268
|
+
swap_wrapper :default, custom_wrapper_with_input_aria_modal do
|
269
|
+
with_concat_form_for @user do |f|
|
270
|
+
concat f.input :name, input_html: { aria: { modal: 'another-aria', target: 'merge-aria' } }
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
assert_select "input[aria-wrapper='aria-wrapper'][aria-modal='another-aria'][aria-target='merge-aria']"
|
275
|
+
end
|
276
|
+
|
245
277
|
test 'input accepts attributes in the DSL' do
|
246
|
-
swap_wrapper :default,
|
278
|
+
swap_wrapper :default, custom_wrapper_with_input_class do
|
247
279
|
with_concat_form_for @user do |f|
|
248
280
|
concat f.input :name
|
249
281
|
end
|
@@ -253,7 +285,7 @@ class WrapperTest < ActionView::TestCase
|
|
253
285
|
end
|
254
286
|
|
255
287
|
test 'label accepts attributes in the DSL' do
|
256
|
-
swap_wrapper :default,
|
288
|
+
swap_wrapper :default, custom_wrapper_with_label_class do
|
257
289
|
with_concat_form_for @user do |f|
|
258
290
|
concat f.input :name
|
259
291
|
end
|
@@ -263,7 +295,7 @@ class WrapperTest < ActionView::TestCase
|
|
263
295
|
end
|
264
296
|
|
265
297
|
test 'label_input accepts attributes in the DSL' do
|
266
|
-
swap_wrapper :default,
|
298
|
+
swap_wrapper :default, custom_wrapper_with_label_input_class do
|
267
299
|
with_concat_form_for @user do |f|
|
268
300
|
concat f.input :name
|
269
301
|
end
|
@@ -274,7 +306,7 @@ class WrapperTest < ActionView::TestCase
|
|
274
306
|
end
|
275
307
|
|
276
308
|
test 'input accepts data attributes in the DSL' do
|
277
|
-
swap_wrapper :default,
|
309
|
+
swap_wrapper :default, custom_wrapper_with_input_attributes do
|
278
310
|
with_concat_form_for @user do |f|
|
279
311
|
concat f.input :name
|
280
312
|
end
|
@@ -284,7 +316,7 @@ class WrapperTest < ActionView::TestCase
|
|
284
316
|
end
|
285
317
|
|
286
318
|
test 'inline wrapper displays when there is content' do
|
287
|
-
swap_wrapper :default,
|
319
|
+
swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do
|
288
320
|
with_form_for @user, :name, hint: "cannot be blank"
|
289
321
|
assert_select 'section.custom_wrapper div.no_output_wrapper p.omg_hint', "cannot be blank"
|
290
322
|
assert_select 'p.omg_hint'
|
@@ -292,7 +324,7 @@ class WrapperTest < ActionView::TestCase
|
|
292
324
|
end
|
293
325
|
|
294
326
|
test 'inline wrapper does not display when there is no content' do
|
295
|
-
swap_wrapper :default,
|
327
|
+
swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do
|
296
328
|
with_form_for @user, :name
|
297
329
|
assert_select 'section.custom_wrapper div.no_output_wrapper'
|
298
330
|
assert_no_select 'p.omg_hint'
|
@@ -300,7 +332,7 @@ class WrapperTest < ActionView::TestCase
|
|
300
332
|
end
|
301
333
|
|
302
334
|
test 'optional wrapper does not display when there is content' do
|
303
|
-
swap_wrapper :default,
|
335
|
+
swap_wrapper :default, custom_wrapper_with_unless_blank do
|
304
336
|
with_form_for @user, :name, hint: "can't be blank"
|
305
337
|
assert_select 'section.custom_wrapper div.no_output_wrapper'
|
306
338
|
assert_select 'div.no_output_wrapper'
|
@@ -309,7 +341,7 @@ class WrapperTest < ActionView::TestCase
|
|
309
341
|
end
|
310
342
|
|
311
343
|
test 'optional wrapper does not display when there is no content' do
|
312
|
-
swap_wrapper :default,
|
344
|
+
swap_wrapper :default, custom_wrapper_with_unless_blank do
|
313
345
|
with_form_for @user, :name
|
314
346
|
assert_no_select 'section.custom_wrapper div.no_output_wrapper'
|
315
347
|
assert_no_select 'div.no_output_wrapper'
|
@@ -137,6 +137,14 @@ class BooleanInputTest < ActionView::TestCase
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
+
test 'input with nested style allows disabling hidden field' do
|
141
|
+
swap SimpleForm, boolean_style: :nested do
|
142
|
+
with_input_for @user, :active, :boolean, include_hidden: false
|
143
|
+
assert_select "label.boolean > input.boolean"
|
144
|
+
assert_no_select "input[type=hidden] + label.boolean"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
140
148
|
test 'input boolean works using :input only in wrapper config (no label_input)' do
|
141
149
|
swap_wrapper do
|
142
150
|
with_input_for @user, :active, :boolean
|
@@ -156,6 +164,16 @@ class BooleanInputTest < ActionView::TestCase
|
|
156
164
|
end
|
157
165
|
end
|
158
166
|
|
167
|
+
test 'input boolean allows specifying boolean_label_class on a per-input basis' do
|
168
|
+
swap_wrapper do
|
169
|
+
swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
|
170
|
+
with_input_for @user, :active, :boolean, boolean_label_class: 'baz'
|
171
|
+
|
172
|
+
assert_select 'label.boolean + input[type=hidden] + label.baz > input.boolean'
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
159
177
|
test 'input boolean with nested style works using :input only in wrapper config (no label_input), adding the extra label wrapper with custom class' do
|
160
178
|
swap_wrapper do
|
161
179
|
swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
|
@@ -6,7 +6,11 @@ class DateTimeInputWithHtml5Test < ActionView::TestCase
|
|
6
6
|
test 'input generates a datetime input for datetime attributes if HTML5 compatibility is explicitly enbled' do
|
7
7
|
with_input_for @user, :created_at, :datetime, html5: true
|
8
8
|
|
9
|
-
|
9
|
+
if ActionPack::VERSION::STRING >= '5'
|
10
|
+
assert_select 'input[type="datetime-local"]'
|
11
|
+
elsif ActionPack::VERSION::STRING < '5'
|
12
|
+
assert_select 'input[type="datetime"]'
|
13
|
+
end
|
10
14
|
end
|
11
15
|
|
12
16
|
test 'input generates a datetime select for datetime attributes' do
|
@@ -76,7 +80,11 @@ class DateTimeInputWithoutHtml5Test < ActionView::TestCase
|
|
76
80
|
swap_wrapper do
|
77
81
|
with_input_for @user, :created_at, :datetime, html5: true
|
78
82
|
|
79
|
-
|
83
|
+
if ActionPack::VERSION::STRING >= '5'
|
84
|
+
assert_select 'input[type="datetime-local"]'
|
85
|
+
elsif ActionPack::VERSION::STRING < '5'
|
86
|
+
assert_select 'input[type="datetime"]'
|
87
|
+
end
|
80
88
|
end
|
81
89
|
end
|
82
90
|
|
@@ -169,4 +177,9 @@ class DateTimeInputWithoutHtml5Test < ActionView::TestCase
|
|
169
177
|
with_input_for :project, :created_at, :time, html5: false
|
170
178
|
assert_select 'label[for=project_created_at_4i]'
|
171
179
|
end
|
180
|
+
|
181
|
+
test 'label points to attribute name if HTML5 compatibility is explicitly enabled' do
|
182
|
+
with_input_for :project, :created_at, :date, html5: true
|
183
|
+
assert_select 'label[for=project_created_at]'
|
184
|
+
end
|
172
185
|
end
|
@@ -14,6 +14,7 @@ class DiscoveryTest < ActionView::TestCase
|
|
14
14
|
Object.send :remove_const, :CustomizedInput
|
15
15
|
Object.send :remove_const, :DeprecatedInput
|
16
16
|
Object.send :remove_const, :CollectionSelectInput
|
17
|
+
CustomInputs.send :remove_const, :CustomizedInput
|
17
18
|
CustomInputs.send :remove_const, :PasswordInput
|
18
19
|
CustomInputs.send :remove_const, :NumericInput
|
19
20
|
end
|
@@ -113,6 +113,9 @@ class NumericInputTest < ActionView::TestCase
|
|
113
113
|
|
114
114
|
with_input_for @validating_user, :age, :integer
|
115
115
|
assert_select 'input[step="1"]'
|
116
|
+
|
117
|
+
with_input_for @validating_user, :age, :integer, as: :decimal, input_html: { step: 0.5 }
|
118
|
+
assert_select 'input[step="0.5"]'
|
116
119
|
end
|
117
120
|
|
118
121
|
test 'numeric input does not generate placeholder by default' do
|
@@ -5,14 +5,22 @@ class PriorityInputTest < ActionView::TestCase
|
|
5
5
|
test 'input generates a country select field' do
|
6
6
|
with_input_for @user, :country, :country
|
7
7
|
assert_select 'select#user_country'
|
8
|
-
|
8
|
+
if ActionPack::VERSION::STRING >= '5'
|
9
|
+
assert_select 'select option[value=BR]', 'Brazil'
|
10
|
+
elsif ActionPack::VERSION::STRING < '5'
|
11
|
+
assert_select 'select option[value=Brazil]', 'Brazil'
|
12
|
+
end
|
9
13
|
assert_no_select 'select option[value=""][disabled=disabled]'
|
10
14
|
end
|
11
15
|
|
12
16
|
test 'input generates a country select with SimpleForm default' do
|
13
17
|
swap SimpleForm, country_priority: [ 'Brazil' ] do
|
14
18
|
with_input_for @user, :country, :country
|
15
|
-
|
19
|
+
if ActionPack::VERSION::STRING >= '5'
|
20
|
+
assert_select 'select option[value="---------------"][disabled=disabled]'
|
21
|
+
elsif ActionPack::VERSION::STRING < '5'
|
22
|
+
assert_select 'select option[value=""][disabled=disabled]'
|
23
|
+
end
|
16
24
|
end
|
17
25
|
end
|
18
26
|
|
@@ -34,6 +34,38 @@ class RequiredTest < ActionView::TestCase
|
|
34
34
|
with_input_for @user, :name, :string
|
35
35
|
assert_select 'input[type=text].required'
|
36
36
|
assert_no_select 'input[type=text][required]'
|
37
|
+
assert_no_select 'input[type=text][aria-required]'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
test 'when not using browser validations, when required option is set to false, input does not generate required html attribute' do
|
42
|
+
swap SimpleForm, browser_validations: false do
|
43
|
+
with_input_for @user, :name, :string, required: false
|
44
|
+
assert_no_select 'input[type=text].required'
|
45
|
+
assert_no_select 'input[type=text][required]'
|
46
|
+
assert_no_select 'input[type=text][aria-required]'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
test 'when not using browser validations, when required option is set to true, input generates required html attribute' do
|
51
|
+
swap SimpleForm, browser_validations: false do
|
52
|
+
with_input_for @user, :name, :string, required: true
|
53
|
+
assert_select 'input[type=text].required'
|
54
|
+
assert_select 'input[type=text][required]'
|
55
|
+
assert_select 'input[type=text][aria-required]'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
test 'when not using browser validations, when required option is true in the wrapper, input does not generate required html attribute' do
|
60
|
+
swap SimpleForm, browser_validations: false do
|
61
|
+
swap_wrapper :default, self.custom_wrapper_with_required_input do
|
62
|
+
with_concat_form_for(@user) do |f|
|
63
|
+
concat f.input :name
|
64
|
+
end
|
65
|
+
assert_select 'input[type=text].required'
|
66
|
+
assert_no_select 'input[type=text][required]'
|
67
|
+
assert_no_select 'input[type=text][aria-required]'
|
68
|
+
end
|
37
69
|
end
|
38
70
|
end
|
39
71
|
|
@@ -110,4 +142,16 @@ class RequiredTest < ActionView::TestCase
|
|
110
142
|
assert_no_select 'input[required]'
|
111
143
|
assert_select 'input.optional#validating_user_phone_number'
|
112
144
|
end
|
145
|
+
|
146
|
+
test 'builder input does not generate required html attribute when option is set to false when it is set to true in wrapper' do
|
147
|
+
swap SimpleForm, browser_validations: true do
|
148
|
+
swap_wrapper :default, self.custom_wrapper_with_required_input do
|
149
|
+
with_concat_form_for(@user) do |f|
|
150
|
+
concat f.input :name, required: false
|
151
|
+
end
|
152
|
+
assert_no_select 'input[type=text][required]'
|
153
|
+
assert_no_select 'input[type=text][aria-required]'
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
113
157
|
end
|
@@ -32,9 +32,21 @@ class StringInputTest < ActionView::TestCase
|
|
32
32
|
assert_select 'input.string[maxlength="25"]'
|
33
33
|
end
|
34
34
|
|
35
|
-
test 'input
|
36
|
-
with_input_for @validating_user, :
|
37
|
-
|
35
|
+
test 'input infers minlength column definition from validation when present' do
|
36
|
+
with_input_for @validating_user, :name, :string
|
37
|
+
assert_select 'input.string[minlength="5"]'
|
38
|
+
end
|
39
|
+
|
40
|
+
if ActionPack::VERSION::STRING < '5'
|
41
|
+
test 'input does not get maxlength from validation when tokenizer present' do
|
42
|
+
with_input_for @validating_user, :action, :string
|
43
|
+
assert_no_select 'input.string[maxlength]'
|
44
|
+
end
|
45
|
+
|
46
|
+
test 'input does not get minlength from validation when tokenizer present' do
|
47
|
+
with_input_for @validating_user, :action, :string
|
48
|
+
assert_no_select 'input.string[minlength]'
|
49
|
+
end
|
38
50
|
end
|
39
51
|
|
40
52
|
test 'input gets maxlength from validation when :is option present' do
|
@@ -42,6 +54,11 @@ class StringInputTest < ActionView::TestCase
|
|
42
54
|
assert_select 'input.string[maxlength="12"]'
|
43
55
|
end
|
44
56
|
|
57
|
+
test 'input gets minlength from validation when :is option present' do
|
58
|
+
with_input_for @validating_user, :home_picture, :string
|
59
|
+
assert_select 'input.string[minlength="12"]'
|
60
|
+
end
|
61
|
+
|
45
62
|
test 'input maxlength is the column limit plus one to make room for decimal point' do
|
46
63
|
with_input_for @user, :credit_limit, :string
|
47
64
|
|
@@ -115,15 +132,6 @@ class StringInputTest < ActionView::TestCase
|
|
115
132
|
end
|
116
133
|
end
|
117
134
|
|
118
|
-
test 'input translates 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
|
-
|
127
135
|
[:email, :url, :search, :tel].each do |type|
|
128
136
|
test "input allows type #{type}" do
|
129
137
|
with_input_for @user, :name, type
|
@@ -12,6 +12,13 @@ class TextInputTest < ActionView::TestCase
|
|
12
12
|
assert_select 'textarea.text[placeholder="Put in some text"]'
|
13
13
|
end
|
14
14
|
|
15
|
+
test 'input generates a placeholder from the translations' do
|
16
|
+
store_translations(:en, simple_form: { placeholders: { user: { name: "placeholder from i18n en.simple_form.placeholders.user.name" } } }) do
|
17
|
+
with_input_for @user, :name, :text
|
18
|
+
assert_select 'textarea.text[placeholder="placeholder from i18n en.simple_form.placeholders.user.name"]'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
15
22
|
test 'input gets maxlength from column definition for text attributes' do
|
16
23
|
with_input_for @user, :description, :text
|
17
24
|
assert_select 'textarea.text[maxlength="200"]'
|
@@ -21,4 +28,9 @@ class TextInputTest < ActionView::TestCase
|
|
21
28
|
with_input_for @validating_user, :description, :text
|
22
29
|
assert_select 'textarea.text[maxlength="50"]'
|
23
30
|
end
|
31
|
+
|
32
|
+
test 'input infers minlength column definition from validation when present for text attributes' do
|
33
|
+
with_input_for @validating_user, :description, :text
|
34
|
+
assert_select 'textarea.text[minlength="15"]'
|
35
|
+
end
|
24
36
|
end
|