formtastic 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/../spec_helper'
3
+
4
+ describe 'file input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+
12
+ semantic_form_for(@new_post) do |builder|
13
+ concat(builder.input(:body, :as => :file))
14
+ end
15
+ end
16
+
17
+ it_should_have_input_wrapper_with_class("file")
18
+ it_should_have_input_wrapper_with_id("post_body_input")
19
+ it_should_have_label_with_text(/Body/)
20
+ it_should_have_label_for("post_body")
21
+ it_should_have_input_with_id("post_body")
22
+ it_should_have_input_with_name("post[body]")
23
+ it_should_apply_error_logic_for_input_type(:file)
24
+
25
+ it 'should use input_html to style inputs' do
26
+ semantic_form_for(@new_post) do |builder|
27
+ concat(builder.input(:title, :as => :file, :input_html => { :class => 'myclass' }))
28
+ end
29
+ output_buffer.should have_tag("form li input.myclass")
30
+ end
31
+
32
+ end
33
+
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/../spec_helper'
3
+
4
+ describe 'hidden input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+
12
+ semantic_form_for(@new_post) do |builder|
13
+ concat(builder.input(:secret, :as => :hidden))
14
+ end
15
+ end
16
+
17
+ it_should_have_input_wrapper_with_class("hidden")
18
+ it_should_have_input_wrapper_with_id("post_secret_input")
19
+ it_should_not_have_a_label
20
+
21
+ it "should generate a input field" do
22
+ output_buffer.should have_tag("form li input#post_secret")
23
+ output_buffer.should have_tag("form li input[@type=\"hidden\"]")
24
+ output_buffer.should have_tag("form li input[@name=\"post[secret]\"]")
25
+ end
26
+
27
+ it "should not render inline errors" do
28
+ @errors = mock('errors')
29
+ @errors.stub!(:[]).with(:secret).and_return(["foo", "bah"])
30
+ @new_post.stub!(:errors).and_return(@errors)
31
+
32
+ semantic_form_for(@new_post) do |builder|
33
+ concat(builder.input(:secret, :as => :hidden))
34
+ end
35
+
36
+ output_buffer.should_not have_tag("form li p.inline-errors")
37
+ output_buffer.should_not have_tag("form li ul.errors")
38
+ end
39
+
40
+ end
41
+
@@ -0,0 +1,44 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/../spec_helper'
3
+
4
+ describe 'numeric input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+
12
+ semantic_form_for(@new_post) do |builder|
13
+ concat(builder.input(:title, :as => :numeric))
14
+ end
15
+ end
16
+
17
+ it_should_have_input_wrapper_with_class(:numeric)
18
+ it_should_have_input_wrapper_with_id("post_title_input")
19
+ it_should_have_label_with_text(/Title/)
20
+ it_should_have_label_for("post_title")
21
+ it_should_have_input_with_id("post_title")
22
+ it_should_have_input_with_type(:text)
23
+ it_should_have_input_with_name("post[title]")
24
+ it_should_use_default_text_field_size_when_method_has_no_database_column(:string)
25
+ it_should_apply_custom_input_attributes_when_input_html_provided(:string)
26
+ it_should_apply_custom_for_to_label_when_input_html_id_provided(:string)
27
+ it_should_apply_error_logic_for_input_type(:numeric)
28
+
29
+ describe "when no object is provided" do
30
+ before do
31
+ semantic_form_for(:project, :url => 'http://test.host/') do |builder|
32
+ concat(builder.input(:title, :as => :numeric))
33
+ end
34
+ end
35
+
36
+ it_should_have_label_with_text(/Title/)
37
+ it_should_have_label_for("project_title")
38
+ it_should_have_input_with_id("project_title")
39
+ it_should_have_input_with_type(:text)
40
+ it_should_have_input_with_name("project[title]")
41
+ end
42
+
43
+ end
44
+
@@ -0,0 +1,46 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/../spec_helper'
3
+
4
+ describe 'password input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+
12
+ semantic_form_for(@new_post) do |builder|
13
+ concat(builder.input(:title, :as => :password))
14
+ end
15
+ end
16
+
17
+ it_should_have_input_wrapper_with_class(:password)
18
+ it_should_have_input_wrapper_with_id("post_title_input")
19
+ it_should_have_label_with_text(/Title/)
20
+ it_should_have_label_for("post_title")
21
+ it_should_have_input_with_id("post_title")
22
+ it_should_have_input_with_type(:password)
23
+ it_should_have_input_with_name("post[title]")
24
+ it_should_have_maxlength_matching_column_limit
25
+ it_should_use_default_text_field_size_for_columns_longer_than_default_text_field_size(:string)
26
+ it_should_use_column_size_for_columns_shorter_than_default_text_field_size(:string)
27
+ it_should_use_default_text_field_size_when_method_has_no_database_column(:string)
28
+ it_should_apply_custom_input_attributes_when_input_html_provided(:string)
29
+ it_should_apply_custom_for_to_label_when_input_html_id_provided(:string)
30
+ it_should_apply_error_logic_for_input_type(:password)
31
+
32
+ describe "when no object is provided" do
33
+ before do
34
+ semantic_form_for(:project, :url => 'http://test.host/') do |builder|
35
+ concat(builder.input(:title, :as => :password))
36
+ end
37
+ end
38
+
39
+ it_should_have_label_with_text(/Title/)
40
+ it_should_have_label_for("project_title")
41
+ it_should_have_input_with_id("project_title")
42
+ it_should_have_input_with_type(:password)
43
+ it_should_have_input_with_name("project[title]")
44
+ end
45
+
46
+ end
@@ -0,0 +1,113 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/../spec_helper'
3
+
4
+ describe 'radio input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ end
12
+
13
+ describe 'for belongs_to association' do
14
+ before do
15
+ semantic_form_for(@new_post) do |builder|
16
+ concat(builder.input(:author, :as => :radio, :value_as_class => true))
17
+ end
18
+ end
19
+
20
+ it_should_have_input_wrapper_with_class("radio")
21
+ it_should_have_input_wrapper_with_id("post_author_input")
22
+ it_should_have_a_nested_fieldset
23
+ it_should_apply_error_logic_for_input_type(:radio)
24
+ it_should_use_the_collection_when_provided(:radio, 'input')
25
+
26
+
27
+ it 'should generate a legend containing label text for the input' do
28
+ output_buffer.should have_tag('form li fieldset legend')
29
+ output_buffer.should have_tag('form li fieldset legend', /Author/)
30
+ end
31
+
32
+ it 'should generate an ordered list with a list item for each choice' do
33
+ output_buffer.should have_tag('form li fieldset ol')
34
+ output_buffer.should have_tag('form li fieldset ol li', :count => ::Author.find(:all).size)
35
+ end
36
+
37
+ it 'should have one option with a "checked" attribute' do
38
+ output_buffer.should have_tag('form li input[@checked]', :count => 1)
39
+ end
40
+
41
+ describe "each choice" do
42
+
43
+ it 'should contain a label for the radio input with a nested input and label text' do
44
+ ::Author.find(:all).each do |author|
45
+ output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
46
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_id_#{author.id}']")
47
+ end
48
+ end
49
+
50
+ it 'should use values as li.class when value_as_class is true' do
51
+ ::Author.find(:all).each do |author|
52
+ output_buffer.should have_tag("form li fieldset ol li.#{author.id} label")
53
+ end
54
+ end
55
+
56
+ it "should have a radio input" do
57
+ ::Author.find(:all).each do |author|
58
+ output_buffer.should have_tag("form li fieldset ol li label input#post_author_id_#{author.id}")
59
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
60
+ output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
61
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='post[author_id]']")
62
+ end
63
+ end
64
+
65
+ it "should mark input as checked if it's the the existing choice" do
66
+ @new_post.author_id.should == @bob.id
67
+ @new_post.author.id.should == @bob.id
68
+ @new_post.author.should == @bob
69
+
70
+ semantic_form_for(@new_post) do |builder|
71
+ concat(builder.input(:author, :as => :radio))
72
+ end
73
+
74
+ output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
75
+ end
76
+ end
77
+
78
+ describe 'and no object is given' do
79
+ before(:each) do
80
+ output_buffer.replace ''
81
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
82
+ concat(builder.input(:author_id, :as => :radio, :collection => ::Author.find(:all)))
83
+ end
84
+ end
85
+
86
+ it 'should generate a fieldset with legend' do
87
+ output_buffer.should have_tag('form li fieldset legend', /Author/)
88
+ end
89
+
90
+ it 'should generate an li tag for each item in the collection' do
91
+ output_buffer.should have_tag('form li fieldset ol li', :count => ::Author.find(:all).size)
92
+ end
93
+
94
+ it 'should generate labels for each item' do
95
+ ::Author.find(:all).each do |author|
96
+ output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
97
+ output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
98
+ end
99
+ end
100
+
101
+ it 'should generate inputs for each item' do
102
+ ::Author.find(:all).each do |author|
103
+ output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
104
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
105
+ output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
106
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id]']")
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ end
113
+
@@ -0,0 +1,263 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/../spec_helper'
3
+
4
+ describe 'select input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ end
12
+
13
+ describe 'for a belongs_to association' do
14
+ before do
15
+ semantic_form_for(@new_post) do |builder|
16
+ concat(builder.input(:author, :as => :select))
17
+ end
18
+ end
19
+
20
+ it_should_have_input_wrapper_with_class("select")
21
+ it_should_have_input_wrapper_with_id("post_author_input")
22
+ it_should_have_label_with_text(/Author/)
23
+ it_should_have_label_for('post_author_id')
24
+ it_should_apply_error_logic_for_input_type(:select)
25
+ it_should_call_find_on_association_class_when_no_collection_is_provided(:select)
26
+ it_should_use_the_collection_when_provided(:select, 'option')
27
+
28
+ it 'should have a select inside the wrapper' do
29
+ output_buffer.should have_tag('form li select')
30
+ output_buffer.should have_tag('form li select#post_author_id')
31
+ end
32
+
33
+ it 'should not create a multi-select' do
34
+ output_buffer.should_not have_tag('form li select[@multiple]')
35
+ end
36
+
37
+ it 'should create a select without size' do
38
+ output_buffer.should_not have_tag('form li select[@size]')
39
+ end
40
+
41
+ it 'should have a blank option' do
42
+ output_buffer.should have_tag("form li select option[@value='']")
43
+ end
44
+
45
+ it 'should have a select option for each Author' do
46
+ output_buffer.should have_tag('form li select option', :count => ::Author.find(:all).size + 1)
47
+ ::Author.find(:all).each do |author|
48
+ output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
49
+ end
50
+ end
51
+
52
+ it 'should have one option with a "selected" attribute' do
53
+ output_buffer.should have_tag('form li select option[@selected]', :count => 1)
54
+ end
55
+
56
+ it 'should not singularize the association name' do
57
+ @new_post.stub!(:author_status).and_return(@bob)
58
+ @new_post.stub!(:author_status_id).and_return(@bob.id)
59
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
60
+
61
+ semantic_form_for(@new_post) do |builder|
62
+ concat(builder.input(:author_status, :as => :select))
63
+ end
64
+
65
+ output_buffer.should have_tag('form li select#post_author_status_id')
66
+ end
67
+ end
68
+
69
+ describe 'for a belongs_to association with :group_by => :continent' do
70
+ before do
71
+ @authors = [@bob, @fred, @fred, @fred]
72
+ ::Author.stub!(:find).and_return(@authors)
73
+ @continent_names = %w(Europe Africa)
74
+ @continents = (0..1).map { |i| mock("continent", :id => (100 - i) ) }
75
+ @authors[0..1].each_with_index { |author, i| author.stub!(:continent).and_return(@continents[i]) }
76
+ @continents.each_with_index do |continent, i|
77
+ continent.stub!(:to_label).and_return(@continent_names[i])
78
+ continent.stub!(:authors).and_return([@authors[i]])
79
+ end
80
+
81
+ semantic_form_for(@new_post) do |builder|
82
+ concat(builder.input(:author, :as => :select, :group_by => :continent ) )
83
+ concat(builder.input(:author, :as => :select, :group_by => :continent, :group_label_method => :id ) )
84
+ end
85
+ end
86
+
87
+ it_should_have_input_wrapper_with_class("select")
88
+ it_should_have_input_wrapper_with_id("post_author_input")
89
+ it_should_have_label_with_text(/Author/)
90
+ it_should_have_label_for('post_author_id')
91
+
92
+ # TODO, need to find a way to repeat some of the specs and logic from the belongs_to specs without grouping
93
+
94
+ 0.upto(1) do |i|
95
+ it 'should have all option groups and the right values' do
96
+ output_buffer.should have_tag("form li select optgroup[@label='#{@continent_names[i]}']", @authors[i].to_label)
97
+ end
98
+
99
+ it 'should have custom group labels' do
100
+ output_buffer.should have_tag("form li select optgroup[@label='#{@continents[i].id}']", @authors[i].to_label)
101
+ end
102
+ end
103
+
104
+ it 'should have no duplicate groups' do
105
+ output_buffer.should have_tag('form li select optgroup', :count => 4)
106
+ end
107
+
108
+ it 'should sort the groups on the label method' do
109
+ output_buffer.should have_tag("form li select optgroup[@label='Africa']")
110
+ output_buffer.should have_tag("form li select optgroup[@label='99']")
111
+ end
112
+
113
+ it 'should call find with :include for more optimized queries' do
114
+ Author.should_receive(:find).with(:all, :include => :continent)
115
+
116
+ semantic_form_for(@new_post) do |builder|
117
+ concat(builder.input(:author, :as => :select, :group_by => :continent ) )
118
+ end
119
+ end
120
+ end
121
+
122
+ describe 'for a has_many association' do
123
+ before do
124
+ semantic_form_for(@fred) do |builder|
125
+ concat(builder.input(:posts, :as => :select))
126
+ end
127
+ end
128
+
129
+ it_should_have_input_wrapper_with_class("select")
130
+ it_should_have_input_wrapper_with_id("author_posts_input")
131
+ it_should_have_label_with_text(/Post/)
132
+ it_should_have_label_for('author_post_ids')
133
+ it_should_apply_error_logic_for_input_type(:select)
134
+ it_should_call_find_on_association_class_when_no_collection_is_provided(:select)
135
+ it_should_use_the_collection_when_provided(:select, 'option')
136
+
137
+ it 'should have a select inside the wrapper' do
138
+ output_buffer.should have_tag('form li select')
139
+ output_buffer.should have_tag('form li select#author_post_ids')
140
+ end
141
+
142
+ it 'should have a multi-select select' do
143
+ output_buffer.should have_tag('form li select[@multiple="multiple"]')
144
+ end
145
+
146
+ it 'should have a select option for each Post' do
147
+ output_buffer.should have_tag('form li select option', :count => ::Post.find(:all).size)
148
+ ::Post.find(:all).each do |post|
149
+ output_buffer.should have_tag("form li select option[@value='#{post.id}']", /#{post.to_label}/)
150
+ end
151
+ end
152
+
153
+ it 'should not have a blank option' do
154
+ output_buffer.should_not have_tag("form li select option[@value='']")
155
+ end
156
+
157
+ it 'should have one option with a "selected" attribute' do
158
+ output_buffer.should have_tag('form li select option[@selected]', :count => 1)
159
+ end
160
+ end
161
+
162
+ describe 'for a has_and_belongs_to_many association' do
163
+ before do
164
+ semantic_form_for(@freds_post) do |builder|
165
+ concat(builder.input(:authors, :as => :select))
166
+ end
167
+ end
168
+
169
+ it_should_have_input_wrapper_with_class("select")
170
+ it_should_have_input_wrapper_with_id("post_authors_input")
171
+ it_should_have_label_with_text(/Author/)
172
+ it_should_have_label_for('post_author_ids')
173
+ it_should_apply_error_logic_for_input_type(:select)
174
+ it_should_call_find_on_association_class_when_no_collection_is_provided(:select)
175
+ it_should_use_the_collection_when_provided(:select, 'option')
176
+
177
+ it 'should have a select inside the wrapper' do
178
+ output_buffer.should have_tag('form li select')
179
+ output_buffer.should have_tag('form li select#post_author_ids')
180
+ end
181
+
182
+ it 'should have a multi-select select' do
183
+ output_buffer.should have_tag('form li select[@multiple="multiple"]')
184
+ end
185
+
186
+ it 'should have a select option for each Author' do
187
+ output_buffer.should have_tag('form li select option', :count => ::Author.find(:all).size)
188
+ ::Author.find(:all).each do |author|
189
+ output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
190
+ end
191
+ end
192
+
193
+ it 'should not have a blank option' do
194
+ output_buffer.should_not have_tag("form li select option[@value='']")
195
+ end
196
+
197
+ it 'should have one option with a "selected" attribute' do
198
+ output_buffer.should have_tag('form li select option[@selected]', :count => 1)
199
+ end
200
+ end
201
+
202
+ describe 'when :prompt => "choose something" is set' do
203
+ before do
204
+ @new_post.stub!(:author_id).and_return(nil)
205
+ semantic_form_for(@new_post) do |builder|
206
+ concat(builder.input(:author, :as => :select, :prompt => "choose author"))
207
+ end
208
+ end
209
+
210
+ it 'should have a select with prompt' do
211
+ output_buffer.should have_tag("form li select option[@value='']", /choose author/)
212
+ end
213
+
214
+ it 'should not have a blank select option' do
215
+ output_buffer.should_not have_tag("form li select option[@value='']", "")
216
+ end
217
+ end
218
+
219
+ describe 'when no object is given' do
220
+ before(:each) do
221
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
222
+ concat(builder.input(:author, :as => :select, :collection => ::Author.find(:all)))
223
+ end
224
+ end
225
+
226
+ it 'should generate label' do
227
+ output_buffer.should have_tag('form li label', /Author/)
228
+ output_buffer.should have_tag("form li label[@for='project_author']")
229
+ end
230
+
231
+ it 'should generate select inputs' do
232
+ output_buffer.should have_tag('form li select#project_author')
233
+ output_buffer.should have_tag('form li select option', :count => ::Author.find(:all).size + 1)
234
+ end
235
+
236
+ it 'should generate an option to each item' do
237
+ ::Author.find(:all).each do |author|
238
+ output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
239
+ end
240
+ end
241
+ end
242
+
243
+ describe 'when :selected is set' do
244
+ before do
245
+ @new_post.stub!(:author_id).and_return(nil)
246
+ semantic_form_for(@new_post) do |builder|
247
+ concat(builder.input(:author, :as => :select, :selected => @bob.id ))
248
+ end
249
+ end
250
+
251
+ it 'should have a selected item' do
252
+ output_buffer.should have_tag("form li select option[@selected='selected']")
253
+ end
254
+
255
+ it 'bob should be selected' do
256
+ output_buffer.should have_tag("form li select option[@selected='selected']", /bob/i)
257
+ output_buffer.should have_tag("form li select option[@selected='selected'][@value='42']")
258
+ end
259
+
260
+ end
261
+
262
+ end
263
+