justinfrench-formtastic 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,63 +2,14 @@ require File.dirname(__FILE__) + '/test_helper'
2
2
  require 'formtastic'
3
3
 
4
4
  module FormtasticSpecHelper
5
-
6
- def should_have_maxlength_matching_column_limit(method_name, as, column_type)
7
- semantic_form_for(@new_post) do |builder|
8
- concat(builder.input(method_name, :as => as))
9
- end
10
- @new_post.column_for_attribute(method_name).limit.should == 50
11
- output_buffer.should have_tag("form li input[@maxlength='#{@new_post.column_for_attribute(method_name).limit}']")
12
- end
13
-
14
- def should_use_default_text_size_for_columns_longer_than_default(method_name, as, column_type)
15
- default_size = Formtastic::SemanticFormBuilder.default_text_field_size
16
- column_limit_larger_than_default = default_size * 2
17
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => column_type, :limit => column_limit_larger_than_default))
18
- semantic_form_for(@new_post) do |builder|
19
- concat(builder.input(method_name, :as => as))
20
- end
21
- output_buffer.should have_tag("form li input[@size='#{default_size}']")
22
- end
23
-
24
- def should_use_the_column_size_for_columns_shorter_than_default(method_name, as, column_type)
25
- default_size = Formtastic::SemanticFormBuilder.default_text_field_size
26
- column_limit_shorter_than_default = 1
27
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => column_type, :limit => column_limit_shorter_than_default))
28
- semantic_form_for(@new_post) do |builder|
29
- concat(builder.input(method_name, :as => as))
30
- end
31
- output_buffer.should have_tag("form li input[@size='#{column_limit_shorter_than_default}']")
32
- end
33
-
34
- def should_use_default_size_for_methods_without_columns(as)
35
- default_size = Formtastic::SemanticFormBuilder.default_text_field_size
36
- @new_post.stub!(:method_without_column)
37
- semantic_form_for(@new_post) do |builder|
38
- concat(builder.input(:method_without_column, :as => as))
39
- end
40
- output_buffer.should have_tag("form li input[@size='#{default_size}']")
41
- end
42
-
43
5
  def default_input_type(column_type, column_name = :generic_column_name)
44
6
  @new_post.stub!(column_name)
45
7
  @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => column_type)) unless column_type.nil?
46
- semantic_form_for(@new_post) do |builder|
47
- @default_type = builder.send(:default_input_type, @new_post, column_name)
48
- end
49
- return @default_type
50
- end
51
8
 
52
- def attachment_input_type(method, column_name = :generic_column_name)
53
- @new_post.stub!(:column_for_attribute).and_return(nil)
54
- column = mock('column')
55
- [:file?, :public_filename].each do |test|
56
- column.stub!(:respond_to?).with(test).and_return(method == test)
57
- end
58
- @new_post.should_receive(column_name).and_return(column)
59
9
  semantic_form_for(@new_post) do |builder|
60
- @default_type = builder.send(:default_input_type, @new_post, column_name)
10
+ @default_type = builder.send(:default_input_type, column_name)
61
11
  end
12
+
62
13
  return @default_type
63
14
  end
64
15
  end
@@ -85,7 +36,7 @@ describe 'Formtastic' do
85
36
  def protect_against_forgery?; false; end
86
37
 
87
38
  before do
88
- Formtastic::SemanticFormBuilder.label_str_method = :titleize
39
+ Formtastic::SemanticFormBuilder.label_str_method = :humanize
89
40
 
90
41
  @output_buffer = ''
91
42
 
@@ -124,7 +75,7 @@ describe 'Formtastic' do
124
75
  @bob.stub!(:errors).and_return(mock('errors', :on => nil))
125
76
 
126
77
  Author.stub!(:find).and_return([@fred, @bob])
127
- Author.stub!(:human_attribute_name).and_return { |column_name| column_name.to_s }
78
+ Author.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
128
79
  Author.stub!(:human_name).and_return('Author')
129
80
  Author.stub!(:reflect_on_all_validations).and_return([])
130
81
  Author.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :klass => Post, :macro => :has_many) if column_name == :posts }
@@ -150,7 +101,7 @@ describe 'Formtastic' do
150
101
  @fred.stub!(:posts).and_return([@freds_post])
151
102
  @fred.stub!(:post_ids).and_return([@freds_post.id])
152
103
 
153
- Post.stub!(:human_attribute_name).and_return { |column_name| column_name.to_s }
104
+ Post.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
154
105
  Post.stub!(:human_name).and_return('Post')
155
106
  Post.stub!(:reflect_on_all_validations).and_return([])
156
107
  Post.stub!(:reflect_on_association).and_return do |column_name|
@@ -189,13 +140,17 @@ describe 'Formtastic' do
189
140
  output_buffer.should have_tag("form.formtastic")
190
141
  end
191
142
 
192
- it 'adds class matching the object\'s class to the generated form when a symbol is provided' do
143
+ it 'adds class matching the object name to the generated form when a symbol is provided' do
193
144
  semantic_form_for(:post, Post.new, :url => '/hello') do |builder|
194
145
  end
195
146
  output_buffer.should have_tag("form.post")
147
+
148
+ semantic_form_for(:project, :url => '/hello') do |builder|
149
+ end
150
+ output_buffer.should have_tag("form.project")
196
151
  end
197
152
 
198
- it 'adds class matching the object\'s class to the generated form when a symbol is provided when an object is provided' do
153
+ it 'adds class matching the object\'s class to the generated form when an object is provided' do
199
154
  semantic_form_for(@new_post) do |builder|
200
155
  end
201
156
  output_buffer.should have_tag("form.post")
@@ -227,13 +182,6 @@ describe 'Formtastic' do
227
182
  end
228
183
  end
229
184
 
230
- it 'can be called with a resource-oriented style with an inline object' do
231
- semantic_form_for(Post.new) do |builder|
232
- builder.object.class.should == Post
233
- builder.object_name.should == "post"
234
- end
235
- end
236
-
237
185
  it 'can be called with a generic style and instance variable' do
238
186
  semantic_form_for(:post, @new_post, :url => new_post_path) do |builder|
239
187
  builder.object.class.should == Post
@@ -326,11 +274,11 @@ describe 'Formtastic' do
326
274
  end
327
275
  end
328
276
 
329
- it 'should generate html id for li tag properly' do
277
+ it 'should sanitize html id for li tag' do
330
278
  @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
331
279
  semantic_form_for(@new_post) do |builder|
332
280
  builder.semantic_fields_for(@bob, :index => 1) do |nested_builder|
333
- concat(nested_builder.inputs :login)
281
+ concat(nested_builder.inputs(:login))
334
282
  end
335
283
  end
336
284
  output_buffer.should have_tag('form fieldset.inputs #post_author_1_login_input')
@@ -351,9 +299,9 @@ describe 'Formtastic' do
351
299
  Formtastic::SemanticFormBuilder.inline_order = [:input, :hints, :errors]
352
300
 
353
301
  semantic_form_for(@new_post) do |builder|
354
- builder.should_receive(:string_input).once.ordered
355
- builder.should_receive(:inline_hints).once.ordered
356
- builder.should_receive(:inline_errors).once.ordered
302
+ builder.should_receive(:inline_input_for).once.ordered
303
+ builder.should_receive(:inline_hints_for).once.ordered
304
+ builder.should_receive(:inline_errors_for).once.ordered
357
305
  concat(builder.input(:title))
358
306
  end
359
307
  end
@@ -362,9 +310,9 @@ describe 'Formtastic' do
362
310
  Formtastic::SemanticFormBuilder.inline_order = [:hints, :input, :errors]
363
311
 
364
312
  semantic_form_for(@new_post) do |builder|
365
- builder.should_receive(:inline_hints).once.ordered
366
- builder.should_receive(:string_input).once.ordered
367
- builder.should_receive(:inline_errors).once.ordered
313
+ builder.should_receive(:inline_hints_for).once.ordered
314
+ builder.should_receive(:inline_input_for).once.ordered
315
+ builder.should_receive(:inline_errors_for).once.ordered
368
316
  concat(builder.input(:title))
369
317
  end
370
318
  end
@@ -373,19 +321,13 @@ describe 'Formtastic' do
373
321
  describe 'arguments and options' do
374
322
 
375
323
  it 'should require the first argument (the method on form\'s object)' do
