simple_form 2.0.0 → 2.1.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 (60) hide show
  1. data/CHANGELOG.md +34 -231
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +221 -159
  4. data/lib/generators/simple_form/install_generator.rb +14 -5
  5. data/lib/generators/simple_form/templates/config/initializers/{simple_form.rb.tt → simple_form.rb} +8 -42
  6. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +45 -0
  7. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +26 -0
  8. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -5
  9. data/lib/simple_form/action_view_extensions/builder.rb +46 -30
  10. data/lib/simple_form/action_view_extensions/builder.rb.orig +247 -0
  11. data/lib/simple_form/action_view_extensions/form_helper.rb +7 -9
  12. data/lib/simple_form/components/hints.rb +3 -2
  13. data/lib/simple_form/components/label_input.rb +1 -1
  14. data/lib/simple_form/components/labels.rb +1 -1
  15. data/lib/simple_form/components/maxlength.rb +1 -1
  16. data/lib/simple_form/components/min_max.rb +2 -1
  17. data/lib/simple_form/components/pattern.rb +1 -1
  18. data/lib/simple_form/components/readonly.rb +1 -1
  19. data/lib/simple_form/components.rb +12 -10
  20. data/lib/simple_form/error_notification.rb +1 -1
  21. data/lib/simple_form/form_builder.rb +18 -8
  22. data/lib/simple_form/form_builder.rb.orig +486 -0
  23. data/lib/simple_form/helpers/validators.rb +2 -2
  24. data/lib/simple_form/inputs/base.rb +33 -8
  25. data/lib/simple_form/inputs/boolean_input.rb +19 -5
  26. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +2 -6
  27. data/lib/simple_form/inputs/date_time_input.rb +0 -4
  28. data/lib/simple_form/inputs.rb +19 -17
  29. data/lib/simple_form/version.rb +1 -1
  30. data/lib/simple_form/version.rb.orig +7 -0
  31. data/lib/simple_form/wrappers/many.rb +5 -1
  32. data/lib/simple_form/wrappers/root.rb +4 -2
  33. data/lib/simple_form/wrappers/single.rb +6 -0
  34. data/lib/simple_form.rb +17 -8
  35. data/test/action_view_extensions/builder_test.rb +145 -66
  36. data/test/action_view_extensions/form_helper_test.rb +59 -20
  37. data/test/components/label_test.rb +34 -17
  38. data/test/form_builder/association_test.rb +19 -10
  39. data/test/form_builder/error_notification_test.rb +1 -1
  40. data/test/form_builder/general_test.rb +74 -12
  41. data/test/form_builder/hint_test.rb +15 -0
  42. data/test/form_builder/input_field_test.rb +45 -0
  43. data/test/form_builder/label_test.rb +6 -0
  44. data/test/form_builder/wrapper_test.rb +58 -4
  45. data/test/generators/simple_form_generator_test.rb +11 -1
  46. data/test/inputs/boolean_input_test.rb +39 -0
  47. data/test/inputs/datetime_input_test.rb +2 -2
  48. data/test/inputs/disabled_test.rb +51 -11
  49. data/test/inputs/discovery_test.rb +9 -1
  50. data/test/inputs/general_test.rb +58 -11
  51. data/test/inputs/grouped_collection_select_input_test.rb +15 -0
  52. data/test/inputs/numeric_input_test.rb +6 -0
  53. data/test/inputs/readonly_test.rb +51 -11
  54. data/test/inputs/string_input_test.rb +6 -0
  55. data/test/support/discovery_inputs.rb +6 -0
  56. data/test/support/misc_helpers.rb +41 -1
  57. data/test/support/models.rb +8 -4
  58. data/test/test_helper.rb +8 -6
  59. metadata +26 -13
  60. data/test/support/mock_response.rb +0 -14
@@ -9,96 +9,135 @@ class FormHelperTest < ActionView::TestCase
9
9
  end
10
10
 
11
11
  test 'SimpleForm should add default class to form' do
12
- concat(simple_form_for(:user) do |f| end)
12
+ with_concat_form_for(:user)
13
13
  assert_select 'form.simple_form'
