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