376
- lambda {
324
+ lambda {
377
325
  semantic_form_for(@new_post) do |builder|
378
326
  concat(builder.input()) # no args passed in at all
379
327
  end
380
328
  }.should raise_error(ArgumentError)
381
329
  end
382
330
 
383
- it 'should raise a helpful error when the object does not respond to the method supplied in the first argument' do
384
- semantic_form_for(@new_post) do |builder|
385
- lambda { builder.input(:method_on_post_that_doesnt_exist) }.should raise_error(NoMethodError, /method_on_post_that_doesnt_exist/)
386
- end
387
- end
388
-
389
331
  describe ':required option' do
390
332
 
391
333
  describe 'when true' do
@@ -446,58 +388,78 @@ describe 'Formtastic' do
446
388
 
447
389
  describe 'when not provided' do
448
390
 
449
- describe 'and the validation reflection plugin is available' do
391
+ describe 'and an object was not given' do
450
392
 
451
- before do
452
- @new_post.class.stub!(:method_defined?).with(:reflect_on_all_validations).and_return(true)
393
+ it 'should use the default value' do
394
+ Formtastic::SemanticFormBuilder.all_fields_required_by_default.should == true
395
+ Formtastic::SemanticFormBuilder.all_fields_required_by_default = false
396
+
397
+ semantic_form_for(:project, :url => 'http://test.host/') do |builder|
398
+ concat(builder.input(:title))
399
+ end
400
+ output_buffer.should_not have_tag('form li.required')
401
+ output_buffer.should have_tag('form li.optional')
402
+
403
+ Formtastic::SemanticFormBuilder.all_fields_required_by_default = true
453
404
  end
454
405
 
455
- describe 'and validates_presence_of was called for the method' do
406
+ end
407
+
408
+ describe 'and an object was given' do
409
+
410
+ describe 'and the validation reflection plugin is available' do
456
411
 
457
412
  before do
458
- @new_post.class.should_receive(:reflect_on_all_validations).and_return([
459
- mock('MacroReflection', :macro => :validates_presence_of, :name => :title)
460
- ])
413
+ @new_post.class.stub!(:method_defined?).with(:reflect_on_all_validations).and_return(true)
461
414
  end
462
415
 
463
- it 'should be required' do
464
- semantic_form_for(@new_post) do |builder|
465
- concat(builder.input(:title))
416
+ describe 'and validates_presence_of was called for the method' do
417
+ before do
418
+ @new_post.class.should_receive(:reflect_on_all_validations).and_return([
419
+ mock('MacroReflection', :macro => :validates_presence_of, :name => :title)
420
+ ])
421
+ end
422
+
423
+ it 'should be required' do
424
+ semantic_form_for(@new_post) do |builder|
425
+ concat(builder.input(:title))
426
+ end
427
+ output_buffer.should have_tag('form li.required')
428
+ output_buffer.should_not have_tag('form li.optional')
429
+ end
430
+ end
431
+
432
+ describe 'and validates_presence_of was not called for the method' do
433
+ before do
434
+ @new_post.class.should_receive(:reflect_on_all_validations).and_return([])
435
+ end
436
+
437
+ it 'should not be required' do
438
+ semantic_form_for(@new_post) do |builder|
439
+ concat(builder.input(:title))
440
+ end
441
+ output_buffer.should_not have_tag('form li.required')
442
+ output_buffer.should have_tag('form li.optional')
466
443
  end
467
- output_buffer.should have_tag('form li.required')
468
- output_buffer.should_not have_tag('form li.optional')
469
444
  end
470
445
 
471
446
  end
472
447
 
473
- describe 'and validates_presence_of was not called for the method' do
448
+ describe 'and the validation reflection plugin is not available' do
474
449
 
475
- before do
476
- @new_post.class.should_receive(:reflect_on_all_validations).and_return([])
477
- end
450
+ it 'should use the default value' do
451
+ Formtastic::SemanticFormBuilder.all_fields_required_by_default.should == true
452
+ Formtastic::SemanticFormBuilder.all_fields_required_by_default = false
478
453
 
479
- it 'should not be required' do
480
454
  semantic_form_for(@new_post) do |builder|
481
455
  concat(builder.input(:title))
482
456
  end
483
457
  output_buffer.should_not have_tag('form li.required')
484
458
  output_buffer.should have_tag('form li.optional')
485
- end
486
-
487
- end
488
-
489
- end
490
-
491
- describe 'and the validation reflection plugin is not available' do
492
459
 
493
- it 'should use the default value' do
494
- Formtastic::SemanticFormBuilder.all_fields_required_by_default.should == true
495
- Formtastic::SemanticFormBuilder.all_fields_required_by_default = false
496
- semantic_form_for(@new_post) do |builder|
497
- concat(builder.input(:title))
460
+ Formtastic::SemanticFormBuilder.all_fields_required_by_default = true
498
461
  end
499
- output_buffer.should_not have_tag('form li.required')
500
- output_buffer.should have_tag('form li.optional')
462
+
501
463
  end
502
464
 
503
465
  end
@@ -510,15 +472,16 @@ describe 'Formtastic' do
510
472
 
511
473
  describe 'when not provided' do
512
474
 
513
- it 'should default to a string for methods that don\'t have a column in the database (and can\'t be guessed)' do
514
- @new_post.stub!(:method_without_a_database_column)
515
- @new_post.stub!(:column_for_attribute).and_return(nil)
516
- default_input_type(nil, :method_without_a_database_column).should == :string
475
+ it 'should default to a string for forms without objects' do
476
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
477
+ concat(builder.input(:anything))
478
+ end
479
+ output_buffer.should have_tag('form li.string')
517
480
  end
518
481
 
519
482
  it 'should default to a string for methods on objects that don\'t respond to "column_for_attribute"' do
520
483
  @new_post.stub!(:method_without_a_database_column)
521
- # @new_post.stub!(:column_for_attribute).and_raise(NoMethodError)
484
+ @new_post.stub!(:column_for_attribute).and_return(nil)
522
485
  default_input_type(nil, :method_without_a_database_column).should == :string
523
486
  end
524
487
 
@@ -577,19 +540,28 @@ describe 'Formtastic' do
577
540
  end
578
541
 
579
542
  describe 'defaulting to file column' do
580
- it 'should default to :file for attributes that respond to #file?' do
581
- attachment_input_type(:file?).should == :file
582
- end
543
+ Formtastic::SemanticFormBuilder.file_methods.each do |method|
544
+ it "should default to :file for attributes that respond to ##{method}" do
545
+ @new_post.stub!(:column_for_attribute).and_return(nil)
546
+ column = mock('column')
547
+
548
+ Formtastic::SemanticFormBuilder.file_methods.each do |test|
549
+ column.stub!(:respond_to?).with(test).and_return(method == test)
550
+ end
583
551
 
584
- it 'should default to :file for attributes that respond to #public_filename' do
585
- attachment_input_type(:public_filename).should == :file
552
+ @new_post.should_receive(method).and_return(column)
553
+
554
+ semantic_form_for(@new_post) do |builder|
555
+ builder.send(:default_input_type, method).should == :file
556
+ end
557
+ end
586
558
  end
587
559
 
588
560
  end
589
561
  end
590
562
 
591
563
  it 'should call the corresponding input method' do
592
- [:select, :radio, :password, :text, :date, :datetime, :time, :boolean, :boolean_select, :string, :numeric, :file].each do |input_style|
564
+ [:select, :radio, :date, :datetime, :time, :boolean].each do |input_style|
593
565
  @new_post.stub!(:generic_column_name)
594
566
  @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
595
567
  semantic_form_for(@new_post) do |builder|
@@ -597,6 +569,15 @@ describe 'Formtastic' do
597
569
  concat(builder.input(:generic_column_name, :as => input_style))
598
570
  end
599
571
  end
572
+
573
+ Formtastic::SemanticFormBuilder::INPUT_MAPPINGS.keys.each do |input_style|
574
+ @new_post.stub!(:generic_column_name)
575
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
576
+ semantic_form_for(@new_post) do |builder|
577
+ builder.should_receive(:input_simple).once.and_return("fake HTML output from #input")
578
+ concat(builder.input(:generic_column_name, :as => input_style))
579
+ end
580
+ end
600
581
  end
601
582
 
602
583
  end
@@ -615,42 +596,28 @@ describe 'Formtastic' do
615
596
  end
616
597
 
617
598
  describe 'when not provided' do
618
- describe 'when the default is :titleize' do
619
- before do
620
- Formtastic::SemanticFormBuilder.label_str_method = :titleize
621
- @new_post.stub!(:meta_description) # a two word method name
622
- semantic_form_for(@new_post) do |builder|
623
- concat(builder.input(:meta_description))
624
- end
625
- end
626
- it 'should default the titleized method name, passing it down to the label tag' do
627
- output_buffer.should have_tag("form li label", /#{'meta_description'.titleize}/)
628
- end
629
- end
630
-
631
- describe 'when the default is :humanize' do
632
- before do
599
+ describe 'and object is not given' do
600
+ it 'should default the humanized method name, passing it down to the label tag' do
633
601
  Formtastic::SemanticFormBuilder.label_str_method = :humanize
634
- @new_post.stub!(:meta_description) # a two word method name
635
- semantic_form_for(@new_post) do |builder|
602
+
603
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
636
604
  concat(builder.input(:meta_description))
637
605
  end
638
- end
639
- it 'should default the humanized method name, passing it down to the label tag' do
606
+
640
607
  output_buffer.should have_tag("form li label", /#{'meta_description'.humanize}/)
641
608
  end
642
609
  end
643
610
 
644
- describe 'when the default is :to_s' do
645
- before do
646
- Formtastic::SemanticFormBuilder.label_str_method = :to_s
611
+ describe 'and object is given' do
612
+ it 'should delegate the label logic to class human attribute name and pass it down to the label tag' do
647
613
  @new_post.stub!(:meta_description) # a two word method name
614
+ @new_post.class.should_receive(:human_attribute_name).with('meta_description').and_return('meta_description'.humanize)
615
+
648
616
  semantic_form_for(@new_post) do |builder|
649
617
  concat(builder.input(:meta_description))
650
618
  end
651
- end
652
- it 'should default the humanized method name, passing it down to the label tag' do
653
- output_buffer.should have_tag("form li label", /meta_description/)
619
+
620
+ output_buffer.should have_tag("form li label", /#{'meta_description'.humanize}/)
654
621
  end
655
622
  end
656
623
  end
@@ -660,7 +627,6 @@ describe 'Formtastic' do
660
627
  describe ':hint option' do
661
628
 
662
629
  describe 'when provided' do
663
-
664
630
  it 'should be passed down to the paragraph tag' do
665
631
  hint_text = "this is the title of the post"
666
632
  semantic_form_for(@new_post) do |builder|
@@ -668,11 +634,9 @@ describe 'Formtastic' do
668
634
  end
669
635
  output_buffer.should have_tag("form li p.inline-hints", hint_text)
670
636
  end
671
-
672
637
  end
673
638
 
674
639
  describe 'when not provided' do
675
-
676
640
  it 'should not render a hint paragraph' do
677
641
  hint_text = "this is the title of the post"
678
642
  semantic_form_for(@new_post) do |builder|
@@ -680,11 +644,9 @@ describe 'Formtastic' do
680
644
  end
681
645
  output_buffer.should_not have_tag("form li p.inline-hints")
682
646
  end
683
-
684
647
  end
685
648
 
686
649
  end
687
-
688
650
  end
689
651
 
690
652
  describe ':as any type of input' do
@@ -799,733 +761,803 @@ describe 'Formtastic' do
799
761
 
800
762
  end
801
763
 
802
- end
803
-
804
- describe ':as => :string' do
764
+ describe 'when no object is provided' do
805
765
 
806
- before do
807
- @new_post.stub!(:title)
808
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 50))
766
+ before do
767
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
768
+ concat(builder.input(:title))
769
+ end
770
+ end
809
771
 
810
- semantic_form_for(@new_post) do |builder|
811
- concat(builder.input(:title, :as => :string))
772
+ it 'should not apply an errors class to the list item' do
773
+ output_buffer.should_not have_tag('form li.error')
812
774
  end
813
- end
814
775
 
815
- it 'should have a string class on the wrapper' do
816
- output_buffer.should have_tag('form li.string')
817
- end
776
+ it 'should not render a paragraph for the errors' do
777
+ output_buffer.should_not have_tag('form li.error p.inline-errors')
778
+ end
818
779
 
819
- it 'should have a post_title_input id on the wrapper' do
820
- output_buffer.should have_tag('form li#post_title_input')
821
- end
780
+ it 'should not display an error list' do
781
+ output_buffer.should_not have_tag('form li.error ul.errors')
782
+ end
822
783
 
823
- it 'should generate a label for the input' do
824
- output_buffer.should have_tag('form li label')
825
- output_buffer.should have_tag('form li label[@for="post_title"')
826
- output_buffer.should have_tag('form li label', /Title/)
827
784
  end
785
+ end
828
786
 
829
- it 'should generate a text input' do
830
- output_buffer.should have_tag('form li input')
831
- output_buffer.should have_tag('form li input#post_title')
832
- output_buffer.should have_tag('form li input[@type="text"]')
833
- output_buffer.should have_tag('form li input[@name="post[title]"]')
834
- end
787
+ # Test string_mappings: :string, :password and :numeric
788
+ string_mappings = Formtastic::SemanticFormBuilder::INPUT_MAPPINGS.slice(*Formtastic::SemanticFormBuilder::STRING_MAPPINGS)
789
+ string_mappings.each do |type, template_method|
790
+ describe ":as => #{type.inspect}" do
835
791
 
836
- it 'should have a maxlength matching the column limit' do
837
- should_have_maxlength_matching_column_limit(:title, :string, :string)
838
- end
792
+ before do
793
+ @new_post.stub!(:title)
794
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => type, :limit => 50))
839
795
 
840
- it 'should use default_text_field_size for columns longer than default_text_field_size' do
841
- should_use_default_text_size_for_columns_longer_than_default(:title, :string, :string)
842
- end
796
+ semantic_form_for(@new_post) do |builder|
797
+ concat(builder.input(:title, :as => type))
798
+ end
799
+ end
843
800
 
844
- it 'should use the column size for columns shorter than default_text_field_size' do
845
- should_use_the_column_size_for_columns_shorter_than_default(:title, :string, :string)
846
- end
801
+ it "should have a #{type} class on the wrapper" do
802
+ output_buffer.should have_tag("form li.#{type}")
803
+ end
847
804
 
848
- it 'should use default_text_field_size for methods without database columns' do
849
- should_use_default_size_for_methods_without_columns(:string)
850
- end
805
+ it 'should have a post_title_input id on the wrapper' do
806
+ output_buffer.should have_tag('form li#post_title_input')
807
+ end
851
808
 
852
- describe "with object that does not respond to 'column_for_attribute'" do
853
- before do
854
- @new_post.stub!(:column_for_attribute).and_raise(NoMethodError)
809
+ it 'should generate a label for the input' do
810
+ output_buffer.should have_tag('form li label')
811
+ output_buffer.should have_tag('form li label[@for="post_title"')
812
+ output_buffer.should have_tag('form li label', /Title/)
855
813
  end
856
814
 
857
- it "should have a maxlength of default_text_field_size" do
858
- should_use_default_size_for_methods_without_columns(:string)
815
+ input_type = template_method.to_s.split('_').first
816
+
817
+ it "should generate a #{input_type} input" do
818
+ output_buffer.should have_tag("form li input")
819
+ output_buffer.should have_tag("form li input#post_title")
820
+ output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
821
+ output_buffer.should have_tag("form li input[@name=\"post[title]\"]")
859
822
  end
860
- end
861
823
 
862
- end
824
+ it 'should have a maxlength matching the column limit' do
825
+ @new_post.column_for_attribute(:title).limit.should == 50
826
+ output_buffer.should have_tag("form li input[@maxlength='50']")
827
+ end
863
828
 
864
- describe 'for belongs_to associations' do
829
+ it 'should use default_text_field_size for columns longer than default_text_field_size' do
830
+ default_size = Formtastic::SemanticFormBuilder.default_text_field_size
831
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => type, :limit => default_size * 2))
865
832
 
866
- before do
867
- @new_post.stub!(:author).and_return(@bob)
868
- @new_post.stub!(:author_id).and_return(@bob.id)
869
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
870
- end
833
+ semantic_form_for(@new_post) do |builder|
834
+ concat(builder.input(:title, :as => type))
835
+ end
871
836
 
872
- describe ':as => :radio' do
837
+ output_buffer.should have_tag("form li input[@size='#{default_size}']")
838
+ end
873
839
 
874
- describe 'when using association_id' do
840
+ it 'should use the column size for columns shorter than default_text_field_size' do
841
+ column_limit_shorted_than_default = 1
842
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => type, :limit => column_limit_shorted_than_default))
875
843
 
876
- before do
877
- # Check for deprecation message
878
- ::ActiveSupport::Deprecation.should_receive(:warn).with(/association/, anything())
879
- semantic_form_for(@new_post) do |builder|
880
- concat(builder.input(:author_id, :as => :radio))
881
- end
844
+ semantic_form_for(@new_post) do |builder|
845
+ concat(builder.input(:title, :as => type))
882
846
  end
883
847
 
884
- it 'should have a radio class on the wrapper' do
885
- output_buffer.should have_tag('form li.radio')
886
- end
848
+ output_buffer.should have_tag("form li input[@size='#{column_limit_shorted_than_default}']")
849
+ end
887
850
 
888
- it 'should have a post_author_id_input id on the wrapper' do
889
- output_buffer.should have_tag('form li#post_author_id_input')
890
- end
851
+ it 'should use default_text_field_size for methods without database columns' do
852
+ default_size = Formtastic::SemanticFormBuilder.default_text_field_size
853
+ @new_post.stub!(:column_for_attribute).and_return(nil) # Return a nil column
891
854
 
892
- it 'should generate a fieldset and legend containing label text for the input' do
893
- output_buffer.should have_tag('form li fieldset')
894
- output_buffer.should have_tag('form li fieldset legend')
895
- output_buffer.should have_tag('form li fieldset legend', /Author/)
855
+ semantic_form_for(@new_post) do |builder|
856
+ concat(builder.input(:title, :as => type))
896
857
  end
897
858
 
898
- it 'should generate an ordered list with a list item for each choice' do
899
- output_buffer.should have_tag('form li fieldset ol')
900
- output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
859
+ output_buffer.should have_tag("form li input[@size='#{default_size}']")
860
+ end
861
+
862
+ it 'should use input_html to style inputs' do
863
+ semantic_form_for(@new_post) do |builder|
864
+ concat(builder.input(:title, :as => type, :input_html => { :class => 'myclass' }))
901
865
  end
866
+ output_buffer.should have_tag("form li input.myclass")
867
+ end
902
868
 
903
- it 'should have one option with a "selected" attribute' do
904
- output_buffer.should have_tag('form li input[@checked]', :count => 1)
869
+ it 'should generate input and labels even if no object is given' do
870
+ semantic_form_for(:project, :url => 'http://test.host/') do |builder|
871
+ concat(builder.input(:title, :as => type))
905
872
  end
906
873
 
907
- describe "each choice" do
874
+ output_buffer.should have_tag('form li label')
875
+ output_buffer.should have_tag('form li label[@for="project_title"')
876
+ output_buffer.should have_tag('form li label', /Title/)
908
877
 
909
- it 'should contain a label for the radio input with a nested input and label text' do
910
- Author.find(:all).each do |author|
911
- output_buffer.should have_tag('form li fieldset ol li label')
912
- output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
913
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_id_#{author.id}']")
914
- output_buffer.should have_tag("form li fieldset ol li label input")
915
- end
916
- end
878
+ output_buffer.should have_tag("form li input")
879
+ output_buffer.should have_tag("form li input#project_title")
880
+ output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
881
+ output_buffer.should have_tag("form li input[@name=\"project[title]\"]")
882
+ end
917
883
 
918
- it "should have a radio input" do
919
- Author.find(:all).each do |author|
920
- output_buffer.should have_tag("form li fieldset ol li label input#post_author_id_#{author.id}")
921
- output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
922
- output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
923
- output_buffer.should have_tag("form li fieldset ol li label input[@name='post[author_id]']")
924
- end
925
- end
884
+ end
885
+ end
926
886
 
927
- xit "should mark input as checked if it's the the existing choice" do
928
- @new_post.author_id.should == @bob.id
929
- @new_post.author.id.should == @bob.id
930
- @new_post.author.should == @bob
931
- semantic_form_for(@new_post) do |builder|
932
- concat(builder.input(:author_id, :as => :radio))
933
- end
887
+ # Test other mappings that are not strings: :text and :file.
888
+ other_mappings = Formtastic::SemanticFormBuilder::INPUT_MAPPINGS.except(*Formtastic::SemanticFormBuilder::STRING_MAPPINGS)
889
+ other_mappings.each do |type, template_method|
890
+ describe ":as => #{type.inspect}" do
934
891
 
935
- output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
936
- end
892
+ before do
893
+ @new_post.stub!(:body)
894
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => type))
937
895
 
896
+ semantic_form_for(@new_post) do |builder|
897
+ concat(builder.input(:body, :as => type))
938
898
  end
899
+ end
939
900
 
