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