14
14
  end
15
15
 
16
16
  test 'SimpleForm should use default browser validations by default' do
17
- concat(simple_form_for(:user) do |f| end)
17
+ with_concat_form_for(:user)
18
18
  assert_no_select 'form[novalidate]'
19
19
  end
20
20
 
21
21
  test 'SimpleForm should not use default browser validations if specified in the configuration options' do
22
22
  swap SimpleForm, :browser_validations => false do
23
- concat(simple_form_for(:user) do |f| end)
23
+ with_concat_form_for(:user)
24
24
  assert_select 'form[novalidate="novalidate"]'
25
25
  end
26
26
  end
27
27
 
28
28
  test 'a form specific disabled validation option should override the default enabled browser validation configuration option' do
29
- concat(simple_form_for(:user, :html => { :novalidate => true }) do |f| end)
29
+ with_concat_form_for(:user, :html => { :novalidate => true })
30
30
  assert_select 'form[novalidate="novalidate"]'
31
31
  end
32
32
 
33
33
  test 'a form specific enabled validation option should override the disabled browser validation configuration option' do
34
34
  swap SimpleForm, :browser_validations => false do
35
- concat(simple_form_for(:user, :html => { :novalidate => false }) do |f| end)
35
+ with_concat_form_for(:user, :html => { :novalidate => false })
36
36
  assert_no_select 'form[novalidate]'
37
37
  end
38
38
  end
39
39
 
40
40
  test 'SimpleForm should add object name as css class to form when object is not present' do
41
- concat(simple_form_for(:user) do |f| end)
41
+ with_concat_form_for(:user, :html => { :novalidate => true })
42
42
  assert_select 'form.simple_form.user'
43
43
  end
44
44
 
45
45
  test 'SimpleForm 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)
46
+ with_concat_form_for(:user, :as => 'superuser')
47
47
  assert_select 'form.simple_form.superuser'
48
48
  end
49
49
 
50
50
  test 'SimpleForm should add object class name with new prefix as css class to form if record is not persisted' do
51
51
  @user.new_record!
52
- concat(simple_form_for(@user) do |f| end)
52
+ with_concat_form_for(@user)
53
53
  assert_select 'form.simple_form.new_user'
54
54
  end
55
55
 
56
56
  test 'SimpleForm should add :as option with new prefix as css class to form if record is not persisted' do
57
57
  @user.new_record!
58
- concat(simple_form_for(@user, :as => 'superuser') do |f| end)
58
+ with_concat_form_for(@user, :as => 'superuser')
59
59
  assert_select 'form.simple_form.new_superuser'
60
60
  end
61
61
 
62
62
  test 'SimpleForm should add edit class prefix as css class to form if record is persisted' do
63
- concat(simple_form_for(@user) do |f| end)
63
+ with_concat_form_for(@user)
64
64
  assert_select 'form.simple_form.edit_user'
65
65
  end
66
66
 
67
67
  test 'SimpleForm 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)
68
+ with_concat_form_for(@user, :as => 'superuser')
69
69
  assert_select 'form.simple_form.edit_superuser'
70
70
  end
71
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
+
72
77
  test 'SimpleForm should not add object class to form if css_class is specified' do
73
- concat(simple_form_for(:user, :html => {:class => nil}) do |f| end)
78
+ with_concat_form_for(:user, :html => {:class => nil})
74
79
  assert_no_select 'form.user'
75
80
  end
76
81
 
77
82
  test 'SimpleForm should add custom class to form if css_class is specified' do
78
- concat(simple_form_for(:user, :html => {:class => 'my_class'}) do |f| end)
83
+ with_concat_form_for(:user, :html => {:class => 'my_class'})
79
84
  assert_select 'form.my_class'
80
85
  end
81
86
 
82
87
  test 'pass options to SimpleForm' do
83
- concat(simple_form_for(:user, :url => '/account', :html => { :id => 'my_form' }) do |f| end)
88
+ with_concat_form_for(:user, :url => '/account', :html => { :id => 'my_form' })
84
89
  assert_select 'form#my_form'
85
90
  assert_select 'form[action=/account]'
86
91
  end