901
+ it "should have a #{type} class on the wrapper" do
902
+ output_buffer.should have_tag('form li.#{type}')
940
903
  end
941
904
 
942
- describe 'when using association' do
905
+ it 'should have a post_title_input id on the wrapper' do
906
+ output_buffer.should have_tag('form li#post_body_input')
907
+ end
943
908
 
944
- before do
909
+ it 'should generate a label for the input' do
910
+ output_buffer.should have_tag('form li label')
911
+ output_buffer.should have_tag('form li label[@for="post_body"')
912
+ output_buffer.should have_tag('form li label', /Body/)
913
+ end
914
+
915
+ input_type = template_method.to_s.gsub(/_field|_/, '')
916
+
917
+ if template_method.to_s =~ /_field$/ # password_field
918
+
919
+ it "should generate a #{input_type} input" do
920
+ output_buffer.should have_tag("form li input")
921
+ output_buffer.should have_tag("form li input#post_body")
922
+ output_buffer.should have_tag("form li input[@name=\"post[body]\"]")
923
+ output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
924
+ end
925
+
926
+ it 'should use input_html to style inputs' do
945
927
  semantic_form_for(@new_post) do |builder|
946
- concat(builder.input(:author, :as => :radio))
928
+ concat(builder.input(:title, :as => type, :input_html => { :class => 'myclass' }))
947
929
  end
930
+ output_buffer.should have_tag("form li input.myclass")
948
931
  end
949
932
 
950
- it 'should have a radio class on the wrapper' do
951
- output_buffer.should have_tag('form li.radio')
952
- end
933
+ else # text_area
953
934
 
954
- it 'should have a post_author_id_input id on the wrapper' do
955
- output_buffer.should have_tag('form li#post_author_input')
935
+ it "should generate a #{input_type} input" do
936
+ output_buffer.should have_tag("form li #{input_type}")
937
+ output_buffer.should have_tag("form li #{input_type}#post_body")
938
+ output_buffer.should have_tag("form li #{input_type}[@name=\"post[body]\"]")
956
939
  end
957
940
 
958
- it 'should generate a fieldset and legend containing label text for the input' do
959
- output_buffer.should have_tag('form li fieldset')
960
- output_buffer.should have_tag('form li fieldset legend')
961
- output_buffer.should have_tag('form li fieldset legend', /Author/)
941
+ it 'should use input_html to style inputs' do
942
+ semantic_form_for(@new_post) do |builder|
943
+ concat(builder.input(:title, :as => type, :input_html => { :class => 'myclass' }))
944
+ end
945
+ output_buffer.should have_tag("form li #{input_type}.myclass")
962
946
  end
963
947
 
964
- it 'should generate an ordered list with a list item for each choice' do
965
- output_buffer.should have_tag('form li fieldset ol')
966
- output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
967
- end
948
+ end
968
949
 
969
- it 'should have one option with a "selected" attribute' do
970
- output_buffer.should have_tag('form li input[@checked]', :count => 1)
950
+ it 'should generate input and labels even if no object is given' do
951
+ semantic_form_for(:project, :url => 'http://test.host/') do |builder|
952
+ concat(builder.input(:title, :as => type))
971
953
  end
972
954
 
973
- describe "each choice" do
955
+ output_buffer.should have_tag('form li label')
956
+ output_buffer.should have_tag('form li label[@for="project_title"')
957
+ output_buffer.should have_tag('form li label', /Title/)
974
958
 
975
- it 'should contain a label for the radio input with a nested input and label text' do
976
- Author.find(:all).each do |author|
977
- output_buffer.should have_tag('form li fieldset ol li label')
978
- output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
979
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_id_#{author.id}']")
980
- output_buffer.should have_tag("form li fieldset ol li label input")
981
- end
982
- end
959
+ if template_method.to_s =~ /_field$/ # password_field
960
+ output_buffer.should have_tag("form li input")
961
+ output_buffer.should have_tag("form li input#project_title")
962
+ output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
963
+ output_buffer.should have_tag("form li input[@name=\"project[title]\"]")
964
+ else
965
+ output_buffer.should have_tag("form li #{input_type}")
966
+ output_buffer.should have_tag("form li #{input_type}#project_title")
967
+ output_buffer.should have_tag("form li #{input_type}[@name=\"project[title]\"]")
968
+ end
969
+ end
983
970
 
984
- it "should have a radio input" do
985
- Author.find(:all).each do |author|
986
- output_buffer.should have_tag("form li fieldset ol li label input#post_author_id_#{author.id}")
987
- output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
988
- output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
989
- output_buffer.should have_tag("form li fieldset ol li label input[@name='post[author_id]']")
990
- end
991
- end
971
+ end
972
+ end
992
973
 
993
- xit "should mark input as checked if it's the the existing choice" do
994
- @new_post.author_id.should == @bob.id
995
- @new_post.author.id.should == @bob.id
996
- @new_post.author.should == @bob
997
- semantic_form_for(@new_post) do |builder|
998
- concat(builder.input(:author_id, :as => :radio))
999
- end
1000
974
 
1001
- output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
1002
- end
975
+ describe ':as => :radio' do
976
+
977
+ before do
978
+ @new_post.stub!(:author).and_return(@bob)
979
+ @new_post.stub!(:author_id).and_return(@bob.id)
980
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
981
+ end
1003
982
 
983
+ describe 'for belongs_to association' do
984
+ before do
985
+ semantic_form_for(@new_post) do |builder|
986
+ concat(builder.input(:author, :as => :radio, :value_as_class => true))
1004
987
  end
988
+ end
1005
989
 
990
+ it 'should have a radio class on the wrapper' do
991
+ output_buffer.should have_tag('form li.radio')
1006
992
  end
1007
993
 
1008
- describe 'when the :collection option is not provided' do
994
+ it 'should have a post_author_id_input id on the wrapper' do
995
+ output_buffer.should have_tag('form li#post_author_input')
996
+ end
1009
997
 
1010
- it 'should perform a basic find on the parent class' do
1011
- Author.should_receive(:find)
1012
- semantic_form_for(@new_post) do |builder|
1013
- concat(builder.input(:author, :as => :radio))
1014
- end
1015
- end
998
+ it 'should generate a fieldset and legend containing label text for the input' do
999
+ output_buffer.should have_tag('form li fieldset')
1000
+ output_buffer.should have_tag('form li fieldset legend')
1001
+ output_buffer.should have_tag('form li fieldset legend', /Author/)
1002
+ end
1016
1003
 
1004
+ it 'should generate an ordered list with a list item for each choice' do
1005
+ output_buffer.should have_tag('form li fieldset ol')
1006
+ output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
1017
1007
  end
1018
1008
 
1019
- describe 'when the :collection option is provided' do
1009
+ it 'should have one option with a "selected" attribute' do
1010
+ output_buffer.should have_tag('form li input[@checked]', :count => 1)
1011
+ end
1020
1012
 
1021
- before do
1022
- @authors = Author.find(:all) * 2
1023
- output_buffer.replace '' # clears the output_buffer from the before block, hax!
1024
- end
1013
+ describe "each choice" do
1025
1014
 
1026
- it 'should not call find() on the parent class' do
1027
- Author.should_not_receive(:find)
1028
- semantic_form_for(@new_post) do |builder|
1029
- concat(builder.input(:author, :as => :radio, :collection => @authors))
1015
+ it 'should contain a label for the radio input with a nested input and label text' do
1016
+ Author.find(:all).each do |author|
1017
+ output_buffer.should have_tag('form li fieldset ol li label')
1018
+ output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
1019
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_id_#{author.id}']")
1020
+ output_buffer.should have_tag("form li fieldset ol li label input")
1030
1021
  end
1031
1022
  end
1032
1023
 
1033
- it 'should use the provided collection' do
1034
- semantic_form_for(@new_post) do |builder|
1035
- concat(builder.input(:author, :as => :radio, :collection => @authors))
1024
+ it 'should use values as li.class when value_as_class is true' do
1025
+ Author.find(:all).each do |author|
1026
+ output_buffer.should have_tag("form li fieldset ol li.#{author.id} label")
1036
1027
  end
1037
- output_buffer.should have_tag('form li fieldset ol li', :count => @authors.size)
1038
1028
  end
1039
1029
 
1040
- describe 'and the :collection is an array of strings' do
1041
-
1042
- before do
1043
- @new_post.stub!(:category_name).and_return('')
1044
- @categories = [ 'General', 'Design', 'Development' ]
1030
+ it "should have a radio input" do
1031
+ Author.find(:all).each do |author|
1032
+ output_buffer.should have_tag("form li fieldset ol li label input#post_author_id_#{author.id}")
1033
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
1034
+ output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
1035
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='post[author_id]']")
1045
1036
  end
1037
+ end
1046
1038
 
