rspec-rails 2.13.0 → 2.13.1

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 (46) hide show
  1. checksums.yaml +7 -0
  2. data/Capybara.md +1 -3
  3. data/Changelog.md +14 -0
  4. data/README.md +46 -16
  5. data/features/Transactions.md +2 -2
  6. data/features/Upgrade.md +4 -0
  7. data/features/controller_specs/Cookies.md +1 -1
  8. data/features/controller_specs/README.md +9 -9
  9. data/features/controller_specs/controller_spec.feature +1 -1
  10. data/features/controller_specs/engine_routes.feature +51 -0
  11. data/features/helper_specs/helper_spec.feature +26 -0
  12. data/features/matchers/README.md +3 -3
  13. data/features/model_specs/errors_on.feature +1 -1
  14. data/features/routing_specs/README.md +6 -7
  15. data/features/routing_specs/engine_routes.feature +38 -0
  16. data/features/support/rails_versions.rb +4 -0
  17. data/lib/generators/rspec.rb +2 -1
  18. data/lib/generators/rspec/controller/controller_generator.rb +1 -1
  19. data/lib/generators/rspec/install/install_generator.rb +2 -0
  20. data/lib/generators/rspec/install/templates/spec/spec_helper.rb.tt +2 -2
  21. data/lib/generators/rspec/scaffold/scaffold_generator.rb +1 -1
  22. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +4 -8
  23. data/lib/rspec/rails.rb +1 -0
  24. data/lib/rspec/rails/adapters.rb +30 -1
  25. data/lib/rspec/rails/example/controller_example_group.rb +43 -6
  26. data/lib/rspec/rails/example/rails_example_group.rb +2 -0
  27. data/lib/rspec/rails/example/routing_example_group.rb +28 -2
  28. data/lib/rspec/rails/example/view_example_group.rb +1 -1
  29. data/lib/rspec/rails/fixture_support.rb +1 -0
  30. data/lib/rspec/rails/matchers/routing_matchers.rb +1 -1
  31. data/lib/rspec/rails/mocks.rb +1 -1
  32. data/lib/rspec/rails/rails_version.rb +17 -0
  33. data/lib/rspec/rails/tasks/rspec.rake +8 -6
  34. data/lib/rspec/rails/version.rb +1 -1
  35. data/spec/generators/rspec/controller/controller_generator_spec.rb +11 -0
  36. data/spec/generators/rspec/install/install_generator_spec.rb +1 -1
  37. data/spec/generators/rspec/scaffold/scaffold_generator_spec.rb +23 -0
  38. data/spec/rspec/rails/assertion_delegator_spec.rb +13 -0
  39. data/spec/rspec/rails/example/view_example_group_spec.rb +1 -1
  40. data/spec/rspec/rails/matchers/have_rendered_spec.rb +3 -3
  41. data/spec/rspec/rails/matchers/relation_match_array_spec.rb +1 -1
  42. data/spec/rspec/rails/matchers/route_to_spec.rb +9 -10
  43. data/spec/rspec/rails/minitest_lifecycle_adapter_spec.rb +22 -0
  44. data/spec/rspec/rails/rails_version_spec.rb +29 -0
  45. data/spec/support/null_object.rb +6 -0
  46. metadata +67 -86
@@ -6,9 +6,9 @@ require 'rspec/autorun'
6
6
 
7
7
  # Requires supporting ruby files with custom matchers and macros, etc,
8
8
  # in spec/support/ and its subdirectories.
9
- Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
9
+ Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
10
10
 
11
- <% if ::Rails.version >= '4' -%>
11
+ <% if RSpec::Rails.rails_version_satisfied_by?('>= 4.0.0.beta1') -%>
12
12
  # Checks for pending migrations before tests are run.
13
13
  # If you are not using ActiveRecord, you can remove this line.
14
14
  ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
@@ -27,7 +27,7 @@ module Rspec
27
27
  end
28
28
 
29
29
  def generate_view_specs
30
- return unless options[:view_specs]
30
+ return unless options[:view_specs] && options[:template_engine]
31
31
 
32
32
  copy_view :edit
33
33
  copy_view :index unless options[:singleton]
@@ -23,17 +23,13 @@ describe <%= controller_class_name %>Controller do
23
23
 
24
24
  # This should return the minimal set of attributes required to create a valid
