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.
Files changed (58) hide show
  1. data/.gitignore +2 -0
  2. data/.gitmodules +3 -0
  3. data/.travis.yml +6 -0
  4. data/CHANGELOG.rdoc +109 -0
  5. data/Gemfile +8 -0
  6. data/Gemfile.lock +82 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.rdoc +180 -53
  9. data/Rakefile +27 -0
  10. data/lib/generators/simple_form/USAGE +1 -1
  11. data/lib/generators/simple_form/install_generator.rb +5 -6
  12. data/lib/generators/simple_form/templates/_form.html.erb +2 -12
  13. data/lib/generators/simple_form/templates/_form.html.haml +10 -0
  14. data/lib/generators/simple_form/templates/_form.html.slim +10 -0
  15. data/lib/generators/simple_form/templates/en.yml +14 -0
  16. data/lib/generators/simple_form/templates/simple_form.rb +66 -12
  17. data/lib/simple_form/action_view_extensions/builder.rb +99 -40
  18. data/lib/simple_form/action_view_extensions/form_helper.rb +29 -6
  19. data/lib/simple_form/components/errors.rb +16 -6
  20. data/lib/simple_form/components/hints.rb +2 -2
  21. data/lib/simple_form/components/label_input.rb +13 -0
  22. data/lib/simple_form/components/labels.rb +5 -7
  23. data/lib/simple_form/components/placeholders.rb +22 -0
  24. data/lib/simple_form/components/wrapper.rb +19 -2
  25. data/lib/simple_form/components.rb +6 -4
  26. data/lib/simple_form/error_notification.rb +42 -0
  27. data/lib/simple_form/form_builder.rb +187 -72
  28. data/lib/simple_form/has_errors.rb +14 -0
  29. data/lib/simple_form/inputs/base.rb +106 -24
  30. data/lib/simple_form/inputs/block_input.rb +3 -2
  31. data/lib/simple_form/inputs/boolean_input.rb +22 -0
  32. data/lib/simple_form/inputs/collection_input.rb +46 -17
  33. data/lib/simple_form/inputs/date_time_input.rb +11 -5
  34. data/lib/simple_form/inputs/hidden_input.rb +11 -2
  35. data/lib/simple_form/inputs/mapping_input.rb +12 -6
  36. data/lib/simple_form/inputs/numeric_input.rb +55 -6
  37. data/lib/simple_form/inputs/priority_input.rb +5 -1
  38. data/lib/simple_form/inputs/string_input.rb +25 -11
  39. data/lib/simple_form/inputs.rb +1 -0
  40. data/lib/simple_form/map_type.rb +9 -6
  41. data/lib/simple_form/version.rb +1 -1
  42. data/lib/simple_form.rb +92 -8
  43. data/simple_form.gemspec +22 -0
  44. data/test/action_view_extensions/builder_test.rb +187 -51
  45. data/test/action_view_extensions/form_helper_test.rb +17 -5
  46. data/test/components/error_test.rb +23 -12
  47. data/test/components/hint_test.rb +4 -8
  48. data/test/components/label_test.rb +79 -11
  49. data/test/components/wrapper_test.rb +63 -0
  50. data/test/discovery_inputs.rb +21 -0
  51. data/test/error_notification_test.rb +62 -0
  52. data/test/form_builder_test.rb +332 -35
  53. data/test/inputs_test.rb +516 -53
  54. data/test/support/misc_helpers.rb +32 -4
  55. data/test/support/mock_controller.rb +4 -4
  56. data/test/support/models.rb +75 -11
  57. data/test/test_helper.rb +28 -12
  58. 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
- concat(form_for @user do |f|
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
- concat(form_for @user do |f|
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
- concat(form_for @user do |f|
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
- concat(form_for @user do |f|
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
- concat(form_for @user do |f|
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
- concat(form_for @user do |f|
55
- concat f.collection_radio :active, [[1, true], [0, false]], :last, :first, {}, :class => 'radio'
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
- concat(form_for @user do |f|
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
- concat(form_for @user do |f|
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
- concat(form_for @user do |f|
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
- concat(form_for @user do |f|
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
- concat(form_for @user do |f|
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
- concat(form_for @user do |f|
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
- concat(form_for @user do |f|
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
- concat(form_for @user do |f|
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
- concat(form_for @user do |f|
152
- concat(f.fields_for :post do |p|
153
- concat p.collection_check_boxes :tag_ids, collection, :id, :name
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
- concat(form_for @user do |f|
167
- concat(f.simple_fields_for :posts do |posts_form|
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 :user do |f| end)
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 :user do |f| end)
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 @user do |f| end)
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 :user, :url => '/account', :html => { :id => 'my_form' } do |f| end)
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 :user do |f|
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
- concat(simple_form_for object do |f|
7
- f.attribute_name = attribute_name
8
- f.reflection = Association.new(Company, :company, {}) if options.delete(:setup_association)
9
- f.input_type = type
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 several errors' do
32
- with_error_for @user, :age, :numeric
33
- assert_select 'span.error', 'is not a number and must be greater than 18'
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
- concat(simple_form_for object do |f|
7
- f.attribute_name = attribute_name
8
- f.reflection = Association.new(Company, :company, {}) if options.delete(:setup_association)
9
- f.input_type = type
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
- concat(simple_form_for object do |f|
11
- f.attribute_name = attribute_name
12
- f.reflection = Association.new(Company, :company, {}) if options.delete(:setup_association)
13
- f.input_type = type
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