simple_form 1.5.2 → 2.0.0.rc

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of simple_form might be problematic. Click here for more details.

Files changed (105) hide show
  1. data/CHANGELOG.md +224 -0
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +817 -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/config/initializers/simple_form.rb.tt +173 -0
  7. data/lib/simple_form.rb +109 -43
  8. data/lib/simple_form/action_view_extensions/builder.rb +158 -53
  9. data/lib/simple_form/action_view_extensions/form_helper.rb +29 -22
  10. data/lib/simple_form/components.rb +11 -1
  11. data/lib/simple_form/components/errors.rb +6 -24
  12. data/lib/simple_form/components/hints.rb +7 -21
  13. data/lib/simple_form/components/html5.rb +26 -0
  14. data/lib/simple_form/components/labels.rb +15 -13
  15. data/lib/simple_form/components/maxlength.rb +41 -0
  16. data/lib/simple_form/components/min_max.rb +49 -0
  17. data/lib/simple_form/components/pattern.rb +34 -0
  18. data/lib/simple_form/components/placeholders.rb +5 -17
  19. data/lib/simple_form/components/readonly.rb +22 -0
  20. data/lib/simple_form/core_ext/hash.rb +16 -0
  21. data/lib/simple_form/error_notification.rb +8 -1
  22. data/lib/simple_form/form_builder.rb +86 -22
  23. data/lib/simple_form/helpers.rb +7 -4
  24. data/lib/simple_form/helpers/autofocus.rb +11 -0
  25. data/lib/simple_form/helpers/disabled.rb +15 -0
  26. data/lib/simple_form/helpers/readonly.rb +15 -0
  27. data/lib/simple_form/helpers/required.rb +7 -10
  28. data/lib/simple_form/helpers/validators.rb +4 -4
  29. data/lib/simple_form/inputs.rb +17 -13
  30. data/lib/simple_form/inputs/base.rb +50 -81
  31. data/lib/simple_form/inputs/boolean_input.rb +43 -4
  32. data/lib/simple_form/inputs/collection_check_boxes_input.rb +21 -0
  33. data/lib/simple_form/inputs/collection_input.rb +27 -13
  34. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +69 -0
  35. data/lib/simple_form/inputs/collection_select_input.rb +14 -0
  36. data/lib/simple_form/inputs/date_time_input.rb +2 -2
  37. data/lib/simple_form/inputs/grouped_collection_select_input.rb +41 -0
  38. data/lib/simple_form/inputs/hidden_input.rb +3 -6
  39. data/lib/simple_form/inputs/numeric_input.rb +3 -51
  40. data/lib/simple_form/inputs/password_input.rb +1 -2
  41. data/lib/simple_form/inputs/priority_input.rb +2 -2
  42. data/lib/simple_form/inputs/range_input.rb +1 -3
  43. data/lib/simple_form/inputs/string_input.rb +6 -8
  44. data/lib/simple_form/inputs/text_input.rb +1 -2
  45. data/lib/simple_form/version.rb +1 -1
  46. data/lib/simple_form/wrappers.rb +8 -0
  47. data/lib/simple_form/wrappers/builder.rb +75 -0
  48. data/lib/simple_form/wrappers/many.rb +68 -0
  49. data/lib/simple_form/wrappers/root.rb +34 -0
  50. data/lib/simple_form/wrappers/single.rb +18 -0
  51. data/test/action_view_extensions/builder_test.rb +195 -100
  52. data/test/action_view_extensions/form_helper_test.rb +24 -2
  53. data/test/components/label_test.rb +20 -5
  54. data/test/form_builder/association_test.rb +167 -0
  55. data/test/form_builder/button_test.rb +28 -0
  56. data/test/{error_notification_test.rb → form_builder/error_notification_test.rb} +2 -1
  57. data/test/form_builder/error_test.rb +101 -0
  58. data/test/form_builder/general_test.rb +348 -0
  59. data/test/form_builder/hint_test.rb +115 -0
  60. data/test/form_builder/input_field_test.rb +51 -0
  61. data/test/form_builder/label_test.rb +51 -0
  62. data/test/form_builder/wrapper_test.rb +140 -0
  63. data/test/generators/simple_form_generator_test.rb +32 -0
  64. data/test/inputs/boolean_input_test.rb +91 -0
  65. data/test/inputs/collection_check_boxes_input_test.rb +224 -0
  66. data/test/inputs/collection_radio_buttons_input_test.rb +326 -0
  67. data/test/inputs/collection_select_input_test.rb +241 -0
  68. data/test/inputs/datetime_input_test.rb +85 -0
  69. data/test/inputs/disabled_test.rb +38 -0
  70. data/test/inputs/discovery_test.rb +61 -0
  71. data/test/inputs/file_input_test.rb +16 -0
  72. data/test/inputs/general_test.rb +69 -0
  73. data/test/inputs/grouped_collection_select_input_test.rb +109 -0
  74. data/test/inputs/hidden_input_test.rb +30 -0
  75. data/test/inputs/numeric_input_test.rb +167 -0
  76. data/test/inputs/priority_input_test.rb +43 -0
  77. data/test/inputs/readonly_test.rb +61 -0
  78. data/test/inputs/required_test.rb +113 -0
  79. data/test/inputs/string_input_test.rb +140 -0
  80. data/test/inputs/text_input_test.rb +24 -0
  81. data/test/{discovery_inputs.rb → support/discovery_inputs.rb} +0 -0
  82. data/test/support/misc_helpers.rb +48 -6
  83. data/test/support/mock_controller.rb +2 -2
  84. data/test/support/models.rb +20 -5
  85. data/test/test_helper.rb +5 -8
  86. metadata +123 -98
  87. data/.gitignore +0 -3
  88. data/.gitmodules +0 -3
  89. data/.travis.yml +0 -15
  90. data/CHANGELOG.rdoc +0 -159
  91. data/Gemfile +0 -9
  92. data/README.rdoc +0 -466
  93. data/Rakefile +0 -27
  94. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +0 -93
  95. data/lib/simple_form/components/wrapper.rb +0 -38
  96. data/lib/simple_form/helpers/has_errors.rb +0 -15
  97. data/lib/simple_form/helpers/maxlength.rb +0 -24
  98. data/lib/simple_form/helpers/pattern.rb +0 -28
  99. data/simple_form.gemspec +0 -25
  100. data/test/components/error_test.rb +0 -56
  101. data/test/components/hint_test.rb +0 -74
  102. data/test/components/wrapper_test.rb +0 -63
  103. data/test/custom_components.rb +0 -7
  104. data/test/form_builder_test.rb +0 -930
  105. data/test/inputs_test.rb +0 -995