87
92
 
88
93
  test 'fields for yields an instance of FormBuilder' do
89
- concat(simple_fields_for(:user) do |f|
94
+ with_concat_form_for(:user) do |f|
90
95
  assert f.instance_of?(SimpleForm::FormBuilder)
91
- end)
96
+ end
92
97
  end
93
98
 
94
99
  test 'fields for with a hash like model yeilds an instance of FormBuilder' do
95
- @hash_backed_author = HashBackedAuthor.new
96
-
97
- concat(simple_fields_for(:author, @hash_backed_author) do |f|
100
+ with_concat_fields_for(:author, HashBackedAuthor.new) do |f|
98
101
  assert f.instance_of?(SimpleForm::FormBuilder)
99
102
  f.input :name
100
- end)
103
+ end
101
104
 
102
105
  assert_select "input[name='author[name]'][value='hash backed author']"
103
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
104
143
  end
@@ -38,7 +38,7 @@ class IsolatedLabelTest < ActionView::TestCase
38
38
  @controller.action_name = "new"
39
39
  store_translations(:en, :simple_form => { :labels => { :user => {
40
40
  :new => { :description => 'Nova descrição' }
41
- } } } ) do
41
+ } } }) do
42
42
  with_label_for @user, :description, :text
43
43
  assert_select 'label[for=user_description]', /Nova descrição/
44
44
  end
@@ -48,7 +48,7 @@ class IsolatedLabelTest < ActionView::TestCase
48
48
  @controller.action_name = "create"
49
49
  store_translations(:en, :simple_form => { :labels => { :user => {
50
50
  :new => { :description => 'Nova descrição' }
51
- } } } ) do
51
+ } } }) do
52
52
  with_label_for @user, :description, :text
53
53
  assert_select 'label[for=user_description]', /Nova descrição/
54
54
  end
@@ -66,43 +66,53 @@ class IsolatedLabelTest < ActionView::TestCase
66
66
  test 'label should use i18n based on model and attribute to lookup translation' do
67
67
  store_translations(:en, :simple_form => { :labels => { :user => {
68
68
  :description => 'Descrição'
69
- } } } ) do
69
+ } } }) do
70
70
  with_label_for @user, :description, :text
71
71
  assert_select 'label[for=user_description]', /Descrição/
72
72
  end
73
73
  end
74
74
 
75
- test 'input should use i18n under defaults to lookup translation' do
76
- store_translations(:en, :simple_form => { :labels => { :defaults => {:age => 'Idade'} } } ) do
75
+ test 'label should use i18n under defaults to lookup translation' do
76
+ store_translations(:en, :simple_form => { :labels => { :defaults => { :age => 'Idade' } } }) do
77
77
  with_label_for @user, :age, :integer
78
78
  assert_select 'label[for=user_age]', /Idade/
79
79
  end
80
80
  end
81
81
 
82
- test 'input should not use i18n label if translate is false' do
82
+ test 'label should not use i18n label if translate is false' do
83
83
  swap SimpleForm, :translate_labels => false do
84
- store_translations(:en, :simple_form => { :labels => { :defaults => {:age => 'Idade'} } } ) do
84
+ store_translations(:en, :simple_form => { :labels => { :defaults => { :age => 'Idade' } } }) do
85
85
  with_label_for @user, :age, :integer
86
86
  assert_select 'label[for=user_age]', /Age/
87
87
  end
88
88
  end
89
89
  end
90
90
 
91
- test 'label should use i18n with lookup for association name' do
91
+ test 'label uses i18n with lookup for association name' do
92
92
  store_translations(:en, :simple_form => { :labels => {
93
93
  :user => { :company => 'My company!' }
94
- } } ) do
94
+ } }) do
95
95
  with_label_for @user, :company_id, :string, :setup_association => true
96
96
  assert_select 'label[for=user_company_id]', /My company!/
97
97
  end
98
98
  end
99
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
+
100
110
  test 'label should do correct i18n lookup for nested models with nested translation' do
101
111
  @user.company = Company.new(1, 'Empresa')
102
112
 
