rspec-rails 1.2.7.1 → 1.2.9

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 (67) hide show
  1. data/Contribute.rdoc +4 -0
  2. data/History.rdoc +26 -1
  3. data/Manifest.txt +2 -3
  4. data/Rakefile +16 -15
  5. data/TODO.txt +2 -3
  6. data/Upgrade.rdoc +34 -0
  7. data/generators/integration_spec/templates/integration_spec.rb +1 -1
  8. data/generators/rspec/rspec_generator.rb +0 -1
  9. data/generators/rspec/templates/rspec.rake +1 -39
  10. data/generators/rspec/templates/spec_helper.rb +5 -2
  11. data/generators/rspec_controller/rspec_controller_generator.rb +2 -0
  12. data/generators/rspec_controller/templates/controller_spec.rb +1 -1
  13. data/generators/rspec_controller/templates/helper_spec.rb +1 -1
  14. data/generators/rspec_controller/templates/view_spec.rb +1 -1
  15. data/generators/rspec_model/templates/model_spec.rb +1 -1
  16. data/generators/rspec_scaffold/templates/controller_spec.rb +1 -1
  17. data/generators/rspec_scaffold/templates/edit_erb_spec.rb +1 -1
  18. data/generators/rspec_scaffold/templates/helper_spec.rb +1 -1
  19. data/generators/rspec_scaffold/templates/index_erb_spec.rb +1 -1
  20. data/generators/rspec_scaffold/templates/new_erb_spec.rb +1 -1
  21. data/generators/rspec_scaffold/templates/routing_spec.rb +16 -46
  22. data/generators/rspec_scaffold/templates/show_erb_spec.rb +1 -1
  23. data/lib/spec/rails/example/controller_example_group.rb +12 -1
  24. data/lib/spec/rails/example/routing_helpers.rb +16 -20
  25. data/lib/spec/rails/extensions/action_controller/rescue.rb +2 -2
  26. data/lib/spec/rails/extensions/action_controller/test_case.rb +1 -1
  27. data/lib/spec/rails/matchers.rb +1 -0
  28. data/lib/spec/rails/matchers/render_template.rb +8 -2
  29. data/lib/spec/rails/matchers/route_to.rb +149 -0
  30. data/lib/spec/rails/version.rb +3 -3
  31. data/spec/autotest/mappings_spec.rb +1 -1
  32. data/spec/resources/controllers/controller_spec_controller.rb +5 -1
  33. data/spec/resources/controllers/render_spec_controller.rb +4 -0
  34. data/spec/spec/rails/example/assigns_hash_proxy_spec.rb +1 -1
  35. data/spec/spec/rails/example/configuration_spec.rb +1 -1
  36. data/spec/spec/rails/example/controller_example_group_spec.rb +15 -7
  37. data/spec/spec/rails/example/controller_isolation_spec.rb +22 -9
  38. data/spec/spec/rails/example/cookies_proxy_spec.rb +1 -1
  39. data/spec/spec/rails/example/error_handling_spec.rb +1 -1
  40. data/spec/spec/rails/example/example_group_factory_spec.rb +1 -1
  41. data/spec/spec/rails/example/helper_example_group_spec.rb +2 -2
  42. data/spec/spec/rails/example/model_example_group_spec.rb +1 -1
  43. data/spec/spec/rails/example/routing_example_group_spec.rb +3 -2
  44. data/spec/spec/rails/example/shared_routing_example_group_examples.rb +224 -31
  45. data/spec/spec/rails/example/test_unit_assertion_accessibility_spec.rb +1 -1
  46. data/spec/spec/rails/example/view_example_group_spec.rb +1 -1
  47. data/spec/spec/rails/extensions/action_view_base_spec.rb +1 -1
  48. data/spec/spec/rails/extensions/active_record_spec.rb +1 -1
  49. data/spec/spec/rails/interop/testcase_spec.rb +1 -1
  50. data/spec/spec/rails/matchers/ar_be_valid_spec.rb +11 -37
  51. data/spec/spec/rails/matchers/assert_select_spec.rb +1 -1
  52. data/spec/spec/rails/matchers/errors_on_spec.rb +1 -1
  53. data/spec/spec/rails/matchers/have_text_spec.rb +1 -1
  54. data/spec/spec/rails/matchers/include_text_spec.rb +1 -1
  55. data/spec/spec/rails/matchers/redirect_to_spec.rb +1 -1
  56. data/spec/spec/rails/matchers/render_template_spec.rb +8 -1
  57. data/spec/spec/rails/matchers/should_change_spec.rb +1 -1
  58. data/spec/spec/rails/mocks/mock_model_spec.rb +1 -1
  59. data/spec/spec/rails/mocks/stub_model_spec.rb +1 -1
  60. data/spec/spec/rails/sample_modified_fixture.rb +1 -1
  61. data/spec/spec/rails/sample_spec.rb +1 -1
  62. data/spec/spec/rails/spec_spec.rb +1 -1
  63. data/spec/spec_helper.rb +23 -24
  64. metadata +11 -12
  65. data/generators/rspec/templates/script/spec_server +0 -9
  66. data/lib/spec/rails/spec_server.rb +0 -135
  67. data/spec/spec/rails/spec_server_spec.rb +0 -108