25
25
  # <%= class_name %>. As you add validations to <%= class_name %>, be sure to
26
- # update the return value of this method accordingly.
27
- def valid_attributes
28
- <%= formatted_hash(example_valid_attributes) %>
29
- end
26
+ # adjust the attributes here as well.
27
+ let(:valid_attributes) { <%= formatted_hash(example_valid_attributes) %> }
30
28
 
31
29
  # This should return the minimal set of values that should be in the session
32
30
  # in order to pass any filters (e.g. authentication) defined in
33
31
  # <%= controller_class_name %>Controller. Be sure to keep this updated too.
34
- def valid_session
35
- {}
36
- end
32
+ let(:valid_session) { {} }
37
33
 
38
34
  <% unless options[:singleton] -%>
39
35
  describe "GET index" do
@@ -113,7 +109,7 @@ describe <%= controller_class_name %>Controller do
113
109
  # specifies that the <%= class_name %> created on the previous line
114
110
  # receives the :update_attributes message with whatever params are
115
111
  # submitted in the request.
116
- <%- if Rails.version >= '4' -%>
112
+ <%- if RSpec::Rails.rails_version_satisfied_by?('>= 4.0.0.beta1') -%>
117
113
  <%= class_name %>.any_instance.should_receive(:update).with(<%= formatted_hash(example_params_for_update) %>)
118
114
  <%- else -%>
119
115
  <%= class_name %>.any_instance.should_receive(:update_attributes).with(<%= formatted_hash(example_params_for_update) %>)
@@ -5,6 +5,7 @@ RSpec::configure do |c|
5
5
  c.backtrace_clean_patterns << /lib\/rspec\/rails/
6
6
  end
7
7
 
8
+ require 'rspec/rails/rails_version'
8
9
  require 'rspec/rails/extensions'
9
10
  require 'rspec/rails/view_rendering'
10
11
  require 'rspec/rails/adapters'
@@ -24,7 +24,8 @@ module RSpec
24
24
  end
25
25
 
26
26
  assertion_modules.each do |mod|
27
- mod.instance_methods.each do |method|
27
+ mod.public_instance_methods.each do |method|
28
+ next if method == :method_missing || method == "method_missing"
28
29
  class_eval <<-EOM, __FILE__, __LINE__ + 1
29
30
  def #{method}(*args, &block)
