simple_form 0.5 → 1.0.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.

Potentially problematic release.


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

Files changed (48) hide show
  1. data/README.rdoc +339 -6
  2. data/generators/simple_form_install/USAGE +3 -0
  3. data/generators/simple_form_install/simple_form_install_generator.rb +19 -0
  4. data/generators/simple_form_install/templates/simple_form.rb +38 -0
  5. data/init.rb +1 -0
  6. data/lib/simple_form.rb +57 -1
  7. data/lib/simple_form/action_view_extensions/builder.rb +122 -0
  8. data/lib/simple_form/action_view_extensions/form_helper.rb +33 -0
  9. data/lib/simple_form/action_view_extensions/instance_tag.rb +37 -0
  10. data/lib/simple_form/components.rb +8 -0
  11. data/lib/simple_form/components/errors.rb +35 -0
  12. data/lib/simple_form/components/hints.rb +21 -0
  13. data/lib/simple_form/components/labels.rb +68 -0
  14. data/lib/simple_form/components/wrapper.rb +21 -0
  15. data/lib/simple_form/form_builder.rb +332 -0
  16. data/lib/simple_form/i18n_cache.rb +22 -0
  17. data/lib/simple_form/inputs.rb +12 -0
  18. data/lib/simple_form/inputs/base.rb +107 -0
  19. data/lib/simple_form/inputs/block_input.rb +13 -0
  20. data/lib/simple_form/inputs/collection_input.rb +58 -0
  21. data/lib/simple_form/inputs/date_time_input.rb +18 -0
  22. data/lib/simple_form/inputs/hidden_input.rb +11 -0
  23. data/lib/simple_form/inputs/mapping_input.rb +23 -0
  24. data/lib/simple_form/inputs/priority_input.rb +20 -0
  25. data/lib/simple_form/inputs/text_field_input.rb +16 -0
  26. data/lib/simple_form/locale/en.yml +14 -0
  27. data/lib/simple_form/map_type.rb +13 -0
  28. data/lib/simple_form/version.rb +3 -0
  29. data/test/action_view_extensions/builder_test.rb +172 -0
  30. data/test/action_view_extensions/form_helper_test.rb +50 -0
  31. data/test/components/error_test.rb +45 -0
  32. data/test/components/hint_test.rb +78 -0
  33. data/test/components/label_test.rb +170 -0
  34. data/test/form_builder_test.rb +550 -0
  35. data/test/inputs_test.rb +337 -0
  36. data/test/simple_form_test.rb +9 -0
  37. data/test/support/country_select/init.rb +1 -0
  38. data/test/support/country_select/install.rb +2 -0
  39. data/test/support/country_select/lib/country_select.rb +84 -0
  40. data/test/support/country_select/uninstall.rb +1 -0
  41. data/test/support/misc_helpers.rb +29 -0
  42. data/test/support/mock_controller.rb +11 -0
  43. data/test/support/mock_response.rb +14 -0
  44. data/test/support/models.rb +100 -0
  45. data/test/test_helper.rb +60 -0
  46. metadata +50 -10
  47. data/CHANGELOG +0 -27
  48. data/Rakefile +0 -17
