formtastic 1.0.1 → 1.1.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/README.textile +2 -2
  2. data/Rakefile +33 -8
  3. data/generators/formtastic/templates/formtastic.css +3 -18
  4. data/init.rb +5 -0
  5. data/lib/formtastic.rb +180 -82
  6. data/lib/formtastic/i18n.rb +8 -9
  7. data/lib/formtastic/layout_helper.rb +0 -1
  8. data/lib/formtastic/railtie.rb +12 -0
  9. data/lib/formtastic/util.rb +7 -0
  10. data/lib/generators/formtastic/form/form_generator.rb +86 -0
  11. data/lib/generators/formtastic/install/install_generator.rb +24 -0
  12. data/rails/init.rb +1 -6
  13. data/spec/buttons_spec.rb +25 -8
  14. data/spec/commit_button_spec.rb +67 -29
  15. data/spec/custom_builder_spec.rb +40 -4
  16. data/spec/defaults_spec.rb +1 -1
  17. data/spec/error_proc_spec.rb +1 -1
  18. data/spec/errors_spec.rb +3 -2
  19. data/spec/form_helper_spec.rb +33 -17
  20. data/spec/helpers/layout_helper_spec.rb +21 -0
  21. data/spec/i18n_spec.rb +13 -9
  22. data/spec/include_blank_spec.rb +9 -5
  23. data/spec/input_spec.rb +188 -48
  24. data/spec/inputs/boolean_input_spec.rb +14 -7
  25. data/spec/inputs/check_boxes_input_spec.rb +150 -20
  26. data/spec/inputs/country_input_spec.rb +9 -5
  27. data/spec/inputs/date_input_spec.rb +21 -9
  28. data/spec/inputs/datetime_input_spec.rb +33 -14
  29. data/spec/inputs/file_input_spec.rb +4 -3
  30. data/spec/inputs/hidden_input_spec.rb +11 -4
  31. data/spec/inputs/numeric_input_spec.rb +3 -3
  32. data/spec/inputs/password_input_spec.rb +3 -3
  33. data/spec/inputs/radio_input_spec.rb +29 -10
  34. data/spec/inputs/select_input_spec.rb +66 -26
  35. data/spec/inputs/string_input_spec.rb +5 -4
  36. data/spec/inputs/text_input_spec.rb +4 -3
  37. data/spec/inputs/time_input_spec.rb +26 -10
  38. data/spec/inputs/time_zone_input_spec.rb +11 -5
  39. data/spec/inputs_spec.rb +103 -39
  40. data/spec/label_spec.rb +5 -3
  41. data/spec/semantic_errors_spec.rb +7 -7
  42. data/spec/semantic_fields_for_spec.rb +5 -4
  43. data/spec/spec_helper.rb +86 -38
  44. data/spec/{custom_macros.rb → support/custom_macros.rb} +69 -35
  45. data/spec/support/output_buffer.rb +4 -0
  46. data/spec/support/test_environment.rb +45 -0
  47. metadata +26 -28
  48. data/spec/layout_helper_spec.rb +0 -29
data/spec/label_spec.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'spec_helper'
3
3
 
4
4
  describe 'SemanticFormBuilder#label' do
5
5
 
@@ -32,16 +32,18 @@ describe 'SemanticFormBuilder#label' do
32
32
 
33
33
  describe 'when a collection is given' do
34
34
  it 'should use a supplied label_method for simple collections' do
35
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
35
+ form = semantic_form_for(:project, :url => 'http://test.host') do |builder|
36
36
  concat(builder.input(:author_id, :as => :check_boxes, :collection => [:a, :b, :c], :value_method => :to_s, :label_method => proc {|f| ('Label_%s' % [f])}))
37
37
  end
38
+ output_buffer.concat(form) if Formtastic::Util.rails3?
38
39
  output_buffer.should have_tag('form li fieldset ol li label', :with => /Label_[abc]/, :count => 3)
39
40
  end
40
41
 
41
42
  it 'should use a supplied value_method for simple collections' do
42
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
43
+ form = semantic_form_for(:project, :url => 'http://test.host') do |builder|
43
44
  concat(builder.input(:author_id, :as => :check_boxes, :collection => [:a, :b, :c], :value_method => proc {|f| ('Value_%s' % [f.to_s])}))
44
45
  end
46
+ output_buffer.concat(form) if Formtastic::Util.rails3?
45
47
  output_buffer.should have_tag('form li fieldset ol li label input[value="Value_a"]')
46
48
  output_buffer.should have_tag('form li fieldset ol li label input[value="Value_b"]')
47
49
  output_buffer.should have_tag('form li fieldset ol li label input[value="Value_c"]')
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'spec_helper'
3
3
 
4
4
  describe 'SemanticFormBuilder#semantic_errors' do
5
5
 
@@ -17,7 +17,7 @@ describe 'SemanticFormBuilder#semantic_errors' do
17
17
 
18
18
  describe 'when there is only one error on base' do
19
19
  before do
20
- @errors.stub!(:on_base).and_return(@base_error)
20
+ @errors.stub!(:[]).with(:base).and_return(@base_error)
21
21
  end
