simple_form 3.4.0 → 5.1.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +118 -8
- data/MIT-LICENSE +2 -1
- data/README.md +235 -67
- data/lib/generators/simple_form/install_generator.rb +1 -0
- data/lib/generators/simple_form/templates/README +2 -3
- data/lib/generators/simple_form/templates/_form.html.erb +2 -0
- data/lib/generators/simple_form/templates/_form.html.haml +2 -0
- data/lib/generators/simple_form/templates/_form.html.slim +1 -0
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +14 -7
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +360 -74
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +20 -8
- data/lib/simple_form/action_view_extensions/builder.rb +1 -0
- data/lib/simple_form/action_view_extensions/form_helper.rb +1 -0
- data/lib/simple_form/components/errors.rb +15 -2
- data/lib/simple_form/components/hints.rb +1 -0
- data/lib/simple_form/components/html5.rb +1 -0
- data/lib/simple_form/components/label_input.rb +2 -1
- data/lib/simple_form/components/labels.rb +12 -7
- data/lib/simple_form/components/maxlength.rb +4 -17
- data/lib/simple_form/components/min_max.rb +1 -0
- data/lib/simple_form/components/minlength.rb +5 -18
- data/lib/simple_form/components/pattern.rb +1 -0
- data/lib/simple_form/components/placeholders.rb +2 -1
- data/lib/simple_form/components/readonly.rb +1 -0
- data/lib/simple_form/components.rb +1 -0
- data/lib/simple_form/error_notification.rb +1 -0
- data/lib/simple_form/form_builder.rb +104 -29
- data/lib/simple_form/helpers/autofocus.rb +1 -0
- data/lib/simple_form/helpers/disabled.rb +1 -0
- data/lib/simple_form/helpers/readonly.rb +1 -0
- data/lib/simple_form/helpers/required.rb +1 -0
- data/lib/simple_form/helpers/validators.rb +2 -1
- data/lib/simple_form/helpers.rb +1 -0
- data/lib/simple_form/inputs/base.rb +24 -5
- data/lib/simple_form/inputs/block_input.rb +1 -0
- data/lib/simple_form/inputs/boolean_input.rb +4 -2
- data/lib/simple_form/inputs/collection_check_boxes_input.rb +3 -2
- data/lib/simple_form/inputs/collection_input.rb +6 -7
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +2 -1
- data/lib/simple_form/inputs/collection_select_input.rb +1 -0
- data/lib/simple_form/inputs/color_input.rb +14 -0
- data/lib/simple_form/inputs/date_time_input.rb +1 -0
- data/lib/simple_form/inputs/file_input.rb +1 -0
- data/lib/simple_form/inputs/grouped_collection_select_input.rb +1 -0
- data/lib/simple_form/inputs/hidden_input.rb +1 -0
- data/lib/simple_form/inputs/numeric_input.rb +1 -0
- data/lib/simple_form/inputs/password_input.rb +1 -0
- data/lib/simple_form/inputs/priority_input.rb +1 -4
- data/lib/simple_form/inputs/range_input.rb +1 -0
- data/lib/simple_form/inputs/rich_text_area_input.rb +12 -0
- data/lib/simple_form/inputs/string_input.rb +2 -1
- data/lib/simple_form/inputs/text_input.rb +1 -0
- data/lib/simple_form/inputs.rb +3 -0
- data/lib/simple_form/map_type.rb +1 -0
- data/lib/simple_form/railtie.rb +1 -0
- data/lib/simple_form/tags.rb +7 -2
- data/lib/simple_form/version.rb +2 -1
- data/lib/simple_form/wrappers/builder.rb +1 -0
- data/lib/simple_form/wrappers/leaf.rb +2 -1
- data/lib/simple_form/wrappers/many.rb +1 -0
- data/lib/simple_form/wrappers/root.rb +9 -2
- data/lib/simple_form/wrappers/single.rb +2 -1
- data/lib/simple_form/wrappers.rb +1 -0
- data/lib/simple_form.rb +79 -11
- data/test/action_view_extensions/builder_test.rb +28 -9
- data/test/action_view_extensions/form_helper_test.rb +3 -2
- data/test/components/custom_components_test.rb +62 -0
- data/test/components/label_test.rb +33 -8
- data/test/form_builder/association_test.rb +33 -2
- data/test/form_builder/button_test.rb +1 -0
- data/test/form_builder/error_notification_test.rb +1 -0
- data/test/form_builder/error_test.rb +12 -0
- data/test/form_builder/general_test.rb +75 -13
- data/test/form_builder/hint_test.rb +6 -0
- data/test/form_builder/input_field_test.rb +30 -10
- data/test/form_builder/label_test.rb +10 -4
- data/test/form_builder/wrapper_test.rb +32 -5
- data/test/generators/simple_form_generator_test.rb +4 -3
- data/test/inputs/boolean_input_test.rb +17 -0
- data/test/inputs/collection_check_boxes_input_test.rb +38 -18
- data/test/inputs/collection_radio_buttons_input_test.rb +48 -28
- data/test/inputs/collection_select_input_test.rb +46 -43
- data/test/inputs/color_input_test.rb +10 -0
- data/test/inputs/datetime_input_test.rb +7 -16
- data/test/inputs/disabled_test.rb +14 -0
- data/test/inputs/discovery_test.rb +22 -0
- data/test/inputs/file_input_test.rb +1 -0
- data/test/inputs/general_test.rb +3 -2
- data/test/inputs/grouped_collection_select_input_test.rb +11 -10
- data/test/inputs/hidden_input_test.rb +1 -0
- data/test/inputs/numeric_input_test.rb +2 -1
- data/test/inputs/priority_input_test.rb +7 -14
- data/test/inputs/readonly_test.rb +1 -0
- data/test/inputs/required_test.rb +1 -0
- data/test/inputs/rich_text_area_input_test.rb +15 -0
- data/test/inputs/string_input_test.rb +10 -16
- data/test/inputs/text_input_test.rb +1 -0
- data/test/simple_form_test.rb +1 -0
- data/test/support/discovery_inputs.rb +8 -0
- data/test/support/misc_helpers.rb +22 -1
- data/test/support/mock_controller.rb +7 -1
- data/test/support/models.rb +80 -18
- data/test/test_helper.rb +9 -4
- metadata +49 -55
- data/lib/simple_form/i18n_cache.rb +0 -22
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
# Module that represents a custom component.
|
6
|
+
module Numbers
|
7
|
+
def number(wrapper_options = nil)
|
8
|
+
@number ||= options[:number].to_s.html_safe
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Module that represents a custom component.
|
13
|
+
module InputGroup
|
14
|
+
def prepend(wrapper_options = nil)
|
15
|
+
span_tag = content_tag(:span, options[:prepend], class: 'input-group-text')
|
16
|
+
template.content_tag(:div, span_tag, class: 'input-group-prepend')
|
17
|
+
end
|
18
|
+
|
19
|
+
def append(wrapper_options = nil)
|
20
|
+
span_tag = content_tag(:span, options[:append], class: 'input-group-text')
|
21
|
+
template.content_tag(:div, span_tag, class: 'input-group-append')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class CustomComponentsTest < ActionView::TestCase
|
26
|
+
test 'includes the custom components' do
|
27
|
+
SimpleForm.include_component Numbers
|
28
|
+
|
29
|
+
custom_wrapper = SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
|
30
|
+
b.use :number, wrap_with: { tag: 'div', class: 'number' }
|
31
|
+
end
|
32
|
+
|
33
|
+
with_form_for @user, :name, number: 1, wrapper: custom_wrapper
|
34
|
+
|
35
|
+
assert_select 'div.number', text: '1'
|
36
|
+
end
|
37
|
+
|
38
|
+
test 'includes custom components and use it as optional in the wrapper' do
|
39
|
+
SimpleForm.include_component InputGroup
|
40
|
+
|
41
|
+
custom_wrapper = SimpleForm.build tag: :div, class: 'custom_wrapper' do |b|
|
42
|
+
b.use :label
|
43
|
+
b.optional :prepend
|
44
|
+
b.use :input
|
45
|
+
b.use :append
|
46
|
+
end
|
47
|
+
|
48
|
+
with_form_for @user, :name, prepend: true, wrapper: custom_wrapper
|
49
|
+
|
50
|
+
assert_select 'div.input-group-prepend > span.input-group-text'
|
51
|
+
assert_select 'div.input-group-append > span.input-group-text'
|
52
|
+
end
|
53
|
+
|
54
|
+
test 'raises a TypeError when the component is not a Module' do
|
55
|
+
component = 'MyComponent'
|
56
|
+
|
57
|
+
exception = assert_raises TypeError do
|
58
|
+
SimpleForm.include_component(component)
|
59
|
+
end
|
60
|
+
assert_equal exception.message, "SimpleForm.include_component expects a module but got: String"
|
61
|
+
end
|
62
|
+
end
|
@@ -1,12 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# encoding: UTF-8
|
2
3
|
require 'test_helper'
|
3
4
|
|
4
5
|
# Isolated tests for label without triggering f.label.
|
5
6
|
class IsolatedLabelTest < ActionView::TestCase
|
6
|
-
setup do
|
7
|
-
SimpleForm::Inputs::Base.reset_i18n_cache :translate_required_html
|
8
|
-
end
|
9
|
-
|
10
7
|
def with_label_for(object, attribute_name, type, options = {})
|
11
8
|
with_concat_form_for(object) do |f|
|
12
9
|
options[:reflection] = Association.new(Company, :company, {}) if options.delete(:setup_association)
|
@@ -177,7 +174,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
177
174
|
end
|
178
175
|
|
179
176
|
test 'label does not have css class from type when generate_additional_classes_for does not include :label' do
|
180
|
-
swap SimpleForm, generate_additional_classes_for: [
|
177
|
+
swap SimpleForm, generate_additional_classes_for: %i[wrapper input] do
|
181
178
|
with_label_for @user, :name, :string
|
182
179
|
assert_no_select 'label.string'
|
183
180
|
with_label_for @user, :description, :text
|
@@ -192,7 +189,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
192
189
|
end
|
193
190
|
|
194
191
|
test 'label does not generate empty css class' do
|
195
|
-
swap SimpleForm, generate_additional_classes_for: [
|
192
|
+
swap SimpleForm, generate_additional_classes_for: %i[wrapper input] do
|
196
193
|
with_label_for @user, :name, :string
|
197
194
|
assert_no_select 'label[class]'
|
198
195
|
end
|
@@ -206,7 +203,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
206
203
|
end
|
207
204
|
|
208
205
|
test 'label does not obtain required from ActiveModel::Validations when generate_additional_classes_for does not include :label' do
|
209
|
-
swap SimpleForm, generate_additional_classes_for: [
|
206
|
+
swap SimpleForm, generate_additional_classes_for: %i[wrapper input] do
|
210
207
|
with_label_for @validating_user, :name, :string
|
211
208
|
assert_no_select 'label.required'
|
212
209
|
with_label_for @validating_user, :status, :string
|
@@ -248,6 +245,15 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
248
245
|
end
|
249
246
|
end
|
250
247
|
|
248
|
+
test 'label uses custom i18n scope to find required text' do
|
249
|
+
store_translations(:en, my_scope: { required: { text: 'Pflichtfeld' } }) do
|
250
|
+
swap SimpleForm, i18n_scope: :my_scope do
|
251
|
+
with_label_for @user, :name, :string
|
252
|
+
assert_select 'form label abbr[title="Pflichtfeld"]', '*'
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
251
257
|
test 'label uses i18n to find required mark' do
|
252
258
|
store_translations(:en, simple_form: { required: { mark: '*-*' } }) do
|
253
259
|
with_label_for @user, :name, :string
|
@@ -255,6 +261,15 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
255
261
|
end
|
256
262
|
end
|
257
263
|
|
264
|
+
test 'label uses custom i18n scope to find required mark' do
|
265
|
+
store_translations(:en, my_scope: { required: { mark: '!!' } }) do
|
266
|
+
swap SimpleForm, i18n_scope: :my_scope do
|
267
|
+
with_label_for @user, :name, :string
|
268
|
+
assert_select 'form label abbr', '!!'
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
258
273
|
test 'label uses i18n to find required string tag' do
|
259
274
|
store_translations(:en, simple_form: { required: { html: '<span class="required" title="requerido">*</span>' } }) do
|
260
275
|
with_label_for @user, :name, :string
|
@@ -263,6 +278,16 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
263
278
|
end
|
264
279
|
end
|
265
280
|
|
281
|
+
test 'label uses custom i18n scope to find required string tag' do
|
282
|
+
store_translations(:en, my_scope: { required: { html: '<span class="mandatory" title="Pflichtfeld">!!</span>' } }) do
|
283
|
+
swap SimpleForm, i18n_scope: :my_scope do
|
284
|
+
with_label_for @user, :name, :string
|
285
|
+
assert_no_select 'form label abbr'
|
286
|
+
assert_select 'form label span.mandatory[title=Pflichtfeld]', '!!'
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
266
291
|
test 'label allows overwriting input id' do
|
267
292
|
with_label_for @user, :name, :string, input_html: { id: 'my_new_id' }
|
268
293
|
assert_select 'label[for=my_new_id]'
|
@@ -289,7 +314,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
289
314
|
end
|
290
315
|
|
291
316
|
test 'label includes for attribute for select collection' do
|
292
|
-
with_label_for @user, :sex, :select, collection: [
|
317
|
+
with_label_for @user, :sex, :select, collection: %i[male female]
|
293
318
|
assert_select 'label[for=user_sex]'
|
294
319
|
end
|
295
320
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# encoding: UTF-8
|
2
3
|
require 'test_helper'
|
3
4
|
|
@@ -14,6 +15,12 @@ class AssociationTest < ActionView::TestCase
|
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
18
|
+
test 'builder association works with decorated object responsive to #to_model' do
|
19
|
+
assert_nothing_raised do
|
20
|
+
with_association_for @decorated_user, :company
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
17
24
|
test 'builder association with a block calls simple_fields_for' do
|
18
25
|
simple_form_for @user do |f|
|
19
26
|
f.association :posts do |posts_form|
|
@@ -121,6 +128,15 @@ class AssociationTest < ActionView::TestCase
|
|
121
128
|
assert_no_select 'form select option[value="2"]'
|
122
129
|
end
|
123
130
|
|
131
|
+
test 'builder allows collection to have a scope with parameter' do
|
132
|
+
with_association_for @user, :special_tags
|
133
|
+
assert_select 'form select.select#user_special_tag_ids'
|
134
|
+
assert_select 'form select[multiple=multiple]'
|
135
|
+
assert_select 'form select option[value="1"]', 'Tag 1'
|
136
|
+
assert_no_select 'form select option[value="2"]'
|
137
|
+
assert_no_select 'form select option[value="3"]'
|
138
|
+
end
|
139
|
+
|
124
140
|
test 'builder marks the record which already belongs to the user' do
|
125
141
|
@user.company_id = 2
|
126
142
|
with_association_for @user, :company, as: :radio_buttons
|
@@ -154,6 +170,15 @@ class AssociationTest < ActionView::TestCase
|
|
154
170
|
end
|
155
171
|
end
|
156
172
|
|
173
|
+
test 'builder does not call where if the given association does not respond to it' do
|
174
|
+
with_association_for @user, :friends
|
175
|
+
assert_select 'form select.select#user_friend_ids'
|
176
|
+
assert_select 'form select[multiple=multiple]'
|
177
|
+
assert_select 'form select option[value="1"]', 'Friend 1'
|
178
|
+
assert_select 'form select option[value="2"]', 'Friend 2'
|
179
|
+
assert_select 'form select option[value="3"]', 'Friend 3'
|
180
|
+
end
|
181
|
+
|
157
182
|
test 'builder does not call order if the given association does not respond to it' do
|
158
183
|
with_association_for @user, :pictures
|
159
184
|
assert_select 'form select.select#user_picture_ids'
|
@@ -210,12 +235,18 @@ class AssociationTest < ActionView::TestCase
|
|
210
235
|
end
|
211
236
|
|
212
237
|
test 'builder with collection support does not change the options hash' do
|
213
|
-
options = { as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li}
|
238
|
+
options = { as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li }
|
214
239
|
with_association_for @user, :tags, options
|
215
240
|
|
216
241
|
assert_select 'form ul', count: 1
|
217
242
|
assert_select 'form ul li', count: 3
|
218
|
-
assert_equal({ as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li},
|
243
|
+
assert_equal({ as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li },
|
219
244
|
options)
|
220
245
|
end
|
246
|
+
|
247
|
+
test 'builder with group select considers multiple select by default' do
|
248
|
+
with_association_for @user, :tags, as: :grouped_select, group_method: :group_method
|
249
|
+
|
250
|
+
assert_select 'select[multiple="multiple"].grouped_select'
|
251
|
+
end
|
221
252
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'test_helper'
|
2
3
|
|
3
4
|
# Tests for f.error and f.full_error
|
@@ -35,6 +36,11 @@ class ErrorTest < ActionView::TestCase
|
|
35
36
|
assert_select 'span.error', "cannot be blank"
|
36
37
|
end
|
37
38
|
|
39
|
+
test 'error generates messages with decorated object responsive to #to_model' do
|
40
|
+
with_error_for @decorated_user, :name
|
41
|
+
assert_select 'span.error', "cannot be blank"
|
42
|
+
end
|
43
|
+
|
38
44
|
test 'error generates messages for attribute with one error when using first' do
|
39
45
|
swap SimpleForm, error_method: :first do
|
40
46
|
with_error_for @user, :age
|
@@ -218,6 +224,12 @@ class ErrorTest < ActionView::TestCase
|
|
218
224
|
assert_no_select 'span.error'
|
219
225
|
end
|
220
226
|
|
227
|
+
test 'input with custom error works when form does not use a model' do
|
228
|
+
with_form_for :user, :active, error: "Super User Active! cannot be blank"
|
229
|
+
|
230
|
+
assert_select 'span.error'
|
231
|
+
end
|
232
|
+
|
221
233
|
test 'input with custom error works when using full_error component' do
|
222
234
|
swap_wrapper :default, custom_wrapper_with_full_error do
|
223
235
|
error_text = "Super User Name! cannot be blank"
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# encoding: UTF-8
|
2
3
|
require 'test_helper'
|
3
4
|
|
@@ -30,6 +31,12 @@ class FormBuilderTest < ActionView::TestCase
|
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
34
|
+
test 'builder works with decorated object responsive to #to_model' do
|
35
|
+
assert_nothing_raised do
|
36
|
+
with_form_for @decorated_user, :name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
33
40
|
test 'builder input allows a block to configure input' do
|
34
41
|
with_form_for @user, :name do
|
35
42
|
text_field_tag :foo, :bar, id: :cool
|
@@ -49,7 +56,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
49
56
|
test 'builder does not override custom input mappings for custom collection' do
|
50
57
|
swap SimpleForm, input_mappings: { /gender$/ => :check_boxes } do
|
51
58
|
with_concat_form_for @user do |f|
|
52
|
-
f.input :gender, collection: [
|
59
|
+
f.input :gender, collection: %i[male female]
|
53
60
|
end
|
54
61
|
|
55
62
|
assert_no_select 'select option', 'Male'
|
@@ -58,7 +65,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
58
65
|
end
|
59
66
|
|
60
67
|
test 'builder allows to skip input_type class' do
|
61
|
-
swap SimpleForm, generate_additional_classes_for: [
|
68
|
+
swap SimpleForm, generate_additional_classes_for: %i[label wrapper] do
|
62
69
|
with_form_for @user, :post_count
|
63
70
|
assert_no_select "form input#user_post_count.integer"
|
64
71
|
assert_select "form input#user_post_count"
|
@@ -119,9 +126,40 @@ class FormBuilderTest < ActionView::TestCase
|
|
119
126
|
|
120
127
|
test 'builder generates text areas for text columns' do
|
121
128
|
with_form_for @user, :description
|
129
|
+
assert_no_select 'form input#user_description.string'
|
130
|
+
assert_select 'form textarea#user_description.text'
|
131
|
+
end
|
132
|
+
|
133
|
+
test 'builder generates text areas for text columns when hinted' do
|
134
|
+
with_form_for @user, :description, as: :text
|
135
|
+
assert_no_select 'form input#user_description.string'
|
122
136
|
assert_select 'form textarea#user_description.text'
|
123
137
|
end
|
124
138
|
|
139
|
+
test 'builder generates text field for text columns when hinted' do
|
140
|
+
with_form_for @user, :description, as: :string
|
141
|
+
assert_no_select 'form textarea#user_description.text'
|
142
|
+
assert_select 'form input#user_description.string'
|
143
|
+
end
|
144
|
+
|
145
|
+
test 'builder generates text areas for hstore columns' do
|
146
|
+
with_form_for @user, :hstore
|
147
|
+
assert_no_select 'form input#user_hstore.string'
|
148
|
+
assert_select 'form textarea#user_hstore.text'
|
149
|
+
end
|
150
|
+
|
151
|
+
test 'builder generates text areas for json columns' do
|
152
|
+
with_form_for @user, :json
|
153
|
+
assert_no_select 'form input#user_json.string'
|
154
|
+
assert_select 'form textarea#user_json.text'
|
155
|
+
end
|
156
|
+
|
157
|
+
test 'builder generates text areas for jsonb columns' do
|
158
|
+
with_form_for @user, :jsonb
|
159
|
+
assert_no_select 'form input#user_jsonb.string'
|
160
|
+
assert_select 'form textarea#user_jsonb.text'
|
161
|
+
end
|
162
|
+
|
125
163
|
test 'builder generates a checkbox for boolean columns' do
|
126
164
|
with_form_for @user, :active
|
127
165
|
assert_select 'form input[type=checkbox]#user_active.boolean'
|
@@ -146,6 +184,11 @@ class FormBuilderTest < ActionView::TestCase
|
|
146
184
|
end
|
147
185
|
end
|
148
186
|
|
187
|
+
test 'builder generates string fields for citext columns' do
|
188
|
+
with_form_for @user, :citext
|
189
|
+
assert_select 'form input#user_citext.string'
|
190
|
+
end
|
191
|
+
|
149
192
|
test 'builder generates password fields for columns that matches password' do
|
150
193
|
with_form_for @user, :password
|
151
194
|
assert_select 'form input#user_password.password'
|
@@ -196,20 +239,29 @@ class FormBuilderTest < ActionView::TestCase
|
|
196
239
|
assert_select 'form select#user_updated_at_1i.datetime'
|
197
240
|
end
|
198
241
|
|
199
|
-
test 'builder generates file for
|
200
|
-
|
201
|
-
|
242
|
+
test 'builder generates file input for ActiveStorage >= 5.2 and Refile >= 0.2.0 <= 0.4.0' do
|
243
|
+
with_form_for UserWithAttachment.build, :avatar
|
244
|
+
assert_select 'form input#user_with_attachment_avatar.file'
|
245
|
+
end
|
246
|
+
|
247
|
+
test 'builder generates file input for ActiveStorage::Attached::Many' do
|
248
|
+
with_form_for UserWithAttachment.build, :avatars
|
249
|
+
assert_select 'form input#user_with_attachment_avatars.file'
|
250
|
+
end
|
202
251
|
|
203
|
-
|
204
|
-
|
252
|
+
test 'builder generates file input for Refile >= 0.3.0 and CarrierWave >= 0.2.2' do
|
253
|
+
with_form_for UserWithAttachment.build, :cover
|
254
|
+
assert_select 'form input#user_with_attachment_cover.file'
|
205
255
|
end
|
206
256
|
|
207
|
-
test 'builder generates file for
|
208
|
-
|
209
|
-
|
257
|
+
test 'builder generates file input for Refile >= 0.4.0 and Shrine >= 0.9.0' do
|
258
|
+
with_form_for UserWithAttachment.build, :profile_image
|
259
|
+
assert_select 'form input#user_with_attachment_profile_image.file'
|
260
|
+
end
|
210
261
|
|
211
|
-
|
212
|
-
|
262
|
+
test 'builder generates file input for Paperclip ~> 2.0' do
|
263
|
+
with_form_for UserWithAttachment.build, :portrait
|
264
|
+
assert_select 'form input#user_with_attachment_portrait.file'
|
213
265
|
end
|
214
266
|
|
215
267
|
test 'build generates select if a collection is given' do
|
@@ -217,15 +269,25 @@ class FormBuilderTest < ActionView::TestCase
|
|
217
269
|
assert_select 'form select#user_age.select'
|
218
270
|
end
|
219
271
|
|
272
|
+
test 'builder does not generate url fields for columns that contain only the letters url' do
|
273
|
+
with_form_for @user, :hourly
|
274
|
+
assert_no_select 'form input#user_url.string.url'
|
275
|
+
assert_select 'form input#user_hourly.string'
|
276
|
+
end
|
277
|
+
|
220
278
|
test 'builder allows overriding default input type for text' do
|
221
279
|
with_form_for @user, :name, as: :text
|
222
280
|
assert_no_select 'form input#user_name'
|
223
281
|
assert_select 'form textarea#user_name.text'
|
282
|
+
end
|
224
283
|
|
284
|
+
test 'builder allows overriding default input type for radio_buttons' do
|
225
285
|
with_form_for @user, :active, as: :radio_buttons
|
226
286
|
assert_no_select 'form input[type=checkbox]'
|
227
287
|
assert_select 'form input.radio_buttons[type=radio]', count: 2
|
288
|
+
end
|
228
289
|
|
290
|
+
test 'builder allows overriding default input type for string' do
|
229
291
|
with_form_for @user, :born_at, as: :string
|
230
292
|
assert_no_select 'form select'
|
231
293
|
assert_select 'form input#user_born_at.string'
|
@@ -365,7 +427,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
365
427
|
end
|
366
428
|
|
367
429
|
# DEFAULT OPTIONS
|
368
|
-
[
|
430
|
+
%i[input input_field].each do |method|
|
369
431
|
test "builder receives a default argument and pass it to the inputs when calling '#{method}'" do
|
370
432
|
with_concat_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f|
|
371
433
|
f.public_send(method, :name)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'test_helper'
|
2
3
|
|
3
4
|
# Tests for f.hint
|
@@ -18,6 +19,11 @@ class HintTest < ActionView::TestCase
|
|
18
19
|
assert_select 'span.hint', 'Use with care...'
|
19
20
|
end
|
20
21
|
|
22
|
+
test 'hint is generated with decorated object responsive to #to_model' do
|
23
|
+
with_hint_for @decorated_user, :name, hint: 'Use with care...'
|
24
|
+
assert_select 'span.hint', 'Use with care...'
|
25
|
+
end
|
26
|
+
|
21
27
|
test 'hint does not modify the options hash' do
|
22
28
|
options = { hint: 'Use with care...' }
|
23
29
|
with_hint_for @user, :name, options
|
@@ -1,13 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'test_helper'
|
2
3
|
|
3
4
|
# Tests for f.input_field
|
4
5
|
class InputFieldTest < ActionView::TestCase
|
5
|
-
def with_input_field_for(object, *args)
|
6
|
-
with_concat_form_for(object) do |f|
|
7
|
-
f.input_field(*args)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
6
|
test "builder input_field only renders the input tag, nothing else" do
|
12
7
|
with_input_field_for @user, :name
|
13
8
|
|
@@ -84,13 +79,13 @@ class InputFieldTest < ActionView::TestCase
|
|
84
79
|
test 'builder input_field infers pattern from attributes' do
|
85
80
|
with_input_field_for @other_validating_user, :country, as: :string, pattern: true
|
86
81
|
|
87
|
-
assert_select '
|
82
|
+
assert_select "input:match('pattern', ?)", /\w+/
|
88
83
|
end
|
89
84
|
|
90
85
|
test 'builder input_field accepts custom pattern' do
|
91
86
|
with_input_field_for @other_validating_user, :country, as: :string, pattern: '\d+'
|
92
87
|
|
93
|
-
assert_select '
|
88
|
+
assert_select "input:match('pattern', ?)", /\\d+/
|
94
89
|
end
|
95
90
|
|
96
91
|
test 'builder input_field uses readonly component' do
|
@@ -112,7 +107,7 @@ class InputFieldTest < ActionView::TestCase
|
|
112
107
|
end
|
113
108
|
|
114
109
|
test 'builder collection input_field generates input tag with a clean HTML' do
|
115
|
-
with_input_field_for @user, :status, collection: [
|
110
|
+
with_input_field_for @user, :status, collection: %w[Open Closed],
|
116
111
|
class: 'status', label_method: :to_s, value_method: :to_s
|
117
112
|
|
118
113
|
assert_no_select 'select.status[input_html]'
|
@@ -137,7 +132,7 @@ class InputFieldTest < ActionView::TestCase
|
|
137
132
|
swap_wrapper :default, custom_wrapper_with_html5_components do
|
138
133
|
with_input_field_for @user, :name, pattern: '\w+'
|
139
134
|
|
140
|
-
assert_select '
|
135
|
+
assert_select "input:match('pattern', ?)", /\w+/
|
141
136
|
end
|
142
137
|
end
|
143
138
|
|
@@ -172,4 +167,29 @@ class InputFieldTest < ActionView::TestCase
|
|
172
167
|
assert_select 'input[readonly="readonly"]'
|
173
168
|
end
|
174
169
|
end
|
170
|
+
|
171
|
+
test 'adds valid class to input_field when it is configured' do
|
172
|
+
swap SimpleForm, input_field_valid_class: 'is-valid' do
|
173
|
+
@user.instance_eval { undef errors }
|
174
|
+
with_input_field_for @user, :name
|
175
|
+
|
176
|
+
assert_select 'input.string.required.is-valid'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
test 'adds error class to input_field when it is configured' do
|
181
|
+
swap SimpleForm, input_field_error_class: 'is-invalid' do
|
182
|
+
with_input_field_for @user, :name
|
183
|
+
|
184
|
+
assert_select 'input.string.required.is-invalid'
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
test 'does not add validation classes to input_field when it is not configured' do
|
189
|
+
swap SimpleForm, input_field_error_class: nil, input_field_valid_class: nil do
|
190
|
+
with_input_field_for @user, :name
|
191
|
+
|
192
|
+
assert_select 'input.string.required'
|
193
|
+
end
|
194
|
+
end
|
175
195
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# encoding: UTF-8
|
2
3
|
require 'test_helper'
|
3
4
|
|
@@ -13,7 +14,12 @@ class LabelTest < ActionView::TestCase
|
|
13
14
|
assert_select 'label.string[for=user_name]', /Name/
|
14
15
|
end
|
15
16
|
|
16
|
-
test 'builder generates a label for the
|
17
|
+
test 'builder generates a label for the attribute with decorated object responsive to #to_model' do
|
18
|
+
with_label_for @decorated_user, :name
|
19
|
+
assert_select 'label.string[for=user_name]', /Name/
|
20
|
+
end
|
21
|
+
|
22
|
+
test 'builder generates a label for the boolean attribute' do
|
17
23
|
with_label_for @user, :name, as: :boolean
|
18
24
|
assert_select 'label.boolean[for=user_name]', /Name/
|
19
25
|
assert_no_select 'label[as=boolean]'
|
@@ -108,21 +114,21 @@ class LabelTest < ActionView::TestCase
|
|
108
114
|
end
|
109
115
|
|
110
116
|
test 'builder allows custom formatting when label is explicitly specified' do
|
111
|
-
swap SimpleForm, label_text:
|
117
|
+
swap SimpleForm, label_text: ->(l, r, explicit_label) { explicit_label ? l : "#{l.titleize}:" } do
|
112
118
|
with_label_for @user, :time_zone, 'What is your home time zone?'
|
113
119
|
assert_select 'label[for=user_time_zone]', 'What is your home time zone?'
|
114
120
|
end
|
115
121
|
end
|
116
122
|
|
117
123
|
test 'builder allows custom formatting when label is generated' do
|
118
|
-
swap SimpleForm, label_text:
|
124
|
+
swap SimpleForm, label_text: ->(l, r, explicit_label) { explicit_label ? l : "#{l.titleize}:" } do
|
119
125
|
with_label_for @user, :time_zone
|
120
126
|
assert_select 'label[for=user_time_zone]', 'Time Zone:'
|
121
127
|
end
|
122
128
|
end
|
123
129
|
|
124
130
|
test 'builder allows label specific `label_text` option' do
|
125
|
-
with_label_for @user, :time_zone, label_text:
|
131
|
+
with_label_for @user, :time_zone, label_text: ->(l, _, _) { "#{l.titleize}:" }
|
126
132
|
|
127
133
|
assert_no_select 'label[label_text]'
|
128
134
|
assert_select 'label[for=user_time_zone]', 'Time Zone:'
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'test_helper'
|
2
3
|
|
3
4
|
class WrapperTest < ActionView::TestCase
|
@@ -37,6 +38,34 @@ class WrapperTest < ActionView::TestCase
|
|
37
38
|
assert_select 'div.field_with_errors'
|
38
39
|
end
|
39
40
|
|
41
|
+
test 'wrapper adds error class to input for attribute with errors' do
|
42
|
+
with_form_for @user, :name, wrapper: custom_wrapper_with_input_error_class
|
43
|
+
assert_select 'div.field_with_errors'
|
44
|
+
assert_select 'input.is-invalid'
|
45
|
+
end
|
46
|
+
|
47
|
+
test 'wrapper does not add error class to input when the attribute is valid' do
|
48
|
+
with_form_for @user, :phone_number, wrapper: custom_wrapper_with_input_error_class
|
49
|
+
assert_no_select 'div.field_with_errors'
|
50
|
+
assert_no_select 'input.is-invalid'
|
51
|
+
end
|
52
|
+
|
53
|
+
test 'wrapper adds valid class for present attribute without errors' do
|
54
|
+
@user.instance_eval { undef errors }
|
55
|
+
with_form_for @user, :name, wrapper: custom_wrapper_with_input_valid_class
|
56
|
+
assert_select 'div.field_without_errors'
|
57
|
+
assert_select 'input.is-valid'
|
58
|
+
assert_no_select 'div.field_with_errors'
|
59
|
+
assert_no_select 'input.is-invalid'
|
60
|
+
end
|
61
|
+
|
62
|
+
test 'wrapper does not determine if valid class is needed when it is set to nil' do
|
63
|
+
@user.instance_eval { undef errors }
|
64
|
+
with_form_for @user, :name, wrapper: custom_wrapper_with_input_valid_class(valid_class: nil)
|
65
|
+
|
66
|
+
assert_no_select 'div.field_without_errors'
|
67
|
+
end
|
68
|
+
|
40
69
|
test 'wrapper adds hint class for attribute with a hint' do
|
41
70
|
with_form_for @user, :name, hint: 'hint'
|
42
71
|
assert_select 'div.field_with_hint'
|
@@ -88,7 +117,7 @@ class WrapperTest < ActionView::TestCase
|
|
88
117
|
end
|
89
118
|
|
90
119
|
test 'wrapper skips additional classes when configured' do
|
91
|
-
swap SimpleForm, generate_additional_classes_for: [
|
120
|
+
swap SimpleForm, generate_additional_classes_for: %i[input label] do
|
92
121
|
with_form_for @user, :name, wrapper_class: :wrapper
|
93
122
|
assert_select 'form div.wrapper'
|
94
123
|
assert_no_select 'div.required'
|
@@ -98,7 +127,7 @@ class WrapperTest < ActionView::TestCase
|
|
98
127
|
end
|
99
128
|
|
100
129
|
test 'wrapper does not generate empty css class' do
|
101
|
-
swap SimpleForm, generate_additional_classes_for: [
|
130
|
+
swap SimpleForm, generate_additional_classes_for: %i[input label] do
|
102
131
|
swap_wrapper :default, custom_wrapper_without_class do
|
103
132
|
with_form_for @user, :name
|
104
133
|
assert_no_select 'div#custom_wrapper_without_class[class]'
|
@@ -139,7 +168,7 @@ class WrapperTest < ActionView::TestCase
|
|
139
168
|
test 'custom wrappers can have full error message on attributes' do
|
140
169
|
swap_wrapper :default, custom_wrapper_with_full_error do
|
141
170
|
with_form_for @user, :name
|
142
|
-
assert_select 'span.error', "Name cannot be blank"
|
171
|
+
assert_select 'span.error', "Super User Name! cannot be blank"
|
143
172
|
end
|
144
173
|
end
|
145
174
|
|
@@ -263,8 +292,6 @@ class WrapperTest < ActionView::TestCase
|
|
263
292
|
end
|
264
293
|
|
265
294
|
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
295
|
swap_wrapper :default, custom_wrapper_with_input_aria_modal do
|
269
296
|
with_concat_form_for @user do |f|
|
270
297
|
concat f.input :name, input_html: { aria: { modal: 'another-aria', target: 'merge-aria' } }
|