rspec-rails 2.0.0.beta.19 → 2.0.0.beta.20
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/.gitignore +2 -1
- data/Gemfile +7 -0
- data/Gotchas.markdown +14 -0
- data/README.markdown +49 -9
- data/Rakefile +1 -2
- data/Upgrade.markdown +7 -0
- data/VERSION +1 -1
- data/features/controller_specs/anonymous_controller.feature +57 -19
- data/features/controller_specs/isolation_from_views.feature +2 -2
- data/features/controller_specs/readers.feature +1 -1
- data/features/controller_specs/render_views.feature +4 -4
- data/features/helper_specs/helper_spec.feature +53 -0
- data/features/mailer_specs/url_helpers.feature +2 -2
- data/features/matchers/new_record_matcher.feature +46 -1
- data/features/matchers/redirect_to_matcher.feature +41 -0
- data/features/matchers/render_template_matcher.feature +25 -0
- data/features/mocks/mock_model.feature +131 -0
- data/features/mocks/stub_model.feature +58 -0
- data/features/routing_specs/access_to_named_routes.feature +15 -0
- data/features/support/env.rb +1 -0
- data/features/view_specs/inferred_controller_path.feature +44 -0
- data/lib/generators/rspec/install/templates/spec/spec_helper.rb +4 -5
- data/lib/generators/rspec/scaffold/templates/routing_spec.rb +2 -2
- data/lib/rspec/rails.rb +1 -4
- data/lib/rspec/rails/adapters.rb +32 -6
- data/lib/rspec/rails/browser_simulators.rb +30 -0
- data/lib/rspec/rails/example.rb +2 -1
- data/lib/rspec/rails/example/controller_example_group.rb +36 -16
- data/lib/rspec/rails/example/helper_example_group.rb +8 -4
- data/lib/rspec/rails/example/mailer_example_group.rb +11 -2
- data/lib/rspec/rails/example/model_example_group.rb +1 -1
- data/lib/rspec/rails/example/rails_example_group.rb +11 -0
- data/lib/rspec/rails/example/request_example_group.rb +17 -6
- data/lib/rspec/rails/example/routing_example_group.rb +6 -1
- data/lib/rspec/rails/example/view_example_group.rb +18 -14
- data/lib/rspec/rails/matchers/be_a_new.rb +36 -1
- data/lib/rspec/rails/mocks.rb +9 -8
- data/lib/rspec/rails/tasks/rspec.rake +7 -0
- data/lib/rspec/rails/view_rendering.rb +8 -2
- data/rspec-rails.gemspec +21 -14
- data/spec/rspec/rails/assertion_adapter_spec.rb +28 -0
- data/spec/rspec/rails/example/helper_example_group_spec.rb +2 -0
- data/spec/rspec/rails/example/routing_example_group_spec.rb +17 -0
- data/spec/rspec/rails/example/view_rendering_spec.rb +56 -15
- data/spec/rspec/rails/matchers/be_a_new_spec.rb +98 -0
- data/spec/rspec/rails/matchers/errors_on_spec.rb +4 -4
- data/spec/rspec/rails/mocks/ar_classes.rb +17 -0
- data/spec/rspec/rails/mocks/stub_model_spec.rb +36 -15
- data/templates/Gemfile +2 -0
- metadata +23 -34
- data/lib/rspec/rails/monkey.rb +0 -1
- data/lib/rspec/rails/monkey/action_mailer/test_case.rb +0 -69
@@ -0,0 +1,41 @@
|
|
1
|
+
Feature: redirect_to matcher
|
2
|
+
|
3
|
+
The redirect_to matcher is used to specify that the redirect called
|
4
|
+
in the latest action ended with the intended behaviour. Essentially,
|
5
|
+
it delegates to "assert_redirect". For more info, please check out
|
6
|
+
the Rails documentation on this method.
|
7
|
+
|
8
|
+
It is available in controller specs (spec/controllers) and request
|
9
|
+
specs (spec/requests).
|
10
|
+
|
11
|
+
Scenario: redirect_to with four possible options
|
12
|
+
Given a file named "spec/controllers/widgets_controller_spec.rb" with:
|
13
|
+
"""
|
14
|
+
require "spec_helper"
|
15
|
+
|
16
|
+
describe WidgetsController do
|
17
|
+
|
18
|
+
describe "#create" do
|
19
|
+
subject { post :create, :widget => { :name => "Foo" } }
|
20
|
+
|
21
|
+
it "redirects to widget_url(@widget)" do
|
22
|
+
subject.should redirect_to(widget_url(assigns(:widget)))
|
23
|
+
end
|
24
|
+
|
25
|
+
it "redirects_to :action => :show" do
|
26
|
+
subject.should redirect_to :action => :show,
|
27
|
+
:id => assigns(:widget).id
|
28
|
+
end
|
29
|
+
|
30
|
+
it "redirects_to(@widget)" do
|
31
|
+
subject.should redirect_to(assigns(:widget))
|
32
|
+
end
|
33
|
+
|
34
|
+
it "redirects_to /widgets/:id" do
|
35
|
+
subject.should redirect_to("/widgets/#{assigns(:widget).id}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
"""
|
40
|
+
When I run "rspec spec/controllers/widgets_controller_spec.rb"
|
41
|
+
Then the output should contain "4 examples, 0 failures"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Feature: render_template matcher
|
2
|
+
|
3
|
+
This matcher just delegates to the Rails assertion method
|
4
|
+
"assert_template". For complete info on the available options,
|
5
|
+
please take a look at the Rails documentation.
|
6
|
+
|
7
|
+
This method is available in spec/controllers and spec/requests.
|
8
|
+
|
9
|
+
Scenario: render_template with three possible options
|
10
|
+
Given a file named "spec/controllers/gadgets_spec.rb" with:
|
11
|
+
"""
|
12
|
+
require "spec_helper"
|
13
|
+
|
14
|
+
describe GadgetsController do
|
15
|
+
describe "#index" do
|
16
|
+
subject { get :index }
|
17
|
+
|
18
|
+
specify { should render_template(:index) }
|
19
|
+
specify { should render_template("index") }
|
20
|
+
specify { should render_template("gadgets/index") }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
"""
|
24
|
+
When I run "rspec spec/controllers/gadgets_spec.rb"
|
25
|
+
Then the output should contain "3 examples, 0 failures"
|
@@ -0,0 +1,131 @@
|
|
1
|
+
Feature: mock_model
|
2
|
+
|
3
|
+
The mock_model method generates a test double object that acts like an
|
4
|
+
Active Model model. This is different from the stub_model method which
|
5
|
+
generates an instance of a real ActiveModel class.
|
6
|
+
|
7
|
+
The benefit of mock_model over stub_model is that its a true double, so the
|
8
|
+
examples are not dependent on the behaviour (or mis-behaviour), or even the
|
9
|
+
existence of any other code. If you're working on a controller spec and you
|
10
|
+
need a model that doesn't exist, you can pass mock_model a string and the
|
11
|
+
generated object will act as though its an instance of the class named by
|
12
|
+
that string.
|
13
|
+
|
14
|
+
Scenario: passing a string that represents a non-existent constant
|
15
|
+
Given a file named "spec/models/car_spec.rb" with:
|
16
|
+
"""
|
17
|
+
require "spec_helper"
|
18
|
+
|
19
|
+
describe "mock_model('Car') with no Car constant in existence" do
|
20
|
+
it "generates a constant" do
|
21
|
+
Object.const_defined?(:Car).should be_false
|
22
|
+
mock_model("Car")
|
23
|
+
Object.const_defined?(:Car).should be_true
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "generates an object that ..." do
|
27
|
+
it "returns the correct name" do
|
28
|
+
car = mock_model("Car")
|
29
|
+
car.class.name.should eq("Car")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "says it is a Car" do
|
33
|
+
car = mock_model("Car")
|
34
|
+
car.should be_a(Car)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
"""
|
39
|
+
When I run "rspec spec/models/car_spec.rb"
|
40
|
+
Then the output should contain "3 examples, 0 failures"
|
41
|
+
|
42
|
+
Scenario: passing a string that represents an existing constant
|
43
|
+
Given a file named "spec/models/widget_spec.rb" with:
|
44
|
+
"""
|
45
|
+
require "spec_helper"
|
46
|
+
|
47
|
+
describe Widget do
|
48
|
+
it "uses the existing constant" do
|
49
|
+
widget = mock_model("Widget")
|
50
|
+
widget.should be_a(Widget)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
"""
|
54
|
+
When I run "rspec spec/models/widget_spec.rb"
|
55
|
+
Then the output should contain "1 example, 0 failures"
|
56
|
+
|
57
|
+
Scenario: passing a class that does not extend ActiveModel::Naming
|
58
|
+
Given a file named "spec/models/string_spec.rb" with:
|
59
|
+
"""
|
60
|
+
require "spec_helper"
|
61
|
+
|
62
|
+
describe String do
|
63
|
+
it "raises" do
|
64
|
+
expect { mock_model(String) }.to raise_exception
|
65
|
+
end
|
66
|
+
end
|
67
|
+
"""
|
68
|
+
When I run "rspec spec/models/string_spec.rb"
|
69
|
+
Then the output should contain "1 example, 0 failures"
|
70
|
+
|
71
|
+
Scenario: passing an Active Record constant
|
72
|
+
Given a file named "spec/models/widget_spec.rb" with:
|
73
|
+
"""
|
74
|
+
require "spec_helper"
|
75
|
+
|
76
|
+
describe Widget do
|
77
|
+
let(:widget) { mock_model(Widget) }
|
78
|
+
|
79
|
+
it "is valid by default" do
|
80
|
+
widget.should be_valid
|
81
|
+
end
|
82
|
+
|
83
|
+
it "is not a new record by default" do
|
84
|
+
widget.should_not be_new_record
|
85
|
+
end
|
86
|
+
|
87
|
+
it "can be converted to a new record" do
|
88
|
+
widget.as_new_record.should be_new_record
|
89
|
+
end
|
90
|
+
|
91
|
+
it "sets :id to nil upon destroy" do
|
92
|
+
widget.destroy
|
93
|
+
widget.id.should be_nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
"""
|
97
|
+
When I run "rspec spec/models/widget_spec.rb"
|
98
|
+
Then the output should contain "4 examples, 0 failures"
|
99
|
+
|
100
|
+
Scenario: passing an Active Record constant with method stubs
|
101
|
+
Given a file named "spec/models/widget_spec.rb" with:
|
102
|
+
"""
|
103
|
+
require "spec_helper"
|
104
|
+
|
105
|
+
describe "mock_model(Widget) with stubs" do
|
106
|
+
let(:widget) do
|
107
|
+
mock_model Widget, :foo => "bar",
|
108
|
+
:save => true,
|
109
|
+
:update_attributes => false
|
110
|
+
end
|
111
|
+
|
112
|
+
it "supports stubs for methods that don't exist in ActiveModel or ActiveRecord" do
|
113
|
+
widget.foo.should eq("bar")
|
114
|
+
end
|
115
|
+
|
116
|
+
it "supports stubs for methods that do exist" do
|
117
|
+
widget.save.should eq(true)
|
118
|
+
widget.update_attributes.should be_false
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "#errors" do
|
122
|
+
context "with update_attributes => false" do
|
123
|
+
it "is not empty" do
|
124
|
+
widget.errors.should_not be_empty
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
"""
|
130
|
+
When I run "rspec spec/models/widget_spec.rb"
|
131
|
+
Then the output should contain "3 examples, 0 failures"
|
@@ -0,0 +1,58 @@
|
|
1
|
+
Feature: stub_model
|
2
|
+
|
3
|
+
The stub_model method generates an instance of a Active Model model.
|
4
|
+
|
5
|
+
While you can use stub_model in any example (model, view, controller,
|
6
|
+
helper), it is especially useful in view examples, which are inherently
|
7
|
+
more state-based than interaction-based.
|
8
|
+
|
9
|
+
Scenario: passing an Active Record constant with a hash of stubs
|
10
|
+
Given a file named "spec/models/widget_spec.rb" with:
|
11
|
+
"""
|
12
|
+
require "spec_helper"
|
13
|
+
|
14
|
+
describe "stub_model(Widget) with a hash of stubs" do
|
15
|
+
let(:widget) do
|
16
|
+
stub_model Widget, :id => 5, :random_attribute => true
|
17
|
+
end
|
18
|
+
|
19
|
+
it "stubs :id" do
|
20
|
+
widget.id.should eql(5)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "stubs :random_attribute" do
|
24
|
+
widget.random_attribute.should be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns false for new_record? if :id is set" do
|
28
|
+
widget.should_not be_new_record
|
29
|
+
end
|
30
|
+
|
31
|
+
it "can be converted to a new record" do
|
32
|
+
widget.as_new_record
|
33
|
+
widget.should be_new_record
|
34
|
+
end
|
35
|
+
end
|
36
|
+
"""
|
37
|
+
When I run "rspec spec/models/widget_spec.rb"
|
38
|
+
Then the output should contain "4 examples, 0 failures"
|
39
|
+
|
40
|
+
Scenario: passing an Active Record constant with a block of stubs
|
41
|
+
Given a file named "spec/models/widget_spec.rb" with:
|
42
|
+
"""
|
43
|
+
require "spec_helper"
|
44
|
+
|
45
|
+
describe "stub_model(Widget) with a block of stubs" do
|
46
|
+
let(:widget) do
|
47
|
+
stub_model Widget do |widget|
|
48
|
+
widget.id = 5
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it "stubs :id" do
|
53
|
+
widget.id.should eql(5)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
"""
|
57
|
+
When I run "rspec spec/models/widget_spec.rb"
|
58
|
+
Then the output should contain "1 example, 0 failures"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: access to named routes in routing specs
|
2
|
+
|
3
|
+
Scenario: access existing named route
|
4
|
+
Given a file named "spec/routing/widget_routes_spec.rb" with:
|
5
|
+
"""
|
6
|
+
require "spec_helper"
|
7
|
+
|
8
|
+
describe "routes to the widgets controller" do
|
9
|
+
it "routes a named route" do
|
10
|
+
{:get => new_widget_path}.should route_to(:controller => "widgets", :action => "new")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
"""
|
14
|
+
When I run "rspec spec"
|
15
|
+
Then the output should contain "1 example, 0 failures"
|
data/features/support/env.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
Feature: view spec infers controller path and action
|
2
|
+
|
3
|
+
Scenario: infer controller path
|
4
|
+
Given a file named "spec/views/widgets/new.html.erb_spec.rb" with:
|
5
|
+
"""
|
6
|
+
require "spec_helper"
|
7
|
+
|
8
|
+
describe "widgets/new.html.erb" do
|
9
|
+
it "infers the controller path" do
|
10
|
+
controller.request.path_parameters["controller"].should eq("widgets")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
"""
|
14
|
+
When I run "rspec spec/views"
|
15
|
+
Then the output should contain "1 example, 0 failures"
|
16
|
+
|
17
|
+
Scenario: infer action
|
18
|
+
Given a file named "spec/views/widgets/new.html.erb_spec.rb" with:
|
19
|
+
"""
|
20
|
+
require "spec_helper"
|
21
|
+
|
22
|
+
describe "widgets/new.html.erb" do
|
23
|
+
it "infers the controller path" do
|
24
|
+
controller.request.path_parameters["action"].should eq("new")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
"""
|
28
|
+
When I run "rspec spec/views"
|
29
|
+
Then the output should contain "1 example, 0 failures"
|
30
|
+
|
31
|
+
Scenario: do not infer action in a partial
|
32
|
+
Given a file named "spec/views/widgets/_form.html.erb_spec.rb" with:
|
33
|
+
"""
|
34
|
+
require "spec_helper"
|
35
|
+
|
36
|
+
describe "widgets/_form.html.erb" do
|
37
|
+
it "includes a link to new" do
|
38
|
+
controller.request.path_parameters["action"].should be_nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
"""
|
42
|
+
When I run "rspec spec/views"
|
43
|
+
Then the output should contain "1 example, 0 failures"
|
44
|
+
|
@@ -1,12 +1,11 @@
|
|
1
|
-
# This file is copied to
|
2
|
-
# from the project root directory.
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
3
2
|
ENV["RAILS_ENV"] ||= 'test'
|
4
3
|
require File.expand_path("../../config/environment", __FILE__)
|
5
4
|
require 'rspec/rails'
|
6
5
|
|
7
|
-
# Requires supporting files with custom matchers and macros, etc,
|
8
|
-
# in
|
9
|
-
Dir[
|
6
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
7
|
+
# in spec/support/ and its subdirectories.
|
8
|
+
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
10
9
|
|
11
10
|
RSpec.configure do |config|
|
12
11
|
# == Mock Framework
|
@@ -3,12 +3,12 @@ require "spec_helper"
|
|
3
3
|
describe <%= controller_class_name %>Controller do
|
4
4
|
describe "routing" do
|
5
5
|
|
6
|
-
|
6
|
+
<% unless options[:singleton] -%>
|
7
7
|
it "recognizes and generates #index" do
|
8
8
|
{ :get => "/<%= table_name %>" }.should route_to(:controller => "<%= table_name %>", :action => "index")
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
<% end -%>
|
12
12
|
it "recognizes and generates #new" do
|
13
13
|
{ :get => "/<%= table_name %>/new" }.should route_to(:controller => "<%= table_name %>", :action => "new")
|
14
14
|
end
|
data/lib/rspec/rails.rb
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
require 'webrat'
|
2
|
-
|
3
1
|
require 'rspec/core'
|
4
|
-
require 'rspec/rails/monkey'
|
5
2
|
require 'rspec/rails/extensions'
|
6
3
|
require 'rspec/rails/view_rendering'
|
7
4
|
require 'rspec/rails/adapters'
|
@@ -9,5 +6,5 @@ require 'rspec/rails/matchers'
|
|
9
6
|
require 'rspec/rails/fixture_support'
|
10
7
|
require 'rspec/rails/mocks'
|
11
8
|
require 'rspec/rails/module_inclusion'
|
9
|
+
require 'rspec/rails/browser_simulators'
|
12
10
|
require 'rspec/rails/example'
|
13
|
-
|
data/lib/rspec/rails/adapters.rb
CHANGED
@@ -15,21 +15,47 @@ module RSpec
|
|
15
15
|
methods.each {|method| after { send method } }
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
module InstanceMethods
|
20
|
+
def method_name
|
21
|
+
@example
|
22
|
+
end
|
23
|
+
end
|
18
24
|
end
|
19
25
|
|
20
26
|
module TestUnitAssertionAdapter
|
21
27
|
extend ActiveSupport::Concern
|
22
|
-
|
23
|
-
|
28
|
+
|
29
|
+
class AssertionDelegate
|
30
|
+
include Test::Unit::Assertions
|
24
31
|
end
|
25
32
|
|
26
|
-
|
33
|
+
module ClassMethods
|
34
|
+
def assertion_method_names
|
35
|
+
Test::Unit::Assertions.public_instance_methods.select{|m| m.to_s =~ /^assert/} +
|
36
|
+
[:build_message]
|
37
|
+
end
|
27
38
|
|
28
|
-
|
29
|
-
|
30
|
-
|
39
|
+
def define_assertion_delegators
|
40
|
+
assertion_method_names.each do |m|
|
41
|
+
class_eval <<-CODE
|
42
|
+
def #{m}(*args, &block)
|
43
|
+
assertion_delegate.send :#{m}, *args, &block
|
44
|
+
end
|
45
|
+
CODE
|
46
|
+
end
|
31
47
|
end
|
32
48
|
end
|
49
|
+
|
50
|
+
module InstanceMethods
|
51
|
+
def assertion_delegate
|
52
|
+
@assertion_delegate ||= AssertionDelegate.new
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
included do
|
57
|
+
define_assertion_delegators
|
58
|
+
end
|
33
59
|
end
|
34
60
|
end
|
35
61
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
begin
|
2
|
+
require 'capybara/rails'
|
3
|
+
rescue LoadError
|
4
|
+
end
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'webrat'
|
8
|
+
rescue LoadError
|
9
|
+
end
|
10
|
+
|
11
|
+
module RSpec
|
12
|
+
module Rails
|
13
|
+
module BrowserSimulators
|
14
|
+
extend ActiveSupport::Concern
|
15
|
+
|
16
|
+
def self.included(mod)
|
17
|
+
mod.instance_eval do
|
18
|
+
def webrat(&block)
|
19
|
+
block.call if defined?(Webrat)
|
20
|
+
end
|
21
|
+
|
22
|
+
def capybara(&block)
|
23
|
+
block.call if defined?(Capybara)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|