rspec-rails 2.8.0.rc1 → 2.8.0.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. data/License.txt +22 -0
  2. data/README.md +253 -119
  3. data/features/README.md +0 -2
  4. data/features/Upgrade.md +1 -1
  5. data/lib/generators/rspec/install/templates/spec/spec_helper.rb +1 -1
  6. data/lib/generators/rspec/integration/integration_generator.rb +1 -0
  7. data/lib/generators/rspec/scaffold/scaffold_generator.rb +1 -0
  8. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +23 -16
  9. data/lib/rspec/rails/adapters.rb +25 -13
  10. data/lib/rspec/rails/example/controller_example_group.rb +65 -122
  11. data/lib/rspec/rails/example/helper_example_group.rb +11 -36
  12. data/lib/rspec/rails/example/mailer_example_group.rb +1 -1
  13. data/lib/rspec/rails/example/rails_example_group.rb +5 -0
  14. data/lib/rspec/rails/example/request_example_group.rb +4 -19
  15. data/lib/rspec/rails/example/routing_example_group.rb +8 -10
  16. data/lib/rspec/rails/example/view_example_group.rb +21 -35
  17. data/lib/rspec/rails/extensions/active_record/base.rb +15 -12
  18. data/lib/rspec/rails/fixture_support.rb +1 -1
  19. data/lib/rspec/rails/matchers/be_a_new.rb +63 -30
  20. data/lib/rspec/rails/matchers/be_new_record.rb +18 -3
  21. data/lib/rspec/rails/matchers/have_extension.rb +26 -14
  22. data/lib/rspec/rails/matchers/redirect_to.rb +26 -7
  23. data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
  24. data/lib/rspec/rails/matchers/render_template.rb +27 -8
  25. data/lib/rspec/rails/matchers/routing_matchers.rb +72 -24
  26. data/lib/rspec/rails/mocks.rb +42 -34
  27. data/lib/rspec/rails/module_inclusion.rb +2 -1
  28. data/lib/rspec/rails/version.rb +1 -1
  29. data/lib/rspec/rails/view_assigns.rb +31 -34
  30. data/lib/rspec/rails/view_rendering.rb +10 -6
  31. data/spec/rspec/rails/example/controller_example_group_spec.rb +2 -2
  32. data/spec/rspec/rails/example/helper_example_group_spec.rb +5 -5
  33. data/spec/rspec/rails/example/view_example_group_spec.rb +5 -5
  34. data/spec/rspec/rails/matchers/be_a_new_spec.rb +2 -0
  35. data/spec/rspec/rails/matchers/be_new_record_spec.rb +2 -0
  36. data/spec/rspec/rails/matchers/render_template_spec.rb +3 -5
  37. data/spec/rspec/rails/mocks/mock_model_spec.rb +28 -0
  38. metadata +22 -19
@@ -1,30 +1,6 @@
1
1
  require 'rspec/rails/view_assigns'
2
2
 
3
3
  module RSpec::Rails
4
- # Extends ActionView::TestCase::Behavior
5
- #
6
- # == Examples
7
- #
8
- # describe RoleBasedDisplayHelper do
9
- # describe "display_for" do
10
- # context "given the role of the current user" do
11
- # it "yields to the block" do
12
- # helper.stub(:current_user) { double(:roles => ['admin'] }
13
- # text = helper.display_for('admin') { "this text" }
14
- # text.should eq("this text")
15
- # end
16
- # end
17
- #
18
- # context "given a different role that that of the current user" do
19
- # it "renders an empty String" do
20
- # helper.stub(:current_user) { double(:roles => ['manager'] }
21
- # text = helper.display_for('admin') { "this text" }
22
- # text.should eq("")
23
- # end
24
- # end
25
- # end
26
- # end
27
- #
28
4
  module HelperExampleGroup
29
5
  extend ActiveSupport::Concern