22
22
 
23
23
  it 'should render an unordered list' do
@@ -29,7 +29,7 @@ describe 'SemanticFormBuilder#semantic_errors' do
29
29
 
30
30
  describe 'when there is more than one error on base' do
31
31
  before do
32
- @errors.stub!(:on_base).and_return(@base_errors)
32
+ @errors.stub!(:[]).with(:base).and_return(@base_errors)
33
33
  end
34
34
 
35
35
  it 'should render an unordered list' do
@@ -45,7 +45,7 @@ describe 'SemanticFormBuilder#semantic_errors' do
45
45
  describe 'when there are errors on title' do
46
46
  before do
47
47
  @errors.stub!(:[]).with(:title).and_return(@title_errors)
48
- @errors.stub!(:on_base).and_return([])
48
+ @errors.stub!(:[]).with(:base).and_return([])
49
49
  end
50
50
 
51
51
  it 'should render an unordered list' do
@@ -59,7 +59,7 @@ describe 'SemanticFormBuilder#semantic_errors' do
59
59
  describe 'when there are errors on title and base' do
60
60
  before do
61
61
  @errors.stub!(:[]).with(:title).and_return(@title_errors)
62
- @errors.stub!(:on_base).and_return(@base_error)
62
+ @errors.stub!(:[]).with(:base).and_return(@base_error)
63
63
  end
64
64
 
65
65
  it 'should render an unordered list' do
@@ -74,7 +74,7 @@ describe 'SemanticFormBuilder#semantic_errors' do
74
74
  describe 'when there are no errors' do
75
75
  before do
76
76
  @errors.stub!(:[]).with(:title).and_return(nil)
77
- @errors.stub!(:on_base).and_return(nil)
77
+ @errors.stub!(:[]).with(:base).and_return(nil)
78
78
  end
79
79
 
80
80
  it 'should return nil' do
@@ -86,7 +86,7 @@ describe 'SemanticFormBuilder#semantic_errors' do
86
86
 
87
87
  describe 'when there is one error on base and options with class is passed' do
88
88
  before do
89
- @errors.stub!(:on_base).and_return(@base_error)
89
+ @errors.stub!(:[]).with(:base).and_return(@base_error)
90
90
  end
91
91
 
92
92
  it 'should render an unordered list with given class' do
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'spec_helper'
3
3
 
4
4
  describe 'SemanticFormBuilder#semantic_fields_for' do
5
5
 
@@ -29,11 +29,12 @@ describe 'SemanticFormBuilder#semantic_fields_for' do
29
29
 
30
30
  it 'should sanitize html id for li tag' do
31
31
  @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
32
- semantic_form_for(@new_post) do |builder|
33
- builder.semantic_fields_for(@bob, :index => 1) do |nested_builder|
32
+ form = semantic_form_for(@new_post) do |builder|
33
+ concat(builder.semantic_fields_for(@bob, :index => 1) do |nested_builder|
34
34
  concat(nested_builder.inputs(:login))
35
- end
35
+ end)
36
36
  end
37
+ output_buffer.concat(form) if Formtastic::Util.rails3?
37
38
  output_buffer.should have_tag('form fieldset.inputs #post_author_1_login_input')
38
39
  # Not valid selector, so using good ol' regex
39
40
  output_buffer.should_not =~ /id="post\[author\]_1_login_input"/
data/spec/spec_helper.rb CHANGED
@@ -1,52 +1,47 @@
1
1
  # coding: utf-8
2
2
  require 'rubygems'
3
-
4
- gem 'i18n', '< 0.4'
5
-
6
- gem 'activesupport', '2.3.8'
7
- gem 'actionpack', '2.3.8'
8
3
  require 'active_support'
9
4
  require 'action_pack'
10
5
  require 'action_view'
11
6
  require 'action_controller'
7
+ require 'action_mailer'
12
8
 
13
-
14
-
15
- gem 'rspec', '>= 1.2.6'
16
- gem 'rspec-rails', '>= 1.2.6'
17
- gem 'hpricot', '>= 0.6.1'
18
- gem 'rspec_tag_matchers', '>= 1.0.0'
19
- require 'rspec_tag_matchers'
20
-
21
- require 'custom_macros'
22
-
23
- Spec::Runner.configure do |config|
24
- config.include(RspecTagMatchers)
25
- config.include(CustomMacros)
26
- end
27
-
28
- require File.expand_path(File.join(File.dirname(__FILE__), '../lib/formtastic'))
29
9
  require File.expand_path(File.join(File.dirname(__FILE__), '../lib/formtastic/util'))
10
+ require File.expand_path(File.join(File.dirname(__FILE__), '../lib/formtastic'))
30
11
  require File.expand_path(File.join(File.dirname(__FILE__), '../lib/formtastic/layout_helper'))
31
12
 
13
+ # Requires supporting files with custom matchers and macros, etc,
14
+ # in ./support/ and its subdirectories in alphabetic order.
15
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each {|f| require f}
32
16
 