@@ -1,38 +1,34 @@
1
+ require 'rack/utils'
2
+
1
3
  module Spec
2
4
  module Rails
3
5
  module Example
4
6
  module RoutingHelpers
5
7
 
6
- module ParamsFromQueryString # :nodoc:
7
- def params_from_querystring(querystring) # :nodoc:
8
- params = {}
9
- querystring.split('&').each do |piece|
10
- key, value = piece.split('=')
11
- params[key.to_sym] = value
12
- end
13
- params
14
- end
15
- end
16
-
17
8
  class RouteFor
18
- include ::Spec::Rails::Example::RoutingHelpers::ParamsFromQueryString
19
9
  def initialize(example, options)
20
10
  @example, @options = example, options
21
11
  end
22
-
12
+
23
13
  def ==(expected)
24
14
  if Hash === expected
25
15
  path, querystring = expected[:path].split('?')
16
+ path_string = path
26
17
  path = expected.merge(:path => path)
27
18
  else
28
19
  path, querystring = expected.split('?')
20
+ path_string = path
21
+ path = { :path => path, :method => :get }
22
+ end
23
+ params = querystring.blank? ? {} : Rack::Utils.parse_query(querystring).symbolize_keys!
24
+ begin
25
+ @example.assert_routing(path, @options, {}, params)
26
+ true
27
+ rescue ActionController::RoutingError, ::Test::Unit::AssertionFailedError => e
28
+ raise e.class, "#{e}\nIf you're expecting this failure, we suggest {:#{path[:method]}=>\"#{path[:path]}\"}.should_not be_routable"
29
29
  end
30
- params = querystring.blank? ? {} : @example.params_from_querystring(querystring)
31
- @example.assert_recognizes(@options, path, params)
32
- true
33
30
  end
34
31
  end
35
-
36
32
  # Uses ActionController::Routing::Routes to generate
37
33
  # the correct route for a given set of options.
38
34
  # == Examples
@@ -46,6 +42,8 @@ module Spec
46
42
 
47
43
  # Uses ActionController::Routing::Routes to parse
48
44
  # an incoming path so the parameters it generates can be checked
45
+ #
46
+ # Note that this method is obsoleted by the route_to matcher.
49
47
  # == Example
50
48
  # params_from(:get, '/registrations/1/edit')
51
49
  # => :controller => 'registrations', :action => 'edit', :id => '1'
@@ -53,13 +51,11 @@ module Spec
53
51
  ensure_that_routes_are_loaded
54
52
  path, querystring = path.split('?')
55
53
  params = ActionController::Routing::Routes.recognize_path(path, :method => method)
56
- querystring.blank? ? params : params.merge(params_from_querystring(querystring))
54
+ querystring.blank? ? params : params.merge(Rack::Utils.parse_query(querystring).symbolize_keys!)
57
55
  end
58
56
 
