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.
- data/License.txt +22 -0
- data/README.md +253 -119
- data/features/README.md +0 -2
- data/features/Upgrade.md +1 -1
- data/lib/generators/rspec/install/templates/spec/spec_helper.rb +1 -1
- data/lib/generators/rspec/integration/integration_generator.rb +1 -0
- data/lib/generators/rspec/scaffold/scaffold_generator.rb +1 -0
- data/lib/generators/rspec/scaffold/templates/controller_spec.rb +23 -16
- data/lib/rspec/rails/adapters.rb +25 -13
- data/lib/rspec/rails/example/controller_example_group.rb +65 -122
- data/lib/rspec/rails/example/helper_example_group.rb +11 -36
- data/lib/rspec/rails/example/mailer_example_group.rb +1 -1
- data/lib/rspec/rails/example/rails_example_group.rb +5 -0
- data/lib/rspec/rails/example/request_example_group.rb +4 -19
- data/lib/rspec/rails/example/routing_example_group.rb +8 -10
- data/lib/rspec/rails/example/view_example_group.rb +21 -35
- data/lib/rspec/rails/extensions/active_record/base.rb +15 -12
- data/lib/rspec/rails/fixture_support.rb +1 -1
- data/lib/rspec/rails/matchers/be_a_new.rb +63 -30
- data/lib/rspec/rails/matchers/be_new_record.rb +18 -3
- data/lib/rspec/rails/matchers/have_extension.rb +26 -14
- data/lib/rspec/rails/matchers/redirect_to.rb +26 -7
- data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
- data/lib/rspec/rails/matchers/render_template.rb +27 -8
- data/lib/rspec/rails/matchers/routing_matchers.rb +72 -24
- data/lib/rspec/rails/mocks.rb +42 -34
- data/lib/rspec/rails/module_inclusion.rb +2 -1
- data/lib/rspec/rails/version.rb +1 -1
- data/lib/rspec/rails/view_assigns.rb +31 -34
- data/lib/rspec/rails/view_rendering.rb +10 -6
- data/spec/rspec/rails/example/controller_example_group_spec.rb +2 -2
- data/spec/rspec/rails/example/helper_example_group_spec.rb +5 -5
- data/spec/rspec/rails/example/view_example_group_spec.rb +5 -5
- data/spec/rspec/rails/matchers/be_a_new_spec.rb +2 -0
- data/spec/rspec/rails/matchers/be_new_record_spec.rb +2 -0
- data/spec/rspec/rails/matchers/render_template_spec.rb +3 -5
- data/spec/rspec/rails/mocks/mock_model_spec.rb +28 -0
- 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
|
-
|
13
|
+
described_class
|
37
14
|
end
|
38
15
|
end
|
39
16
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
53
|
-
|
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
|
@@ -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
|
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
|
-
#
|
55
|
-
#
|
56
|
-
#
|
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
|
66
|
-
# Use this to stub methods _before_ calling
|
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
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
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
|
-
#
|
68
|
+
# @example
|
85
69
|
#
|
86
|
-
#
|
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
|
-
#
|
78
|
+
# params[:foo] = 'bar'
|
95
79
|
def params
|
96
80
|
controller.params
|
97
81
|
end
|
98
82
|
|
99
|
-
# @deprecated
|
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
|
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
|
6
|
+
# Extension to enhance `should have` on AR Model classes
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
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
|
28
|
-
#
|
29
|
-
#
|
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
|
-
#
|
33
|
+
# @example
|
32
34
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
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,40 +1,73 @@
|
|
1
|
-
RSpec::Matchers
|
2
|
-
|
3
|
-
|
4
|
-
end
|
1
|
+
module RSpec::Rails::Matchers
|
2
|
+
class BeANew
|
3
|
+
include RSpec::Matchers::BaseMatcher
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
26
|
-
@attributes ||= {}
|
27
|
-
end
|
40
|
+
private
|
28
41
|
|
29
|
-
|
30
|
-
|
31
|
-
actual.attributes[key].eql?(value)
|
42
|
+
def attributes
|
43
|
+
@attributes ||= {}
|
32
44
|
end
|
33
|
-
end
|
34
45
|
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
2
|
-
|
3
|
-
|
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
|