1047
- it 'should use the string as the label text and value for each radio button' do
1048
- semantic_form_for(@new_post) do |builder|
1049
- concat(builder.input(:category_name, :as => :radio, :collection => @categories))
1050
- end
1051
- @categories.each do |item|
1052
- output_buffer.should have_tag('form li fieldset ol li label', /#{item}/i)
1053
- output_buffer.should have_tag('form li fieldset ol li label input[@value='+item+']')
1054
- end
1039
+ it "should mark input as checked if it's the the existing choice" do
1040
+ @new_post.author_id.should == @bob.id
1041
+ @new_post.author.id.should == @bob.id
1042
+ @new_post.author.should == @bob
1043
+
1044
+ semantic_form_for(@new_post) do |builder|
1045
+ concat(builder.input(:author, :as => :radio))
1055
1046
  end
1056
1047
 
1057
- it 'should generate a sanitized label for attribute' do
1058
- @bob.stub!(:category_name).and_return(@categories)
1059
- semantic_form_for(@new_post) do |builder|
1060
- builder.semantic_fields_for(@bob) do |bob_builder|
1061
- concat(bob_builder.input(:category_name, :as => :radio, :collection => @categories))
1062
- end
1063
- end
1048
+ output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
1049
+ end
1050
+ end
1064
1051
 
1065
- @categories.each do |item|
1066
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_#{item.downcase}']")
1067
- end
1068
- end
1052
+ it 'should generate a fieldset, legend, labels and inputs even if no object is given' do
1053
+ output_buffer.replace ''
1069
1054
 
1055
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
1056
+ concat(builder.input(:author_id, :as => :radio, :collection => Author.find(:all)))
1070
1057
  end
1071
1058
 
1072
- describe 'and the :collection is a hash of strings' do
1059
+ output_buffer.should have_tag('form li fieldset legend', /Author/)
1060
+ output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
1073
1061
 
1074
- before do
1075
- @new_post.stub!(:category_name).and_return('')
1076
- @categories = { 'General' => 'gen', 'Design' => 'des','Development' => 'dev' }
1077
- end
1062
+ Author.find(:all).each do |author|
1063
+ output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
1064
+ output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
1078
1065
 
1079
- it 'should use the key as the label text and the hash value as the value attribute for each radio button' do
1080
- semantic_form_for(@new_post) do |builder|
1081
- concat(builder.input(:category_name, :as => :radio, :collection => @categories))
1082
- end
1083
- @categories.each do |label, value|
1084
- output_buffer.should have_tag('form li fieldset ol li label', /#{label}/i)
1085
- output_buffer.should have_tag('form li fieldset ol li label input[@value='+value+']')
1086
- end
1087
- end
1066
+ output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
1067
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
1068
+ output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
1069
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id]']")
1070
+ end
1071
+ end
1072
+
1073
+ end
1074
+
1075
+ end
1076
+
1077
+ describe ':as => :select' do
1078
+
1079
+ before do
1080
+ @new_post.stub!(:author).and_return(@bob)
1081
+ @new_post.stub!(:author_id).and_return(@bob.id)
1082
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
1083
+ end
1088
1084
 
1085
+ describe 'for a belongs_to association' do
1086
+ before do
1087
+ semantic_form_for(@new_post) do |builder|
1088
+ concat(builder.input(:author, :as => :select))
1089
1089
  end
1090
+ end
1090
1091
 
1092
+ it 'should have a select class on the wrapper' do
1093
+ output_buffer.should have_tag('form li.select')
1091
1094
  end
1092
1095
 
1093
- describe 'when the :label_method option is provided' do
1094
- before do
1095
- semantic_form_for(@new_post) do |builder|
1096
- concat(builder.input(:author, :as => :radio, :label_method => :login))
1097
- end
1096
+ it 'should have a post_author_input id on the wrapper' do
1097
+ output_buffer.should have_tag('form li#post_author_input')
1098
+ end
1099
+
1100
+ it 'should have a label inside the wrapper' do
1101
+ output_buffer.should have_tag('form li label')
1102
+ output_buffer.should have_tag('form li label', /Author/)
1103
+ output_buffer.should have_tag("form li label[@for='post_author_id']")
1104
+ end
1105
+
1106
+ it 'should have a select inside the wrapper' do
1107
+ output_buffer.should have_tag('form li select')
1108
+ output_buffer.should have_tag('form li select#post_author_id')
1109
+ end
1110
+
1111
+ it 'should not create a multi-select' do
1112
+ output_buffer.should_not have_tag('form li select[@multiple]')
1113
+ end
1114
+
1115
+ it 'should create a select without size' do
1116
+ output_buffer.should_not have_tag('form li select[@size]')
1117
+ end
1118
+
1119
+ it 'should have a select option for each Author' do
1120
+ output_buffer.should have_tag('form li select option', :count => Author.find(:all).size)
1121
+ Author.find(:all).each do |author|
1122
+ output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1098
1123
  end
1124
+ end
1099
1125
 
1100
- it 'should have options with text content from the specified method' do
1101
- Author.find(:all).each do |author|
1102
- output_buffer.should have_tag("form li fieldset ol li label", /#{author.login}/)
1103
- end
1126
+ it 'should have one option with a "selected" attribute' do
1127
+ output_buffer.should have_tag('form li select option[@selected]', :count => 1)
1128
+ end
1129
+ end
1130
+
1131
+ describe 'for a has_many association' do
1132
+ before do
1133
+ semantic_form_for(@fred) do |builder|
1134
+ concat(builder.input(:posts, :as => :select))
1104
1135
  end
1105
1136
  end
1106
1137
 
1107
- describe 'when the :label_method option is not provided' do
1108
- Formtastic::SemanticFormBuilder.collection_label_methods.each do |label_method|
1109
- describe "when the collection objects respond to #{label_method}" do
1110
- before do
1111
- @fred.stub!(:respond_to?).and_return { |m| m.to_s == label_method }
1112
- Author.find(:all).each { |a| a.stub!(label_method).and_return('The Label Text') }
1113
- semantic_form_for(@new_post) do |builder|
1114
- concat(builder.input(:author, :as => :radio))
1115
- end
1116
- end
1138
+ it 'should have a select class on the wrapper' do
1139
+ output_buffer.should have_tag('form li.select')
1140
+ end
1117
1141
 
1118
- it "should render the options with #{label_method} as the label" do
1119
- Author.find(:all).each do |author|
1120
- output_buffer.should have_tag("form li fieldset ol li label", /The Label Text/)
1121
- end
1122
- end
1123
- end
1142
+ it 'should have a post_author_input id on the wrapper' do
1143
+ output_buffer.should have_tag('form li#author_posts_input')
1144
+ end
1145
+
1146
+ it 'should have a label inside the wrapper' do
1147
+ output_buffer.should have_tag('form li label')
1148
+ output_buffer.should have_tag('form li label', /Posts/)
1149
+ output_buffer.should have_tag("form li label[@for='author_post_ids']")
1150
+ end
1151
+
1152
+ it 'should have a select inside the wrapper' do
1153
+ output_buffer.should have_tag('form li select')
1154
+ output_buffer.should have_tag('form li select#author_post_ids')
1155
+ end
1156
+
1157
+ it 'should have a multi-select select' do
1158
+ output_buffer.should have_tag('form li select[@multiple="multiple"]')
1159
+ end
1160
+
1161
+ it 'should have a select option for each Post' do
1162
+ output_buffer.should have_tag('form li select option', :count => Post.find(:all).size)
1163
+ Post.find(:all).each do |post|
1164
+ output_buffer.should have_tag("form li select option[@value='#{post.id}']", /#{post.to_label}/)
1124
1165
  end
1125
1166
  end
1126
1167
 
1168
+ it 'should have one option with a "selected" attribute' do
1169
+ output_buffer.should have_tag('form li select option[@selected]', :count => 1)
1170
+ end
1127
1171
  end
1128
1172
 
1129
- describe ':as => :select' do
1173
+ describe 'for a has_and_belongs_to_many association' do
1174
+ before do
1175
+ semantic_form_for(@freds_post) do |builder|
1176
+ concat(builder.input(:authors, :as => :select))
1177
+ end
1178
+ end
1179
+
1180
+ it 'should have a select class on the wrapper' do
1181
+ output_buffer.should have_tag('form li.select')
1182
+ end
1130
1183
 
1131
- describe 'when using the association method' do
1184
+ it 'should have a post_author_input id on the wrapper' do
1185
+ output_buffer.should have_tag('form li#post_authors_input')
1186
+ end
1132
1187
 
1133
- describe 'for a belongs_to association' do
1188
+ it 'should have a label inside the wrapper' do
1189
+ output_buffer.should have_tag('form li label')
1190
+ output_buffer.should have_tag('form li label', /Authors/)
1191
+ output_buffer.should have_tag("form li label[@for='post_author_ids']")
1192
+ end
1134
1193
 
1135
- before do
1136
- semantic_form_for(@new_post) do |builder|
1137
- concat(builder.input(:author, :as => :select))
1138
- end
1139
- end
1194
+ it 'should have a select inside the wrapper' do
1195
+ output_buffer.should have_tag('form li select')
1196
+ output_buffer.should have_tag('form li select#post_author_ids')
1197
+ end
1140
1198
 
1141
- it 'should have a select class on the wrapper' do
1142
- output_buffer.should have_tag('form li.select')
1143
- end
1199
+ it 'should have a multi-select select' do
1200
+ output_buffer.should have_tag('form li select[@multiple="multiple"]')
1201
+ end
1144
1202
 
1145
- it 'should have a post_author_id_input id on the wrapper' do
1146
- output_buffer.should have_tag('form li#post_author_input')
1147
- end
1203
+ it 'should have a select option for each Author' do
1204
+ output_buffer.should have_tag('form li select option', :count => Author.find(:all).size)
1205
+ Author.find(:all).each do |author|
1206
+ output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1207
+ end
1208
+ end
1148
1209
 
1149
- it 'should have a label inside the wrapper' do
1150
- output_buffer.should have_tag('form li label')
1151
- end
1210
+ it 'should have one option with a "selected" attribute' do
1211
+ output_buffer.should have_tag('form li select option[@selected]', :count => 1)
1212
+ end
1213
+ end
1152
1214
 
1153
- it 'should have a select inside the wrapper' do
1154
- output_buffer.should have_tag('form li select')
1155
- end
1215
+ describe 'when :include_blank => true, :prompt => "choose something" is set' do
1216
+ before do
1217
+ @new_post.stub!(:author_id).and_return(nil)
1218
+ semantic_form_for(@new_post) do |builder|
1219
+ concat(builder.input(:author, :as => :select, :include_blank => true, :prompt => "choose author"))
1220
+ end
1221
+ end
1156
1222
 
1157
- it 'should not create a multi-select' do
1158
- output_buffer.should_not have_tag('form li select[@multiple]')
1159
- end
1223
+ it 'should have a blank select option' do
1224
+ output_buffer.should have_tag("form li select option[@value='']", //)
1225
+ end
1160
1226
 
1161
- it 'should create a select without size' do
1162
- output_buffer.should_not have_tag('form li select[@size]')
1163
- end
1227
+ it 'should have a select with prompt' do
1228
+ output_buffer.should have_tag("form li select option[@value='']", /choose author/)
1229
+ end
1230
+ end
1164
1231
 
1165
- it 'should have a select option for each Author' do
1166
- output_buffer.should have_tag('form li select option', :count => Author.find(:all).size)
1167
- Author.find(:all).each do |author|
1168
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1169
- end
1170
- end
1232
+ it 'should generate label, select and options even if object is not given' do
1233
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
1234
+ concat(builder.input(:author, :as => :select, :collection => Author.find(:all)))
1235
+ end
1171
1236
 
1172
- it 'should have one option with a "selected" attribute' do
1173
- output_buffer.should have_tag('form li select option[@selected]', :count => 1)
1174
- end
1237
+ output_buffer.should have_tag('form li label', /Author/)
1238
+ output_buffer.should have_tag("form li label[@for='project_author']")
1175
1239
 
1176
- end
1240
+ output_buffer.should have_tag('form li select#project_author')
1241
+ output_buffer.should have_tag('form li select option', :count => Author.find(:all).size)
1242
+
1243
+ Author.find(:all).each do |author|
1244
+ output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1245
+ end
1246
+ end
1247
+ end
1177
1248
 
1178
- describe 'for a has_many association' do
1249
+ describe 'for collections' do
1179
1250
 
1180
- before do
1181
- semantic_form_for(@fred) do |builder|
1182
- concat(builder.input(:posts, :as => :select))
1251
+ before do
1252
+ @new_post.stub!(:author).and_return(@bob)
1253
+ @new_post.stub!(:author_id).and_return(@bob.id)
1254
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
1255
+ end
1256
+
1257
+ { :select => :option, :radio => :input }.each do |type, countable|
1258
+
1259
+ describe ":as => #{type.inspect}" do
1260
+ describe 'when the :collection option is not provided' do
1261
+ it 'should perform a basic find on the association class' do
1262
+ Author.should_receive(:find)
1263
+
1264
+ semantic_form_for(@new_post) do |builder|
1265
+ concat(builder.input(:author, :as => type))
1183
1266
  end
1184
1267
  end
1185
1268
 
1186
- it 'should have a select class on the wrapper' do
1187
- output_buffer.should have_tag('form li.select')
1188
- end
1269
+ it 'should show a deprecation warning if user gives the association using _id' do
1270
+ # Check for deprecation message
1271
+ ::ActiveSupport::Deprecation.should_receive(:warn).with(/association/, anything())
1189
1272
 
1190
- it 'should have a post_author_id_input id on the wrapper' do
1191
- output_buffer.should have_tag('form li#author_posts_input')
1273
+ Author.should_receive(:find)
1274
+ semantic_form_for(@new_post) do |builder|
1275
+ concat(builder.input(:author_id, :as => type))
1276
+ end
1192
1277
  end
1278
+ end
1193
1279
 
1194
- it 'should have a label inside the wrapper' do
1195
- output_buffer.should have_tag('form li label')
1196
- end
1280
+ describe 'when the :collection option is provided' do
1197
1281
 
1198
- it 'should have a select inside the wrapper' do
1199
- output_buffer.should have_tag('form li select')
1282
+ before do
1283
+ @authors = Author.find(:all) * 2
1284
+ output_buffer.replace '' # clears the output_buffer from the before block, hax!
1200
1285
  end
1201
1286
 
1202
- it 'should have a multi-select select' do
1203
- output_buffer.should have_tag('form li select[@multiple="multiple"]')
1287
+ it 'should not call find() on the parent class' do
1288
+ Author.should_not_receive(:find)
1289
+ semantic_form_for(@new_post) do |builder|
1290
+ concat(builder.input(:author, :as => type, :collection => @authors))
1291
+ end
1204
1292
  end
1205
1293
 
1206
- it 'should have a select option for each Post' do
1207
- output_buffer.should have_tag('form li select option', :count => Post.find(:all).size)
1208
- Post.find(:all).each do |post|
1209
- output_buffer.should have_tag("form li select option[@value='#{post.id}']", /#{post.to_label}/)
1294
+ it 'should use the provided collection' do
1295
+ semantic_form_for(@new_post) do |builder|
1296
+ concat(builder.input(:author, :as => type, :collection => @authors))
1210
1297
  end
1298
+ output_buffer.should have_tag("form li.#{type} #{countable}", :count => @authors.size)
1211
1299
  end
1212
1300
 
1213
- it 'should have one option with a "selected" attribute' do
1214
- output_buffer.should have_tag('form li select option[@selected]', :count => 1)
1215
- end
1301
+ describe 'and the :collection is an array of strings' do
1302
+ before do
1303
+ @new_post.stub!(:category_name).and_return('')
1304
+ @categories = [ 'General', 'Design', 'Development' ]
1305
+ end
1216
1306
 
1217
- end
1307
+ it "should use the string as the label text and value for each #{countable}" do
1308
+ semantic_form_for(@new_post) do |builder|
1309
+ concat(builder.input(:category_name, :as => type, :collection => @categories))
1310
+ end
1218
1311
 
1219
- describe 'for a has_and_belongs_to_many association' do
1312
+ @categories.each do |item|
1313
+ output_buffer.should have_tag("form li.#{type}", /#{item}/)
1314
+ output_buffer.should have_tag("form li.#{type} #{countable}[@value=#{item}]")
1315
+ end
1316
+ end
1220
1317
 
1221
- before do
1222
- semantic_form_for(@freds_post) do |builder|
1223
- concat(builder.input(:authors, :as => :select))
1318
+ if type == :radio
1319
+ it 'should generate a sanitized label for attribute' do
1320
+ @bob.stub!(:category_name).and_return(@categories)
1321
+ semantic_form_for(@new_post) do |builder|
1322
+ builder.semantic_fields_for(@bob) do |bob_builder|
1323
+ concat(bob_builder.input(:category_name, :as => type, :collection => @categories))
1324
+ end
1325
+ end
1326
+
1327
+ @categories.each do |item|
1328
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_#{item.downcase}']")
1329
+ end
1330
+ end
1224
1331
  end
1225
1332
  end
1226
1333
 
1227
- it 'should have a select class on the wrapper' do
1228
- output_buffer.should have_tag('form li.select')
1229
- end
1334
+ describe 'and the :collection is a hash of strings' do
1335
+ before do
1336
+ @new_post.stub!(:category_name).and_return('')
1337
+ @categories = { 'General' => 'gen', 'Design' => 'des','Development' => 'dev' }
1338
+ end
1230
1339
 
1231
- it 'should have a post_author_id_input id on the wrapper' do
1232
- output_buffer.should have_tag('form li#post_authors_input')
1233
- end
1340
+ it "should use the key as the label text and the hash value as the value attribute for each #{countable}" do
1341
+ semantic_form_for(@new_post) do |builder|
1342
+ concat(builder.input(:category_name, :as => type, :collection => @categories))
1343
+ end
1234
1344
 
1235
- it 'should have a label inside the wrapper' do
1236
- output_buffer.should have_tag('form li label')
1345
+ @categories.each do |label, value|
1346
+ output_buffer.should have_tag("form li.#{type}", /#{label}/)
1347
+ output_buffer.should have_tag("form li.#{type} #{countable}[@value=#{value}]")
1348
+ end
1349
+ end
1237
1350
  end
1238
1351
 
1239
- it 'should have a select inside the wrapper' do
1240
- output_buffer.should have_tag('form li select')
1241
- end
1352
+ describe 'and the :collection is an array of arrays' do
1353
+ before do
1354
+ @new_post.stub!(:category_name).and_return('')
1355
+ @categories = { 'General' => 'gen', 'Design' => 'des','Development' => 'dev' }.to_a
1356
+ end
1242
1357
 
1243
- it 'should have a multi-select select' do
1244
- output_buffer.should have_tag('form li select[@multiple="multiple"]')
1245
- end
1358
+ it "should use the first value as the label text and the last value as the value attribute for #{countable}" do
1359
+ semantic_form_for(@new_post) do |builder|
1360
+ concat(builder.input(:category_name, :as => :radio, :collection => @categories))
1361
+ end
1246
1362
 
1247
- it 'should have a select option for each Author' do
1248
- output_buffer.should have_tag('form li select option', :count => Author.find(:all).size)
1249
- Author.find(:all).each do |author|
1250
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1363
+ @categories.each do |label, value|
1364
+ output_buffer.should have_tag('form li fieldset ol li label', /#{label}/i)
1365
+ output_buffer.should have_tag('form li fieldset ol li label input[@value='+value+']')
1366
+ end
1251
1367
  end
1252
1368
  end
1253
1369
 
1254
- it 'should have one option with a "selected" attribute' do
1255
- output_buffer.should have_tag('form li select option[@selected]', :count => 1)
1256
- end
1370
+ describe 'and the :collection is an array of symbols' do
1371
+ before do
1372
+ @new_post.stub!(:category_name).and_return('')
1373
+ @categories = [ :General, :Design, :Development ]
1374
+ end
1257
1375
 
1258
- end
1376
+ it "should use the symbol as the label text and value for each #{countable}" do
1377
+ semantic_form_for(@new_post) do |builder|
1378
+ concat(builder.input(:category_name, :as => :radio, :collection => @categories))
1379
+ end
1259
1380
 
1260
- end
1381
+ @categories.each do |value|
1382
+ output_buffer.should have_tag('form li fieldset ol li label', /#{value}/i)
1383
+ output_buffer.should have_tag('form li fieldset ol li label input[@value='+value.to_s+']')
1384
+ end
1385
+ end
1386
+ end
1261
1387
 
1262
- describe 'when using the association_id method' do
1388
+ describe 'when the :label_method option is provided' do
1389
+ before do
1390
+ semantic_form_for(@new_post) do |builder|
1391
+ concat(builder.input(:author, :as => type, :label_method => :login))
1392
+ end
1393
+ end
1263
1394
 
1264
- before do
1265
- ::ActiveSupport::Deprecation.should_receive(:warn).with(/association/, anything())
1266
- semantic_form_for(@new_post) do |builder|
1267
- concat(builder.input(:author_id, :as => :select))
1395
+ it 'should have options with text content from the specified method' do
1396
+ Author.find(:all).each do |author|
1397
+ output_buffer.should have_tag("form li.#{type}", /#{author.login}/)
1398
+ end
1399
+ end
1268
1400
  end
1269
- end
1270
1401
 
1271
- it 'should have a select class on the wrapper' do
1272
- output_buffer.should have_tag('form li.select')
1273
- end
1402
+ describe 'when the :label_method option is not provided' do
1403
+ Formtastic::SemanticFormBuilder.collection_label_methods.each do |label_method|
1274
1404
 
1275
- it 'should have a post_author_id_input id on the wrapper' do
1276
- output_buffer.should have_tag('form li#post_author_id_input')
1277
- end
1405
+ describe "when the collection objects respond to #{label_method}" do
1406
+ before do
1407
+ @fred.stub!(:respond_to?).and_return { |m| m.to_s == label_method }
1408
+ Author.find(:all).each { |a| a.stub!(label_method).and_return('The Label Text') }
1278
1409
 
1279
- it 'should have a label inside the wrapper' do
1280
- output_buffer.should have_tag('form li label')
1281
- end
1410
+ semantic_form_for(@new_post) do |builder|
1411
+ concat(builder.input(:author, :as => type))
1412
+ end
1413
+ end
1282
1414
 
1283
- it 'should have a select inside the wrapper' do
1284
- output_buffer.should have_tag('form li select')
1285
- end
1415
+ it "should render the options with #{label_method} as the label" do
1416
+ Author.find(:all).each do |author|
1417
+ output_buffer.should have_tag("form li.#{type}", /The Label Text/)
1418
+ end
1419
+ end
1420
+ end
1286
1421
 
1287
- it 'should have a select option for each Author' do
1288
- output_buffer.should have_tag('form li select option', :count => Author.find(:all).size)
1289
- Author.find(:all).each do |author|
1290
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1422
+ end
1291
1423
  end
1292
- end
1293
-
1294
- it 'should have one option with a "selected" attribute' do
1295
- output_buffer.should have_tag('form li select option[@selected]', :count => 1)
1296
- end
1297
-
1298
- end
1299
1424
 
1300
- describe 'when the :collection option is not provided' do
1425
+ describe 'when the :value_method option is provided' do
1426
+ before do
1427
+ semantic_form_for(@new_post) do |builder|
1428
+ concat(builder.input(:author, :as => type, :value_method => :login))
1429
+ end
1430
+ end
1301
1431
 
1302
- it 'should perform a basic find on the parent class' do
1303
- Author.should_receive(:find)
1304
- semantic_form_for(@new_post) do |builder|
1305
- concat(builder.input(:author, :as => :select))
1432
+ it 'should have options with values from specified method' do
1433
+ Author.find(:all).each do |author|
1434
+ output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{author.login}']")
1435
+ end
1436
+ end
1306
1437
  end
1438
+
1307
1439
  end
1308
1440
 
1309
- end
1441
+ describe 'when attribute is a boolean' do
1310
1442
 
1311
- describe 'when the :collection option is provided' do
1443
+ before do
1444
+ @new_post.stub!(:allow_comments)
1445
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1312
1446
 
1313
- before do
1314
- @authors = Author.find(:all) * 2
1315
- output_buffer.replace '' # clears the output_buffer from the before block, hax!
1316
- end
1447
+ semantic_form_for(@new_post) do |builder|
1448
+ concat(builder.input(:allow_comments, :as => type))
1449
+ end
1450
+ end
1317
1451
 
1318
- it 'should not call find() on the parent class' do
1319
- Author.should_not_receive(:find)
1320
- semantic_form_for(@new_post) do |builder|
1321
- concat(builder.input(:author, :as => :select, :collection => @authors))
1452
+ it "should have a #{type} class on the wrapper" do
1453
+ output_buffer.should have_tag("form li.#{type}")
1322
1454
  end
1323
- end
1324
1455
 
1325
- it 'should use the provided collection' do
1326
- semantic_form_for(@new_post) do |builder|
1327
- concat(builder.input(:author, :as => :select, :collection => @authors))
1456
+ it 'should have a post_allow_comments_input id on the wrapper' do
1457
+ output_buffer.should have_tag('form li#post_allow_comments_input')
1328
1458
  end
1329
- output_buffer.should have_tag('form li select option', :count => @authors.size)
1330
- end
1331
1459
 
1332
- describe 'and the :collection is an array of strings' do
1460
+ it 'should generate a fieldset containing a legend' do
1461
+ output_buffer.should have_tag("form li.#{type}", /Allow comments/)
1462
+ end
1333
1463
 
1334
- before do
1335
- @new_post.stub!(:category_name).and_return('')
1336
- @categories = [ 'General', 'Design', 'Development' ]
1464
+ it "should generate two #{countable}" do
1465
+ output_buffer.should have_tag("form li.#{type} #{countable}", :count => 2)
1466
+ output_buffer.should have_tag(%{form li.#{type} #{countable}[@value="true"]})
1467
+ output_buffer.should have_tag(%{form li.#{type} #{countable}[@value="false"]})
1337
1468
  end
1338
1469
 
1339
- it 'should use the string as the text and value for each option element' do
1340
- semantic_form_for(@new_post) do |builder|
1341
- concat(builder.input(:category_name, :as => :select, :collection => @categories))
1470
+ describe 'when the locale sets the label text' do
1471
+ before do
1472
+ I18n.backend.store_translations 'en', :formtastic => {:yes => 'Absolutely!', :no => 'Never!'}
1473
+
1474
+ semantic_form_for(@new_post) do |builder|
1475
+ concat(builder.input(:allow_comments, :as => type))
1476
+ end
1342
1477
  end
1343
- @categories.each do |item|
1344
- output_buffer.should have_tag('form li select option[@value='+item+']', item)
1478
+
1479
+ after do
1480
+ I18n.backend.store_translations 'en', :formtastic => {:yes => nil, :no => nil}
1345
1481
  end
1346
- end
1347
1482
 
1348
- end
1483
+ it 'should allow translation of the labels' do
1484
+ output_buffer.should have_tag("form li.#{type}", /Absolutely\!/)
1485
+ output_buffer.should have_tag("form li.#{type}", /Never\!/)
1486
+ end
1487
+ end
1349
1488
 
1350
- describe 'and the :collection is a hash of strings' do
1489
+ checked_or_selected = { :select => :selected, :radio => :checked }[type]
1351
1490
 
1352
- before do
1353
- @new_post.stub!(:category_name).and_return('')
1354
- @categories = { 'General' => 'gen', 'Design' => 'des','Development' => 'dev' }
1355
- end
1491
+ describe 'when the value is nil' do
1492
+ before do
1493
+ @new_post.stub!(:allow_comments).and_return(nil)
1494
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1356
1495
 
1357
- it 'should use the key as the text and the hash value as the value attribute for each option element' do
1358
- semantic_form_for(@new_post) do |builder|
1359
- concat(builder.input(:category_name, :as => :select, :collection => @categories))
1496
+ semantic_form_for(@new_post) do |builder|
1497
+ concat(builder.input(:allow_comments, :as => type))
1498
+ end
1360
1499
  end
1361
- @categories.each do |label, value|
1362
- output_buffer.should have_tag('form li select option[@value='+value+']', label)
1500
+
1501
+ it "should not mark either #{countable} as #{checked_or_selected}" do
1502
+ output_buffer.should_not have_tag(%{form li.#{type} input[@#{checked_or_selected}="#{checked_or_selected}"]})
1363
1503
  end
1364
1504
  end
1365
1505
 
1366
- end
1506
+ describe 'when the value is true' do
1507
+ before do
1508
+ @new_post.stub!(:allow_comments).and_return(true)
1509
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1510
+ semantic_form_for(@new_post) do |builder|
1511
+ concat(builder.input(:allow_comments, :as => type))
1512
+ end
1513
+ end
1367
1514
 
1368
- end
1515
+ it "should mark the true #{countable} as #{checked_or_selected}" do
1516
+ output_buffer.should have_tag(%{form li.#{type} #{countable}[@value="true"][@#{checked_or_selected}="#{checked_or_selected}"]}, :count => 1)
1517
+ end
1369
1518
 
1370
- describe 'when :include_blank => true, :prompt => "choose something" is set' do
1371
- before do
1372
- @new_post.stub!(:author_id).and_return(nil)
1373
- semantic_form_for(@new_post) do |builder|
1374
- concat(builder.input(:author, :as => :select, :include_blank => true, :prompt => "choose author"))
1519
+ it "should not mark the false #{countable} as #{checked_or_selected}" do
1520
+ output_buffer.should_not have_tag(%{form li.#{type} #{countable}[@value="false"][@#{checked_or_selected}="#{checked_or_selected}"]})
1521
+ end
1375
1522
  end
1376
- end
1377
-
1378
- it 'should have a blank select option' do
1379
- output_buffer.should have_tag("form li select option[@value='']", //)
1380
- end
1381
1523
 
1382
- it 'should have a select with prompt' do
1383
- output_buffer.should have_tag("form li select option[@value='']", /choose author/)
1384
- end
1385
- end
1524
+ describe 'when the value is false' do
1525
+ before do
1526
+ @new_post.stub!(:allow_comments).and_return(false)
1527
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1528
+ semantic_form_for(@new_post) do |builder|
1529
+ concat(builder.input(:allow_comments, :as => type))
1530
+ end
1531
+ end
1386
1532
 
1387
- describe 'when the :value_method option is provided' do
1388
- before do
1389
- semantic_form_for(@new_post) do |builder|
1390
- concat(builder.input(:author, :as => :select, :value_method => :login))
1391
- end
1392
- end
1533
+ it "should not mark the true #{countable} as #{checked_or_selected}" do
1534
+ output_buffer.should_not have_tag(%{form li.#{type} #{countable}[@value="true"][@#{checked_or_selected}="#{checked_or_selected}"]})
1535
+ end
1393
1536
 
1394
- it 'should have options with values from specified method' do
1395
- Author.find(:all).each do |author|
1396
- output_buffer.should have_tag("form li select option[@value='#{author.login}']")
1537
+ it "should mark the false #{countable} as #{checked_or_selected}" do
1538
+ output_buffer.should have_tag(%{form li.#{type} #{countable}[@value="false"][@#{checked_or_selected}="#{checked_or_selected}"]}, :count => 1)
1539
+ end
1397
1540
  end
1398
- end
1399
- end
1400
1541
 
1401
- describe 'when the :label_method option is not provided' do
1402
- Formtastic::SemanticFormBuilder.collection_label_methods.each do |label_method|
1403
- describe "when the collection objects respond to #{label_method}" do
1542
+ describe 'when :true and :false options are provided' do
1404
1543
  before do
1405
- @fred.stub!(:respond_to?).and_return { |m| m.to_s == label_method }
1406
- Author.find(:all).each { |a| a.stub!(label_method).and_return('The Label Text') }
1544
+ @new_post.stub!(:allow_comments)
1545
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1407
1546
  semantic_form_for(@new_post) do |builder|
1408
- concat(builder.input(:author, :as => :select))
1547
+ concat(builder.input(:allow_comments, :as => type, :true => "Absolutely", :false => "No Way"))
1409
1548
  end
1410
1549
  end
1411
1550
 
1412
- it "should render the options with #{label_method} as the label" do
1413
- Author.find(:all).each do |author|
1414
- output_buffer.should have_tag("form li select option", /The Label Text/)
1415
- end
1551
+ it 'should use them as labels' do
1552
+ output_buffer.should have_tag("form li.#{type}", /Absolutely/)
1553
+ output_buffer.should have_tag("form li.#{type}", /No Way/)
1416
1554
  end
1417
1555
  end
1418
1556
  end
1419
- end
1420
1557
 
1421
- describe 'when the :label_method option is provided' do
1422
- before do
1423
- semantic_form_for(@new_post) do |builder|
1424
- concat(builder.input(:author, :as => :select, :label_method => :login))
1425
- end
1426
- end
1427
1558
 
1428
- it 'should have options with text content from the specified method' do
1429
- Author.find(:all).each do |author|
1430
- output_buffer.should have_tag("form li select option", /#{author.login}/)
1431
- end
1432
- end
1433
1559
  end
1434
-
1435
- end
1436
- end
1437
-
1438
- describe ':as => :password' do
1439
-
1440
- before do
1441
- @new_post.stub!(:password_hash)
1442
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 50))
1443
-
1444
- semantic_form_for(@new_post) do |builder|
1445
- concat(builder.input(:password_hash, :as => :password))
1446
- end
1447
- end
1448
-
1449
- it 'should have a password class on the wrapper' do
1450
- output_buffer.should have_tag('form li.password')
1451
- end
1452
-
1453
- it 'should have a post_title_input id on the wrapper' do
1454
- output_buffer.should have_tag('form li#post_password_hash_input')
1455
- end
1456
-
1457
- it 'should generate a label for the input' do
1458
- output_buffer.should have_tag('form li label')
1459
- output_buffer.should have_tag('form li label[@for="post_password_hash"')
1460
- output_buffer.should have_tag('form li label', /Password Hash/)
1461
- end
1462
-
1463
- it 'should generate a password input' do
1464
- output_buffer.should have_tag('form li input')
1465
- output_buffer.should have_tag('form li input#post_password_hash')
1466
- output_buffer.should have_tag('form li input[@type="password"]')
1467
- output_buffer.should have_tag('form li input[@name="post[password_hash]"]')
1468
- end
1469
-
1470
- it 'should have a maxlength matching the column limit' do
1471
- should_have_maxlength_matching_column_limit(:password_hash, :password, :string)
1472
- end
1473
-
1474
- it 'should use default_text_field_size for columns longer than default_text_field_size' do
1475
- should_use_default_text_size_for_columns_longer_than_default(:password_hash, :password, :string)
1476
- end
1477
-
1478
- it 'should use the column size for columns shorter than default_text_field_size' do
1479
- should_use_the_column_size_for_columns_shorter_than_default(:password_hash, :password, :string)
1480
- end
1481
-
1482
- it 'should use default_text_field_size for methods without database columns' do
1483
- should_use_default_size_for_methods_without_columns(:password)
1484
- end
1485
-
1486
- describe "with object that does not respond to 'column_for_attribute'" do
1487
- before do
1488
- @new_post.stub!(:column_for_attribute).and_raise(NoMethodError)
1489
- end
1490
-
1491
- it "should have a maxlength of default_text_field_size" do
1492
- should_use_default_size_for_methods_without_columns(:string)
1493
- end
1494
- end
1495
-
1496
- end
1497
-
1498
- describe ':as => :text' do
1499
-
1500
- before do
1501
- @new_post.stub!(:body)
1502
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :text))
1503
-
1504
- semantic_form_for(@new_post) do |builder|
1505
- concat(builder.input(:body, :as => :text))
1506
- end
1507
- end
1508
-
1509
- it 'should have a text class on the wrapper' do
1510
- output_buffer.should have_tag('form li.text')
1511
- end
1512
-
1513
- it 'should have a post_title_input id on the wrapper' do
1514
- output_buffer.should have_tag('form li#post_body_input')
1515
- end
1516
-
1517
- it 'should generate a label for the input' do
1518
- output_buffer.should have_tag('form li label')
1519
- output_buffer.should have_tag('form li label[@for="post_body"')
1520
- output_buffer.should have_tag('form li label', /Body/)
1521
1560
  end
1522
-
1523
- it 'should generate a text input' do
1524
- output_buffer.should have_tag('form li textarea')
1525
- output_buffer.should have_tag('form li textarea#post_body')
1526
- output_buffer.should have_tag('form li textarea[@name="post[body]"]')
1527
- end
1528
-
1529
1561
  end
1530
1562
 
1531
1563
  describe ':as => :date' do
@@ -1548,7 +1580,7 @@ describe 'Formtastic' do
1548
1580
  end
1549
1581
 
1550
1582
  it 'should have a legend containing the label text inside the fieldset' do
1551
- output_buffer.should have_tag('form li.date fieldset legend', /Publish At/)
1583
+ output_buffer.should have_tag('form li.date fieldset legend', /Publish at/)
1552
1584
  end
1553
1585
 
1554
1586
  it 'should have an ordered list of three items inside the fieldset' do
@@ -1566,37 +1598,6 @@ describe 'Formtastic' do
1566
1598
  it 'should have three selects for year, month and day' do
1567
1599
  output_buffer.should have_tag('form li.date fieldset ol li select', :count => 3)
1568
1600
  end
1569
-
1570
- describe 'when :include_blank => true is set' do
1571
- before do
1572
- semantic_form_for(@new_post) do |builder|
1573
- concat(builder.input(:publish_at, :as => :date, :include_blank => true))
1574
- end
1575
- end
1576
-
1577
- it 'should have a blank select option' do
1578
- output_buffer.should have_tag("option[@value='']", "")
1579
- end
1580
- end
1581
-
1582
- describe 'when the locale changes the label text' do
1583
- before do
1584
- I18n.backend.store_translations 'en', :formtastic => {:year => 'The Year', :month => 'The Month', :day => 'The Day'}
1585
- semantic_form_for(@new_post) do |builder|
1586
- concat(builder.input(:publish_at, :as => :date))
1587
- end
1588
- end
1589
-
1590
- after do
1591
- I18n.backend.store_translations 'en', :formtastic => {:year => nil, :month => nil, :day => nil}
1592
- end
1593
-
1594
- it 'should have translated labels for year, month and day' do
1595
- output_buffer.should have_tag('form li.date fieldset ol li label', /The Year/)
1596
- output_buffer.should have_tag('form li.date fieldset ol li label', /The Month/)
1597
- output_buffer.should have_tag('form li.date fieldset ol li label', /The Day/)
1598
- end
1599
- end
1600
1601
  end
1601
1602
 
1602
1603
  describe ':as => :datetime' do
@@ -1619,7 +1620,7 @@ describe 'Formtastic' do
1619
1620
  end
1620
1621
 
1621
1622
  it 'should have a legend containing the label text inside the fieldset' do
1622
- output_buffer.should have_tag('form li.datetime fieldset legend', /Publish At/)
1623
+ output_buffer.should have_tag('form li.datetime fieldset legend', /Publish at/)
1623
1624
  end
1624
1625
 
1625
1626
  it 'should have an ordered list of five items inside the fieldset' do
@@ -1640,547 +1641,256 @@ describe 'Formtastic' do
1640
1641
  output_buffer.should have_tag('form li.datetime fieldset ol li select', :count => 5)
1641
1642
  end
1642
1643
 
1643
- it 'should generate a sanitized label for attribute' do
1644
+ it 'should generate a sanitized label and matching ids for attribute' do
1644
1645
  @bob.stub!(:publish_at)
1645
1646
  @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :datetime))
1646
1647
 
1647
- semantic_form_for(@new_post) do |builder|
1648
- builder.semantic_fields_for(@bob) do |bob_builder|
1649
- concat(bob_builder.input(:publish_at, :as => :datetime))
1650
- end
1651
- end
1652
-
1653
- 1.upto(5) do |i|
1654
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_publish_at_#{i}i']")
1655
- end
1656
- end
1657
-
1658
- describe 'when :discard_input => true is set' do
1659
- it 'should use default hidden value equals to 1 when attribute returns nil' do
1660
- semantic_form_for(@new_post) do |builder|
1661
- concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
1662
- end
1663
-
1664
- output_buffer.should have_tag("form li fieldset ol input[@type='hidden'][@value='1']")
1665
- end
1666
-
1667
- it 'should use default attribute value when it is not nil' do
1668
- @new_post.stub!(:publish_at).and_return(Date.new(2007,12,27))
1669
- semantic_form_for(@new_post) do |builder|
1670
- concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
1671
- end
1672
-
1673
- output_buffer.should have_tag("form li fieldset ol input[@type='hidden'][@value='27']")
1674
- end
1675
- end
1676
-
1677
- describe 'when :include_blank => true is set' do
1678
- before do
1679
- semantic_form_for(@new_post) do |builder|
1680
- concat(builder.input(:publish_at, :as => :datetime, :include_blank => true))
1681
- end
1682
- end
1683
-
1684
- it 'should have a blank select option' do
1685
- output_buffer.should have_tag("option[@value='']", "")
1686
- end
1687
- end
1688
-
1689
- describe 'inputs order' do
1690
- it 'should have a default' do
1691
- semantic_form_for(@new_post) do |builder|
1692
- self.should_receive(:select_year).once.ordered.and_return('')
1693
- self.should_receive(:select_month).once.ordered.and_return('')
1694
- self.should_receive(:select_day).once.ordered.and_return('')
1695
- builder.input(:publish_at, :as => :datetime)
1696
- end
1697
- end
1698
-
1699
- it 'should be specified with :order option' do
1700
- I18n.backend.store_translations 'en', :date => { :order => [:month, :year, :day] }
1701
- semantic_form_for(@new_post) do |builder|
1702
- self.should_receive(:select_month).once.ordered.and_return('')
1703
- self.should_receive(:select_year).once.ordered.and_return('')
1704
- self.should_receive(:select_day).once.ordered.and_return('')
1705
- builder.input(:publish_at, :as => :datetime)
1706
- end
1707
- end
1708
-
1709
- it 'should be changed through I18n' do
1710
- semantic_form_for(@new_post) do |builder|
1711
- self.should_receive(:select_day).once.ordered.and_return('')
1712
- self.should_receive(:select_month).once.ordered.and_return('')
1713
- self.should_receive(:select_year).once.ordered.and_return('')
1714
- builder.input(:publish_at, :as => :datetime, :order => [:day, :month, :year])
1715
- end
1716
- end
1717
- end
1718
-
1719
- describe 'when the locale changes the label text' do
1720
- before do
1721
- I18n.backend.store_translations 'en', :formtastic => {
1722
- :year => 'The Year', :month => 'The Month', :day => 'The Day',
1723
- :hour => 'The Hour', :minute => 'The Minute'
1724
- }
1725
- semantic_form_for(@new_post) do |builder|
1726
- concat(builder.input(:publish_at, :as => :datetime))
1727
- end
1728
- end
1729
-
1730
- after do
1731
- I18n.backend.store_translations 'en', :formtastic => {
1732
- :year => nil, :month => nil, :day => nil,
1733
- :hour => nil, :minute => nil
1734
- }
1735
- end
1736
-
1737
- it 'should have translated labels for year, month, day, hour and minute' do
1738
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Year/)
1739
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Month/)
1740
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Day/)
1741
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Hour/)
1742
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Minute/)
1743
- end
1744
- end
1745
- end
1746
-
1747
- describe ':as => :time' do
1748
-
1749
- before do
1750
- @new_post.stub!(:publish_at)
1751
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :time))
1752
-
1753
- semantic_form_for(@new_post) do |builder|
1754
- concat(builder.input(:publish_at, :as => :time))
1755
- end
1756
- end
1757
-
1758
- it 'should have a time class on the wrapper li' do
1759
- output_buffer.should have_tag('form li.time')
1760
- end
1761
-
1762
- it 'should have a fieldset inside the li wrapper' do
1763
- output_buffer.should have_tag('form li.time fieldset')
1764
- end
1765
-
1766
- it 'should have a legend containing the label text inside the fieldset' do
1767
- output_buffer.should have_tag('form li.time fieldset legend', /Publish At/)
1768
- end
1769
-
1770
- it 'should have an ordered list of two items inside the fieldset' do
1771
- output_buffer.should have_tag('form li.time fieldset ol')
1772
- output_buffer.should have_tag('form li.time fieldset ol li', :count => 2)
1773
- end
1774
-
1775
- it 'should have five labels for hour and minute' do
1776
- output_buffer.should have_tag('form li.time fieldset ol li label', :count => 2)
1777
- output_buffer.should have_tag('form li.time fieldset ol li label', /hour/i)
1778
- output_buffer.should have_tag('form li.time fieldset ol li label', /minute/i)
1779
- end
1780
-
1781
- it 'should have five selects for hour and minute' do
1782
- output_buffer.should have_tag('form li.time fieldset ol li select', :count => 2)
1783
- end
1784
-
1785
- describe 'when :include_blank => true is set' do
1786
- before do
1787
- semantic_form_for(@new_post) do |builder|
1788
- concat(builder.input(:publish_at, :as => :time, :include_blank => true))
1789
- end
1790
- end
1791
-
1792
- it 'should have a blank select option' do
1793
- output_buffer.should have_tag("option[@value='']", "")
1794
- end
1795
- end
1796
-
1797
- describe 'when the locale changes the label text' do
1798
- before do
1799
- I18n.backend.store_translations 'en', :formtastic => {:hour => 'The Hour', :minute => 'The Minute'}
1800
- semantic_form_for(@new_post) do |builder|
1801
- concat(builder.input(:publish_at, :as => :time))
1802
- end
1803
- end
1804
-
1805
- after do
1806
- I18n.backend.store_translations 'en', :formtastic => {:hour => nil, :minute => nil}
1807
- end
1808
-
1809
- it 'should have translated labels for year, month, day, hour and minute' do
1810
- output_buffer.should have_tag('form li.time fieldset ol li label', /The Hour/)
1811
- output_buffer.should have_tag('form li.time fieldset ol li label', /The Minute/)
1812
- end
1813
- end
1814
- end
1815
-
1816
- describe ':as => :boolean' do
1817
-
1818
- before do
1819
- @new_post.stub!(:allow_comments)
1820
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1821
-
1822
- semantic_form_for(@new_post) do |builder|
1823
- concat(builder.input(:allow_comments, :as => :boolean))
1824
- end
1825
- end
1826
-
1827
- it 'should have a boolean class on the wrapper' do
1828
- output_buffer.should have_tag('form li.boolean')
1829
- end
1830
-
1831
- it 'should have a post_allow_comments_input id on the wrapper' do
1832
- output_buffer.should have_tag('form li#post_allow_comments_input')
1833
- end
1834
-
1835
- it 'should generate a label containing the input' do
1836
- output_buffer.should have_tag('form li label')
1837
- output_buffer.should have_tag('form li label[@for="post_allow_comments"')
1838
- output_buffer.should have_tag('form li label', /Allow Comments/)
1839
- output_buffer.should have_tag('form li label input[@type="checkbox"]')
1840
- end
1841
-
1842
- it 'should generate a checkbox input' do
1843
- output_buffer.should have_tag('form li label input')
1844
- output_buffer.should have_tag('form li label input#post_allow_comments')
1845
- output_buffer.should have_tag('form li label input[@type="checkbox"]')
1846
- output_buffer.should have_tag('form li label input[@name="post[allow_comments]"]')
1847
- end
1848
-
1849
- end
1850
-
1851
- describe ':as => :boolean_radio' do
1852
-
1853
- before do
1854
- @new_post.stub!(:allow_comments)
1855
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1856
-
1857
- semantic_form_for(@new_post) do |builder|
1858
- concat(builder.input(:allow_comments, :as => :boolean_radio))
1859
- end
1860
- end
1861
-
1862
- it 'should have a boolean_radio class on the wrapper' do
1863
- output_buffer.should have_tag('form li.boolean_radio')
1864
- end
1865
-
1866
- it 'should have a post_allow_comments_input id on the wrapper' do
1867
- output_buffer.should have_tag('form li#post_allow_comments_input')
1868
- end
1869
-
1870
- it 'should generate a fieldset containing a legend' do
1871
- output_buffer.should have_tag('form li fieldset legend', /Allow Comments/)
1872
- end
1873
-
1874
- it 'should generate a fieldset containing an ordered list of two items with true and false classes' do
1875
- output_buffer.should have_tag('form li fieldset ol li.true', :count => 1)
1876
- output_buffer.should have_tag('form li fieldset ol li.false', :count => 1)
1877
- end
1878
-
1879
- it 'should generate a fieldset containing two labels' do
1880
- output_buffer.should have_tag('form li fieldset ol li label', :count => 2)
1881
- output_buffer.should have_tag('form li fieldset ol li label', /Yes$/)
1882
- output_buffer.should have_tag('form li fieldset ol li label', /No$/)
1883
- end
1884
-
1885
- it 'should generate a fieldset containing two radio inputs' do
1886
- output_buffer.should have_tag('form li fieldset ol li label input[@type="radio"]', :count => 2)
1887
- output_buffer.should have_tag('form li fieldset ol li label input[@value="true"]')
1888
- output_buffer.should have_tag('form li fieldset ol li label input[@value="false"]')
1889
- end
1890
-
1891
- describe 'when the locale sets the label text' do
1892
- before do
1893
- I18n.backend.store_translations 'en', :formtastic => {:yes => 'Absolutely!', :no => 'Never!'}
1894
- semantic_form_for(@new_post) do |builder|
1895
- concat(builder.input(:allow_comments, :as => :boolean_radio))
1896
- end
1897
- end
1898
-
1899
- after do
1900
- I18n.backend.store_translations 'en', :formtastic => {:yes => nil, :no => nil}
1901
- end
1902
-
1903
- it 'should allow translation of the labels' do
1904
- output_buffer.should have_tag('form li fieldset ol li label', /Absolutely\!$/)
1905
- output_buffer.should have_tag('form li fieldset ol li label', /Never\!$/)
1906
- end
1907
- end
1908
-
1909
-
1910
- describe 'when the value is nil' do
1911
- before do
1912
- @new_post.stub!(:allow_comments).and_return(nil)
1913
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1914
-
1915
- semantic_form_for(@new_post) do |builder|
1916
- concat(builder.input(:allow_comments, :as => :boolean_radio))
1648
+ semantic_form_for(@new_post) do |builder|
1649
+ builder.semantic_fields_for(@bob, :index => 10) do |bob_builder|
1650
+ concat(bob_builder.input(:publish_at, :as => :datetime))
1917
1651
  end
1918
1652
  end
1919
1653
 
1920
- it 'should not mark either input as checked' do
1921
- output_buffer.should_not have_tag('form li fieldset ol li label input[@checked="checked"]')
1654
+ 1.upto(5) do |i|
1655
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_10_publish_at_#{i}i']")
1656
+ output_buffer.should have_tag("form li fieldset ol li #post_author_10_publish_at_#{i}i")
1922
1657
  end
1923
-
1924
1658
  end
1925
1659
 
1926
- describe 'when the value is true' do
1927
- before do
1928
- @new_post.stub!(:allow_comments).and_return(true)
1929
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1660
+ describe 'when :discard_input => true is set' do
1661
+ it 'should use default hidden value equals to 1 when attribute returns nil' do
1930
1662
  semantic_form_for(@new_post) do |builder|
1931
- concat(builder.input(:allow_comments, :as => :boolean_radio))
1663
+ concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
1932
1664
  end
1665
+
1666
+ output_buffer.should have_tag("form li fieldset ol input[@type='hidden'][@value='1']")
1933
1667
  end
1934
- it 'should mark the true input as checked' do
1935
- output_buffer.should have_tag('form li fieldset ol li label input[@value="true"][@checked="checked"]', :count => 1)
1936
- end
1937
- it 'should not mark the false input as checked' do
1938
- output_buffer.should_not have_tag('form li fieldset ol li label input[@value="false"][@checked="checked"]')
1939
- end
1940
- end
1941
1668
 
1942
- describe 'when the value is false' do
1943
- before do
1944
- @new_post.stub!(:allow_comments).and_return(false)
1945
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1669
+ it 'should use default attribute value when it is not nil' do
1670
+ @new_post.stub!(:publish_at).and_return(Date.new(2007,12,27))
1946
1671
  semantic_form_for(@new_post) do |builder|
1947
- concat(builder.input(:allow_comments, :as => :boolean_radio))
1672
+ concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
1948
1673
  end
1949
- end
1950
- it 'should not mark the true input as checked' do
1951
- output_buffer.should_not have_tag('form li fieldset ol li.true label input[@value="true"][@checked="checked"]', :count => 1)
1952
- end
1953
- it 'should mark the false input as checked' do
1954
- output_buffer.should have_tag('form li fieldset ol li.false label input[@value="false"][@checked="checked"]')
1674
+
1675
+ output_buffer.should have_tag("form li fieldset ol input[@type='hidden'][@value='27']")
1955
1676
  end
1956
1677
  end
1957
1678
 
1958
- describe 'when :true and :false options are provided' do
1679
+ describe 'when :include_blank => true is set' do
1959
1680
  before do
1960
- @new_post.stub!(:allow_comments)
1961
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1962
1681
  semantic_form_for(@new_post) do |builder|
1963
- concat(builder.input(:allow_comments, :as => :boolean_radio, :true => "Absolutely", :false => "No Way"))
1682
+ concat(builder.input(:publish_at, :as => :datetime, :include_blank => true))
1964
1683
  end
1965
1684
  end
1966
- it 'should pass them down to the input labels' do
1967
- output_buffer.should have_tag('form li fieldset ol li.true label', /Absolutely$/)
1968
- output_buffer.should have_tag('form li fieldset ol li.false label', /No Way$/)
1969
- end
1970
- end
1971
- end
1972
-
1973
- describe ':as => :boolean_select' do
1974
-
1975
- before do
1976
- @new_post.stub!(:allow_comments)
1977
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1978
1685
 
1979
- semantic_form_for(@new_post) do |builder|
1980
- concat(builder.input(:allow_comments, :as => :boolean_select))
1686
+ it 'should have a blank select option' do
1687
+ output_buffer.should have_tag("option[@value='']", "")
1981
1688
  end
1982
1689
  end
1983
1690
 
1984
- it 'should have a boolean_select class on the wrapper' do
1985
- output_buffer.should have_tag('form li.boolean_select')
1986
- end
1987
-
1988
- it 'should have a post_allow_comments_input id on the wrapper' do
1989
- output_buffer.should have_tag('form li#post_allow_comments_input')
1990
- end
1991
-
1992
- it 'should generate a label containing the input' do
1993
- output_buffer.should have_tag('form li label')
1994
- output_buffer.should have_tag('form li label[@for="post_allow_comments"')
1995
- output_buffer.should have_tag('form li label', /Allow Comments/)
1996
- end
1997
-
1998
- it 'should generate a select box with two options' do
1999
- output_buffer.should have_tag('form li select')
2000
- output_buffer.should have_tag('form li select#post_allow_comments')
2001
- output_buffer.should have_tag('form li select[@name="post[allow_comments]"]')
2002
- output_buffer.should have_tag('form li select#post_allow_comments option', :count => 2)
2003
- end
2004
-
2005
- describe 'when the locale sets the label text' do
2006
- before do
2007
- I18n.backend.store_translations 'en', :formtastic => {:yes => 'Absolutely!', :no => 'Never!'}
1691
+ describe 'inputs order' do
1692
+ it 'should have a default' do
2008
1693
  semantic_form_for(@new_post) do |builder|
2009
- concat(builder.input(:allow_comments, :as => :boolean_select))
1694
+ self.should_receive(:select_year).once.ordered.and_return('')
1695
+ self.should_receive(:select_month).once.ordered.and_return('')
1696
+ self.should_receive(:select_day).once.ordered.and_return('')
1697
+ builder.input(:publish_at, :as => :datetime)
2010
1698
  end
2011
1699
  end
2012
1700
 
2013
- after do
2014
- I18n.backend.store_translations 'en', :formtastic => {:yes => nil, :no => nil}
2015
- end
2016
-
2017
- it 'should allow translation of the labels' do
2018
- output_buffer.should have_tag('form li select')
2019
- output_buffer.should have_tag('form li select#post_allow_comments')
2020
- output_buffer.should have_tag('form li select#post_allow_comments option[@value="true"]', /Absolutely\!/)
2021
- output_buffer.should have_tag('form li select#post_allow_comments option[@value="false"]', /Never\!/)
2022
- end
2023
- end
2024
-
2025
- describe 'when the :true and :false options are supplied' do
2026
-
2027
- before do
1701
+ it 'should be specified with :order option' do
1702
+ I18n.backend.store_translations 'en', :date => { :order => [:month, :year, :day] }
2028
1703
  semantic_form_for(@new_post) do |builder|
2029
- concat(builder.input(:allow_comments, :as => :boolean_select, :true => "Yes Please!", :false => "No Thanks!"))
1704
+ self.should_receive(:select_month).once.ordered.and_return('')
1705
+ self.should_receive(:select_year).once.ordered.and_return('')
1706
+ self.should_receive(:select_day).once.ordered.and_return('')
1707
+ builder.input(:publish_at, :as => :datetime)
2030
1708
  end
2031
1709
  end
2032
1710
 
2033
- it 'should use the values as the text for the option tags' do
2034
- output_buffer.should have_tag('form li select')
2035
- output_buffer.should have_tag('form li select#post_allow_comments')
2036
- output_buffer.should have_tag('form li select#post_allow_comments option[@value="true"]', /Yes Please\!/)
2037
- output_buffer.should have_tag('form li select#post_allow_comments option[@value="false"]', /No Thanks\!/)
1711
+ it 'should be changed through I18n' do
1712
+ semantic_form_for(@new_post) do |builder|
1713
+ self.should_receive(:select_day).once.ordered.and_return('')
1714
+ self.should_receive(:select_month).once.ordered.and_return('')
1715
+ self.should_receive(:select_year).once.ordered.and_return('')
1716
+ builder.input(:publish_at, :as => :datetime, :order => [:day, :month, :year])
1717
+ end
2038
1718
  end
2039
-
2040
1719
  end
2041
1720
 
2042
- describe 'when the :true and :false options are not supplied' do
2043
-
1721
+ describe 'when the locale changes the label text' do
2044
1722
  before do
1723
+ I18n.backend.store_translations 'en', :datetime => {:prompts => {
1724
+ :year => 'The Year', :month => 'The Month', :day => 'The Day',
1725
+ :hour => 'The Hour', :minute => 'The Minute'
1726
+ }}
2045
1727
  semantic_form_for(@new_post) do |builder|
2046
- concat(builder.input(:allow_comments, :as => :boolean_select))
1728
+ concat(builder.input(:publish_at, :as => :datetime))
2047
1729
  end
2048
1730
  end
2049
1731
 
2050
- it 'should use the default values' do
2051
- output_buffer.should have_tag('form li select')
2052
- output_buffer.should have_tag('form li select#post_allow_comments')
2053
- output_buffer.should have_tag('form li select#post_allow_comments option[@value="true"]', /Yes/)
2054
- output_buffer.should have_tag('form li select#post_allow_comments option[@value="false"]', /No/)
1732
+ after do
1733
+ I18n.backend.store_translations 'en', :formtastic => {
1734
+ :year => nil, :month => nil, :day => nil,
1735
+ :hour => nil, :minute => nil
1736
+ }
2055
1737
  end
2056
1738
 
1739
+ it 'should have translated labels for year, month, day, hour and minute' do
1740
+ output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Year/)
1741
+ output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Month/)
1742
+ output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Day/)
1743
+ output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Hour/)
1744
+ output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Minute/)
1745
+ end
2057
1746
  end
2058
1747
 
2059
- describe 'when :include_blank => true, :prompt => "choose something" is set' do
2060
- before do
2061
- semantic_form_for(@new_post) do |builder|
2062
- concat(builder.input(:allow_comments, :as => :boolean_select, :include_blank => true, :prompt => "choose something"))
2063
- end
2064
- end
1748
+ it 'should have fieldset, legend, label and selects even if object is not given' do
1749
+ output_buffer.replace ''
2065
1750
 
2066
- it 'should have a blank select option' do
2067
- output_buffer.should have_tag("form li select option[@value='']", / /)
2068
- end
2069
- it 'should have a select with prompt' do
2070
- output_buffer.should have_tag("form li select option[@value='']", /choose something/)
1751
+ semantic_form_for(:project, :url => 'http://test.host') do |@builder|
1752
+ concat(@builder.input(:publish_at, :as => :datetime))
2071
1753
  end
2072
- end
2073
1754
 
1755
+ output_buffer.should have_tag('form li.datetime fieldset legend', /Publish at/)
1756
+ output_buffer.should have_tag('form li.datetime fieldset ol li label', :count => 5)
1757
+ output_buffer.should have_tag('form li.datetime fieldset ol li select', :count => 5)
1758
+ end
2074
1759
  end
2075
1760
 
2076
- describe ':as => :numeric' do
2077
-
1761
+ describe ':as => :time' do
2078
1762
  before do
2079
- @new_post.stub!(:comments_count)
2080
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 50))
1763
+ @new_post.stub!(:publish_at)
1764
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :time))
2081
1765
 
2082
1766
  semantic_form_for(@new_post) do |builder|
2083
- concat(builder.input(:comments_count, :as => :numeric))
1767
+ concat(builder.input(:publish_at, :as => :time))
2084
1768
  end
2085
- output_buffer.should have_tag('form li.numeric')
2086
- end
2087
-
2088
- it 'should have a numeric class on the wrapper' do
2089
- output_buffer.should have_tag("form li.numeric")
2090
1769
  end
2091
1770
 
2092
- it 'should have a comments_count_input id on the wrapper' do
2093
- output_buffer.should have_tag('form li#post_comments_count_input')
1771
+ it 'should have a time class on the wrapper li' do
1772
+ output_buffer.should have_tag('form li.time')
2094
1773
  end
2095
1774
 
2096
- it 'should generate a label for the input' do
2097
- output_buffer.should have_tag('form li label')
2098
- output_buffer.should have_tag('form li label[@for="post_comments_count"')
2099
- output_buffer.should have_tag('form li label', /Comments Count/)
1775
+ it 'should have a fieldset inside the li wrapper' do
1776
+ output_buffer.should have_tag('form li.time fieldset')
2100
1777
  end
2101
1778
 
2102
- it 'should generate a text input' do
2103
- output_buffer.should have_tag('form li input')
2104
- output_buffer.should have_tag('form li input#post_comments_count')
2105
- output_buffer.should have_tag('form li input[@type="text"]')
2106
- output_buffer.should have_tag('form li input[@name="post[comments_count]"]')
1779
+ it 'should have a legend containing the label text inside the fieldset' do
1780
+ output_buffer.should have_tag('form li.time fieldset legend', /Publish at/)
2107
1781
  end
2108
1782
 
2109
- it 'should have a maxlength matching the column limit' do
2110
- should_have_maxlength_matching_column_limit(:comments_count, :numeric, :integer)
1783
+ it 'should have an ordered list of two items inside the fieldset' do
1784
+ output_buffer.should have_tag('form li.time fieldset ol')
1785
+ output_buffer.should have_tag('form li.time fieldset ol li', :count => 2)
2111
1786
  end
2112
1787
 
2113
- it 'should use default_text_field_size for columns longer than default_text_field_size' do
2114
- should_use_default_text_size_for_columns_longer_than_default(:comments_count, :numeric, :integer)
1788
+ it 'should have five labels for hour and minute' do
1789
+ output_buffer.should have_tag('form li.time fieldset ol li label', :count => 2)
1790
+ output_buffer.should have_tag('form li.time fieldset ol li label', /hour/i)
1791
+ output_buffer.should have_tag('form li.time fieldset ol li label', /minute/i)
2115
1792
  end
2116
1793
 
2117
- it 'should use the column size for columns shorter than default_text_field_size' do
2118
- should_use_the_column_size_for_columns_shorter_than_default(:comments_count, :numeric, :integer)
1794
+ it 'should have five selects for hour and minute' do
1795
+ output_buffer.should have_tag('form li.time fieldset ol li select', :count => 2)
2119
1796
  end
1797
+ end
2120
1798
 
2121
- it 'should use default_text_field_size for methods without database columns' do
2122
- should_use_default_size_for_methods_without_columns(:numeric)
2123
- end
1799
+ [:boolean_select, :boolean_radio].each do |type|
1800
+ describe ":as => #{type.inspect}" do
1801
+ it 'should show a deprecation warning' do
1802
+ @new_post.stub!(:allow_comments)
1803
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
2124
1804
 
2125
- describe "with object that does not respond to 'column_for_attribute'" do
2126
- before do
2127
- @new_post.stub!(:column_for_attribute).and_raise(NoMethodError)
2128
- end
1805
+ ::ActiveSupport::Deprecation.should_receive(:warn).with(/select|radio/, anything())
2129
1806
 
2130
- it "should have a maxlength of default_text_field_size" do
2131
- should_use_default_size_for_methods_without_columns(:string)
1807
+ semantic_form_for(@new_post) do |builder|
1808
+ concat(builder.input(:allow_comments, :as => type))
1809
+ end
2132
1810
  end
2133
1811
  end
2134
-
2135
1812
  end
2136
1813
 
2137
- describe ':as => :file' do
1814
+ describe ':as => :boolean' do
1815
+
2138
1816
  before do
2139
- @new_post.stub!(:some_file)
2140
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 50))
1817
+ @new_post.stub!(:allow_comments)
1818
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
2141
1819
 
2142
1820
  semantic_form_for(@new_post) do |builder|
2143
- concat(builder.input(:some_file, :as => :file))
1821
+ concat(builder.input(:allow_comments, :as => :boolean))
2144
1822
  end
2145
1823
  end
2146
1824
 
2147
- it 'should have a file class on the wrapper' do
2148
- output_buffer.should have_tag('form li.file')
1825
+ it 'should have a boolean class on the wrapper' do
1826
+ output_buffer.should have_tag('form li.boolean')
2149
1827
  end
2150
1828
 
2151
- it 'should have a post_some_file_input id on the wrapper' do
2152
- output_buffer.should have_tag('form li#post_some_file_input')
1829
+ it 'should have a post_allow_comments_input id on the wrapper' do
1830
+ output_buffer.should have_tag('form li#post_allow_comments_input')
2153
1831
  end
2154
1832
 
2155
- it 'should generate a label for the input' do
1833
+ it 'should generate a label containing the input' do
2156
1834
  output_buffer.should have_tag('form li label')
2157
- output_buffer.should have_tag('form li label[@for="post_some_file"')
2158
- output_buffer.should have_tag('form li label', /Some File/)
1835
+ output_buffer.should have_tag('form li label[@for="post_allow_comments"')
1836
+ output_buffer.should have_tag('form li label', /Allow comments/)
1837
+ output_buffer.should have_tag('form li label input[@type="checkbox"]')
1838
+ end
1839
+
1840
+ it 'should generate a checkbox input' do
1841
+ output_buffer.should have_tag('form li label input')
1842
+ output_buffer.should have_tag('form li label input#post_allow_comments')
1843
+ output_buffer.should have_tag('form li label input[@type="checkbox"]')
1844
+ output_buffer.should have_tag('form li label input[@name="post[allow_comments]"]')
1845
+ output_buffer.should have_tag('form li label input[@type="checkbox"][@value="1"]')
2159
1846
  end
2160
1847
 
2161
- it 'should generate a file input' do
2162
- output_buffer.should have_tag('form li input')
2163
- output_buffer.should have_tag('form li input#post_some_file')
2164
- output_buffer.should have_tag('form li input[@type="file"]')
2165
- output_buffer.should have_tag('form li input[@name="post[some_file]"]')
1848
+ it 'should allow checked and unchecked values to be sent' do
1849
+ semantic_form_for(@new_post) do |builder|
1850
+ concat(builder.input(:allow_comments, :as => :boolean, :checked_value => 'checked', :unchecked_value => 'unchecked'))
1851
+ end
1852
+
1853
+ output_buffer.should have_tag('form li label input[@type="checkbox"][@value="checked"]')
1854
+ output_buffer.should have_tag('form li label input[@type="hidden"][@value="unchecked"]')
2166
1855
  end
2167
- end
2168
1856
 
1857
+ it 'should generate a label and a checkbox even if no object is given' do
1858
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
1859
+ concat(builder.input(:allow_comments, :as => :boolean))
1860
+ end
1861
+
1862
+ output_buffer.should have_tag('form li label[@for="project_allow_comments"')
1863
+ output_buffer.should have_tag('form li label', /Allow comments/)
1864
+ output_buffer.should have_tag('form li label input[@type="checkbox"]')
1865
+
1866
+ output_buffer.should have_tag('form li label input#project_allow_comments')
1867
+ output_buffer.should have_tag('form li label input[@type="checkbox"]')
1868
+ output_buffer.should have_tag('form li label input[@name="project[allow_comments]"]')
1869
+ end
1870
+
1871
+ end
2169
1872
  end
2170
1873
 
1874
+
2171
1875
  describe '#inputs' do
2172
1876
 
2173
1877
  describe 'with a block' do
2174
1878
 
2175
1879
  describe 'when no options are provided' do
2176
1880
  before do
1881
+ output_buffer.replace 'before_builder' # clear the output buffer and sets before_builder
2177
1882
  semantic_form_for(@new_post) do |builder|
2178
- builder.inputs do
1883
+ @inputs_output = builder.inputs do
2179
1884
  concat('hello')
2180
1885
  end
2181
1886
  end
2182
1887
  end
2183
1888
 
1889
+ it 'should output just the content wrapped in inputs, not the whole template' do
1890
+ output_buffer.should =~ /before_builder/
1891
+ @inputs_output.should_not =~ /before_builder/
1892
+ end
1893
+
2184
1894
  it 'should render a fieldset inside the form, with a class of "inputs"' do
2185
1895
  output_buffer.should have_tag("form fieldset.inputs")
2186
1896
  end
@@ -2196,6 +1906,16 @@ describe 'Formtastic' do
2196
1906
  it 'should not render a legend inside the fieldset' do
2197
1907
  output_buffer.should_not have_tag("form fieldset.inputs legend")
2198
1908
  end
1909
+
1910
+ it 'should render a fieldset even if no object is given' do
1911
+ semantic_form_for(:project, :url => 'http://test.host/') do |builder|
1912
+ @inputs_output = builder.inputs do
1913
+ concat('bye')
1914
+ end
1915
+ end
1916
+
1917
+ output_buffer.should have_tag("form fieldset.inputs ol", /bye/)
1918
+ end
2199
1919
  end
2200
1920
 
2201
1921
  describe 'when a :for option is provided' do
@@ -2204,7 +1924,7 @@ describe 'Formtastic' do
2204
1924
 
2205
1925
  semantic_form_for(@new_post) do |builder|
2206
1926
  builder.inputs :for => [:author, @bob] do |bob_builder|
2207
- concat(bob_builder.input :login)
1927
+ concat(bob_builder.input(:login))
2208
1928
  end
2209
1929
  end
2210
1930
 
@@ -2222,6 +1942,39 @@ describe 'Formtastic' do
2222
1942
  'but the block does not accept any argument.')
2223
1943
  end
2224
1944
  end
1945
+
1946
+ it 'should pass options down to semantic_fields_for' do
1947
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
1948
+
1949
+ semantic_form_for(@new_post) do |builder|
1950
+ builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
1951
+ concat(bob_builder.input(:login))
1952
+ end
1953
+ end
1954
+
1955
+ output_buffer.should have_tag('form fieldset ol li #post_author_10_login')
1956
+ end
1957
+
1958
+ it 'should not add builder as a fieldset attribute tag' do
1959
+ semantic_form_for(@new_post) do |builder|
1960
+ builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
1961
+ concat('input')
1962
+ end
1963
+ end
1964
+
1965
+ output_buffer.should_not have_tag('fieldset[@builder="Formtastic::SemanticFormHelper"]')
1966
+ end
1967
+
1968
+ it 'should send parent_builder as an option to allow child index interpolation' do
1969
+ semantic_form_for(@new_post) do |builder|
1970
+ builder.should_receive(:instance_variable_get).with('@nested_child_index').and_return(0)
1971
+ builder.inputs :for => [:author, @bob], :name => 'Author #%i' do |bob_builder|
1972
+ concat('input')
1973
+ end
1974
+ end
1975
+
1976
+ output_buffer.should have_tag('fieldset legend', 'Author #1')
1977
+ end
2225
1978
  end
2226
1979
 
2227
1980
  describe 'when a :name option is provided' do
@@ -2261,8 +2014,9 @@ describe 'Formtastic' do
2261
2014
  describe 'without a block' do
2262
2015
 
2263
2016
  before do
2264
- Post.stub!(:reflections).and_return({:author => mock('reflection')})
2265
- Post.stub!(:content_columns).and_return([mock('column', :name => 'title'), mock('column', :name => 'body')])
2017
+ Post.stub!(:reflections).and_return({:author => mock('reflection', :macro => :belongs_to),
2018
+ :comments => mock('reflection', :macro => :has_many) })
2019
+ Post.stub!(:content_columns).and_return([mock('column', :name => 'title'), mock('column', :name => 'body'), mock('column', :name => 'created_at')])
2266
2020
  Author.stub!(:find).and_return([@fred, @bob])
2267
2021
 
2268
2022
  @new_post.stub!(:title)
@@ -2271,6 +2025,7 @@ describe 'Formtastic' do
2271
2025
 
2272
2026
  @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 255))