33
17
  module FormtasticSpecHelper
18
+ include ActionPack
19
+ include ActionView::Context if defined?(ActionView::Context)
20
+ include ActionController::RecordIdentifier
34
21
  include ActionView::Helpers::FormHelper
35
22
  include ActionView::Helpers::FormTagHelper
36
23
  include ActionView::Helpers::FormOptionsHelper
37
24
  include ActionView::Helpers::UrlHelper
38
25
  include ActionView::Helpers::TagHelper
39
26
  include ActionView::Helpers::TextHelper
40
- include ActionView::Helpers::ActiveRecordHelper
41
- include ActionView::Helpers::RecordIdentificationHelper
27
+ include ActionView::Helpers::ActiveRecordHelper if defined?(ActionView::Helpers::ActiveRecordHelper)
28
+ include ActionView::Helpers::ActiveModelHelper if defined?(ActionView::Helpers::ActiveModelHelper)
42
29
  include ActionView::Helpers::DateHelper
43
30
  include ActionView::Helpers::CaptureHelper
44
31
  include ActionView::Helpers::AssetTagHelper
45
32
  include ActiveSupport
46
- include ActionController::PolymorphicRoutes
33
+ include ActionController::PolymorphicRoutes if defined?(ActionController::PolymorphicRoutes)
47
34
 
48
35
  include Formtastic::SemanticFormHelper
49
36
 
37
+ def rails3?
38
+ ActionPack::VERSION::MAJOR > 2
39
+ end
40
+
41
+ def rails2?
42
+ ActionPack::VERSION::MAJOR == 2
43
+ end
44
+
50
45
  def default_input_type(column_type, column_name = :generic_column_name)
51
46
  @new_post.stub!(column_name)
52
47
  @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => column_type)) unless column_type.nil?
@@ -58,27 +53,56 @@ module FormtasticSpecHelper
58
53
  return @default_type
59
54
  end
60
55
 
56
+ def active_model_presence_validator(attributes, options = {})
57
+ presence_validator = mock('ActiveModel::Validations::PresenceValidator', :attributes => attributes, :options => options)
58
+ presence_validator.stub!(:kind).and_return(:presence)
59
+ presence_validator
60
+ end
61
+
61
62
  class ::Post
63
+ extend ActiveModel::Naming if defined?(ActiveModel::Naming)
64
+ include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
65
+
62
66
  def id
63
67
  end
68
+
69
+ def persisted?
70
+ end
64
71
  end
65
72
  module ::Namespaced
66
73
  class Post
74
+ extend ActiveModel::Naming if defined?(ActiveModel::Naming)
75
+ include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
76
+
67
77
  def id
68
78
  end
79
+
80
+ def persisted?
81
+ end
69
82
  end
70
83
  end
71
84
  class ::Author
85
+ extend ActiveModel::Naming if defined?(ActiveModel::Naming)
86
+ include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
87
+
72
88
  def to_label
73
89
  end
74
90
  end
75
91
  class ::Continent
92
+ extend ActiveModel::Naming if defined?(ActiveModel::Naming)
93
+ include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
94
+ end
95
+ class ::PostModel
96
+ extend ActiveModel::Naming if defined?(ActiveModel::Naming)
97
+ include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
76
98
  end
77
99
 
78
100
  def mock_everything
79
101
 
80
102
  # Resource-oriented styles like form_for(@post) will expect a path method for the object,
81
103
  # so we're defining some here.
104
+ def post_models_path; "/postmodels/1"; end
105
+
82
106
  def post_path(o); "/posts/1"; end
83
107
  def posts_path; "/posts"; end
84
108
  def new_post_path; "/posts/new"; end
@@ -88,14 +112,18 @@ module FormtasticSpecHelper
88
112
  def new_author_path; "/authors/new"; end
89
113
 
90
114
  @fred = mock('user')
115
+ @fred.stub!(:to_ary)
91
116
  @fred.stub!(:class).and_return(::Author)
92
117
  @fred.stub!(:to_label).and_return('Fred Smith')
93
118
  @fred.stub!(:login).and_return('fred_smith')
94
119
  @fred.stub!(:id).and_return(37)
95
120
  @fred.stub!(:new_record?).and_return(false)
96
121
  @fred.stub!(:errors).and_return(mock('errors', :[] => nil))
122
+ @fred.stub!(:to_key).and_return(nil)
123
+ @fred.stub!(:persisted?).and_return(nil)
97
124
 
98
125
  @bob = mock('user')
126
+ @bob.stub!(:to_ary)
99
127
  @bob.stub!(:class).and_return(::Author)
100
128
  @bob.stub!(:to_label).and_return('Bob Rock')
101
129
  @bob.stub!(:login).and_return('bob')
@@ -105,37 +133,50 @@ module FormtasticSpecHelper
105
133
  @bob.stub!(:post_ids).and_return([])
106
134
  @bob.stub!(:new_record?).and_return(false)
107
135
  @bob.stub!(:errors).and_return(mock('errors', :[] => nil))