59
57
  private
60
58
 
61
- include ParamsFromQueryString
62
-
63
59
  def ensure_that_routes_are_loaded
64
60
  ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty?
65
61
  end
@@ -9,7 +9,7 @@ rspec-rails.
9
9
  Use rescue_action_in_public!, which is defined directly in
10
10
  rails' testing framework, instead.
11
11
  WARNING
12
- if Rails::VERSION::STRING =~ /^2\.0/
12
+ if ::Rails::VERSION::STRING =~ /^2\.0/
13
13
  @use_rails_error_handling = true
14
14
  else
15
15
  # anything but 0.0.0.0 - borrowed from rails own rescue_action_in_public!
@@ -23,7 +23,7 @@ WARNING
23
23
 
24
24
  protected
25
25
 
26
- if Rails::VERSION::STRING =~ /^2\.0/
26
+ if ::Rails::VERSION::STRING =~ /^2\.0/
27
27
  def rescue_action_in_public?
28
28
  request.respond_to?(:rescue_action_in_public?) and request.rescue_action_in_public?
29
29
  end
@@ -2,7 +2,7 @@ module ActionController
2
2
  class TestCase
3
3
  include ::Spec::Rails::Example::RoutingHelpers
4
4
 
5
- if Rails::VERSION::STRING =~ /2\.0/
5
+ if ::Rails::VERSION::STRING =~ /2\.0/
6
6
  # Introduced in Rails 2.1, but we need it for 2.0
7
7
  def rescue_action_in_public!
8
8
  # See rescue.rb in this same directory
@@ -5,6 +5,7 @@ require 'spec/rails/matchers/change'
5
5
  require 'spec/rails/matchers/have_text'
6
6
  require 'spec/rails/matchers/include_text'
7
7
  require 'spec/rails/matchers/redirect_to'
8
+ require 'spec/rails/matchers/route_to'
8
9
  require 'spec/rails/matchers/render_template'
9
10
 
10
11
  module Spec
@@ -14,7 +14,9 @@ module Spec
14
14
  response_or_controller.response :
15
15
  response_or_controller
16
16
 
17
- if response.respond_to?(:rendered_file)
17
+ if response.respond_to?(:redirect?) && response.redirect?
18
+ @redirect_url = response.redirect_url
19
+ elsif response.respond_to?(:rendered_file)
18
20
  @actual = response.rendered_file
19
21
  elsif response.respond_to?(:rendered)
20
22
  case template = response.rendered[:template]
@@ -46,7 +48,11 @@ module Spec
46
48
  end
47
49
 
48
50
  def failure_message_for_should
49
- "expected #{@expected.inspect}, got #{@actual.inspect}"
51
+ if @redirect_url
52
+ "expected #{@expected.inspect}, got redirected to #{@redirect_url.inspect}"
53
+ else
54
+ "expected #{@expected.inspect}, got #{@actual.inspect}"
55
+ end
50
56
  end
51
57
 
52
58
  def failure_message_for_should_not