2273
2027
  @new_post.stub!(:column_for_attribute).with(:body).and_return(mock('column', :type => :text))
2028
+ @new_post.stub!(:column_for_attribute).with(:created_at).and_return(mock('column', :type => :datetime))
2274
2029
  @new_post.stub!(:column_for_attribute).with(:author).and_return(nil)
2275
2030
  end
2276
2031
 
@@ -2297,8 +2052,10 @@ describe 'Formtastic' do
2297
2052
  output_buffer.should have_tag('form > fieldset.inputs > ol')
2298
2053
  end
2299
2054
 
2300
- it 'should render a list item in the ol for each column returned by Post.column_names' do
2301
- output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => (Post.content_columns.size + Post.reflections.size))
2055
+ it 'should render a list item in the ol for each column and reflection' do
2056
+ # Remove the :has_many macro and :created_at column
2057
+ count = Post.content_columns.size + Post.reflections.size - 2
2058
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => count)
2302
2059
  end
2303
2060
 
2304
2061
  it 'should render a string list item for title' do
@@ -2310,34 +2067,61 @@ describe 'Formtastic' do
2310
2067
  end
2311
2068
 
2312
2069
  it 'should render a select list item for author_id' do
2313
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.select')
2070
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.select', :count => 1)
2071
+ end
2072
+
2073
+ it 'should not render timestamps inputs by default' do
2074
+ output_buffer.should_not have_tag('form > fieldset.inputs > ol > li.datetime')
2314
2075
  end