136
+ @bob.stub!(:to_key).and_return(nil)
137
+ @bob.stub!(:persisted?).and_return(nil)
108
138
 
109
139
  @james = mock('user')
110
- @james.stub!(:class).and_return(::Author)
111
- @james.stub!(:to_label).and_return('James Shock')
112
- @james.stub!(:login).and_return('james')
113
- @james.stub!(:id).and_return(75)
114
- @james.stub!(:posts).and_return([])
115
- @james.stub!(:post_ids).and_return([])
116
- @james.stub!(:new_record?).and_return(false)
117
- @james.stub!(:errors).and_return(mock('errors', :[] => nil))
140
+ @james.stub!(:to_ary)
141
+ @james.stub!(:class).and_return(::Author)
142
+ @james.stub!(:to_label).and_return('James Shock')
143
+ @james.stub!(:login).and_return('james')
144
+ @james.stub!(:id).and_return(75)
145
+ @james.stub!(:posts).and_return([])
146
+ @james.stub!(:post_ids).and_return([])
147
+ @james.stub!(:new_record?).and_return(false)
148
+ @james.stub!(:errors).and_return(mock('errors', :[] => nil))
149
+ @james.stub!(:to_key).and_return(nil)
150
+ @james.stub!(:persisted?).and_return(nil)
118
151
 
119
152
 
120
153
  ::Author.stub!(:find).and_return([@fred, @bob])
154
+ ::Author.stub!(:all).and_return([@fred, @bob])
155
+ ::Author.stub!(:to_ary)
121
156
  ::Author.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
122
157
  ::Author.stub!(:human_name).and_return('::Author')
123
- ::Author.stub!(:reflect_on_validations_for).and_return([])
124
158
  ::Author.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :options => {}, :klass => Post, :macro => :has_many) if column_name == :posts }
125
159
  ::Author.stub!(:content_columns).and_return([mock('column', :name => 'login'), mock('column', :name => 'created_at')])
160
+ ::Author.stub!(:to_key).and_return(nil)
161
+ ::Author.stub!(:persisted?).and_return(nil)
126
162
 
127
163
  # Sometimes we need a mock @post object and some Authors for belongs_to
128
164
  @new_post = mock('post')
165
+ @new_post.stub!(:to_ary)
129
166
  @new_post.stub!(:class).and_return(::Post)
130
167
  @new_post.stub!(:id).and_return(nil)
131
168
  @new_post.stub!(:new_record?).and_return(true)
132
169
  @new_post.stub!(:errors).and_return(mock('errors', :[] => nil))
133
170
  @new_post.stub!(:author).and_return(nil)
134
- @new_post.stub!(:reviewer).and_return(nil)
171
+ @new_post.stub!(:reviewer).and_return(nil)
135
172
  @new_post.stub!(:main_post).and_return(nil)
136
173
  @new_post.stub!(:sub_posts).and_return([]) #TODO should be a mock with methods for adding sub posts
174
+ @new_post.stub!(:to_key).and_return(nil)
175
+ @new_post.stub!(:to_model).and_return(@new_post)
176
+ @new_post.stub!(:persisted?).and_return(nil)
137
177
 
138
178
  @freds_post = mock('post')
179
+ @freds_post.stub!(:to_ary)
139
180
  @freds_post.stub!(:class).and_return(::Post)
140
181
  @freds_post.stub!(:to_label).and_return('Fred Smith')
141
182
  @freds_post.stub!(:id).and_return(19)
@@ -145,6 +186,8 @@ module FormtasticSpecHelper
145
186
  @freds_post.stub!(:author_ids).and_return([@fred.id])
146
187
  @freds_post.stub!(:new_record?).and_return(false)
147
188
  @freds_post.stub!(:errors).and_return(mock('errors', :[] => nil))
189
+ @freds_post.stub!(:to_key).and_return(nil)
190
+ @freds_post.stub!(:persisted?).and_return(nil)
148
191
  @fred.stub!(:posts).and_return([@freds_post])
149
192
  @fred.stub!(:post_ids).and_return([@freds_post.id])
150
193
 
@@ -159,8 +202,8 @@ module FormtasticSpecHelper
159
202
  mock = mock('reflection', :options => {}, :klass => ::Author, :macro => :belongs_to)
160
203
  mock.stub!(:[]).with(:class_name).and_return("Author")
161
204
  mock
162
- when :reviewer
163
- mock = mock('reflection', :options => {:class_name => 'Author'}, :klass => ::Author, :macro => :belongs_to)
205
+ when :reviewer
206
+ mock = mock('reflection', :options => {:class_name => 'Author'}, :klass => ::Author, :macro => :belongs_to)
164
207
  mock.stub!(:[]).with(:class_name).and_return("Author")
165
208
  mock
166
209
  when :authors
@@ -173,9 +216,14 @@ module FormtasticSpecHelper
173
216
 
174
217
  end
175
218
  ::Post.stub!(:find).and_return([@freds_post])
219
+ ::Post.stub!(:all).and_return([@freds_post])
176
220
  ::Post.stub!(:content_columns).and_return([mock('column', :name => 'title'), mock('column', :name => 'body'), mock('column', :name => 'created_at')])