30
31
  assertion_instance.send(:#{method}, *args, &block)
@@ -36,6 +37,34 @@ module RSpec
36
37
  end
37
38
  end
38
39
 
40
+ # MiniTest::Unit::LifecycleHooks
41
+ module MiniTestLifecycleAdapter
42
+ extend ActiveSupport::Concern
43
+
44
+ included do |group|
45
+ group.before { after_setup }
46
+ group.after { before_teardown }
47
+
48
+ group.around do |example|
49
+ before_setup
50
+ example.run
51
+ after_teardown
52
+ end
53
+ end
54
+
55
+ def before_setup
56
+ end
57
+
58
+ def after_setup
59
+ end
60
+
61
+ def before_teardown
62
+ end
63
+
64
+ def after_teardown
65
+ end
66
+ end
67
+
39
68
  module SetupAndTeardownAdapter
40
69
  extend ActiveSupport::Concern
41
70
 
@@ -11,6 +11,7 @@ module RSpec::Rails
11
11
  include RSpec::Rails::Matchers::RedirectTo
12
12
  include RSpec::Rails::Matchers::RenderTemplate
13
13
  include RSpec::Rails::Matchers::RoutingMatchers
14
+ include RSpec::Rails::AssertionDelegator.new(ActionDispatch::Assertions::RoutingAssertions)
14
15
 
15
16
  module ClassMethods
16
17
  # @private
@@ -64,18 +65,43 @@ module RSpec::Rails
64
65
  metadata[:example_group][:described_class].class_eval(&body)
65
66
 
66
67
  before do
67
- @orig_routes, @routes = @routes, ActionDispatch::Routing::RouteSet.new
68
- @routes.draw { resources :anonymous }
68
+ @orig_routes = self.routes
69
+ self.routes = ActionDispatch::Routing::RouteSet.new.tap { |r|
70
+ r.draw { resources :anonymous }
71
+ }
69
72
  end
70
73
 
71
74
  after do
72
- @routes, @orig_routes = @orig_routes, nil
75
+ self.routes = @orig_routes
76
+ @orig_routes = nil
77
+ end
78
+ end
79
+
80
+ # Specifies the routeset that will be used for the example group. This
81
+ # is most useful when testing Rails engines.
82
+ #
83
+ # @example
84
+ #
85
+ # describe MyEngine::PostsController do
86
+ # routes { MyEngine::Engine.routes }
87
+ #
88
+ # # ...
89
+ # end
90
+ def routes(&blk)
91
+ before do
92
+ self.routes = blk.call
73
93
  end
74
94
  end
75
95
  end
76
96
 
77
97
  attr_reader :controller, :routes
78
98
 
99
+ # @api private
100
+ def routes=(routes)
101
+ @routes = routes
102
+ assertion_instance.instance_variable_set(:@routes, routes)
103
+ end
104
+
79
105
  module BypassRescue
80
106
  def rescue_with_handler(exception)
81
107
  raise exception
@@ -107,7 +133,9 @@ module RSpec::Rails
107
133
  # If method is a named_route, delegates to the RouteSet associated with
108
134
  # this controller.
109
135
  def method_missing(method, *args, &block)
110
- if @orig_routes && @orig_routes.named_routes.helpers.include?(method)
136
+ if @routes && @routes.named_routes.helpers.include?(method)
137
+ controller.send(method, *args, &block)
138
+ elsif @orig_routes && @orig_routes.named_routes.helpers.include?(method)
111
139
  controller.send(method, *args, &block)
112
140
  else
113
141
  super
@@ -120,8 +148,17 @@ module RSpec::Rails
120
148
  metadata[:type] = :controller
121
149
 
122
150
  before do
123
- @routes = ::Rails.application.routes
124
- ActionController::Base.allow_forgery_protection = false
151
+ self.routes = ::Rails.application.routes
152
+ end
153
+
154
+ around do |ex|
155
+ previous_allow_forgery_protection_value = ActionController::Base.allow_forgery_protection
156
+ begin
157
+ ActionController::Base.allow_forgery_protection = false
158
+ ex.call
159
+ ensure
160
+ ActionController::Base.allow_forgery_protection = previous_allow_forgery_protection_value
161
+ end
125
162
  end
126
163
  end
127
164
  end
@@ -1,12 +1,14 @@
1
1
  # Temporary workaround to resolve circular dependency between rspec-rails' spec
2
2
  # suite and ammeter.
3
3
  require 'rspec/rails/matchers'
4
+ require 'rspec/rails/rails_version'
4
5
 
5
6
  module RSpec
6
7
  module Rails
7
8
  module RailsExampleGroup
8
9
  extend ActiveSupport::Concern
9
10
  include RSpec::Rails::SetupAndTeardownAdapter
11
+ include RSpec::Rails::MiniTestLifecycleAdapter if RSpec::Rails.rails_version_satisfied_by?('>= 4.0.0.beta1')
10
12
  include RSpec::Rails::TestUnitAssertionAdapter
11
13
  include RSpec::Rails::Matchers
12
14
  end
@@ -8,17 +8,43 @@ module RSpec::Rails
8
8
  include RSpec::Rails::Matchers::RoutingMatchers::RouteHelpers
9
9
  include RSpec::Rails::AssertionDelegator.new(ActionDispatch::Assertions::RoutingAssertions)
10
10
 
11
+ module ClassMethods
12
+ # Specifies the routeset that will be used for the example group. This
13
+ # is most useful when testing Rails engines.
14
+ #
15
+ # @example
16
+ #
17
+ # describe MyEngine::PostsController do
18
+ # routes { MyEngine::Engine.routes }
19
+ #
20
+ # it "routes posts#index" do
21
+ # expect(:get => "/posts").to
22
+ # route_to(:controller => "my_engine/posts", :action => "index")
23
+ # end
24
+ # end
25
+ def routes(&blk)
26
+ before do
27
+ self.routes = blk.call
28
+ end
29
+ end
30
+ end
31
+
11
32
  included do
12
33
  metadata[:type] = :routing
13
34
 
14
35
  before do
15
- @routes = ::Rails.application.routes
16
- assertion_instance.instance_variable_set(:@routes, @routes)
36
+ self.routes = ::Rails.application.routes
17
37
  end
18
38
  end
19
39
 
20
40
  attr_reader :routes
21
41
 
42
+ # @api private
43
+ def routes=(routes)
44
+ @routes = routes
45
+ assertion_instance.instance_variable_set(:@routes, routes)
46
+ end
47
+
22
48
  private
23
49
 
24
50
  def method_missing(m, *args, &block)
@@ -107,7 +107,7 @@ module RSpec::Rails
107
107
  end
108
108
 
109
109
  def _default_render_options
110
- if ::Rails.version >= "3.2"
110
+ if RSpec::Rails.rails_version_satisfied_by?('>= 3.2')
111
111
  # pluck the handler, format, and locale out of, eg, posts/index.de.html.haml
112
112
  template, *components = _default_file_to_render.split('.')
113
113
  handler, format, locale = *components.reverse
@@ -4,6 +4,7 @@ module RSpec
4
4
  module FixtureSupport
5
5
  extend ActiveSupport::Concern
6
6
  include RSpec::Rails::SetupAndTeardownAdapter
7
+ include RSpec::Rails::MiniTestLifecycleAdapter if RSpec::Rails.rails_version_satisfied_by?('>= 4.0.0.beta1')
7
8
  include RSpec::Rails::TestUnitAssertionAdapter
8
9
  include ActiveRecord::TestFixtures
9
10
 
@@ -97,7 +97,7 @@ module RSpec::Rails::Matchers
97
97
  end
98
98
 
99
99
  module RouteHelpers
100
- %w(get post put delete options head).each do |method|
100
+ %w(get post put patch delete options head).each do |method|
101
101
  define_method method do |path|
102
102
  { method.to_sym => path }
103
103
  end
@@ -96,7 +96,7 @@ EOM
96
96
  :valid? => true,
97
97
  :blank? => false)