30
6
  include RSpec::Rails::RailsExampleGroup
@@ -32,26 +8,25 @@ module RSpec::Rails
32
8
  include RSpec::Rails::ViewAssigns
33
9
 
34
10
  module ClassMethods
11
+ # @api private
35
12
  def determine_default_helper_class(ignore)
36
- describes
13
+ described_class
37
14
  end
38
15
  end
39
16
 
40
- module InstanceMethods
41
- # Returns an instance of ActionView::Base with the helper being specified
42
- # mixed in, along with any of the built-in rails helpers.
43
- def helper
44
- _view.tap do |v|
45
- v.extend(ApplicationHelper) if defined?(ApplicationHelper)
46
- v.assign(view_assigns)
47
- end
17
+ # Returns an instance of ActionView::Base with the helper being specified
18
+ # mixed in, along with any of the built-in rails helpers.
19
+ def helper
20
+ _view.tap do |v|
21
+ v.extend(ApplicationHelper) if defined?(ApplicationHelper)
22
+ v.assign(view_assigns)
48
23
  end
24
+ end
49
25
 
50
26
  private
51
27
 
52
- def _controller_path
53
- example.example_group.describes.to_s.sub(/Helper/,'').underscore
54
- end
28
+ def _controller_path
29
+ example.example_group.described_class.to_s.sub(/Helper/,'').underscore
55
30
  end
56
31
 
57
32
  included do
@@ -14,7 +14,7 @@ if defined?(ActionMailer)
14
14
 
15
15
  module ClassMethods
16
16
  def mailer_class
17
- describes
17
+ described_class
18
18
  end
19
19
  end
20
20
  end
@@ -1,9 +1,14 @@
1
+ # Temporary workaround to resolve circular dependency between rspec-rails' spec
2
+ # suite and ammeter.
3
+ require 'rspec/rails/matchers'
4
+
1
5
  module RSpec
2
6
  module Rails
3
7
  module RailsExampleGroup
4
8
  extend ActiveSupport::Concern
5
9
  include RSpec::Rails::SetupAndTeardownAdapter
6
10
  include RSpec::Rails::TestUnitAssertionAdapter
11
+ include RSpec::Rails::Matchers
7
12
  end
8
13
  end
9
14
  end
@@ -1,32 +1,17 @@
1
1
  module RSpec::Rails
2
- # Extends ActionDispatch::Integration::Runner to work with RSpec.
3
- #
4
- # == Matchers
5
- #
6
- # In addition to the stock matchers from rspec-expectations, request
7
- # specs add these matchers, which delegate to rails' assertions:
8
- #
9
- # response.should render_template(*args)
10
- # => delegates to assert_template(*args)
11
- #
12
- # response.should redirect_to(destination)
13
- # => delegates to assert_redirected_to(destination)
14
2
  module RequestExampleGroup
15
3
  extend ActiveSupport::Concern
16
4
  include RSpec::Rails::RailsExampleGroup
17
5
  include ActionDispatch::Integration::Runner
18
6
  include ActionDispatch::Assertions
19
-
20
- module InstanceMethods
21
- def app
22
- ::Rails.application
23
- end
24
- end
25
-
26
7
  include RSpec::Rails::Matchers::RedirectTo
27
8
  include RSpec::Rails::Matchers::RenderTemplate
28
9
  include ActionController::TemplateAssertions
29
10
 
11
+ def app
12
+ ::Rails.application
13
+ end
14
+
30
15
  included do
31
16
  metadata[:type] = :request
32
17
 
@@ -8,16 +8,6 @@ module RSpec::Rails
8
8
  include RSpec::Rails::Matchers::RoutingMatchers
9
9
  include RSpec::Rails::Matchers::RoutingMatchers::RouteHelpers
10
10
 