221
+ ::Post.stub!(:to_key).and_return(nil)
222
+ ::Post.stub!(:persisted?).and_return(nil)
223
+ ::Post.stub!(:to_ary)
177
224
 
178
225
  @new_post.stub!(:title)
226
+ @new_post.stub!(:to_ary)
179
227
  @new_post.stub!(:body)
180
228
  @new_post.stub!(:published)
181
229
  @new_post.stub!(:publish_at)
@@ -202,8 +250,8 @@ module FormtasticSpecHelper
202
250
  @new_post.stub!(:author).and_return(@bob)
203
251
  @new_post.stub!(:author_id).and_return(@bob.id)
204
252
 
205
- @new_post.stub!(:reviewer).and_return(@fred)
206
- @new_post.stub!(:reviewer_id).and_return(@fred.id)
253
+ @new_post.stub!(:reviewer).and_return(@fred)
254
+ @new_post.stub!(:reviewer_id).and_return(@fred.id)
207
255
 
208
256
  @new_post.should_receive(:publish_at=).any_number_of_times
209
257
  @new_post.should_receive(:title=).any_number_of_times
@@ -8,66 +8,77 @@ module CustomMacros
8
8
 
9
9
  def it_should_have_input_wrapper_with_class(class_name)
10
10
  it "should have input wrapper with class '#{class_name}'" do
11
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
11
12
  output_buffer.should have_tag("form li.#{class_name}")
12
13
  end
13
14
  end
14
15
 
15
16
  def it_should_have_input_wrapper_with_id(id_string)
16
17
  it "should have input wrapper with id '#{id_string}'" do
18
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
17
19
  output_buffer.should have_tag("form li##{id_string}")
18
20
  end
19
21
  end
20
22
 
21
23
  def it_should_not_have_a_label
22
24
  it "should not have a label" do
25
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
23
26
  output_buffer.should_not have_tag("form li label")
24
27
  end
25
28
  end
26
29
 
27
30
  def it_should_have_a_nested_fieldset
28
31
  it "should have a nested_fieldset" do
32
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
29
33
  output_buffer.should have_tag("form li fieldset")
30
34
  end
31
35
  end
32
36
 
33
37
  def it_should_have_label_with_text(string_or_regex)
34
38
  it "should have a label with text '#{string_or_regex}'" do
39
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
35
40
  output_buffer.should have_tag("form li label", string_or_regex)
36
41
  end
37
42
  end
38
43
 
39
44
  def it_should_have_label_for(element_id)
40
45
  it "should have a label for ##{element_id}" do
46
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
41
47
  output_buffer.should have_tag("form li label[@for='#{element_id}']")
42
48
  end
43
49
  end
44
50
 
45
51
  def it_should_have_input_with_id(element_id)
46
52
  it "should have an input with id '#{element_id}'" do
53
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
47
54
  output_buffer.should have_tag("form li input##{element_id}")
48
55
  end
49
56
  end
50
57
 
51
58
  def it_should_have_input_with_type(input_type)
52
59
  it "should have a #{input_type} input" do
60
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
53
61
  output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
54
62
  end
55
63
  end
56
64
 
57
65
  def it_should_have_input_with_name(name)
58
66
  it "should have an input named #{name}" do
67
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
59
68
  output_buffer.should have_tag("form li input[@name=\"#{name}\"]")
60
69
  end
61
70
  end
62
71
 
63
72
  def it_should_have_textarea_with_name(name)
64
73
  it "should have an input named #{name}" do
74
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
65
75
  output_buffer.should have_tag("form li textarea[@name=\"#{name}\"]")
66
76
  end
67
77
  end
68
78
 
69
79
  def it_should_have_textarea_with_id(element_id)
70
80
  it "should have an input with id '#{element_id}'" do
81
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
71
82
  output_buffer.should have_tag("form li textarea##{element_id}")
72
83
  end
73
84
  end
@@ -76,27 +87,30 @@ module CustomMacros
76
87
  it 'should use default_text_field_size when method has no database column' do
77
88
  @new_post.stub!(:column_for_attribute).and_return(nil) # Return a nil column
78
89
 
79
- semantic_form_for(@new_post) do |builder|
90
+ form = semantic_form_for(@new_post) do |builder|
80
91
  concat(builder.input(:title, :as => as))
81
92
  end
93
+ output_buffer.concat(form) if Formtastic::Util.rails3?
82
94
  output_buffer.should have_tag("form li input[@size='#{Formtastic::SemanticFormBuilder.default_text_field_size}']")
83
95
  end
84
96
  end
85
97
 
86
98
  def it_should_apply_custom_input_attributes_when_input_html_provided(as)
87
99
  it 'it should apply custom input attributes when input_html provided' do
88
- semantic_form_for(@new_post) do |builder|
100
+ form = semantic_form_for(@new_post) do |builder|
89
101
  concat(builder.input(:title, :as => as, :input_html => { :class => 'myclass' }))
90
102
  end