@@ -0,0 +1,50 @@
1
+ require 'test_helper'
2
+
3
+ class FormHelperTest < ActionView::TestCase
4
+
5
+ test 'simple form 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 'simple form should add default class to form' do
12
+ simple_form_for :user do |f| end
13
+ assert_select 'form.simple_form'
14
+ end
15
+
16
+ test 'simple form should add object name as css class to form when object is not present' do
17
+ simple_form_for :user do |f| end
18
+ assert_select 'form.simple_form.user'
19
+ end
20
+
21
+ test 'simple form should add object class name as css class to form' do
22
+ simple_form_for @user do |f| end
23
+ assert_select 'form.simple_form.user'
24
+ end
25
+
26
+ test 'pass options to simple form' do
27
+ simple_form_for :user, :url => '/account', :html => { :id => 'my_form' } do |f| end
28
+ assert_select 'form#my_form'
29
+ assert_select 'form[action=/account]'
30
+ end
31
+
32
+ test 'fields for yields an instance of FormBuilder' do
33
+ simple_fields_for :user do |f|
34
+ assert f.instance_of?(SimpleForm::FormBuilder)
35
+ end
36
+ end
37
+
38
+ test 'remote form for yields an instance of FormBuilder' do
39
+ simple_remote_form_for :user do |f|
40
+ assert f.instance_of?(SimpleForm::FormBuilder)
41
+ end
42
+ assert_select "form[onsubmit]"
43
+ end
44
+
45
+ test 'pass options to simple remote form' do
46
+ simple_remote_form_for :user, :url => '/account', :html => { :id => 'my_form' } do |f| end
47
+ assert_select 'form#my_form'
48
+ assert_select 'form[action=/account]'
49
+ end
50
+ end
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ class ErrorTest < ActionView::TestCase
4
+
5
+ def with_error_for(object, attribute_name, type, options={}, &block)
6
+ simple_form_for object do |f|
7
+ f.attribute_name = attribute_name
8
+ f.reflection = Association.new(Company, :company, {}) if options.delete(:setup_association)
9
+ f.input_type = type
10
+ f.options = options
11
+
12
+ concat(SimpleForm::Inputs::Base.new(f).error.to_s)
13
+ end
14
+ end
15
+
16
+ test 'error should not generate content for attribute without errors' do
17
+ with_error_for @user, :active, :boolean
18
+ assert_no_select 'span.error'
19
+ end
20
+
21
+ test 'error should not generate messages when object is not present' do
22
+ with_error_for :project, :name, :string
23
+ assert_no_select 'span.error'
24
+ end
25
+
26
+ test 'error should generate messages for attribute with single error' do
27
+ with_error_for @user, :name, :string
28
+ assert_select 'span.error', "can't be blank"
29
+ end
30
+
31
+ test 'error should generate messages for attribute with several errors' do
32
+ with_error_for @user, :age, :numeric
33
+ assert_select 'span.error', 'is not a number and must be greater than 18'
34
+ end
35
+
36
+ test 'error should be able to pass html options' do
37
+ with_error_for @user, :name, :string, :error_html => { :id => 'error', :class => 'yay' }
38
+ assert_select 'span#error.error.yay'
39
+ end
40
+
41
+ test 'error should find errors on attribute and association' do
42
+ with_error_for @user, :company_id, :select, :setup_association => true
43
+ assert_select 'span.error', 'must be valid and company must be present'
44
+ end
45
+ end
@@ -0,0 +1,78 @@
1
+ require 'test_helper'
2
+
3
+ class HintTest < ActionView::TestCase
4
+
5
+ def with_hint_for(object, attribute_name, type, options={}, &block)
6
+ simple_form_for object do |f|
7
+ f.attribute_name = attribute_name
8
+ f.reflection = Association.new(Company, :company, {}) if options.delete(:setup_association)
9
+ f.input_type = type
10
+ f.options = options
11
+
12
+ concat(SimpleForm::Inputs::Base.new(f).hint.to_s)
13
+ end
14
+ end
15
+
16
+ test 'hint should not be generated by default' do
17
+ with_hint_for @user, :name, :string
18
+ assert_no_select 'span.hint'
19
+ end
20
+
21
+ test 'hint should be generated with input text' do
22
+ with_hint_for @user, :name, :string, :hint => 'Use with care...'
23
+ assert_select 'span.hint', 'Use with care...'
24
+ end
25
+
26
+ test 'hint uses the current component tag set' do
27
+ swap SimpleForm, :hint_tag => :p do
28
+ with_hint_for @user, :name, :string, :hint => 'Use with care...'
29
+ assert_select 'p.hint', 'Use with care...'
30
+ end
31
+ end
32
+
33
+ test 'hint should use i18n based on model, action, and attribute to lookup translation' do
34
+ store_translations(:en, :simple_form => { :hints => { :user => {
35
+ :edit => { :name => 'Content of this input will be truncated...' }
36
+ } } }) do
37
+ with_hint_for @user, :name, :string
38
+ assert_select 'span.hint', 'Content of this input will be truncated...'
39
+ end
40
+ end
41
+
42
+ test 'hint should use i18n with model and attribute to lookup translation' do
43
+ store_translations(:en, :simple_form => { :hints => { :user => {
44
+ :name => 'Content of this input will be capitalized...'
45
+ } } }) do
46
+ with_hint_for @user, :name, :string
47
+ assert_select 'span.hint', 'Content of this input will be capitalized...'
48
+ end
49
+ end
50
+
51
+ test 'hint should use i18n just with attribute to lookup translation' do
52
+ store_translations(:en, :simple_form => { :hints => {
53
+ :name => 'Content of this input will be downcased...'
54
+ } }) do
55
+ with_hint_for @user, :name, :string
56
+ assert_select 'span.hint', 'Content of this input will be downcased...'
57
+ end
58
+ end
59
+
60
+ test 'hint should use i18n with lookup for association name' do
61
+ store_translations(:en, :simple_form => { :hints => {
62
+ :user => { :company => 'My company!' }
63
+ } } ) do
64
+ with_hint_for @user, :company_id, :string, :setup_association => true
65
+ assert_select 'span.hint', /My company!/
66
+ end
67
+ end
68
+
69
+ test 'hint should generate properly when object is not present' do
70
+ with_hint_for :project, :name, :string, :hint => 'Test without object'
71
+ assert_select 'span.hint', 'Test without object'
72
+ end
73
+
74
+ test 'hint should be able to pass html options' do
75
+ with_hint_for @user, :name, :string, :hint => 'Yay!', :hint_html => { :id => 'hint', :class => 'yay' }
76
+ assert_select 'span#hint.hint.yay'
77
+ end
78
+ end
@@ -0,0 +1,170 @@
1
+ require 'test_helper'
2
+
3
+ class LabelTest < ActionView::TestCase
4
+
5
+ setup do
6
+ SimpleForm::Inputs::Base.reset_i18n_cache :translate_required_html
7
+ end
8
+
9
+ def with_label_for(object, attribute_name, type, options={})
10
+ simple_form_for object do |f|
11
+ f.attribute_name = attribute_name
12
+ f.reflection = Association.new(Company, :company, {}) if options.delete(:setup_association)
13
+ f.input_type = type
14
+ f.options = options
15
+
16
+ concat(SimpleForm::Inputs::Base.new(f).label)
17
+ end
18
+ end
19
+
20
+ test 'label should generate a default humanized description' do
21
+ with_label_for @user, :name, :string
22
+ assert_select 'label[for=user_name]', /Name/
23
+ end
24
+
25
+ test 'label should allow a customized description' do
26
+ with_label_for @user, :name, :string, :label => 'My label!'
27
+ assert_select 'label[for=user_name]', /My label!/
28
+ end
29
+
30
+ test 'label should use human attribute name from object when available' do
31
+ with_label_for @user, :description, :text
32
+ assert_select 'label[for=user_description]', /User Description!/
33
+ end
34
+
35
+ test 'label should use human attribute name based on association name' do
36
+ with_label_for @user, :company_id, :string, :setup_association => true
37
+ assert_select 'label', /Company Human Name!/
38
+ end
39
+
40
+ test 'label should use i18n based on model, action, and attribute to lookup translation' do
41
+ @controller.action_name = "new"
42
+ store_translations(:en, :simple_form => { :labels => { :user => {
43
+ :new => { :description => 'Nova descrição' }
44
+ } } } ) do
45
+ with_label_for @user, :description, :text
46
+ assert_select 'label[for=user_description]', /Nova descrição/
47
+ end
48
+ end
49
+
50
+ test 'label should fallback to new when action is create' do
51
+ @controller.action_name = "create"
52
+ store_translations(:en, :simple_form => { :labels => { :user => {
53
+ :new => { :description => 'Nova descrição' }
54
+ } } } ) do
55
+ with_label_for @user, :description, :text
56
+ assert_select 'label[for=user_description]', /Nova descrição/
57
+ end
58
+ end
59
+
60
+ test 'label should use i18n based on model and attribute to lookup translation' do
61
+ store_translations(:en, :simple_form => { :labels => { :user => {
62
+ :description => 'Descrição'
63
+ } } } ) do
64
+ with_label_for @user, :description, :text
65
+ assert_select 'label[for=user_description]', /Descrição/
66
+ end
67
+ end
68
+
69
+ test 'input should use i18n based only on attribute to lookup translation' do
70
+ store_translations(:en, :simple_form => { :labels => { :age => 'Idade' } } ) do
71
+ with_label_for @user, :age, :integer
72
+ assert_select 'label[for=user_age]', /Idade/
73
+ end
74
+ end
75
+
76
+ test 'label should use i18n with lookup for association name' do
77
+ store_translations(:en, :simple_form => { :labels => {
78
+ :user => { :company => 'My company!' }
79
+ } } ) do
80
+ with_label_for @user, :company_id, :string, :setup_association => true
81
+ assert_select 'label[for=user_company_id]', /My company!/
82
+ end
83
+ end
84
+
85
+ test 'label should have css class from type' do
86
+ with_label_for @user, :name, :string
87
+ assert_select 'label.string'
88
+ with_label_for @user, :description, :text
89
+ assert_select 'label.text'
90
+ with_label_for @user, :age, :integer
91
+ assert_select 'label.integer'
92
+ with_label_for @user, :born_at, :date
93
+ assert_select 'label.date'
94
+ with_label_for @user, :created_at, :datetime
95
+ assert_select 'label.datetime'
96
+ end
97
+
98
+ test 'label should be required by default' do
99
+ with_label_for @user, :name, :string
100
+ assert_select 'label.required'
101
+ end
102
+
103
+ test 'label should be able to disable required' do
104
+ with_label_for @user, :name, :string, :required => false
105
+ assert_no_select 'label.required'
106
+ end
107
+
108
+ test 'label should add required text when required' do
109
+ with_label_for @user, :name, :string
110
+ assert_select 'label.required abbr[title=required]', '*'
111
+ end
112
+
113
+ test 'label should not have required text in no required inputs' do
114
+ with_label_for @user, :name, :string, :required => false
115
+ assert_no_select 'form label abbr'
116
+ end
117
+
118
+ test 'label should use i18n to find required text' do
119
+ store_translations(:en, :simple_form => { :required => { :text => 'campo requerido' }}) do
120
+ with_label_for @user, :name, :string
121
+ assert_select 'form label abbr[title=campo requerido]', '*'
122
+ end
123
+ end
124
+
125
+ test 'label should use i18n to find required mark' do
126
+ store_translations(:en, :simple_form => { :required => { :mark => '*-*' }}) do
127
+ with_label_for @user, :name, :string
128
+ assert_select 'form label abbr', '*-*'
129
+ end
130
+ end
131
+
132
+ test 'label should use i18n to find required string tag' do
133
+ store_translations(:en, :simple_form => { :required => { :html => '<span class="required" title="requerido">*</span>' }}) do
134
+ with_label_for @user, :name, :string
135
+ assert_no_select 'form label abbr'
136
+ assert_select 'form label span.required[title=requerido]', '*'
137
+ end
138
+ end
139
+
140
+ test 'label should allow overwriting input id' do
141
+ with_label_for @user, :name, :string, :input_html => { :id => 'my_new_id' }
142
+ assert_select 'label[for=my_new_id]'
143
+ end
144
+
145
+ test 'label should use default input id when it was not overridden' do
146
+ with_label_for @user, :name, :string, :input_html => { :class => 'my_new_id' }
147
+ assert_select 'label[for=user_name]'
148
+ end
149
+
150
+ test 'label should be generated properly when object is not present' do
151
+ with_label_for :project, :name, :string
152
+ assert_select 'label[for=project_name]', /Name/
153
+ end
154
+
155
+ test 'label should use i18n properly when object is not present' do
156
+ store_translations(:en, :simple_form => { :labels => {
157
+ :project => { :name => 'Nome' }
158
+ } } ) do
159
+ with_label_for :project, :name, :string
160
+ assert_select 'label[for=project_name]', /Nome/
161
+ end
162
+ end
163
+
164
+ test 'label should add required by default when object is not present' do
165
+ with_label_for :project, :name, :string
166
+ assert_select 'label.required[for=project_name]'
167
+ with_label_for :project, :description, :string, :required => false
168
+ assert_no_select 'label.required[for=project_description]'
169
+ end
170
+ end
@@ -0,0 +1,550 @@
1
+ require 'test_helper'
2
+
3
+ class FormBuilderTest < ActionView::TestCase
4
+
5
+ def with_form_for(object, *args, &block)
6
+ simple_form_for object do |f|
7
+ concat f.input(*args, &block)
8
+ end
9
+ end
10
+
11
+ def with_button_for(object, *args)
12
+ simple_form_for object do |f|
13
+ concat f.button(*args)
14
+ end
15
+ end
16
+
17
+ def with_error_for(object, *args)
18
+ simple_form_for object do |f|
19
+ concat f.error(*args)
20
+ end
21
+ end
22
+
23
+ def with_hint_for(object, *args)
24
+ simple_form_for object do |f|
25
+ concat f.hint(*args)
26
+ end
27
+ end
28
+
29
+ def with_label_for(object, *args)
30
+ simple_form_for object do |f|
31
+ concat f.label(*args)
32
+ end
33
+ end
34
+
35
+ def with_association_for(object, *args)
36
+ simple_form_for object do |f|
37
+ concat f.association(*args)
38
+ end
39
+ end
40
+
41
+ # All
42
+ test 'nested simple fields should yields an instance of FormBuilder' do
43
+ simple_form_for :user do |f|
44
+ f.simple_fields_for :posts do |posts_form|
45
+ assert posts_form.instance_of?(SimpleForm::FormBuilder)
46
+ end
47
+ end
48
+ end
49
+
50
+ test 'builder input is html safe' do
51
+ simple_form_for @user do |f|
52
+ assert f.input(:name).html_safe?
53
+ end
54
+ end
55
+
56
+ test 'builder input should allow a block to configure input' do
57
+ with_form_for @user, :name do
58
+ concat text_field_tag :foo, :bar, :id => :cool
59
+ end
60
+ assert_no_select 'input.string'
61
+ assert_select 'input#cool'
62
+ end
63
+
64
+ # INPUT TYPES
65
+ test 'builder should generate text fields for string columns' do
66
+ with_form_for @user, :name
67
+ assert_select 'form input#user_name.string'
68
+ end
69
+
70
+ test 'builder should generate text areas for text columns' do
71
+ with_form_for @user, :description
72
+ assert_select 'form textarea#user_description.text'
73
+ end
74
+
75
+ test 'builder should generate a checkbox for boolean columns' do
76
+ with_form_for @user, :active
77
+ assert_select 'form input[type=checkbox]#user_active.boolean'
78
+ end
79
+
80
+ test 'builder should use integer text field for integer columns' do
81
+ with_form_for @user, :age
82
+ assert_select 'form input#user_age.integer'
83
+ end
84
+
85
+ test 'builder should generate decimal text field for decimal columns' do
86
+ with_form_for @user, :credit_limit
87
+ assert_select 'form input#user_credit_limit.decimal'
88
+ end
89
+
90
+ test 'builder should generate password fields for columns that matches password' do
91
+ with_form_for @user, :password
92
+ assert_select 'form input#user_password.password'
93
+ end
94
+
95
+ test 'builder should generate country fields for columns that matches country' do
96
+ with_form_for @user, :residence_country
97
+ assert_select 'form select#user_residence_country.country'
98
+ end
99
+
100
+ test 'builder should generate time_zone fields for columns that matches time_zone' do
101
+ with_form_for @user, :time_zone
102
+ assert_select 'form select#user_time_zone.time_zone'
103
+ end
104
+
105
+ test 'builder should generate date select for date columns' do
106
+ with_form_for @user, :born_at
107
+ assert_select 'form select#user_born_at_1i.date'
108
+ end
109
+
110
+ test 'builder should generate time select for time columns' do
111
+ with_form_for @user, :delivery_time
112
+ assert_select 'form select#user_delivery_time_4i.time'
113
+ end
114
+
115
+ test 'builder should generate datetime select for datetime columns' do
116
+ with_form_for @user, :created_at
117
+ assert_select 'form select#user_created_at_1i.datetime'
118
+ end
119
+
120
+ test 'builder should generate datetime select for timestamp columns' do
121
+ with_form_for @user, :updated_at
122
+ assert_select 'form select#user_updated_at_1i.datetime'
123
+ end
124
+
125
+ test 'builder should generate file for file columns' do
126
+ @user.avatar = mock("file")
127
+ @user.avatar.expects(:respond_to?).with(:mounted_as).returns(false)
128
+ @user.avatar.expects(:respond_to?).with(:file?).returns(false)
129
+ @user.avatar.expects(:respond_to?).with(:public_filename).returns(true)
130
+
131
+ with_form_for @user, :avatar
132
+ assert_select 'form input#user_avatar.file'
133
+ end
134
+
135
+ test 'build should generate select if a collection is given' do
136
+ with_form_for @user, :age, :collection => 1..60
137
+ assert_select 'form select#user_age.select'
138
+ end
139
+
140
+ test 'builder should allow overriding default input type for text' do
141
+ with_form_for @user, :name, :as => :text
142
+ assert_no_select 'form input#user_name'
143
+ assert_select 'form textarea#user_name.text'
144
+
145
+ with_form_for @user, :active, :as => :radio
146
+ assert_no_select 'form input[type=checkbox]'
147
+ assert_select 'form input.radio[type=radio]', :count => 2
148
+
149
+ with_form_for @user, :born_at, :as => :string
150
+ assert_no_select 'form select'
151
+ assert_select 'form input#user_born_at.string'
152
+ end
153
+
154
+ # COMMON OPTIONS
155
+ test 'builder should allow passing options to input' do
156
+ with_form_for @user, :name, :input_html => { :class => 'my_input', :id => 'my_input' }
157
+ assert_select 'form input#my_input.my_input.string'
158
+ end
159
+
160
+ test 'builder should generate a input with label' do
161
+ with_form_for @user, :name
162
+ assert_select 'form label.string[for=user_name]', /Name/
163
+ end
164
+
165
+ test 'builder should be able to disable the label for a input' do
166
+ with_form_for @user, :name, :label => false
167
+ assert_no_select 'form label'
168
+ end
169
+
170
+ test 'builder should use custom label' do
171
+ with_form_for @user, :name, :label => 'Yay!'
172
+ assert_select 'form label', /Yay!/
173
+ end
174
+
175
+ test 'builder should pass options to label' do
176
+ with_form_for @user, :name, :label_html => { :id => "cool" }
177
+ assert_select 'form label#cool', /Name/
178
+ end
179
+
180
+ test 'builder should not generate hints for a input' do
181
+ with_form_for @user, :name
182
+ assert_no_select 'span.hint'
183
+ end
184
+
185
+ test 'builder should be able to add a hint for a input' do
186
+ with_form_for @user, :name, :hint => 'test'
187
+ assert_select 'span.hint', 'test'
188
+ end
189
+
190
+ test 'builder should be able to disable a hint even if it exists in i18n' do
191
+ store_translations(:en, :simple_form => { :hints => { :name => 'Hint test' } }) do
192
+ with_form_for @user, :name, :hint => false
193
+ assert_no_select 'span.hint'
194
+ end
195
+ end
196
+
197
+ test 'builder should pass options to hint' do
198
+ with_form_for @user, :name, :hint => 'test', :hint_html => { :id => "cool" }
199
+ assert_select 'span.hint#cool', 'test'
200
+ end
201
+
202
+ test 'builder should generate errors for attribute without errors' do
203
+ with_form_for @user, :credit_limit
204
+ assert_no_select 'span.errors'
205
+ end
206
+
207
+ test 'builder should generate errors for attribute with errors' do
208
+ with_form_for @user, :name
209
+ assert_select 'span.error', "can't be blank"
210
+ end
211
+
212
+ test 'builder should be able to disable showing errors for a input' do
213
+ with_form_for @user, :name, :error => false
214
+ assert_no_select 'span.error'
215
+ end
216
+
217
+ test 'builder should pass options to errors' do
218
+ with_form_for @user, :name, :error_html => { :id => "cool" }
219
+ assert_select 'span.error#cool', "can't be blank"
220
+ end
221
+
222
+ test 'builder input should be required by default' do
223
+ with_form_for @user, :name
224
+ assert_select 'input.required#user_name'
225
+ end
226
+
227
+ test 'builder input should allow disabling required' do
228
+ with_form_for @user, :name, :required => false
229
+ assert_no_select 'input.required'
230
+ assert_select 'input.optional#user_name'
231
+ end
232
+
233
+ # WRAPPERS
234
+ test 'builder support wrapping around an specific tag' do
235
+ swap SimpleForm, :wrapper_tag => :p do
236
+ with_form_for @user, :name
237
+ assert_select 'form p label[for=user_name]'
238
+ assert_select 'form p input#user_name.string'
239
+ end
240
+ end
241
+
242
+ test 'builder wrapping tag adds default css classes' do
243
+ swap SimpleForm, :wrapper_tag => :p do
244
+ with_form_for @user, :name
245
+ assert_select 'form p.required.string'
246
+
247
+ with_form_for @user, :age, :required => false
248
+ assert_select 'form p.optional.integer'
249
+ end
250
+ end
251
+
252
+ test 'builder wrapping tag allow custom options to be given' do
253
+ swap SimpleForm, :wrapper_tag => :p do
254
+ with_form_for @user, :name, :wrapper_html => { :id => "super_cool", :class => 'yay' }
255
+ assert_select 'form p#super_cool.required.string.yay'
256
+ end
257
+ end
258
+
259
+ test 'builder allows wrapper tag to be given on demand' do
260
+ simple_form_for @user do |f|
261
+ concat f.input :name, :wrapper_tag => :b
262
+ end
263
+ assert_select 'form b.required.string'
264
+ end
265
+
266
+ # WITHOUT OBJECT
267
+ test 'builder should generate properly when object is not present' do
268
+ with_form_for :project, :name
269
+ assert_select 'form input.string#project_name'
270
+ end
271
+
272
+ test 'builder should generate password fields based on attribute name when object is not present' do
273
+ with_form_for :project, :password_confirmation
274
+ assert_select 'form input[type=password].password#project_password_confirmation'
275
+ end
276
+
277
+ test 'builder should generate text fields by default for all attributes when object is not present' do
278
+ with_form_for :project, :created_at
279
+ assert_select 'form input.string#project_created_at'
280
+ with_form_for :project, :budget
281
+ assert_select 'form input.string#project_budget'
282
+ end
283
+
284
+ test 'builder should allow overriding input type when object is not present' do
285
+ with_form_for :project, :created_at, :as => :datetime
286
+ assert_select 'form select.datetime#project_created_at_1i'
287
+ with_form_for :project, :budget, :as => :decimal
288
+ assert_select 'form input.decimal#project_budget'
289
+ end
290
+
291
+ # ERRORS
292
+ test 'builder should generate an error tag for the attribute' do
293
+ with_error_for @user, :name
294
+ assert_select 'span.error', "can't be blank"
295
+ end
296
+
297
+ test 'builder should allow passing options to error tag' do
298
+ with_error_for @user, :name, :id => 'name_error'
299
+ assert_select 'span.error#name_error', "can't be blank"
300
+ end
301
+
302
+ # HINTS
303
+ test 'builder should generate a hint tag for the attribute' do
304
+ store_translations(:en, :simple_form => { :hints => { :user => { :name => "Add your name" }}}) do
305
+ with_hint_for @user, :name
306
+ assert_select 'span.hint', 'Add your name'
307
+ end
308
+ end
309
+
310
+ test 'builder should generate a hint component tag for the given text' do
311
+ with_hint_for @user, 'Hello World!'
312
+ assert_select 'span.hint', 'Hello World!'
313
+ end
314
+
315
+ test 'builder should allow passing options to hint tag' do
316
+ with_hint_for @user, :name, :hint => 'Hello World!', :id => 'name_hint'
317
+ assert_select 'span.hint#name_hint', 'Hello World!'
318
+ end
319
+
320
+ # LABELS
321
+ test 'builder should generate a label for the attribute' do
322
+ with_label_for @user, :name
323
+ assert_select 'label.string[for=user_name]', /Name/
324
+ end
325
+
326
+ test 'builder should allow passing options to label tag' do
327
+ with_label_for @user, :name, :label => 'My label', :id => 'name_label'
328
+ assert_select 'label.string.required#name_label', /My label/
329
+ end
330
+
331
+ test 'builder should fallback to default label when string is given' do
332
+ with_label_for @user, :name, 'Nome do usuário'
333
+ assert_select 'label', 'Nome do usuário'
334
+ assert_no_select 'label.string'
335
+ end
336
+
337
+ test 'builder allows label order to be changed' do
338
+ swap SimpleForm, :label_text => lambda { |l, r| "#{l}:" } do
339
+ with_label_for @user, :age
340
+ assert_select 'label.integer[for=user_age]', "Age:"
341
+ end
342
+ end
343
+
344
+ # BUTTONS
345
+ test 'builder should create buttons' do
346
+ with_button_for :post, :submit
347
+ assert_select 'form input.submit[type=submit][value=Submit Post]'
348
+ end
349
+
350
+ test 'builder should create buttons for new records' do
351
+ @user.new_record!
352
+ with_button_for @user, :submit
353
+ assert_select 'form input.create[type=submit][value=Create User]'
354
+ end
355
+
356
+ test 'builder should create buttons for existing records' do
357
+ with_button_for @user, :submit
358
+ assert_select 'form input.update[type=submit][value=Update User]'
359
+ end
360
+
361
+ test 'builder should create buttons using human_name' do
362
+ @user.class.expects(:human_name).returns("Usuario")
363
+ with_button_for @user, :submit
364
+ assert_select 'form input[type=submit][value=Update Usuario]'
365
+ end
366
+
367
+ test 'builder should create object buttons with localized labels' do
368
+ store_translations(:en, :simple_form => { :buttons => {
369
+ :create => "Criar {{model}}", :update => "Atualizar {{model}}" }}) do
370
+ with_button_for @user, :submit
371
+ assert_select 'form input[type=submit][value=Atualizar User]'
372
+
373
+ @user.new_record!
374
+ with_button_for @user, :submit
375
+ assert_select 'form input[type=submit][value=Criar User]'
376
+ end
377
+ end
378
+
379
+ test 'builder should create non object buttons with localized labels' do
380
+ store_translations(:en, :simple_form => { :buttons => { :submit => "Enviar {{model}}" }}) do
381
+ with_button_for :post, :submit
382
+ assert_select 'form input[type=submit][value=Enviar Post]'
383
+ end
384
+ end
385
+
386
+ test 'builder forwards first options as button text' do
387
+ with_button_for :post, :submit, "Send it!"
388
+ assert_select 'form input[type=submit][value=Send it!]'
389
+ end
390
+
391
+ test 'builder forwards label option as button text' do
392
+ with_button_for :post, :submit, :label => "Send it!"
393
+ assert_select 'form input[type=submit][value=Send it!]'
394
+ end
395
+
396
+ test 'builder forwards all options except label to button' do
397
+ with_button_for :post, :submit, :class => "cool", :id => "super"
398
+ assert_select 'form input#super.submit.cool[type=submit]'
399
+ end
400
+
401
+ test 'builder calls any button tag' do
402
+ with_button_for :post, :image_submit, "/image/foo/bar"
403
+ assert_select 'form input[src=/image/foo/bar][type=image]'
404
+ end
405
+
406
+ # ASSOCIATIONS
407
+ test 'builder should not allow creating an association input when no object exists' do
408
+ assert_raise ArgumentError do
409
+ with_association_for :post, :author
410
+ end
411
+ end
412
+
413
+ test 'builder association with a block call simple_fields_for' do
414
+ simple_form_for @user do |f|
415
+ f.association :posts do |posts_form|
416
+ assert posts_form.instance_of?(SimpleForm::FormBuilder)
417
+ end
418
+ end
419
+ end
420
+
421
+ test 'builder association forwards collection to simple_fields_for' do
422
+ calls = 0
423
+ simple_form_for @user do |f|
424
+ f.association :company, :collection => Company.all do |c|
425
+ calls += 1
426
+ end
427
+ end
428
+
429
+ assert_equal calls, 3
430
+ end
431
+
432
+ # ASSOCIATIONS - BELONGS TO
433
+ test 'builder creates a select for belongs_to associations' do
434
+ with_association_for @user, :company
435
+ assert_select 'form select.select#user_company_id'
436
+ assert_select 'form select option[value=1]', 'Company 1'
437
+ assert_select 'form select option[value=2]', 'Company 2'
438
+ assert_select 'form select option[value=3]', 'Company 3'
439
+ end
440
+
441
+ test 'builder allows collection radio for belongs_to associations' do
442
+ with_association_for @user, :company, :as => :radio
443
+ assert_select 'form input.radio#user_company_id_1'
444
+ assert_select 'form input.radio#user_company_id_2'
445
+ assert_select 'form input.radio#user_company_id_3'
446
+ end
447
+
448
+ test 'builder marks the record which already belongs to the user' do
449
+ @user.company_id = 2
450
+ with_association_for @user, :company, :as => :radio
451
+ assert_no_select 'form input.radio#user_company_id_1[checked=checked]'
452
+ assert_select 'form input.radio#user_company_id_2[checked=checked]'
453
+ assert_no_select 'form input.radio#user_company_id_3[checked=checked]'
454
+ end
455
+
456
+ # ASSOCIATIONS - FINDERS
457
+ test 'builder should allow passing conditions to find collection' do
458
+ with_association_for @user, :company, :conditions => { :id => 1 }
459
+ assert_select 'form select.select#user_company_id'
460
+ assert_select 'form select option[value=1]'
461
+ assert_no_select 'form select option[value=2]'
462
+ assert_no_select 'form select option[value=3]'
463
+ end
464
+
465
+ test 'builder should use reflection conditions to find collection' do
466
+ with_association_for @user, :special_company
467
+ assert_select 'form select.select#user_special_company_id'
468
+ assert_select 'form select option[value=1]'
469
+ assert_no_select 'form select option[value=2]'
470
+ assert_no_select 'form select option[value=3]'
471
+ end
472
+
473
+ test 'builder should allow passing order to find collection' do
474
+ with_association_for @user, :company, :order => 'name'
475
+ assert_select 'form select.select#user_company_id'
476
+ assert_no_select 'form select option[value=1]'
477
+ assert_no_select 'form select option[value=2]'
478
+ assert_select 'form select option[value=3]'
479
+ end
480
+
481
+ test 'builder should allow passing include option to find collection' do
482
+ with_association_for @user, :company, :include => :city
483
+ assert_select 'form select.select#user_company_id'
484
+ assert_select 'form select option[value=1]'
485
+ assert_select 'form select option[value=2]'
486
+ assert_no_select 'form select option[value=3]'
487
+ end
488
+
489
+ test 'builder should allow passing joins option to find collection' do
490
+ with_association_for @user, :company, :joins => :city
491
+ assert_select 'form select.select#user_company_id'
492
+ assert_select 'form select option[value=2]'
493
+ assert_select 'form select option[value=3]'
494
+ assert_no_select 'form select option[value=1]'
495
+ end
496
+
497
+ test 'builder should allow overriding collection to association input' do
498
+ with_association_for @user, :company, :include_blank => false,
499
+ :collection => [Company.new(999, 'Teste')]
500
+ assert_select 'form select.select#user_company_id'
501
+ assert_no_select 'form select option[value=1]'
502
+ assert_select 'form select option[value=999]', 'Teste'
503
+ assert_select 'form select option', :count => 1
504
+ end
505
+
506
+ # ASSOCIATIONS - has_*
507
+ test 'builder does not allow has_one associations' do
508
+ assert_raise RuntimeError do
509
+ with_association_for @user, :first_company, :as => :radio
510
+ end
511
+ end
512
+
513
+ test 'builder creates a select with multiple options for collection associations' do
514
+ with_association_for @user, :tags
515
+ assert_select 'form select.select#user_tag_ids'
516
+ assert_select 'form select[multiple=multiple][size=5]'
517
+ assert_select 'form select option[value=1]', 'Tag 1'
518
+ assert_select 'form select option[value=2]', 'Tag 2'
519
+ assert_select 'form select option[value=3]', 'Tag 3'
520
+ end
521
+
522
+ test 'builder allows size to be overwritten for collection associations' do
523
+ with_association_for @user, :tags, :input_html => { :size => 10 }
524
+ assert_select 'form select[multiple=multiple][size=10]'
525
+ end
526
+
527
+ test 'builder marks all selected records which already belongs to user' do
528
+ @user.tag_ids = [1, 2]
529
+ with_association_for @user, :tags
530
+ assert_select 'form select option[value=1][selected=selected]'
531
+ assert_select 'form select option[value=2][selected=selected]'
532
+ assert_no_select 'form select option[value=3][selected=selected]'
533
+ end
534
+
535
+ test 'builder allows a collection of check boxes for collection associations' do
536
+ @user.tag_ids = [1, 2]
537
+ with_association_for @user, :tags, :as => :check_boxes
538
+ assert_select 'form input#user_tag_ids_1[type=checkbox]'
539
+ assert_select 'form input#user_tag_ids_2[type=checkbox]'
540
+ assert_select 'form input#user_tag_ids_3[type=checkbox]'
541
+ end
542
+
543
+ test 'builder marks all selected records for collection boxes' do
544
+ @user.tag_ids = [1, 2]
545
+ with_association_for @user, :tags, :as => :check_boxes
546
+ assert_select 'form input[type=checkbox][value=1][checked=checked]'
547
+ assert_select 'form input[type=checkbox][value=2][checked=checked]'
548
+ assert_no_select 'form input[type=checkbox][value=3][checked=checked]'
549
+ end
550
+ end