11
- module InstanceMethods
12
- attr_reader :routes
13
-
14
- private
15
-
16
- def method_missing(m, *args, &block)
17
- routes.url_helpers.respond_to?(m) ? routes.url_helpers.send(m, *args) : super
18
- end
19
- end
20
-
21
11
  included do
22
12
  metadata[:type] = :routing
23
13
 
@@ -25,5 +15,13 @@ module RSpec::Rails
25
15
  @routes = ::Rails.application.routes
26
16
  end
27
17
  end
18
+
19
+ attr_reader :routes
20
+
21
+ private
22
+
23
+ def method_missing(m, *args, &block)
24
+ routes.url_helpers.respond_to?(m) ? routes.url_helpers.send(m, *args) : super
25
+ end
28
26
  end
29
27
  end
@@ -1,22 +1,6 @@
1
1
  require 'rspec/rails/view_assigns'
2
2
 
3
3
  module RSpec::Rails
4
- # Extends ActionView::TestCase::Behavior
5
- #
6
- # == Examples
7
- #
8
- # describe "widgets/index.html.erb" do
9
- # it "renders the @widgets" do
10
- # widgets = [
11
- # stub_model(Widget, :name => "Foo"),
12
- # stub_model(Widget, :name => "Bar")
13
- # ]
14
- # assign(:widgets, widgets)
15
- # render
16
- # rendered.should contain("Foo")
17
- # rendered.should contain("Bar")
18
- # end
19
- # end
20
4
  module ViewExampleGroup
21
5
  extend ActiveSupport::Concern
22
6
  include RSpec::Rails::RailsExampleGroup
@@ -39,7 +23,7 @@ module RSpec::Rails
39
23
  end
40
24
  end
41
25
 
42
- module InstanceMethods
26
+ module ExampleMethods
43
27
  # @overload render
44
28
  # @overload render({:partial => path_to_file})
45
29
  # @overload render({:partial => path_to_file}, {... locals ...})
@@ -51,27 +35,27 @@ module RSpec::Rails
51
35
  # The only addition is that you can call render with no arguments, and RSpec
52
36
  # will pass the top level description to render:
53
37
  #
54
- # describe "widgets/new.html.erb" do
55
- # it "shows all the widgets" do
56
- # render # => view.render(:file => "widgets/new.html.erb")
57
- # ...
38
+ # describe "widgets/new.html.erb" do
39
+ # it "shows all the widgets" do
40
+ # render # => view.render(:file => "widgets/new.html.erb")
41
+ # # ...
42
+ # end
58
43
  # end
59
- # end
60
44
  def render(options={}, local_assigns={}, &block)
61
45
  options = {:template => _default_file_to_render} if Hash === options and options.empty?
62
46
  super(options, local_assigns, &block)
63
47
  end
64
48
 
65
- # The instance of +ActionView::Base+ that is used to render the template.
66
- # Use this to stub methods _before_ calling +render+.
49
+ # The instance of `ActionView::Base` that is used to render the template.
50
+ # Use this to stub methods _before_ calling `render`.
67
51
  #
68
- # describe "widgets/new.html.erb" do
69
- # it "shows all the widgets" do
70
- # view.stub(:foo) { "foo" }
71
- # render
72
- # ...
52
+ # describe "widgets/new.html.erb" do
53
+ # it "shows all the widgets" do
54
+ # view.stub(:foo) { "foo" }
55
+ # render
56
+ # # ...
57
+ # end
73
58
  # end
74
- # end
75
59
  def view
76
60
  _view
77
61
  end
@@ -81,9 +65,9 @@ module RSpec::Rails
81
65
  # help isolate view examples from partials rendered by the view template
82
66
  # that is the subject of the example.
83
67
  #
84
- # == Example
68
+ # @example
85
69
  #
86
- # stub_template("widgets/_widget.html.erb" => "This content.")
70
+ # stub_template("widgets/_widget.html.erb" => "This content.")
87
71
  def stub_template(hash)
88
72
  view.view_paths.unshift(ActionView::FixtureResolver.new(hash))