103
113
  store_translations(:en, :simple_form => { :labels => {
104
114
  :user => { :name => 'Usuario', :company => { :name => 'Nome da empresa' } }
105
- } } ) do
115
+ } }) do
106
116
  with_concat_form_for @user do |f|
107
117
  concat f.input :name
108
118
  concat(f.simple_fields_for(:company) do |company_form|
@@ -121,7 +131,7 @@ class IsolatedLabelTest < ActionView::TestCase
121
131
  store_translations(:en, :simple_form => { :labels => {
122
132
  :user => { :name => 'Usuario' },
123
133
  :company => { :name => 'Nome da empresa' }
124
- } } ) do
134
+ } }) do
125
135
  with_concat_form_for @user do |f|
126
136
  concat f.input :name
127
137
  concat(f.simple_fields_for(:company) do |company_form|
@@ -140,7 +150,7 @@ class IsolatedLabelTest < ActionView::TestCase
140
150
  store_translations(:en, :simple_form => { :labels => {
141
151
  :user => { :name => 'Usuario' },
142
152
  :tags => { :name => 'Nome da empresa' }
143
- } } ) do
153
+ } }) do
144
154
  with_concat_form_for @user do |f|
145
155
  concat f.input :name
146
156
  concat(f.simple_fields_for(:tags, :child_index => "new_index") do |tags_form|
@@ -181,6 +191,13 @@ class IsolatedLabelTest < ActionView::TestCase
181
191
  end
182
192
  end
183
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
+
184
201
  test 'label should obtain required from ActiveModel::Validations when it is included' do
185
202
  with_label_for @validating_user, :name, :string
186
203
  assert_select 'label.required'
@@ -225,21 +242,21 @@ class IsolatedLabelTest < ActionView::TestCase
225
242
  end
226
243
 
227
244
  test 'label should use i18n to find required text' do
228
- store_translations(:en, :simple_form => { :required => { :text => 'campo requerido' }}) do
245
+ store_translations(:en, :simple_form => { :required => { :text => 'campo requerido' } }) do
229
246
  with_label_for @user, :name, :string
230
247
  assert_select 'form label abbr[title=campo requerido]', '*'
231
248
  end
232
249
  end
233
250
 
234
251
  test 'label should use i18n to find required mark' do
235
- store_translations(:en, :simple_form => { :required => { :mark => '*-*' }}) do
252
+ store_translations(:en, :simple_form => { :required => { :mark => '*-*' } }) do
236
253
  with_label_for @user, :name, :string
237
254
  assert_select 'form label abbr', '*-*'
238
255
  end
239
256
  end
240
257
 
241
258
  test 'label should use i18n to find required string tag' do
242
- store_translations(:en, :simple_form => { :required => { :html => '<span class="required" title="requerido">*</span>' }}) do
259
+ store_translations(:en, :simple_form => { :required => { :html => '<span class="required" title="requerido">*</span>' } }) do
243
260
  with_label_for @user, :name, :string
244
261
  assert_no_select 'form label abbr'
245
262
  assert_select 'form label span.required[title=requerido]', '*'
@@ -257,7 +274,7 @@ class IsolatedLabelTest < ActionView::TestCase
257
274
  end
258
275
 
259
276
  test 'label should allow overwriting of for attribute with input_html not containing id' do
260
- with_label_for @user, :name, :string, :label_html => { :for => 'my_new_id' }, :input_html => {:class => 'foo'}
277
+ with_label_for @user, :name, :string, :label_html => { :for => 'my_new_id' }, :input_html => { :class => 'foo' }
261
278
  assert_select 'label[for=my_new_id]'
262
279
  end
263
280
 
@@ -279,7 +296,7 @@ class IsolatedLabelTest < ActionView::TestCase
279
296
  test 'label should use i18n properly when object is not present' do
280
297
  store_translations(:en, :simple_form => { :labels => {
281
298
  :project => { :name => 'Nome' }
282
- } } ) do
299
+ } }) do
283
300
  with_label_for :project, :name, :string
284
301
  assert_select 'label[for=project_name]', /Nome/
285
302
  end
@@ -41,8 +41,9 @@ class AssociationTest < ActionView::TestCase
41
41
  end
