formtastic 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
data/spec/buttons_spec.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- require File.dirname(__FILE__) + '/test_helper'
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
3
 
4
4
  describe 'SemanticFormBuilder#buttons' do
5
5
 
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- require File.dirname(__FILE__) + '/test_helper'
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
3
 
4
4
  describe 'SemanticFormBuilder#commit_button' do
5
5
 
@@ -130,7 +130,7 @@ describe 'SemanticFormBuilder#commit_button' do
130
130
  describe 'when explicit label is provided' do
131
131
  it 'should render an input with the explicitly specified label' do
132
132
  semantic_form_for(:post, :url => 'http://example.com') do |builder|
133
- concat(builder.commit_button "Click!")
133
+ concat(builder.commit_button("Click!"))
134
134
  end
135
135
  output_buffer.should have_tag('li.commit input[@value="Click!"][@class~="submit"]')
136
136
  end
@@ -203,7 +203,7 @@ describe 'SemanticFormBuilder#commit_button' do
203
203
  describe 'when explicit label is provided' do
204
204
  it 'should render an input with the explicitly specified label' do
205
205
  semantic_form_for(@new_post) do |builder|
206
- concat(builder.commit_button "Click!")
206
+ concat(builder.commit_button("Click!"))
207
207
  end
208
208
  output_buffer.should have_tag('li.commit input[@value="Click!"][@class~="create"]')
209
209
  end
@@ -276,7 +276,7 @@ describe 'SemanticFormBuilder#commit_button' do
276
276
  describe 'when explicit label is provided' do
277
277
  it 'should render an input with the explicitly specified label' do
278
278
  semantic_form_for(@new_post) do |builder|
279
- concat(builder.commit_button "Click!")
279
+ concat(builder.commit_button("Click!"))
280
280
  end
281
281
  output_buffer.should have_tag('li.commit input[@value="Click!"][@class~="update"]')
282
282
  end
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- require File.dirname(__FILE__) + '/test_helper'
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
3
 
4
4
  describe 'Formtastic::SemanticFormHelper.builder' do
5
5
 