89
73
  end
@@ -91,18 +75,18 @@ module RSpec::Rails
91
75
  # Provides access to the params hash that will be available within the
92
76
  # view:
93
77
  #
94
- # params[:foo] = 'bar'
78
+ # params[:foo] = 'bar'
95
79
  def params
96
80
  controller.params
97
81
  end
98
82
 
99
- # @deprecated # use +view+ instead.
83
+ # @deprecated Use `view` instead.
100
84
  def template
101
85
  RSpec.deprecate("template","view")
102
86
  view
103
87
  end
104
88
 
105
- # @deprecated # use +rendered+ instead.
89
+ # @deprecated Use `rendered` instead.
106
90
  def response
107
91
  RSpec.deprecate("response", "rendered")
108
92
  rendered
@@ -135,6 +119,8 @@ module RSpec::Rails
135
119
  end
136
120
 
137
121
  included do
122
+ include ExampleMethods
123
+
138
124
  metadata[:type] = :view
139
125
  helper *_default_helpers
140
126
 
@@ -3,12 +3,13 @@ module RSpec
3
3
  if defined?(ActiveRecord)
4
4
  module Extensions
5
5
  module ActiveRecord
6
- # Extension to enhance +should have+ on AR Model classes
6
+ # Extension to enhance `should have` on AR Model classes
7
7
  #
8
- # == Examples
9
- # ModelClass.should have(:no).records
10
- # ModelClass.should have(1).record
11
- # ModelClass.should have(n).records
8
+ # @example
9
+ #
10
+ # ModelClass.should have(:no).records
11
+ # ModelClass.should have(1).record
12
+ # ModelClass.should have(n).records
12
13
  def records
13
14
  find(:all)
14
15
  end
@@ -24,16 +25,18 @@ module RSpec
24
25
  end
25
26
 
26
27
  module ::ActiveModel::Validations
27
- # Extension to enhance <tt>should have</tt> on AR Model instances.
28
- # Calls model.valid? in order to prepare the object's errors
29
- # object.
28
+ # Extension to enhance `should have` on AR Model instances. Calls
29
+ # model.valid? in order to prepare the object's errors object.
30
+ #
31
+ # You can also use this to specify the content of the error messages.
30
32
  #
31
- # == Examples
33
+ # @example
32
34
  #
33
- # model.should have(:no).errors_on(:attribute)
34
- # model.should have(1).error_on(:attribute)
35
- # model.should have(n).errors_on(:attribute)
35
+ # model.should have(:no).errors_on(:attribute)
36
+ # model.should have(1).error_on(:attribute)
37
+ # model.should have(n).errors_on(:attribute)
36
38
  #
39
+ # model.errors_on(:attribute).should include("can't be blank")
37
40
  def errors_on(attribute)
38
41
  self.valid?
39
42
  [self.errors[attribute]].flatten.compact
@@ -1,6 +1,6 @@
1
1
  module RSpec
2
2
  module Rails
3
- if defined?(ActiveRecord)
3
+ if defined?(ActiveRecord::TestFixtures)
4
4
  module FixtureSupport
5
5
  extend ActiveSupport::Concern
6
6
 
@@ -1,40 +1,73 @@
1
- RSpec::Matchers.define :be_a_new do |model_klass|
2
- match do |actual|
3
- actual.is_a?(model_klass) && actual.new_record? && attributes_match?(actual)
4
- end
1
+ module RSpec::Rails::Matchers
2
+ class BeANew
3
+ include RSpec::Matchers::BaseMatcher
5
4
 
6
- chain :with do |expected_attributes|
7
- attributes.merge!(expected_attributes)
8
- end
5
+ # @api private
6
+ def matches?(actual)
7
+ super
8
+ actual.is_a?(expected) && actual.new_record? && attributes_match?(actual)
9
+ end
9
10
 