2315
2076
  end
2316
2077
 
2317
2078
  describe 'with column names as args' do
2318
- before do
2319
- semantic_form_for(@new_post) do |builder|
2320
- concat(builder.inputs(:title, :body))
2079
+ describe 'and an object is given' do
2080
+ it 'should render a form with a fieldset containing two list items' do
2081
+ semantic_form_for(@new_post) do |builder|
2082
+ concat(builder.inputs(:title, :body))
2083
+ end
2084
+
2085
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 2)
2086
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
2087
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
2321
2088
  end
2322
2089
  end
2323
2090
 
2324
- it 'should render a form with a fieldset containing two list items' do
2325
- output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 2)
2326
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
2327
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
2091
+ describe 'and no object is given' do
2092
+ it 'should render a form with a fieldset containing two list items' do
2093
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
2094
+ concat(builder.inputs(:title, :body))
2095
+ end
2096
+
2097
+ output_buffer.should have_tag('form > fieldset.inputs > ol > li.string', :count => 2)
2098
+ end
2328
2099
  end
2329
2100
  end
2330
2101
 
2331
2102
  describe 'when a :for option is provided' do
2332
- it 'should render nested inputs' do
2333
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
2103
+ describe 'and an object is given' do
2104
+ it 'should render nested inputs' do
2105
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
2334
2106
 