98
98
 
99
- mock("#{model_class.name}_#{stubs[:id]}", stubs).tap do |m|
99
+ double("#{model_class.name}_#{stubs[:id]}", stubs).tap do |m|
100
100
  m.singleton_class.class_eval do
101
101
  include ActiveModelInstanceMethods
102
102
  include ActiveRecordInstanceMethods if defined?(ActiveRecord)
@@ -0,0 +1,17 @@
1
+ module RSpec
2
+ module Rails
3
+ # @api private
4
+ def self.rails_version_satisfied_by?(requirement)
5
+ Gem::Requirement.new(requirement).satisfied_by?(rails_version)
6
+ end
7
+
8
+ # @api private
9
+ def self.rails_version
10
+ @rails_version ||= if ::Rails.version.is_a?(Gem::Version)
11
+ ::Rails.version
12
+ else
13
+ Gem::Version.new(::Rails.version.to_s)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -25,11 +25,14 @@ namespace :spec do
25
25
  end
26
26
  end
27
27
 
28
- desc "Run all specs with rcov"
29
- RSpec::Core::RakeTask.new(:rcov => spec_prereq) do |t|
30
- t.rcov = true
31
- t.pattern = "./spec/**/*_spec.rb"
32
- t.rcov_opts = '--exclude /gems/,/Library/,/usr/,lib/tasks,.bundle,config,/lib/rspec/,/lib/rspec-,spec'
28
+ # RCov task only enabled for Ruby 1.8
29
+ if RUBY_VERSION < '1.9'
30
+ desc "Run all specs with rcov"
31
+ RSpec::Core::RakeTask.new(:rcov => spec_prereq) do |t|
32
+ t.rcov = true
33
+ t.pattern = "./spec/**/*_spec.rb"
34
+ t.rcov_opts = '--exclude /gems/,/Library/,/usr/,lib/tasks,.bundle,config,/lib/rspec/,/lib/rspec-,spec'
35
+ end
33
36
  end
34
37
 
35
38
  task :statsetup do
@@ -42,4 +45,3 @@ namespace :spec do
42
45
  end
43
46
  end
44
47
  end
45
-
@@ -1,7 +1,7 @@
1
1
  module RSpec
2
2
  module Rails
3
3
  module Version
4
- STRING = '2.13.0'
4
+ STRING = '2.13.1'
5
5
  end
6
6
  end
7
7
  end
@@ -50,6 +50,17 @@ describe Rspec::Generators::ControllerGenerator do
50
50
  it { should_not exist }
51
51
  end
52
52
  end
