simple_form 1.5.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. data/CHANGELOG.md +234 -0
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +816 -0
  4. data/lib/generators/simple_form/install_generator.rb +15 -1
  5. data/lib/generators/simple_form/templates/README +12 -0
  6. data/lib/generators/simple_form/templates/_form.html.erb +2 -2
  7. data/lib/generators/simple_form/templates/_form.html.haml +2 -2
  8. data/lib/generators/simple_form/templates/_form.html.slim +4 -4
  9. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb.tt +176 -0
  10. data/lib/simple_form/action_view_extensions/builder.rb +206 -59
  11. data/lib/simple_form/action_view_extensions/form_helper.rb +30 -23
  12. data/lib/simple_form/components/errors.rb +6 -24
  13. data/lib/simple_form/components/hints.rb +7 -21
  14. data/lib/simple_form/components/html5.rb +26 -0
  15. data/lib/simple_form/components/labels.rb +22 -14
  16. data/lib/simple_form/components/maxlength.rb +41 -0
  17. data/lib/simple_form/components/min_max.rb +49 -0
  18. data/lib/simple_form/components/pattern.rb +34 -0
  19. data/lib/simple_form/components/placeholders.rb +5 -17
  20. data/lib/simple_form/components/readonly.rb +22 -0
  21. data/lib/simple_form/components.rb +11 -1
  22. data/lib/simple_form/core_ext/hash.rb +16 -0
  23. data/lib/simple_form/error_notification.rb +9 -3
  24. data/lib/simple_form/form_builder.rb +105 -28
  25. data/lib/simple_form/helpers/autofocus.rb +11 -0
  26. data/lib/simple_form/helpers/disabled.rb +15 -0
  27. data/lib/simple_form/helpers/readonly.rb +15 -0
  28. data/lib/simple_form/helpers/required.rb +10 -11
  29. data/lib/simple_form/helpers/validators.rb +4 -4
  30. data/lib/simple_form/helpers.rb +7 -4
  31. data/lib/simple_form/inputs/base.rb +53 -81
  32. data/lib/simple_form/inputs/boolean_input.rb +46 -4
  33. data/lib/simple_form/inputs/collection_check_boxes_input.rb +21 -0
  34. data/lib/simple_form/inputs/collection_input.rb +27 -13
  35. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +67 -0
  36. data/lib/simple_form/inputs/collection_select_input.rb +14 -0
  37. data/lib/simple_form/inputs/date_time_input.rb +10 -6
  38. data/lib/simple_form/inputs/grouped_collection_select_input.rb +41 -0
  39. data/lib/simple_form/inputs/hidden_input.rb +3 -6
  40. data/lib/simple_form/inputs/numeric_input.rb +3 -51
  41. data/lib/simple_form/inputs/password_input.rb +1 -2
  42. data/lib/simple_form/inputs/priority_input.rb +2 -2
  43. data/lib/simple_form/inputs/range_input.rb +1 -3
  44. data/lib/simple_form/inputs/string_input.rb +6 -8
  45. data/lib/simple_form/inputs/text_input.rb +1 -2
  46. data/lib/simple_form/inputs.rb +17 -13
  47. data/lib/simple_form/version.rb +1 -1
  48. data/lib/simple_form/wrappers/builder.rb +103 -0
  49. data/lib/simple_form/wrappers/many.rb +69 -0
  50. data/lib/simple_form/wrappers/root.rb +34 -0
  51. data/lib/simple_form/wrappers/single.rb +18 -0
  52. data/lib/simple_form/wrappers.rb +8 -0
  53. data/lib/simple_form.rb +118 -48
  54. data/test/action_view_extensions/builder_test.rb +285 -102
  55. data/test/action_view_extensions/form_helper_test.rb +32 -10
  56. data/test/components/label_test.rb +44 -5
  57. data/test/form_builder/association_test.rb +177 -0
  58. data/test/form_builder/button_test.rb +47 -0
  59. data/test/{error_notification_test.rb → form_builder/error_notification_test.rb} +18 -1
  60. data/test/form_builder/error_test.rb +121 -0
  61. data/test/form_builder/general_test.rb +356 -0
  62. data/test/form_builder/hint_test.rb +123 -0
  63. data/test/form_builder/input_field_test.rb +63 -0
  64. data/test/form_builder/label_test.rb +65 -0
  65. data/test/form_builder/wrapper_test.rb +149 -0
  66. data/test/generators/simple_form_generator_test.rb +32 -0
  67. data/test/inputs/boolean_input_test.rb +101 -0
  68. data/test/inputs/collection_check_boxes_input_test.rb +224 -0
  69. data/test/inputs/collection_radio_buttons_input_test.rb +326 -0
  70. data/test/inputs/collection_select_input_test.rb +241 -0
  71. data/test/inputs/datetime_input_test.rb +99 -0
  72. data/test/inputs/disabled_test.rb +38 -0
  73. data/test/inputs/discovery_test.rb +61 -0
  74. data/test/inputs/file_input_test.rb +16 -0
  75. data/test/inputs/general_test.rb +69 -0
  76. data/test/inputs/grouped_collection_select_input_test.rb +118 -0
  77. data/test/inputs/hidden_input_test.rb +30 -0
  78. data/test/inputs/numeric_input_test.rb +167 -0
  79. data/test/inputs/priority_input_test.rb +43 -0
  80. data/test/inputs/readonly_test.rb +61 -0
  81. data/test/inputs/required_test.rb +113 -0
  82. data/test/inputs/string_input_test.rb +140 -0
  83. data/test/inputs/text_input_test.rb +24 -0
  84. data/test/support/misc_helpers.rb +53 -12
  85. data/test/support/mock_controller.rb +2 -2
  86. data/test/support/models.rb +20 -5
  87. data/test/test_helper.rb +11 -12
  88. metadata +124 -96
  89. data/.gitignore +0 -3
  90. data/.gitmodules +0 -3
  91. data/.travis.yml +0 -15
  92. data/CHANGELOG.rdoc +0 -159
  93. data/Gemfile +0 -9
  94. data/README.rdoc +0 -466
  95. data/Rakefile +0 -27
  96. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +0 -93
  97. data/lib/simple_form/components/wrapper.rb +0 -38
  98. data/lib/simple_form/helpers/has_errors.rb +0 -15
  99. data/lib/simple_form/helpers/maxlength.rb +0 -24
  100. data/lib/simple_form/helpers/pattern.rb +0 -28
  101. data/simple_form.gemspec +0 -25
  102. data/test/components/error_test.rb +0 -56
  103. data/test/components/hint_test.rb +0 -74
  104. data/test/components/wrapper_test.rb +0 -63
  105. data/test/custom_components.rb +0 -7
  106. data/test/form_builder_test.rb +0 -930
  107. data/test/inputs_test.rb +0 -995
  108. /data/test/{discovery_inputs.rb → support/discovery_inputs.rb} +0 -0