@@ -0,0 +1,149 @@
1
+ require 'rack/utils'
2
+
3
+ module Spec
4
+ module Rails
5
+ module Matchers
6
+ USAGE = ArgumentError.new( 'usage: { :method => "path" }.should route_to( :controller => "controller", :action => "action", [ args ] )' )
7
+
8
+ class PathDecomposer
9
+ def self.decompose_path(path)
10
+ method, path = if Hash === path
11
+ raise USAGE if path.keys.size > 1
12
+ path.entries.first
13
+ else
14
+ [:get, path]
15
+ end
16
+ path, querystring = path.split('?')
17
+ return method, path, querystring
18
+ end
19
+ end
20
+
21
+ class RouteTo #:nodoc:
22
+ def initialize(expected, example)
23
+ @route, @example = expected,example
24
+ end
25
+
26
+ def matches?(path)
27
+ begin
28
+ @actual = path
29
+ method, path, querystring = PathDecomposer.decompose_path(path)
30
+ params = querystring.blank? ? {} : Rack::Utils.parse_query(querystring).symbolize_keys!
31
+ @example.assert_routing({ :method => method, :path => path }, @route, {}, params)
32
+ true
33
+ rescue ActionController::RoutingError, ::Test::Unit::AssertionFailedError, ActionController::MethodNotAllowed => e
34
+ raise e.class, "#{e}\nIf you're expecting this failure, we suggest { :#{method} => \"#{path}\" }.should_not be_routable"
35
+ rescue Exception => e
36
+ raise e.class, "#{e}\n#{e.backtrace.join( "\n" )}"
37
+ end
38
+ end
39
+
40
+ def does_not_match(path)
41
+ raise ArgumentError, "Don't test a negative route like this."
42
+ end
43
+
44
+ def failure_message_for_should
45
+ "Expected #{@expected.inspect} to route to #{@actual.inspect}, but it didn't.\n"+
46
+ "In this case, we expected you to get an exception. So this message probably means something weird happened."
47
+ end
48
+
49
+ def failure_message_for_should_not
50
+ "Expected a routing error, but the route passed instead. \nNote, when expecting routes to fail, you should use 'should_not be_routable' instead."
51
+ end
52
+
53
+ def description
54
+ "route to #{@expected.inspect}"
55
+ end
56
+
57
+ private
58
+ attr_reader :expected
59
+ attr_reader :actual
60
+
61
+ end
62
+
63
+ # :call-seq:
64
+ # "path".should route_to(expected) # assumes GET
65
+ # { :get => "path" }.should route_to(expected)
66
+ # { :put => "path" }.should route_to(expected)
67
+ #
68
+ # Uses ActionController::Routing::Routes to verify that
69
+ # the path-and-method routes to a given set of options.
70
+ # Also verifies route-generation, so that the expected options
71
+ # do generate a pathname consisten with the indicated path/method.
72
+ #
73
+ # For negative tests, only the route recognition failure can be
74
+ # tested; since route generation via path_to() will always generate
75
+ # a path as requested. Use .should_not be_routable() in this case.
76
+ #
77
+ # == Examples
78
+ # { :get => '/registrations/1/edit' }.
79
+ # should route_to(:controller => 'registrations', :action => 'edit', :id => '1')
80
+ # { :put => "/registrations/1" }.should
81
+ # route_to(:controller => 'registrations', :action => 'update', :id => 1)
82
+ # { :post => "/registrations/" }.should
83
+ # route_to(:controller => 'registrations', :action => 'create')
84
+
85
+ def route_to(expected)
86
+ RouteTo.new(expected, self)
87
+ end
88
+
89
+ class BeRoutable
90
+ def initialize(example)
91
+ @example = example
92
+ end
93
+
94
+ def matches?(path)
95
+ begin
96
+ @actual = path
97
+ method, path = PathDecomposer.decompose_path(path)
98
+ @example.assert_recognizes({}, { :method => method, :path => path }, {} )
99
+ true
100
+ rescue ActionController::RoutingError, ActionController::MethodNotAllowed
101
+ false
102
+ rescue ::Test::Unit::AssertionFailedError => e
103
+ # the second thingy will always be "<{}>" becaues of the way we called assert_recognizes({}...) above.
104
+ e.to_s =~ /<(.*)> did not match <\{\}>/ and @actual_place = $1 or raise
105
+ true
106
+ end
107
+ end
108
+ def failure_message_for_should
109
+ "Expected '#{@actual.keys.first.to_s.upcase} #{@actual.values.first}' to be routable, but it wasn't.\n"+
110
+ "To really test routability, we recommend #{@actual.inspect}.\n"+
111
+ " should route_to( :action => 'action', :controller => 'controller' )\n\n"+
112
+
113
+ "That way, you'll verify where your route goes to. Plus, we'll verify\n"+
114
+ "the generation of the expected path from the action/controller, as in\n"+
115
+ "the url_for() helper."
116
+ end
117
+
118
+ def failure_message_for_should_not
119
+ "Expected '#{@actual.keys.first.to_s.upcase} #{@actual.values.first}' to fail, but it routed to #{@actual_place} instead"
120
+ end
121
+
122
+ end
123
+ # :call-seq:
124
+ # { "path" }.should_not be_routable # assumes GET
125
+ # { :get => "path" }.should_not be_routable
126
+ # { :put => "path" }.should_not be_routable
127
+ #
128
+ # Uses ActionController::Routing::Routes to verify that
129
+ # the path-and-method cannot be routed to a controller.
130
+ # Since url_for() will always generate a path, even if that
131
+ # path is not routable, the negative test only needs to be
132
+ # performed on the route recognition.
133
+ #
134
+ # Don't use this matcher for testing expected routability -
135
+ # use .should route_to( :controller => "controller", :action => "action" ) instead
136
+ #
137
+ # == Examples
138
+ # { :get => '/registrations/1/attendees/3/edit' }.should_not be_routable
139
+ # { :get => '/attendees/3/edit' }.should route_to( ...<controller/action>... )
140
+
141
+ def be_routable
142
+ BeRoutable.new(self)
143
+ end
144
+
145
+ alias_method :be_routeable, :be_routable
146
+ end
147
+ end
148
+ end
149
+
@@ -4,10 +4,10 @@ module Spec # :nodoc:
4
4
  unless defined? MAJOR