53
+
54
+ describe 'with --no-template-engine' do
55
+ before do
56
+ run_generator %w(posts index --no-template-engine)
57
+ end
58
+
59
+ describe 'index.html.erb' do
60
+ subject { file('spec/views/posts/index.html._spec.rb') }
61
+ it { should_not exist }
62
+ end
63
+ end
53
64
  end
54
65
 
55
66
  describe 'are generated' do
@@ -16,7 +16,7 @@ describe Rspec::Generators::InstallGenerator do
16
16
  File.read( file('spec/spec_helper.rb') ).should =~ /^require 'rspec\/autorun'$/m
17
17
  end
18
18
 
19
- if ::Rails.version >= '4'
19
+ if RSpec::Rails.rails_version_satisfied_by?('>= 4.0.0.beta1')
20
20
  it "generates spec/spec_helper.rb with a check for pending migrations" do
21
21
  run_generator
22
22
  File.read( file('spec/spec_helper.rb') ).should =~ /ActiveRecord::Migration\.check_pending!/m
@@ -72,6 +72,29 @@ describe Rspec::Generators::ScaffoldGenerator do
72
72
  end
73
73
  end
74
74
 
75
+ describe 'with --no-template-engine' do
76
+ before { run_generator %w(posts --no-template-engine) }
77
+ describe 'edit' do
78
+ subject { file("spec/views/posts/edit.html._spec.rb") }
79
+ it { should_not exist }
80
+ end
81
+
82
+ describe 'index' do
83
+ subject { file("spec/views/posts/index.html._spec.rb") }
84
+ it { should_not exist }
85
+ end
86
+
87
+ describe 'new' do
88
+ subject { file("spec/views/posts/new.html._spec.rb") }
89
+ it { should_not exist }
90
+ end
91
+
92
+ describe 'show' do
93
+ subject { file("spec/views/posts/show.html._spec.rb") }
94
+ it { should_not exist }
95
+ end
96
+ end
97
+
75
98
  describe 'with --no-view-specs' do
76
99
  before { run_generator %w(posts --no-view-specs) }
77
100
 
@@ -27,4 +27,17 @@ describe RSpec::Rails::AssertionDelegator do
27
27
  expect(klass.new).to have_thing(:a)
28
28
  expect(klass.new).not_to have_thing(:b)
29
29
  end
30
+
31
+ it "does not delegate method_missing" do
32
+ assertions = Module.new {
33
+ def method_missing(method, *args)
34
+ end
35
+ }
36
+
37
+ klass = Class.new {
38
+ include RSpec::Rails::AssertionDelegator.new(assertions)
39
+ }
40
+
41
+ expect { klass.new.abc123 }.to raise_error(NoMethodError)
42
+ end
30
43
  end
@@ -118,7 +118,7 @@ module RSpec::Rails
118
118
  view_spec.stub(:_default_file_to_render) { "widgets/new.en.html.erb" }
119
119
  view_spec.render
120
120
 
121
- if ::Rails.version >= "3.2"
121
+ if RSpec::Rails.rails_version_satisfied_by?('>= 3.2')
122
122
  view_spec.received.first.should == [{:template => "widgets/new", :locales=>['en'], :formats=>['html'], :handlers=>['erb']}, {}, nil]
123
123
  else
124
124
  view_spec.received.first.should == [{:template => "widgets/new.en.html.erb"}, {}, nil]
@@ -29,7 +29,7 @@ require "spec_helper"
29
29
  context "with should" do
30
30
  context "when assert_template passes" do
31
31
  it "passes" do
32
- self.stub!(:assert_template)
32
+ def assert_template(*); end
33
33
  expect do
34
34
  expect(response).to send(template_expectation, "template_name")
35
35
  end.to_not raise_exception
@@ -38,7 +38,7 @@ require "spec_helper"
38
38
 
39
39
  context "when assert_template fails" do
40
40
  it "uses failure message from assert_template" do
41
- self.stub!(:assert_template) do
41
+ def assert_template(*)
42
42
  raise ActiveSupport::TestCase::Assertion.new("this message")
43
43
  end
44
44
  expect do
@@ -49,7 +49,7 @@ require "spec_helper"
49
49
 
50
50
  context "when fails due to some other exception" do
51
51
  it "raises that exception" do
52
- self.stub!(:assert_template) do
52
+ def assert_template(*)
53
53
  raise "oops"
54
54
  end
55
55
  expect do