103
+ output_buffer.concat(form) if Formtastic::Util.rails3?
91
104
  output_buffer.should have_tag("form li input.myclass")
92
105
  end
93
106
  end
94
107
 
95
108
  def it_should_apply_custom_for_to_label_when_input_html_id_provided(as)
96
109
  it 'it should apply custom for to label when input_html :id provided' do
97
- semantic_form_for(@new_post) do |builder|
110
+ form = semantic_form_for(@new_post) do |builder|
98
111
  concat(builder.input(:title, :as => as, :input_html => { :id => 'myid' }))
99
112
  end
113
+ output_buffer.concat(form) if Formtastic::Util.rails3?
100
114
  output_buffer.should have_tag('form li label[@for="myid"]')
101
115
  end
102
116
  end
@@ -104,6 +118,7 @@ module CustomMacros
104
118
  def it_should_have_maxlength_matching_column_limit
105
119
  it 'should have a maxlength matching column limit' do
106
120
  @new_post.column_for_attribute(:title).limit.should == 50
121
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
107
122
  output_buffer.should have_tag("form li input[@maxlength='50']")
108
123
  end
109
124
  end
@@ -113,10 +128,11 @@ module CustomMacros
113
128
  default_size = Formtastic::SemanticFormBuilder.default_text_field_size
114
129
  @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => as, :limit => default_size * 2))
115
130
 
116
- semantic_form_for(@new_post) do |builder|
131
+ form = semantic_form_for(@new_post) do |builder|
117
132
  concat(builder.input(:title, :as => as))
118
133
  end
119
134
 
135
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
120
136
  output_buffer.should have_tag("form li input[@size='#{default_size}']")
121
137
  end
122
138
  end
@@ -126,10 +142,11 @@ module CustomMacros
126
142
  column_limit_shorted_than_default = 1
127
143
  @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => as, :limit => column_limit_shorted_than_default))
128
144
 
129
- semantic_form_for(@new_post) do |builder|
145
+ form = semantic_form_for(@new_post) do |builder|
130
146
  concat(builder.input(:title, :as => as))
131
147
  end
132
148
 
149
+ output_buffer.concat(form) if Formtastic::Util.rails3?
133
150
  output_buffer.should have_tag("form li input[@size='#{column_limit_shorted_than_default}']")
134
151
  end
135
152
  end
@@ -144,72 +161,82 @@ module CustomMacros
144
161
  end
145
162
 
146
163
  it 'should apply an errors class to the list item' do
147
- semantic_form_for(@new_post) do |builder|
164
+ form = semantic_form_for(@new_post) do |builder|
148
165
  concat(builder.input(:title, :as => type))
149
166
  end
167
+ output_buffer.concat(form) if Formtastic::Util.rails3?
150
168
  output_buffer.should have_tag('form li.error')
151
169
  end
152
170
 
153
171
  it 'should not wrap the input with the Rails default error wrapping' do
154
- semantic_form_for(@new_post) do |builder|
172
+ form = semantic_form_for(@new_post) do |builder|
155
173
  concat(builder.input(:title, :as => type))
156
174
  end
175
+ output_buffer.concat(form) if Formtastic::Util.rails3?
157
176
  output_buffer.should_not have_tag('div.fieldWithErrors')
158
177
  end
159
178
 
160
179
  it 'should render a paragraph for the errors' do
161
180
  ::Formtastic::SemanticFormBuilder.inline_errors = :sentence
162
- semantic_form_for(@new_post) do |builder|
181
+ form = semantic_form_for(@new_post) do |builder|
163
182
  concat(builder.input(:title, :as => type))
164
183
  end
184
+ output_buffer.concat(form) if Formtastic::Util.rails3?
165
185
  output_buffer.should have_tag('form li.error p.inline-errors')
166
186
  end
167
187
 
168
188
  it 'should not display an error list' do
169
189
  ::Formtastic::SemanticFormBuilder.inline_errors = :list
170
- semantic_form_for(@new_post) do |builder|
190
+ form = semantic_form_for(@new_post) do |builder|
171
191
  concat(builder.input(:title, :as => type))
172
192
  end
193
+ output_buffer.concat(form) if Formtastic::Util.rails3?
173
194
  output_buffer.should have_tag('form li.error ul.errors')
174
195
  end
175
196
  end
176
197
 
177
198
  describe 'when there are no errors on the object for this method' do
178
199
  before do
179
- semantic_form_for(@new_post) do |builder|
200
+ @form = semantic_form_for(@new_post) do |builder|
180
201
  concat(builder.input(:title, :as => type))
181
202
  end
182
203
  end
183
204
 
184
205
  it 'should not apply an errors class to the list item' do
206
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
185
207
  output_buffer.should_not have_tag('form li.error')
186
208
  end
187
209
 
188
210
  it 'should not render a paragraph for the errors' do
211
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
189
212
  output_buffer.should_not have_tag('form li.error p.inline-errors')
190
213
  end
191
214
 
192
215
  it 'should not display an error list' do
216
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
193
217
  output_buffer.should_not have_tag('form li.error ul.errors')