42
42
 
43
43
  test 'builder preloads collection association' do
44
- value = @user.tags
44
+ value = @user.tags = Object.new
45
45
  value.expects(:to_a).returns(value)
46
+
46
47
  with_association_for @user, :tags
47
48
  assert_select 'form select.select#user_tag_ids'
48
49
  assert_select 'form select option[value=1]', 'Tag 1'
@@ -51,19 +52,21 @@ class AssociationTest < ActionView::TestCase
51
52
  end
52
53
 
53
54
  test 'builder does not preload collection association if preload is false' do
54
- value = @user.company
55
+ value = @user.tags = Object.new
55
56
  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'
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'
61
63
  end
62
64
 
63
65
  test 'builder does not preload non-collection association' do
64
- value = @user.company
66
+ value = @user.company = Object.new
65
67
  value.expects(:to_a).never
66
- with_association_for @user, :company, :preload => false
68
+
69
+ with_association_for @user, :company
67
70
  assert_select 'form select.select#user_company_id'
68
71
  assert_select 'form select option[value=1]', 'Company 1'
69
72
  assert_select 'form select option[value=2]', 'Company 2'
@@ -79,6 +82,12 @@ class AssociationTest < ActionView::TestCase
79
82
  assert_select 'form select option[value=3]', 'Company 3'
80
83
  end
81
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
+
82
91
  test 'builder allows collection radio for belongs_to associations' do
83
92
  with_association_for @user, :company, :as => :radio_buttons
84
93
  assert_select 'form input.radio_buttons#user_company_id_1'
@@ -114,7 +123,7 @@ class AssociationTest < ActionView::TestCase
114
123
 
115
124
  # ASSOCIATIONS - has_*
116
125
  test 'builder does not allow has_one associations' do
117
- assert_raise RuntimeError do
126
+ assert_raise ArgumentError do
118
127
  with_association_for @user, :first_company, :as => :radio_buttons
119
128
  end
120
129
  end
@@ -23,7 +23,7 @@ class ErrorNotificationTest < ActionView::TestCase
23
23
 
24
24
  test 'error notification is generated when the object has some error' do
25
25
  with_error_notification_for @user
26
- assert_select 'p.error_notification', 'Some errors were found, please take a look:'
26
+ assert_select 'p.error_notification', 'Please review the problems below:'
27
27
  end
28
28
 
29
29
  test 'error notification uses I18n based on model to generate the notification message' do
@@ -46,6 +46,15 @@ class FormBuilderTest < ActionView::TestCase
46
46
  end
47
47
  end
48
48
 
49
+ test 'builder should allow to add additional classes only for wrapper' do
50
+ swap SimpleForm, :generate_additional_classes_for => [:wrapper] do
51
+ with_form_for @user, :post_count
52
+ assert_no_select "form input#user_post_count.string"
53
+ assert_no_select "form label#user_post_count.string"
54
+ assert_select "form div.input.string"
55
+ end
56
+ end
57
+
49
58
  test 'builder should allow adding custom input mappings for integer input types' do
50
59
  swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
51
60
  with_form_for @user, :lock_version
@@ -202,6 +211,22 @@ class FormBuilderTest < ActionView::TestCase
202
211
  assert_select 'form input#my_input.my_input.string'
203
212
  end
204
213
 
214
+ test 'builder should not propagate input options to wrapper with custom wrapper' do
215
+ swap_wrapper :default, self.custom_wrapper_with_wrapped_input do
216
+ with_form_for @user, :name, :input_html => { :class => 'my_input' }
217
+ assert_no_select 'form div.input.my_input'
218
+ assert_select 'form input.my_input.string'
219
+ end
220
+ end
221
+
222
+ test 'builder should not propagate label options to wrapper with custom wrapper' do
223
+ swap_wrapper :default, self.custom_wrapper_with_wrapped_label do
224
+ with_form_for @user, :name, :label_html => { :class => 'my_label' }
225
+ assert_no_select 'form div.label.my_label'
226
+ assert_select 'form label.my_label.string'
227
+ end
228
+ end
229
+
205
230
  test 'builder should generate a input with label' do
