simple_form_awesome 2.2.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 (103) hide show
  1. data/CHANGELOG.md +327 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +25 -0
  4. data/lib/generators/simple_form/USAGE +3 -0
  5. data/lib/generators/simple_form/install_generator.rb +48 -0
  6. data/lib/generators/simple_form/templates/AUI_README +19 -0
  7. data/lib/generators/simple_form/templates/README +12 -0
  8. data/lib/generators/simple_form/templates/_form.html.erb +13 -0
  9. data/lib/generators/simple_form/templates/_form.html.haml +10 -0
  10. data/lib/generators/simple_form/templates/_form.html.slim +10 -0
  11. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +142 -0
  12. data/lib/generators/simple_form/templates/config/initializers/simple_form_aui.rb +21 -0
  13. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +45 -0
  14. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +26 -0
  15. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +26 -0
  16. data/lib/simple_form/action_view_extensions/builder.rb +340 -0
  17. data/lib/simple_form/action_view_extensions/form_helper.rb +72 -0
  18. data/lib/simple_form/components/errors.rb +35 -0
  19. data/lib/simple_form/components/hints.rb +18 -0
  20. data/lib/simple_form/components/html5.rb +26 -0
  21. data/lib/simple_form/components/label_input.rb +15 -0
  22. data/lib/simple_form/components/labels.rb +79 -0
  23. data/lib/simple_form/components/maxlength.rb +41 -0
  24. data/lib/simple_form/components/min_max.rb +50 -0
  25. data/lib/simple_form/components/pattern.rb +34 -0
  26. data/lib/simple_form/components/placeholders.rb +16 -0
  27. data/lib/simple_form/components/readonly.rb +22 -0
  28. data/lib/simple_form/components.rb +20 -0
  29. data/lib/simple_form/core_ext/hash.rb +16 -0
  30. data/lib/simple_form/error_notification.rb +48 -0
  31. data/lib/simple_form/form_builder.rb +482 -0
  32. data/lib/simple_form/helpers/autofocus.rb +11 -0
  33. data/lib/simple_form/helpers/disabled.rb +15 -0
  34. data/lib/simple_form/helpers/readonly.rb +15 -0
  35. data/lib/simple_form/helpers/required.rb +35 -0
  36. data/lib/simple_form/helpers/validators.rb +44 -0
  37. data/lib/simple_form/helpers.rb +12 -0
  38. data/lib/simple_form/i18n_cache.rb +22 -0
  39. data/lib/simple_form/inputs/aui_string_input.rb +10 -0
  40. data/lib/simple_form/inputs/base.rb +184 -0
  41. data/lib/simple_form/inputs/block_input.rb +14 -0
  42. data/lib/simple_form/inputs/boolean_input.rb +78 -0
  43. data/lib/simple_form/inputs/collection_check_boxes_input.rb +21 -0
  44. data/lib/simple_form/inputs/collection_input.rb +101 -0
  45. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +63 -0
  46. data/lib/simple_form/inputs/collection_select_input.rb +14 -0
  47. data/lib/simple_form/inputs/date_time_input.rb +28 -0
  48. data/lib/simple_form/inputs/file_input.rb +9 -0
  49. data/lib/simple_form/inputs/grouped_collection_select_input.rb +41 -0
  50. data/lib/simple_form/inputs/hidden_input.rb +17 -0
  51. data/lib/simple_form/inputs/numeric_input.rb +24 -0
  52. data/lib/simple_form/inputs/password_input.rb +12 -0
  53. data/lib/simple_form/inputs/priority_input.rb +24 -0
  54. data/lib/simple_form/inputs/range_input.rb +14 -0
  55. data/lib/simple_form/inputs/string_input.rb +23 -0
  56. data/lib/simple_form/inputs/text_area_input.rb +12 -0
  57. data/lib/simple_form/inputs/text_input.rb +11 -0
  58. data/lib/simple_form/inputs.rb +23 -0
  59. data/lib/simple_form/map_type.rb +16 -0
  60. data/lib/simple_form/version.rb +3 -0
  61. data/lib/simple_form/wrappers/builder.rb +103 -0
  62. data/lib/simple_form/wrappers/many.rb +73 -0
  63. data/lib/simple_form/wrappers/root.rb +36 -0
  64. data/lib/simple_form/wrappers/single.rb +24 -0
  65. data/lib/simple_form/wrappers.rb +8 -0
  66. data/lib/simple_form.rb +221 -0
  67. data/test/action_view_extensions/builder_test.rb +583 -0
  68. data/test/action_view_extensions/form_helper_test.rb +143 -0
  69. data/test/components/label_test.rb +327 -0
  70. data/test/form_builder/association_test.rb +186 -0
  71. data/test/form_builder/button_test.rb +47 -0
  72. data/test/form_builder/error_notification_test.rb +79 -0
  73. data/test/form_builder/error_test.rb +121 -0
  74. data/test/form_builder/general_test.rb +402 -0
  75. data/test/form_builder/hint_test.rb +138 -0
  76. data/test/form_builder/input_field_test.rb +63 -0
  77. data/test/form_builder/label_test.rb +71 -0
  78. data/test/form_builder/wrapper_test.rb +203 -0
  79. data/test/generators/simple_form_generator_test.rb +42 -0
  80. data/test/inputs/boolean_input_test.rb +140 -0
  81. data/test/inputs/collection_check_boxes_input_test.rb +224 -0
  82. data/test/inputs/collection_radio_buttons_input_test.rb +326 -0
  83. data/test/inputs/collection_select_input_test.rb +241 -0
  84. data/test/inputs/datetime_input_test.rb +99 -0
  85. data/test/inputs/disabled_test.rb +78 -0
  86. data/test/inputs/discovery_test.rb +69 -0
  87. data/test/inputs/file_input_test.rb +16 -0
  88. data/test/inputs/general_test.rb +116 -0
  89. data/test/inputs/grouped_collection_select_input_test.rb +118 -0
  90. data/test/inputs/hidden_input_test.rb +30 -0
  91. data/test/inputs/numeric_input_test.rb +173 -0
  92. data/test/inputs/priority_input_test.rb +43 -0
  93. data/test/inputs/readonly_test.rb +101 -0
  94. data/test/inputs/required_test.rb +113 -0
  95. data/test/inputs/string_input_test.rb +146 -0
  96. data/test/inputs/text_input_test.rb +24 -0
  97. data/test/simple_form_test.rb +9 -0
  98. data/test/support/discovery_inputs.rb +27 -0
  99. data/test/support/misc_helpers.rb +138 -0
  100. data/test/support/mock_controller.rb +24 -0
  101. data/test/support/models.rb +216 -0
  102. data/test/test_helper.rb +95 -0
  103. metadata +217 -0