@@ -42,9 +42,31 @@ class FormHelperTest < ActionView::TestCase
42
42
  assert_select 'form.simple_form.user'
43
43
  end
44
44
 
45
- test 'simple form should add object class name as css class to form' do
45
+ test 'simple form should add :as option as css class to form when object is not present' do
46
+ concat(simple_form_for(:user, :as => 'superuser') do |f| end)
47
+ assert_select 'form.simple_form.superuser'
48
+ end
49
+
50
+ test 'simple form should add object class name with new prefix as css class to form if record is not persisted' do
51
+ @user.new_record!
46
52
  concat(simple_form_for(@user) do |f| end)
47
- assert_select 'form.simple_form.user'
53
+ assert_select 'form.simple_form.new_user'
54
+ end
55
+
56
+ test 'simple form should add :as option with new prefix as css class to form if record is not persisted' do
57
+ @user.new_record!
58
+ concat(simple_form_for(@user, :as => 'superuser') do |f| end)
59
+ assert_select 'form.simple_form.new_superuser'
60
+ end
61
+
62
+ test 'simple form should add edit class prefix as css class to form if record is persisted' do
63
+ concat(simple_form_for(@user) do |f| end)
64
+ assert_select 'form.simple_form.edit_user'
65
+ end
66
+
67
+ test 'simple form should add :as options with edit prefix as css class to form if record is persisted' do
68
+ concat(simple_form_for(@user, :as => 'superuser') do |f| end)
69
+ assert_select 'form.simple_form.edit_superuser'
48
70
  end
49
71
 
50
72
  test 'simple form should not add object class to form if css_class is specified' do
@@ -1,7 +1,8 @@
1
1
  # encoding: UTF-8
2
2
  require 'test_helper'
3
3
 
4
- class LabelTest < ActionView::TestCase
4
+ # Isolated tests for label without triggering f.label.
5
+ class IsolatedLabelTest < ActionView::TestCase
5
6
  setup do
6
7
  SimpleForm::Inputs::Base.reset_i18n_cache :translate_required_html
7
8
  end
@@ -71,16 +72,16 @@ class LabelTest < ActionView::TestCase
71
72
  end
72
73
  end
73
74
 
74
- test 'input should use i18n based only on attribute to lookup translation' do
75
- store_translations(:en, :simple_form => { :labels => { :age => 'Idade' } } ) do
75
+ test 'input should use i18n under defaults to lookup translation' do
76
+ store_translations(:en, :simple_form => { :labels => { :defaults => {:age => 'Idade'} } } ) do
76
77
  with_label_for @user, :age, :integer
77
78
  assert_select 'label[for=user_age]', /Idade/
78
79
  end