206
231
  with_form_for @user, :name
207
232
  assert_select 'form label.string[for=user_name]', /Name/
@@ -212,6 +237,11 @@ class FormBuilderTest < ActionView::TestCase
212
237
  assert_no_select 'form label'
213
238
  end
214
239
 
240
+ test 'builder should be able to disable the label for an input and return a html safe string' do
241
+ with_form_for @user, :name, :label => false, :wrapper => custom_wrapper_with_wrapped_label_input
242
+ assert_select 'form input#user_name'
243
+ end
244
+
215
245
  test 'builder should use custom label' do
216
246
  with_form_for @user, :name, :label => 'Yay!'
217
247
  assert_select 'form label', /Yay!/
@@ -234,6 +264,8 @@ class FormBuilderTest < ActionView::TestCase
234
264
 
235
265
  test 'builder should be able to disable a hint even if it exists in i18n' do
236
266
  store_translations(:en, :simple_form => { :hints => { :name => 'Hint test' } }) do
267
+ SimpleForm::Inputs::Base.any_instance.expects(:hint).never
268
+
237
269
  with_form_for @user, :name, :hint => false
238
270
  assert_no_select 'span.hint'
239
271
  end
@@ -274,35 +306,65 @@ class FormBuilderTest < ActionView::TestCase
274
306
  end
275
307
 
276
308
  # 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
309
+ [:input, :input_field].each do |method|
310
+ test "builder should receive a default argument and pass it to the inputs when calling '#{method}'" do
311
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class' } } do |f|
312
+ f.send(method, :name)
313
+ end
314
+ assert_select 'input.default_class'
315
+ end
316
+
317
+ test "builder should receive a default argument and pass it to the inputs without changing the defaults when calling '#{method}'" do
318
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class', :id => 'default_id' } } do |f|
319
+ concat(f.send(method, :name))
320
+ concat(f.send(method, :credit_limit))
321
+ end
322
+
323
+ assert_select "input.string.default_class[name='user[name]']"
324
+ assert_no_select "input.string[name='user[credit_limit]']"
325
+ end
326
+
327
+ test "builder should receive a default argument and pass it to the inputs and nested form when calling '#{method}'" do
328
+ @user.company = Company.new(1, 'Empresa')
329
+
330
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class' } } do |f|
331
+ concat(f.send(method, :name))
332
+ concat(f.simple_fields_for(:company) do |company_form|
333
+ concat(company_form.send(method, :name))
334
+ end)
335
+ end
336
+
337
+ assert_select "input.string.default_class[name='user[name]']"
338
+ assert_select "input.string.default_class[name='user[company_attributes][name]']"
280
339
  end
281
- assert_select 'input.default_class'
282
340
  end
283
341
 
284
- test 'builder should receive a default argument and pass it to the inputs, respecting the specific options' do
342
+ test "builder should receive a default argument and pass it to the inputs when calling 'input', respecting the specific options" do
285
343
  with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class' } } do |f|
286
344
  f.input :name, :input_html => { :id => 'specific_id' }
287
345
  end
288
346
  assert_select 'input.default_class#specific_id'
289
347
  end
290
348
 
291
- test 'builder should receive a default argument and pass it to the inputs, overwriting the defaults with specific options' do
349
+ test "builder should receive a default argument and pass it to the inputs when calling 'input_field', respecting the specific options" do
350
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class' } } do |f|
351
+ f.input_field :name, :id => 'specific_id'
352
+ end
353
+ assert_select 'input.default_class#specific_id'
354
+ end
355
+
356
+ test "builder should receive a default argument and pass it to the inputs when calling 'input', overwriting the defaults with specific options" do
292
357
  with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class', :id => 'default_id' } } do |f|
293
358
  f.input :name, :input_html => { :id => 'specific_id' }
294
359
  end
295
360
  assert_select 'input.default_class#specific_id'
296
361
  end
297
362
 
298
- test 'builder should receive a default argument and pass it to the inputs without changing the defaults' do
363
+ test "builder should receive a default argument and pass it to the inputs when calling 'input_field', overwriting the defaults with specific options" do
299
364
  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)