2335
- semantic_form_for(@new_post) do |builder|
2336
- concat(builder.inputs :login, :for => @bob)
2107
+ semantic_form_for(@new_post) do |builder|
2108
+ concat(builder.inputs(:login, :for => @bob))
2109
+ end
2110
+
2111
+ output_buffer.should have_tag("form fieldset.inputs #post_author_login")
2112
+ output_buffer.should_not have_tag("form fieldset.inputs #author_login")
2337
2113
  end
2114
+ end
2338
2115
 
2339
- output_buffer.should have_tag("form fieldset.inputs #post_author_login")
2340
- output_buffer.should_not have_tag("form fieldset.inputs #author_login")
2116
+ describe 'and no object is given' do
2117
+ it 'should render nested inputs' do
2118
+ semantic_form_for(:project, :url => 'http://test.host/') do |builder|
2119
+ concat(builder.inputs(:login, :for => @bob))
2120
+ end
2121
+
2122
+ output_buffer.should have_tag("form fieldset.inputs #project_author_login")
2123
+ output_buffer.should_not have_tag("form fieldset.inputs #project_login")
2124
+ end
2341
2125
  end
2342
2126
  end
2343
2127
 
@@ -2376,15 +2160,19 @@ describe 'Formtastic' do
2376
2160
  end