194
218
  end
195
219
  end
196
220
 
197
221
  describe 'when no object is provided' do
198
222
  before do
199
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
223
+ @form = semantic_form_for(:project, :url => 'http://test.host') do |builder|
200
224
  concat(builder.input(:title, :as => type))
201
225
  end
202
226
  end
203
227
 
204
228
  it 'should not apply an errors class to the list item' do
229
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
205
230
  output_buffer.should_not have_tag('form li.error')
206
231
  end
207
232
 
208
233
  it 'should not render a paragraph for the errors' do
234
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
209
235
  output_buffer.should_not have_tag('form li.error p.inline-errors')
210
236
  end
211
237
 
212
238
  it 'should not display an error list' do
239
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
213
240
  output_buffer.should_not have_tag('form li.error ul.errors')
214
241
  end
215
242
  end
@@ -217,8 +244,8 @@ module CustomMacros
217
244
 
218
245
  def it_should_call_find_on_association_class_when_no_collection_is_provided(as)
219
246
  it "should call find on the association class when no collection is provided" do
220
- ::Author.should_receive(:find)
221
- semantic_form_for(@new_post) do |builder|
247
+ ::Author.should_receive(:all)
248
+ form = semantic_form_for(@new_post) do |builder|
222
249
  concat(builder.input(:author, :as => as))
223
250
  end
224
251
  end
@@ -232,17 +259,11 @@ module CustomMacros
232
259
  output_buffer.replace '' # clears the output_buffer from the before block, hax!
233
260
  end
234
261
 
235
- it 'should not call find() on the parent class' do
236
- ::Author.should_not_receive(:find)
237
- semantic_form_for(@new_post) do |builder|
238
- concat(builder.input(:author, :as => as, :collection => @authors))
239
- end
240
- end
241
-
242
262
  it 'should use the provided collection' do
243
- semantic_form_for(@new_post) do |builder|
263
+ form = semantic_form_for(@new_post) do |builder|
244
264
  concat(builder.input(:author, :as => as, :collection => @authors))
245
265
  end
266
+ output_buffer.concat(form) if Formtastic::Util.rails3?
246
267
  output_buffer.should have_tag("form li.#{as} #{countable}", :count => @authors.size + (as == :select ? 1 : 0))
247
268
  end
248
269
 
@@ -252,9 +273,10 @@ module CustomMacros
252
273
  end
253
274
 
254
275
  it "should use the string as the label text and value for each #{countable}" do
255
- semantic_form_for(@new_post) do |builder|
276
+ form = semantic_form_for(@new_post) do |builder|
256
277
  concat(builder.input(:category_name, :as => as, :collection => @categories))
257
278
  end
279
+ output_buffer.concat(form) if Formtastic::Util.rails3?
258
280
 
259
281
  @categories.each do |value|