5
5
  MAJOR = 1
6
6
  MINOR = 2
7
- TINY = 7
8
- REALLY_TINY = 1
7
+ TINY = 9
8
+ PRE = nil
9
9
 
10
- STRING = [MAJOR, MINOR, TINY, REALLY_TINY].compact.join('.')
10
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
11
11
 
12
12
  SUMMARY = "rspec-rails #{STRING}"
13
13
  end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
2
  require File.dirname(__FILE__) + '/../../lib/autotest/rails_rspec'
3
3
  require File.dirname(__FILE__) + '/../../../rspec/spec/autotest/autotest_matchers'
4
4
 
@@ -114,10 +114,14 @@ class ControllerSpecController < ActionController::Base
114
114
  def un_rescued_error_action
115
115
  raise ControllerSpecController::UnRescuedError
116
116
  end
117
+
118
+ def action_that_returns_headers
119
+ render :text => request.headers[params[:header]]
120
+ end
117
121
  end
118
122
 
119
123
  class ControllerInheritingFromApplicationControllerController < ApplicationController
120
124
  def action_with_inherited_before_filter
121
125
  render :text => ""
122
126
  end
123
- end
127
+ end
@@ -15,6 +15,10 @@ class RenderSpecController < ApplicationController
15
15
  def text_action
16
16
  render :text => "this is the text for this action"
17
17
  end
18
+
19
+ def action_with_redirect
20
+ redirect_to :action => :some_action
21
+ end
18
22
 
19
23
  def action_with_partial
20
24
  render :partial => "a_partial"
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../../../spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe "AssignsHashProxy" do
4
4
  def orig_assigns
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../../../spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  module Spec
4
4
  module Runner
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../../../spec_helper'
1
+ require 'spec_helper'
2
2
  require 'controller_spec_controller'
3
3
  require File.join(File.dirname(__FILE__), "/shared_routing_example_group_examples.rb")
4
4
 