2377
2161
  end
2378
2162
  end
2163
+
2379
2164
  it 'should render a fieldset inside the form, with a class of "inputs"' do
2380
2165
  output_buffer.should have_tag("form fieldset.buttons")
2381
2166
  end
2167
+
2382
2168
  it 'should render an ol inside the fieldset' do
2383
2169
  output_buffer.should have_tag("form fieldset.buttons ol")
2384
2170
  end
2171
+
2385
2172
  it 'should render the contents of the block inside the ol' do
2386
2173
  output_buffer.should have_tag("form fieldset.buttons ol", /hello/)
2387
2174
  end
2175
+
2388
2176
  it 'should not render a legend inside the fieldset' do
2389
2177
  output_buffer.should_not have_tag("form fieldset.buttons legend")
2390
2178
  end
@@ -2580,6 +2368,36 @@ describe 'Formtastic' do
2580
2368
  output_buffer.should have_tag('li.commit input[@value="Make Post"]')
2581
2369
  end
2582
2370
  end
2371
+
2372
+ end
2373
+
2374
+ describe 'when used without object' do
2375
+
2376
+ it 'should render an input with a value attribute of "Submit"' do
2377
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
2378
+ concat(builder.commit_button)
2379
+ end
2380
+
2381
+ output_buffer.should have_tag('li.commit input[@value="Submit Project"]')
2382
+ end
2383
+
2384
+ describe 'when the locale sets the label text' do
2385
+ before do
2386
+ I18n.backend.store_translations 'en', :formtastic => { :submit => 'Send' }
2387
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
2388
+ concat(builder.commit_button)
2389
+ end
2390
+ end
2391
+
2392
+ after do
2393
+ I18n.backend.store_translations 'en', :formtastic => {:submit => nil}
2394
+ end
2395
+
2396
+ it 'should allow translation of the labels' do
2397
+ output_buffer.should have_tag('li.commit input[@value="Send Project"]')
2398
+ end
2399
+ end
2400
+
2583
2401
  end
2584
2402
 
2585
2403
  end