@@ -1,930 +0,0 @@
1
- # encoding: UTF-8
2
- require 'test_helper'
3
-
4
- class FormBuilderTest < ActionView::TestCase
5
-
6
- def with_form_for(object, *args, &block)
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
16
- end
17
-
18
- def with_button_for(object, *args)
19
- with_concat_form_for(object) do |f|
20
- f.button(*args)
21
- end
22
- end
23
-
24
- def with_error_for(object, *args)
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
34
- end
35
-
36
- def with_hint_for(object, *args)
37
- with_concat_form_for(object) do |f|
38
- f.hint(*args)
39
- end
40
- end
41
-
42
- def with_label_for(object, *args, &block)
43
- with_concat_form_for(object) do |f|
44
- f.label(*args, &block)
45
- end
46
- end
47
-
48
- def with_association_for(object, *args)
49
- with_concat_form_for(object) do |f|
50
- f.association(*args)
51
- end
52
- end
53
-
54
- # All
55
- test 'nested simple fields should yield an instance of FormBuilder' do
56
- simple_form_for :user do |f|
57
- f.simple_fields_for :posts do |posts_form|
58
- assert posts_form.instance_of?(SimpleForm::FormBuilder)
59
- end
60
- end
61
- end
62
-
63
- test 'builder input is html safe' do
64
- simple_form_for @user do |f|
65
- assert f.input(:name).html_safe?
66
- end
67
- end
68
-
69
- test 'builder input should allow a block to configure input' do
70
- with_form_for @user, :name do
71
- text_field_tag :foo, :bar, :id => :cool
72
- end
73
- assert_no_select 'input.string'
74
- assert_select 'input#cool'
75
- end
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 matches' 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
-
109
- # INPUT TYPES
110
- test 'builder should generate text fields for string columns' do
111
- with_form_for @user, :name
112
- assert_select 'form input#user_name.string'
113
- end
114
-
115
- test 'builder should generate text areas for text columns' do
116
- with_form_for @user, :description
117
- assert_select 'form textarea#user_description.text'
118
- end
119
-
120
- test 'builder should generate a checkbox for boolean columns' do
121
- with_form_for @user, :active
122
- assert_select 'form input[type=checkbox]#user_active.boolean'
123
- end
124
-
125
- test 'builder should use integer text field for integer columns' do
126
- with_form_for @user, :age
127
- assert_select 'form input#user_age.numeric.integer'
128
- end
129
-
130
- test 'builder should generate decimal text field for decimal columns' do
131
- with_form_for @user, :credit_limit
132
- assert_select 'form input#user_credit_limit.numeric.decimal'
133
- end
134
-
135
- test 'builder should generate password fields for columns that matches password' do
136
- with_form_for @user, :password
137
- assert_select 'form input#user_password.password'
138
- end
139
-
140
- test 'builder should generate country fields for columns that matches country' do
141
- with_form_for @user, :residence_country
142
- assert_select 'form select#user_residence_country.country'
143
- end
144
-
145
- test 'builder should generate time_zone fields for columns that matches time_zone' do
146
- with_form_for @user, :time_zone
147
- assert_select 'form select#user_time_zone.time_zone'
148
- end
149
-
150
- test 'builder should generate email fields for columns that matches email' do
151
- with_form_for @user, :email
152
- assert_select 'form input#user_email.string.email'
153
- end
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
-
160
- test 'builder should generate url fields for columns that matches url' do
161
- with_form_for @user, :url
162
- assert_select 'form input#user_url.string.url'
163
- end
164
-
165
- test 'builder should generate date select for date columns' do
166
- with_form_for @user, :born_at
167
- assert_select 'form select#user_born_at_1i.date'
168
- end
169
-
170
- test 'builder should generate time select for time columns' do
171
- with_form_for @user, :delivery_time
172
- assert_select 'form select#user_delivery_time_4i.time'
173
- end
174
-
175
- test 'builder should generate datetime select for datetime columns' do
176
- with_form_for @user, :created_at
177
- assert_select 'form select#user_created_at_1i.datetime'
178
- end
179
-
180
- test 'builder should generate datetime select for timestamp columns' do
181
- with_form_for @user, :updated_at
182
- assert_select 'form select#user_updated_at_1i.datetime'
183
- end
184
-
185
- test 'builder should generate file for file columns' do
186
- @user.avatar = mock("file")
187
- @user.avatar.expects(:respond_to?).with(:mounted_as).returns(false)
188
- @user.avatar.expects(:respond_to?).with(:file?).returns(false)
189
- @user.avatar.expects(:respond_to?).with(:public_filename).returns(true)
190
-
191
- with_form_for @user, :avatar
192
- assert_select 'form input#user_avatar.file'
193
- end
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
-
203
- test 'build should generate select if a collection is given' do
204
- with_form_for @user, :age, :collection => 1..60
205
- assert_select 'form select#user_age.select'
206
- end
207
-
208
- test 'builder should allow overriding default input type for text' do
209
- with_form_for @user, :name, :as => :text
210
- assert_no_select 'form input#user_name'
211
- assert_select 'form textarea#user_name.text'
212
-
213
- with_form_for @user, :active, :as => :radio
214
- assert_no_select 'form input[type=checkbox]'
215
- assert_select 'form input.radio[type=radio]', :count => 2
216
-
217
- with_form_for @user, :born_at, :as => :string
218
- assert_no_select 'form select'
219
- assert_select 'form input#user_born_at.string'
220
- end
221
-
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
-
230
- test 'builder should allow passing options to input' do
231
- with_form_for @user, :name, :input_html => { :class => 'my_input', :id => 'my_input' }
232
- assert_select 'form input#my_input.my_input.string'
233
- end
234
-
235
- test 'builder should generate a input with label' do
236
- with_form_for @user, :name
237
- assert_select 'form label.string[for=user_name]', /Name/
238
- end
239
-
240
- test 'builder should be able to disable the label for a input' do
241
- with_form_for @user, :name, :label => false
242
- assert_no_select 'form label'
243
- end
244
-
245
- test 'builder should use custom label' do
246
- with_form_for @user, :name, :label => 'Yay!'
247
- assert_select 'form label', /Yay!/
248
- end
249
-
250
- test 'builder should pass options to label' do
251
- with_form_for @user, :name, :label_html => { :id => "cool" }
252
- assert_select 'form label#cool', /Name/
253
- end
254
-
255
- test 'builder should not generate hints for a input' do
256
- with_form_for @user, :name
257
- assert_no_select 'span.hint'
258
- end
259
-
260
- test 'builder should be able to add a hint for a input' do
261
- with_form_for @user, :name, :hint => 'test'
262
- assert_select 'span.hint', 'test'
263
- end
264
-
265
- test 'builder should be able to disable a hint even if it exists in i18n' do
266
- store_translations(:en, :simple_form => { :hints => { :name => 'Hint test' } }) do
267
- with_form_for @user, :name, :hint => false
268
- assert_no_select 'span.hint'
269
- end
270
- end
271
-
272
- test 'builder should pass options to hint' do
273
- with_form_for @user, :name, :hint => 'test', :hint_html => { :id => "cool" }
274
- assert_select 'span.hint#cool', 'test'
275
- end
276
-
277
- test 'builder should generate errors for attribute without errors' do
278
- with_form_for @user, :credit_limit
279
- assert_no_select 'span.errors'
280
- end
281
-
282
- test 'builder should generate errors for attribute with errors' do
283
- with_form_for @user, :name
284
- assert_select 'span.error', "can't be blank"
285
- end
286
-
287
- test 'builder should be able to disable showing errors for a input' do
288
- with_form_for @user, :name, :error => false
289
- assert_no_select 'span.error'
290
- end
291
-
292
- test 'builder should pass options to errors' do
293
- with_form_for @user, :name, :error_html => { :id => "cool" }
294
- assert_select 'span.error#cool', "can't be blank"
295
- end
296
-
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
307
- test 'builder input should obtain required from ActiveModel::Validations when it is included' do
308
- with_form_for @validating_user, :name
309
- assert_select 'input.required[required]#validating_user_name'
310
- with_form_for @validating_user, :status
311
- assert_select 'input.optional#validating_user_status'
312
- end
313
-
314
- test 'builder input should allow overriding required when ActiveModel::Validations is included' do
315
- with_form_for @validating_user, :name, :required => false
316
- assert_select 'input.optional#validating_user_name'
317
- with_form_for @validating_user, :status, :required => true
318
- assert_select 'input.required[required]#validating_user_status'
319
- end
320
-
321
- test 'builder input should be required by default when ActiveModel::Validations is not included' do
322
- with_form_for @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
332
- end
333
-
334
- test 'builder input should allow disabling required when ActiveModel::Validations is not included' do
335
- with_form_for @user, :name, :required => false
336
- assert_no_select 'input.required'
337
- assert_no_select 'input[required]'
338
- assert_select 'input.optional#user_name'
339
- end
340
-
341
- # VALIDATORS :if :unless
342
-
343
- test 'builder input should not be required when ActiveModel::Validations is included and if option is present' do
344
- with_form_for @validating_user, :age
345
- assert_no_select 'input.required'
346
- assert_no_select 'input[required]'
347
- assert_select 'input.optional#validating_user_age'
348
- end
349
-
350
- test 'builder input should not be required when ActiveModel::Validations is included and unless option is present' do
351
- with_form_for @validating_user, :amount
352
- assert_no_select 'input.required'
353
- assert_no_select 'input[required]'
354
- assert_select 'input.optional#validating_user_amount'
355
- end
356
-
357
- # VALIDATORS :on
358
-
359
- test 'builder input should be required when validation is on create and is not persisted' do
360
- @validating_user.new_record!
361
- with_form_for @validating_user, :action
362
- assert_select 'input.required'
363
- assert_select 'input[required]'
364
- assert_select 'input.required[required]#validating_user_action'
365
- end
366
-
367
- test 'builder input should not be required when validation is on create and is persisted' do
368
- with_form_for @validating_user, :action
369
- assert_no_select 'input.required'
370
- assert_no_select 'input[required]'
371
- assert_select 'input.optional#validating_user_action'
372
- end
373
-
374
- test 'builder input should be required when validation is on save' do
375
- with_form_for @validating_user, :credit_limit
376
- assert_select 'input.required'
377
- assert_select 'input[required]'
378
- assert_select 'input.required[required]#validating_user_credit_limit'
379
-
380
- @validating_user.new_record!
381
- with_form_for @validating_user, :credit_limit
382
- assert_select 'input.required'
383
- assert_select 'input[required]'
384
- assert_select 'input.required[required]#validating_user_credit_limit'
385
- end
386
-
387
- test 'builder input should be required when validation is on update and is persisted' do
388
- with_form_for @validating_user, :phone_number
389
- assert_select 'input.required'
390
- assert_select 'input[required]'
391
- assert_select 'input.required[required]#validating_user_phone_number'
392
- end
393
-
394
- test 'builder input should not be required when validation is on update and is not persisted' do
395
- @validating_user.new_record!
396
- with_form_for @validating_user, :phone_number
397
- assert_no_select 'input.required'
398
- assert_no_select 'input[required]'
399
- assert_select 'input.optional#validating_user_phone_number'
400
- end
401
-
402
- # WRAPPERS
403
-
404
- test 'builder support wrapping around an specific tag' do
405
- swap SimpleForm, :wrapper_tag => :p do
406
- with_form_for @user, :name
407
- assert_select 'form p label[for=user_name]'
408
- assert_select 'form p input#user_name.string'
409
- end
410
- end
411
-
412
- test 'builder support no wrapping when wrapper is false' do
413
- with_form_for @user, :name, :wrapper => false
414
- assert_select 'form > label[for=user_name]'
415
- assert_select 'form > input#user_name.string'
416
- end
417
-
418
- test 'builder wrapping tag adds default css classes' do
419
- swap SimpleForm, :wrapper_tag => :p do
420
- with_form_for @user, :name
421
- assert_select 'form p.input.required.string'
422
-
423
- with_form_for @user, :age, :required => false
424
- assert_select 'form p.input.optional.integer'
425
- end
426
- end
427
-
428
- test 'builder wrapping tag allow custom options to be given' do
429
- swap SimpleForm, :wrapper_tag => :p do
430
- with_form_for @user, :name, :wrapper_html => { :id => "super_cool", :class => 'yay' }
431
- assert_select 'form p#super_cool.required.string.yay'
432
- end
433
- end
434
-
435
- test 'builder allows wrapper tag to be given on demand' do
436
- with_concat_form_for(@user) do |f|
437
- f.input :name, :wrapper_tag => :b
438
- end
439
- assert_select 'form b.required.string'
440
- end
441
-
442
- test 'builder allows wrapper class to be given on demand' do
443
- with_concat_form_for(@user) do |f|
444
- f.input :name, :wrapper_class => :wrapper
445
- end
446
- assert_select 'form div.wrapper.required.string'
447
- end
448
-
449
- test 'builder wrapping tag adds errors class for attribute with errors' do
450
- with_form_for @user, :name
451
- assert_select 'form div.input.required.string.field_with_errors'
452
- end
453
-
454
- # ONLY THE INPUT TAG
455
- test "builder input_field should only render the input tag, nothing else" do
456
- with_concat_form_for(@user) do |f|
457
- f.input_field :name
458
- end
459
- assert_select 'form > input.required.string'
460
- assert_no_select 'div.string'
461
- assert_no_select 'label'
462
- assert_no_select '.hint'
463
- end
464
-
465
- test 'builder input_field should allow overriding default input type' do
466
- with_concat_form_for(@user) do |f|
467
- f.input_field :name, :as => :text
468
- end
469
-
470
- assert_no_select 'input#user_name'
471
- assert_select 'textarea#user_name.text'
472
- end
473
-
474
- test 'builder input_field should allow passing options to input tag' do
475
- with_concat_form_for(@user) do |f|
476
- f.input_field :name, :id => 'name_input', :class => 'name'
477
- end
478
-
479
- assert_select 'input.string.name#name_input'
480
- end
481
-
482
- test 'builder input_field should generate an input tag with a clean HTML' do
483
- with_concat_form_for(@user) do |f|
484
- f.input_field :name, :as => :integer, :class => 'name'
485
- end
486
-
487
- assert_no_select 'input.integer[input_html]'
488
- assert_no_select 'input.integer[as]'
489
- end
490
-
491
- test 'builder collection input_field should generate input tag with a clean HTML' do
492
- with_concat_form_for(@user) do |f|
493
- f.input_field :status, :collection => ['Open', 'Closed'], :class => 'status', :label_method => :to_s, :value_method => :to_s
494
- end
495
-
496
- assert_no_select 'select.status[input_html]'
497
- assert_no_select 'select.status[collection]'
498
- assert_no_select 'select.status[label_method]'
499
- assert_no_select 'select.status[value_method]'
500
- end
501
-
502
- # WITHOUT OBJECT
503
- test 'builder should generate properly when object is not present' do
504
- with_form_for :project, :name
505
- assert_select 'form input.string#project_name'
506
- end
507
-
508
- test 'builder should generate password fields based on attribute name when object is not present' do
509
- with_form_for :project, :password_confirmation
510
- assert_select 'form input[type=password].password#project_password_confirmation'
511
- end
512
-
513
- test 'builder should generate text fields by default for all attributes when object is not present' do
514
- with_form_for :project, :created_at
515
- assert_select 'form input.string#project_created_at'
516
- with_form_for :project, :budget
517
- assert_select 'form input.string#project_budget'
518
- end
519
-
520
- test 'builder should allow overriding input type when object is not present' do
521
- with_form_for :project, :created_at, :as => :datetime
522
- assert_select 'form select.datetime#project_created_at_1i'
523
- with_form_for :project, :budget, :as => :decimal
524
- assert_select 'form input.decimal#project_budget'
525
- end
526
-
527
- # ERRORS
528
- test 'builder should generate an error tag for the attribute' do
529
- with_error_for @user, :name
530
- assert_select 'span.error', "can't be blank"
531
- end
532
-
533
- test 'builder should generate an error tag with a clean HTML' do
534
- with_error_for @user, :name
535
- assert_no_select 'span.error[error_html]'
536
- end
537
-
538
- test 'builder should generate an error tag with a clean HTML when errors options are present' do
539
- with_error_for @user, :name, :error_tag => :p, :error_prefix => 'Name', :error_method => :first
540
- assert_no_select 'p.error[error_html]'
541
- assert_no_select 'p.error[error_tag]'
542
- assert_no_select 'p.error[error_prefix]'
543
- assert_no_select 'p.error[error_method]'
544
- end
545
-
546
- test 'builder should allow passing options to error tag' do
547
- with_error_for @user, :name, :id => 'name_error'
548
- assert_select 'span.error#name_error', "can't be blank"
549
- end
550
-
551
- # FULL ERRORS
552
- test 'builder should generate an full error tag for the attribute' do
553
- with_full_error_for @user, :name
554
- assert_select 'span.error', "Super User Name! can't be blank"
555
- end
556
-
557
- test 'builder should generate an full error tag with a clean HTML' do
558
- with_full_error_for @user, :name
559
- assert_no_select 'span.error[error_html]'
560
- end
561
-
562
- test 'builder should allow passing options to full error tag' do
563
- with_full_error_for @user, :name, :id => 'name_error', :error_prefix => "Your name"
564
- assert_select 'span.error#name_error', "Your name can't be blank"
565
- end
566
-
567
- # HINTS
568
- test 'builder should generate a hint tag for the attribute' do
569
- store_translations(:en, :simple_form => { :hints => { :user => { :name => "Add your name" }}}) do
570
- with_hint_for @user, :name
571
- assert_select 'span.hint', 'Add your name'
572
- end
573
- end
574
-
575
- test 'builder should generate a hint component tag for the given text for a model with ActiveModel::Validations' do
576
- with_hint_for @validating_user, 'Hello World!'
577
- assert_select 'span.hint', 'Hello World!'
578
- end
579
-
580
- test 'builder should generate a hint component tag for the given text' do
581
- with_hint_for @user, 'Hello World!'
582
- assert_select 'span.hint', 'Hello World!'
583
- end
584
-
585
- test 'builder should generate a hint componet tag with a clean HTML' do
586
- with_hint_for @validating_user, 'Hello World!'
587
- assert_no_select 'span.hint[hint]'
588
- assert_no_select 'span.hint[hint_html]'
589
- end
590
-
591
- test 'builder should generate a hint componet tag with a clean HTML when hint_tag option is present' do
592
- with_hint_for @user, 'Hello World!', :hint_tag => :p
593
- assert_no_select 'p.hint[hint]'
594
- assert_no_select 'p.hint[hint_html]'
595
- assert_no_select 'p.hint[hint_tag]'
596
- end
597
-
598
- test 'builder should allow passing options to hint tag' do
599
- with_hint_for @user, :name, :hint => 'Hello World!', :id => 'name_hint'
600
- assert_select 'span.hint#name_hint', 'Hello World!'
601
- end
602
-
603
- # LABELS
604
- test 'builder should generate a label for the attribute' do
605
- with_label_for @user, :name
606
- assert_select 'label.string[for=user_name]', /Name/
607
- end
608
-
609
- test 'builder should generate a label componet tag with a clean HTML' do
610
- with_label_for @user, :name
611
- assert_no_select 'label.string[label_html]'
612
- end
613
-
614
- test 'builder should add a required class to label if the attribute is required' do
615
- with_label_for @validating_user, :name
616
- assert_select 'label.string.required[for=validating_user_name]', /Name/
617
- end
618
-
619
- test 'builder should allow passing options to label tag' do
620
- with_label_for @user, :name, :label => 'My label', :id => 'name_label'
621
- assert_select 'label.string#name_label', /My label/
622
- end
623
-
624
- test 'builder should fallback to default label when string is given' do
625
- with_label_for @user, :name, 'Nome do usuário'
626
- assert_select 'label', 'Nome do usuário'
627
- assert_no_select 'label.string'
628
- end
629
-
630
- test 'builder should fallback to default label when block is given' do
631
- with_label_for @user, :name do
632
- 'Nome do usuário'
633
- end
634
- assert_select 'label', 'Nome do usuário'
635
- assert_no_select 'label.string'
636
- end
637
-
638
- test 'builder allows label order to be changed' do
639
- swap SimpleForm, :label_text => lambda { |l, r| "#{l}:" } do
640
- with_label_for @user, :age
641
- assert_select 'label.integer[for=user_age]', "Age:"
642
- end
643
- end
644
-
645
- # BUTTONS
646
- test 'builder should create buttons' do
647
- with_button_for :post, :submit
648
- assert_select 'form input.button[type=submit][value=Save Post]'
649
- end
650
-
651
- test 'builder should create buttons for records' do
652
- @user.new_record!
653
- with_button_for @user, :submit
654
- assert_select 'form input.button[type=submit][value=Create User]'
655
- end
656
-
657
- # ASSOCIATIONS
658
- test 'builder should not allow creating an association input when no object exists' do
659
- assert_raise ArgumentError do
660
- with_association_for :post, :author
661
- end
662
- end
663
-
664
- test 'builder association with a block calls simple_fields_for' do
665
- simple_form_for @user do |f|
666
- f.association :posts do |posts_form|
667
- assert posts_form.instance_of?(SimpleForm::FormBuilder)
668
- end
669
- end
670
- end
671
-
672
- test 'builder association forwards collection to simple_fields_for' do
673
- calls = 0
674
- simple_form_for @user do |f|
675
- f.association :company, :collection => Company.all do |c|
676
- calls += 1
677
- end
678
- end
679
-
680
- assert_equal 3, calls
681
- end
682
-
683
- test 'builder association marks input as required based on both association and attribute' do
684
- swap SimpleForm, :required_by_default => false do
685
- with_association_for @validating_user, :company, :collection => []
686
- assert_select 'label.required'
687
- end
688
- end
689
-
690
- test 'builder preloads collection association' do
691
- value = @user.tags
692
- value.expects(:to_a).returns(value)
693
- with_association_for @user, :tags
694
- assert_select 'form select.select#user_tag_ids'
695
- assert_select 'form select option[value=1]', 'Tag 1'
696
- assert_select 'form select option[value=2]', 'Tag 2'
697
- assert_select 'form select option[value=3]', 'Tag 3'
698
- end
699
-
700
- test 'builder does not preload collection association if preload is false' do
701
- value = @user.company
702
- value.expects(:to_a).never
703
- with_association_for @user, :company, :preload => false
704
- assert_select 'form select.select#user_company_id'
705
- assert_select 'form select option[value=1]', 'Company 1'
706
- assert_select 'form select option[value=2]', 'Company 2'
707
- assert_select 'form select option[value=3]', 'Company 3'
708
- end
709
-
710
- test 'builder does not preload non-collection association' do
711
- value = @user.company
712
- value.expects(:to_a).never
713
- with_association_for @user, :company, :preload => false
714
- assert_select 'form select.select#user_company_id'
715
- assert_select 'form select option[value=1]', 'Company 1'
716
- assert_select 'form select option[value=2]', 'Company 2'
717
- assert_select 'form select option[value=3]', 'Company 3'
718
- end
719
-
720
- # ASSOCIATIONS - BELONGS TO
721
- test 'builder creates a select for belongs_to associations' do
722
- with_association_for @user, :company
723
- assert_select 'form select.select#user_company_id'
724
- assert_select 'form select option[value=1]', 'Company 1'
725
- assert_select 'form select option[value=2]', 'Company 2'
726
- assert_select 'form select option[value=3]', 'Company 3'
727
- end
728
-
729
- test 'builder allows collection radio for belongs_to associations' do
730
- with_association_for @user, :company, :as => :radio
731
- assert_select 'form input.radio#user_company_id_1'
732
- assert_select 'form input.radio#user_company_id_2'
733
- assert_select 'form input.radio#user_company_id_3'
734
- end
735
-
736
- test 'builder marks the record which already belongs to the user' do
737
- @user.company_id = 2
738
- with_association_for @user, :company, :as => :radio
739
- assert_no_select 'form input.radio#user_company_id_1[checked=checked]'
740
- assert_select 'form input.radio#user_company_id_2[checked=checked]'
741
- assert_no_select 'form input.radio#user_company_id_3[checked=checked]'
742
- end
743
-
744
- # ASSOCIATIONS - FINDERS
745
- test 'builder should use reflection conditions to find collection' do
746
- with_association_for @user, :special_company
747
- assert_select 'form select.select#user_special_company_id'
748
- assert_select 'form select option[value=1]'
749
- assert_no_select 'form select option[value=2]'
750
- assert_no_select 'form select option[value=3]'
751
- end
752
-
753
- test 'builder should allow overriding collection to association input' do
754
- with_association_for @user, :company, :include_blank => false,
755
- :collection => [Company.new(999, 'Teste')]
756
- assert_select 'form select.select#user_company_id'
757
- assert_no_select 'form select option[value=1]'
758
- assert_select 'form select option[value=999]', 'Teste'
759
- assert_select 'form select option', :count => 1
760
- end
761
-
762
- # ASSOCIATIONS - has_*
763
- test 'builder does not allow has_one associations' do
764
- assert_raise RuntimeError do
765
- with_association_for @user, :first_company, :as => :radio
766
- end
767
- end
768
-
769
- test 'builder creates a select with multiple options for collection associations' do
770
- with_association_for @user, :tags
771
- assert_select 'form select.select#user_tag_ids'
772
- assert_select 'form select[multiple=multiple][size=5]'
773
- assert_select 'form select option[value=1]', 'Tag 1'
774
- assert_select 'form select option[value=2]', 'Tag 2'
775
- assert_select 'form select option[value=3]', 'Tag 3'
776
- end
777
-
778
- test 'builder allows size to be overwritten for collection associations' do
779
- with_association_for @user, :tags, :input_html => { :size => 10 }
780
- assert_select 'form select[multiple=multiple][size=10]'
781
- end
782
-
783
- test 'builder marks all selected records which already belongs to user' do
784
- @user.tag_ids = [1, 2]
785
- with_association_for @user, :tags
786
- assert_select 'form select option[value=1][selected=selected]'
787
- assert_select 'form select option[value=2][selected=selected]'
788
- assert_no_select 'form select option[value=3][selected=selected]'
789
- end
790
-
791
- test 'builder allows a collection of check boxes for collection associations' do
792
- @user.tag_ids = [1, 2]
793
- with_association_for @user, :tags, :as => :check_boxes
794
- assert_select 'form input#user_tag_ids_1[type=checkbox]'
795
- assert_select 'form input#user_tag_ids_2[type=checkbox]'
796
- assert_select 'form input#user_tag_ids_3[type=checkbox]'
797
- end
798
-
799
- test 'builder marks all selected records for collection boxes' do
800
- @user.tag_ids = [1, 2]
801
- with_association_for @user, :tags, :as => :check_boxes
802
- assert_select 'form input[type=checkbox][value=1][checked=checked]'
803
- assert_select 'form input[type=checkbox][value=2][checked=checked]'
804
- assert_no_select 'form input[type=checkbox][value=3][checked=checked]'
805
- end
806
-
807
- test 'builder with collection support giving collection and item wrapper tags' do
808
- with_association_for @user, :tags, :as => :check_boxes,
809
- :collection_wrapper_tag => :ul, :item_wrapper_tag => :li
810
-
811
- assert_select 'form ul', :count => 1
812
- assert_select 'form ul li', :count => 3
813
- end
814
-
815
- # CUSTOM FORM BUILDER
816
- test 'custom builder should inherit mappings' do
817
- with_custom_form_for @user, :email
818
- assert_select 'form input[type=email]#user_email.custom'
819
- end
820
-
821
- test 'form with CustomMapTypeFormBuilder should use custom map type builder' do
822
- with_concat_custom_mapping_form_for(:user) do |user|
823
- assert user.instance_of?(CustomMapTypeFormBuilder)
824
- end
825
- end
826
-
827
- test 'form with CustomMapTypeFormBuilder should use custom mapping' do
828
- with_concat_custom_mapping_form_for(:user) do |user|
829
- assert_equal SimpleForm::Inputs::StringInput, user.class.mappings[:custom_type]
830
- end
831
- end
832
-
833
- test 'form without CustomMapTypeFormBuilder should not use custom mapping' do
834
- with_concat_form_for(:user) do |user|
835
- assert_nil user.class.mappings[:custom_type]
836
- end
837
- end
838
-
839
- # DISCOVERY
840
- # Setup new inputs and remove them after the test.
841
- def discovery(value=false)
842
- swap SimpleForm, :cache_discovery => value do
843
- begin
844
- load "discovery_inputs.rb"
845
- yield
846
- ensure
847
- SimpleForm::FormBuilder.discovery_cache.clear
848
- Object.send :remove_const, :StringInput
849
- Object.send :remove_const, :NumericInput
850
- Object.send :remove_const, :CustomizedInput
851
- end
852
- end
853
- end
854
-
855
- test 'builder should not discover new inputs if cached' do
856
- with_form_for @user, :name
857
- assert_select 'form input#user_name.string'
858
-
859
- discovery(true) do
860
- with_form_for @user, :name
861
- assert_no_select 'form section input#user_name.string'
862
- end
863
- end
864
-
865
- test 'builder should discover new inputs' do
866
- discovery do
867
- with_form_for @user, :name, :as => :customized
868
- assert_select 'form section input#user_name.string'
869
- end
870
- end
871
-
872
- test 'builder should not discover new inputs if discovery is off' do
873
- with_form_for @user, :name
874
- assert_select 'form input#user_name.string'
875
-
876
- swap SimpleForm, :inputs_discovery => false do
877
- discovery do
878
- with_form_for @user, :name
879
- assert_no_select 'form section input#user_name.string'
880
- end
881
- end
882
- end
883
-
884
- test 'builder should discover new inputs from mappings if not cached' do
885
- discovery do
886
- with_form_for @user, :name
887
- assert_select 'form section input#user_name.string'
888
- end
889
- end
890
-
891
- test 'builder should discover new inputs from internal fallbacks if not cached' do
892
- discovery do
893
- with_form_for @user, :age
894
- assert_select 'form section input#user_age.numeric.integer'
895
- end
896
- end
897
-
898
- # CUSTOM COMPONENTS
899
- # Setup new components and remove them after the test.
900
- def custom_component(components=[:label_input, :div])
901
- swap SimpleForm, :components => components do
902
- begin
903
- load "custom_components.rb"
904
- yield
905
- ensure
906
- Div.send(:undef_method, :div)
907
- Object.send :remove_const, :Div
908
- end
909
- end
910
- end
911
-
912
- test 'builder should accept new components' do
913
- custom_component do
914
- with_form_for @user, :age
915
- assert_select 'form input#user_age.numeric.integer'
916
- assert_select 'form .custom_input'
917
- end
918
- end
919
-
920
- test 'input field should render only the input' do
921
- custom_component do
922
- with_concat_form_for(@user) do |f|
923
- f.input_field :age
924
- end
925
-
926
- assert_select 'form input#user_age.numeric.integer'
927
- assert_no_select 'form .custom_input'
928
- end
929
- end
930
- end