@@ -0,0 +1,143 @@
1
+ require 'test_helper'
2
+
3
+ class FormHelperTest < ActionView::TestCase
4
+
5
+ test 'SimpleForm for yields an instance of FormBuilder' do
6
+ simple_form_for :user do |f|
7
+ assert f.instance_of?(SimpleForm::FormBuilder)
8
+ end
9
+ end
10
+
11
+ test 'SimpleForm should add default class to form' do
12
+ with_concat_form_for(:user)
13
+ assert_select 'form.simple_form'
14
+ end
15
+
16
+ test 'SimpleForm should use default browser validations by default' do
17
+ with_concat_form_for(:user)
18
+ assert_no_select 'form[novalidate]'
19
+ end
20
+
21
+ test 'SimpleForm should not use default browser validations if specified in the configuration options' do
22
+ swap SimpleForm, :browser_validations => false do
23
+ with_concat_form_for(:user)
24
+ assert_select 'form[novalidate="novalidate"]'
25
+ end
26
+ end
27
+
28
+ test 'a form specific disabled validation option should override the default enabled browser validation configuration option' do
29
+ with_concat_form_for(:user, :html => { :novalidate => true })
30
+ assert_select 'form[novalidate="novalidate"]'
31
+ end
32
+
33
+ test 'a form specific enabled validation option should override the disabled browser validation configuration option' do
34
+ swap SimpleForm, :browser_validations => false do
35
+ with_concat_form_for(:user, :html => { :novalidate => false })
36
+ assert_no_select 'form[novalidate]'
37
+ end
38
+ end
39
+
40
+ test 'SimpleForm should add object name as css class to form when object is not present' do
41
+ with_concat_form_for(:user, :html => { :novalidate => true })
42
+ assert_select 'form.simple_form.user'
43
+ end
44
+
45
+ test 'SimpleForm should add :as option as css class to form when object is not present' do
46
+ with_concat_form_for(:user, :as => 'superuser')
47
+ assert_select 'form.simple_form.superuser'
48
+ end
49
+
50
+ test 'SimpleForm should add object class name with new prefix as css class to form if record is not persisted' do
51
+ @user.new_record!
52
+ with_concat_form_for(@user)
53
+ assert_select 'form.simple_form.new_user'
54
+ end
55
+
56
+ test 'SimpleForm should add :as option with new prefix as css class to form if record is not persisted' do
57
+ @user.new_record!
58
+ with_concat_form_for(@user, :as => 'superuser')
59
+ assert_select 'form.simple_form.new_superuser'
60
+ end
61
+
62
+ test 'SimpleForm should add edit class prefix as css class to form if record is persisted' do
63
+ with_concat_form_for(@user)
64
+ assert_select 'form.simple_form.edit_user'
65
+ end
66
+
67
+ test 'SimpleForm should add :as options with edit prefix as css class to form if record is persisted' do
68
+ with_concat_form_for(@user, :as => 'superuser')
69
+ assert_select 'form.simple_form.edit_superuser'
70
+ end
71
+
72
+ test 'SimpleForm should add last object name as css class to form when there is array of objects' do
73
+ with_concat_form_for([Company.new, @user])
74
+ assert_select 'form.simple_form.edit_user'
75
+ end
76
+
77
+ test 'SimpleForm should not add object class to form if css_class is specified' do
78
+ with_concat_form_for(:user, :html => {:class => nil})
79
+ assert_no_select 'form.user'
80
+ end
81
+
82
+ test 'SimpleForm should add custom class to form if css_class is specified' do
83
+ with_concat_form_for(:user, :html => {:class => 'my_class'})
84
+ assert_select 'form.my_class'
85
+ end
86
+
87
+ test 'pass options to SimpleForm' do
88
+ with_concat_form_for(:user, :url => '/account', :html => { :id => 'my_form' })
89
+ assert_select 'form#my_form'
90
+ assert_select 'form[action=/account]'
91
+ end
92
+
93
+ test 'fields for yields an instance of FormBuilder' do
94
+ with_concat_form_for(:user) do |f|
95
+ assert f.instance_of?(SimpleForm::FormBuilder)
96
+ end
97
+ end
98
+
99
+ test 'fields for with a hash like model yeilds an instance of FormBuilder' do
100
+ with_concat_fields_for(:author, HashBackedAuthor.new) do |f|
101
+ assert f.instance_of?(SimpleForm::FormBuilder)
102
+ f.input :name
103
+ end
104
+
105
+ assert_select "input[name='author[name]'][value='hash backed author']"
106
+ end
107
+
108
+ test 'custom error proc is not destructive' do
109
+ swap_field_error_proc do
110
+ result = nil
111
+ simple_form_for :user do |f|
112
+ result = simple_fields_for 'address' do
113
+ 'hello'
114
+ end
115
+ end
116
+
117
+ assert_equal 'hello', result
118
+ end
119
+ end
120
+
121
+ test 'custom error proc survives an exception' do
122
+ swap_field_error_proc do
123
+ begin
124
+ simple_form_for :user do |f|
125
+ simple_fields_for 'address' do
126
+ raise 'an exception'
127
+ end
128
+ end
129
+ rescue StandardError
130
+ end
131
+ end
132
+ end
133
+
134
+ private
135
+
136
+ def swap_field_error_proc(expected_error_proc = lambda {})
137
+ swap ActionView::Base, :field_error_proc => expected_error_proc do
138
+ yield
139
+
140
+ assert_equal expected_error_proc, ActionView::Base.field_error_proc
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,327 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ # Isolated tests for label without triggering f.label.
5
+ class IsolatedLabelTest < ActionView::TestCase
6
+ setup do
7
+ SimpleForm::Inputs::Base.reset_i18n_cache :translate_required_html
8
+ end
9
+
10
+ def with_label_for(object, attribute_name, type, options={})
11
+ with_concat_form_for(object) do |f|
12
+ options[:reflection] = Association.new(Company, :company, {}) if options.delete(:setup_association)
13
+ SimpleForm::Inputs::Base.new(f, attribute_name, nil, type, options).label
14
+ end
15
+ end
16
+
17
+ test 'label should generate a default humanized description' do
18
+ with_label_for @user, :name, :string
19
+ assert_select 'label[for=user_name]', /Name/
20
+ end
21
+
22
+ test 'label should allow a customized description' do
23
+ with_label_for @user, :name, :string, :label => 'My label!'
24
+ assert_select 'label[for=user_name]', /My label!/
25
+ end
26
+
27
+ test 'label should use human attribute name from object when available' do
28
+ with_label_for @user, :description, :text
29
+ assert_select 'label[for=user_description]', /User Description!/
30
+ end
31
+
32
+ test 'label should use human attribute name based on association name' do
33
+ with_label_for @user, :company_id, :string, :setup_association => true
34
+ assert_select 'label', /Company Human Name!/
35
+ end
36
+
37
+ test 'label should use i18n based on model, action, and attribute to lookup translation' do
38
+ @controller.action_name = "new"
39
+ store_translations(:en, :simple_form => { :labels => { :user => {
40
+ :new => { :description => 'Nova descrição' }
41
+ } } }) do
42
+ with_label_for @user, :description, :text
43
+ assert_select 'label[for=user_description]', /Nova descrição/
44
+ end
45
+ end
46
+
47
+ test 'label should fallback to new when action is create' do
48
+ @controller.action_name = "create"
49
+ store_translations(:en, :simple_form => { :labels => { :user => {
50
+ :new => { :description => 'Nova descrição' }
51
+ } } }) do
52
+ with_label_for @user, :description, :text
53
+ assert_select 'label[for=user_description]', /Nova descrição/
54
+ end
55
+ end
56
+
57
+ test 'label should not explode while looking for i18n translation when action is not set' do
58
+ def @controller.action_name; nil; end
59
+
60
+ assert_nothing_raised do
61
+ with_label_for @user, :description, :text
62
+ end
63
+ assert_select 'label[for=user_description]'
64
+ end
65
+
66
+ test 'label should use i18n based on model and attribute to lookup translation' do
67
+ store_translations(:en, :simple_form => { :labels => { :user => {
68
+ :description => 'Descrição'
69
+ } } }) do
70
+ with_label_for @user, :description, :text
71
+ assert_select 'label[for=user_description]', /Descrição/
72
+ end
73
+ end
74
+
75
+ test 'label should use i18n under defaults to lookup translation' do
76
+ store_translations(:en, :simple_form => { :labels => { :defaults => { :age => 'Idade' } } }) do
77
+ with_label_for @user, :age, :integer
78
+ assert_select 'label[for=user_age]', /Idade/
79
+ end
80
+ end
81
+
82
+ test 'label should not use i18n label if translate is false' do
83
+ swap SimpleForm, :translate_labels => false do
84
+ store_translations(:en, :simple_form => { :labels => { :defaults => { :age => 'Idade' } } }) do
85
+ with_label_for @user, :age, :integer
86
+ assert_select 'label[for=user_age]', /Age/
87
+ end
88
+ end
89
+ end
90
+
91
+ test 'label uses i18n with lookup for association name' do
92
+ store_translations(:en, :simple_form => { :labels => {
93
+ :user => { :company => 'My company!' }
94
+ } }) do
95
+ with_label_for @user, :company_id, :string, :setup_association => true
96
+ assert_select 'label[for=user_company_id]', /My company!/
97
+ end
98
+ end
99
+
100
+ test 'label uses i18n under defaults namespace to lookup for association name' do
101
+ store_translations(:en, :simple_form => { :labels => {
102
+ :defaults => { :company => 'Plataformatec' }
103
+ } }) do
104
+ with_label_for @user, :company, :string, :setup_association => true
105
+
106
+ assert_select 'form label', /Plataformatec/
107
+ end
108
+ end
109
+
110
+ test 'label should do correct i18n lookup for nested models with nested translation' do
111
+ @user.company = Company.new(1, 'Empresa')
112
+
113
+ store_translations(:en, :simple_form => { :labels => {
114
+ :user => { :name => 'Usuario', :company => { :name => 'Nome da empresa' } }
115
+ } }) do
116
+ with_concat_form_for @user do |f|
117
+ concat f.input :name
118
+ concat(f.simple_fields_for(:company) do |company_form|
119
+ concat(company_form.input :name)
120
+ end)
121
+ end
122
+
123
+ assert_select 'label[for=user_name]', /Usuario/
124
+ assert_select 'label[for=user_company_attributes_name]', /Nome da empresa/
125
+ end
126
+ end
127
+
128
+ test 'label should do correct i18n lookup for nested models with no nested translation' do
129
+ @user.company = Company.new(1, 'Empresa')
130
+
131
+ store_translations(:en, :simple_form => { :labels => {
132
+ :user => { :name => 'Usuario' },
133
+ :company => { :name => 'Nome da empresa' }
134
+ } }) do
135
+ with_concat_form_for @user do |f|
136
+ concat f.input :name
137
+ concat(f.simple_fields_for(:company) do |company_form|
138
+ concat(company_form.input :name)
139
+ end)
140
+ end
141
+
142
+ assert_select 'label[for=user_name]', /Usuario/
143
+ assert_select 'label[for=user_company_attributes_name]', /Nome da empresa/
144
+ end
145
+ end
146
+
147
+ test 'label should do correct i18n lookup for nested has_many models with no nested translation' do
148
+ @user.tags = [Tag.new(1, 'Empresa')]
149
+
150
+ store_translations(:en, :simple_form => { :labels => {
151
+ :user => { :name => 'Usuario' },
152
+ :tags => { :name => 'Nome da empresa' }
153
+ } }) do
154
+ with_concat_form_for @user do |f|
155
+ concat f.input :name
156
+ concat(f.simple_fields_for(:tags, :child_index => "new_index") do |tags_form|
157
+ concat(tags_form.input :name)
158
+ end)
159
+ end
160
+
161
+ assert_select 'label[for=user_name]', /Usuario/
162
+ assert_select 'label[for=user_tags_attributes_new_index_name]', /Nome da empresa/
163
+ end
164
+ end
165
+
166
+ test 'label should have css class from type' do
167
+ with_label_for @user, :name, :string
168
+ assert_select 'label.string'
169
+ with_label_for @user, :description, :text
170
+ assert_select 'label.text'
171
+ with_label_for @user, :age, :integer
172
+ assert_select 'label.integer'
173
+ with_label_for @user, :born_at, :date
174
+ assert_select 'label.date'
175
+ with_label_for @user, :created_at, :datetime
176
+ assert_select 'label.datetime'
177
+ end
178
+
179
+ test 'label should not have css class from type when generate_additional_classes_for does not include :label' do
180
+ swap SimpleForm, :generate_additional_classes_for => [:wrapper, :input] do
181
+ with_label_for @user, :name, :string
182
+ assert_no_select 'label.string'
183
+ with_label_for @user, :description, :text
184
+ assert_no_select 'label.text'
185
+ with_label_for @user, :age, :integer
186
+ assert_no_select 'label.integer'
187
+ with_label_for @user, :born_at, :date
188
+ assert_no_select 'label.date'
189
+ with_label_for @user, :created_at, :datetime
190
+ assert_no_select 'label.datetime'
191
+ end
192
+ end
193
+
194
+ test 'label should not generate empty css class' do
195
+ swap SimpleForm, :generate_additional_classes_for => [:wrapper, :input] do
196
+ with_label_for @user, :name, :string
197
+ assert_no_select 'label[class]'
198
+ end
199
+ end
200
+
201
+ test 'label should obtain required from ActiveModel::Validations when it is included' do
202
+ with_label_for @validating_user, :name, :string
203
+ assert_select 'label.required'
204
+ with_label_for @validating_user, :status, :string
205
+ assert_select 'label.optional'
206
+ end
207
+
208
+ test 'label should not obtain required from ActiveModel::Validations when generate_additional_classes_for does not include :label' do
209
+ swap SimpleForm, :generate_additional_classes_for => [:wrapper, :input] do
210
+ with_label_for @validating_user, :name, :string
211
+ assert_no_select 'label.required'
212
+ with_label_for @validating_user, :status, :string
213
+ assert_no_select 'label.optional'
214
+ end
215
+ end
216
+
217
+ test 'label should allow overriding required when ActiveModel::Validations is included' do
218
+ with_label_for @validating_user, :name, :string, :required => false
219
+ assert_select 'label.optional'
220
+ with_label_for @validating_user, :status, :string, :required => true
221
+ assert_select 'label.required'
222
+ end
223
+
224
+ test 'label should be required by default when ActiveModel::Validations is not included' do
225
+ with_label_for @user, :name, :string
226
+ assert_select 'label.required'
227
+ end
228
+
229
+ test 'label should be able to disable required when ActiveModel::Validations is not included' do
230
+ with_label_for @user, :name, :string, :required => false
231
+ assert_no_select 'label.required'
232
+ end
233
+
234
+ test 'label should add required text when required' do
235
+ with_label_for @user, :name, :string
236
+ assert_select 'label.required abbr[title=required]', '*'
237
+ end
238
+
239
+ test 'label should not have required text in no required inputs' do
240
+ with_label_for @user, :name, :string, :required => false
241
+ assert_no_select 'form label abbr'
242
+ end
243
+
244
+ test 'label should use i18n to find required text' do
245
+ store_translations(:en, :simple_form => { :required => { :text => 'campo requerido' } }) do
246
+ with_label_for @user, :name, :string
247
+ assert_select 'form label abbr[title=campo requerido]', '*'
248
+ end
249
+ end
250
+
251
+ test 'label should use i18n to find required mark' do
252
+ store_translations(:en, :simple_form => { :required => { :mark => '*-*' } }) do
253
+ with_label_for @user, :name, :string
254
+ assert_select 'form label abbr', '*-*'
255
+ end
256
+ end
257
+
258
+ test 'label should use i18n to find required string tag' do
259
+ store_translations(:en, :simple_form => { :required => { :html => '<span class="required" title="requerido">*</span>' } }) do
260
+ with_label_for @user, :name, :string
261
+ assert_no_select 'form label abbr'
262
+ assert_select 'form label span.required[title=requerido]', '*'
263
+ end
264
+ end
265
+
266
+ test 'label should allow overwriting input id' do
267
+ with_label_for @user, :name, :string, :input_html => { :id => 'my_new_id' }
268
+ assert_select 'label[for=my_new_id]'
269
+ end
270
+
271
+ test 'label should allow overwriting of for attribute' do
272
+ with_label_for @user, :name, :string, :label_html => { :for => 'my_new_id' }
273
+ assert_select 'label[for=my_new_id]'
274
+ end
275
+
276
+ test 'label should allow overwriting of for attribute with input_html not containing id' do
277
+ with_label_for @user, :name, :string, :label_html => { :for => 'my_new_id' }, :input_html => { :class => 'foo' }
278
+ assert_select 'label[for=my_new_id]'
279
+ end
280
+
281
+ test 'label should use default input id when it was not overridden' do
282
+ with_label_for @user, :name, :string, :input_html => { :class => 'my_new_id' }
283
+ assert_select 'label[for=user_name]'
284
+ end
285
+
286
+ test 'label should be generated properly when object is not present' do
287
+ with_label_for :project, :name, :string
288
+ assert_select 'label[for=project_name]', /Name/
289
+ end
290
+
291
+ test 'label should include for attribute for select collection' do
292
+ with_label_for @user, :sex, :select, :collection => [:male, :female]
293
+ assert_select 'label[for=user_sex]'
294
+ end
295
+
296
+ test 'label should use i18n properly when object is not present' do
297
+ store_translations(:en, :simple_form => { :labels => {
298
+ :project => { :name => 'Nome' }
299
+ } }) do
300
+ with_label_for :project, :name, :string
301
+ assert_select 'label[for=project_name]', /Nome/
302
+ end
303
+ end
304
+
305
+ test 'label should add required by default when object is not present' do
306
+ with_label_for :project, :name, :string
307
+ assert_select 'label.required[for=project_name]'
308
+ with_label_for :project, :description, :string, :required => false
309
+ assert_no_select 'label.required[for=project_description]'
310
+ end
311
+
312
+ test 'label should add chosen label class' do
313
+ swap SimpleForm, :label_class => :my_custom_class do
314
+ with_label_for @user, :name, :string
315
+ assert_select 'label.my_custom_class'
316
+ end
317
+ end
318
+
319
+ test 'label strips extra classes even when label_class is nil' do
320
+ swap SimpleForm, :label_class => nil do
321
+ with_label_for @user, :name, :string
322
+ assert_select "label[class='string required']"
323
+ assert_no_select "label[class='string required ']"
324
+ assert_no_select "label[class=' string required']"
325
+ end
326
+ end
327
+ end
@@ -0,0 +1,186 @@
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 = Object.new
45
+ value.expects(:to_a).returns(value)
46
+
47
+ with_association_for @user, :tags
48
+ assert_select 'form select.select#user_tag_ids'
49
+ assert_select 'form select option[value=1]', 'Tag 1'
50
+ assert_select 'form select option[value=2]', 'Tag 2'
51
+ assert_select 'form select option[value=3]', 'Tag 3'
52
+ end
53
+
54
+ test 'builder does not preload collection association if preload is false' do
55
+ value = @user.tags = Object.new
56
+ value.expects(:to_a).never
57
+
58
+ with_association_for @user, :tags, :preload => false
59
+ assert_select 'form select.select#user_tag_ids'
60
+ assert_select 'form select option[value=1]', 'Tag 1'
61
+ assert_select 'form select option[value=2]', 'Tag 2'
62
+ assert_select 'form select option[value=3]', 'Tag 3'
63
+ end
64
+
65
+ test 'builder does not preload non-collection association' do
66
+ value = @user.company = Object.new
67
+ value.expects(:to_a).never
68
+
69
+ with_association_for @user, :company
70
+ assert_select 'form select.select#user_company_id'
71
+ assert_select 'form select option[value=1]', 'Company 1'
72
+ assert_select 'form select option[value=2]', 'Company 2'
73
+ assert_select 'form select option[value=3]', 'Company 3'
74
+ end
75
+
76
+ # ASSOCIATIONS - BELONGS TO
77
+ test 'builder creates a select for belongs_to associations' do
78
+ with_association_for @user, :company
79
+ assert_select 'form select.select#user_company_id'
80
+ assert_select 'form select option[value=1]', 'Company 1'
81
+ assert_select 'form select option[value=2]', 'Company 2'
82
+ assert_select 'form select option[value=3]', 'Company 3'
83
+ end
84
+
85
+ test 'builder creates blank select if collection is nil' do
86
+ with_association_for @user, :company, :collection => nil
87
+ assert_select 'form select.select#user_company_id'
88
+ assert_no_select 'form select option[value=1]', 'Company 1'
89
+ end
90
+
91
+ test 'builder allows collection radio for belongs_to associations' do
92
+ with_association_for @user, :company, :as => :radio_buttons
93
+ assert_select 'form input.radio_buttons#user_company_id_1'
94
+ assert_select 'form input.radio_buttons#user_company_id_2'
95
+ assert_select 'form input.radio_buttons#user_company_id_3'
96
+ end
97
+
98
+ test 'builder marks the record which already belongs to the user' do
99
+ @user.company_id = 2
100
+ with_association_for @user, :company, :as => :radio_buttons
101
+ assert_no_select 'form input.radio_buttons#user_company_id_1[checked=checked]'
102
+ assert_select 'form input.radio_buttons#user_company_id_2[checked=checked]'
103
+ assert_no_select 'form input.radio_buttons#user_company_id_3[checked=checked]'
104
+ end
105
+
106
+ # ASSOCIATIONS - FINDERS
107
+ test 'builder should use reflection conditions to find collection' do
108
+ with_association_for @user, :special_company
109
+ assert_select 'form select.select#user_special_company_id'
110
+ assert_select 'form select option[value=1]'
111
+ assert_no_select 'form select option[value=2]'
112
+ assert_no_select 'form select option[value=3]'
113
+ end
114
+
115
+ test 'builder should allow overriding collection to association input' do
116
+ with_association_for @user, :company, :include_blank => false,
117
+ :collection => [Company.new(999, 'Teste')]
118
+ assert_select 'form select.select#user_company_id'
119
+ assert_no_select 'form select option[value=1]'
120
+ assert_select 'form select option[value=999]', 'Teste'
121
+ assert_select 'form select option', :count => 1
122
+ end
123
+
124
+ # ASSOCIATIONS - has_*
125
+ test 'builder does not allow has_one associations' do
126
+ assert_raise ArgumentError do
127
+ with_association_for @user, :first_company, :as => :radio_buttons
128
+ end
129
+ end
130
+
131
+ test 'builder creates a select with multiple options for collection associations' do
132
+ with_association_for @user, :tags
133
+ assert_select 'form select.select#user_tag_ids'
134
+ assert_select 'form select[multiple=multiple][size=5]'
135
+ assert_select 'form select option[value=1]', 'Tag 1'
136
+ assert_select 'form select option[value=2]', 'Tag 2'
137
+ assert_select 'form select option[value=3]', 'Tag 3'
138
+ end
139
+
140
+ test 'builder allows size to be overwritten for collection associations' do
141
+ with_association_for @user, :tags, :input_html => { :size => 10 }
142
+ assert_select 'form select[multiple=multiple][size=10]'
143
+ end
144
+
145
+ test 'builder marks all selected records which already belongs to user' do
146
+ @user.tag_ids = [1, 2]
147
+ with_association_for @user, :tags
148
+ assert_select 'form select option[value=1][selected=selected]'
149
+ assert_select 'form select option[value=2][selected=selected]'
150
+ assert_no_select 'form select option[value=3][selected=selected]'
151
+ end
152
+
153
+ test 'builder allows a collection of check boxes for collection associations' do
154
+ @user.tag_ids = [1, 2]
155
+ with_association_for @user, :tags, :as => :check_boxes
156
+ assert_select 'form input#user_tag_ids_1[type=checkbox]'
157
+ assert_select 'form input#user_tag_ids_2[type=checkbox]'
158
+ assert_select 'form input#user_tag_ids_3[type=checkbox]'
159
+ end
160
+
161
+ test 'builder marks all selected records for collection boxes' do
162
+ @user.tag_ids = [1, 2]
163
+ with_association_for @user, :tags, :as => :check_boxes
164
+ assert_select 'form input[type=checkbox][value=1][checked=checked]'
165
+ assert_select 'form input[type=checkbox][value=2][checked=checked]'
166
+ assert_no_select 'form input[type=checkbox][value=3][checked=checked]'
167
+ end
168
+
169
+ test 'builder with collection support giving collection and item wrapper tags' do
170
+ with_association_for @user, :tags, :as => :check_boxes,
171
+ :collection_wrapper_tag => :ul, :item_wrapper_tag => :li
172
+
173
+ assert_select 'form ul', :count => 1
174
+ assert_select 'form ul li', :count => 3
175
+ end
176
+
177
+ test 'builder with collection support should not change the options hash' do
178
+ options = { :as => :check_boxes, :collection_wrapper_tag => :ul, :item_wrapper_tag => :li}
179
+ with_association_for @user, :tags, options
180
+
181
+ assert_select 'form ul', :count => 1
182
+ assert_select 'form ul li', :count => 3
183
+ assert_equal({ :as => :check_boxes, :collection_wrapper_tag => :ul, :item_wrapper_tag => :li},
184
+ options)
185
+ end
186
+ end