simple_form 2.0.0 → 3.5.1
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 +7 -0
- data/CHANGELOG.md +97 -198
- data/MIT-LICENSE +1 -1
- data/README.md +572 -296
- data/lib/generators/simple_form/install_generator.rb +17 -7
- data/lib/generators/simple_form/templates/README +3 -4
- data/lib/generators/simple_form/templates/_form.html.erb +1 -0
- data/lib/generators/simple_form/templates/_form.html.haml +1 -0
- data/lib/generators/simple_form/templates/config/initializers/{simple_form.rb.tt → simple_form.rb} +57 -63
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +155 -0
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +111 -0
- data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +14 -7
- data/lib/simple_form/action_view_extensions/builder.rb +5 -305
- data/lib/simple_form/action_view_extensions/form_helper.rb +18 -20
- data/lib/simple_form/components/errors.rb +30 -3
- data/lib/simple_form/components/hints.rb +10 -3
- data/lib/simple_form/components/html5.rb +17 -3
- data/lib/simple_form/components/label_input.rb +21 -2
- data/lib/simple_form/components/labels.rb +16 -11
- data/lib/simple_form/components/maxlength.rb +19 -12
- data/lib/simple_form/components/min_max.rb +4 -2
- data/lib/simple_form/components/minlength.rb +48 -0
- data/lib/simple_form/components/pattern.rb +5 -4
- data/lib/simple_form/components/placeholders.rb +3 -2
- data/lib/simple_form/components/readonly.rb +3 -2
- data/lib/simple_form/components.rb +15 -11
- data/lib/simple_form/error_notification.rb +4 -3
- data/lib/simple_form/form_builder.rb +283 -105
- 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 +4 -3
- data/lib/simple_form/helpers.rb +7 -6
- data/lib/simple_form/i18n_cache.rb +1 -0
- data/lib/simple_form/inputs/base.rb +76 -23
- data/lib/simple_form/inputs/block_input.rb +3 -2
- data/lib/simple_form/inputs/boolean_input.rb +55 -16
- data/lib/simple_form/inputs/collection_check_boxes_input.rb +2 -1
- data/lib/simple_form/inputs/collection_input.rb +41 -18
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +11 -19
- data/lib/simple_form/inputs/collection_select_input.rb +5 -2
- data/lib/simple_form/inputs/date_time_input.rb +23 -12
- data/lib/simple_form/inputs/file_input.rb +5 -2
- data/lib/simple_form/inputs/grouped_collection_select_input.rb +16 -3
- data/lib/simple_form/inputs/hidden_input.rb +5 -2
- data/lib/simple_form/inputs/numeric_input.rb +4 -8
- data/lib/simple_form/inputs/password_input.rb +6 -4
- data/lib/simple_form/inputs/priority_input.rb +5 -2
- data/lib/simple_form/inputs/range_input.rb +2 -1
- data/lib/simple_form/inputs/string_input.rb +6 -4
- data/lib/simple_form/inputs/text_input.rb +6 -3
- data/lib/simple_form/inputs.rb +20 -17
- data/lib/simple_form/map_type.rb +1 -0
- data/lib/simple_form/railtie.rb +15 -0
- data/lib/simple_form/tags.rb +69 -0
- data/lib/simple_form/version.rb +2 -1
- data/lib/simple_form/wrappers/builder.rb +12 -35
- data/lib/simple_form/wrappers/leaf.rb +29 -0
- data/lib/simple_form/wrappers/many.rb +12 -7
- data/lib/simple_form/wrappers/root.rb +7 -4
- data/lib/simple_form/wrappers/single.rb +12 -3
- data/lib/simple_form/wrappers.rb +3 -1
- data/lib/simple_form.rb +118 -63
- data/test/action_view_extensions/builder_test.rb +230 -164
- data/test/action_view_extensions/form_helper_test.rb +107 -39
- data/test/components/label_test.rb +105 -87
- data/test/form_builder/association_test.rb +131 -62
- data/test/form_builder/button_test.rb +15 -14
- data/test/form_builder/error_notification_test.rb +11 -10
- data/test/form_builder/error_test.rb +188 -34
- data/test/form_builder/general_test.rb +247 -102
- data/test/form_builder/hint_test.rb +59 -32
- data/test/form_builder/input_field_test.rb +138 -25
- data/test/form_builder/label_test.rb +84 -13
- data/test/form_builder/wrapper_test.rb +236 -33
- data/test/generators/simple_form_generator_test.rb +15 -4
- data/test/inputs/boolean_input_test.rb +147 -13
- data/test/inputs/collection_check_boxes_input_test.rb +166 -71
- data/test/inputs/collection_radio_buttons_input_test.rb +229 -113
- data/test/inputs/collection_select_input_test.rb +222 -85
- data/test/inputs/datetime_input_test.rb +134 -47
- data/test/inputs/disabled_test.rb +62 -21
- data/test/inputs/discovery_test.rb +70 -10
- data/test/inputs/file_input_test.rb +4 -3
- data/test/inputs/general_test.rb +90 -26
- data/test/inputs/grouped_collection_select_input_test.rb +88 -23
- data/test/inputs/hidden_input_test.rb +7 -5
- data/test/inputs/numeric_input_test.rb +56 -46
- data/test/inputs/priority_input_test.rb +31 -16
- data/test/inputs/readonly_test.rb +68 -27
- data/test/inputs/required_test.rb +63 -18
- data/test/inputs/string_input_test.rb +76 -51
- data/test/inputs/text_input_test.rb +21 -8
- data/test/simple_form_test.rb +9 -0
- data/test/support/discovery_inputs.rb +39 -2
- data/test/support/misc_helpers.rb +176 -20
- data/test/support/mock_controller.rb +13 -7
- data/test/support/models.rb +187 -71
- data/test/test_helper.rb +38 -39
- metadata +53 -39
- data/lib/simple_form/core_ext/hash.rb +0 -16
- data/test/support/mock_response.rb +0 -14
|
@@ -1,77 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'test_helper'
|
|
2
3
|
|
|
3
4
|
class WrapperTest < ActionView::TestCase
|
|
4
|
-
test 'wrapper
|
|
5
|
+
test 'wrapper does not have error class for attribute without errors' do
|
|
5
6
|
with_form_for @user, :active
|
|
6
7
|
assert_no_select 'div.field_with_errors'
|
|
7
8
|
end
|
|
8
9
|
|
|
9
|
-
test 'wrapper
|
|
10
|
+
test 'wrapper does not have error class when object is not present' do
|
|
10
11
|
with_form_for :project, :name
|
|
11
12
|
assert_no_select 'div.field_with_errors'
|
|
12
13
|
end
|
|
13
14
|
|
|
14
|
-
test 'wrapper
|
|
15
|
+
test 'wrapper adds the attribute name class' do
|
|
16
|
+
with_form_for @user, :name
|
|
17
|
+
assert_select 'div.user_name'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
test 'wrapper adds the attribute name class for nested forms' do
|
|
21
|
+
@user.company = Company.new(1, 'Empresa')
|
|
22
|
+
with_concat_form_for @user do |f|
|
|
23
|
+
concat(f.simple_fields_for(:company) do |company_form|
|
|
24
|
+
concat(company_form.input :name)
|
|
25
|
+
end)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
assert_select 'div.user_company_name'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test 'wrapper adds the association name class' do
|
|
32
|
+
with_form_for @user, :company
|
|
33
|
+
assert_select 'div.user_company'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
test 'wrapper adds error class for attribute with errors' do
|
|
15
37
|
with_form_for @user, :name
|
|
16
38
|
assert_select 'div.field_with_errors'
|
|
17
39
|
end
|
|
18
40
|
|
|
19
|
-
test 'wrapper
|
|
20
|
-
with_form_for @user, :name, :
|
|
41
|
+
test 'wrapper adds hint class for attribute with a hint' do
|
|
42
|
+
with_form_for @user, :name, hint: 'hint'
|
|
21
43
|
assert_select 'div.field_with_hint'
|
|
22
44
|
end
|
|
23
45
|
|
|
24
|
-
test 'wrapper
|
|
46
|
+
test 'wrapper does not have disabled class by default' do
|
|
25
47
|
with_form_for @user, :active
|
|
26
48
|
assert_no_select 'div.disabled'
|
|
27
49
|
end
|
|
28
50
|
|
|
29
|
-
test 'wrapper
|
|
30
|
-
with_form_for @user, :active, :
|
|
51
|
+
test 'wrapper has disabled class when input is disabled' do
|
|
52
|
+
with_form_for @user, :active, disabled: true
|
|
31
53
|
assert_select 'div.disabled'
|
|
32
54
|
end
|
|
33
55
|
|
|
34
|
-
test 'wrapper
|
|
35
|
-
with_form_for @user, :name, :
|
|
56
|
+
test 'wrapper supports no wrapping when wrapper is false' do
|
|
57
|
+
with_form_for @user, :name, wrapper: false
|
|
36
58
|
assert_select 'form > label[for=user_name]'
|
|
37
59
|
assert_select 'form > input#user_name.string'
|
|
38
60
|
end
|
|
39
61
|
|
|
40
|
-
test 'wrapper
|
|
41
|
-
with_form_for @user, :name, :
|
|
62
|
+
test 'wrapper supports no wrapping when wrapper tag is false' do
|
|
63
|
+
with_form_for @user, :name, wrapper: custom_wrapper_without_top_level
|
|
42
64
|
assert_select 'form > label[for=user_name]'
|
|
43
65
|
assert_select 'form > input#user_name.string'
|
|
44
66
|
end
|
|
45
67
|
|
|
46
|
-
test 'wrapper
|
|
68
|
+
test 'wrapper wraps tag adds required/optional css classes' do
|
|
47
69
|
with_form_for @user, :name
|
|
48
70
|
assert_select 'form div.input.required.string'
|
|
49
71
|
|
|
50
|
-
with_form_for @user, :age, :
|
|
72
|
+
with_form_for @user, :age, required: false
|
|
51
73
|
assert_select 'form div.input.optional.integer'
|
|
52
74
|
end
|
|
53
75
|
|
|
54
|
-
test 'wrapper
|
|
55
|
-
with_form_for @user, :name, :
|
|
76
|
+
test 'wrapper allows custom options to be given' do
|
|
77
|
+
with_form_for @user, :name, wrapper_html: { id: "super_cool", class: 'yay' }
|
|
56
78
|
assert_select 'form #super_cool.required.string.yay'
|
|
57
79
|
end
|
|
58
80
|
|
|
59
|
-
test 'wrapper
|
|
60
|
-
with_form_for @user, :name, :
|
|
81
|
+
test 'wrapper allows tag to be given on demand' do
|
|
82
|
+
with_form_for @user, :name, wrapper_tag: :b
|
|
61
83
|
assert_select 'form b.required.string'
|
|
62
84
|
end
|
|
63
85
|
|
|
64
|
-
test 'wrapper
|
|
65
|
-
with_form_for @user, :name, :
|
|
86
|
+
test 'wrapper allows wrapper class to be given on demand' do
|
|
87
|
+
with_form_for @user, :name, wrapper_class: :wrapper
|
|
66
88
|
assert_select 'form div.wrapper.required.string'
|
|
67
89
|
end
|
|
68
90
|
|
|
69
|
-
test 'wrapper
|
|
70
|
-
swap SimpleForm, :
|
|
71
|
-
with_form_for @user, :name, :
|
|
91
|
+
test 'wrapper skips additional classes when configured' do
|
|
92
|
+
swap SimpleForm, generate_additional_classes_for: %i[input label] do
|
|
93
|
+
with_form_for @user, :name, wrapper_class: :wrapper
|
|
72
94
|
assert_select 'form div.wrapper'
|
|
73
95
|
assert_no_select 'div.required'
|
|
74
96
|
assert_no_select 'div.string'
|
|
97
|
+
assert_no_select 'div.user_name'
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
test 'wrapper does not generate empty css class' do
|
|
102
|
+
swap SimpleForm, generate_additional_classes_for: %i[input label] do
|
|
103
|
+
swap_wrapper :default, custom_wrapper_without_class do
|
|
104
|
+
with_form_for @user, :name
|
|
105
|
+
assert_no_select 'div#custom_wrapper_without_class[class]'
|
|
106
|
+
end
|
|
75
107
|
end
|
|
76
108
|
end
|
|
77
109
|
|
|
@@ -79,7 +111,7 @@ class WrapperTest < ActionView::TestCase
|
|
|
79
111
|
|
|
80
112
|
test 'custom wrappers works' do
|
|
81
113
|
swap_wrapper do
|
|
82
|
-
with_form_for @user, :name, :
|
|
114
|
+
with_form_for @user, :name, hint: "cool"
|
|
83
115
|
assert_select "section.custom_wrapper div.another_wrapper label"
|
|
84
116
|
assert_select "section.custom_wrapper div.another_wrapper input.string"
|
|
85
117
|
assert_no_select "section.custom_wrapper div.another_wrapper span.omg_error"
|
|
@@ -90,25 +122,40 @@ class WrapperTest < ActionView::TestCase
|
|
|
90
122
|
|
|
91
123
|
test 'custom wrappers can be turned off' do
|
|
92
124
|
swap_wrapper do
|
|
93
|
-
with_form_for @user, :name, :
|
|
125
|
+
with_form_for @user, :name, another: false
|
|
94
126
|
assert_no_select "section.custom_wrapper div.another_wrapper label"
|
|
95
127
|
assert_no_select "section.custom_wrapper div.another_wrapper input.string"
|
|
96
128
|
assert_select "section.custom_wrapper div.error_wrapper span.omg_error"
|
|
97
129
|
end
|
|
98
130
|
end
|
|
99
131
|
|
|
132
|
+
test 'custom wrappers can have additional attributes' do
|
|
133
|
+
swap_wrapper :default, custom_wrapper_with_additional_attributes do
|
|
134
|
+
with_form_for @user, :name
|
|
135
|
+
|
|
136
|
+
assert_select "div.custom_wrapper[title='some title'][data-wrapper='test']"
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
test 'custom wrappers can have full error message on attributes' do
|
|
141
|
+
swap_wrapper :default, custom_wrapper_with_full_error do
|
|
142
|
+
with_form_for @user, :name
|
|
143
|
+
assert_select 'span.error', "Name cannot be blank"
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
100
147
|
test 'custom wrappers on a form basis' do
|
|
101
148
|
swap_wrapper :another do
|
|
102
|
-
|
|
149
|
+
with_concat_form_for(@user) do |f|
|
|
103
150
|
f.input :name
|
|
104
|
-
|
|
151
|
+
end
|
|
105
152
|
|
|
106
153
|
assert_no_select "section.custom_wrapper div.another_wrapper label"
|
|
107
154
|
assert_no_select "section.custom_wrapper div.another_wrapper input.string"
|
|
108
155
|
|
|
109
|
-
|
|
156
|
+
with_concat_form_for(@user, wrapper: :another) do |f|
|
|
110
157
|
f.input :name
|
|
111
|
-
|
|
158
|
+
end
|
|
112
159
|
|
|
113
160
|
assert_select "section.custom_wrapper div.another_wrapper label"
|
|
114
161
|
assert_select "section.custom_wrapper div.another_wrapper input.string"
|
|
@@ -122,28 +169,184 @@ class WrapperTest < ActionView::TestCase
|
|
|
122
169
|
assert_no_select "section.custom_wrapper div.another_wrapper input.string"
|
|
123
170
|
output_buffer.replace ""
|
|
124
171
|
|
|
125
|
-
with_form_for @user, :name, :
|
|
172
|
+
with_form_for @user, :name, wrapper: :another
|
|
126
173
|
assert_select "section.custom_wrapper div.another_wrapper label"
|
|
127
174
|
assert_select "section.custom_wrapper div.another_wrapper input.string"
|
|
128
175
|
output_buffer.replace ""
|
|
129
176
|
end
|
|
130
177
|
|
|
131
|
-
with_form_for @user, :name, :
|
|
178
|
+
with_form_for @user, :name, wrapper: custom_wrapper
|
|
132
179
|
assert_select "section.custom_wrapper div.another_wrapper label"
|
|
133
180
|
assert_select "section.custom_wrapper div.another_wrapper input.string"
|
|
134
181
|
end
|
|
135
182
|
|
|
136
183
|
test 'access wrappers with indifferent access' do
|
|
137
184
|
swap_wrapper :another do
|
|
138
|
-
with_form_for @user, :name, :
|
|
185
|
+
with_form_for @user, :name, wrapper: "another"
|
|
139
186
|
assert_select "section.custom_wrapper div.another_wrapper label"
|
|
140
187
|
assert_select "section.custom_wrapper div.another_wrapper input.string"
|
|
141
188
|
end
|
|
142
189
|
end
|
|
143
190
|
|
|
191
|
+
test 'does not duplicate label classes for different inputs' do
|
|
192
|
+
swap_wrapper :default, custom_wrapper_with_label_html_option do
|
|
193
|
+
with_concat_form_for(@user) do |f|
|
|
194
|
+
concat f.input :name, required: false
|
|
195
|
+
concat f.input :email, as: :email, required: true
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
assert_select "label.string.optional.extra-label-class[for='user_name']"
|
|
199
|
+
assert_select "label.email.required.extra-label-class[for='user_email']"
|
|
200
|
+
assert_no_select "label.string.optional.extra-label-class[for='user_email']"
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
144
204
|
test 'raise error when wrapper not found' do
|
|
145
205
|
assert_raise SimpleForm::WrapperNotFound do
|
|
146
|
-
with_form_for @user, :name, :
|
|
206
|
+
with_form_for @user, :name, wrapper: :not_found
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
test 'uses wrapper for specified in config mapping' do
|
|
211
|
+
swap_wrapper :another do
|
|
212
|
+
swap SimpleForm, wrapper_mappings: { string: :another } do
|
|
213
|
+
with_form_for @user, :name
|
|
214
|
+
assert_select "section.custom_wrapper div.another_wrapper label"
|
|
215
|
+
assert_select "section.custom_wrapper div.another_wrapper input.string"
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
test 'uses custom wrapper mapping per form basis' do
|
|
221
|
+
swap_wrapper :another do
|
|
222
|
+
with_concat_form_for @user, wrapper_mappings: { string: :another } do |f|
|
|
223
|
+
concat f.input :name
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
assert_select "section.custom_wrapper div.another_wrapper label"
|
|
228
|
+
assert_select "section.custom_wrapper div.another_wrapper input.string"
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
test 'simple_fields_form reuses custom wrapper mapping per form basis' do
|
|
232
|
+
@user.company = Company.new(1, 'Empresa')
|
|
233
|
+
|
|
234
|
+
swap_wrapper :another do
|
|
235
|
+
with_concat_form_for @user, wrapper_mappings: { string: :another } do |f|
|
|
236
|
+
concat(f.simple_fields_for(:company) do |company_form|
|
|
237
|
+
concat(company_form.input(:name))
|
|
238
|
+
end)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
assert_select "section.custom_wrapper div.another_wrapper label"
|
|
243
|
+
assert_select "section.custom_wrapper div.another_wrapper input.string"
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
test "input attributes class will merge with wrapper_options' classes" do
|
|
247
|
+
swap_wrapper :default, custom_wrapper_with_input_class do
|
|
248
|
+
with_concat_form_for @user do |f|
|
|
249
|
+
concat f.input :name, input_html: { class: 'another-class' }
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
assert_select "div.custom_wrapper input.string.inline-class.another-class"
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
test "input with data attributes will merge with wrapper_options' data" do
|
|
257
|
+
swap_wrapper :default, custom_wrapper_with_input_data_modal do
|
|
258
|
+
with_concat_form_for @user do |f|
|
|
259
|
+
concat f.input :name, input_html: { data: { modal: 'another-data', target: 'merge-data' } }
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
assert_select "input[data-wrapper='data-wrapper'][data-modal='another-data'][data-target='merge-data']"
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
test "input with aria attributes will merge with wrapper_options' aria" do
|
|
267
|
+
skip unless ActionPack::VERSION::MAJOR == '4' && ActionPack::VERSION::MINOR >= '2'
|
|
268
|
+
|
|
269
|
+
swap_wrapper :default, custom_wrapper_with_input_aria_modal do
|
|
270
|
+
with_concat_form_for @user do |f|
|
|
271
|
+
concat f.input :name, input_html: { aria: { modal: 'another-aria', target: 'merge-aria' } }
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
assert_select "input[aria-wrapper='aria-wrapper'][aria-modal='another-aria'][aria-target='merge-aria']"
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
test 'input accepts attributes in the DSL' do
|
|
279
|
+
swap_wrapper :default, custom_wrapper_with_input_class do
|
|
280
|
+
with_concat_form_for @user do |f|
|
|
281
|
+
concat f.input :name
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
assert_select "div.custom_wrapper input.string.inline-class"
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
test 'label accepts attributes in the DSL' do
|
|
289
|
+
swap_wrapper :default, custom_wrapper_with_label_class do
|
|
290
|
+
with_concat_form_for @user do |f|
|
|
291
|
+
concat f.input :name
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
assert_select "div.custom_wrapper label.string.inline-class"
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
test 'label_input accepts attributes in the DSL' do
|
|
299
|
+
swap_wrapper :default, custom_wrapper_with_label_input_class do
|
|
300
|
+
with_concat_form_for @user do |f|
|
|
301
|
+
concat f.input :name
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
assert_select "div.custom_wrapper label.string.inline-class"
|
|
306
|
+
assert_select "div.custom_wrapper input.string.inline-class"
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
test 'input accepts data attributes in the DSL' do
|
|
310
|
+
swap_wrapper :default, custom_wrapper_with_input_attributes do
|
|
311
|
+
with_concat_form_for @user do |f|
|
|
312
|
+
concat f.input :name
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
assert_select "div.custom_wrapper input.string[data-modal=true]"
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
test 'inline wrapper displays when there is content' do
|
|
320
|
+
swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do
|
|
321
|
+
with_form_for @user, :name, hint: "cannot be blank"
|
|
322
|
+
assert_select 'section.custom_wrapper div.no_output_wrapper p.omg_hint', "cannot be blank"
|
|
323
|
+
assert_select 'p.omg_hint'
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
test 'inline wrapper does not display when there is no content' do
|
|
328
|
+
swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do
|
|
329
|
+
with_form_for @user, :name
|
|
330
|
+
assert_select 'section.custom_wrapper div.no_output_wrapper'
|
|
331
|
+
assert_no_select 'p.omg_hint'
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
test 'optional wrapper does not display when there is content' do
|
|
336
|
+
swap_wrapper :default, custom_wrapper_with_unless_blank do
|
|
337
|
+
with_form_for @user, :name, hint: "can't be blank"
|
|
338
|
+
assert_select 'section.custom_wrapper div.no_output_wrapper'
|
|
339
|
+
assert_select 'div.no_output_wrapper'
|
|
340
|
+
assert_select 'p.omg_hint'
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
test 'optional wrapper does not display when there is no content' do
|
|
345
|
+
swap_wrapper :default, custom_wrapper_with_unless_blank do
|
|
346
|
+
with_form_for @user, :name
|
|
347
|
+
assert_no_select 'section.custom_wrapper div.no_output_wrapper'
|
|
348
|
+
assert_no_select 'div.no_output_wrapper'
|
|
349
|
+
assert_no_select 'p.omg_hint'
|
|
147
350
|
end
|
|
148
351
|
end
|
|
149
352
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'test_helper'
|
|
2
3
|
|
|
3
4
|
class SimpleFormGeneratorTest < Rails::Generators::TestCase
|
|
@@ -18,12 +19,22 @@ class SimpleFormGeneratorTest < Rails::Generators::TestCase
|
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
test 'generates the simple_form initializer with the bootstrap wrappers' do
|
|
21
|
-
run_generator %w
|
|
22
|
-
assert_file 'config/initializers/simple_form.rb',
|
|
23
|
-
/config\.default_wrapper = :
|
|
22
|
+
run_generator %w[--bootstrap]
|
|
23
|
+
assert_file 'config/initializers/simple_form.rb',
|
|
24
|
+
/config\.default_wrapper = :default/, /config\.boolean_style = :nested/
|
|
25
|
+
assert_file 'config/initializers/simple_form_bootstrap.rb', /config\.wrappers :vertical_form/,
|
|
26
|
+
/config\.wrappers :horizontal_form/, /config\.default_wrapper = :vertical_form/
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
test 'generates the simple_form initializer with the foundation wrappers' do
|
|
30
|
+
run_generator %w[--foundation]
|
|
31
|
+
assert_file 'config/initializers/simple_form.rb',
|
|
32
|
+
/config\.default_wrapper = :default/, /config\.boolean_style = :nested/
|
|
33
|
+
assert_file 'config/initializers/simple_form_foundation.rb', /config\.wrappers :vertical_form/,
|
|
34
|
+
/config\.default_wrapper = :vertical_form/, /config\.item_wrapper_tag = :div/
|
|
24
35
|
end
|
|
25
36
|
|
|
26
|
-
%
|
|
37
|
+
%w[erb haml slim].each do |engine|
|
|
27
38
|
test "generates the scaffold template when using #{engine}" do
|
|
28
39
|
run_generator ['-e', engine]
|
|
29
40
|
assert_file "lib/templates/#{engine}/scaffold/_form.html.#{engine}"
|
|
@@ -1,19 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
# encoding: UTF-8
|
|
2
3
|
require 'test_helper'
|
|
3
4
|
|
|
4
5
|
class BooleanInputTest < ActionView::TestCase
|
|
5
|
-
test 'input
|
|
6
|
+
test 'input generates a checkbox by default for boolean attributes' do
|
|
6
7
|
with_input_for @user, :active, :boolean
|
|
7
8
|
assert_select 'input[type=checkbox].boolean#user_active'
|
|
8
9
|
assert_select 'label.boolean.optional', 'Active'
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
test 'input does not generate the label with the checkbox when label option is false' do
|
|
12
|
-
with_input_for @user, :active, :boolean, :
|
|
13
|
+
with_input_for @user, :active, :boolean, label: false
|
|
13
14
|
assert_select 'input[type=checkbox].boolean#user_active'
|
|
14
15
|
assert_no_select 'label'
|
|
15
16
|
end
|
|
16
17
|
|
|
18
|
+
test 'input uses custom checked value' do
|
|
19
|
+
@user.action = 'on'
|
|
20
|
+
with_input_for @user, :action, :boolean, checked_value: 'on', unchecked_value: 'off'
|
|
21
|
+
assert_select 'input[type=checkbox][value=on][checked=checked]'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
test 'input uses custom unchecked value' do
|
|
25
|
+
@user.action = 'off'
|
|
26
|
+
with_input_for @user, :action, :boolean, checked_value: 'on', unchecked_value: 'off'
|
|
27
|
+
assert_select 'input[type=checkbox][value=on]'
|
|
28
|
+
assert_no_select 'input[checked=checked][value=on]'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test 'input generates hidden input with custom unchecked value' do
|
|
32
|
+
with_input_for @user, :action, :boolean, checked_value: 'on', unchecked_value: 'off'
|
|
33
|
+
assert_select 'input[type=hidden][value=off]'
|
|
34
|
+
end
|
|
35
|
+
|
|
17
36
|
test 'input uses inline boolean style by default' do
|
|
18
37
|
with_input_for @user, :active, :boolean
|
|
19
38
|
assert_select 'input.boolean + label.boolean.optional'
|
|
@@ -21,7 +40,7 @@ class BooleanInputTest < ActionView::TestCase
|
|
|
21
40
|
end
|
|
22
41
|
|
|
23
42
|
test 'input allows changing default boolean style config to nested, generating a default label and a manual hidden field for checkbox' do
|
|
24
|
-
swap SimpleForm, :
|
|
43
|
+
swap SimpleForm, boolean_style: :nested do
|
|
25
44
|
with_input_for @user, :active, :boolean
|
|
26
45
|
assert_select 'label[for=user_active]', 'Active'
|
|
27
46
|
assert_select 'label.boolean > input.boolean'
|
|
@@ -29,8 +48,50 @@ class BooleanInputTest < ActionView::TestCase
|
|
|
29
48
|
end
|
|
30
49
|
end
|
|
31
50
|
|
|
51
|
+
test 'input boolean with nested allows :inline_label' do
|
|
52
|
+
swap SimpleForm, boolean_style: :nested do
|
|
53
|
+
with_input_for @user, :active, :boolean, inline_label: 'I am so inline.'
|
|
54
|
+
assert_select 'label.checkbox', text: ' I am so inline.'
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
test 'input boolean with nested escapes :inline_label with HTML' do
|
|
59
|
+
swap SimpleForm, boolean_style: :nested do
|
|
60
|
+
with_input_for @user, :active, :boolean, inline_label: '<b>I am so inline.</b>'
|
|
61
|
+
assert_no_select 'label.checkbox b'
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
test 'input boolean with nested allows :inline_label with HTML when safe' do
|
|
66
|
+
swap SimpleForm, boolean_style: :nested do
|
|
67
|
+
with_input_for @user, :active, :boolean, inline_label: '<b>I am so inline.</b>'.html_safe
|
|
68
|
+
assert_select 'label.checkbox b', text: 'I am so inline.'
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
test 'input boolean with nested style creates an inline label using the default label text when inline_label option set to true' do
|
|
73
|
+
swap SimpleForm, boolean_style: :nested do
|
|
74
|
+
with_input_for @user, :active, :boolean, inline_label: true
|
|
75
|
+
assert_select 'label.checkbox', text: ' Active'
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
test 'input boolean with nested style creates an inline label using the label text when inline_label option set to true' do
|
|
80
|
+
swap SimpleForm, boolean_style: :nested do
|
|
81
|
+
with_input_for @user, :active, :boolean, inline_label: true, label_text: proc { 'New Active' }
|
|
82
|
+
assert_select 'label.checkbox', text: ' New Active'
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
test 'input boolean with nested style creates an inline label using the label html when inline_label option set to true' do
|
|
87
|
+
swap SimpleForm, boolean_style: :nested do
|
|
88
|
+
with_input_for @user, :active, :boolean, inline_label: true, label_text: proc { '<b>New Active</b>' }
|
|
89
|
+
assert_select 'label.checkbox', text: ' New Active'
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
32
93
|
test 'input boolean with nested generates a manual hidden field for checkbox outside the label, to recreate Rails functionality with valid html5' do
|
|
33
|
-
swap SimpleForm, :
|
|
94
|
+
swap SimpleForm, boolean_style: :nested do
|
|
34
95
|
with_input_for @user, :active, :boolean
|
|
35
96
|
|
|
36
97
|
assert_select "input[type=hidden][name='user[active]'] + label.boolean > input.boolean"
|
|
@@ -39,23 +100,23 @@ class BooleanInputTest < ActionView::TestCase
|
|
|
39
100
|
end
|
|
40
101
|
|
|
41
102
|
test 'input boolean with nested generates a disabled hidden field for checkbox outside the label, if the field is disabled' do
|
|
42
|
-
swap SimpleForm, :
|
|
43
|
-
with_input_for @user, :active, :boolean, :
|
|
103
|
+
swap SimpleForm, boolean_style: :nested do
|
|
104
|
+
with_input_for @user, :active, :boolean, disabled: true
|
|
44
105
|
|
|
45
106
|
assert_select "input[type=hidden][name='user[active]'][disabled] + label.boolean > input.boolean[disabled]"
|
|
46
107
|
end
|
|
47
108
|
end
|
|
48
109
|
|
|
49
110
|
test 'input accepts changing boolean style to nested through given options' do
|
|
50
|
-
with_input_for @user, :active, :boolean, :
|
|
111
|
+
with_input_for @user, :active, :boolean, boolean_style: :nested
|
|
51
112
|
assert_select 'label[for=user_active]', 'Active'
|
|
52
113
|
assert_select 'label.boolean > input.boolean'
|
|
53
114
|
assert_no_select 'input[type=checkbox] + label'
|
|
54
115
|
end
|
|
55
116
|
|
|
56
117
|
test 'input accepts changing boolean style to inline through given options, when default is nested' do
|
|
57
|
-
swap SimpleForm, :
|
|
58
|
-
with_input_for @user, :active, :boolean, :
|
|
118
|
+
swap SimpleForm, boolean_style: :nested do
|
|
119
|
+
with_input_for @user, :active, :boolean, boolean_style: :inline
|
|
59
120
|
assert_select 'label[for=user_active]', 'Active'
|
|
60
121
|
assert_select 'input.boolean + label.boolean'
|
|
61
122
|
assert_no_select 'label > input'
|
|
@@ -63,13 +124,36 @@ class BooleanInputTest < ActionView::TestCase
|
|
|
63
124
|
end
|
|
64
125
|
|
|
65
126
|
test 'input with nested style allows disabling label' do
|
|
66
|
-
swap SimpleForm, :
|
|
67
|
-
with_input_for @user, :active, :boolean, :
|
|
127
|
+
swap SimpleForm, boolean_style: :nested do
|
|
128
|
+
with_input_for @user, :active, :boolean, label: false
|
|
68
129
|
assert_select 'input.boolean'
|
|
69
130
|
assert_no_select 'label.boolean'
|
|
70
131
|
end
|
|
71
132
|
end
|
|
72
133
|
|
|
134
|
+
test 'input with nested style allows customizing input_html' do
|
|
135
|
+
swap SimpleForm, boolean_style: :nested do
|
|
136
|
+
with_input_for @user, :active, :boolean, input_html: { name: 'active_user' }
|
|
137
|
+
assert_select "input[type=hidden][name=active_user] + label.boolean > input.boolean[name=active_user]"
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
test 'input with nested style allows disabling hidden field' do
|
|
142
|
+
swap SimpleForm, boolean_style: :nested do
|
|
143
|
+
with_input_for @user, :active, :boolean, include_hidden: false
|
|
144
|
+
assert_select "label.boolean > input.boolean"
|
|
145
|
+
assert_no_select "input[type=hidden] + label.boolean"
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
test 'input with nested style does not include hidden field when unchecked_value is false' do
|
|
150
|
+
swap SimpleForm, boolean_style: :nested do
|
|
151
|
+
with_input_for @user, :active, :boolean, unchecked_value: false
|
|
152
|
+
assert_select "label.boolean > input.boolean"
|
|
153
|
+
assert_no_select "input[type=hidden] + label.boolean"
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
73
157
|
test 'input boolean works using :input only in wrapper config (no label_input)' do
|
|
74
158
|
swap_wrapper do
|
|
75
159
|
with_input_for @user, :active, :boolean
|
|
@@ -81,7 +165,7 @@ class BooleanInputTest < ActionView::TestCase
|
|
|
81
165
|
|
|
82
166
|
test 'input boolean with nested style works using :input only in wrapper config (no label_input), adding the extra "checkbox" label wrapper' do
|
|
83
167
|
swap_wrapper do
|
|
84
|
-
swap SimpleForm, :
|
|
168
|
+
swap SimpleForm, boolean_style: :nested do
|
|
85
169
|
with_input_for @user, :active, :boolean
|
|
86
170
|
|
|
87
171
|
assert_select 'label.boolean + input[type=hidden] + label.checkbox > input.boolean'
|
|
@@ -89,13 +173,63 @@ class BooleanInputTest < ActionView::TestCase
|
|
|
89
173
|
end
|
|
90
174
|
end
|
|
91
175
|
|
|
176
|
+
test 'input boolean allows specifying boolean_label_class on a per-input basis' do
|
|
177
|
+
swap_wrapper do
|
|
178
|
+
swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
|
|
179
|
+
with_input_for @user, :active, :boolean, boolean_label_class: 'baz'
|
|
180
|
+
|
|
181
|
+
assert_select 'label.boolean + input[type=hidden] + label.baz > input.boolean'
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
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
|
|
187
|
+
swap_wrapper do
|
|
188
|
+
swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
|
|
189
|
+
with_input_for @user, :active, :boolean
|
|
190
|
+
|
|
191
|
+
assert_select 'label.boolean + input[type=hidden] + label.foo > input.boolean'
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
92
196
|
test 'input boolean with nested style works using :label_input in wrapper config, adding "checkbox" class to label' do
|
|
93
197
|
swap_wrapper :default, self.custom_wrapper_without_top_level do
|
|
94
|
-
swap SimpleForm, :
|
|
198
|
+
swap SimpleForm, boolean_style: :nested do
|
|
95
199
|
with_input_for @user, :active, :boolean
|
|
96
200
|
|
|
97
201
|
assert_select 'input[type=hidden] + label.boolean.checkbox > input.boolean'
|
|
98
202
|
end
|
|
99
203
|
end
|
|
100
204
|
end
|
|
205
|
+
|
|
206
|
+
test 'input boolean with nested style works using :label_input in wrapper config, adding custom class to label' do
|
|
207
|
+
swap_wrapper :default, self.custom_wrapper_without_top_level do
|
|
208
|
+
swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do
|
|
209
|
+
with_input_for @user, :active, :boolean
|
|
210
|
+
|
|
211
|
+
assert_select 'input[type=hidden] + label.boolean.foo > input.boolean'
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
test 'input boolean without additional classes adds "checkbox" class to label' do
|
|
217
|
+
swap_wrapper :default, self.custom_wrapper_without_top_level do
|
|
218
|
+
swap SimpleForm, boolean_style: :nested, generate_additional_classes_for: [:input] do
|
|
219
|
+
with_input_for @user, :active, :boolean
|
|
220
|
+
|
|
221
|
+
assert_select 'label'
|
|
222
|
+
assert_select 'label.checkbox'
|
|
223
|
+
assert_no_select 'label.boolean'
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
test 'input boolean works with wrapper config defining a class for the input' do
|
|
229
|
+
swap_wrapper :default, self.custom_wrapper_with_input_class do
|
|
230
|
+
with_input_for @user, :active, :boolean
|
|
231
|
+
|
|
232
|
+
assert_select 'input.boolean.inline-class'
|
|
233
|
+
end
|
|
234
|
+
end
|
|
101
235
|
end
|