simple_form 1.2.0 → 1.4.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/.gitignore +2 -0
- data/.gitmodules +3 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.rdoc +109 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +82 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +180 -53
- data/Rakefile +27 -0
- data/lib/generators/simple_form/USAGE +1 -1
- data/lib/generators/simple_form/install_generator.rb +5 -6
- data/lib/generators/simple_form/templates/_form.html.erb +2 -12
- data/lib/generators/simple_form/templates/_form.html.haml +10 -0
- data/lib/generators/simple_form/templates/_form.html.slim +10 -0
- data/lib/generators/simple_form/templates/en.yml +14 -0
- data/lib/generators/simple_form/templates/simple_form.rb +66 -12
- data/lib/simple_form/action_view_extensions/builder.rb +99 -40
- data/lib/simple_form/action_view_extensions/form_helper.rb +29 -6
- data/lib/simple_form/components/errors.rb +16 -6
- data/lib/simple_form/components/hints.rb +2 -2
- data/lib/simple_form/components/label_input.rb +13 -0
- data/lib/simple_form/components/labels.rb +5 -7
- data/lib/simple_form/components/placeholders.rb +22 -0
- data/lib/simple_form/components/wrapper.rb +19 -2
- data/lib/simple_form/components.rb +6 -4
- data/lib/simple_form/error_notification.rb +42 -0
- data/lib/simple_form/form_builder.rb +187 -72
- data/lib/simple_form/has_errors.rb +14 -0
- data/lib/simple_form/inputs/base.rb +106 -24
- data/lib/simple_form/inputs/block_input.rb +3 -2
- data/lib/simple_form/inputs/boolean_input.rb +22 -0
- data/lib/simple_form/inputs/collection_input.rb +46 -17
- data/lib/simple_form/inputs/date_time_input.rb +11 -5
- data/lib/simple_form/inputs/hidden_input.rb +11 -2
- data/lib/simple_form/inputs/mapping_input.rb +12 -6
- data/lib/simple_form/inputs/numeric_input.rb +55 -6
- data/lib/simple_form/inputs/priority_input.rb +5 -1
- data/lib/simple_form/inputs/string_input.rb +25 -11
- data/lib/simple_form/inputs.rb +1 -0
- data/lib/simple_form/map_type.rb +9 -6
- data/lib/simple_form/version.rb +1 -1
- data/lib/simple_form.rb +92 -8
- data/simple_form.gemspec +22 -0
- data/test/action_view_extensions/builder_test.rb +187 -51
- data/test/action_view_extensions/form_helper_test.rb +17 -5
- data/test/components/error_test.rb +23 -12
- data/test/components/hint_test.rb +4 -8
- data/test/components/label_test.rb +79 -11
- data/test/components/wrapper_test.rb +63 -0
- data/test/discovery_inputs.rb +21 -0
- data/test/error_notification_test.rb +62 -0
- data/test/form_builder_test.rb +332 -35
- data/test/inputs_test.rb +516 -53
- data/test/support/misc_helpers.rb +32 -4
- data/test/support/mock_controller.rb +4 -4
- data/test/support/models.rb +75 -11
- data/test/test_helper.rb +28 -12
- metadata +51 -11
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class WrapperTest < ActionView::TestCase
|
|
4
|
+
def with_error_for(object, attribute_name, &block)
|
|
5
|
+
with_concat_form_for(object) do |f|
|
|
6
|
+
f.input attribute_name
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def with_form_for(object, *args, &block)
|
|
11
|
+
with_concat_form_for(object) do |f|
|
|
12
|
+
f.input(*args, &block)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
test 'wrapper should not have error class for attribute without errors' do
|
|
17
|
+
with_error_for @user, :active
|
|
18
|
+
assert_no_select 'div.field_with_errors'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
test 'wrapper should not have error class when object is not present' do
|
|
22
|
+
with_error_for :project, :name
|
|
23
|
+
assert_no_select 'div.field_with_errors'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
test 'wrapper should add error class for attribute with errors' do
|
|
27
|
+
with_error_for @user, :name
|
|
28
|
+
assert_select 'div.field_with_errors'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test 'wrapper should add chosen error class for attribute with errors' do
|
|
32
|
+
swap SimpleForm, :wrapper_error_class => "omgError" do
|
|
33
|
+
with_error_for @user, :name
|
|
34
|
+
assert_select 'div.omgError'
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test 'wrapper should add chosen wrapper class' do
|
|
39
|
+
swap SimpleForm, :wrapper_class => "wrapper" do
|
|
40
|
+
with_form_for @user, :active
|
|
41
|
+
assert_select 'div.wrapper'
|
|
42
|
+
assert_no_select 'div.input'
|
|
43
|
+
|
|
44
|
+
with_form_for @user, :name
|
|
45
|
+
assert_select 'div.wrapper'
|
|
46
|
+
assert_no_select 'div.input'
|
|
47
|
+
|
|
48
|
+
with_form_for :project, :name
|
|
49
|
+
assert_select 'div.wrapper'
|
|
50
|
+
assert_no_select 'div.input'
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
test 'wrapper should not have disabled class by default' do
|
|
55
|
+
with_form_for @user, :active
|
|
56
|
+
assert_no_select 'div.disabled'
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
test 'wrapper should add disabled class when the input is disabled' do
|
|
60
|
+
with_form_for @user, :active, :disabled => true
|
|
61
|
+
assert_select 'div.disabled'
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class StringInput < SimpleForm::Inputs::StringInput
|
|
2
|
+
def input
|
|
3
|
+
"<section>#{super}</section>".html_safe
|
|
4
|
+
end
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
class NumericInput < SimpleForm::Inputs::NumericInput
|
|
8
|
+
def input
|
|
9
|
+
"<section>#{super}</section>".html_safe
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class CustomizedInput < SimpleForm::Inputs::StringInput
|
|
14
|
+
def input
|
|
15
|
+
"<section>#{super}</section>".html_safe
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def input_method
|
|
19
|
+
:text_field
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
require 'test_helper'
|
|
3
|
+
|
|
4
|
+
class ErrorNotificationTest < ActionView::TestCase
|
|
5
|
+
|
|
6
|
+
def with_error_notification_for(object, options={}, &block)
|
|
7
|
+
with_concat_form_for(object) do |f|
|
|
8
|
+
f.error_notification(options)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
test 'error notification is not generated when the object has no error' do
|
|
13
|
+
assert @validating_user.valid?
|
|
14
|
+
with_error_notification_for @validating_user
|
|
15
|
+
assert_no_select 'p.error_notification'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
test 'error notification is not generated for forms without objects' do
|
|
19
|
+
with_error_notification_for :user
|
|
20
|
+
assert_no_select 'p.error_notification'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
test 'error notification is generated when the object has some error' do
|
|
24
|
+
with_error_notification_for @user
|
|
25
|
+
assert_select 'p.error_notification', 'Some errors were found, please take a look:'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test 'error notification uses I18n based on model to generate the notification message' do
|
|
29
|
+
store_translations(:en, :simple_form => { :error_notification => { :user =>
|
|
30
|
+
'Alguns erros foram encontrados para o usuário:'
|
|
31
|
+
} }) do
|
|
32
|
+
with_error_notification_for @user
|
|
33
|
+
assert_select 'p.error_notification', 'Alguns erros foram encontrados para o usuário:'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
test 'error notification uses I18n fallbacking to default message' do
|
|
38
|
+
store_translations(:en, :simple_form => { :error_notification => {
|
|
39
|
+
:default_message => 'Opa! Alguns erros foram encontrados, poderia verificar?'
|
|
40
|
+
} }) do
|
|
41
|
+
with_error_notification_for @user
|
|
42
|
+
assert_select 'p.error_notification', 'Opa! Alguns erros foram encontrados, poderia verificar?'
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
test 'error notification allows passing the notification message' do
|
|
47
|
+
with_error_notification_for @user, :message => 'Erro encontrado ao criar usuario'
|
|
48
|
+
assert_select 'p.error_notification', 'Erro encontrado ao criar usuario'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
test 'error notification accepts other html options' do
|
|
52
|
+
with_error_notification_for @user, :id => 'user_error_message', :class => 'form_error'
|
|
53
|
+
assert_select 'p#user_error_message.form_error.error_notification'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
test 'error notification allows configuring the wrapper element' do
|
|
57
|
+
swap SimpleForm, :error_notification_tag => :div do
|
|
58
|
+
with_error_notification_for @user
|
|
59
|
+
assert_select 'div.error_notification'
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
data/test/form_builder_test.rb
CHANGED
|
@@ -1,41 +1,54 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
1
2
|
require 'test_helper'
|
|
2
3
|
|
|
3
4
|
class FormBuilderTest < ActionView::TestCase
|
|
4
5
|
|
|
5
6
|
def with_form_for(object, *args, &block)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
end
|
|
7
|
+
with_concat_form_for(object) do |f|
|
|
8
|
+
f.input(*args, &block)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def with_custom_form_for(object, *args, &block)
|
|
13
|
+
with_concat_custom_form_for(object) do |f|
|
|
14
|
+
f.input(*args, &block)
|
|
15
|
+
end
|
|
9
16
|
end
|
|
10
17
|
|
|
11
18
|
def with_button_for(object, *args)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
end
|
|
19
|
+
with_concat_form_for(object) do |f|
|
|
20
|
+
f.button(*args)
|
|
21
|
+
end
|
|
15
22
|
end
|
|
16
23
|
|
|
17
24
|
def with_error_for(object, *args)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
end
|
|
25
|
+
with_concat_form_for(object) do |f|
|
|
26
|
+
f.error(*args)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def with_full_error_for(object, *args)
|
|
31
|
+
with_concat_form_for(object) do |f|
|
|
32
|
+
f.full_error(*args)
|
|
33
|
+
end
|
|
21
34
|
end
|
|
22
35
|
|
|
23
36
|
def with_hint_for(object, *args)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
end
|
|
37
|
+
with_concat_form_for(object) do |f|
|
|
38
|
+
f.hint(*args)
|
|
39
|
+
end
|
|
27
40
|
end
|
|
28
41
|
|
|
29
42
|
def with_label_for(object, *args)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
end
|
|
43
|
+
with_concat_form_for(object) do |f|
|
|
44
|
+
f.label(*args)
|
|
45
|
+
end
|
|
33
46
|
end
|
|
34
47
|
|
|
35
48
|
def with_association_for(object, *args)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
end
|
|
49
|
+
with_concat_form_for(object) do |f|
|
|
50
|
+
f.association(*args)
|
|
51
|
+
end
|
|
39
52
|
end
|
|
40
53
|
|
|
41
54
|
# All
|
|
@@ -55,12 +68,44 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
55
68
|
|
|
56
69
|
test 'builder input should allow a block to configure input' do
|
|
57
70
|
with_form_for @user, :name do
|
|
58
|
-
|
|
71
|
+
text_field_tag :foo, :bar, :id => :cool
|
|
59
72
|
end
|
|
60
73
|
assert_no_select 'input.string'
|
|
61
74
|
assert_select 'input#cool'
|
|
62
75
|
end
|
|
63
76
|
|
|
77
|
+
test 'builder should allow adding custom input mappings for default input types' do
|
|
78
|
+
swap SimpleForm, :input_mappings => { /count$/ => :integer } do
|
|
79
|
+
with_form_for @user, :post_count
|
|
80
|
+
assert_no_select 'form input#user_post_count.string'
|
|
81
|
+
assert_select 'form input#user_post_count.numeric.integer'
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
test 'builder should allow adding custom input mappings for integer input types' do
|
|
86
|
+
swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
|
|
87
|
+
with_form_for @user, :lock_version
|
|
88
|
+
assert_no_select 'form input#user_lock_version.integer'
|
|
89
|
+
assert_select 'form input#user_lock_version.hidden'
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
test 'builder uses the first matching custom input map when more than one match' do
|
|
94
|
+
swap SimpleForm, :input_mappings => { /count$/ => :integer, /^post_/ => :password } do
|
|
95
|
+
with_form_for @user, :post_count
|
|
96
|
+
assert_no_select 'form input#user_post_count.password'
|
|
97
|
+
assert_select 'form input#user_post_count.numeric.integer'
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
test 'builder uses the custom map only for matched attributes' do
|
|
102
|
+
swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
|
|
103
|
+
with_form_for @user, :post_count
|
|
104
|
+
assert_no_select 'form input#user_post_count.hidden'
|
|
105
|
+
assert_select 'form input#user_post_count.string'
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
64
109
|
# INPUT TYPES
|
|
65
110
|
test 'builder should generate text fields for string columns' do
|
|
66
111
|
with_form_for @user, :name
|
|
@@ -107,6 +152,11 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
107
152
|
assert_select 'form input#user_email.string.email'
|
|
108
153
|
end
|
|
109
154
|
|
|
155
|
+
test 'builder should generate tel fields for columns that matches phone' do
|
|
156
|
+
with_form_for @user, :phone_number
|
|
157
|
+
assert_select 'form input#user_phone_number.string.tel'
|
|
158
|
+
end
|
|
159
|
+
|
|
110
160
|
test 'builder should generate url fields for columns that matches url' do
|
|
111
161
|
with_form_for @user, :url
|
|
112
162
|
assert_select 'form input#user_url.string.url'
|
|
@@ -142,6 +192,14 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
142
192
|
assert_select 'form input#user_avatar.file'
|
|
143
193
|
end
|
|
144
194
|
|
|
195
|
+
test 'builder should generate file for attributes that are real db columns but have file methods' do
|
|
196
|
+
@user.home_picture = mock("file")
|
|
197
|
+
@user.home_picture.expects(:respond_to?).with(:mounted_as).returns(true)
|
|
198
|
+
|
|
199
|
+
with_form_for @user, :home_picture
|
|
200
|
+
assert_select 'form input#user_home_picture.file'
|
|
201
|
+
end
|
|
202
|
+
|
|
145
203
|
test 'build should generate select if a collection is given' do
|
|
146
204
|
with_form_for @user, :age, :collection => 1..60
|
|
147
205
|
assert_select 'form select#user_age.select'
|
|
@@ -162,6 +220,13 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
162
220
|
end
|
|
163
221
|
|
|
164
222
|
# COMMON OPTIONS
|
|
223
|
+
test 'builder should add chosen form class' do
|
|
224
|
+
swap SimpleForm, :form_class => :my_custom_class do
|
|
225
|
+
with_form_for @user, :name
|
|
226
|
+
assert_select 'form.my_custom_class'
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
165
230
|
test 'builder should allow passing options to input' do
|
|
166
231
|
with_form_for @user, :name, :input_html => { :class => 'my_input', :id => 'my_input' }
|
|
167
232
|
assert_select 'form input#my_input.my_input.string'
|
|
@@ -229,29 +294,47 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
229
294
|
assert_select 'span.error#cool', "can't be blank"
|
|
230
295
|
end
|
|
231
296
|
|
|
232
|
-
|
|
297
|
+
test 'placeholder should not be generated when set to false' do
|
|
298
|
+
store_translations(:en, :simple_form => { :placeholders => { :user => {
|
|
299
|
+
:name => 'Name goes here'
|
|
300
|
+
} } }) do
|
|
301
|
+
with_form_for @user, :name, :placeholder => false
|
|
302
|
+
assert_no_select 'input[placeholder]'
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# REQUIRED AND PRESENCE VALIDATION
|
|
233
307
|
test 'builder input should obtain required from ActiveModel::Validations when it is included' do
|
|
234
308
|
with_form_for @validating_user, :name
|
|
235
|
-
assert_select 'input.required#validating_user_name'
|
|
309
|
+
assert_select 'input.required[required]#validating_user_name'
|
|
236
310
|
with_form_for @validating_user, :status
|
|
237
311
|
assert_select 'input.optional#validating_user_status'
|
|
238
312
|
end
|
|
239
|
-
|
|
313
|
+
|
|
240
314
|
test 'builder input should allow overriding required when ActiveModel::Validations is included' do
|
|
241
315
|
with_form_for @validating_user, :name, :required => false
|
|
242
316
|
assert_select 'input.optional#validating_user_name'
|
|
243
317
|
with_form_for @validating_user, :status, :required => true
|
|
244
|
-
assert_select 'input.required#validating_user_status'
|
|
318
|
+
assert_select 'input.required[required]#validating_user_status'
|
|
245
319
|
end
|
|
246
|
-
|
|
320
|
+
|
|
247
321
|
test 'builder input should be required by default when ActiveModel::Validations is not included' do
|
|
248
322
|
with_form_for @user, :name
|
|
249
|
-
assert_select 'input.required#user_name'
|
|
323
|
+
assert_select 'input.required[required]#user_name'
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
test 'builder input should not be required by default when ActiveModel::Validations is not included if option is set to false' do
|
|
327
|
+
swap SimpleForm, :required_by_default => false do
|
|
328
|
+
with_form_for @user, :name
|
|
329
|
+
assert_select 'input.optional#user_name'
|
|
330
|
+
assert_no_select 'input[required]'
|
|
331
|
+
end
|
|
250
332
|
end
|
|
251
|
-
|
|
333
|
+
|
|
252
334
|
test 'builder input should allow disabling required when ActiveModel::Validations is not included' do
|
|
253
335
|
with_form_for @user, :name, :required => false
|
|
254
336
|
assert_no_select 'input.required'
|
|
337
|
+
assert_no_select 'input[required]'
|
|
255
338
|
assert_select 'input.optional#user_name'
|
|
256
339
|
end
|
|
257
340
|
|
|
@@ -282,12 +365,61 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
282
365
|
end
|
|
283
366
|
|
|
284
367
|
test 'builder allows wrapper tag to be given on demand' do
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
end
|
|
368
|
+
with_concat_form_for(@user) do |f|
|
|
369
|
+
f.input :name, :wrapper_tag => :b
|
|
370
|
+
end
|
|
288
371
|
assert_select 'form b.required.string'
|
|
289
372
|
end
|
|
290
373
|
|
|
374
|
+
test 'builder allows wrapper class to be given on demand' do
|
|
375
|
+
with_concat_form_for(@user) do |f|
|
|
376
|
+
f.input :name, :wrapper_class => :wrapper
|
|
377
|
+
end
|
|
378
|
+
assert_select 'form div.wrapper.required.string'
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
test 'builder wrapping tag adds errors class for attribute with errors' do
|
|
382
|
+
with_form_for @user, :name
|
|
383
|
+
assert_select 'form div.input.required.string.field_with_errors'
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
# ONLY THE INPUT TAG
|
|
387
|
+
test "builder input_field should only render the input tag, nothing else" do
|
|
388
|
+
with_concat_form_for(@user) do |f|
|
|
389
|
+
f.input_field :name
|
|
390
|
+
end
|
|
391
|
+
assert_select 'form > input.required.string'
|
|
392
|
+
assert_no_select 'div.string'
|
|
393
|
+
assert_no_select 'label'
|
|
394
|
+
assert_no_select '.hint'
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
test 'builder input_field should allow overriding default input type' do
|
|
398
|
+
with_concat_form_for(@user) do |f|
|
|
399
|
+
f.input_field :name, :as => :text
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
assert_no_select 'input#user_name'
|
|
403
|
+
assert_select 'textarea#user_name.text'
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
test 'builder input_field should allow passing options to input tag' do
|
|
407
|
+
with_concat_form_for(@user) do |f|
|
|
408
|
+
f.input_field :name, :id => 'name_input', :class => 'name'
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
assert_select 'input.string.name#name_input'
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
test 'builder input_field should generate an input tag with a clean HTML' do
|
|
415
|
+
with_concat_form_for(@user) do |f|
|
|
416
|
+
f.input_field :name, :as => :integer, :class => 'name'
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
assert_no_select 'input.integer[input_html]'
|
|
420
|
+
assert_no_select 'input.integer[as]'
|
|
421
|
+
end
|
|
422
|
+
|
|
291
423
|
# WITHOUT OBJECT
|
|
292
424
|
test 'builder should generate properly when object is not present' do
|
|
293
425
|
with_form_for :project, :name
|
|
@@ -319,11 +451,32 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
319
451
|
assert_select 'span.error', "can't be blank"
|
|
320
452
|
end
|
|
321
453
|
|
|
454
|
+
test 'builder should generate an error tag with a clean HTML' do
|
|
455
|
+
with_error_for @user, :name
|
|
456
|
+
assert_no_select 'span.error[error_html]'
|
|
457
|
+
end
|
|
458
|
+
|
|
322
459
|
test 'builder should allow passing options to error tag' do
|
|
323
460
|
with_error_for @user, :name, :id => 'name_error'
|
|
324
461
|
assert_select 'span.error#name_error', "can't be blank"
|
|
325
462
|
end
|
|
326
463
|
|
|
464
|
+
# FULL ERRORS
|
|
465
|
+
test 'builder should generate an full error tag for the attribute' do
|
|
466
|
+
with_full_error_for @user, :name
|
|
467
|
+
assert_select 'span.error', "Super User Name! can't be blank"
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
test 'builder should generate an full error tag with a clean HTML' do
|
|
471
|
+
with_full_error_for @user, :name
|
|
472
|
+
assert_no_select 'span.error[error_html]'
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
test 'builder should allow passing options to full error tag' do
|
|
476
|
+
with_full_error_for @user, :name, :id => 'name_error', :error_prefix => "Your name"
|
|
477
|
+
assert_select 'span.error#name_error', "Your name can't be blank"
|
|
478
|
+
end
|
|
479
|
+
|
|
327
480
|
# HINTS
|
|
328
481
|
test 'builder should generate a hint tag for the attribute' do
|
|
329
482
|
store_translations(:en, :simple_form => { :hints => { :user => { :name => "Add your name" }}}) do
|
|
@@ -332,10 +485,21 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
332
485
|
end
|
|
333
486
|
end
|
|
334
487
|
|
|
488
|
+
test 'builder should generate a hint component tag for the given text for a model with ActiveModel::Validations' do
|
|
489
|
+
with_hint_for @validating_user, 'Hello World!'
|
|
490
|
+
assert_select 'span.hint', 'Hello World!'
|
|
491
|
+
end
|
|
492
|
+
|
|
335
493
|
test 'builder should generate a hint component tag for the given text' do
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
494
|
+
with_hint_for @user, 'Hello World!'
|
|
495
|
+
assert_select 'span.hint', 'Hello World!'
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
test 'builder should generate a hint componet tag with a clean HTML' do
|
|
499
|
+
with_hint_for @validating_user, 'Hello World!'
|
|
500
|
+
assert_no_select 'span.hint[hint]'
|
|
501
|
+
assert_no_select 'span.hint[hint_html]'
|
|
502
|
+
end
|
|
339
503
|
|
|
340
504
|
test 'builder should allow passing options to hint tag' do
|
|
341
505
|
with_hint_for @user, :name, :hint => 'Hello World!', :id => 'name_hint'
|
|
@@ -348,9 +512,14 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
348
512
|
assert_select 'label.string[for=user_name]', /Name/
|
|
349
513
|
end
|
|
350
514
|
|
|
515
|
+
test 'builder should generate a label componet tag with a clean HTML' do
|
|
516
|
+
with_label_for @user, :name
|
|
517
|
+
assert_no_select 'label.string[label_html]'
|
|
518
|
+
end
|
|
519
|
+
|
|
351
520
|
test 'builder should add a required class to label if the attribute is required' do
|
|
352
521
|
with_label_for @validating_user, :name
|
|
353
|
-
assert_select 'label.string[for=validating_user_name]', /Name/
|
|
522
|
+
assert_select 'label.string.required[for=validating_user_name]', /Name/
|
|
354
523
|
end
|
|
355
524
|
|
|
356
525
|
test 'builder should allow passing options to label tag' do
|
|
@@ -374,13 +543,13 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
374
543
|
# BUTTONS
|
|
375
544
|
test 'builder should create buttons' do
|
|
376
545
|
with_button_for :post, :submit
|
|
377
|
-
assert_select 'form input[type=submit][value=Save Post]'
|
|
546
|
+
assert_select 'form input.button[type=submit][value=Save Post]'
|
|
378
547
|
end
|
|
379
548
|
|
|
380
549
|
test 'builder should create buttons for records' do
|
|
381
550
|
@user.new_record!
|
|
382
551
|
with_button_for @user, :submit
|
|
383
|
-
assert_select 'form input[type=submit][value=Create User]'
|
|
552
|
+
assert_select 'form input.button[type=submit][value=Create User]'
|
|
384
553
|
end
|
|
385
554
|
|
|
386
555
|
# ASSOCIATIONS
|
|
@@ -409,6 +578,43 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
409
578
|
assert_equal 3, calls
|
|
410
579
|
end
|
|
411
580
|
|
|
581
|
+
test 'builder association mark input as required based both association and attribute' do
|
|
582
|
+
swap SimpleForm, :required_by_default => false do
|
|
583
|
+
with_association_for @validating_user, :company, :collection => []
|
|
584
|
+
assert_select 'label.required'
|
|
585
|
+
end
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
test 'builder preloads collection association' do
|
|
589
|
+
value = @user.tags
|
|
590
|
+
value.expects(:to_a).returns(value)
|
|
591
|
+
with_association_for @user, :tags
|
|
592
|
+
assert_select 'form select.select#user_tag_ids'
|
|
593
|
+
assert_select 'form select option[value=1]', 'Tag 1'
|
|
594
|
+
assert_select 'form select option[value=2]', 'Tag 2'
|
|
595
|
+
assert_select 'form select option[value=3]', 'Tag 3'
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
test 'builder does not preload collection association if preload false' do
|
|
599
|
+
value = @user.company
|
|
600
|
+
value.expects(:to_a).never
|
|
601
|
+
with_association_for @user, :company, :preload => false
|
|
602
|
+
assert_select 'form select.select#user_company_id'
|
|
603
|
+
assert_select 'form select option[value=1]', 'Company 1'
|
|
604
|
+
assert_select 'form select option[value=2]', 'Company 2'
|
|
605
|
+
assert_select 'form select option[value=3]', 'Company 3'
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
test 'builder does not preload non collection association' do
|
|
609
|
+
value = @user.company
|
|
610
|
+
value.expects(:to_a).never
|
|
611
|
+
with_association_for @user, :company, :preload => false
|
|
612
|
+
assert_select 'form select.select#user_company_id'
|
|
613
|
+
assert_select 'form select option[value=1]', 'Company 1'
|
|
614
|
+
assert_select 'form select option[value=2]', 'Company 2'
|
|
615
|
+
assert_select 'form select option[value=3]', 'Company 3'
|
|
616
|
+
end
|
|
617
|
+
|
|
412
618
|
# ASSOCIATIONS - BELONGS TO
|
|
413
619
|
test 'builder creates a select for belongs_to associations' do
|
|
414
620
|
with_association_for @user, :company
|
|
@@ -495,4 +701,95 @@ class FormBuilderTest < ActionView::TestCase
|
|
|
495
701
|
assert_select 'form input[type=checkbox][value=2][checked=checked]'
|
|
496
702
|
assert_no_select 'form input[type=checkbox][value=3][checked=checked]'
|
|
497
703
|
end
|
|
704
|
+
|
|
705
|
+
test 'builder with collection support giving collection and item wrapper tags' do
|
|
706
|
+
with_association_for @user, :tags, :as => :check_boxes,
|
|
707
|
+
:collection_wrapper_tag => :ul, :item_wrapper_tag => :li
|
|
708
|
+
|
|
709
|
+
assert_select 'form ul', :count => 1
|
|
710
|
+
assert_select 'form ul li', :count => 3
|
|
711
|
+
end
|
|
712
|
+
|
|
713
|
+
# CUSTOM FORM BUILDER
|
|
714
|
+
test 'custom builder should inherit mappings' do
|
|
715
|
+
with_custom_form_for @user, :email
|
|
716
|
+
assert_select 'form input[type=email]#user_email.custom'
|
|
717
|
+
end
|
|
718
|
+
|
|
719
|
+
test 'form with CustomMapTypeFormBuilder should use custom map type builder' do
|
|
720
|
+
with_concat_custom_mapping_form_for(:user) do |user|
|
|
721
|
+
assert user.instance_of?(CustomMapTypeFormBuilder)
|
|
722
|
+
end
|
|
723
|
+
end
|
|
724
|
+
|
|
725
|
+
test 'form with CustomMapTypeFormBuilder should use custom mapping' do
|
|
726
|
+
with_concat_custom_mapping_form_for(:user) do |user|
|
|
727
|
+
assert_equal SimpleForm::Inputs::StringInput, user.class.mappings[:custom_type]
|
|
728
|
+
end
|
|
729
|
+
end
|
|
730
|
+
|
|
731
|
+
test 'form without CustomMapTypeFormBuilder should not use custom mapping' do
|
|
732
|
+
with_concat_form_for(:user) do |user|
|
|
733
|
+
assert_nil user.class.mappings[:custom_type]
|
|
734
|
+
end
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
# DISCOVERY
|
|
738
|
+
# Setup new inputs and remove them after the test.
|
|
739
|
+
def discovery(value=false)
|
|
740
|
+
swap SimpleForm, :cache_discovery => value do
|
|
741
|
+
begin
|
|
742
|
+
load "discovery_inputs.rb"
|
|
743
|
+
yield
|
|
744
|
+
ensure
|
|
745
|
+
SimpleForm::FormBuilder.discovery_cache.clear
|
|
746
|
+
Object.send :remove_const, :StringInput
|
|
747
|
+
Object.send :remove_const, :NumericInput
|
|
748
|
+
Object.send :remove_const, :CustomizedInput
|
|
749
|
+
end
|
|
750
|
+
end
|
|
751
|
+
end
|
|
752
|
+
|
|
753
|
+
test 'builder should not discover new inputs if cached' do
|
|
754
|
+
with_form_for @user, :name
|
|
755
|
+
assert_select 'form input#user_name.string'
|
|
756
|
+
|
|
757
|
+
discovery(true) do
|
|
758
|
+
with_form_for @user, :name
|
|
759
|
+
assert_no_select 'form section input#user_name.string'
|
|
760
|
+
end
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
test 'builder should discover new inputs' do
|
|
764
|
+
discovery do
|
|
765
|
+
with_form_for @user, :name, :as => :customized
|
|
766
|
+
assert_select 'form section input#user_name.string'
|
|
767
|
+
end
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
test 'builder should not discover new inputs if discovery is off' do
|
|
771
|
+
with_form_for @user, :name
|
|
772
|
+
assert_select 'form input#user_name.string'
|
|
773
|
+
|
|
774
|
+
swap SimpleForm, :inputs_discovery => false do
|
|
775
|
+
discovery do
|
|
776
|
+
with_form_for @user, :name
|
|
777
|
+
assert_no_select 'form section input#user_name.string'
|
|
778
|
+
end
|
|
779
|
+
end
|
|
780
|
+
end
|
|
781
|
+
|
|
782
|
+
test 'builder should discover new inputs from mappings if not cached' do
|
|
783
|
+
discovery do
|
|
784
|
+
with_form_for @user, :name
|
|
785
|
+
assert_select 'form section input#user_name.string'
|
|
786
|
+
end
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
test 'builder should discover new inputs from internal fallbacks if not cached' do
|
|
790
|
+
discovery do
|
|
791
|
+
with_form_for @user, :age
|
|
792
|
+
assert_select 'form section input#user_age.numeric.integer'
|
|
793
|
+
end
|
|
794
|
+
end
|
|
498
795
|
end
|