formtastic 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,374 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/test_helper'
3
+
4
+ describe 'SemanticFormBuilder#inputs' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ end
12
+
13
+ describe 'with a block' do
14
+
15
+ describe 'when no options are provided' do
16
+ before do
17
+ output_buffer.replace 'before_builder' # clear the output buffer and sets before_builder
18
+ semantic_form_for(@new_post) do |builder|
19
+ @inputs_output = builder.inputs do
20
+ concat('hello')
21
+ end
22
+ end
23
+ end
24
+
25
+ it 'should output just the content wrapped in inputs, not the whole template' do
26
+ output_buffer.should =~ /before_builder/
27
+ @inputs_output.should_not =~ /before_builder/
28
+ end
29
+
30
+ it 'should render a fieldset inside the form, with a class of "inputs"' do
31
+ output_buffer.should have_tag("form fieldset.inputs")
32
+ end
33
+
34
+ it 'should render an ol inside the fieldset' do
35
+ output_buffer.should have_tag("form fieldset.inputs ol")
36
+ end
37
+
38
+ it 'should render the contents of the block inside the ol' do
39
+ output_buffer.should have_tag("form fieldset.inputs ol", /hello/)
40
+ end
41
+
42
+ it 'should not render a legend inside the fieldset' do
43
+ output_buffer.should_not have_tag("form fieldset.inputs legend")
44
+ end
45
+
46
+ it 'should render a fieldset even if no object is given' do
47
+ semantic_form_for(:project, :url => 'http://test.host/') do |builder|
48
+ @inputs_output = builder.inputs do
49
+ concat('bye')
50
+ end
51
+ end
52
+
53
+ output_buffer.should have_tag("form fieldset.inputs ol", /bye/)
54
+ end
55
+ end
56
+
57
+ describe 'when a :for option is provided' do
58
+
59
+ before do
60
+ @new_post.stub!(:respond_to?).and_return(true, true)
61
+ @new_post.stub!(:author).and_return(@bob)
62
+ end
63
+
64
+ it 'should render nested inputs' do
65
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
66
+
67
+ semantic_form_for(@new_post) do |builder|
68
+ builder.inputs :for => [:author, @bob] do |bob_builder|
69
+ concat(bob_builder.input(:login))
70
+ end
71
+ end
72
+
73
+ output_buffer.should have_tag("form fieldset.inputs #post_author_attributes_login")
74
+ output_buffer.should_not have_tag("form fieldset.inputs #author_login")
75
+
76
+ end
77
+
78
+ describe "as a symbol representing the association name" do
79
+
80
+ it 'should nest the inputs with an _attributes suffix on the association name' do
81
+ semantic_form_for(@new_post) do |post|
82
+ post.inputs :for => :author do |author|
83
+ concat(author.input(:login))
84
+ end
85
+ end
86
+ output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
87
+ end
88
+
89
+ end
90
+
91
+ describe 'as an array containing the a symbole for the association name and the associated object' do
92
+
93
+ it 'should nest the inputs with an _attributes suffix on the association name' do
94
+ semantic_form_for(@new_post) do |post|
95
+ post.inputs :for => [:author, @new_post.author] do |author|
96
+ concat(author.input(:login))
97
+ end
98
+ end
99
+ output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
100
+ end
101
+
102
+ end
103
+
104
+ describe 'as an associated object' do
105
+
106
+ it 'should not nest the inputs with an _attributes suffix' do
107
+ semantic_form_for(@new_post) do |post|
108
+ post.inputs :for => @new_post.author do |author|
109
+ concat(author.input(:login))
110
+ end
111
+ end
112
+ output_buffer.should have_tag("form input[@name='post[author][login]']")
113
+ end
114
+
115
+ end
116
+
117
+ it 'should raise an error if :for and block with no argument is given' do
118
+ semantic_form_for(@new_post) do |builder|
119
+ proc {
120
+ builder.inputs(:for => [:author, @bob]) do
121
+ #
122
+ end
123
+ }.should raise_error(ArgumentError, 'You gave :for option with a block to inputs method, ' <<
124
+ 'but the block does not accept any argument.')
125
+ end
126
+ end
127
+
128
+ it 'should pass options down to semantic_fields_for' do
129
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
130
+
131
+ semantic_form_for(@new_post) do |builder|
132
+ builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
133
+ concat(bob_builder.input(:login))
134
+ end
135
+ end
136
+
137
+ output_buffer.should have_tag('form fieldset ol li #post_author_attributes_10_login')
138
+ end
139
+
140
+ it 'should not add builder as a fieldset attribute tag' do
141
+ semantic_form_for(@new_post) do |builder|
142
+ builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
143
+ concat('input')
144
+ end
145
+ end
146
+
147
+ output_buffer.should_not have_tag('fieldset[@builder="Formtastic::SemanticFormHelper"]')
148
+ end
149
+
150
+ it 'should send parent_builder as an option to allow child index interpolation' do
151
+ semantic_form_for(@new_post) do |builder|
152
+ builder.instance_variable_set('@nested_child_index', 0)
153
+ builder.inputs :for => [:author, @bob], :name => 'Author #%i' do |bob_builder|
154
+ concat('input')
155
+ end
156
+ end
157
+
158
+ output_buffer.should have_tag('fieldset legend', 'Author #1')
159
+ end
160
+
161
+ it 'should also provide child index interpolation when nested child index is a hash' do
162
+ semantic_form_for(@new_post) do |builder|
163
+ builder.instance_variable_set('@nested_child_index', :author => 10)
164
+ builder.inputs :for => [:author, @bob], :name => 'Author #%i' do |bob_builder|
165
+ concat('input')
166
+ end
167
+ end
168
+
169
+ output_buffer.should have_tag('fieldset legend', 'Author #11')
170
+ end
171
+ end
172
+
173
+ describe 'when a :name or :title option is provided' do
174
+ describe 'and is a string' do
175
+ before do
176
+ @legend_text = "Advanced options"
177
+ @legend_text_using_title = "Advanced options 2"
178
+ semantic_form_for(@new_post) do |builder|
179
+ builder.inputs :name => @legend_text do
180
+ end
181
+ builder.inputs :title => @legend_text_using_title do
182
+ end
183
+ end
184
+ end
185
+
186
+ it 'should render a fieldset with a legend inside the form' do
187
+ output_buffer.should have_tag("form fieldset legend", /#{@legend_text}/)
188
+ output_buffer.should have_tag("form fieldset legend", /#{@legend_text_using_title}/)
189
+ end
190
+ end
191
+
192
+ describe 'and is a symbol' do
193
+ before do
194
+ @localized_legend_text = "Localized advanced options"
195
+ @localized_legend_text_using_title = "Localized advanced options 2"
196
+ I18n.backend.store_translations :en, :formtastic => {
197
+ :titles => {
198
+ :post => {
199
+ :advanced_options => @localized_legend_text,
200
+ :advanced_options_2 => @localized_legend_text_using_title
201
+ }
202
+ }
203
+ }
204
+ semantic_form_for(@new_post) do |builder|
205
+ builder.inputs :name => :advanced_options do
206
+ end
207
+ builder.inputs :title => :advanced_options_2 do
208
+ end
209
+ end
210
+ end
211
+
212
+ it 'should render a fieldset with a localized legend inside the form' do
213
+ output_buffer.should have_tag("form fieldset legend", /#{@localized_legend_text}/)
214
+ output_buffer.should have_tag("form fieldset legend", /#{@localized_legend_text_using_title}/)
215
+ end
216
+ end
217
+ end
218
+
219
+ describe 'when other options are provided' do
220
+ before do
221
+ @id_option = 'advanced'
222
+ @class_option = 'wide'
223
+
224
+ semantic_form_for(@new_post) do |builder|
225
+ builder.inputs :id => @id_option, :class => @class_option do
226
+ end
227
+ end
228
+ end
229
+
230
+ it 'should pass the options into the fieldset tag as attributes' do
231
+ output_buffer.should have_tag("form fieldset##{@id_option}")
232
+ output_buffer.should have_tag("form fieldset.#{@class_option}")
233
+ end
234
+ end
235
+
236
+ end
237
+
238
+ describe 'without a block' do
239
+
240
+ before do
241
+ ::Post.stub!(:reflections).and_return({:author => mock('reflection', :options => {}, :macro => :belongs_to),
242
+ :comments => mock('reflection', :options => {}, :macro => :has_many) })
243
+ ::Post.stub!(:content_columns).and_return([mock('column', :name => 'title'), mock('column', :name => 'body'), mock('column', :name => 'created_at')])
244
+ ::Author.stub!(:find).and_return([@fred, @bob])
245
+
246
+ @new_post.stub!(:title)
247
+ @new_post.stub!(:body)
248
+ @new_post.stub!(:author_id)
249
+
250
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 255))
251
+ @new_post.stub!(:column_for_attribute).with(:body).and_return(mock('column', :type => :text))
252
+ @new_post.stub!(:column_for_attribute).with(:created_at).and_return(mock('column', :type => :datetime))
253
+ @new_post.stub!(:column_for_attribute).with(:author).and_return(nil)
254
+ end
255
+
256
+ describe 'with no args' do
257
+ before do
258
+ semantic_form_for(@new_post) do |builder|
259
+ concat(builder.inputs)
260
+ end
261
+ end
262
+
263
+ it 'should render a form' do
264
+ output_buffer.should have_tag('form')
265
+ end
266
+
267
+ it 'should render a fieldset inside the form' do
268
+ output_buffer.should have_tag('form > fieldset.inputs')
269
+ end
270
+
271
+ it 'should not render a legend in the fieldset' do
272
+ output_buffer.should_not have_tag('form > fieldset.inputs > legend')
273
+ end
274
+
275
+ it 'should render an ol in the fieldset' do
276
+ output_buffer.should have_tag('form > fieldset.inputs > ol')
277
+ end
278
+
279
+ it 'should render a list item in the ol for each column and reflection' do
280
+ # Remove the :has_many macro and :created_at column
281
+ count = ::Post.content_columns.size + ::Post.reflections.size - 2
282
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => count)
283
+ end
284
+
285
+ it 'should render a string list item for title' do
286
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
287
+ end
288
+
289
+ it 'should render a text list item for body' do
290
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
291
+ end
292
+
293
+ it 'should render a select list item for author_id' do
294
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.select', :count => 1)
295
+ end
296
+
297
+ it 'should not render timestamps inputs by default' do
298
+ output_buffer.should_not have_tag('form > fieldset.inputs > ol > li.datetime')
299
+ end
300
+ end
301
+
302
+ describe 'with column names as args' do
303
+ describe 'and an object is given' do
304
+ it 'should render a form with a fieldset containing two list items' do
305
+ semantic_form_for(@new_post) do |builder|
306
+ concat(builder.inputs(:title, :body))
307
+ end
308
+
309
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 2)
310
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
311
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
312
+ end
313
+ end
314
+
315
+ describe 'and no object is given' do
316
+ it 'should render a form with a fieldset containing two list items' do
317
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
318
+ concat(builder.inputs(:title, :body))
319
+ end
320
+
321
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.string', :count => 2)
322
+ end
323
+ end
324
+ end
325
+
326
+ describe 'when a :for option is provided' do
327
+ describe 'and an object is given' do
328
+ it 'should render nested inputs' do
329
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
330
+
331
+ semantic_form_for(@new_post) do |builder|
332
+ concat(builder.inputs(:login, :for => @bob))
333
+ end
334
+
335
+ output_buffer.should have_tag("form fieldset.inputs #post_author_login")
336
+ output_buffer.should_not have_tag("form fieldset.inputs #author_login")
337
+ end
338
+ end
339
+
340
+ describe 'and no object is given' do
341
+ it 'should render nested inputs' do
342
+ semantic_form_for(:project, :url => 'http://test.host/') do |builder|
343
+ concat(builder.inputs(:login, :for => @bob))
344
+ end
345
+
346
+ output_buffer.should have_tag("form fieldset.inputs #project_author_login")
347
+ output_buffer.should_not have_tag("form fieldset.inputs #project_login")
348
+ end
349
+ end
350
+ end
351
+
352
+ describe 'with column names and an options hash as args' do
353
+ before do
354
+ semantic_form_for(@new_post) do |builder|
355
+ concat(builder.inputs(:title, :body, :name => "Legendary Legend Text", :id => "my-id"))
356
+ end
357
+ end
358
+
359
+ it 'should render a form with a fieldset containing two list items' do
360
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 2)
361
+ end
362
+
363
+ it 'should pass the options down to the fieldset' do
364
+ output_buffer.should have_tag('form > fieldset#my-id.inputs')
365
+ end
366
+
367
+ it 'should use the special :name option as a text for the legend tag' do
368
+ output_buffer.should have_tag('form > fieldset#my-id.inputs > legend', /Legendary Legend Text/)
369
+ end
370
+ end
371
+
372
+ end
373
+
374
+ end
@@ -0,0 +1,54 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/test_helper'
3
+
4
+ describe 'SemanticFormBuilder#label' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ end
12
+
13
+ it 'should humanize the given attribute' do
14
+ semantic_form_for(@new_post) do |builder|
15
+ builder.label(:login).should have_tag('label', :with => /Login/)
16
+ end
17
+ end
18
+
19
+ it 'should be printed as span' do
20
+ semantic_form_for(@new_post) do |builder|
21
+ builder.label(:login, nil, { :required => true, :as_span => true }).should have_tag('span.label abbr')
22
+ end
23
+ end
24
+
25
+ describe 'when required is given' do
26
+ it 'should append a required note' do
27
+ semantic_form_for(@new_post) do |builder|
28
+ builder.label(:login, nil, :required => true).should have_tag('label abbr')
29
+ end
30
+ end
31
+
32
+ it 'should allow require option to be given as second argument' do
33
+ semantic_form_for(@new_post) do |builder|
34
+ builder.label(:login, :required => true).should have_tag('label abbr')
35
+ end
36
+ end
37
+ end
38
+
39
+ describe 'when label is given' do
40
+ it 'should allow the text to be given as label option' do
41
+ semantic_form_for(@new_post) do |builder|
42
+ builder.label(:login, :required => true, :label => 'My label').should have_tag('label', :with => /My label/)
43
+ end
44
+ end
45
+
46
+ it 'should return nil if label is false' do
47
+ semantic_form_for(@new_post) do |builder|
48
+ builder.label(:login, :label => false).should be_blank
49
+ end
50
+ end
51
+ end
52
+
53
+ end
54
+
@@ -0,0 +1,42 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/test_helper'
3
+
4
+ describe 'SemanticFormBuilder#semantic_fields_for' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ @new_post.stub!(:author).and_return(::Author.new)
12
+ end
13
+
14
+ it 'yields an instance of SemanticFormHelper.builder' do
15
+ semantic_form_for(@new_post) do |builder|
16
+ builder.semantic_fields_for(:author) do |nested_builder|
17
+ nested_builder.class.should == Formtastic::SemanticFormHelper.builder
18
+ end
19
+ end
20
+ end
21
+
22
+ it 'nests the object name' do
23
+ semantic_form_for(@new_post) do |builder|
24
+ builder.semantic_fields_for(@bob) do |nested_builder|
25
+ nested_builder.object_name.should == 'post[author]'
26
+ end
27
+ end
28
+ end
29
+
30
+ it 'should sanitize html id for li tag' do
31
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
32
+ semantic_form_for(@new_post) do |builder|
33
+ builder.semantic_fields_for(@bob, :index => 1) do |nested_builder|
34
+ concat(nested_builder.inputs(:login))
35
+ end
36
+ end
37
+ output_buffer.should have_tag('form fieldset.inputs #post_author_1_login_input')
38
+ output_buffer.should_not have_tag('form fieldset.inputs #post[author]_1_login_input')
39
+ end
40
+
41
+ end
42
+