rspec-rails 2.8.0.rc1 → 2.8.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|