365
+ f.input_field :name, :id => 'specific_id'
302
366
  end
303
-
304
- assert_select "input.string.default_class[name='user[name]']"
305
- assert_no_select "input.string[name='user[credit_limit]']"
367
+ assert_select 'input.default_class#specific_id'
306
368
  end
307
369
 
308
370
  # WITHOUT OBJECT
@@ -42,6 +42,11 @@ class HintTest < ActionView::TestCase
42
42
  assert_select 'span#hint.hint.yay'
43
43
  end
44
44
 
45
+ test 'hint should be output as html_safe' do
46
+ with_hint_for @user, :name, :hint => '<b>Bold</b> and not...'
47
+ assert_select 'span.hint', 'Bold and not...'
48
+ end
49
+
45
50
  # Without attribute name
46
51
 
47
52
  test 'hint without attribute name' do
@@ -105,6 +110,16 @@ class HintTest < ActionView::TestCase
105
110
  end
106
111
  end
107
112
 
113
+ test 'hint should output translations as html_safe' do
114
+ store_translations(:en, :simple_form => { :hints => { :user => {
115
+ :edit => { :name => '<b>This is bold</b> and this is not...' }
116
+ } } }) do
117
+ with_hint_for @user, :name
118
+ assert_select 'span.hint', 'This is bold and this is not...'
119
+ end
120
+ end
121
+
122
+
108
123
  # No object
109
124
 
110
125
  test 'hint should generate properly when object is not present' do
@@ -50,6 +50,51 @@ class InputFieldTest < ActionView::TestCase
50
50
  assert_no_select 'input.integer[as]'
51
51
  end
52
52
 
53
+ test 'builder input_field should use i18n to translate placeholder text' do
54
+ store_translations(:en, :simple_form => { :placeholders => { :user => {
55
+ :name => 'Name goes here'
56
+ } } }) do
57
+
58
+ with_concat_form_for(@user) do |f|
59
+ f.input_field :name
60
+ end
61
+
62
+ assert_select 'input.string[placeholder=Name goes here]'
63
+ end
64
+ end
65
+
66
+ test 'builder input_field should use min_max component' do
67
+ with_concat_form_for(@other_validating_user) do |f|
68
+ f.input_field :age, :as => :integer
69
+ end
70
+
71
+ assert_select 'input[min=18]'
72
+ end
73
+
74
+ test 'builder input_field should use pattern component' do
75
+ with_concat_form_for(@other_validating_user) do |f|
76
+ f.input_field :country, :as => :string
77
+ end
78
+
79
+ assert_select 'input[pattern="\w+"]'
80
+ end
81
+
82
+ test 'builder input_field should use readonly component' do
83
+ with_concat_form_for(@other_validating_user) do |f|
84
+ f.input_field :age, :as => :integer, :readonly => true
85
+ end
86
+
87
+ assert_select 'input.integer.readonly[readonly]'
88
+ end
89
+
90
+ test 'builder input_field should use maxlength component' do
91
+ with_concat_form_for(@validating_user) do |f|
92
+ f.input_field :name, :as => :string
93
+ end
94
+
95
+ assert_select 'input.string[maxlength=25]'
96
+ end
97
+
53
98
  test 'builder collection input_field should generate input tag with a clean HTML' do
54
99
  with_concat_form_for(@user) do |f|
55
100
  f.input_field :status, :collection => ['Open', 'Closed'], :class => 'status', :label_method => :to_s, :value_method => :to_s
@@ -13,6 +13,12 @@ class LabelTest < ActionView::TestCase
13
13
  assert_select 'label.string[for=user_name]', /Name/
14
14
  end
15
15
 
16
+ test 'builder should generate a label for the boolean attrbiute' do
17
+ with_label_for @user, :name, :as => :boolean
18
+ assert_select 'label.boolean[for=user_name]', /Name/
19
+ assert_no_select 'label[as=boolean]'
20
+ end
21
+
16
22
  test 'builder should generate a label componet tag with a clean HTML' do
17
23
  with_label_for @user, :name
18
24
  assert_no_select 'label.string[label_html]'