formtastic 2.3.0.rc2 → 2.3.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/.travis.yml +27 -1
  2. data/Appraisals +5 -0
  3. data/CHANGELOG +1 -0
  4. data/README.textile +19 -26
  5. data/formtastic.gemspec +4 -3
  6. data/gemfiles/rails_3.0.gemfile +1 -1
  7. data/gemfiles/rails_3.1.gemfile +1 -1
  8. data/gemfiles/rails_3.2.gemfile +1 -1
  9. data/gemfiles/rails_4.0.4.gemfile +7 -0
  10. data/gemfiles/rails_4.gemfile +1 -1
  11. data/lib/formtastic/form_builder.rb +9 -1
  12. data/lib/formtastic/helpers/form_helper.rb +11 -6
  13. data/lib/formtastic/helpers/inputs_helper.rb +6 -1
  14. data/lib/formtastic/inputs/base/collections.rb +1 -1
  15. data/lib/formtastic/inputs/base/validations.rb +1 -1
  16. data/lib/formtastic/inputs/boolean_input.rb +4 -14
  17. data/lib/formtastic/inputs/check_boxes_input.rb +7 -1
  18. data/lib/formtastic/inputs/radio_input.rb +2 -0
  19. data/lib/formtastic/util.rb +13 -1
  20. data/lib/formtastic/version.rb +1 -1
  21. data/lib/generators/templates/_form.html.slim +2 -2
  22. data/lib/generators/templates/formtastic.rb +15 -1
  23. data/spec/actions/generic_action_spec.rb +3 -3
  24. data/spec/builder/custom_builder_spec.rb +7 -7
  25. data/spec/builder/semantic_fields_for_spec.rb +8 -8
  26. data/spec/generators/formtastic/form/form_generator_spec.rb +6 -6
  27. data/spec/helpers/action_helper_spec.rb +11 -11
  28. data/spec/helpers/form_helper_spec.rb +22 -11
  29. data/spec/helpers/input_helper_spec.rb +44 -44
  30. data/spec/helpers/inputs_helper_spec.rb +64 -31
  31. data/spec/helpers/semantic_errors_helper_spec.rb +12 -12
  32. data/spec/i18n_spec.rb +5 -5
  33. data/spec/inputs/boolean_input_spec.rb +6 -5
  34. data/spec/inputs/check_boxes_input_spec.rb +27 -9
  35. data/spec/inputs/country_input_spec.rb +5 -5
  36. data/spec/inputs/custom_input_spec.rb +1 -1
  37. data/spec/inputs/date_picker_input_spec.rb +4 -4
  38. data/spec/inputs/datetime_picker_input_spec.rb +4 -4
  39. data/spec/inputs/hidden_input_spec.rb +3 -3
  40. data/spec/inputs/include_blank_spec.rb +2 -2
  41. data/spec/inputs/number_input_spec.rb +36 -36
  42. data/spec/inputs/radio_input_spec.rb +23 -5
  43. data/spec/inputs/range_input_spec.rb +19 -19
  44. data/spec/inputs/select_input_spec.rb +40 -20
  45. data/spec/inputs/string_input_spec.rb +2 -2
  46. data/spec/inputs/time_picker_input_spec.rb +4 -4
  47. data/spec/localizer_spec.rb +1 -1
  48. data/spec/spec_helper.rb +203 -188
  49. data/spec/support/custom_macros.rb +8 -8
  50. metadata +15 -13
@@ -1,3 +1,3 @@
1
1
  module Formtastic
2
- VERSION = "2.3.0.rc2"
2
+ VERSION = "2.3.0.rc3"
3
3
  end
@@ -4,5 +4,5 @@
4
4
  = f.input :<%= attribute.name %>
5
5
  <%- end -%>
6
6
 
7
- = f.buttons do
8
- = f.commit_button
7
+ = f.actions do
8
+ = f.action :submit, as: :input
@@ -66,7 +66,21 @@
66
66
  # specifying that class here. Defaults to Formtastic::FormBuilder.
67
67
  # Formtastic::Helpers::FormHelper.builder = MyCustomBuilder
68
68
 
69
- # You can opt-in to Formtastic's use of the HTML5 `required` attribute on `<input>`, `<select>`
69
+ # All formtastic forms have a class that indicates that they are just that. You
70
+ # can change it to any class you want.
71
+ # Formtastic::Helpers::FormHelper.default_form_class = 'formtastic'
72
+
73
+ # Formtastic will infer a class name from the model, array, string ot symbol you pass to the
74
+ # form builder. You can customize the way that class is presented by overriding
75
+ # this proc.
76
+ # Formtastic::Helpers::FormHelper.default_form_model_class_proc = proc { |model_class_name| model_class_name }
77
+
78
+ # Allows to set a custom field_error_proc wrapper. By default this wrapper
79
+ # is disabled since `formtastic` already adds an error class to the LI tag
80
+ # containing the input.
81
+ # Formtastic::Helpers::FormHelper.formtastic_field_error_proc = proc { |html_tag, instance_tag| html_tag }
82
+
83
+ # You can opt-in to Formtastic's use of the HTML5 `required` attribute on `<input>`, `<select>`
70
84
  # and `<textarea>` tags by setting this to true (defaults to false).