10
- failure_message_for_should do |actual|
11
- [].tap do |message|
12
- unless actual.is_a?(model_klass) && actual.new_record?
13
- message << "expected #{actual.inspect} to be a new #{model_klass.inspect}"
14
- end
15
- unless attributes_match?(actual)
16
- if unmatched_attributes.size > 1
17
- message << "attributes #{unmatched_attributes.inspect} were not set on #{actual.inspect}"
18
- else
19
- message << "attribute #{unmatched_attributes.inspect} was not set on #{actual.inspect}"
11
+ # Use this to specify the specific attributes to match on the new record.
12
+ #
13
+ # @example
14
+ #
15
+ # it "assigns a new Thing with the submitted attributes" do
16
+ # post :create, :thing => { :name => "Illegal Value" }
17
+ # assigns(:thing).should be_a_new(Thing).with(:name => nil)
18
+ # end
19
+ def with(expected_attributes)
20
+ attributes.merge!(expected_attributes)
21
+ self
22
+ end
23
+
24
+ # @api private
25
+ def failure_message_for_should
26
+ [].tap do |message|
27
+ unless actual.is_a?(expected) && actual.new_record?
28
+ message << "expected #{actual.inspect} to be a new #{expected.inspect}"
20
29
  end
21
- end
22
- end.join(' and ')
23
- end
30
+ unless attributes_match?(actual)
31
+ if unmatched_attributes.size > 1
32
+ message << "attributes #{unmatched_attributes.inspect} were not set on #{actual.inspect}"
33
+ else
34
+ message << "attribute #{unmatched_attributes.inspect} was not set on #{actual.inspect}"
35
+ end
36
+ end
37
+ end.join(' and ')
38
+ end
24
39
 
25
- def attributes
26
- @attributes ||= {}
27
- end
40
+ private
28
41
 
29
- def attributes_match?(actual)
30
- attributes.stringify_keys.all? do |key, value|
31
- actual.attributes[key].eql?(value)
42
+ def attributes
43
+ @attributes ||= {}
32
44
  end
33
- end
34
45
 
35
- def unmatched_attributes
36
- attributes.stringify_keys.reject do |key, value|
37
- actual.attributes[key].eql?(value)
46
+ def attributes_match?(actual)
47
+ attributes.stringify_keys.all? do |key, value|
48
+ actual.attributes[key].eql?(value)
49
+ end
38
50
  end
51
+
52
+ def unmatched_attributes
53
+ attributes.stringify_keys.reject do |key, value|
54
+ actual.attributes[key].eql?(value)
55
+ end
56
+ end
57
+ end
58
+
59
+ # Passes if actual is an instance of `model_class` and returns `false` for
60
+ # `persisted?`. Typically used to specify instance variables assigned to
61
+ # views by controller actions
62
+ #
63
+ # @example
64
+ #
65
+ # get :new
66
+ # assigns(:thing).should be_a_new(Thing)
67
+ #
68
+ # post :create, :thing => { :name => "Illegal Value" }
69
+ # assigns(:thing).should be_a_new(Thing).with(:name => nil)
70
+ def be_a_new(model_class)
71
+ BeANew.new(model_class)
39
72
  end
40
73
  end
@@ -1,5 +1,20 @@
1
- RSpec::Matchers.define :be_new_record do
2
- match do |actual|
3
- !actual.persisted?
1
+ module RSpec::Rails::Matchers
2
+ class BeANewRecord
3
+ include RSpec::Matchers::BaseMatcher
4
+
5
+ # @api private
6
+ def matches?(actual)
7
+ !actual.persisted?
8
+ end
9
+ end
10
+
11
+ # Passes if actual returns `false` for `persisted?`.
12
+ #
13
+ # @example
14
+ #
15
+ # get :new
16
+ # assigns(:thing).should be_new_record
17
+ def be_new_record
18
+ BeANewRecord.new
4
19
  end
5
20
  end