simple_form 1.5.2 → 2.0.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.
- data/CHANGELOG.md +234 -0
- data/MIT-LICENSE +1 -1
- data/README.md +816 -0
- data/lib/generators/simple_form/install_generator.rb +15 -1
- data/lib/generators/simple_form/templates/README +12 -0
- data/lib/generators/simple_form/templates/_form.html.erb +2 -2
- data/lib/generators/simple_form/templates/_form.html.haml +2 -2
- data/lib/generators/simple_form/templates/_form.html.slim +4 -4
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb.tt +176 -0
- data/lib/simple_form/action_view_extensions/builder.rb +206 -59
- data/lib/simple_form/action_view_extensions/form_helper.rb +30 -23
- data/lib/simple_form/components/errors.rb +6 -24
- data/lib/simple_form/components/hints.rb +7 -21
- data/lib/simple_form/components/html5.rb +26 -0
- data/lib/simple_form/components/labels.rb +22 -14
- data/lib/simple_form/components/maxlength.rb +41 -0
- data/lib/simple_form/components/min_max.rb +49 -0
- data/lib/simple_form/components/pattern.rb +34 -0
- data/lib/simple_form/components/placeholders.rb +5 -17
- data/lib/simple_form/components/readonly.rb +22 -0
- data/lib/simple_form/components.rb +11 -1
- data/lib/simple_form/core_ext/hash.rb +16 -0
- data/lib/simple_form/error_notification.rb +9 -3
- data/lib/simple_form/form_builder.rb +105 -28
- data/lib/simple_form/helpers/autofocus.rb +11 -0
- data/lib/simple_form/helpers/disabled.rb +15 -0
- data/lib/simple_form/helpers/readonly.rb +15 -0
- data/lib/simple_form/helpers/required.rb +10 -11
- data/lib/simple_form/helpers/validators.rb +4 -4
- data/lib/simple_form/helpers.rb +7 -4
- data/lib/simple_form/inputs/base.rb +53 -81
- data/lib/simple_form/inputs/boolean_input.rb +46 -4
- data/lib/simple_form/inputs/collection_check_boxes_input.rb +21 -0
- data/lib/simple_form/inputs/collection_input.rb +27 -13
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +67 -0
- data/lib/simple_form/inputs/collection_select_input.rb +14 -0
- data/lib/simple_form/inputs/date_time_input.rb +10 -6
- data/lib/simple_form/inputs/grouped_collection_select_input.rb +41 -0
- data/lib/simple_form/inputs/hidden_input.rb +3 -6
- data/lib/simple_form/inputs/numeric_input.rb +3 -51
- data/lib/simple_form/inputs/password_input.rb +1 -2
- data/lib/simple_form/inputs/priority_input.rb +2 -2
- data/lib/simple_form/inputs/range_input.rb +1 -3
- data/lib/simple_form/inputs/string_input.rb +6 -8
- data/lib/simple_form/inputs/text_input.rb +1 -2
- data/lib/simple_form/inputs.rb +17 -13
- data/lib/simple_form/version.rb +1 -1
- data/lib/simple_form/wrappers/builder.rb +103 -0
- data/lib/simple_form/wrappers/many.rb +69 -0
- data/lib/simple_form/wrappers/root.rb +34 -0
- data/lib/simple_form/wrappers/single.rb +18 -0
- data/lib/simple_form/wrappers.rb +8 -0
- data/lib/simple_form.rb +118 -48
- data/test/action_view_extensions/builder_test.rb +285 -102
- data/test/action_view_extensions/form_helper_test.rb +32 -10
- data/test/components/label_test.rb +44 -5
- data/test/form_builder/association_test.rb +177 -0
- data/test/form_builder/button_test.rb +47 -0
- data/test/{error_notification_test.rb → form_builder/error_notification_test.rb} +18 -1
- data/test/form_builder/error_test.rb +121 -0
- data/test/form_builder/general_test.rb +356 -0
- data/test/form_builder/hint_test.rb +123 -0
- data/test/form_builder/input_field_test.rb +63 -0
- data/test/form_builder/label_test.rb +65 -0
- data/test/form_builder/wrapper_test.rb +149 -0
- data/test/generators/simple_form_generator_test.rb +32 -0
- data/test/inputs/boolean_input_test.rb +101 -0
- data/test/inputs/collection_check_boxes_input_test.rb +224 -0
- data/test/inputs/collection_radio_buttons_input_test.rb +326 -0
- data/test/inputs/collection_select_input_test.rb +241 -0
- data/test/inputs/datetime_input_test.rb +99 -0
- data/test/inputs/disabled_test.rb +38 -0
- data/test/inputs/discovery_test.rb +61 -0
- data/test/inputs/file_input_test.rb +16 -0
- data/test/inputs/general_test.rb +69 -0
- data/test/inputs/grouped_collection_select_input_test.rb +118 -0
- data/test/inputs/hidden_input_test.rb +30 -0
- data/test/inputs/numeric_input_test.rb +167 -0
- data/test/inputs/priority_input_test.rb +43 -0
- data/test/inputs/readonly_test.rb +61 -0
- data/test/inputs/required_test.rb +113 -0
- data/test/inputs/string_input_test.rb +140 -0
- data/test/inputs/text_input_test.rb +24 -0
- data/test/support/misc_helpers.rb +53 -12
- data/test/support/mock_controller.rb +2 -2
- data/test/support/models.rb +20 -5
- data/test/test_helper.rb +11 -12
- metadata +124 -96
- data/.gitignore +0 -3
- data/.gitmodules +0 -3
- data/.travis.yml +0 -15
- data/CHANGELOG.rdoc +0 -159
- data/Gemfile +0 -9
- data/README.rdoc +0 -466
- data/Rakefile +0 -27
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +0 -93
- data/lib/simple_form/components/wrapper.rb +0 -38
- data/lib/simple_form/helpers/has_errors.rb +0 -15
- data/lib/simple_form/helpers/maxlength.rb +0 -24
- data/lib/simple_form/helpers/pattern.rb +0 -28
- data/simple_form.gemspec +0 -25
- data/test/components/error_test.rb +0 -56
- data/test/components/hint_test.rb +0 -74
- data/test/components/wrapper_test.rb +0 -63
- data/test/custom_components.rb +0 -7
- data/test/form_builder_test.rb +0 -930
- data/test/inputs_test.rb +0 -995
- /data/test/{discovery_inputs.rb → support/discovery_inputs.rb} +0 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
require 'test_helper'
|
|
3
|
+
|
|
4
|
+
class FormBuilderTest < ActionView::TestCase
|
|
5
|
+
def with_custom_form_for(object, *args, &block)
|
|
6
|
+
with_concat_custom_form_for(object) do |f|
|
|
7
|
+
f.input(*args, &block)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
test 'nested simple fields should yield an instance of FormBuilder' do
|
|
12
|
+
simple_form_for :user do |f|
|
|
13
|
+
f.simple_fields_for :posts do |posts_form|
|
|
14
|
+
assert posts_form.instance_of?(SimpleForm::FormBuilder)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
test 'builder input is html safe' do
|
|
20
|
+
simple_form_for @user do |f|
|
|
21
|
+
assert f.input(:name).html_safe?
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
test 'builder input should allow a block to configure input' do
|
|
26
|
+
with_form_for @user, :name do
|
|
27
|
+
text_field_tag :foo, :bar, :id => :cool
|
|
28
|
+
end
|
|
29
|
+
assert_no_select 'input.string'
|
|
30
|
+
assert_select 'input#cool'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
test 'builder should allow adding custom input mappings for default input types' do
|
|
34
|
+
swap SimpleForm, :input_mappings => { /count$/ => :integer } do
|
|
35
|
+
with_form_for @user, :post_count
|
|
36
|
+
assert_no_select 'form input#user_post_count.string'
|
|
37
|
+
assert_select 'form input#user_post_count.numeric.integer'
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
test 'builder should allow to skip input_type class' do
|
|
42
|
+
swap SimpleForm, :generate_additional_classes_for => [:label, :wrapper] do
|
|
43
|
+
with_form_for @user, :post_count
|
|
44
|
+
assert_no_select "form input#user_post_count.integer"
|
|
45
|
+
assert_select "form input#user_post_count"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
test 'builder should allow adding custom input mappings for integer input types' do
|
|
50
|
+
swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
|
|
51
|
+
with_form_for @user, :lock_version
|
|
52
|
+
assert_no_select 'form input#user_lock_version.integer'
|
|
53
|
+
assert_select 'form input#user_lock_version.hidden'
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
test 'builder uses the first matching custom input map when more than one matches' do
|
|
58
|
+
swap SimpleForm, :input_mappings => { /count$/ => :integer, /^post_/ => :password } do
|
|
59
|
+
with_form_for @user, :post_count
|
|
60
|
+
assert_no_select 'form input#user_post_count.password'
|
|
61
|
+
assert_select 'form input#user_post_count.numeric.integer'
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
test 'builder uses the custom map only for matched attributes' do
|
|
66
|
+
swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
|
|
67
|
+
with_form_for @user, :post_count
|
|
68
|
+
assert_no_select 'form input#user_post_count.hidden'
|
|
69
|
+
assert_select 'form input#user_post_count.string'
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# INPUT TYPES
|
|
74
|
+
test 'builder should generate text fields for string columns' do
|
|
75
|
+
with_form_for @user, :name
|
|
76
|
+
assert_select 'form input#user_name.string'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
test 'builder should generate text areas for text columns' do
|
|
80
|
+
with_form_for @user, :description
|
|
81
|
+
assert_select 'form textarea#user_description.text'
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
test 'builder should generate a checkbox for boolean columns' do
|
|
85
|
+
with_form_for @user, :active
|
|
86
|
+
assert_select 'form input[type=checkbox]#user_active.boolean'
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
test 'builder should use integer text field for integer columns' do
|
|
90
|
+
with_form_for @user, :age
|
|
91
|
+
assert_select 'form input#user_age.numeric.integer'
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
test 'builder should generate decimal text field for decimal columns' do
|
|
95
|
+
with_form_for @user, :credit_limit
|
|
96
|
+
assert_select 'form input#user_credit_limit.numeric.decimal'
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
test 'builder should generate password fields for columns that matches password' do
|
|
100
|
+
with_form_for @user, :password
|
|
101
|
+
assert_select 'form input#user_password.password'
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
test 'builder should generate country fields for columns that matches country' do
|
|
105
|
+
with_form_for @user, :residence_country
|
|
106
|
+
assert_select 'form select#user_residence_country.country'
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
test 'builder should generate time_zone fields for columns that matches time_zone' do
|
|
110
|
+
with_form_for @user, :time_zone
|
|
111
|
+
assert_select 'form select#user_time_zone.time_zone'
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
test 'builder should generate email fields for columns that matches email' do
|
|
115
|
+
with_form_for @user, :email
|
|
116
|
+
assert_select 'form input#user_email.string.email'
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
test 'builder should generate tel fields for columns that matches phone' do
|
|
120
|
+
with_form_for @user, :phone_number
|
|
121
|
+
assert_select 'form input#user_phone_number.string.tel'
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
test 'builder should generate url fields for columns that matches url' do
|
|
125
|
+
with_form_for @user, :url
|
|
126
|
+
assert_select 'form input#user_url.string.url'
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
test 'builder should generate date select for date columns' do
|
|
130
|
+
with_form_for @user, :born_at
|
|
131
|
+
assert_select 'form select#user_born_at_1i.date'
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
test 'builder should generate time select for time columns' do
|
|
135
|
+
with_form_for @user, :delivery_time
|
|
136
|
+
assert_select 'form select#user_delivery_time_4i.time'
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
test 'builder should generate datetime select for datetime columns' do
|
|
140
|
+
with_form_for @user, :created_at
|
|
141
|
+
assert_select 'form select#user_created_at_1i.datetime'
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
test 'builder should generate datetime select for timestamp columns' do
|
|
145
|
+
with_form_for @user, :updated_at
|
|
146
|
+
assert_select 'form select#user_updated_at_1i.datetime'
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
test 'builder should generate file for file columns' do
|
|
150
|
+
@user.avatar = mock("file")
|
|
151
|
+
@user.avatar.expects(:respond_to?).with(:mounted_as).returns(false)
|
|
152
|
+
@user.avatar.expects(:respond_to?).with(:file?).returns(false)
|
|
153
|
+
@user.avatar.expects(:respond_to?).with(:public_filename).returns(true)
|
|
154
|
+
|
|
155
|
+
with_form_for @user, :avatar
|
|
156
|
+
assert_select 'form input#user_avatar.file'
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
test 'builder should generate file for attributes that are real db columns but have file methods' do
|
|
160
|
+
@user.home_picture = mock("file")
|
|
161
|
+
@user.home_picture.expects(:respond_to?).with(:mounted_as).returns(true)
|
|
162
|
+
|
|
163
|
+
with_form_for @user, :home_picture
|
|
164
|
+
assert_select 'form input#user_home_picture.file'
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
test 'build should generate select if a collection is given' do
|
|
168
|
+
with_form_for @user, :age, :collection => 1..60
|
|
169
|
+
assert_select 'form select#user_age.select'
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
test 'builder should allow overriding default input type for text' do
|
|
173
|
+
with_form_for @user, :name, :as => :text
|
|
174
|
+
assert_no_select 'form input#user_name'
|
|
175
|
+
assert_select 'form textarea#user_name.text'
|
|
176
|
+
|
|
177
|
+
with_form_for @user, :active, :as => :radio_buttons
|
|
178
|
+
assert_no_select 'form input[type=checkbox]'
|
|
179
|
+
assert_select 'form input.radio_buttons[type=radio]', :count => 2
|
|
180
|
+
|
|
181
|
+
with_form_for @user, :born_at, :as => :string
|
|
182
|
+
assert_no_select 'form select'
|
|
183
|
+
assert_select 'form input#user_born_at.string'
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# COMMON OPTIONS
|
|
187
|
+
test 'builder should add chosen form class' do
|
|
188
|
+
swap SimpleForm, :form_class => :my_custom_class do
|
|
189
|
+
with_form_for @user, :name
|
|
190
|
+
assert_select 'form.my_custom_class'
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
test 'builder should allow passing options to input' do
|
|
195
|
+
with_form_for @user, :name, :input_html => { :class => 'my_input', :id => 'my_input' }
|
|
196
|
+
assert_select 'form input#my_input.my_input.string'
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
test 'builder should not propagate input options to wrapper' do
|
|
200
|
+
with_form_for @user, :name, :input_html => { :class => 'my_input', :id => 'my_input' }
|
|
201
|
+
assert_no_select 'form div.input.my_input.string'
|
|
202
|
+
assert_select 'form input#my_input.my_input.string'
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
test 'builder should generate a input with label' do
|
|
206
|
+
with_form_for @user, :name
|
|
207
|
+
assert_select 'form label.string[for=user_name]', /Name/
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
test 'builder should be able to disable the label for a input' do
|
|
211
|
+
with_form_for @user, :name, :label => false
|
|
212
|
+
assert_no_select 'form label'
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
test 'builder should use custom label' do
|
|
216
|
+
with_form_for @user, :name, :label => 'Yay!'
|
|
217
|
+
assert_select 'form label', /Yay!/
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
test 'builder should pass options to label' do
|
|
221
|
+
with_form_for @user, :name, :label_html => { :id => "cool" }
|
|
222
|
+
assert_select 'form label#cool', /Name/
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
test 'builder should not generate hints for a input' do
|
|
226
|
+
with_form_for @user, :name
|
|
227
|
+
assert_no_select 'span.hint'
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
test 'builder should be able to add a hint for a input' do
|
|
231
|
+
with_form_for @user, :name, :hint => 'test'
|
|
232
|
+
assert_select 'span.hint', 'test'
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
test 'builder should be able to disable a hint even if it exists in i18n' do
|
|
236
|
+
store_translations(:en, :simple_form => { :hints => { :name => 'Hint test' } }) do
|
|
237
|
+
with_form_for @user, :name, :hint => false
|
|
238
|
+
assert_no_select 'span.hint'
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
test 'builder should pass options to hint' do
|
|
243
|
+
with_form_for @user, :name, :hint => 'test', :hint_html => { :id => "cool" }
|
|
244
|
+
assert_select 'span.hint#cool', 'test'
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
test 'builder should generate errors for attribute without errors' do
|
|
248
|
+
with_form_for @user, :credit_limit
|
|
249
|
+
assert_no_select 'span.errors'
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
test 'builder should generate errors for attribute with errors' do
|
|
253
|
+
with_form_for @user, :name
|
|
254
|
+
assert_select 'span.error', "can't be blank"
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
test 'builder should be able to disable showing errors for a input' do
|
|
258
|
+
with_form_for @user, :name, :error => false
|
|
259
|
+
assert_no_select 'span.error'
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
test 'builder should pass options to errors' do
|
|
263
|
+
with_form_for @user, :name, :error_html => { :id => "cool" }
|
|
264
|
+
assert_select 'span.error#cool', "can't be blank"
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
test 'placeholder should not be generated when set to false' do
|
|
268
|
+
store_translations(:en, :simple_form => { :placeholders => { :user => {
|
|
269
|
+
:name => 'Name goes here'
|
|
270
|
+
} } }) do
|
|
271
|
+
with_form_for @user, :name, :placeholder => false
|
|
272
|
+
assert_no_select 'input[placeholder]'
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# DEFAULT OPTIONS
|
|
277
|
+
test 'builder should receive a default argument and pass it to the inputs' do
|
|
278
|
+
with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class' } } do |f|
|
|
279
|
+
f.input :name
|
|
280
|
+
end
|
|
281
|
+
assert_select 'input.default_class'
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
test 'builder should receive a default argument and pass it to the inputs, respecting the specific options' do
|
|
285
|
+
with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class' } } do |f|
|
|
286
|
+
f.input :name, :input_html => { :id => 'specific_id' }
|
|
287
|
+
end
|
|
288
|
+
assert_select 'input.default_class#specific_id'
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
test 'builder should receive a default argument and pass it to the inputs, overwriting the defaults with specific options' do
|
|
292
|
+
with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class', :id => 'default_id' } } do |f|
|
|
293
|
+
f.input :name, :input_html => { :id => 'specific_id' }
|
|
294
|
+
end
|
|
295
|
+
assert_select 'input.default_class#specific_id'
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
test 'builder should receive a default argument and pass it to the inputs without changing the defaults' do
|
|
299
|
+
with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class', :id => 'default_id' } } do |f|
|
|
300
|
+
concat(f.input :name)
|
|
301
|
+
concat(f.input :credit_limit)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
assert_select "input.string.default_class[name='user[name]']"
|
|
305
|
+
assert_no_select "input.string[name='user[credit_limit]']"
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# WITHOUT OBJECT
|
|
309
|
+
test 'builder should generate properly when object is not present' do
|
|
310
|
+
with_form_for :project, :name
|
|
311
|
+
assert_select 'form input.string#project_name'
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
test 'builder should generate password fields based on attribute name when object is not present' do
|
|
315
|
+
with_form_for :project, :password_confirmation
|
|
316
|
+
assert_select 'form input[type=password].password#project_password_confirmation'
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
test 'builder should generate text fields by default for all attributes when object is not present' do
|
|
320
|
+
with_form_for :project, :created_at
|
|
321
|
+
assert_select 'form input.string#project_created_at'
|
|
322
|
+
with_form_for :project, :budget
|
|
323
|
+
assert_select 'form input.string#project_budget'
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
test 'builder should allow overriding input type when object is not present' do
|
|
327
|
+
with_form_for :project, :created_at, :as => :datetime
|
|
328
|
+
assert_select 'form select.datetime#project_created_at_1i'
|
|
329
|
+
with_form_for :project, :budget, :as => :decimal
|
|
330
|
+
assert_select 'form input.decimal#project_budget'
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# CUSTOM FORM BUILDER
|
|
334
|
+
test 'custom builder should inherit mappings' do
|
|
335
|
+
with_custom_form_for @user, :email
|
|
336
|
+
assert_select 'form input[type=email]#user_email.custom'
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
test 'form with CustomMapTypeFormBuilder should use custom map type builder' do
|
|
340
|
+
with_concat_custom_mapping_form_for(:user) do |user|
|
|
341
|
+
assert user.instance_of?(CustomMapTypeFormBuilder)
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
test 'form with CustomMapTypeFormBuilder should use custom mapping' do
|
|
346
|
+
with_concat_custom_mapping_form_for(:user) do |user|
|
|
347
|
+
assert_equal SimpleForm::Inputs::StringInput, user.class.mappings[:custom_type]
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
test 'form without CustomMapTypeFormBuilder should not use custom mapping' do
|
|
352
|
+
with_concat_form_for(:user) do |user|
|
|
353
|
+
assert_nil user.class.mappings[:custom_type]
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
# Tests for f.hint
|
|
4
|
+
class HintTest < ActionView::TestCase
|
|
5
|
+
def with_hint_for(object, *args)
|
|
6
|
+
with_concat_form_for(object) do |f|
|
|
7
|
+
f.hint(*args)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
test 'hint should not be generated by default' do
|
|
12
|
+
with_hint_for @user, :name
|
|
13
|
+
assert_no_select 'span.hint'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
test 'hint should be generated with optional text' do
|
|
17
|
+
with_hint_for @user, :name, :hint => 'Use with care...'
|
|
18
|
+
assert_select 'span.hint', 'Use with care...'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
test 'hint should not modify the options hash' do
|
|
22
|
+
options = { :hint => 'Use with care...' }
|
|
23
|
+
with_hint_for @user, :name, options
|
|
24
|
+
assert_select 'span.hint', 'Use with care...'
|
|
25
|
+
assert_equal({ :hint => 'Use with care...' }, options)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test 'hint should be generated cleanly with optional text' do
|
|
29
|
+
with_hint_for @user, :name, :hint => 'Use with care...', :hint_tag => :span
|
|
30
|
+
assert_no_select 'span.hint[hint]'
|
|
31
|
+
assert_no_select 'span.hint[hint_tag]'
|
|
32
|
+
assert_no_select 'span.hint[hint_html]'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
test 'hint uses the current component tag set' do
|
|
36
|
+
with_hint_for @user, :name, :hint => 'Use with care...', :hint_tag => :p
|
|
37
|
+
assert_select 'p.hint', 'Use with care...'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
test 'hint should be able to pass html options' do
|
|
41
|
+
with_hint_for @user, :name, :hint => 'Yay!', :id => 'hint', :class => 'yay'
|
|
42
|
+
assert_select 'span#hint.hint.yay'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Without attribute name
|
|
46
|
+
|
|
47
|
+
test 'hint without attribute name' do
|
|
48
|
+
with_hint_for @validating_user, 'Hello World!'
|
|
49
|
+
assert_select 'span.hint', 'Hello World!'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
test 'hint without attribute name should generate component tag with a clean HTML' do
|
|
53
|
+
with_hint_for @validating_user, 'Hello World!'
|
|
54
|
+
assert_no_select 'span.hint[hint]'
|
|
55
|
+
assert_no_select 'span.hint[hint_html]'
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
test 'hint without attribute name uses the current component tag set' do
|
|
59
|
+
with_hint_for @user, 'Hello World!', :hint_tag => :p
|
|
60
|
+
assert_no_select 'p.hint[hint]'
|
|
61
|
+
assert_no_select 'p.hint[hint_html]'
|
|
62
|
+
assert_no_select 'p.hint[hint_tag]'
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
test 'hint without attribute name should be able to pass html options' do
|
|
66
|
+
with_hint_for @user, 'Yay', :id => 'hint', :class => 'yay'
|
|
67
|
+
assert_select 'span#hint.hint.yay', 'Yay'
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# I18n
|
|
71
|
+
|
|
72
|
+
test 'hint should use i18n based on model, action, and attribute to lookup translation' do
|
|
73
|
+
store_translations(:en, :simple_form => { :hints => { :user => {
|
|
74
|
+
:edit => { :name => 'Content of this input will be truncated...' }
|
|
75
|
+
} } }) do
|
|
76
|
+
with_hint_for @user, :name
|
|
77
|
+
assert_select 'span.hint', 'Content of this input will be truncated...'
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
test 'hint should use i18n with model and attribute to lookup translation' do
|
|
82
|
+
store_translations(:en, :simple_form => { :hints => { :user => {
|
|
83
|
+
:name => 'Content of this input will be capitalized...'
|
|
84
|
+
} } }) do
|
|
85
|
+
with_hint_for @user, :name
|
|
86
|
+
assert_select 'span.hint', 'Content of this input will be capitalized...'
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
test 'hint should use i18n under defaults namespace to lookup translation' do
|
|
91
|
+
store_translations(:en, :simple_form => {
|
|
92
|
+
:hints => {:defaults => {:name => 'Content of this input will be downcased...' } }
|
|
93
|
+
}) do
|
|
94
|
+
with_hint_for @user, :name
|
|
95
|
+
assert_select 'span.hint', 'Content of this input will be downcased...'
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
test 'hint should use i18n with lookup for association name' do
|
|
100
|
+
store_translations(:en, :simple_form => { :hints => {
|
|
101
|
+
:user => { :company => 'My company!' }
|
|
102
|
+
} } ) do
|
|
103
|
+
with_hint_for @user, :company_id, :as => :string, :reflection => Association.new(Company, :company, {})
|
|
104
|
+
assert_select 'span.hint', /My company!/
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# No object
|
|
109
|
+
|
|
110
|
+
test 'hint should generate properly when object is not present' do
|
|
111
|
+
with_hint_for :project, :name, :hint => 'Test without object'
|
|
112
|
+
assert_select 'span.hint', 'Test without object'
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Custom wrappers
|
|
116
|
+
|
|
117
|
+
test 'hint with custom wrappers works' do
|
|
118
|
+
swap_wrapper do
|
|
119
|
+
with_hint_for @user, :name, :hint => "can't be blank"
|
|
120
|
+
assert_select 'div.omg_hint', "can't be blank"
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
# Tests for f.input_field
|
|
4
|
+
class InputFieldTest < ActionView::TestCase
|
|
5
|
+
test "builder input_field should only render the input tag, nothing else" do
|
|
6
|
+
with_concat_form_for(@user) do |f|
|
|
7
|
+
f.input_field :name
|
|
8
|
+
end
|
|
9
|
+
assert_select 'form > input.required.string'
|
|
10
|
+
assert_no_select 'div.string'
|
|
11
|
+
assert_no_select 'label'
|
|
12
|
+
assert_no_select '.hint'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test 'builder input_field should allow overriding default input type' do
|
|
16
|
+
with_concat_form_for(@user) do |f|
|
|
17
|
+
f.input_field :name, :as => :text
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
assert_no_select 'input#user_name'
|
|
21
|
+
assert_select 'textarea#user_name.text'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
test 'builder input_field should allow passing options to input tag' do
|
|
25
|
+
with_concat_form_for(@user) do |f|
|
|
26
|
+
f.input_field :name, :id => 'name_input', :class => 'name'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
assert_select 'input.string.name#name_input'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
test 'builder input_field should not modify the options hash' do
|
|
33
|
+
options = { :id => 'name_input', :class => 'name' }
|
|
34
|
+
|
|
35
|
+
with_concat_form_for(@user) do |f|
|
|
36
|
+
f.input_field :name, options
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
assert_select 'input.string.name#name_input'
|
|
40
|
+
assert_equal({ :id => 'name_input', :class => 'name' }, options)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
test 'builder input_field should generate an input tag with a clean HTML' do
|
|
45
|
+
with_concat_form_for(@user) do |f|
|
|
46
|
+
f.input_field :name, :as => :integer, :class => 'name'
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
assert_no_select 'input.integer[input_html]'
|
|
50
|
+
assert_no_select 'input.integer[as]'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
test 'builder collection input_field should generate input tag with a clean HTML' do
|
|
54
|
+
with_concat_form_for(@user) do |f|
|
|
55
|
+
f.input_field :status, :collection => ['Open', 'Closed'], :class => 'status', :label_method => :to_s, :value_method => :to_s
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
assert_no_select 'select.status[input_html]'
|
|
59
|
+
assert_no_select 'select.status[collection]'
|
|
60
|
+
assert_no_select 'select.status[label_method]'
|
|
61
|
+
assert_no_select 'select.status[value_method]'
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
require 'test_helper'
|
|
3
|
+
|
|
4
|
+
class LabelTest < ActionView::TestCase
|
|
5
|
+
def with_label_for(object, *args, &block)
|
|
6
|
+
with_concat_form_for(object) do |f|
|
|
7
|
+
f.label(*args, &block)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
test 'builder should generate a label for the attribute' do
|
|
12
|
+
with_label_for @user, :name
|
|
13
|
+
assert_select 'label.string[for=user_name]', /Name/
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
test 'builder should generate a label componet tag with a clean HTML' do
|
|
17
|
+
with_label_for @user, :name
|
|
18
|
+
assert_no_select 'label.string[label_html]'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
test 'builder should add a required class to label if the attribute is required' do
|
|
22
|
+
with_label_for @validating_user, :name
|
|
23
|
+
assert_select 'label.string.required[for=validating_user_name]', /Name/
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
test 'builder should allow passing options to label tag' do
|
|
27
|
+
with_label_for @user, :name, :label => 'My label', :id => 'name_label'
|
|
28
|
+
assert_select 'label.string#name_label', /My label/
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test 'builder label should generate label tag with clean HTML' do
|
|
32
|
+
with_label_for @user, :name, :label => 'My label', :required => true, :id => 'name_label'
|
|
33
|
+
assert_select 'label.string#name_label', /My label/
|
|
34
|
+
assert_no_select 'label[label]'
|
|
35
|
+
assert_no_select 'label[required]'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test 'builder should not modify the options hash' do
|
|
39
|
+
options = { :label => 'My label', :id => 'name_label' }
|
|
40
|
+
with_label_for @user, :name, options
|
|
41
|
+
assert_select 'label.string#name_label', /My label/
|
|
42
|
+
assert_equal({ :label => 'My label', :id => 'name_label' }, options)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
test 'builder should fallback to default label when string is given' do
|
|
46
|
+
with_label_for @user, :name, 'Nome do usuário'
|
|
47
|
+
assert_select 'label', 'Nome do usuário'
|
|
48
|
+
assert_no_select 'label.string'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
test 'builder should fallback to default label when block is given' do
|
|
52
|
+
with_label_for @user, :name do
|
|
53
|
+
'Nome do usuário'
|
|
54
|
+
end
|
|
55
|
+
assert_select 'label', 'Nome do usuário'
|
|
56
|
+
assert_no_select 'label.string'
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
test 'builder allows label order to be changed' do
|
|
60
|
+
swap SimpleForm, :label_text => lambda { |l, r| "#{l}:" } do
|
|
61
|
+
with_label_for @user, :age
|
|
62
|
+
assert_select 'label.integer[for=user_age]', "Age:"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|