260
282
  output_buffer.should have_tag("form li.#{as}", /#{value}/)
@@ -265,11 +287,13 @@ module CustomMacros
265
287
  if as == :radio
266
288
  it 'should generate a sanitized label for attribute' do
267
289
  @bob.stub!(:category_name).and_return(@categories)
268
- semantic_form_for(@new_post) do |builder|
269
- builder.semantic_fields_for(@bob) do |bob_builder|
290
+ form = semantic_form_for(@new_post) do |builder|
291
+ fields = builder.semantic_fields_for(@bob) do |bob_builder|
270
292
  concat(bob_builder.input(:category_name, :as => as, :collection => @categories))
271
293
  end
294
+ concat(fields)
272
295
  end
296
+ output_buffer.concat(form) if Formtastic::Util.rails3?
273
297
  output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_general']")
274
298
  output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_design']")
275
299
  output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_development']")
@@ -284,9 +308,10 @@ module CustomMacros
284
308
  end
285
309
 
286
310
  it "should use the key as the label text and the hash value as the value attribute for each #{countable}" do
287
- semantic_form_for(@new_post) do |builder|
311
+ form = semantic_form_for(@new_post) do |builder|
288
312
  concat(builder.input(:category_name, :as => as, :collection => @categories))
289
313
  end
314
+ output_buffer.concat(form) if Formtastic::Util.rails3?
290
315
 
291
316
  @categories.each do |label, value|
292
317
  output_buffer.should have_tag("form li.#{as}", /#{label}/)
@@ -301,9 +326,10 @@ module CustomMacros
301
326
  end
302
327
 
303
328
  it "should use the first value as the label text and the last value as the value attribute for #{countable}" do
304
- semantic_form_for(@new_post) do |builder|
329
+ form = semantic_form_for(@new_post) do |builder|
305
330
  concat(builder.input(:category_name, :as => as, :collection => @categories))
306
331
  end
332
+ output_buffer.concat(form) if Formtastic::Util.rails3?
307
333
 
308
334
  @categories.each do |text, value|
309
335
  label = as == :select ? :option : :label
@@ -321,9 +347,10 @@ module CustomMacros
321
347
  end
322
348
 
323
349
  it "should use the first value as the label text and the last value as the value attribute for #{countable}" do
324
- semantic_form_for(@new_post) do |builder|
350
+ form = semantic_form_for(@new_post) do |builder|
325
351
  concat(builder.input(:category_name, :as => as, :collection => @choices))
326
352
  end
353
+ output_buffer.concat(form) if Formtastic::Util.rails3?
327
354
 
328
355
  output_buffer.should have_tag("form li.#{as} #{countable}#post_category_name_true")
329
356
  output_buffer.should have_tag("form li.#{as} #{countable}#post_category_name_false")
@@ -337,9 +364,10 @@ module CustomMacros
337
364
  end
338
365
 
339
366
  it "should use the symbol as the label text and value for each #{countable}" do
340
- semantic_form_for(@new_post) do |builder|
367
+ form = semantic_form_for(@new_post) do |builder|
341
368
  concat(builder.input(:category_name, :as => as, :collection => @categories))
342
369
  end
370
+ output_buffer.concat(form) if Formtastic::Util.rails3?
343
371
 
344
372
  @categories.each do |value|
345
373
  label = as == :select ? :option : :label
@@ -355,9 +383,10 @@ module CustomMacros
355
383
  end
356
384
 
357
385
  it "should use the key as the label text and the hash value as the value attribute for each #{countable}" do
358
- semantic_form_for(@new_post) do |builder|
386
+ form = semantic_form_for(@new_post) do |builder|
359
387
  concat(builder.input(:category_name, :as => as, :collection => @categories))
360
388
  end
389
+ output_buffer.concat(form) if Formtastic::Util.rails3?
361
390
 
362
391
  @categories.each do |label, value|
363
392
  output_buffer.should have_tag("form li.#{as}", /#{label}/)
@@ -371,12 +400,13 @@ module CustomMacros
371
400
 
372
401
  describe 'as a symbol' do
373
402
  before do
374
- semantic_form_for(@new_post) do |builder|
403
+ @form = semantic_form_for(@new_post) do |builder|
375
404
  concat(builder.input(:author, :as => as, :label_method => :login))
376
405
  end
377
406
  end
378
407
 
379
408
  it 'should have options with text content from the specified method' do
409
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
380
410
  ::Author.find(:all).each do |author|
381
411
  output_buffer.should have_tag("form li.#{as}", /#{author.login}/)
382
412
  end
@@ -385,12 +415,13 @@ module CustomMacros
385
415
 
386
416
  describe 'as a proc' do
387
417
  before do
388
- semantic_form_for(@new_post) do |builder|
418
+ @form = semantic_form_for(@new_post) do |builder|
389
419
  concat(builder.input(:author, :as => as, :label_method => Proc.new {|a| a.login.reverse }))
390
420
  end
391
421
  end
392
422
 
393
423
  it 'should have options with the proc applied to each' do
424
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
394
425
  ::Author.find(:all).each do |author|
395
426
  output_buffer.should have_tag("form li.#{as}", /#{author.login.reverse}/)
396
427
  end
@@ -404,15 +435,16 @@ module CustomMacros
404
435
 
405
436
  describe "when the collection objects respond to #{label_method}" do
406
437
  before do
407
- @fred.stub!(:respond_to?).and_return { |m| m.to_s == label_method }
438
+ @fred.stub!(:respond_to?).and_return { |m| m.to_s == label_method || m.to_s == 'id' }
408
439
  ::Author.find(:all).each { |a| a.stub!(label_method).and_return('The Label Text') }
409
440
 
410
- semantic_form_for(@new_post) do |builder|
441
+ @form = semantic_form_for(@new_post) do |builder|
411
442
  concat(builder.input(:author, :as => as))
412
443
  end
413
444
  end
414
445
 
415
446
  it "should render the options with #{label_method} as the label" do
447
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
416
448
  ::Author.find(:all).each do |author|
417
449
  output_buffer.should have_tag("form li.#{as}", /The Label Text/)
418
450
  end
@@ -426,12 +458,13 @@ module CustomMacros
426
458
 
427
459
  describe 'as a symbol' do
428
460
  before do
429
- semantic_form_for(@new_post) do |builder|
461
+ @form = semantic_form_for(@new_post) do |builder|
430
462
  concat(builder.input(:author, :as => as, :value_method => :login))
431
463
  end
432
464
  end
433
465
 
434
466
  it 'should have options with values from specified method' do
467
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
435
468
  ::Author.find(:all).each do |author|
436
469
  output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{author.login}']")
437
470
  end
@@ -440,12 +473,13 @@ module CustomMacros
440
473
 
441
474
  describe 'as a proc' do
442
475
  before do
443
- semantic_form_for(@new_post) do |builder|
476
+ @form = semantic_form_for(@new_post) do |builder|
444
477
  concat(builder.input(:author, :as => as, :value_method => Proc.new {|a| a.login.reverse }))
445
478
  end
446
479
  end
447
480
 
448
481
  it 'should have options with the proc applied to each value' do
482
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
449
483
  ::Author.find(:all).each do |author|
450
484
  output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{author.login.reverse}']")
451
485
  end