rspec-rails 2.0.0.beta.7 → 2.0.0.beta.8
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/README.markdown +23 -11
- data/VERSION +1 -1
- data/features/view_specs/view_spec.feature +53 -0
- data/lib/generators/rspec/install/templates/lib/tasks/rspec.rake +1 -1
- data/lib/generators/rspec/install/templates/spec/spec_helper.rb +2 -2
- data/lib/generators/rspec/scaffold/templates/controller_spec.rb +2 -2
- data/lib/rspec/rails.rb +2 -0
- data/lib/rspec/rails/adapters.rb +28 -0
- data/lib/rspec/rails/example/controller_example_group.rb +18 -39
- data/lib/rspec/rails/example/request_example_group.rb +13 -11
- data/lib/rspec/rails/example/view_example_group.rb +1 -1
- data/lib/rspec/rails/matchers.rb +2 -1
- data/lib/rspec/rails/mocks.rb +24 -11
- data/lib/rspec/rails/monkey.rb +2 -0
- data/lib/rspec/rails/monkey/action_controller/test_case.rb +199 -0
- data/lib/rspec/rails/monkey/active_support/notifications/fanout.rb +20 -0
- data/rspec-rails.gemspec +12 -7
- data/spec/rspec/rails/matchers/render_template_spec.rb +20 -3
- data/spec/rspec/rails/mocks/mock_model_spec.rb +39 -14
- metadata +12 -7
data/README.markdown
CHANGED
@@ -27,7 +27,7 @@ Configure:
|
|
27
27
|
|
28
28
|
Add this line to the Gemfile:
|
29
29
|
|
30
|
-
gem "rspec-rails", ">= 2.0.0.beta.
|
30
|
+
gem "rspec-rails", ">= 2.0.0.beta.8"
|
31
31
|
|
32
32
|
This will expose generators, including rspec:install. Now you can run:
|
33
33
|
|
@@ -44,8 +44,8 @@ doesn't work all that well yet.
|
|
44
44
|
Currently supported:
|
45
45
|
|
46
46
|
* each example runs in its own transaction
|
47
|
-
*
|
48
|
-
*
|
47
|
+
* configurable in Rspec.configure
|
48
|
+
* see generated spec/spec_helper.rb
|
49
49
|
* model specs in spec/models
|
50
50
|
* controller specs in spec/controllers
|
51
51
|
* no view isolation yet
|
@@ -71,14 +71,26 @@ Currently supported:
|
|
71
71
|
|
72
72
|
## Controller Specs
|
73
73
|
|
74
|
-
Controller specs live in spec/controllers, and
|
75
|
-
|
76
|
-
|
74
|
+
Controller specs live in spec/controllers, and mix in
|
75
|
+
ActionController::TestCase::Behavior. See the documentation
|
76
|
+
for ActionController::TestCase to see what facilities are
|
77
|
+
available from Rails.
|
77
78
|
|
78
|
-
|
79
|
-
get :show, {:id => '37'}, {'HTTP_ACCEPT' => Mime::JS}
|
79
|
+
You can use RSpec expectations/matchers or Test::Unit assertions.
|
80
80
|
|
81
|
-
|
81
|
+
In addition to what Rails offers, controller specs provide all
|
82
|
+
of rspec-core's matchers and the rspec-rails' specific matchers
|
83
|
+
as well.
|
84
|
+
|
85
|
+
## Matchers
|
86
|
+
|
87
|
+
### render_template
|
88
|
+
Delegates to Rails' assert_template:
|
89
|
+
|
90
|
+
response.should render_template("new")
|
91
|
+
|
92
|
+
### redirect_to
|
93
|
+
Delegates to assert_redirect
|
94
|
+
|
95
|
+
response.should redirect_to(widgets_path)
|
82
96
|
|
83
|
-
After a request is made, you set expectations on the `request` and `response`
|
84
|
-
objects.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.0.beta.
|
1
|
+
2.0.0.beta.8
|
@@ -0,0 +1,53 @@
|
|
1
|
+
Feature: view spec
|
2
|
+
|
3
|
+
View specs live in spec/views and render view templates in isolation.
|
4
|
+
|
5
|
+
Scenario: passing spec
|
6
|
+
Given a file named "spec/views/widgets/index.html.erb_spec.rb" with:
|
7
|
+
"""
|
8
|
+
require "spec_helper"
|
9
|
+
|
10
|
+
describe "widgets/index.html.erb" do
|
11
|
+
it "displays all the widgets" do
|
12
|
+
assign(:widgets, [
|
13
|
+
stub_model(Widget, :name => "slicer"),
|
14
|
+
stub_model(Widget, :name => "dicer")
|
15
|
+
])
|
16
|
+
|
17
|
+
render
|
18
|
+
|
19
|
+
response.should contain("slicer")
|
20
|
+
response.should contain("dicer")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
"""
|
24
|
+
When I run "rspec spec/views"
|
25
|
+
Then I should see "1 example, 0 failures"
|
26
|
+
|
27
|
+
Scenario: passing spec with before and nesting
|
28
|
+
Given a file named "spec/views/widgets/index.html.erb_spec.rb" with:
|
29
|
+
"""
|
30
|
+
require "spec_helper"
|
31
|
+
|
32
|
+
describe "widgets/index.html.erb" do
|
33
|
+
|
34
|
+
context "with 2 widgets" do
|
35
|
+
before(:each) do
|
36
|
+
assign(:widgets, [
|
37
|
+
stub_model(Widget, :name => "slicer"),
|
38
|
+
stub_model(Widget, :name => "dicer")
|
39
|
+
])
|
40
|
+
end
|
41
|
+
|
42
|
+
it "displays both widgets" do
|
43
|
+
render
|
44
|
+
|
45
|
+
response.should contain("slicer")
|
46
|
+
response.should contain("dicer")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
"""
|
51
|
+
When I run "rspec spec/views"
|
52
|
+
Then I should see "1 example, 0 failures"
|
53
|
+
|
@@ -28,7 +28,7 @@ end
|
|
28
28
|
|
29
29
|
Rake.application.instance_variable_get('@tasks').delete('default')
|
30
30
|
|
31
|
-
spec_prereq =
|
31
|
+
spec_prereq = Rails.root.join('config', 'database.yml').exist? ? "db:test:prepare" : :noop
|
32
32
|
task :noop do
|
33
33
|
end
|
34
34
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# This file is copied to ~/spec when you run 'ruby script/generate rspec'
|
2
2
|
# from the project root directory.
|
3
3
|
ENV["RAILS_ENV"] ||= 'test'
|
4
|
-
require File.dirname(__FILE__) + "/../config/environment" unless defined?(
|
4
|
+
require File.dirname(__FILE__) + "/../config/environment" unless defined?(Rails)
|
5
5
|
require 'rspec/rails'
|
6
6
|
|
7
7
|
# Requires supporting files with custom matchers and macros, etc,
|
@@ -20,5 +20,5 @@ Rspec.configure do |config|
|
|
20
20
|
|
21
21
|
# If you'd prefer not to run each of your examples within a transaction,
|
22
22
|
# uncomment the following line.
|
23
|
-
# config.use_transactional_examples false
|
23
|
+
# config.use_transactional_examples = false
|
24
24
|
end
|
@@ -66,7 +66,7 @@ describe <%= controller_class_name %>Controller do
|
|
66
66
|
it "re-renders the 'new' template" do
|
67
67
|
<%= stub! orm_class.build(class_name) %> { <%= mock_file_name(:save => false) %> }
|
68
68
|
post :create, :<%= file_name %> => {}
|
69
|
-
response.should render_template(
|
69
|
+
response.should render_template("new")
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -104,7 +104,7 @@ describe <%= controller_class_name %>Controller do
|
|
104
104
|
it "re-renders the 'edit' template" do
|
105
105
|
<%= stub! orm_class.find(class_name) %> { <%= mock_file_name(:update_attributes => false) %> }
|
106
106
|
put :update, :id => "1"
|
107
|
-
response.should render_template(
|
107
|
+
response.should render_template("edit")
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
data/lib/rspec/rails.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'test/unit/assertions'
|
3
|
+
|
4
|
+
module Rspec
|
5
|
+
module Rails
|
6
|
+
module SetupAndTeardownAdapter
|
7
|
+
def setup(*methods)
|
8
|
+
methods.each {|method| before { send method } }
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown(*methods)
|
12
|
+
methods.each {|method| after { send method } }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module TestUnitAssertionAdapter
|
17
|
+
extend ActiveSupport::Concern
|
18
|
+
|
19
|
+
included do
|
20
|
+
include Test::Unit::Assertions
|
21
|
+
|
22
|
+
before do
|
23
|
+
@_result = Struct.new(:add_assertion).new
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,53 +1,32 @@
|
|
1
|
-
require 'active_support/core_ext/class/attribute_accessors'
|
2
1
|
require 'action_controller'
|
3
|
-
require 'action_dispatch'
|
4
2
|
require 'webrat'
|
5
3
|
|
6
|
-
# Preliminary documentation (more to come ....):
|
7
|
-
#
|
8
|
-
# allow_forgery_protection is set to false
|
9
|
-
# - you can set it to true in a before(:each) block
|
10
|
-
# if you have a specific example that needs it, but
|
11
|
-
# be sure to restore it to false (or supply tokens
|
12
|
-
# to all of your example requests)
|
13
|
-
|
14
4
|
module ControllerExampleGroupBehaviour
|
15
|
-
|
16
|
-
include ActionDispatch::Integration::Runner
|
17
|
-
include Webrat::Matchers
|
18
|
-
include Webrat::Methods
|
19
|
-
include Rspec::Matchers
|
20
|
-
|
21
|
-
def self.setup(*args); end
|
22
|
-
def self.teardown(*args); end
|
5
|
+
extend ActiveSupport::Concern
|
23
6
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
mod.before do
|
28
|
-
@_result = Struct.new(:add_assertion).new
|
29
|
-
ActionController::Base.allow_forgery_protection = false
|
7
|
+
module ControllerClassReader
|
8
|
+
def controller_class
|
9
|
+
describes
|
30
10
|
end
|
31
11
|
end
|
32
12
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
13
|
+
included do
|
14
|
+
extend Rspec::Rails::SetupAndTeardownAdapter
|
15
|
+
include Rspec::Rails::TestUnitAssertionAdapter
|
16
|
+
include ActionController::TestCase::Behavior
|
17
|
+
extend ControllerClassReader
|
18
|
+
include Webrat::Matchers
|
19
|
+
include Webrat::Methods
|
20
|
+
include Rspec::Matchers
|
21
|
+
before do
|
22
|
+
@routes = ::Rails.application.routes
|
23
|
+
ActionController::Base.allow_forgery_protection = false
|
38
24
|
end
|
39
25
|
end
|
40
26
|
|
41
|
-
%w[get post put delete head].map do |method|
|
42
|
-
eval <<-CODE
|
43
|
-
def #{method}(*args)
|
44
|
-
@_action = args.shift
|
45
|
-
super '/', *args
|
46
|
-
end
|
47
|
-
CODE
|
48
|
-
end
|
49
|
-
|
50
27
|
Rspec.configure do |c|
|
51
|
-
c.include self, :example_group => {
|
28
|
+
c.include self, :example_group => {
|
29
|
+
:describes => lambda {|described| described < ActionController::Base }
|
30
|
+
}
|
52
31
|
end
|
53
32
|
end
|
@@ -2,15 +2,17 @@ require 'action_dispatch'
|
|
2
2
|
require 'webrat'
|
3
3
|
|
4
4
|
module RequestExampleGroupBehaviour
|
5
|
-
|
5
|
+
extend ActiveSupport::Concern
|
6
6
|
include ActionDispatch::Integration::Runner
|
7
|
-
include Webrat::Matchers
|
8
|
-
include Webrat::Methods
|
9
|
-
include Rspec::Matchers
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
included do
|
9
|
+
include Rspec::Rails::TestUnitAssertionAdapter
|
10
|
+
include ActionDispatch::Assertions
|
11
|
+
include Webrat::Matchers
|
12
|
+
include Webrat::Methods
|
13
|
+
include Rspec::Matchers
|
14
|
+
|
15
|
+
before do
|
14
16
|
@router = ::Rails.application.routes
|
15
17
|
end
|
16
18
|
end
|
@@ -19,14 +21,14 @@ module RequestExampleGroupBehaviour
|
|
19
21
|
::Rails.application
|
20
22
|
end
|
21
23
|
|
22
|
-
Webrat.configure do |config|
|
23
|
-
config.mode = :rack
|
24
|
-
end
|
25
|
-
|
26
24
|
def last_response
|
27
25
|
response
|
28
26
|
end
|
29
27
|
|
28
|
+
Webrat.configure do |config|
|
29
|
+
config.mode = :rack
|
30
|
+
end
|
31
|
+
|
30
32
|
Rspec.configure do |c|
|
31
33
|
c.include self, :example_group => { :file_path => /\bspec\/requests\// }
|
32
34
|
end
|
data/lib/rspec/rails/matchers.rb
CHANGED
@@ -13,7 +13,7 @@ end
|
|
13
13
|
|
14
14
|
begin
|
15
15
|
require "active_record"
|
16
|
-
rescue
|
16
|
+
rescue LoadError
|
17
17
|
|
18
18
|
end
|
19
19
|
|
@@ -25,6 +25,7 @@ end
|
|
25
25
|
|
26
26
|
Rspec::Matchers.define :render_template do |options, message|
|
27
27
|
match_unless_raises Test::Unit::AssertionFailedError do |_|
|
28
|
+
options = options.to_s if Symbol === options
|
28
29
|
assert_template options, message
|
29
30
|
end
|
30
31
|
end
|
data/lib/rspec/rails/mocks.rb
CHANGED
@@ -4,29 +4,42 @@ module Rspec
|
|
4
4
|
class IllegalDataAccessException < StandardError; end
|
5
5
|
|
6
6
|
module Mocks
|
7
|
+
|
8
|
+
module InstanceMethods
|
9
|
+
def valid?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
def as_new_record
|
14
|
+
self.stub(:id) { nil }
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def new_record?
|
19
|
+
!persisted?
|
20
|
+
end
|
21
|
+
|
22
|
+
def persisted?
|
23
|
+
!!id
|
24
|
+
end
|
25
|
+
end
|
7
26
|
|
8
27
|
# Creates a mock object instance for a +model_class+ with common
|
9
28
|
# methods stubbed out. Additional methods may be easily stubbed (via
|
10
29
|
# add_stubs) if +stubs+ is passed.
|
11
30
|
def mock_model(model_class, options_and_stubs = {})
|
12
|
-
id = options_and_stubs[:id]
|
31
|
+
id = options_and_stubs.has_key?(:id) ? options_and_stubs[:id] : next_id
|
13
32
|
options_and_stubs = options_and_stubs.reverse_merge({
|
14
33
|
:id => id,
|
15
|
-
:to_param => id.to_s,
|
16
|
-
:new_record? => false,
|
17
34
|
:destroyed? => false,
|
18
|
-
:marked_for_destruction? => false
|
19
|
-
:errors => stub("errors", :count => 0, :any? => false)
|
35
|
+
:marked_for_destruction? => false
|
20
36
|
})
|
21
37
|
derived_name = "#{model_class.name}_#{id}"
|
22
38
|
m = mock(derived_name, options_and_stubs)
|
39
|
+
m.extend InstanceMethods
|
40
|
+
m.extend ActiveModel::Conversion
|
41
|
+
m.stub(:errors) { ActiveModel::Errors.new(m) }
|
23
42
|
m.__send__(:__mock_proxy).instance_eval(<<-CODE, __FILE__, __LINE__)
|
24
|
-
def @object.as_new_record
|
25
|
-
self.stub(:id) { nil }
|
26
|
-
self.stub(:to_param) { nil }
|
27
|
-
self.stub(:new_record?) { true }
|
28
|
-
self
|
29
|
-
end
|
30
43
|
def @object.is_a?(other)
|
31
44
|
#{model_class}.ancestors.include?(other)
|
32
45
|
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'action_controller'
|
2
|
+
require 'action_controller/test_case'
|
3
|
+
|
4
|
+
module ActionController
|
5
|
+
# This has been merged to rails HEAD after the 3.0.0.beta.3 release (see
|
6
|
+
# https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/4433).
|
7
|
+
# Once 3.0.0.rc.1 comes out, we can remove it.
|
8
|
+
module TemplateAssertions
|
9
|
+
def teardown_subscriptions
|
10
|
+
ActiveSupport::Notifications.unsubscribe("action_view.render_template")
|
11
|
+
ActiveSupport::Notifications.unsubscribe("action_view.render_template!")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# The remainder of this file has yet to be merged to rails HEAD and is
|
16
|
+
# therefore merely speculative and hopeful.
|
17
|
+
class TestCase < ActiveSupport::TestCase
|
18
|
+
module Behavior
|
19
|
+
extend ActiveSupport::Concern
|
20
|
+
include ActionDispatch::TestProcess
|
21
|
+
|
22
|
+
attr_reader :response, :request
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
|
26
|
+
# Sets the controller class name. Useful if the name can't be inferred from test class.
|
27
|
+
# Expects +controller_class+ as a constant. Example: <tt>tests WidgetController</tt>.
|
28
|
+
def tests(controller_class)
|
29
|
+
self.controller_class = controller_class
|
30
|
+
end
|
31
|
+
|
32
|
+
def controller_class=(new_class)
|
33
|
+
prepare_controller_class(new_class) if new_class
|
34
|
+
write_inheritable_attribute(:controller_class, new_class)
|
35
|
+
end
|
36
|
+
|
37
|
+
def controller_class
|
38
|
+
if current_controller_class = read_inheritable_attribute(:controller_class)
|
39
|
+
current_controller_class
|
40
|
+
else
|
41
|
+
self.controller_class = determine_default_controller_class(name)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def determine_default_controller_class(name)
|
46
|
+
name.sub(/Test$/, '').constantize
|
47
|
+
rescue NameError
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def prepare_controller_class(new_class)
|
52
|
+
new_class.send :include, ActionController::TestCase::RaiseActionExceptions
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
# Executes a request simulating GET HTTP method and set/volley the response
|
58
|
+
def get(action, parameters = nil, session = nil, flash = nil)
|
59
|
+
process(action, parameters, session, flash, "GET")
|
60
|
+
end
|
61
|
+
|
62
|
+
# Executes a request simulating POST HTTP method and set/volley the response
|
63
|
+
def post(action, parameters = nil, session = nil, flash = nil)
|
64
|
+
process(action, parameters, session, flash, "POST")
|
65
|
+
end
|
66
|
+
|
67
|
+
# Executes a request simulating PUT HTTP method and set/volley the response
|
68
|
+
def put(action, parameters = nil, session = nil, flash = nil)
|
69
|
+
process(action, parameters, session, flash, "PUT")
|
70
|
+
end
|
71
|
+
|
72
|
+
# Executes a request simulating DELETE HTTP method and set/volley the response
|
73
|
+
def delete(action, parameters = nil, session = nil, flash = nil)
|
74
|
+
process(action, parameters, session, flash, "DELETE")
|
75
|
+
end
|
76
|
+
|
77
|
+
# Executes a request simulating HEAD HTTP method and set/volley the response
|
78
|
+
def head(action, parameters = nil, session = nil, flash = nil)
|
79
|
+
process(action, parameters, session, flash, "HEAD")
|
80
|
+
end
|
81
|
+
|
82
|
+
def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
|
83
|
+
@request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
|
84
|
+
@request.env['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
|
85
|
+
returning __send__(request_method, action, parameters, session, flash) do
|
86
|
+
@request.env.delete 'HTTP_X_REQUESTED_WITH'
|
87
|
+
@request.env.delete 'HTTP_ACCEPT'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
alias xhr :xml_http_request
|
91
|
+
|
92
|
+
def process(action, parameters = nil, session = nil, flash = nil, http_method = 'GET')
|
93
|
+
# Sanity check for required instance variables so we can give an
|
94
|
+
# understandable error message.
|
95
|
+
%w(@routes @controller @request @response).each do |iv_name|
|
96
|
+
if !(instance_variable_names.include?(iv_name) || instance_variable_names.include?(iv_name.to_sym)) || instance_variable_get(iv_name).nil?
|
97
|
+
raise "#{iv_name} is nil: make sure you set it in your test's setup method."
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
@request.recycle!
|
102
|
+
@response.recycle!
|
103
|
+
@controller.response_body = nil
|
104
|
+
@controller.formats = nil
|
105
|
+
@controller.params = nil
|
106
|
+
|
107
|
+
@html_document = nil
|
108
|
+
@request.env['REQUEST_METHOD'] = http_method
|
109
|
+
|
110
|
+
parameters ||= {}
|
111
|
+
@request.assign_parameters(@routes, @controller.class.name.underscore.sub(/_controller$/, ''), action.to_s, parameters)
|
112
|
+
|
113
|
+
@request.session = ActionController::TestSession.new(session) unless session.nil?
|
114
|
+
@request.session["flash"] = @request.flash.update(flash || {})
|
115
|
+
@request.session["flash"].sweep
|
116
|
+
|
117
|
+
@controller.request = @request
|
118
|
+
@controller.params.merge!(parameters)
|
119
|
+
build_request_uri(action, parameters)
|
120
|
+
Base.class_eval { include Testing }
|
121
|
+
@controller.process_with_new_base_test(@request, @response)
|
122
|
+
@request.session.delete('flash') if @request.session['flash'].blank?
|
123
|
+
@response
|
124
|
+
end
|
125
|
+
|
126
|
+
def setup_controller_request_and_response
|
127
|
+
@request = TestRequest.new
|
128
|
+
@response = TestResponse.new
|
129
|
+
|
130
|
+
if klass = self.class.controller_class
|
131
|
+
@controller ||= klass.new rescue nil
|
132
|
+
end
|
133
|
+
|
134
|
+
@request.env.delete('PATH_INFO')
|
135
|
+
|
136
|
+
if @controller
|
137
|
+
@controller.request = @request
|
138
|
+
@controller.params = {}
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Cause the action to be rescued according to the regular rules for rescue_action when the visitor is not local
|
143
|
+
def rescue_action_in_public!
|
144
|
+
@request.remote_addr = '208.77.188.166' # example.com
|
145
|
+
end
|
146
|
+
|
147
|
+
included do
|
148
|
+
include ActionController::TemplateAssertions
|
149
|
+
include ActionDispatch::Assertions
|
150
|
+
setup :setup_controller_request_and_response
|
151
|
+
end
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
def build_request_uri(action, parameters)
|
156
|
+
unless @request.env["PATH_INFO"]
|
157
|
+
options = @controller.__send__(:url_options).merge(parameters)
|
158
|
+
options.update(
|
159
|
+
:only_path => true,
|
160
|
+
:action => action,
|
161
|
+
:relative_url_root => nil,
|
162
|
+
:_path_segments => @request.symbolized_path_parameters)
|
163
|
+
|
164
|
+
url, query_string = @routes.url_for(options).split("?", 2)
|
165
|
+
|
166
|
+
@request.env["SCRIPT_NAME"] = @controller.config.relative_url_root
|
167
|
+
@request.env["PATH_INFO"] = url
|
168
|
+
@request.env["QUERY_STRING"] = query_string || ""
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline
|
174
|
+
# (bystepping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular
|
175
|
+
# rescue_action process takes place. This means you can test your rescue_action code by setting remote_addr to something else
|
176
|
+
# than 0.0.0.0.
|
177
|
+
#
|
178
|
+
# The exception is stored in the exception accessor for further inspection.
|
179
|
+
module RaiseActionExceptions
|
180
|
+
def self.included(base)
|
181
|
+
base.class_eval do
|
182
|
+
attr_accessor :exception
|
183
|
+
protected :exception, :exception=
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
protected
|
188
|
+
def rescue_action_without_handler(e)
|
189
|
+
self.exception = e
|
190
|
+
|
191
|
+
if request.remote_addr == "0.0.0.0"
|
192
|
+
raise(e)
|
193
|
+
else
|
194
|
+
super(e)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'active_support/notifications/fanout'
|
2
|
+
|
3
|
+
# This has been merged to rails HEAD after the 3.0.0.beta.3 release (see
|
4
|
+
# https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/4433).
|
5
|
+
# Once 3.0.0.rc.1 comes out, we can remove it.
|
6
|
+
class ActiveSupport::Notifications::Fanout
|
7
|
+
def unsubscribe(subscriber_or_name)
|
8
|
+
@listeners_for.clear
|
9
|
+
@subscribers.reject! do |s|
|
10
|
+
s.instance_eval do
|
11
|
+
case subscriber_or_name
|
12
|
+
when String
|
13
|
+
@pattern && @pattern =~ subscriber_or_name
|
14
|
+
when self
|
15
|
+
true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/rspec-rails.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rspec-rails}
|
8
|
-
s.version = "2.0.0.beta.
|
8
|
+
s.version = "2.0.0.beta.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["David Chelimsky", "Chad Humphries"]
|
12
|
-
s.date = %q{2010-04-
|
12
|
+
s.date = %q{2010-04-27}
|
13
13
|
s.description = %q{Rspec-2 for Rails-3}
|
14
14
|
s.email = %q{dchelimsky@gmail.com;chad.humphries@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
"features/model_specs/transactional_examples.feature",
|
27
27
|
"features/step_definitions/model_steps.rb",
|
28
28
|
"features/support/env.rb",
|
29
|
+
"features/view_specs/view_spec.feature",
|
29
30
|
"lib/autotest/rails_rspec2.rb",
|
30
31
|
"lib/generators/rspec.rb",
|
31
32
|
"lib/generators/rspec/controller/controller_generator.rb",
|
@@ -59,6 +60,7 @@ Gem::Specification.new do |s|
|
|
59
60
|
"lib/generators/rspec/view/view_generator.rb",
|
60
61
|
"lib/rspec-rails.rb",
|
61
62
|
"lib/rspec/rails.rb",
|
63
|
+
"lib/rspec/rails/adapters.rb",
|
62
64
|
"lib/rspec/rails/example.rb",
|
63
65
|
"lib/rspec/rails/example/controller_example_group.rb",
|
64
66
|
"lib/rspec/rails/example/mailer_example_group.rb",
|
@@ -66,6 +68,9 @@ Gem::Specification.new do |s|
|
|
66
68
|
"lib/rspec/rails/example/view_example_group.rb",
|
67
69
|
"lib/rspec/rails/matchers.rb",
|
68
70
|
"lib/rspec/rails/mocks.rb",
|
71
|
+
"lib/rspec/rails/monkey.rb",
|
72
|
+
"lib/rspec/rails/monkey/action_controller/test_case.rb",
|
73
|
+
"lib/rspec/rails/monkey/active_support/notifications/fanout.rb",
|
69
74
|
"lib/rspec/rails/transactional_database_support.rb",
|
70
75
|
"lib/rspec/rails/version.rb",
|
71
76
|
"rspec-rails.gemspec",
|
@@ -84,7 +89,7 @@ Gem::Specification.new do |s|
|
|
84
89
|
s.homepage = %q{http://github.com/rspec/rspec-rails}
|
85
90
|
s.post_install_message = %q{**************************************************
|
86
91
|
|
87
|
-
Thank you for installing rspec-rails-2.0.0.beta.
|
92
|
+
Thank you for installing rspec-rails-2.0.0.beta.8!
|
88
93
|
|
89
94
|
This version of rspec-rails only works with
|
90
95
|
versions of rails >= 3.0.0.pre.
|
@@ -99,7 +104,7 @@ Gem::Specification.new do |s|
|
|
99
104
|
s.require_paths = ["lib"]
|
100
105
|
s.rubyforge_project = %q{rspec}
|
101
106
|
s.rubygems_version = %q{1.3.6}
|
102
|
-
s.summary = %q{rspec-rails-2.0.0.beta.
|
107
|
+
s.summary = %q{rspec-rails-2.0.0.beta.8}
|
103
108
|
s.test_files = [
|
104
109
|
"spec/rspec/rails/matchers/be_a_new_spec.rb",
|
105
110
|
"spec/rspec/rails/matchers/redirect_to_spec.rb",
|
@@ -116,14 +121,14 @@ Gem::Specification.new do |s|
|
|
116
121
|
s.specification_version = 3
|
117
122
|
|
118
123
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
119
|
-
s.add_runtime_dependency(%q<rspec>, ["= 2.0.0.beta.
|
124
|
+
s.add_runtime_dependency(%q<rspec>, ["= 2.0.0.beta.8"])
|
120
125
|
s.add_runtime_dependency(%q<webrat>, [">= 0.7.0"])
|
121
126
|
else
|
122
|
-
s.add_dependency(%q<rspec>, ["= 2.0.0.beta.
|
127
|
+
s.add_dependency(%q<rspec>, ["= 2.0.0.beta.8"])
|
123
128
|
s.add_dependency(%q<webrat>, [">= 0.7.0"])
|
124
129
|
end
|
125
130
|
else
|
126
|
-
s.add_dependency(%q<rspec>, ["= 2.0.0.beta.
|
131
|
+
s.add_dependency(%q<rspec>, ["= 2.0.0.beta.8"])
|
127
132
|
s.add_dependency(%q<webrat>, [">= 0.7.0"])
|
128
133
|
end
|
129
134
|
end
|
@@ -1,8 +1,25 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe "render_template" do
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
context "given a hash" do
|
5
|
+
it "delegates to assert_template" do
|
6
|
+
self.should_receive(:assert_template).with({:this => "hash"}, "this message")
|
7
|
+
"response".should render_template({:this => "hash"}, "this message")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "given a string" do
|
12
|
+
it "delegates to assert_template" do
|
13
|
+
self.should_receive(:assert_template).with("this string", "this message")
|
14
|
+
"response".should render_template("this string", "this message")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "given a string" do
|
19
|
+
it "converts to_s and delegates to assert_template" do
|
20
|
+
self.should_receive(:assert_template).with("template_name", "this message")
|
21
|
+
"response".should render_template(:template_name, "this message")
|
22
|
+
end
|
7
23
|
end
|
8
24
|
end
|
25
|
+
|
@@ -52,6 +52,25 @@ describe "mock_model" do
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
context "with id nil" do
|
56
|
+
it "is not persisted" do
|
57
|
+
mock_model(MockableModel, :id => nil).should_not be_persisted
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "valid?" do
|
62
|
+
context "default" do
|
63
|
+
it "returns true" do
|
64
|
+
mock_model(MockableModel).should be_valid
|
65
|
+
end
|
66
|
+
end
|
67
|
+
context "stubbed with false" do
|
68
|
+
it "returns false" do
|
69
|
+
mock_model(MockableModel, :valid? => false).should_not be_valid
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
55
74
|
describe "as association", :type => :view do
|
56
75
|
before(:each) do
|
57
76
|
@real = AssociatedModel.create!
|
@@ -68,20 +87,7 @@ describe "mock_model" do
|
|
68
87
|
end
|
69
88
|
end
|
70
89
|
|
71
|
-
describe "
|
72
|
-
before(:each) do
|
73
|
-
@model = mock_model(MockableModel, :null_object => true, :mocked_method => "mocked")
|
74
|
-
end
|
75
|
-
|
76
|
-
it "should be able to mock methods" do
|
77
|
-
@model.mocked_method.should == "mocked"
|
78
|
-
end
|
79
|
-
it "should return itself to unmocked methods" do
|
80
|
-
@model.unmocked_method.should equal(@model)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
describe "#as_null_object", :type => :view do
|
90
|
+
describe "#as_null_object" do
|
85
91
|
before(:each) do
|
86
92
|
@model = mock_model(MockableModel, :mocked_method => "mocked").as_null_object
|
87
93
|
end
|
@@ -108,7 +114,26 @@ describe "mock_model" do
|
|
108
114
|
mock_model(MockableModel).as_new_record.to_param.should be(nil)
|
109
115
|
end
|
110
116
|
end
|
117
|
+
|
118
|
+
describe "ActiveModel Lint tests" do
|
119
|
+
require 'test/unit/assertions'
|
120
|
+
require 'active_model/lint'
|
121
|
+
include Test::Unit::Assertions
|
122
|
+
include ActiveModel::Lint::Tests
|
123
|
+
|
124
|
+
ActiveModel::Lint::Tests.public_instance_methods.grep(/^test/).each do |m|
|
125
|
+
example m.gsub('_',' ') do
|
126
|
+
send m
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def model
|
131
|
+
mock_model(MockableModel, :id => nil)
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
111
135
|
end
|
112
136
|
|
113
137
|
|
114
138
|
|
139
|
+
|
metadata
CHANGED
@@ -7,8 +7,8 @@ version: !ruby/object:Gem::Version
|
|
7
7
|
- 0
|
8
8
|
- 0
|
9
9
|
- beta
|
10
|
-
-
|
11
|
-
version: 2.0.0.beta.
|
10
|
+
- 8
|
11
|
+
version: 2.0.0.beta.8
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- David Chelimsky
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2010-04-
|
20
|
+
date: 2010-04-27 00:00:00 -05:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|
@@ -32,8 +32,8 @@ dependencies:
|
|
32
32
|
- 0
|
33
33
|
- 0
|
34
34
|
- beta
|
35
|
-
-
|
36
|
-
version: 2.0.0.beta.
|
35
|
+
- 8
|
36
|
+
version: 2.0.0.beta.8
|
37
37
|
type: :runtime
|
38
38
|
version_requirements: *id001
|
39
39
|
- !ruby/object:Gem::Dependency
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- features/model_specs/transactional_examples.feature
|
70
70
|
- features/step_definitions/model_steps.rb
|
71
71
|
- features/support/env.rb
|
72
|
+
- features/view_specs/view_spec.feature
|
72
73
|
- lib/autotest/rails_rspec2.rb
|
73
74
|
- lib/generators/rspec.rb
|
74
75
|
- lib/generators/rspec/controller/controller_generator.rb
|
@@ -102,6 +103,7 @@ files:
|
|
102
103
|
- lib/generators/rspec/view/view_generator.rb
|
103
104
|
- lib/rspec-rails.rb
|
104
105
|
- lib/rspec/rails.rb
|
106
|
+
- lib/rspec/rails/adapters.rb
|
105
107
|
- lib/rspec/rails/example.rb
|
106
108
|
- lib/rspec/rails/example/controller_example_group.rb
|
107
109
|
- lib/rspec/rails/example/mailer_example_group.rb
|
@@ -109,6 +111,9 @@ files:
|
|
109
111
|
- lib/rspec/rails/example/view_example_group.rb
|
110
112
|
- lib/rspec/rails/matchers.rb
|
111
113
|
- lib/rspec/rails/mocks.rb
|
114
|
+
- lib/rspec/rails/monkey.rb
|
115
|
+
- lib/rspec/rails/monkey/action_controller/test_case.rb
|
116
|
+
- lib/rspec/rails/monkey/active_support/notifications/fanout.rb
|
112
117
|
- lib/rspec/rails/transactional_database_support.rb
|
113
118
|
- lib/rspec/rails/version.rb
|
114
119
|
- rspec-rails.gemspec
|
@@ -130,7 +135,7 @@ licenses: []
|
|
130
135
|
post_install_message: |
|
131
136
|
**************************************************
|
132
137
|
|
133
|
-
Thank you for installing rspec-rails-2.0.0.beta.
|
138
|
+
Thank you for installing rspec-rails-2.0.0.beta.8!
|
134
139
|
|
135
140
|
This version of rspec-rails only works with
|
136
141
|
versions of rails >= 3.0.0.pre.
|
@@ -167,7 +172,7 @@ rubyforge_project: rspec
|
|
167
172
|
rubygems_version: 1.3.6
|
168
173
|
signing_key:
|
169
174
|
specification_version: 3
|
170
|
-
summary: rspec-rails-2.0.0.beta.
|
175
|
+
summary: rspec-rails-2.0.0.beta.8
|
171
176
|
test_files:
|
172
177
|
- spec/rspec/rails/matchers/be_a_new_spec.rb
|
173
178
|
- spec/rspec/rails/matchers/redirect_to_spec.rb
|