@@ -0,0 +1,461 @@
1
+ module CustomMacros
2
+
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+
9
+ def it_should_have_input_wrapper_with_class(class_name)
10
+ it "should have input wrapper with class '#{class_name}'" do
11
+ output_buffer.should have_tag("form li.#{class_name}")
12
+ end
13
+ end
14
+
15
+ def it_should_have_input_wrapper_with_id(id_string)
16
+ it "should have input wrapper with id '#{id_string}'" do
17
+ output_buffer.should have_tag("form li##{id_string}")
18
+ end
19
+ end
20
+
21
+ def it_should_not_have_a_label
22
+ it "should not have a label" do
23
+ output_buffer.should_not have_tag("form li label")
24
+ end
25
+ end
26
+
27
+ def it_should_have_a_nested_fieldset
28
+ it "should have a nested_fieldset" do
29
+ output_buffer.should have_tag("form li fieldset")
30
+ end
31
+ end
32
+
33
+ def it_should_have_label_with_text(string_or_regex)
34
+ it "should have a label with text '#{string_or_regex}'" do
35
+ output_buffer.should have_tag("form li label", string_or_regex)
36
+ end
37
+ end
38
+
39
+ def it_should_have_label_for(element_id)
40
+ it "should have a label for ##{element_id}" do
41
+ output_buffer.should have_tag("form li label[@for='#{element_id}']")
42
+ end
43
+ end
44
+
45
+ def it_should_have_input_with_id(element_id)
46
+ it "should have an input with id '#{element_id}'" do
47
+ output_buffer.should have_tag("form li input##{element_id}")
48
+ end
49
+ end
50
+
51
+ def it_should_have_input_with_type(input_type)
52
+ it "should have a #{input_type} input" do
53
+ output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
54
+ end
55
+ end
56
+
57
+ def it_should_have_input_with_name(name)
58
+ it "should have an input named #{name}" do
59
+ output_buffer.should have_tag("form li input[@name=\"#{name}\"]")
60
+ end
61
+ end
62
+
63
+ def it_should_have_textarea_with_name(name)
64
+ it "should have an input named #{name}" do
65
+ output_buffer.should have_tag("form li textarea[@name=\"#{name}\"]")
66
+ end
67
+ end
68
+
69
+ def it_should_have_textarea_with_id(element_id)
70
+ it "should have an input with id '#{element_id}'" do
71
+ output_buffer.should have_tag("form li textarea##{element_id}")
72
+ end
73
+ end
74
+
75
+ def it_should_use_default_text_field_size_when_method_has_no_database_column(as)
76
+ it 'should use default_text_field_size when method has no database column' do
77
+ @new_post.stub!(:column_for_attribute).and_return(nil) # Return a nil column
78
+ semantic_form_for(@new_post) do |builder|
79
+ concat(builder.input(:title, :as => as))
80
+ end
81
+ output_buffer.should have_tag("form li input[@size='#{Formtastic::SemanticFormBuilder.default_text_field_size}']")
82
+ end
83
+ end
84
+
85
+ def it_should_apply_custom_input_attributes_when_input_html_provided(as)
86
+ it 'it should apply custom input attributes when input_html provided' do
87
+ semantic_form_for(@new_post) do |builder|
88
+ concat(builder.input(:title, :as => as, :input_html => { :class => 'myclass' }))
89
+ end
90
+ output_buffer.should have_tag("form li input.myclass")
91
+ end
92
+ end
93
+
94
+ def it_should_apply_custom_for_to_label_when_input_html_id_provided(as)
95
+ it 'it should apply custom for to label when input_html :id provided' do
96
+ semantic_form_for(@new_post) do |builder|
97
+ concat(builder.input(:title, :as => as, :input_html => { :id => 'myid' }))
98
+ end
99
+ output_buffer.should have_tag('form li label[@for="myid"]')
100
+ end
101
+ end
102
+
103
+ def it_should_have_maxlength_matching_column_limit
104
+ it 'should have a maxlength matching column limit' do
105
+ @new_post.column_for_attribute(:title).limit.should == 50
106
+ output_buffer.should have_tag("form li input[@maxlength='50']")
107
+ end
108
+ end
109
+
110
+ def it_should_use_default_text_field_size_for_columns_longer_than_default_text_field_size(as)
111
+ it 'should use default_text_field_size for columns longer than default_text_field_size' do
112
+ default_size = Formtastic::SemanticFormBuilder.default_text_field_size
113
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => as, :limit => default_size * 2))
114
+
115
+ semantic_form_for(@new_post) do |builder|
116
+ concat(builder.input(:title, :as => as))
117
+ end
118
+
119
+ output_buffer.should have_tag("form li input[@size='#{default_size}']")
120
+ end
121
+ end
122
+
123
+ def it_should_use_column_size_for_columns_shorter_than_default_text_field_size(as)
124
+ it 'should use the column size for columns shorter than default_text_field_size' do
125
+ column_limit_shorted_than_default = 1
126
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => as, :limit => column_limit_shorted_than_default))
127
+
128
+ semantic_form_for(@new_post) do |builder|
129
+ concat(builder.input(:title, :as => as))
130
+ end
131
+
132
+ output_buffer.should have_tag("form li input[@size='#{column_limit_shorted_than_default}']")
133
+ end
134
+ end
135
+
136
+ def it_should_apply_error_logic_for_input_type(type)
137
+ describe 'when there are errors on the object for this method' do
138
+ before do
139
+ @title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
140
+ @errors = mock('errors')
141
+ @errors.stub!(:[]).with(:title).and_return(@title_errors)
142
+ @new_post.stub!(:errors).and_return(@errors)
143
+ end
144
+
145
+ it 'should apply an errors class to the list item' do
146
+ semantic_form_for(@new_post) do |builder|
147
+ concat(builder.input(:title, :as => type))
148
+ end
149
+ output_buffer.should have_tag('form li.error')
150
+ end
151
+
152
+ it 'should not wrap the input with the Rails default error wrapping' do
153
+ semantic_form_for(@new_post) do |builder|
154
+ concat(builder.input(:title, :as => type))
155
+ end
156
+ output_buffer.should_not have_tag('div.fieldWithErrors')
157
+ end
158
+
159
+ it 'should render a paragraph for the errors' do
160
+ Formtastic::SemanticFormBuilder.inline_errors = :sentence
161
+ semantic_form_for(@new_post) do |builder|
162
+ concat(builder.input(:title, :as => type))
163
+ end
164
+ output_buffer.should have_tag('form li.error p.inline-errors')
165
+ end
166
+
167
+ it 'should not display an error list' do
168
+ Formtastic::SemanticFormBuilder.inline_errors = :list
169
+ semantic_form_for(@new_post) do |builder|
170
+ concat(builder.input(:title, :as => type))
171
+ end
172
+ output_buffer.should have_tag('form li.error ul.errors')
173
+ end
174
+ end
175
+
176
+ describe 'when there are no errors on the object for this method' do
177
+ before do
178
+ semantic_form_for(@new_post) do |builder|
179
+ concat(builder.input(:title, :as => type))
180
+ end
181
+ end
182
+
183
+ it 'should not apply an errors class to the list item' do
184
+ output_buffer.should_not have_tag('form li.error')
185
+ end
186
+
187
+ it 'should not render a paragraph for the errors' do
188
+ output_buffer.should_not have_tag('form li.error p.inline-errors')
189
+ end
190
+
191
+ it 'should not display an error list' do
192
+ output_buffer.should_not have_tag('form li.error ul.errors')
193
+ end
194
+ end
195
+
196
+ describe 'when no object is provided' do
197
+ before do
198
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
199
+ concat(builder.input(:title, :as => type))
200
+ end
201
+ end
202
+
203
+ it 'should not apply an errors class to the list item' do
204
+ output_buffer.should_not have_tag('form li.error')
205
+ end
206
+
207
+ it 'should not render a paragraph for the errors' do
208
+ output_buffer.should_not have_tag('form li.error p.inline-errors')
209
+ end
210
+
211
+ it 'should not display an error list' do
212
+ output_buffer.should_not have_tag('form li.error ul.errors')
213
+ end
214
+ end
215
+ end
216
+
217
+ def it_should_call_find_on_association_class_when_no_collection_is_provided(as)
218
+ it "should call find on the association class when no collection is provided" do
219
+ ::Author.should_receive(:find)
220
+ semantic_form_for(@new_post) do |builder|
221
+ concat(builder.input(:author, :as => as))
222
+ end
223
+ end
224
+ end
225
+
226
+ def it_should_use_the_collection_when_provided(as, countable)
227
+ describe 'when the :collection option is provided' do
228
+
229
+ before do
230
+ @authors = ::Author.find(:all) * 2
231
+ output_buffer.replace '' # clears the output_buffer from the before block, hax!
232
+ end
233
+
234
+ it 'should not call find() on the parent class' do
235
+ ::Author.should_not_receive(:find)
236
+ semantic_form_for(@new_post) do |builder|
237
+ concat(builder.input(:author, :as => as, :collection => @authors))
238
+ end
239
+ end
240
+
241
+ it 'should use the provided collection' do
242
+ semantic_form_for(@new_post) do |builder|
243
+ concat(builder.input(:author, :as => as, :collection => @authors))
244
+ end
245
+ output_buffer.should have_tag("form li.#{as} #{countable}", :count => @authors.size + (as == :select ? 1 : 0))
246
+ end
247
+
248
+ describe 'and the :collection is an array of strings' do
249
+ before do
250
+ @categories = [ 'General', 'Design', 'Development', 'Quasi-Serious Inventions' ]
251
+ end
252
+
253
+ it "should use the string as the label text and value for each #{countable}" do
254
+ semantic_form_for(@new_post) do |builder|
255
+ concat(builder.input(:category_name, :as => as, :collection => @categories))
256
+ end
257
+
258
+ @categories.each do |value|
259
+ output_buffer.should have_tag("form li.#{as}", /#{value}/)
260
+ output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value}']")
261
+ end
262
+ end
263
+
264
+ if as == :radio
265
+ it 'should generate a sanitized label for attribute' do
266
+ @bob.stub!(:category_name).and_return(@categories)
267
+ semantic_form_for(@new_post) do |builder|
268
+ builder.semantic_fields_for(@bob) do |bob_builder|
269
+ concat(bob_builder.input(:category_name, :as => as, :collection => @categories))
270
+ end
271
+ end
272
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_general']")
273
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_design']")
274
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_development']")
275
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_quasiserious_inventions']")
276
+ end
277
+ end
278
+ end
279
+
280
+ describe 'and the :collection is a hash of strings' do
281
+ before do
282
+ @categories = { 'General' => 'gen', 'Design' => 'des','Development' => 'dev' }
283
+ end
284
+
285
+ it "should use the key as the label text and the hash value as the value attribute for each #{countable}" do
286
+ semantic_form_for(@new_post) do |builder|
287
+ concat(builder.input(:category_name, :as => as, :collection => @categories))
288
+ end
289
+
290
+ @categories.each do |label, value|
291
+ output_buffer.should have_tag("form li.#{as}", /#{label}/)
292
+ output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value}']")
293
+ end
294
+ end
295
+ end
296
+
297
+ describe 'and the :collection is an array of arrays' do
298
+ before do
299
+ @categories = { 'General' => 'gen', 'Design' => 'des', 'Development' => 'dev' }.to_a
300
+ end
301
+
302
+ it "should use the first value as the label text and the last value as the value attribute for #{countable}" do
303
+ semantic_form_for(@new_post) do |builder|
304
+ concat(builder.input(:category_name, :as => as, :collection => @categories))
305
+ end
306
+
307
+ @categories.each do |text, value|
308
+ label = as == :select ? :option : :label
309
+ output_buffer.should have_tag("form li.#{as} #{label}", /#{text}/i)
310
+ output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value.to_s}']")
311
+ output_buffer.should have_tag("form li.#{as} #{countable}#post_category_name_#{value.to_s}") if as == :radio
312
+ end
313
+ end
314
+ end
315
+
316
+ if as == :radio
317
+ describe 'and the :collection is an array of arrays with boolean values' do
318
+ before do
319
+ @choices = { 'Yeah' => true, 'Nah' => false }.to_a
320
+ end
321
+
322
+ it "should use the first value as the label text and the last value as the value attribute for #{countable}" do
323
+ semantic_form_for(@new_post) do |builder|
324
+ concat(builder.input(:category_name, :as => as, :collection => @choices))
325
+ end
326
+
327
+ output_buffer.should have_tag("form li.#{as} #{countable}#post_category_name_true")
328
+ output_buffer.should have_tag("form li.#{as} #{countable}#post_category_name_false")
329
+ end
330
+ end
331
+ end
332
+
333
+ describe 'and the :collection is an array of symbols' do
334
+ before do
335
+ @categories = [ :General, :Design, :Development ]
336
+ end
337
+
338
+ it "should use the symbol as the label text and value for each #{countable}" do
339
+ semantic_form_for(@new_post) do |builder|
340
+ concat(builder.input(:category_name, :as => as, :collection => @categories))
341
+ end
342
+
343
+ @categories.each do |value|
344
+ label = as == :select ? :option : :label
345
+ output_buffer.should have_tag("form li.#{as} #{label}", /#{value}/i)
346
+ output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value.to_s}']")
347
+ end
348
+ end
349
+ end
350
+
351
+ describe 'and the :collection is an OrderedHash of strings' do
352
+ before do
353
+ @categories = ActiveSupport::OrderedHash.new('General' => 'gen', 'Design' => 'des','Development' => 'dev')
354
+ end
355
+
356
+ it "should use the key as the label text and the hash value as the value attribute for each #{countable}" do
357
+ semantic_form_for(@new_post) do |builder|
358
+ concat(builder.input(:category_name, :as => as, :collection => @categories))
359
+ end
360
+
361
+ @categories.each do |label, value|
362
+ output_buffer.should have_tag("form li.#{as}", /#{label}/)
363
+ output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value}']")
364
+ end
365
+ end
366
+
367
+ end
368
+
369
+ describe 'when the :label_method option is provided' do
370
+
371
+ describe 'as a symbol' do
372
+ before do
373
+ semantic_form_for(@new_post) do |builder|
374
+ concat(builder.input(:author, :as => as, :label_method => :login))
375
+ end
376
+ end
377
+
378
+ it 'should have options with text content from the specified method' do
379
+ ::Author.find(:all).each do |author|
380
+ output_buffer.should have_tag("form li.#{as}", /#{author.login}/)
381
+ end
382
+ end
383
+ end
384
+
385
+ describe 'as a proc' do
386
+ before do
387
+ semantic_form_for(@new_post) do |builder|
388
+ concat(builder.input(:author, :as => as, :label_method => Proc.new {|a| a.login.reverse }))
389
+ end
390
+ end
391
+
392
+ it 'should have options with the proc applied to each' do
393
+ ::Author.find(:all).each do |author|
394
+ output_buffer.should have_tag("form li.#{as}", /#{author.login.reverse}/)
395
+ end
396
+ end
397
+ end
398
+
399
+ end
400
+
401
+ describe 'when the :label_method option is not provided' do
402
+ Formtastic::SemanticFormBuilder.collection_label_methods.each do |label_method|
403
+
404
+ describe "when the collection objects respond to #{label_method}" do
405
+ before do
406
+ @fred.stub!(:respond_to?).and_return { |m| m.to_s == label_method }
407
+ ::Author.find(:all).each { |a| a.stub!(label_method).and_return('The Label Text') }
408
+
409
+ semantic_form_for(@new_post) do |builder|
410
+ concat(builder.input(:author, :as => as))
411
+ end
412
+ end
413
+
414
+ it "should render the options with #{label_method} as the label" do
415
+ ::Author.find(:all).each do |author|
416
+ output_buffer.should have_tag("form li.#{as}", /The Label Text/)
417
+ end
418
+ end
419
+ end
420
+
421
+ end
422
+ end
423
+
424
+ describe 'when the :value_method option is provided' do
425
+
426
+ describe 'as a symbol' do
427
+ before do
428
+ semantic_form_for(@new_post) do |builder|
429
+ concat(builder.input(:author, :as => as, :value_method => :login))
430
+ end
431
+ end
432
+
433
+ it 'should have options with values from specified method' do
434
+ ::Author.find(:all).each do |author|
435
+ output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{author.login}']")
436
+ end
437
+ end
438
+ end
439
+
440
+ describe 'as a proc' do
441
+ before do
442
+ semantic_form_for(@new_post) do |builder|
443
+ concat(builder.input(:author, :as => as, :value_method => Proc.new {|a| a.login.reverse }))
444
+ end
445
+ end
446
+
447
+ it 'should have options with the proc applied to each value' do
448
+ ::Author.find(:all).each do |author|
449
+ output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{author.login.reverse}']")
450
+ end
451
+ end
452
+ end
453
+ end
454
+
455
+ end
456
+ end
457
+
458
+ end
459
+
460
+
461
+ end