ehoch_simple_form 2.0.2.dev

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/CHANGELOG.md +257 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +797 -0
  4. data/lib/generators/simple_form/USAGE +3 -0
  5. data/lib/generators/simple_form/install_generator.rb +32 -0
  6. data/lib/generators/simple_form/templates/README +12 -0
  7. data/lib/generators/simple_form/templates/_form.html.erb +13 -0
  8. data/lib/generators/simple_form/templates/_form.html.haml +10 -0
  9. data/lib/generators/simple_form/templates/_form.html.slim +10 -0
  10. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb.tt +181 -0
  11. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +26 -0
  12. data/lib/simple_form.rb +215 -0
  13. data/lib/simple_form/action_view_extensions/builder.rb +338 -0
  14. data/lib/simple_form/action_view_extensions/form_helper.rb +74 -0
  15. data/lib/simple_form/components.rb +20 -0
  16. data/lib/simple_form/components/errors.rb +35 -0
  17. data/lib/simple_form/components/hints.rb +18 -0
  18. data/lib/simple_form/components/html5.rb +26 -0
  19. data/lib/simple_form/components/label_input.rb +15 -0
  20. data/lib/simple_form/components/labels.rb +79 -0
  21. data/lib/simple_form/components/maxlength.rb +41 -0
  22. data/lib/simple_form/components/min_max.rb +50 -0
  23. data/lib/simple_form/components/pattern.rb +34 -0
  24. data/lib/simple_form/components/placeholders.rb +16 -0
  25. data/lib/simple_form/components/readonly.rb +22 -0
  26. data/lib/simple_form/core_ext/hash.rb +16 -0
  27. data/lib/simple_form/error_notification.rb +48 -0
  28. data/lib/simple_form/form_builder.rb +472 -0
  29. data/lib/simple_form/helpers.rb +12 -0
  30. data/lib/simple_form/helpers/autofocus.rb +11 -0
  31. data/lib/simple_form/helpers/disabled.rb +15 -0
  32. data/lib/simple_form/helpers/readonly.rb +15 -0
  33. data/lib/simple_form/helpers/required.rb +35 -0
  34. data/lib/simple_form/helpers/validators.rb +44 -0
  35. data/lib/simple_form/i18n_cache.rb +22 -0
  36. data/lib/simple_form/inputs.rb +21 -0
  37. data/lib/simple_form/inputs/base.rb +162 -0
  38. data/lib/simple_form/inputs/block_input.rb +14 -0
  39. data/lib/simple_form/inputs/boolean_input.rb +64 -0
  40. data/lib/simple_form/inputs/collection_check_boxes_input.rb +21 -0
  41. data/lib/simple_form/inputs/collection_input.rb +101 -0
  42. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +63 -0
  43. data/lib/simple_form/inputs/collection_select_input.rb +14 -0
  44. data/lib/simple_form/inputs/date_time_input.rb +28 -0
  45. data/lib/simple_form/inputs/file_input.rb +9 -0
  46. data/lib/simple_form/inputs/grouped_collection_select_input.rb +41 -0
  47. data/lib/simple_form/inputs/hidden_input.rb +17 -0
  48. data/lib/simple_form/inputs/numeric_input.rb +24 -0
  49. data/lib/simple_form/inputs/password_input.rb +12 -0
  50. data/lib/simple_form/inputs/priority_input.rb +24 -0
  51. data/lib/simple_form/inputs/range_input.rb +14 -0
  52. data/lib/simple_form/inputs/string_input.rb +23 -0
  53. data/lib/simple_form/inputs/text_input.rb +11 -0
  54. data/lib/simple_form/map_type.rb +16 -0
  55. data/lib/simple_form/version.rb +3 -0
  56. data/lib/simple_form/wrappers.rb +8 -0
  57. data/lib/simple_form/wrappers/builder.rb +103 -0
  58. data/lib/simple_form/wrappers/many.rb +69 -0
  59. data/lib/simple_form/wrappers/root.rb +34 -0
  60. data/lib/simple_form/wrappers/single.rb +18 -0
  61. data/test/action_view_extensions/builder_test.rb +577 -0
  62. data/test/action_view_extensions/form_helper_test.rb +104 -0
  63. data/test/components/label_test.rb +310 -0
  64. data/test/form_builder/association_test.rb +177 -0
  65. data/test/form_builder/button_test.rb +47 -0
  66. data/test/form_builder/error_notification_test.rb +79 -0
  67. data/test/form_builder/error_test.rb +121 -0
  68. data/test/form_builder/general_test.rb +356 -0
  69. data/test/form_builder/hint_test.rb +139 -0
  70. data/test/form_builder/input_field_test.rb +63 -0
  71. data/test/form_builder/label_test.rb +71 -0
  72. data/test/form_builder/wrapper_test.rb +149 -0
  73. data/test/generators/simple_form_generator_test.rb +32 -0
  74. data/test/inputs/boolean_input_test.rb +108 -0
  75. data/test/inputs/collection_check_boxes_input_test.rb +224 -0
  76. data/test/inputs/collection_radio_buttons_input_test.rb +326 -0
  77. data/test/inputs/collection_select_input_test.rb +241 -0
  78. data/test/inputs/datetime_input_test.rb +99 -0
  79. data/test/inputs/disabled_test.rb +38 -0
  80. data/test/inputs/discovery_test.rb +61 -0
  81. data/test/inputs/file_input_test.rb +16 -0
  82. data/test/inputs/general_test.rb +69 -0
  83. data/test/inputs/grouped_collection_select_input_test.rb +118 -0
  84. data/test/inputs/hidden_input_test.rb +30 -0
  85. data/test/inputs/numeric_input_test.rb +173 -0
  86. data/test/inputs/priority_input_test.rb +43 -0
  87. data/test/inputs/readonly_test.rb +61 -0
  88. data/test/inputs/required_test.rb +113 -0
  89. data/test/inputs/string_input_test.rb +140 -0
  90. data/test/inputs/text_input_test.rb +24 -0
  91. data/test/simple_form_test.rb +9 -0
  92. data/test/support/discovery_inputs.rb +21 -0
  93. data/test/support/misc_helpers.rb +102 -0
  94. data/test/support/mock_controller.rb +24 -0
  95. data/test/support/models.rb +210 -0
  96. data/test/test_helper.rb +90 -0
  97. metadata +210 -0
