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
|
@@ -1,29 +1,55 @@
|
|
|
1
1
|
require 'test_helper'
|
|
2
2
|
|
|
3
3
|
class BuilderTest < ActionView::TestCase
|
|
4
|
+
def with_custom_form_for(object, *args, &block)
|
|
5
|
+
with_concat_custom_form_for(object) do |f|
|
|
6
|
+
assert f.instance_of?(CustomFormBuilder)
|
|
7
|
+
yield f
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def with_collection_radio(object, attribute, collection, value_method, text_method, options={}, html_options={})
|
|
12
|
+
with_concat_form_for(object) do |f|
|
|
13
|
+
f.collection_radio attribute, collection, value_method, text_method, options, html_options
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options={}, html_options={})
|
|
18
|
+
with_concat_form_for(object) do |f|
|
|
19
|
+
f.collection_check_boxes attribute, collection, value_method, text_method, options, html_options
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
4
23
|
# COLLECTION RADIO
|
|
5
24
|
test 'collection radio accepts a collection and generate inputs from value method' do
|
|
6
|
-
|
|
7
|
-
concat f.collection_radio :active, [true, false], :to_s, :to_s
|
|
8
|
-
end)
|
|
25
|
+
with_collection_radio @user, :active, [true, false], :to_s, :to_s
|
|
9
26
|
|
|
10
27
|
assert_select 'form input[type=radio][value=true]#user_active_true'
|
|
11
28
|
assert_select 'form input[type=radio][value=false]#user_active_false'
|
|
12
29
|
end
|
|
13
30
|
|
|
14
31
|
test 'collection radio accepts a collection and generate inputs from label method' do
|
|
15
|
-
|
|
16
|
-
concat f.collection_radio :active, [true, false], :to_s, :to_s
|
|
17
|
-
end)
|
|
32
|
+
with_collection_radio @user, :active, [true, false], :to_s, :to_s
|
|
18
33
|
|
|
19
34
|
assert_select 'form label.collection_radio[for=user_active_true]', 'true'
|
|
20
35
|
assert_select 'form label.collection_radio[for=user_active_false]', 'false'
|
|
21
36
|
end
|
|
22
37
|
|
|
38
|
+
test 'collection radio handles camelized collection values for labels correctly' do
|
|
39
|
+
with_collection_radio @user, :active, ['Yes', 'No'], :to_s, :to_s
|
|
40
|
+
|
|
41
|
+
assert_select 'form label.collection_radio[for=user_active_yes]', 'Yes'
|
|
42
|
+
assert_select 'form label.collection_radio[for=user_active_no]', 'No'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
test 'colection radio should sanitize collection values for labels correctly' do
|
|
46
|
+
with_collection_radio @user, :name, ['$0.99', '$1.99'], :to_s, :to_s
|
|
47
|
+
assert_select 'label.collection_radio[for=user_name_099]', '$0.99'
|
|
48
|
+
assert_select 'label.collection_radio[for=user_name_199]', '$1.99'
|
|
49
|
+
end
|
|
50
|
+
|
|
23
51
|
test 'collection radio accepts checked item' do
|
|
24
|
-
|
|
25
|
-
concat f.collection_radio :active, [[1, true], [0, false]], :last, :first, :checked => true
|
|
26
|
-
end)
|
|
52
|
+
with_collection_radio @user, :active, [[1, true], [0, false]], :last, :first, :checked => true
|
|
27
53
|
|
|
28
54
|
assert_select 'form input[type=radio][value=true][checked=checked]'
|
|
29
55
|
assert_no_select 'form input[type=radio][value=false][checked=checked]'
|
|
@@ -31,9 +57,7 @@ class BuilderTest < ActionView::TestCase
|
|
|
31
57
|
|
|
32
58
|
test 'collection radio accepts multiple disabled items' do
|
|
33
59
|
collection = [[1, true], [0, false], [2, 'other']]
|
|
34
|
-
|
|
35
|
-
concat f.collection_radio :active, collection, :last, :first, :disabled => [true, false]
|
|
36
|
-
end)
|
|
60
|
+
with_collection_radio @user, :active, collection, :last, :first, :disabled => [true, false]
|
|
37
61
|
|
|
38
62
|
assert_select 'form input[type=radio][value=true][disabled=disabled]'
|
|
39
63
|
assert_select 'form input[type=radio][value=false][disabled=disabled]'
|
|
@@ -42,29 +66,75 @@ class BuilderTest < ActionView::TestCase
|
|
|
42
66
|
|
|
43
67
|
test 'collection radio accepts single disable item' do
|
|
44
68
|
collection = [[1, true], [0, false]]
|
|
45
|
-
|
|
46
|
-
concat f.collection_radio :active, collection, :last, :first, :disabled => true
|
|
47
|
-
end)
|
|
69
|
+
with_collection_radio @user, :active, collection, :last, :first, :disabled => true
|
|
48
70
|
|
|
49
71
|
assert_select 'form input[type=radio][value=true][disabled=disabled]'
|
|
50
72
|
assert_no_select 'form input[type=radio][value=false][disabled=disabled]'
|
|
51
73
|
end
|
|
52
74
|
|
|
53
75
|
test 'collection radio accepts html options as input' do
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
end)
|
|
76
|
+
collection = [[1, true], [0, false]]
|
|
77
|
+
with_collection_radio @user, :active, collection, :last, :first, {}, :class => 'radio'
|
|
57
78
|
|
|
58
79
|
assert_select 'form input[type=radio][value=true].radio#user_active_true'
|
|
59
80
|
assert_select 'form input[type=radio][value=false].radio#user_active_false'
|
|
60
81
|
end
|
|
61
82
|
|
|
83
|
+
test 'collection radio wraps the collection in the configured collection wrapper tag' do
|
|
84
|
+
swap SimpleForm, :collection_wrapper_tag => :ul do
|
|
85
|
+
with_collection_radio @user, :active, [true, false], :to_s, :to_s
|
|
86
|
+
|
|
87
|
+
assert_select 'form ul input[type=radio][value=true]#user_active_true'
|
|
88
|
+
assert_select 'form ul input[type=radio][value=false]#user_active_false'
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
test 'collection radio wraps the collection in the given collection wrapper tag' do
|
|
93
|
+
with_collection_radio @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
|
|
94
|
+
|
|
95
|
+
assert_select 'form ul input[type=radio][value=true]#user_active_true'
|
|
96
|
+
assert_select 'form ul input[type=radio][value=false]#user_active_false'
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
test 'collection radio does not wrap the collection by default' do
|
|
100
|
+
with_collection_radio @user, :active, [true, false], :to_s, :to_s
|
|
101
|
+
|
|
102
|
+
assert_no_select 'form ul'
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
test 'collection radio wraps each label/radio in the configured item wrapper tag' do
|
|
106
|
+
swap SimpleForm, :item_wrapper_tag => :li do
|
|
107
|
+
with_collection_radio @user, :active, [true, false], :to_s, :to_s
|
|
108
|
+
|
|
109
|
+
assert_select 'form li input[type=radio][value=true]#user_active_true'
|
|
110
|
+
assert_select 'form li input[type=radio][value=false]#user_active_false'
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
test 'collection radio wraps each label/radio in the given item wrapper tag' do
|
|
115
|
+
with_collection_radio @user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => :li
|
|
116
|
+
|
|
117
|
+
assert_select 'form li input[type=radio][value=true]#user_active_true'
|
|
118
|
+
assert_select 'form li input[type=radio][value=false]#user_active_false'
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
test 'collection radio wrap items in a span tag by default' do
|
|
122
|
+
with_collection_radio @user, :active, [true, false], :to_s, :to_s
|
|
123
|
+
|
|
124
|
+
assert_select 'form span input[type=radio][value=true]#user_active_true + label'
|
|
125
|
+
assert_select 'form span input[type=radio][value=false]#user_active_false + label'
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
test 'collection radio does not wrap input inside the label' do
|
|
129
|
+
with_collection_radio @user, :active, [true, false], :to_s, :to_s
|
|
130
|
+
|
|
131
|
+
assert_no_select 'form label input'
|
|
132
|
+
end
|
|
133
|
+
|
|
62
134
|
# COLLECTION CHECK BOX
|
|
63
135
|
test 'collection check box accepts a collection and generate a serie of checkboxes for value method' do
|
|
64
136
|
collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
|
|
65
|
-
|
|
66
|
-
concat f.collection_check_boxes :tag_ids, collection, :id, :name
|
|
67
|
-
end)
|
|
137
|
+
with_collection_check_boxes @user, :tag_ids, collection, :id, :name
|
|
68
138
|
|
|
69
139
|
assert_select "form input[type=hidden][name='user[tag_ids][]'][value=]"
|
|
70
140
|
assert_select 'form input#user_tag_ids_1[type=checkbox][value=1]'
|
|
@@ -73,19 +143,28 @@ class BuilderTest < ActionView::TestCase
|
|
|
73
143
|
|
|
74
144
|
test 'collection check box accepts a collection and generate a serie of checkboxes with labels for label method' do
|
|
75
145
|
collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
|
|
76
|
-
|
|
77
|
-
concat f.collection_check_boxes :tag_ids, collection, :id, :name
|
|
78
|
-
end)
|
|
146
|
+
with_collection_check_boxes @user, :tag_ids, collection, :id, :name
|
|
79
147
|
|
|
80
148
|
assert_select 'form label.collection_check_boxes[for=user_tag_ids_1]', 'Tag 1'
|
|
81
149
|
assert_select 'form label.collection_check_boxes[for=user_tag_ids_2]', 'Tag 2'
|
|
82
150
|
end
|
|
83
151
|
|
|
152
|
+
test 'collection check box handles camelized collection values for labels correctly' do
|
|
153
|
+
with_collection_check_boxes @user, :active, ['Yes', 'No'], :to_s, :to_s
|
|
154
|
+
|
|
155
|
+
assert_select 'form label.collection_check_boxes[for=user_active_yes]', 'Yes'
|
|
156
|
+
assert_select 'form label.collection_check_boxes[for=user_active_no]', 'No'
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
test 'colection check box should sanitize collection values for labels correctly' do
|
|
160
|
+
with_collection_check_boxes @user, :name, ['$0.99', '$1.99'], :to_s, :to_s
|
|
161
|
+
assert_select 'label.collection_check_boxes[for=user_name_099]', '$0.99'
|
|
162
|
+
assert_select 'label.collection_check_boxes[for=user_name_199]', '$1.99'
|
|
163
|
+
end
|
|
164
|
+
|
|
84
165
|
test 'collection check box accepts selected values as :checked option' do
|
|
85
166
|
collection = (1..3).map{|i| [i, "Tag #{i}"] }
|
|
86
|
-
|
|
87
|
-
concat f.collection_check_boxes :tag_ids, collection, :first, :last, :checked => [1, 3]
|
|
88
|
-
end)
|
|
167
|
+
with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :checked => [1, 3]
|
|
89
168
|
|
|
90
169
|
assert_select 'form input[type=checkbox][value=1][checked=checked]'
|
|
91
170
|
assert_select 'form input[type=checkbox][value=3][checked=checked]'
|
|
@@ -94,9 +173,7 @@ class BuilderTest < ActionView::TestCase
|
|
|
94
173
|
|
|
95
174
|
test 'collection check box accepts a single checked value' do
|
|
96
175
|
collection = (1..3).map{|i| [i, "Tag #{i}"] }
|
|
97
|
-
|
|
98
|
-
concat f.collection_check_boxes :tag_ids, collection, :first, :last, :checked => 3
|
|
99
|
-
end)
|
|
176
|
+
with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :checked => 3
|
|
100
177
|
|
|
101
178
|
assert_select 'form input[type=checkbox][value=3][checked=checked]'
|
|
102
179
|
assert_no_select 'form input[type=checkbox][value=1][checked=checked]'
|
|
@@ -105,9 +182,7 @@ class BuilderTest < ActionView::TestCase
|
|
|
105
182
|
|
|
106
183
|
test 'collection check box accepts multiple disabled items' do
|
|
107
184
|
collection = (1..3).map{|i| [i, "Tag #{i}"] }
|
|
108
|
-
|
|
109
|
-
concat f.collection_check_boxes :tag_ids, collection, :first, :last, :disabled => [1, 3]
|
|
110
|
-
end)
|
|
185
|
+
with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :disabled => [1, 3]
|
|
111
186
|
|
|
112
187
|
assert_select 'form input[type=checkbox][value=1][disabled=disabled]'
|
|
113
188
|
assert_select 'form input[type=checkbox][value=3][disabled=disabled]'
|
|
@@ -116,9 +191,7 @@ class BuilderTest < ActionView::TestCase
|
|
|
116
191
|
|
|
117
192
|
test 'collection check box accepts single disable item' do
|
|
118
193
|
collection = (1..3).map{|i| [i, "Tag #{i}"] }
|
|
119
|
-
|
|
120
|
-
concat f.collection_check_boxes :tag_ids, collection, :first, :last, :disabled => 1
|
|
121
|
-
end)
|
|
194
|
+
with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :disabled => 1
|
|
122
195
|
|
|
123
196
|
assert_select 'form input[type=checkbox][value=1][disabled=disabled]'
|
|
124
197
|
assert_no_select 'form input[type=checkbox][value=3][disabled=disabled]'
|
|
@@ -127,9 +200,7 @@ class BuilderTest < ActionView::TestCase
|
|
|
127
200
|
|
|
128
201
|
test 'collection check box accepts a proc to disabled items' do
|
|
129
202
|
collection = (1..3).map{|i| [i, "Tag #{i}"] }
|
|
130
|
-
|
|
131
|
-
concat f.collection_check_boxes :tag_ids, collection, :first, :last, :disabled => proc { |i| i.first == 1 }
|
|
132
|
-
end)
|
|
203
|
+
with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :disabled => proc { |i| i.first == 1 }
|
|
133
204
|
|
|
134
205
|
assert_select 'form input[type=checkbox][value=1][disabled=disabled]'
|
|
135
206
|
assert_no_select 'form input[type=checkbox][value=3][disabled=disabled]'
|
|
@@ -138,9 +209,7 @@ class BuilderTest < ActionView::TestCase
|
|
|
138
209
|
|
|
139
210
|
test 'collection check box accepts html options' do
|
|
140
211
|
collection = [[1, 'Tag 1'], [2, 'Tag 2']]
|
|
141
|
-
|
|
142
|
-
concat f.collection_check_boxes :tag_ids, collection, :first, :last, {}, :class => 'check'
|
|
143
|
-
end)
|
|
212
|
+
with_collection_check_boxes @user, :tag_ids, collection, :first, :last, {}, :class => 'check'
|
|
144
213
|
|
|
145
214
|
assert_select 'form input.check[type=checkbox][value=1]'
|
|
146
215
|
assert_select 'form input.check[type=checkbox][value=2]'
|
|
@@ -148,11 +217,11 @@ class BuilderTest < ActionView::TestCase
|
|
|
148
217
|
|
|
149
218
|
test 'collection check box with fields for' do
|
|
150
219
|
collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
end
|
|
155
|
-
end
|
|
220
|
+
with_concat_form_for(@user) do |f|
|
|
221
|
+
f.fields_for(:post) do |p|
|
|
222
|
+
p.collection_check_boxes :tag_ids, collection, :id, :name
|
|
223
|
+
end
|
|
224
|
+
end
|
|
156
225
|
|
|
157
226
|
assert_select 'form input#user_post_tag_ids_1[type=checkbox][value=1]'
|
|
158
227
|
assert_select 'form input#user_post_tag_ids_2[type=checkbox][value=2]'
|
|
@@ -161,12 +230,79 @@ class BuilderTest < ActionView::TestCase
|
|
|
161
230
|
assert_select 'form label.collection_check_boxes[for=user_post_tag_ids_2]', 'Tag 2'
|
|
162
231
|
end
|
|
163
232
|
|
|
233
|
+
test 'collection check box wraps the collection in the configured collection wrapper tag' do
|
|
234
|
+
swap SimpleForm, :collection_wrapper_tag => :ul do
|
|
235
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
|
|
236
|
+
|
|
237
|
+
assert_select 'form ul input[type=checkbox][value=true]#user_active_true'
|
|
238
|
+
assert_select 'form ul input[type=checkbox][value=false]#user_active_false'
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
test 'collection check box wraps the collection in the given collection wrapper tag' do
|
|
243
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
|
|
244
|
+
|
|
245
|
+
assert_select 'form ul input[type=checkbox][value=true]#user_active_true'
|
|
246
|
+
assert_select 'form ul input[type=checkbox][value=false]#user_active_false'
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
test 'collection check box does not wrap the collection by default' do
|
|
250
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
|
|
251
|
+
|
|
252
|
+
assert_no_select 'form ul'
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
test 'collection check box wraps each label/radio in the configured item wrapper tag' do
|
|
256
|
+
swap SimpleForm, :item_wrapper_tag => :li do
|
|
257
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
|
|
258
|
+
|
|
259
|
+
assert_select 'form li input[type=checkbox][value=true]#user_active_true'
|
|
260
|
+
assert_select 'form li input[type=checkbox][value=false]#user_active_false'
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
test 'collection check box wraps each label/radio in the given item wrapper tag' do
|
|
265
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => :li
|
|
266
|
+
|
|
267
|
+
assert_select 'form li input[type=checkbox][value=true]#user_active_true'
|
|
268
|
+
assert_select 'form li input[type=checkbox][value=false]#user_active_false'
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
test 'collection check box wrap items in a span tag by default' do
|
|
272
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
|
|
273
|
+
|
|
274
|
+
assert_select 'form span input[type=checkbox][value=true]#user_active_true + label'
|
|
275
|
+
assert_select 'form span input[type=checkbox][value=false]#user_active_false + label'
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
test 'collection check box does not wrap input inside the label' do
|
|
279
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
|
|
280
|
+
|
|
281
|
+
assert_no_select 'form label input'
|
|
282
|
+
end
|
|
283
|
+
|
|
164
284
|
# SIMPLE FIELDS
|
|
165
285
|
test 'simple fields for is available and yields an instance of FormBuilder' do
|
|
166
|
-
|
|
167
|
-
|
|
286
|
+
with_concat_form_for(@user) do |f|
|
|
287
|
+
f.simple_fields_for(:posts) do |posts_form|
|
|
168
288
|
assert posts_form.instance_of?(SimpleForm::FormBuilder)
|
|
169
|
-
end
|
|
170
|
-
end
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
test 'fields for yields an instance of CustomBuilder if main builder is a CustomBuilder' do
|
|
294
|
+
with_custom_form_for(:user) do |f|
|
|
295
|
+
f.simple_fields_for(:company) do |company|
|
|
296
|
+
assert company.instance_of?(CustomFormBuilder)
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
test 'fields for yields an instance of FormBuilder if it was set in options' do
|
|
302
|
+
with_custom_form_for(:user) do |f|
|
|
303
|
+
f.simple_fields_for(:company, :builder => SimpleForm::FormBuilder) do |company|
|
|
304
|
+
assert company.instance_of?(SimpleForm::FormBuilder)
|
|
305
|
+
end
|
|
306
|
+
end
|
|
171
307
|
end
|
|
172
308
|
end
|
|
@@ -9,28 +9,40 @@ class FormHelperTest < ActionView::TestCase
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
test 'simple form should add default class to form' do
|
|
12
|
-
concat(simple_form_for
|
|
12
|
+
concat(simple_form_for(:user) do |f| end)
|
|
13
13
|
assert_select 'form.simple_form'
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
test 'simple form should use default browser validations by default' do
|
|
17
|
+
concat(simple_form_for(:user) do |f| end)
|
|
18
|
+
assert_no_select 'form[novalidate]'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
test 'simple form should not use default browser validations if specified in the configuration options' do
|
|
22
|
+
swap SimpleForm, :browser_validations => false do
|
|
23
|
+
concat(simple_form_for(:user) do |f| end)
|
|
24
|
+
assert_select 'form[novalidate="novalidate"]'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
16
28
|
test 'simple form should add object name as css class to form when object is not present' do
|
|
17
|
-
concat(simple_form_for
|
|
29
|
+
concat(simple_form_for(:user) do |f| end)
|
|
18
30
|
assert_select 'form.simple_form.user'
|
|
19
31
|
end
|
|
20
32
|
|
|
21
33
|
test 'simple form should add object class name as css class to form' do
|
|
22
|
-
concat(simple_form_for
|
|
34
|
+
concat(simple_form_for(@user) do |f| end)
|
|
23
35
|
assert_select 'form.simple_form.user'
|
|
24
36
|
end
|
|
25
37
|
|
|
26
38
|
test 'pass options to simple form' do
|
|
27
|
-
concat(simple_form_for
|
|
39
|
+
concat(simple_form_for(:user, :url => '/account', :html => { :id => 'my_form' }) do |f| end)
|
|
28
40
|
assert_select 'form#my_form'
|
|
29
41
|
assert_select 'form[action=/account]'
|
|
30
42
|
end
|
|
31
43
|
|
|
32
44
|
test 'fields for yields an instance of FormBuilder' do
|
|
33
|
-
concat(simple_fields_for
|
|
45
|
+
concat(simple_fields_for(:user) do |f|
|
|
34
46
|
assert f.instance_of?(SimpleForm::FormBuilder)
|
|
35
47
|
end)
|
|
36
48
|
end
|
|
@@ -3,14 +3,10 @@ require 'test_helper'
|
|
|
3
3
|
class ErrorTest < ActionView::TestCase
|
|
4
4
|
|
|
5
5
|
def with_error_for(object, attribute_name, type, options={}, &block)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
f.options = options
|
|
11
|
-
|
|
12
|
-
concat(SimpleForm::Inputs::Base.new(f).error.to_s)
|
|
13
|
-
end)
|
|
6
|
+
with_concat_form_for(object) do |f|
|
|
7
|
+
options[:reflection] = Association.new(Company, :company, {}) if options.delete(:setup_association)
|
|
8
|
+
SimpleForm::Inputs::Base.new(f, attribute_name, nil, type, options).error.to_s
|
|
9
|
+
end
|
|
14
10
|
end
|
|
15
11
|
|
|
16
12
|
test 'error should not generate content for attribute without errors' do
|
|
@@ -23,14 +19,29 @@ class ErrorTest < ActionView::TestCase
|
|
|
23
19
|
assert_no_select 'span.error'
|
|
24
20
|
end
|
|
25
21
|
|
|
22
|
+
test "error should not generate messages when object doesn't respond to errors method" do
|
|
23
|
+
@user.instance_eval { undef errors }
|
|
24
|
+
with_error_for @user, :name, :string
|
|
25
|
+
assert_no_select 'span.error'
|
|
26
|
+
end
|
|
27
|
+
|
|
26
28
|
test 'error should generate messages for attribute with single error' do
|
|
27
29
|
with_error_for @user, :name, :string
|
|
28
30
|
assert_select 'span.error', "can't be blank"
|
|
29
31
|
end
|
|
30
32
|
|
|
31
|
-
test 'error should generate messages for attribute with
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
test 'error should generate messages for attribute with one error when using first' do
|
|
34
|
+
swap SimpleForm, :error_method => :first do
|
|
35
|
+
with_error_for @user, :age, :numeric
|
|
36
|
+
assert_select 'span.error', 'is not a number'
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
test 'error should generate messages for attribute with several errors when using to_sentence' do
|
|
41
|
+
swap SimpleForm, :error_method => :to_sentence do
|
|
42
|
+
with_error_for @user, :age, :numeric
|
|
43
|
+
assert_select 'span.error', 'is not a number and must be greater than 18'
|
|
44
|
+
end
|
|
34
45
|
end
|
|
35
46
|
|
|
36
47
|
test 'error should be able to pass html options' do
|
|
@@ -39,7 +50,7 @@ class ErrorTest < ActionView::TestCase
|
|
|
39
50
|
end
|
|
40
51
|
|
|
41
52
|
test 'error should find errors on attribute and association' do
|
|
42
|
-
with_error_for @user, :company_id, :select, :setup_association => true
|
|
53
|
+
with_error_for @user, :company_id, :select, :setup_association => true, :error_method => :to_sentence
|
|
43
54
|
assert_select 'span.error', 'must be valid and company must be present'
|
|
44
55
|
end
|
|
45
56
|
end
|
|
@@ -3,14 +3,10 @@ require 'test_helper'
|
|
|
3
3
|
class HintTest < ActionView::TestCase
|
|
4
4
|
|
|
5
5
|
def with_hint_for(object, attribute_name, type, options={}, &block)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
f.options = options
|
|
11
|
-
|
|
12
|
-
concat(SimpleForm::Inputs::Base.new(f).hint.to_s)
|
|
13
|
-
end)
|
|
6
|
+
with_concat_form_for(object) do |f|
|
|
7
|
+
options[:reflection] = Association.new(Company, :company, {}) if options.delete(:setup_association)
|
|
8
|
+
SimpleForm::Inputs::Base.new(f, attribute_name, nil, type, options).hint.to_s
|
|
9
|
+
end
|
|
14
10
|
end
|
|
15
11
|
|
|
16
12
|
test 'hint should not be generated by default' do
|
|
@@ -1,20 +1,16 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
1
2
|
require 'test_helper'
|
|
2
3
|
|
|
3
4
|
class LabelTest < ActionView::TestCase
|
|
4
|
-
|
|
5
5
|
setup do
|
|
6
6
|
SimpleForm::Inputs::Base.reset_i18n_cache :translate_required_html
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def with_label_for(object, attribute_name, type, options={})
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
f.options = options
|
|
15
|
-
|
|
16
|
-
concat(SimpleForm::Inputs::Base.new(f).label)
|
|
17
|
-
end)
|
|
10
|
+
with_concat_form_for(object) do |f|
|
|
11
|
+
options[:reflection] = Association.new(Company, :company, {}) if options.delete(:setup_association)
|
|
12
|
+
SimpleForm::Inputs::Base.new(f, attribute_name, nil, type, options).label
|
|
13
|
+
end
|
|
18
14
|
end
|
|
19
15
|
|
|
20
16
|
test 'label should generate a default humanized description' do
|
|
@@ -57,6 +53,15 @@ class LabelTest < ActionView::TestCase
|
|
|
57
53
|
end
|
|
58
54
|
end
|
|
59
55
|
|
|
56
|
+
test 'label should not explode while looking for i18n translation when action is not set' do
|
|
57
|
+
def @controller.action_name; nil; end
|
|
58
|
+
|
|
59
|
+
assert_nothing_raised do
|
|
60
|
+
with_label_for @user, :description, :text
|
|
61
|
+
end
|
|
62
|
+
assert_select 'label[for=user_description]'
|
|
63
|
+
end
|
|
64
|
+
|
|
60
65
|
test 'label should use i18n based on model and attribute to lookup translation' do
|
|
61
66
|
store_translations(:en, :simple_form => { :labels => { :user => {
|
|
62
67
|
:description => 'Descrição'
|
|
@@ -73,6 +78,15 @@ class LabelTest < ActionView::TestCase
|
|
|
73
78
|
end
|
|
74
79
|
end
|
|
75
80
|
|
|
81
|
+
test 'input should not use i18n label if translate is false' do
|
|
82
|
+
swap SimpleForm, :translate => false do
|
|
83
|
+
store_translations(:en, :simple_form => { :labels => { :age => 'Idade' } } ) do
|
|
84
|
+
with_label_for @user, :age, :integer
|
|
85
|
+
assert_select 'label[for=user_age]', /Age/
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
76
90
|
test 'label should use i18n with lookup for association name' do
|
|
77
91
|
store_translations(:en, :simple_form => { :labels => {
|
|
78
92
|
:user => { :company => 'My company!' }
|
|
@@ -82,6 +96,43 @@ class LabelTest < ActionView::TestCase
|
|
|
82
96
|
end
|
|
83
97
|
end
|
|
84
98
|
|
|
99
|
+
test 'label should do correct i18n lookup for nested models with nested translation' do
|
|
100
|
+
@user.company = Company.new(1, 'Empresa')
|
|
101
|
+
|
|
102
|
+
store_translations(:en, :simple_form => { :labels => {
|
|
103
|
+
:user => { :name => 'Usuario', :company => { :name => 'Nome da empresa' } }
|
|
104
|
+
} } ) do
|
|
105
|
+
with_concat_form_for @user do |f|
|
|
106
|
+
concat f.input :name
|
|
107
|
+
concat(f.simple_fields_for(:company) do |company_form|
|
|
108
|
+
concat(company_form.input :name)
|
|
109
|
+
end)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
assert_select 'label[for=user_name]', /Usuario/
|
|
113
|
+
assert_select 'label[for=user_company_attributes_name]', /Nome da empresa/
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
test 'label should do correct i18n lookup for nested models with no nested translation' do
|
|
118
|
+
@user.company = Company.new(1, 'Empresa')
|
|
119
|
+
|
|
120
|
+
store_translations(:en, :simple_form => { :labels => {
|
|
121
|
+
:user => { :name => 'Usuario' },
|
|
122
|
+
:company => { :name => 'Nome da empresa' }
|
|
123
|
+
} } ) do
|
|
124
|
+
with_concat_form_for @user do |f|
|
|
125
|
+
concat f.input :name
|
|
126
|
+
concat(f.simple_fields_for(:company) do |company_form|
|
|
127
|
+
concat(company_form.input :name)
|
|
128
|
+
end)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
assert_select 'label[for=user_name]', /Usuario/
|
|
132
|
+
assert_select 'label[for=user_company_attributes_name]', /Nome da empresa/
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
85
136
|
test 'label should have css class from type' do
|
|
86
137
|
with_label_for @user, :name, :string
|
|
87
138
|
assert_select 'label.string'
|
|
@@ -94,14 +145,14 @@ class LabelTest < ActionView::TestCase
|
|
|
94
145
|
with_label_for @user, :created_at, :datetime
|
|
95
146
|
assert_select 'label.datetime'
|
|
96
147
|
end
|
|
97
|
-
|
|
148
|
+
|
|
98
149
|
test 'label should obtain required from ActiveModel::Validations when it is included' do
|
|
99
150
|
with_label_for @validating_user, :name, :string
|
|
100
151
|
assert_select 'label.required'
|
|
101
152
|
with_label_for @validating_user, :status, :string
|
|
102
153
|
assert_select 'label.optional'
|
|
103
154
|
end
|
|
104
|
-
|
|
155
|
+
|
|
105
156
|
test 'label should allow overriding required when ActiveModel::Validations is included' do
|
|
106
157
|
with_label_for @validating_user, :name, :string, :required => false
|
|
107
158
|
assert_select 'label.optional'
|
|
@@ -156,6 +207,16 @@ class LabelTest < ActionView::TestCase
|
|
|
156
207
|
assert_select 'label[for=my_new_id]'
|
|
157
208
|
end
|
|
158
209
|
|
|
210
|
+
test 'label should allow overwriting of for attribute' do
|
|
211
|
+
with_label_for @user, :name, :string, :label_html => { :for => 'my_new_id' }
|
|
212
|
+
assert_select 'label[for=my_new_id]'
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
test 'label should allow overwriting of for attribute with input_html not containing id' do
|
|
216
|
+
with_label_for @user, :name, :string, :label_html => { :for => 'my_new_id' }, :input_html => {:class => 'foo'}
|
|
217
|
+
assert_select 'label[for=my_new_id]'
|
|
218
|
+
end
|
|
219
|
+
|
|
159
220
|
test 'label should use default input id when it was not overridden' do
|
|
160
221
|
with_label_for @user, :name, :string, :input_html => { :class => 'my_new_id' }
|
|
161
222
|
assert_select 'label[for=user_name]'
|
|
@@ -181,4 +242,11 @@ class LabelTest < ActionView::TestCase
|
|
|
181
242
|
with_label_for :project, :description, :string, :required => false
|
|
182
243
|
assert_no_select 'label.required[for=project_description]'
|
|
183
244
|
end
|
|
245
|
+
|
|
246
|
+
test 'label should add chosen label class' do
|
|
247
|
+
swap SimpleForm, :label_class => :my_custom_class do
|
|
248
|
+
with_label_for @user, :name, :string
|
|
249
|
+
assert_select 'label.my_custom_class'
|
|
250
|
+
end
|
|
251
|
+
end
|
|
184
252
|
end
|