71
85
  # Formtastic::FormBuilder.use_required_attribute = false
72
86
 
@@ -244,7 +244,7 @@ describe 'InputAction::Base' do
244
244
 
245
245
  describe 'when used on a new record' do
246
246
  before do
247
- @new_post.stub!(:new_record?).and_return(true)
247
+ @new_post.stub(:new_record?).and_return(true)
248
248
  end
249
249
 
250
250
  describe 'when explicit label is provided' do
@@ -344,7 +344,7 @@ describe 'InputAction::Base' do
344
344
 
345
345
  describe 'when used on an existing record' do
346
346
  before do
347
- @new_post.stub!(:persisted?).and_return(true)
347
+ @new_post.stub(:persisted?).and_return(true)
348
348
  end
349
349
 
350
350
  describe 'when explicit label is provided' do
@@ -466,7 +466,7 @@ describe 'InputAction::Base' do
466
466
  end
467
467
  @new_user_post = ::UserPost.new
468
468
 
469
- @new_user_post.stub!(:new_record?).and_return(true)
469
+ @new_user_post.stub(:new_record?).and_return(true)
470
470
  concat(semantic_form_for(@new_user_post, :url => '') do |builder|
471
471
  concat(builder.action(:submit, :as => :generic))
472
472
  concat(builder.action(:reset, :as => :generic))
@@ -47,7 +47,7 @@ describe 'Formtastic::Helpers::FormHelper.builder' do
47
47
  describe "when using a custom builder" do
48
48
 
49
49
  before do
50
- @new_post.stub!(:title)
50
+ @new_post.stub(:title)
51
51
  Formtastic::Helpers::FormHelper.builder = MyCustomFormBuilder
52
52
  end
53
53
 
@@ -72,9 +72,9 @@ describe 'Formtastic::Helpers::FormHelper.builder' do
72
72
 
73
73
  # See: https://github.com/justinfrench/formtastic/issues/657
74
74
  it "should not conflict with navigasmic" do
75
- stub!(:builder).and_return('navigasmic')
76
-
77
- lambda { semantic_form_for(@new_post) }.should_not raise_error(NoMethodError)
75
+ self.class.any_instance.stub(:builder).and_return('navigasmic')
76
+
77
+ lambda { semantic_form_for(@new_post) { |f| } }.should_not raise_error
78
78
  end
79
79
 
80
80
  end
@@ -82,8 +82,8 @@ describe 'Formtastic::Helpers::FormHelper.builder' do
82
82
  describe "fields_for" do
83
83
 
84
84
  it "should yield an instance of the parent form builder" do
85
- @new_post.stub!(:comment).and_return([@fred])
86
- @new_post.stub!(:comment_attributes=)
85
+ @new_post.stub(:comment).and_return([@fred])
86
+ @new_post.stub(:comment_attributes=)
87
87
  semantic_form_for(@new_post, :builder => MyCustomFormBuilder) do |builder|
88
88
  builder.class.should.kind_of?(MyCustomFormBuilder)
89
89
 
@@ -102,7 +102,7 @@ describe 'Formtastic::Helpers::FormHelper.builder' do
102
102
  describe "fields_for" do
103
103
 
104
104
  it "should yield an instance of the parent form builder" do
105
- @new_post.stub!(:author_attributes=)
105
+ @new_post.stub(:author_attributes=)
106
106
  semantic_form_for(@new_post, :builder => MyCustomFormBuilder) do |builder|
107
107
  builder.fields_for(:author) do |nested_builder|
108
108
  nested_builder.class.should.kind_of?(MyCustomFormBuilder)
@@ -8,7 +8,7 @@ describe 'Formtastic::FormBuilder#fields_for' do
8
8
  before do
9
9
  @output_buffer = ''
10
10
  mock_everything
11
- @new_post.stub!(:author).and_return(::Author.new)
11
+ @new_post.stub(:author).and_return(::Author.new)
12
12
  end
13
13
 
14
14
  context 'outside a form_for block' do
@@ -77,7 +77,7 @@ describe 'Formtastic::FormBuilder#fields_for' do
77
77
  end
78
78
 
79
79
  it 'should sanitize html id for li tag' do
80
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
80
+ @bob.stub(:column_for_attribute).and_return(double('column', :type => :string, :limit => 255))
81
81
  concat(semantic_form_for(@new_post) do |builder|
82
82
  concat(builder.semantic_fields_for(@bob, :index => 1) do |nested_builder|
83
83
  concat(nested_builder.inputs(:login))
@@ -90,7 +90,7 @@ describe 'Formtastic::FormBuilder#fields_for' do
90
90
  end
91
91
 
92
92
  it 'should use namespace provided in nested fields' do
93
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
93
+ @bob.stub(:column_for_attribute).and_return(double('column', :type => :string, :limit => 255))
94
94
  concat(semantic_form_for(@new_post, :namespace => 'context2') do |builder|
95
95
  concat(builder.semantic_fields_for(@bob, :index => 1) do |nested_builder|
96
96
  concat(nested_builder.inputs(:login))
@@ -100,9 +100,9 @@ describe 'Formtastic::FormBuilder#fields_for' do
100
100
  end
101
101
 
102
102
  it 'should render errors on the nested inputs' do
103
- @errors = mock('errors')
104
- @errors.stub!(:[]).with(errors_matcher(:login)).and_return(['oh noes'])
105
- @bob.stub!(:errors).and_return(@errors)
103
+ @errors = double('errors')
104
+ @errors.stub(:[]).with(errors_matcher(:login)).and_return(['oh noes'])
105
+ @bob.stub(:errors).and_return(@errors)
106
106
 
107
107
  concat(semantic_form_for(@new_post, :namespace => 'context2') do |builder|
108
108
  concat(builder.semantic_fields_for(@bob) do |nested_builder|
@@ -120,8 +120,8 @@ describe 'Formtastic::FormBuilder#fields_for' do
120
120
  output_buffer.replace ''
121
121
 
122
122
  @fred.posts.size.should == 1
123
- @fred.posts.first.stub!(:persisted?).and_return(true)
124
- @fred.stub!(:posts_attributes=)
123
+ @fred.posts.first.stub(:persisted?).and_return(true)
124
+ @fred.stub(:posts_attributes=)
125
125
  concat(semantic_form_for(@fred) do |builder|
126
126
  concat(builder.semantic_fields_for(:posts) do |nested_builder|
127
127
  concat(nested_builder.input(:id, :as => :hidden))
@@ -14,11 +14,11 @@ describe Formtastic::FormGenerator do
14
14
  @output_buffer = ''
15
15
  prepare_destination
16
16
  mock_everything
17
- ::Post.stub!(:reflect_on_all_associations).with(:belongs_to).and_return([
18
- mock('reflection', :name => :author, :options => {}, :klass => ::Author, :macro => :belongs_to),
19
- mock('reflection', :name => :reviewer, :options => {:class_name => 'Author'}, :klass => ::Author, :macro => :belongs_to),
20
- mock('reflection', :name => :main_post, :options => {}, :klass => ::Post, :macro => :belongs_to),
21
- mock('reflection', :name => :attachment, :options => {:polymorphic => true}, :macro => :belongs_to),
17
+ ::Post.stub(:reflect_on_all_associations).with(:belongs_to).and_return([
18
+ double('reflection', :name => :author, :options => {}, :klass => ::Author, :macro => :belongs_to),
19
+ double('reflection', :name => :reviewer, :options => {:class_name => 'Author'}, :klass => ::Author, :macro => :belongs_to),
20
+ double('reflection', :name => :main_post, :options => {}, :klass => ::Post, :macro => :belongs_to),
21
+ double('reflection', :name => :attachment, :options => {:polymorphic => true}, :macro => :belongs_to),
22
22
  ])
23
23
  end
24
24
 
@@ -34,7 +34,7 @@ describe Formtastic::FormGenerator do
34
34
 
35
35
  describe 'with existing model' do
36
36
  it 'should not raise an exception' do
37
- lambda { run_generator %w(Post) }.should_not raise_error(Thor::RequiredArgumentMissingError)
37
+ lambda { run_generator %w(Post) }.should_not raise_error
38
38
  end
39
39
  end
40
40
 
@@ -53,7 +53,7 @@ describe 'Formtastic::FormBuilder#action' do
53
53
  it 'should call the corresponding action class with .to_html' do
54
54
  [:input, :button, :link].each do |action_style|
55
55
  semantic_form_for(:project, :url => "http://test.host") do |builder|
56
- action_instance = mock('Action instance')
56
+ action_instance = double('Action instance')
57
57
  action_class = "#{action_style.to_s}_action".classify
58
58
  action_constant = "Formtastic::Actions::#{action_class}".constantize
59
59
 
@@ -99,7 +99,7 @@ describe 'Formtastic::FormBuilder#action' do
99
99
  # it 'should render a label with localized text and not apply the label_str_method' do
100
100
  # with_config :label_str_method, :reverse do
101
101
  # @localized_label_text = 'Localized title'
102
- # @new_post.stub!(:meta_description)
102
+ # @new_post.stub(:meta_description)
103
103
  # ::I18n.backend.store_translations :en,
104
104
  # :formtastic => {
105
105
  # :labels => {
@@ -132,7 +132,7 @@ describe 'Formtastic::FormBuilder#action' do
132
132
  #
133
133
  # describe 'and object is given' do
134
134
  # it 'should delegate the label logic to class human attribute name and pass it down to the label tag' do
135
- # @new_post.stub!(:meta_description) # a two word method name
135
+ # @new_post.stub(:meta_description) # a two word method name
136
136
  # @new_post.class.should_receive(:human_attribute_name).with('meta_description').and_return('meta_description'.humanize)
137
137
  #
138
138
  # concat(semantic_form_for(@new_post) do |builder|
@@ -145,7 +145,7 @@ describe 'Formtastic::FormBuilder#action' do
145
145
  # describe 'and object is given with label_str_method set to :capitalize' do
146
146
  # it 'should capitalize method name, passing it down to the label tag' do
147
147
  # with_config :label_str_method, :capitalize do
148
- # @new_post.stub!(:meta_description)
148
+ # @new_post.stub(:meta_description)
149
149
  #
150
150
  # concat(semantic_form_for(@new_post) do |builder|
151
151
  # concat(builder.input(:meta_description))
@@ -266,7 +266,7 @@ describe 'Formtastic::FormBuilder#action' do
266
266
  context 'when a customized top-level class does not exist' do
267
267
 
268
268
  it 'should instantiate the Formtastic action' do
269
- action = mock('action', :to_html => 'some HTML')
269
+ action = double('action', :to_html => 'some HTML')
270
270
  Formtastic::Actions::ButtonAction.should_receive(:new).and_return(action)
271
271
  concat(semantic_form_for(@new_post) do |builder|
272
272
  builder.action(:commit, :as => :button)
@@ -280,7 +280,7 @@ describe 'Formtastic::FormBuilder#action' do
280
280
  class ::ButtonAction < Formtastic::Actions::ButtonAction
281
281
  end
282
282
 
283
- action = mock('action', :to_html => 'some HTML')
283
+ action = double('action', :to_html => 'some HTML')
284
284
  Formtastic::Actions::ButtonAction.should_not_receive(:new)
285
285
  ::ButtonAction.should_receive(:new).and_return(action)
286
286
 
@@ -330,31 +330,31 @@ describe 'Formtastic::FormBuilder#action' do
330
330
  concat(semantic_form_for(@new_post) do |builder|
331
331
  concat(builder.action(:cancel, :as => :link))
332
332
  end)
333
- }.should_not raise_error(Formtastic::UnsupportedMethodForAction)
333
+ }.should_not raise_error
334
334
 
335
335
  lambda {
336
336
  concat(semantic_form_for(@new_post) do |builder|
337
337
  concat(builder.action(:submit, :as => :input))
338
338
  end)
339
- }.should_not raise_error(Formtastic::UnsupportedMethodForAction)
339
+ }.should_not raise_error
340
340
 
341
341
  lambda {
342
342
  concat(semantic_form_for(@new_post) do |builder|
343
343
  concat(builder.action(:submit, :as => :button))
344
344
  end)
345
- }.should_not raise_error(Formtastic::UnsupportedMethodForAction)
345
+ }.should_not raise_error
346
346
 
347
347
  lambda {
348
348
  concat(semantic_form_for(@new_post) do |builder|
349
349
  concat(builder.action(:reset, :as => :input))
350
350
  end)
351
- }.should_not raise_error(Formtastic::UnsupportedMethodForAction)
351
+ }.should_not raise_error
352
352
 
353
353
  lambda {
354
354
  concat(semantic_form_for(@new_post) do |builder|
355
355
  concat(builder.action(:reset, :as => :button))
356
356
  end)
357
- }.should_not raise_error(Formtastic::UnsupportedMethodForAction)
357
+ }.should_not raise_error
358
358
  end
359
359
 
360
360
  end
@@ -23,7 +23,7 @@ describe 'FormHelper' do
23
23
  end)
24
24
  output_buffer.should have_tag("form.formtastic")
25
25
  end
26
-
26
+
27
27
  it 'adds a "novalidate" attribute to the generated form when configured to do so' do
28
28
  with_config :perform_browser_validations, true do
29
29
  concat(semantic_form_for(@new_post, :url => '/hello') do |builder|
@@ -31,7 +31,7 @@ describe 'FormHelper' do
31
31
  output_buffer.should_not have_tag("form[@novalidate]")
32
32
  end
33
33
  end
34
-
34
+
35
35
  it 'omits a "novalidate" attribute to the generated form when configured to do so' do
36
36
  with_config :perform_browser_validations, false do
37
37
  concat(semantic_form_for(@new_post, :url => '/hello') do |builder|
@@ -62,7 +62,7 @@ describe 'FormHelper' do
62
62
  end)
63
63
  output_buffer.should have_tag("form.xyz")
64
64
  end
65
-
65
+
66
66
  it 'omits the leading spaces from the classes in the generated form when the default class is nil' do
67
67
  Formtastic::Helpers::FormHelper.default_form_class = nil
68
68
  concat(semantic_form_for(::Post.new, :as => :post, :url => '/hello') do |builder|
@@ -102,6 +102,17 @@ describe 'FormHelper' do
102
102
  output_buffer.should have_tag("form.namespaced_post")
103
103
  end
104
104
 
105
+ it 'adds a customized class to the generated form' do
106
+ Formtastic::Helpers::FormHelper.default_form_model_class_proc = lambda { |model_class_name| "#{model_class_name}_form" }
107
+ concat(semantic_form_for(@new_post, :url => '/hello') do |builder|
108
+ end)
109
+ output_buffer.should have_tag("form.post_form")
110
+
111
+ concat(semantic_form_for(:project, :url => '/hello') do |builder|
112
+ end)
113
+ output_buffer.should have_tag("form.project_form")
114
+ end
115
+
105
116
  describe 'allows :html options' do
106
117
  before(:each) do
107
118
  concat(semantic_form_for(@new_post, :url => '/hello', :html => { :id => "something-special", :class => "something-extra", :multipart => true }) do |builder|
@@ -142,7 +153,7 @@ describe 'FormHelper' do
142
153
  end
143
154
  end
144
155
 
145
- describe ActionView::Base.field_error_proc do
156
+ describe 'ActionView::Base.field_error_proc' do
146
157
  it 'is set to no-op wrapper by default' do
147
158
  semantic_form_for(@new_post, :url => '/hello') do |builder|
148
159
  ::ActionView::Base.field_error_proc.call("html", nil).should == "html"
@@ -150,21 +161,21 @@ describe 'FormHelper' do
150
161
  end
151
162
 
152
163
  it 'is set to the configured custom field_error_proc' do
153
- field_error_proc = mock()
154
- Formtastic::Helpers::FormHelper.field_error_proc = field_error_proc
164
+ field_error_proc = double()
165
+ Formtastic::Helpers::FormHelper.formtastic_field_error_proc = field_error_proc
155
166
  semantic_form_for(@new_post, :url => '/hello') do |builder|
156
167
  ::ActionView::Base.field_error_proc.should == field_error_proc
157
168
  end
158
169
  end
159
-
170
+
160
171
  it 'is restored to its original value after the form is rendered' do
161
- lambda do
162
- Formtastic::Helpers::FormHelper.field_error_proc = proc {""}
172
+ lambda do
173
+ Formtastic::Helpers::FormHelper.formtastic_field_error_proc = proc {""}
163
174
  semantic_form_for(@new_post, :url => '/hello') { |builder| }
164
175
  end.should_not change(::ActionView::Base, :field_error_proc)
165
176
  end
166
- end
167
-
177
+ end
178
+
168
179
  describe "with :builder option" do
169
180
  it "yields an instance of the given builder" do
170
181
  class MyAwesomeCustomBuilder < Formtastic::FormBuilder
@@ -9,9 +9,9 @@ describe 'Formtastic::FormBuilder#input' do
9
9
  @output_buffer = ''
10
10
  mock_everything
11
11
 
12
- @errors = mock('errors')
13
- @errors.stub!(:[]).and_return([])
14
- @new_post.stub!(:errors).and_return(@errors)
12
+ @errors = double('errors')
13
+ @errors.stub(:[]).and_return([])
14
+ @new_post.stub(:errors).and_return(@errors)
15
15
  end
16
16
 
17
17
  after do
@@ -72,7 +72,7 @@ describe 'Formtastic::FormBuilder#input' do
72
72
  end
73
73
 
74
74
  it 'should set and "optional" class also when there is presence validator' do
75
- @new_post.class.should_receive(:validators_on).with(:title).any_number_of_times.and_return([
75
+ @new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
76
76
  active_model_presence_validator([:title])
77
77
  ])
78
78
  concat(semantic_form_for(@new_post) do |builder|
@@ -112,20 +112,20 @@ describe 'Formtastic::FormBuilder#input' do
112
112
 
113
113
  describe 'and an object with :validators_on was given (ActiveModel, Active Resource)' do
114
114
  before do
115
- @new_post.stub!(:class).and_return(::PostModel)
115
+ @new_post.stub(:class).and_return(::PostModel)
116
116
  end
117
117
 
118
118
  after do
119
- @new_post.stub!(:class).and_return(::Post)
119
+ @new_post.stub(:class).and_return(::Post)
120
120
  end
121
121
  describe 'and validates_presence_of was called for the method' do
122
122
  it 'should be required' do
123
123
 
124
- @new_post.class.should_receive(:validators_on).with(:title).any_number_of_times.and_return([
124
+ @new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
125
125
  active_model_presence_validator([:title])
126
126
  ])
127
127
 
128
- @new_post.class.should_receive(:validators_on).with(:body).any_number_of_times.and_return([
128
+ @new_post.class.should_receive(:validators_on).with(:body).at_least(:once).and_return([
129
129
  active_model_presence_validator([:body], {:if => true})
130
130
  ])
131
131
 
@@ -139,7 +139,7 @@ describe 'Formtastic::FormBuilder#input' do
139
139
 
140
140
  it 'should be required when there is :on => :create option on create' do
141
141
  with_config :required_string, " required yo!" do
142
- @new_post.class.should_receive(:validators_on).with(:title).any_number_of_times.and_return([
142
+ @new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
143
143
  active_model_presence_validator([:title], {:on => :create})
144
144
  ])
145
145
  concat(semantic_form_for(@new_post) do |builder|
@@ -152,7 +152,7 @@ describe 'Formtastic::FormBuilder#input' do
152
152
 
153
153
  it 'should be required when there is :on => :save option on create' do
154
154
  with_config :required_string, " required yo!" do
155
- @new_post.class.should_receive(:validators_on).with(:title).any_number_of_times.and_return([
155
+ @new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
156
156
  active_model_presence_validator([:title], {:on => :save})
157
157
  ])
158
158
  concat(semantic_form_for(@new_post) do |builder|
@@ -165,7 +165,7 @@ describe 'Formtastic::FormBuilder#input' do
165
165
 
166
166
  it 'should be required when there is :on => :save option on update' do
167
167
  with_config :required_string, " required yo!" do
168
- @fred.class.should_receive(:validators_on).with(:login).any_number_of_times.and_return([
168
+ @fred.class.should_receive(:validators_on).with(:login).at_least(:once).and_return([
169
169
  active_model_presence_validator([:login], {:on => :save})
170
170
  ])
171
171
  concat(semantic_form_for(@fred) do |builder|
@@ -177,7 +177,7 @@ describe 'Formtastic::FormBuilder#input' do
177
177
  end
178
178
 
179
179
  it 'should not be required when there is :on => :create option on update' do
180
- @fred.class.should_receive(:validators_on).with(:login).any_number_of_times.and_return([
180
+ @fred.class.should_receive(:validators_on).with(:login).at_least(:once).and_return([
181
181
  active_model_presence_validator([:login], {:on => :create})
182
182
  ])
183
183
  concat(semantic_form_for(@fred) do |builder|
@@ -188,7 +188,7 @@ describe 'Formtastic::FormBuilder#input' do
188
188
  end
189
189
 
190
190
  it 'should not be required when there is :on => :update option on create' do
191
- @new_post.class.should_receive(:validators_on).with(:title).any_number_of_times.and_return([
191
+ @new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
192
192
  active_model_presence_validator([:title], {:on => :update})
193
193
  ])
194
194
  concat(semantic_form_for(@new_post) do |builder|
@@ -241,14 +241,14 @@ describe 'Formtastic::FormBuilder#input' do
241
241
 
242
242
  describe 'and validates_inclusion_of was called for the method' do
243
243
  it 'should be required' do
244
- @new_post.class.should_receive(:validators_on).with(:published).any_number_of_times.and_return([
244
+ @new_post.class.should_receive(:validators_on).with(:published).at_least(:once).and_return([
245
245
  active_model_inclusion_validator([:published], {:in => [false, true]})
246
246
  ])
247
247
  should_be_required(:tag => :published, :required => true)
248
248
  end
249
249
 
250
250
  it 'should not be required if allow_blank is true' do
251
- @new_post.class.should_receive(:validators_on).with(:published).any_number_of_times.and_return([
251
+ @new_post.class.should_receive(:validators_on).with(:published).at_least(:once).and_return([
252
252
  active_model_inclusion_validator([:published], {:in => [false, true], :allow_blank => true})
253
253
  ])
254
254
  should_be_required(:tag => :published, :required => false)
@@ -282,13 +282,13 @@ describe 'Formtastic::FormBuilder#input' do
282
282
  end
283
283
 
284
284
  def add_presence_validator(options)
285
- @new_post.class.stub!(:validators_on).with(options[:tag]).and_return([
285
+ @new_post.class.stub(:validators_on).with(options[:tag]).and_return([
286
286
  active_model_presence_validator([options[:tag]], options[:options])
287
287
  ])
288
288
  end
289
289
 
290
290
  def add_length_validator(options)
291
- @new_post.class.should_receive(:validators_on).with(options[:tag]).any_number_of_times {[
291
+ @new_post.class.should_receive(:validators_on).with(options[:tag]).at_least(:once) {[
292
292
  active_model_length_validator([options[:tag]], options[:options])
293
293
  ]}
294
294
  end
@@ -377,32 +377,32 @@ describe 'Formtastic::FormBuilder#input' do
377
377
  end
378
378
 
379
379
  it 'should default to a string for methods on objects that don\'t respond to "column_for_attribute"' do
380
- @new_post.stub!(:method_without_a_database_column)
381
- @new_post.stub!(:column_for_attribute).and_return(nil)
380
+ @new_post.stub(:method_without_a_database_column)
381
+ @new_post.stub(:column_for_attribute).and_return(nil)
382
382
  default_input_type(nil, :method_without_a_database_column).should == :string
383
383
  end
384
384
 
385
385
  it 'should default to :password for methods that don\'t have a column in the database but "password" is in the method name' do
386
- @new_post.stub!(:password_method_without_a_database_column)
387
- @new_post.stub!(:column_for_attribute).and_return(nil)
386
+ @new_post.stub(:password_method_without_a_database_column)
387
+ @new_post.stub(:column_for_attribute).and_return(nil)
388
388
  default_input_type(nil, :password_method_without_a_database_column).should == :password
389
389
  end
390
390
 
391
391
  it 'should default to :password for methods on objects that don\'t respond to "column_for_attribute" but "password" is in the method name' do
392
- @new_post.stub!(:password_method_without_a_database_column)
393
- @new_post.stub!(:column_for_attribute).and_return(nil)
392
+ @new_post.stub(:password_method_without_a_database_column)
393
+ @new_post.stub(:column_for_attribute).and_return(nil)
394
394
  default_input_type(nil, :password_method_without_a_database_column).should == :password
395
395
  end
396
396
 
397
397
  it 'should default to :number for "integer" column with name ending in "_id"' do
398
- @new_post.stub!(:aws_instance_id)
399
- @new_post.stub!(:column_for_attribute).with(:aws_instance_id).and_return(mock('column', :type => :integer))
398
+ @new_post.stub(:aws_instance_id)
399
+ @new_post.stub(:column_for_attribute).with(:aws_instance_id).and_return(double('column', :type => :integer))
400
400
  default_input_type(:integer, :aws_instance_id).should == :number
401
401
  end
402
402
 
403
403
  it 'should default to :select for associations' do
404
- @new_post.class.stub!(:reflect_on_association).with(:user_id).and_return(mock('ActiveRecord::Reflection::AssociationReflection'))
405
- @new_post.class.stub!(:reflect_on_association).with(:section_id).and_return(mock('ActiveRecord::Reflection::AssociationReflection'))
404
+ @new_post.class.stub(:reflect_on_association).with(:user_id).and_return(double('ActiveRecord::Reflection::AssociationReflection'))
405
+ @new_post.class.stub(:reflect_on_association).with(:section_id).and_return(double('ActiveRecord::Reflection::AssociationReflection'))
406
406
  default_input_type(:integer, :user_id).should == :select
407
407
  default_input_type(:integer, :section_id).should == :select
408
408
  end
@@ -473,11 +473,11 @@ describe 'Formtastic::FormBuilder#input' do
473
473
  describe 'defaulting to file column' do
474
474
  Formtastic::FormBuilder.file_methods.each do |method|
475
475
  it "should default to :file for attributes that respond to ##{method}" do
476
- column = mock('column')
476
+ column = double('column')
477
477
 
478
478
  Formtastic::FormBuilder.file_methods.each do |test|
479
479
  ### TODO: Check if this is ok
480
- column.stub!(method).with(test).and_return(method == test)
480
+ column.stub(method).with(test).and_return(method == test)
481
481
  end
482
482
 
483
483
  @new_post.should_receive(method).and_return(column)
@@ -493,10 +493,10 @@ describe 'Formtastic::FormBuilder#input' do
493
493
 
494
494
  it 'should call the corresponding input class with .to_html' do
495
495
  [:select, :time_zone, :radio, :date_select, :datetime_select, :time_select, :boolean, :check_boxes, :hidden, :string, :password, :number, :text, :file].each do |input_style|
496
- @new_post.stub!(:generic_column_name)
497
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
496
+ @new_post.stub(:generic_column_name)
497
+ @new_post.stub(:column_for_attribute).and_return(double('column', :type => :string, :limit => 255))
498
498
  semantic_form_for(@new_post) do |builder|
499
- input_instance = mock('Input instance')
499
+ input_instance = double('Input instance')
500
500
  input_class = "#{input_style.to_s}_input".classify
501
501
  input_constant = "Formtastic::Inputs::#{input_class}".constantize
502
502
 
@@ -542,7 +542,7 @@ describe 'Formtastic::FormBuilder#input' do
542
542
  it 'should render a label with localized text and not apply the label_str_method' do
543
543
  with_config :label_str_method, :reverse do
544
544
  @localized_label_text = 'Localized title'
545
- @new_post.stub!(:meta_description)
545
+ @new_post.stub(:meta_description)
546
546
  ::I18n.backend.store_translations :en,
547
547
  :formtastic => {
548
548
  :labels => {
@@ -575,7 +575,7 @@ describe 'Formtastic::FormBuilder#input' do
575
575
 
576
576
  describe 'and object is given' do
577
577
  it 'should delegate the label logic to class human attribute name and pass it down to the label tag' do
578
- @new_post.stub!(:meta_description) # a two word method name
578
+ @new_post.stub(:meta_description) # a two word method name
579
579
  @new_post.class.should_receive(:human_attribute_name).with('meta_description').and_return('meta_description'.humanize)
580
580
 
581
581
  concat(semantic_form_for(@new_post) do |builder|
@@ -588,7 +588,7 @@ describe 'Formtastic::FormBuilder#input' do
588
588
  describe 'and object is given with label_str_method set to :capitalize' do
589
589
  it 'should capitalize method name, passing it down to the label tag' do
590
590
  with_config :label_str_method, :capitalize do
591
- @new_post.stub!(:meta_description)
591
+ @new_post.stub(:meta_description)
592
592
 
593
593
  concat(semantic_form_for(@new_post) do |builder|
594
594
  concat(builder.input(:meta_description))
@@ -838,15 +838,15 @@ describe 'Formtastic::FormBuilder#input' do
838
838
  describe ':collection option' do
839
839
 
840
840
  it "should be required on polymorphic associations" do
841
- @new_post.stub!(:commentable)
842
- @new_post.class.stub!(:reflections).and_return({
843
- :commentable => mock('macro_reflection', :options => { :polymorphic => true }, :macro => :belongs_to)
841
+ @new_post.stub(:commentable)
842
+ @new_post.class.stub(:reflections).and_return({
843
+ :commentable => double('macro_reflection', :options => { :polymorphic => true }, :macro => :belongs_to)
844
844
  })
845
- @new_post.stub!(:column_for_attribute).with(:commentable).and_return(
846
- mock('column', :type => :integer)
845
+ @new_post.stub(:column_for_attribute).with(:commentable).and_return(
846
+ double('column', :type => :integer)
847
847
  )
848
- @new_post.class.stub!(:reflect_on_association).with(:commentable).and_return(
849
- mock('reflection', :macro => :belongs_to, :options => { :polymorphic => true })
848
+ @new_post.class.stub(:reflect_on_association).with(:commentable).and_return(
849
+ double('reflection', :macro => :belongs_to, :options => { :polymorphic => true })
850
850
  )
851
851
  expect {
852
852
  concat(semantic_form_for(@new_post) do |builder|
@@ -892,7 +892,7 @@ describe 'Formtastic::FormBuilder#input' do
892
892
  context 'when a customized top-level class does not exist' do
893
893
 
894
894
  it 'should instantiate the Formtastic input' do
895
- input = mock('input', :to_html => 'some HTML')
895
+ input = double('input', :to_html => 'some HTML')
896
896
  Formtastic::Inputs::StringInput.should_receive(:new).and_return(input)
897
897
  concat(semantic_form_for(@new_post) do |builder|
898
898
  builder.input(:title, :as => :string)
@@ -906,7 +906,7 @@ describe 'Formtastic::FormBuilder#input' do
906
906
  class ::StringInput < Formtastic::Inputs::StringInput
907
907
  end
908
908
 
909
- input = mock('input', :to_html => 'some HTML')
909
+ input = double('input', :to_html => 'some HTML')
910
910
  Formtastic::Inputs::StringInput.should_not_receive(:new)
911
911
  ::StringInput.should_receive(:new).and_return(input)
912
912