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.

Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +67 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +70 -31
  5. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +5 -2
  6. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +19 -1
  7. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +5 -2
  8. data/lib/simple_form/action_view_extensions/form_helper.rb +3 -1
  9. data/lib/simple_form/components/html5.rb +14 -4
  10. data/lib/simple_form/components/labels.rb +1 -1
  11. data/lib/simple_form/components/maxlength.rb +17 -4
  12. data/lib/simple_form/components/minlength.rb +47 -0
  13. data/lib/simple_form/components.rb +1 -0
  14. data/lib/simple_form/form_builder.rb +17 -9
  15. data/lib/simple_form/inputs/base.rb +12 -10
  16. data/lib/simple_form/inputs/boolean_input.rb +11 -2
  17. data/lib/simple_form/inputs/collection_input.rb +4 -3
  18. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +1 -1
  19. data/lib/simple_form/inputs/date_time_input.rb +12 -8
  20. data/lib/simple_form/inputs/password_input.rb +1 -1
  21. data/lib/simple_form/inputs/string_input.rb +1 -1
  22. data/lib/simple_form/inputs/text_input.rb +1 -1
  23. data/lib/simple_form/version.rb +1 -1
  24. data/lib/simple_form.rb +1 -4
  25. data/test/form_builder/error_test.rb +32 -9
  26. data/test/form_builder/general_test.rb +40 -8
  27. data/test/form_builder/input_field_test.rb +53 -67
  28. data/test/form_builder/label_test.rb +19 -2
  29. data/test/form_builder/wrapper_test.rb +43 -11
  30. data/test/inputs/boolean_input_test.rb +18 -0
  31. data/test/inputs/datetime_input_test.rb +15 -2
  32. data/test/inputs/discovery_test.rb +1 -0
  33. data/test/inputs/numeric_input_test.rb +3 -0
  34. data/test/inputs/priority_input_test.rb +10 -2
  35. data/test/inputs/required_test.rb +44 -0
  36. data/test/inputs/string_input_test.rb +20 -12
  37. data/test/inputs/text_input_test.rb +12 -0
  38. data/test/support/misc_helpers.rb +22 -1
  39. data/test/support/mock_controller.rb +3 -1
  40. data/test/support/models.rb +41 -7
  41. data/test/test_helper.rb +6 -0
  42. 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
- test "builder input_field only renders the input tag, nothing else" do
6
- with_concat_form_for(@user) do |f|
7
- f.input_field :name
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
- with_concat_form_for(@user) do |f|
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
- with_concat_form_for(@user) do |f|
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
- with_concat_form_for(@user) do |f|
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
- with_concat_form_for(@user) do |f|
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
- with_concat_form_for(@user) do |f|
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
- with_concat_form_for(@other_validating_user) do |f|
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
- with_concat_form_for(@other_validating_user) do |f|
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
- with_concat_form_for(@other_validating_user) do |f|
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 patter' do
108
- with_concat_form_for(@other_validating_user) do |f|
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
- with_concat_form_for(@other_validating_user) do |f|
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
- with_concat_form_for(@validating_user) do |f|
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
- with_concat_form_for(@user) do |f|
133
- f.input_field :status, collection: ['Open', 'Closed'], class: 'status', label_method: :to_s, value_method: :to_s
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
- with_concat_form_for(@user) do |f|
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, self.custom_wrapper_with_html5_components do
152
- with_concat_form_for(@user) do |f|
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, self.custom_wrapper_with_html5_components do
162
- with_concat_form_for(@user) do |f|
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, self.custom_wrapper_with_html5_components do
172
- with_concat_form_for(@user) do |f|
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, self.custom_wrapper_with_html5_components do
182
- with_concat_form_for(@user) do |f|
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, self.custom_wrapper_with_label_text do
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, self.custom_wrapper_with_custom_label_component do
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, self.custom_wrapper_with_additional_attributes do
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, self.custom_wrapper_with_full_error do
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, self.custom_wrapper_with_label_html_option do
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, self.custom_wrapper_with_input_class do
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, self.custom_wrapper_with_label_class do
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, self.custom_wrapper_with_label_input_class do
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, self.custom_wrapper_with_input_attributes do
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, self.custom_wrapper_with_wrapped_optional_component do
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, self.custom_wrapper_with_wrapped_optional_component do
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, self.custom_wrapper_with_unless_blank do
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, self.custom_wrapper_with_unless_blank do
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
- assert_select 'input[type="datetime"]'
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
- assert_select 'input[type="datetime"]'
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
- assert_select 'select option[value=Brazil]', 'Brazil'
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
- assert_select 'select option[value=""][disabled=disabled]'
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 does not get maxlength from validation when tokenizer present' do
36
- with_input_for @validating_user, :action, :string
37
- assert_no_select 'input.string[maxlength]'
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