@@ -0,0 +1,47 @@
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 with options' do
17
+ with_button_for :post, :submit, :class => 'my_button'
18
+ assert_select 'form input.button.my_button[type=submit][value=Save Post]'
19
+ end
20
+
21
+ test 'builder should not modify the options hash' do
22
+ options = { :class => 'my_button' }
23
+ with_button_for :post, :submit, options
24
+ assert_select 'form input.button.my_button[type=submit][value=Save Post]'
25
+ assert_equal({ :class => 'my_button' }, options)
26
+ end
27
+
28
+ test 'builder should create buttons for records' do
29
+ @user.new_record!
30
+ with_button_for @user, :submit
31
+ assert_select 'form input.button[type=submit][value=Create User]'
32
+ end
33
+
34
+ test "builder should use the default class from the configuration" do
35
+ swap SimpleForm, :button_class => 'btn' do
36
+ with_button_for :post, :submit
37
+ assert_select 'form input.btn[type=submit][value=Save Post]'
38
+ end
39
+ end
40
+
41
+ if ActionView::Helpers::FormBuilder.method_defined?(:button)
42
+ test "allows to use Rails button helper when available" do
43
+ with_button_for :post, :button, 'Save!'
44
+ assert_select 'form button.button[type=submit]', 'Save!'
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,79 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ # Tests for f.error_notification
5
+ class ErrorNotificationTest < ActionView::TestCase
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
+
15
+ with_error_notification_for @validating_user
16
+ assert_no_select 'p.error_notification'
17
+ end
18
+
19
+ test 'error notification is not generated for forms without objects' do
20
+ with_error_notification_for :user
21
+ assert_no_select 'p.error_notification'
22
+ end
23
+
24
+ test 'error notification is generated when the object has some error' do
25
+ with_error_notification_for @user
26
+ assert_select 'p.error_notification', 'Some errors were found, please take a look:'
27
+ end
28
+
29
+ test 'error notification uses I18n based on model to generate the notification message' do
30
+ store_translations(:en, :simple_form => { :error_notification => { :user =>
31
+ 'Alguns erros foram encontrados para o usuário:'
32
+ } }) do
33
+ with_error_notification_for @user
34
+ assert_select 'p.error_notification', 'Alguns erros foram encontrados para o usuário:'
35
+ end
36
+ end
37
+
38
+ test 'error notification uses I18n fallbacking to default message' do
39
+ store_translations(:en, :simple_form => { :error_notification => {
40
+ :default_message => 'Opa! Alguns erros foram encontrados, poderia verificar?'
41
+ } }) do
42
+ with_error_notification_for @user
43
+ assert_select 'p.error_notification', 'Opa! Alguns erros foram encontrados, poderia verificar?'
44
+ end
45
+ end
46
+
47
+ test 'error notification allows passing the notification message' do
48
+ with_error_notification_for @user, :message => 'Erro encontrado ao criar usuario'
49
+ assert_select 'p.error_notification', 'Erro encontrado ao criar usuario'
50
+ end
51
+
52
+ test 'error notification accepts other html options' do
53
+ with_error_notification_for @user, :id => 'user_error_message', :class => 'form_error'
54
+ assert_select 'p#user_error_message.form_error.error_notification'
55
+ end
56
+
57
+ test 'error notification allows configuring the wrapper element' do
58
+ swap SimpleForm, :error_notification_tag => :div do
59
+ with_error_notification_for @user
60
+ assert_select 'div.error_notification'
61
+ end
62
+ end
63
+
64
+ test 'error notification can contain HTML tags' do
65
+ with_error_notification_for @user, :message => 'Erro encontrado ao criar <b>usuário</b>'
66
+ assert_select 'p.error_notification', 'Erro encontrado ao criar usuário'
67
+ assert_select 'p.error_notification b', 'usuário'
68
+ end
69
+
70
+ test 'error notification uses I18n based on model to generate the notification message and accepts HTML' do
71
+ store_translations(:en, :simple_form => { :error_notification => { :user =>
72
+ 'Alguns erros foram encontrados para o <b>usuário</b>:'
73
+ } }) do
74
+ with_error_notification_for @user
75
+ assert_select 'p.error_notification', 'Alguns erros foram encontrados para o usuário:'
76
+ assert_select 'p.error_notification b', 'usuário'
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,121 @@
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 not modify the options hash' do
58
+ options = { :id => 'error', :class => 'yay' }
59
+ with_error_for @user, :name, options
60
+ assert_select 'span#error.error.yay'
61
+ assert_equal({ :id => 'error', :class => 'yay' }, options)
62
+ end
63
+
64
+ test 'error should find errors on attribute and association' do
65
+ with_error_for @user, :company_id, :as => :select,
66
+ :error_method => :to_sentence, :reflection => Association.new(Company, :company, {})
67
+ assert_select 'span.error', 'must be valid and company must be present'
68
+ end
69
+
70
+ test 'error should generate an error tag with a clean HTML' do
71
+ with_error_for @user, :name
72
+ assert_no_select 'span.error[error_html]'
73
+ end
74
+
75
+ test 'error should generate an error tag with a clean HTML when errors options are present' do
76
+ with_error_for @user, :name, :error_tag => :p, :error_prefix => 'Name', :error_method => :first
77
+ assert_no_select 'p.error[error_html]'
78
+ assert_no_select 'p.error[error_tag]'
79
+ assert_no_select 'p.error[error_prefix]'
80
+ assert_no_select 'p.error[error_method]'
81
+ end
82
+
83
+ test 'error should generate an error message with raw HTML tags' do
84
+ with_error_for @user, :name, :error_prefix => '<b>Name</b>'
85
+ assert_select 'span.error', "Name can't be blank"
86
+ assert_select 'span.error b', "Name"
87
+ end
88
+
89
+ # FULL ERRORS
90
+
91
+ test 'full error should generate an full error tag for the attribute' do
92
+ with_full_error_for @user, :name
93
+ assert_select 'span.error', "Super User Name! can't be blank"
94
+ end
95
+
96
+ test 'full error should generate an full error tag with a clean HTML' do
97
+ with_full_error_for @user, :name
98
+ assert_no_select 'span.error[error_html]'
99
+ end
100
+
101
+ test 'full error should allow passing options to full error tag' do
102
+ with_full_error_for @user, :name, :id => 'name_error', :error_prefix => "Your name"
103
+ assert_select 'span.error#name_error', "Your name can't be blank"
104
+ end
105
+
106
+ test 'full error should not modify the options hash' do
107
+ options = { :id => 'name_error' }
108
+ with_full_error_for @user, :name, options
109
+ assert_select 'span.error#name_error', "Super User Name! can't be blank"
110
+ assert_equal({ :id => 'name_error' }, options)
111
+ end
112
+
113
+ # CUSTOM WRAPPERS
114
+
115
+ test 'error with custom wrappers works' do
116
+ swap_wrapper do
117
+ with_error_for @user, :name
118
+ assert_select 'span.omg_error', "can't be blank"
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,356 @@
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 to skip input_type class' do
42
+ swap SimpleForm, :generate_additional_classes_for => [:label, :wrapper] do
43
+ with_form_for @user, :post_count
44
+ assert_no_select "form input#user_post_count.integer"
45
+ assert_select "form input#user_post_count"
46
+ end
47
+ end
48
+
49
+ test 'builder should allow adding custom input mappings for integer input types' do
50
+ swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
51
+ with_form_for @user, :lock_version
52
+ assert_no_select 'form input#user_lock_version.integer'
53
+ assert_select 'form input#user_lock_version.hidden'
54
+ end
55
+ end
56
+
57
+ test 'builder uses the first matching custom input map when more than one matches' do
58
+ swap SimpleForm, :input_mappings => { /count$/ => :integer, /^post_/ => :password } do
59
+ with_form_for @user, :post_count
60
+ assert_no_select 'form input#user_post_count.password'
61
+ assert_select 'form input#user_post_count.numeric.integer'
62
+ end
63
+ end
64
+
65
+ test 'builder uses the custom map only for matched attributes' do
66
+ swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
67
+ with_form_for @user, :post_count
68
+ assert_no_select 'form input#user_post_count.hidden'
69
+ assert_select 'form input#user_post_count.string'
70
+ end
71
+ end
72
+
73
+ # INPUT TYPES
74
+ test 'builder should generate text fields for string columns' do
75
+ with_form_for @user, :name
76
+ assert_select 'form input#user_name.string'
77
+ end
78
+
79
+ test 'builder should generate text areas for text columns' do
80
+ with_form_for @user, :description
81
+ assert_select 'form textarea#user_description.text'
82
+ end
83
+
84
+ test 'builder should generate a checkbox for boolean columns' do
85
+ with_form_for @user, :active
86
+ assert_select 'form input[type=checkbox]#user_active.boolean'
87
+ end
88
+
89
+ test 'builder should use integer text field for integer columns' do
90
+ with_form_for @user, :age
91
+ assert_select 'form input#user_age.numeric.integer'
92
+ end
93
+
94
+ test 'builder should generate decimal text field for decimal columns' do
95
+ with_form_for @user, :credit_limit
96
+ assert_select 'form input#user_credit_limit.numeric.decimal'
97
+ end
98
+
99
+ test 'builder should generate password fields for columns that matches password' do
100
+ with_form_for @user, :password
101
+ assert_select 'form input#user_password.password'
102
+ end
103
+
104
+ test 'builder should generate country fields for columns that matches country' do
105
+ with_form_for @user, :residence_country
106
+ assert_select 'form select#user_residence_country.country'
107
+ end
108
+
109
+ test 'builder should generate time_zone fields for columns that matches time_zone' do
110
+ with_form_for @user, :time_zone
111
+ assert_select 'form select#user_time_zone.time_zone'
112
+ end
113
+
114
+ test 'builder should generate email fields for columns that matches email' do
115
+ with_form_for @user, :email
116
+ assert_select 'form input#user_email.string.email'
117
+ end
118
+
119
+ test 'builder should generate tel fields for columns that matches phone' do
120
+ with_form_for @user, :phone_number
121
+ assert_select 'form input#user_phone_number.string.tel'
122
+ end
123
+
124
+ test 'builder should generate url fields for columns that matches url' do
125
+ with_form_for @user, :url
126
+ assert_select 'form input#user_url.string.url'
127
+ end
128
+
129
+ test 'builder should generate date select for date columns' do
130
+ with_form_for @user, :born_at
131
+ assert_select 'form select#user_born_at_1i.date'
132
+ end
133
+
134
+ test 'builder should generate time select for time columns' do
135
+ with_form_for @user, :delivery_time
136
+ assert_select 'form select#user_delivery_time_4i.time'
137
+ end
138
+
139
+ test 'builder should generate datetime select for datetime columns' do
140
+ with_form_for @user, :created_at
141
+ assert_select 'form select#user_created_at_1i.datetime'
142
+ end
143
+
144
+ test 'builder should generate datetime select for timestamp columns' do
145
+ with_form_for @user, :updated_at
146
+ assert_select 'form select#user_updated_at_1i.datetime'
147
+ end
148
+
149
+ test 'builder should generate file for file columns' do
150
+ @user.avatar = mock("file")
151
+ @user.avatar.expects(:respond_to?).with(:mounted_as).returns(false)
152
+ @user.avatar.expects(:respond_to?).with(:file?).returns(false)
153
+ @user.avatar.expects(:respond_to?).with(:public_filename).returns(true)
154
+
155
+ with_form_for @user, :avatar
156
+ assert_select 'form input#user_avatar.file'
157
+ end
158
+
159
+ test 'builder should generate file for attributes that are real db columns but have file methods' do
160
+ @user.home_picture = mock("file")
161
+ @user.home_picture.expects(:respond_to?).with(:mounted_as).returns(true)
162
+
163
+ with_form_for @user, :home_picture
164
+ assert_select 'form input#user_home_picture.file'
165
+ end
166
+
167
+ test 'build should generate select if a collection is given' do
168
+ with_form_for @user, :age, :collection => 1..60
169
+ assert_select 'form select#user_age.select'
170
+ end
171
+
172
+ test 'builder should allow overriding default input type for text' do
173
+ with_form_for @user, :name, :as => :text
174
+ assert_no_select 'form input#user_name'
175
+ assert_select 'form textarea#user_name.text'
176
+
177
+ with_form_for @user, :active, :as => :radio_buttons
178
+ assert_no_select 'form input[type=checkbox]'
179
+ assert_select 'form input.radio_buttons[type=radio]', :count => 2
180
+
181
+ with_form_for @user, :born_at, :as => :string
182
+ assert_no_select 'form select'
183
+ assert_select 'form input#user_born_at.string'
184
+ end
185
+
186
+ # COMMON OPTIONS
187
+ test 'builder should add chosen form class' do
188
+ swap SimpleForm, :form_class => :my_custom_class do
189
+ with_form_for @user, :name
190
+ assert_select 'form.my_custom_class'
191
+ end
192
+ end
193
+
194
+ test 'builder should allow passing options to input' do
195
+ with_form_for @user, :name, :input_html => { :class => 'my_input', :id => 'my_input' }
196
+ assert_select 'form input#my_input.my_input.string'
197
+ end
198
+
199
+ test 'builder should not propagate input options to wrapper' do
200
+ with_form_for @user, :name, :input_html => { :class => 'my_input', :id => 'my_input' }
201
+ assert_no_select 'form div.input.my_input.string'
202
+ assert_select 'form input#my_input.my_input.string'
203
+ end
204
+
205
+ test 'builder should generate a input with label' do
206
+ with_form_for @user, :name
207
+ assert_select 'form label.string[for=user_name]', /Name/
208
+ end
209
+
210
+ test 'builder should be able to disable the label for a input' do
211
+ with_form_for @user, :name, :label => false
212
+ assert_no_select 'form label'
213
+ end
214
+
215
+ test 'builder should use custom label' do
216
+ with_form_for @user, :name, :label => 'Yay!'
217
+ assert_select 'form label', /Yay!/
218
+ end
219
+
220
+ test 'builder should pass options to label' do
221
+ with_form_for @user, :name, :label_html => { :id => "cool" }
222
+ assert_select 'form label#cool', /Name/
223
+ end
224
+
225
+ test 'builder should not generate hints for a input' do
226
+ with_form_for @user, :name
227
+ assert_no_select 'span.hint'
228
+ end
229
+
230
+ test 'builder should be able to add a hint for a input' do
231
+ with_form_for @user, :name, :hint => 'test'
232
+ assert_select 'span.hint', 'test'
233
+ end
234
+
235
+ test 'builder should be able to disable a hint even if it exists in i18n' do
236
+ store_translations(:en, :simple_form => { :hints => { :name => 'Hint test' } }) do
237
+ with_form_for @user, :name, :hint => false
238
+ assert_no_select 'span.hint'
239
+ end
240
+ end
241
+
242
+ test 'builder should pass options to hint' do
243
+ with_form_for @user, :name, :hint => 'test', :hint_html => { :id => "cool" }
244
+ assert_select 'span.hint#cool', 'test'
245
+ end
246
+
247
+ test 'builder should generate errors for attribute without errors' do
248
+ with_form_for @user, :credit_limit
249
+ assert_no_select 'span.errors'
250
+ end
251
+
252
+ test 'builder should generate errors for attribute with errors' do
253
+ with_form_for @user, :name
254
+ assert_select 'span.error', "can't be blank"
255
+ end
256
+
257
+ test 'builder should be able to disable showing errors for a input' do
258
+ with_form_for @user, :name, :error => false
259
+ assert_no_select 'span.error'
260
+ end
261
+
262
+ test 'builder should pass options to errors' do
263
+ with_form_for @user, :name, :error_html => { :id => "cool" }
264
+ assert_select 'span.error#cool', "can't be blank"
265
+ end
266
+
267
+ test 'placeholder should not be generated when set to false' do
268
+ store_translations(:en, :simple_form => { :placeholders => { :user => {
269
+ :name => 'Name goes here'
270
+ } } }) do
271
+ with_form_for @user, :name, :placeholder => false
272
+ assert_no_select 'input[placeholder]'
273
+ end
274
+ end
275
+
276
+ # DEFAULT OPTIONS
277
+ test 'builder should receive a default argument and pass it to the inputs' do
278
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class' } } do |f|
279
+ f.input :name
280
+ end
281
+ assert_select 'input.default_class'
282
+ end
283
+
284
+ test 'builder should receive a default argument and pass it to the inputs, respecting the specific options' do
285
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class' } } do |f|
286
+ f.input :name, :input_html => { :id => 'specific_id' }
287
+ end
288
+ assert_select 'input.default_class#specific_id'
289
+ end
290
+
291
+ test 'builder should receive a default argument and pass it to the inputs, overwriting the defaults with specific options' do
292
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class', :id => 'default_id' } } do |f|
293
+ f.input :name, :input_html => { :id => 'specific_id' }
294
+ end
295
+ assert_select 'input.default_class#specific_id'
296
+ end
297
+
298
+ test 'builder should receive a default argument and pass it to the inputs without changing the defaults' do
299
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class', :id => 'default_id' } } do |f|
300
+ concat(f.input :name)
301
+ concat(f.input :credit_limit)
302
+ end
303
+
304
+ assert_select "input.string.default_class[name='user[name]']"
305
+ assert_no_select "input.string[name='user[credit_limit]']"
306
+ end
307
+
308
+ # WITHOUT OBJECT
309
+ test 'builder should generate properly when object is not present' do
310
+ with_form_for :project, :name
311
+ assert_select 'form input.string#project_name'
312
+ end
313
+
314
+ test 'builder should generate password fields based on attribute name when object is not present' do
315
+ with_form_for :project, :password_confirmation
316
+ assert_select 'form input[type=password].password#project_password_confirmation'
317
+ end
318
+
319
+ test 'builder should generate text fields by default for all attributes when object is not present' do
320
+ with_form_for :project, :created_at
321
+ assert_select 'form input.string#project_created_at'
322
+ with_form_for :project, :budget
323
+ assert_select 'form input.string#project_budget'
324
+ end
325
+
326
+ test 'builder should allow overriding input type when object is not present' do
327
+ with_form_for :project, :created_at, :as => :datetime
328
+ assert_select 'form select.datetime#project_created_at_1i'
329
+ with_form_for :project, :budget, :as => :decimal
330
+ assert_select 'form input.decimal#project_budget'
331
+ end
332
+
333
+ # CUSTOM FORM BUILDER
334
+ test 'custom builder should inherit mappings' do
335
+ with_custom_form_for @user, :email
336
+ assert_select 'form input[type=email]#user_email.custom'
337
+ end
338
+
339
+ test 'form with CustomMapTypeFormBuilder should use custom map type builder' do
340
+ with_concat_custom_mapping_form_for(:user) do |user|
341
+ assert user.instance_of?(CustomMapTypeFormBuilder)
342
+ end
343
+ end
344
+
345
+ test 'form with CustomMapTypeFormBuilder should use custom mapping' do
346
+ with_concat_custom_mapping_form_for(:user) do |user|
347
+ assert_equal SimpleForm::Inputs::StringInput, user.class.mappings[:custom_type]
348
+ end
349
+ end
350
+
351
+ test 'form without CustomMapTypeFormBuilder should not use custom mapping' do
352
+ with_concat_form_for(:user) do |user|
353
+ assert_nil user.class.mappings[:custom_type]
354
+ end
355
+ end
356
+ end