@@ -148,7 +148,7 @@ require File.join(File.dirname(__FILE__), "/shared_routing_example_group_example
148
148
  it "should support a Symbol key" do
149
149
  get 'action_which_sets_cookie', :value => "cookie value"
150
150
  if ::Rails::VERSION::STRING >= "2.3"
151
- cookies[:cookie_key].should == "cookie+value"
151
+ cookies[:cookie_key].should match("cookie[\+ ]value")
152
152
  else
153
153
  cookies[:cookie_key].should == ["cookie value"]
154
154
  end
@@ -157,7 +157,7 @@ require File.join(File.dirname(__FILE__), "/shared_routing_example_group_example
157
157
  it "should support a String key" do
158
158
  get 'action_which_sets_cookie', :value => "cookie value"
159
159
  if ::Rails::VERSION::STRING >= "2.3"
160
- cookies['cookie_key'].should == "cookie+value"
160
+ cookies['cookie_key'].should match("cookie[\+ ]value")
161
161
  else
162
162
  cookies['cookie_key'].should == ["cookie value"]
163
163
  end
@@ -188,12 +188,20 @@ require File.join(File.dirname(__FILE__), "/shared_routing_example_group_example
188
188
  }.should_not raise_error
189
189
  end
190
190
 
191
- describe "extending #render on a controller" do
192
- it "supports two arguments (as with rails 2.2)" do
193
- get 'action_with_two_arg_render'
194
- response.body.should =~ /new Effect\.Highlight/
191
+ if ::Rails::VERSION::STRING > '2.1'
192
+ describe "extending #render on a controller" do
193
+ it "supports two arguments (as with rails 2.1)" do
194
+ get 'action_with_two_arg_render'
195
+ response.body.should =~ /new Effect\.Highlight/
196
+ end
195
197
  end
196
198
  end
199
+
200
+ it "should access headers" do
201
+ request.env['ACCEPT'] = "application/json"
202
+ get 'action_that_returns_headers', :header => 'ACCEPT'
203
+ response.body.should == "application/json"
204
+ end
197
205
  end
198
206
 
199
207
  describe "Given a controller spec for RedirectSpecController running in #{mode} mode", :type => :controller do
@@ -1,47 +1,60 @@
1
- require File.dirname(__FILE__) + '/../../../spec_helper'
1
+ require 'spec_helper'
2
2
  require 'controller_spec_controller'
3
3
 
4
4
  describe "a controller spec running in isolation mode", :type => :controller do
5
5
  controller_name :controller_spec
6
6
 
7
- it "should not care if the specified template doesn't exist" do
7
+ it "does not care if the specified template doesn't exist" do
8
8
  get 'some_action'
9
9
  response.should be_success
10
10
  response.should render_template("template/that/does/not/actually/exist")
11
11
  end
12
-
13
- it "should not care if the implied template doesn't exist" do
12
+
13
+ it "does not care if the implied template doesn't exist" do
14
14
  get 'some_action_with_implied_template'
15
15
  response.should be_success
16
16
  response.should render_template("some_action_with_implied_template")
17
17
  end
18
18
 
19
- it "should not care if the template has errors" do
19
+ it "does not care if the template has errors" do
20
20
  get 'action_with_errors_in_template'
21
21
  response.should be_success
22
22
  response.should render_template("action_with_errors_in_template")
23
23
  end
24
+
25
+ it "does not care if the template exists but the action doesn't" do
26
+ get 'non_existent_action_with_existent_template'
27
+ response.should be_success
28
+ end
29
+
30
+ it "fails if the neither the action nor the template exist" do
31
+ expect {get 'non_existent_action'}.to raise_error(ActionController::UnknownAction)
32
+ end
24
33
  end
25
34
 
26
35
  describe "a controller spec running in integration mode", :type => :controller do
27
36
  controller_name :controller_spec
28
37
  integrate_views
29
-
30
- it "should render a template" do
38
+
39
+ it "renders a template" do
31
40
  get 'action_with_template'
32
41
  response.should be_success
33
42
  response.should have_tag('div', 'This is action_with_template.rhtml')
34
43
  end
35
44
 
36
- it "should choke if the template doesn't exist" do
45
+ it "fails if the template doesn't exist" do
37
46
  error = defined?(ActionController::MissingTemplate) ? ActionController::MissingTemplate : ActionView::MissingTemplate
38
47
  lambda { get 'some_action' }.should raise_error(error)
39
48
  end
40
49
 
41
- it "should choke if the template has errors" do
50
+ it "fails if the template has errors" do
42
51
  lambda { get 'action_with_errors_in_template' }.should raise_error(ActionView::TemplateError)
43
52
  end
44
53
 
54
+ it "fails if the action doesn't exist" do
55
+ expect {get 'non_existent_action'}.to raise_error(ActionController::UnknownAction)
56
+ end
57
+
45
58
  describe "nested" do
46
59
  it "should render a template" do
47
60
  get 'action_with_template'