79
80
  end
80
81
 
81
82
  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
83
+ swap SimpleForm, :translate_labels => false do
84
+ store_translations(:en, :simple_form => { :labels => { :defaults => {:age => 'Idade'} } } ) do
84
85
  with_label_for @user, :age, :integer
85
86
  assert_select 'label[for=user_age]', /Age/
86
87
  end
@@ -246,6 +247,11 @@ class LabelTest < ActionView::TestCase
246
247
  assert_select 'label[for=project_name]', /Name/
247
248
  end
248
249
 
250
+ test 'label should include for attribute for select collection' do
251
+ with_label_for @user, :sex, :select, :collection => [:male, :female]
252
+ assert_select 'label[for=user_sex]'
253
+ end
254
+
249
255
  test 'label should use i18n properly when object is not present' do
250
256
  store_translations(:en, :simple_form => { :labels => {
251
257
  :project => { :name => 'Nome' }
@@ -268,4 +274,13 @@ class LabelTest < ActionView::TestCase
268
274
  assert_select 'label.my_custom_class'
269
275
  end
270
276
  end
277
+
278
+ test 'label strips extra classes even when label_class is nil' do
279
+ swap SimpleForm, :label_class => nil do
280
+ with_label_for @user, :name, :string
281
+ assert_select "label[class='string required']"
282
+ assert_no_select "label[class='string required ']"
283
+ assert_no_select "label[class=' string required']"
284
+ end
285
+ end
271
286
  end
@@ -0,0 +1,167 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ class AssociationTest < ActionView::TestCase
5
+ def with_association_for(object, *args)
6
+ with_concat_form_for(object) do |f|
7
+ f.association(*args)
8
+ end
9
+ end
10
+
11
+ test 'builder should not allow creating an association input when no object exists' do
12
+ assert_raise ArgumentError do
13
+ with_association_for :post, :author
14
+ end
15
+ end
16
+
17
+ test 'builder association with a block calls simple_fields_for' do
18
+ simple_form_for @user do |f|
19
+ f.association :posts do |posts_form|
20
+ assert posts_form.instance_of?(SimpleForm::FormBuilder)
21
+ end
22
+ end
23
+ end
24
+
25
+ test 'builder association forwards collection to simple_fields_for' do
26
+ calls = 0
27
+ simple_form_for @user do |f|
28
+ f.association :company, :collection => Company.all do |c|
29
+ calls += 1
30
+ end
31
+ end
32
+
33
+ assert_equal 3, calls
34
+ end
35
+
36
+ test 'builder association marks input as required based on both association and attribute' do
37
+ swap SimpleForm, :required_by_default => false do
38
+ with_association_for @validating_user, :company, :collection => []
39
+ assert_select 'label.required'
40
+ end
41
+ end
42
+
43
+ test 'builder preloads collection association' do
44
+ value = @user.tags
45
+ value.expects(:to_a).returns(value)
46
+ with_association_for @user, :tags
47
+ assert_select 'form select.select#user_tag_ids'
48
+ assert_select 'form select option[value=1]', 'Tag 1'
49
+ assert_select 'form select option[value=2]', 'Tag 2'
50
+ assert_select 'form select option[value=3]', 'Tag 3'
51
+ end
52
+
53
+ test 'builder does not preload collection association if preload is false' do
54
+ value = @user.company
55
+ value.expects(:to_a).never
56
+ with_association_for @user, :company, :preload => false
57
+ assert_select 'form select.select#user_company_id'
58
+ assert_select 'form select option[value=1]', 'Company 1'
59
+ assert_select 'form select option[value=2]', 'Company 2'
60
+ assert_select 'form select option[value=3]', 'Company 3'
61
+ end
62
+
63
+ test 'builder does not preload non-collection association' do
64
+ value = @user.company
65
+ value.expects(:to_a).never
66
+ with_association_for @user, :company, :preload => false
67
+ assert_select 'form select.select#user_company_id'
68
+ assert_select 'form select option[value=1]', 'Company 1'
69
+ assert_select 'form select option[value=2]', 'Company 2'
70
+ assert_select 'form select option[value=3]', 'Company 3'
71
+ end
72
+
73
+ # ASSOCIATIONS - BELONGS TO
74
+ test 'builder creates a select for belongs_to associations' do
75
+ with_association_for @user, :company
76
+ assert_select 'form select.select#user_company_id'
77
+ assert_select 'form select option[value=1]', 'Company 1'
78
+ assert_select 'form select option[value=2]', 'Company 2'
79
+ assert_select 'form select option[value=3]', 'Company 3'
80
+ end
81
+
82
+ test 'builder allows collection radio for belongs_to associations' do
83
+ with_association_for @user, :company, :as => :radio_buttons
84
+ assert_select 'form input.radio_buttons#user_company_id_1'
85
+ assert_select 'form input.radio_buttons#user_company_id_2'
86
+ assert_select 'form input.radio_buttons#user_company_id_3'
87
+ end
88
+
89
+ test 'builder marks the record which already belongs to the user' do
90
+ @user.company_id = 2
91
+ with_association_for @user, :company, :as => :radio_buttons
92
+ assert_no_select 'form input.radio_buttons#user_company_id_1[checked=checked]'
93
+ assert_select 'form input.radio_buttons#user_company_id_2[checked=checked]'
94
+ assert_no_select 'form input.radio_buttons#user_company_id_3[checked=checked]'
95
+ end
96
+
97
+ # ASSOCIATIONS - FINDERS
98
+ test 'builder should use reflection conditions to find collection' do
99
+ with_association_for @user, :special_company
100
+ assert_select 'form select.select#user_special_company_id'
101
+ assert_select 'form select option[value=1]'
102
+ assert_no_select 'form select option[value=2]'
103
+ assert_no_select 'form select option[value=3]'
104
+ end
105
+
106
+ test 'builder should allow overriding collection to association input' do
107
+ with_association_for @user, :company, :include_blank => false,
108
+ :collection => [Company.new(999, 'Teste')]
109
+ assert_select 'form select.select#user_company_id'
110
+ assert_no_select 'form select option[value=1]'
111
+ assert_select 'form select option[value=999]', 'Teste'
112
+ assert_select 'form select option', :count => 1
113
+ end
114
+
115
+ # ASSOCIATIONS - has_*
116
+ test 'builder does not allow has_one associations' do
117
+ assert_raise RuntimeError do
118
+ with_association_for @user, :first_company, :as => :radio_buttons
119
+ end
120
+ end
121
+
122
+ test 'builder creates a select with multiple options for collection associations' do
123
+ with_association_for @user, :tags
124
+ assert_select 'form select.select#user_tag_ids'
125
+ assert_select 'form select[multiple=multiple][size=5]'
126
+ assert_select 'form select option[value=1]', 'Tag 1'
127
+ assert_select 'form select option[value=2]', 'Tag 2'
128
+ assert_select 'form select option[value=3]', 'Tag 3'
129
+ end
130
+
131
+ test 'builder allows size to be overwritten for collection associations' do
132
+ with_association_for @user, :tags, :input_html => { :size => 10 }
133
+ assert_select 'form select[multiple=multiple][size=10]'
134
+ end
135
+
136
+ test 'builder marks all selected records which already belongs to user' do
137
+ @user.tag_ids = [1, 2]
138
+ with_association_for @user, :tags
139
+ assert_select 'form select option[value=1][selected=selected]'
140
+ assert_select 'form select option[value=2][selected=selected]'
141
+ assert_no_select 'form select option[value=3][selected=selected]'
142
+ end
143
+
144
+ test 'builder allows a collection of check boxes for collection associations' do
145
+ @user.tag_ids = [1, 2]
146
+ with_association_for @user, :tags, :as => :check_boxes
147
+ assert_select 'form input#user_tag_ids_1[type=checkbox]'
148
+ assert_select 'form input#user_tag_ids_2[type=checkbox]'
149
+ assert_select 'form input#user_tag_ids_3[type=checkbox]'
150
+ end
151
+
152
+ test 'builder marks all selected records for collection boxes' do
153
+ @user.tag_ids = [1, 2]
154
+ with_association_for @user, :tags, :as => :check_boxes
155
+ assert_select 'form input[type=checkbox][value=1][checked=checked]'
156
+ assert_select 'form input[type=checkbox][value=2][checked=checked]'
157
+ assert_no_select 'form input[type=checkbox][value=3][checked=checked]'
158
+ end
159
+
160
+ test 'builder with collection support giving collection and item wrapper tags' do
161
+ with_association_for @user, :tags, :as => :check_boxes,
162
+ :collection_wrapper_tag => :ul, :item_wrapper_tag => :li
163
+
164
+ assert_select 'form ul', :count => 1
165
+ assert_select 'form ul li', :count => 3
166
+ end
167
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ class ButtonTest < ActionView::TestCase
5
+ def with_button_for(object, *args)
6
+ with_concat_form_for(object) do |f|
7
+ f.button(*args)
8
+ end
9
+ end
10
+
11
+ test 'builder should create buttons' do
12
+ with_button_for :post, :submit
13
+ assert_select 'form input.button[type=submit][value=Save Post]'
14
+ end
15
+
16
+ test 'builder should create buttons for records' do
17
+ @user.new_record!
18
+ with_button_for @user, :submit
19
+ assert_select 'form input.button[type=submit][value=Create User]'
20
+ end
21
+
22
+ test "builder should use the default class from the configuration" do
23
+ swap SimpleForm, :button_class => 'btn' do
24
+ with_button_for :post, :submit
25
+ assert_select 'form input.btn[type=submit][value=Save Post]'
26
+ end
27
+ end
28
+ end
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
  require 'test_helper'
3
3
 
4
+ # Tests for f.error_notification
4
5
  class ErrorNotificationTest < ActionView::TestCase
5
-
6
6
  def with_error_notification_for(object, options={}, &block)
7
7
  with_concat_form_for(object) do |f|
8
8
  f.error_notification(options)
@@ -11,6 +11,7 @@ class ErrorNotificationTest < ActionView::TestCase
11
11
 
12
12
  test 'error notification is not generated when the object has no error' do
13
13
  assert @validating_user.valid?
14
+
14
15
  with_error_notification_for @validating_user
15
16
  assert_no_select 'p.error_notification'
16
17
  end
@@ -0,0 +1,101 @@
1
+ require 'test_helper'
2
+
3
+ # Tests for f.error and f.full_error
4
+ class ErrorTest < ActionView::TestCase
5
+ def with_error_for(object, *args)
6
+ with_concat_form_for(object) do |f|
7
+ f.error(*args)
8
+ end
9
+ end
10
+
11
+ def with_full_error_for(object, *args)
12
+ with_concat_form_for(object) do |f|
13
+ f.full_error(*args)
14
+ end
15
+ end
16
+
17
+ test 'error should not generate content for attribute without errors' do
18
+ with_error_for @user, :active
19
+ assert_no_select 'span.error'
20
+ end
21
+
22
+ test 'error should not generate messages when object is not present' do
23
+ with_error_for :project, :name
24
+ assert_no_select 'span.error'
25
+ end
26
+
27
+ test "error should not generate messages when object doesn't respond to errors method" do
28
+ @user.instance_eval { undef errors }
29
+ with_error_for @user, :name
30
+ assert_no_select 'span.error'
31
+ end
32
+
33
+ test 'error should generate messages for attribute with single error' do
34
+ with_error_for @user, :name
35
+ assert_select 'span.error', "can't be blank"
36
+ end
37
+
38
+ test 'error should generate messages for attribute with one error when using first' do
39
+ swap SimpleForm, :error_method => :first do
40
+ with_error_for @user, :age
41
+ assert_select 'span.error', 'is not a number'
42
+ end
43
+ end
44
+
45
+ test 'error should generate messages for attribute with several errors when using to_sentence' do
46
+ swap SimpleForm, :error_method => :to_sentence do
47
+ with_error_for @user, :age
48
+ assert_select 'span.error', 'is not a number and must be greater than 18'
49
+ end
50
+ end
51
+
52
+ test 'error should be able to pass html options' do
53
+ with_error_for @user, :name, :id => 'error', :class => 'yay'
54
+ assert_select 'span#error.error.yay'
55
+ end
56
+
57
+ test 'error should find errors on attribute and association' do
58
+ with_error_for @user, :company_id, :as => :select,
59
+ :error_method => :to_sentence, :reflection => Association.new(Company, :company, {})
60
+ assert_select 'span.error', 'must be valid and company must be present'
61
+ end
62
+
63
+ test 'error should generate an error tag with a clean HTML' do
64
+ with_error_for @user, :name
65
+ assert_no_select 'span.error[error_html]'
66
+ end
67
+
68
+ test 'error should generate an error tag with a clean HTML when errors options are present' do
69
+ with_error_for @user, :name, :error_tag => :p, :error_prefix => 'Name', :error_method => :first
70
+ assert_no_select 'p.error[error_html]'
71
+ assert_no_select 'p.error[error_tag]'
72
+ assert_no_select 'p.error[error_prefix]'
73
+ assert_no_select 'p.error[error_method]'
74
+ end
75
+
76
+ # FULL ERRORS
77
+
78
+ test 'full error should generate an full error tag for the attribute' do
79
+ with_full_error_for @user, :name
80
+ assert_select 'span.error', "Super User Name! can't be blank"
81
+ end
82
+
83
+ test 'full error should generate an full error tag with a clean HTML' do
84
+ with_full_error_for @user, :name
85
+ assert_no_select 'span.error[error_html]'
86
+ end
87
+
88
+ test 'full error should allow passing options to full error tag' do
89
+ with_full_error_for @user, :name, :id => 'name_error', :error_prefix => "Your name"
90
+ assert_select 'span.error#name_error', "Your name can't be blank"
91
+ end
92
+
93
+ # CUSTOM WRAPPERS
94
+
95
+ test 'error with custom wrappers works' do
96
+ swap_wrapper do
97
+ with_error_for @user, :name
98
+ assert_select 'span.omg_error', "can't be blank"
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,348 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ class FormBuilderTest < ActionView::TestCase
5
+ def with_custom_form_for(object, *args, &block)
6
+ with_concat_custom_form_for(object) do |f|
7
+ f.input(*args, &block)
8
+ end
9
+ end
10
+
11
+ test 'nested simple fields should yield an instance of FormBuilder' do
12
+ simple_form_for :user do |f|
13
+ f.simple_fields_for :posts do |posts_form|
14
+ assert posts_form.instance_of?(SimpleForm::FormBuilder)
15
+ end
16
+ end
17
+ end
18
+
19
+ test 'builder input is html safe' do
20
+ simple_form_for @user do |f|
21
+ assert f.input(:name).html_safe?
22
+ end
23
+ end
24
+
25
+ test 'builder input should allow a block to configure input' do
26
+ with_form_for @user, :name do
27
+ text_field_tag :foo, :bar, :id => :cool
28
+ end
29
+ assert_no_select 'input.string'
30
+ assert_select 'input#cool'
31
+ end
32
+
33
+ test 'builder should allow adding custom input mappings for default input types' do
34
+ swap SimpleForm, :input_mappings => { /count$/ => :integer } do
35
+ with_form_for @user, :post_count
36
+ assert_no_select 'form input#user_post_count.string'
37
+ assert_select 'form input#user_post_count.numeric.integer'
38
+ end
39
+ end
40
+
41
+ test 'builder should allow adding custom input mappings for integer input types' do
42
+ swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
43
+ with_form_for @user, :lock_version
44
+ assert_no_select 'form input#user_lock_version.integer'
45
+ assert_select 'form input#user_lock_version.hidden'
46
+ end
47
+ end
48
+
49
+ test 'builder uses the first matching custom input map when more than one matches' do
50
+ swap SimpleForm, :input_mappings => { /count$/ => :integer, /^post_/ => :password } do
51
+ with_form_for @user, :post_count
52
+ assert_no_select 'form input#user_post_count.password'
53
+ assert_select 'form input#user_post_count.numeric.integer'
54
+ end
55
+ end
56
+
57
+ test 'builder uses the custom map only for matched attributes' do
58
+ swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
59
+ with_form_for @user, :post_count
60
+ assert_no_select 'form input#user_post_count.hidden'
61
+ assert_select 'form input#user_post_count.string'
62
+ end
63
+ end
64
+
65
+ # INPUT TYPES
66
+ test 'builder should generate text fields for string columns' do
67
+ with_form_for @user, :name
68
+ assert_select 'form input#user_name.string'
69
+ end
70
+
71
+ test 'builder should generate text areas for text columns' do
72
+ with_form_for @user, :description
73
+ assert_select 'form textarea#user_description.text'
74
+ end
75
+
76
+ test 'builder should generate a checkbox for boolean columns' do
77
+ with_form_for @user, :active
78
+ assert_select 'form input[type=checkbox]#user_active.boolean'
79
+ end
80
+
81
+ test 'builder should use integer text field for integer columns' do
82
+ with_form_for @user, :age
83
+ assert_select 'form input#user_age.numeric.integer'
84
+ end
85
+
86
+ test 'builder should generate decimal text field for decimal columns' do
87
+ with_form_for @user, :credit_limit
88
+ assert_select 'form input#user_credit_limit.numeric.decimal'
89
+ end
90
+
91
+ test 'builder should generate password fields for columns that matches password' do
92
+ with_form_for @user, :password
93
+ assert_select 'form input#user_password.password'
94
+ end
95
+
96
+ test 'builder should generate country fields for columns that matches country' do
97
+ with_form_for @user, :residence_country
98
+ assert_select 'form select#user_residence_country.country'
99
+ end
100
+
101
+ test 'builder should generate time_zone fields for columns that matches time_zone' do
102
+ with_form_for @user, :time_zone
103
+ assert_select 'form select#user_time_zone.time_zone'
104
+ end
105
+
106
+ test 'builder should generate email fields for columns that matches email' do
107
+ with_form_for @user, :email
108
+ assert_select 'form input#user_email.string.email'
109
+ end
110
+
111
+ test 'builder should generate tel fields for columns that matches phone' do
112
+ with_form_for @user, :phone_number
113
+ assert_select 'form input#user_phone_number.string.tel'
114
+ end
115
+
116
+ test 'builder should generate url fields for columns that matches url' do
117
+ with_form_for @user, :url
118
+ assert_select 'form input#user_url.string.url'
119
+ end
120
+
121
+ test 'builder should generate date select for date columns' do
122
+ with_form_for @user, :born_at
123
+ assert_select 'form select#user_born_at_1i.date'
124
+ end
125
+
126
+ test 'builder should generate time select for time columns' do
127
+ with_form_for @user, :delivery_time
128
+ assert_select 'form select#user_delivery_time_4i.time'
129
+ end
130
+
131
+ test 'builder should generate datetime select for datetime columns' do
132
+ with_form_for @user, :created_at
133
+ assert_select 'form select#user_created_at_1i.datetime'
134
+ end
135
+
136
+ test 'builder should generate datetime select for timestamp columns' do
137
+ with_form_for @user, :updated_at
138
+ assert_select 'form select#user_updated_at_1i.datetime'
139
+ end
140
+
141
+ test 'builder should generate file for file columns' do
142
+ @user.avatar = mock("file")
143
+ @user.avatar.expects(:respond_to?).with(:mounted_as).returns(false)
144
+ @user.avatar.expects(:respond_to?).with(:file?).returns(false)
145
+ @user.avatar.expects(:respond_to?).with(:public_filename).returns(true)
146
+
147
+ with_form_for @user, :avatar
148
+ assert_select 'form input#user_avatar.file'
149
+ end
150
+
151
+ test 'builder should generate file for attributes that are real db columns but have file methods' do
152
+ @user.home_picture = mock("file")
153
+ @user.home_picture.expects(:respond_to?).with(:mounted_as).returns(true)
154
+
155
+ with_form_for @user, :home_picture
156
+ assert_select 'form input#user_home_picture.file'
157
+ end
158
+
159
+ test 'build should generate select if a collection is given' do
160
+ with_form_for @user, :age, :collection => 1..60
161
+ assert_select 'form select#user_age.select'
162
+ end
163
+
164
+ test 'builder should allow overriding default input type for text' do
165
+ with_form_for @user, :name, :as => :text
166
+ assert_no_select 'form input#user_name'
167
+ assert_select 'form textarea#user_name.text'
168
+
169
+ with_form_for @user, :active, :as => :radio_buttons
170
+ assert_no_select 'form input[type=checkbox]'
171
+ assert_select 'form input.radio_buttons[type=radio]', :count => 2
172
+
173
+ with_form_for @user, :born_at, :as => :string
174
+ assert_no_select 'form select'
175
+ assert_select 'form input#user_born_at.string'
176
+ end
177
+
178
+ # COMMON OPTIONS
179
+ test 'builder should add chosen form class' do
180
+ swap SimpleForm, :form_class => :my_custom_class do
181
+ with_form_for @user, :name
182
+ assert_select 'form.my_custom_class'
183
+ end
184
+ end
185
+
186
+ test 'builder should allow passing options to input' do
187
+ with_form_for @user, :name, :input_html => { :class => 'my_input', :id => 'my_input' }
188
+ assert_select 'form input#my_input.my_input.string'
189
+ end
190
+
191
+ test 'builder should not propagate input options to wrapper' do
192
+ with_form_for @user, :name, :input_html => { :class => 'my_input', :id => 'my_input' }
193
+ assert_no_select 'form div.input.my_input.string'
194
+ assert_select 'form input#my_input.my_input.string'
195
+ end
196
+
197
+ test 'builder should generate a input with label' do
198
+ with_form_for @user, :name
199
+ assert_select 'form label.string[for=user_name]', /Name/
200
+ end
201
+
202
+ test 'builder should be able to disable the label for a input' do
203
+ with_form_for @user, :name, :label => false
204
+ assert_no_select 'form label'
205
+ end
206
+
207
+ test 'builder should use custom label' do
208
+ with_form_for @user, :name, :label => 'Yay!'
209
+ assert_select 'form label', /Yay!/
210
+ end
211
+
212
+ test 'builder should pass options to label' do
213
+ with_form_for @user, :name, :label_html => { :id => "cool" }
214
+ assert_select 'form label#cool', /Name/
215
+ end
216
+
217
+ test 'builder should not generate hints for a input' do
218
+ with_form_for @user, :name
219
+ assert_no_select 'span.hint'
220
+ end
221
+
222
+ test 'builder should be able to add a hint for a input' do
223
+ with_form_for @user, :name, :hint => 'test'
224
+ assert_select 'span.hint', 'test'
225
+ end
226
+
227
+ test 'builder should be able to disable a hint even if it exists in i18n' do
228
+ store_translations(:en, :simple_form => { :hints => { :name => 'Hint test' } }) do
229
+ with_form_for @user, :name, :hint => false
230
+ assert_no_select 'span.hint'
231
+ end
232
+ end
233
+
234
+ test 'builder should pass options to hint' do
235
+ with_form_for @user, :name, :hint => 'test', :hint_html => { :id => "cool" }
236
+ assert_select 'span.hint#cool', 'test'
237
+ end
238
+
239
+ test 'builder should generate errors for attribute without errors' do
240
+ with_form_for @user, :credit_limit
241
+ assert_no_select 'span.errors'
242
+ end
243
+
244
+ test 'builder should generate errors for attribute with errors' do
245
+ with_form_for @user, :name
246
+ assert_select 'span.error', "can't be blank"
247
+ end
248
+
249
+ test 'builder should be able to disable showing errors for a input' do
250
+ with_form_for @user, :name, :error => false
251
+ assert_no_select 'span.error'
252
+ end
253
+
254
+ test 'builder should pass options to errors' do
255
+ with_form_for @user, :name, :error_html => { :id => "cool" }
256
+ assert_select 'span.error#cool', "can't be blank"
257
+ end
258
+
259
+ test 'placeholder should not be generated when set to false' do
260
+ store_translations(:en, :simple_form => { :placeholders => { :user => {
261
+ :name => 'Name goes here'
262
+ } } }) do
263
+ with_form_for @user, :name, :placeholder => false
264
+ assert_no_select 'input[placeholder]'
265
+ end
266
+ end
267
+
268
+ # DEFAULT OPTIONS
269
+ test 'builder should receive a default argument and pass it to the inputs' do
270
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class' } } do |f|
271
+ f.input :name
272
+ end
273
+ assert_select 'input.default_class'
274
+ end
275
+
276
+ test 'builder should receive a default argument and pass it to the inputs, respecting the specific options' do
277
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class' } } do |f|
278
+ f.input :name, :input_html => { :id => 'specific_id' }
279
+ end
280
+ assert_select 'input.default_class#specific_id'
281
+ end
282
+
283
+ test 'builder should receive a default argument and pass it to the inputs, overwriting the defaults with specific options' do
284
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class', :id => 'default_id' } } do |f|
285
+ f.input :name, :input_html => { :id => 'specific_id' }
286
+ end
287
+ assert_select 'input.default_class#specific_id'
288
+ end
289
+
290
+ test 'builder should receive a default argument and pass it to the inputs without changing the defaults' do
291
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class', :id => 'default_id' } } do |f|
292
+ concat(f.input :name)
293
+ concat(f.input :credit_limit)
294
+ end
295
+
296
+ assert_select "input.string.default_class[name='user[name]']"
297
+ assert_no_select "input.string[name='user[credit_limit]']"
298
+ end
299
+
300
+ # WITHOUT OBJECT
301
+ test 'builder should generate properly when object is not present' do
302
+ with_form_for :project, :name
303
+ assert_select 'form input.string#project_name'
304
+ end
305
+
306
+ test 'builder should generate password fields based on attribute name when object is not present' do
307
+ with_form_for :project, :password_confirmation
308
+ assert_select 'form input[type=password].password#project_password_confirmation'
309
+ end
310
+
311
+ test 'builder should generate text fields by default for all attributes when object is not present' do
312
+ with_form_for :project, :created_at
313
+ assert_select 'form input.string#project_created_at'
314
+ with_form_for :project, :budget
315
+ assert_select 'form input.string#project_budget'
316
+ end
317
+
318
+ test 'builder should allow overriding input type when object is not present' do
319
+ with_form_for :project, :created_at, :as => :datetime
320
+ assert_select 'form select.datetime#project_created_at_1i'
321
+ with_form_for :project, :budget, :as => :decimal
322
+ assert_select 'form input.decimal#project_budget'
323
+ end
324
+
325
+ # CUSTOM FORM BUILDER
326
+ test 'custom builder should inherit mappings' do
327
+ with_custom_form_for @user, :email
328
+ assert_select 'form input[type=email]#user_email.custom'
329
+ end
330
+
331
+ test 'form with CustomMapTypeFormBuilder should use custom map type builder' do
332
+ with_concat_custom_mapping_form_for(:user) do |user|
333
+ assert user.instance_of?(CustomMapTypeFormBuilder)
334
+ end
335
+ end
336
+
337
+ test 'form with CustomMapTypeFormBuilder should use custom mapping' do
338
+ with_concat_custom_mapping_form_for(:user) do |user|
339
+ assert_equal SimpleForm::Inputs::StringInput, user.class.mappings[:custom_type]
340
+ end
341
+ end
342
+
343
+ test 'form without CustomMapTypeFormBuilder should not use custom mapping' do
344
+ with_concat_form_for(:user) do |user|
345
+ assert_nil user.class.mappings[:custom_type]
346
+ end
347
+ end
348
+ end