formtastic 0.9.1 → 0.9.2

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.
@@ -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
+