rspec-rails 2.6.1 → 2.7.0.rc1

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/README.md +5 -5
  2. data/features/Transactions.md +84 -0
  3. data/features/controller_specs/Cookies.md +57 -0
  4. data/features/controller_specs/anonymous_controller.feature +104 -61
  5. data/features/controller_specs/bypass_rescue.feature +75 -0
  6. data/features/matchers/relation_match_array.feature +20 -0
  7. data/features/mocks/mock_model.feature +6 -6
  8. data/features/support/env.rb +2 -2
  9. data/features/view_specs/view_spec.feature +2 -8
  10. data/lib/autotest/rails_rspec2.rb +1 -1
  11. data/lib/generators/rspec/controller/templates/controller_spec.rb +1 -1
  12. data/lib/generators/rspec/install/templates/spec/spec_helper.rb +6 -0
  13. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +6 -6
  14. data/lib/generators/rspec/view/templates/view_spec.rb +1 -1
  15. data/lib/rspec/rails/example/controller_example_group.rb +19 -1
  16. data/lib/rspec/rails/fixture_support.rb +11 -0
  17. data/lib/rspec/rails/matchers.rb +1 -0
  18. data/lib/rspec/rails/matchers/relation_match_array.rb +3 -0
  19. data/lib/rspec/rails/matchers/routing_matchers.rb +16 -14
  20. data/lib/rspec/rails/mocks.rb +12 -7
  21. data/lib/rspec/rails/version.rb +1 -1
  22. data/spec/generators/rspec/controller/controller_generator_spec.rb +86 -0
  23. data/spec/generators/rspec/helper/helper_generator_spec.rb +30 -0
  24. data/spec/generators/rspec/install/install_generator_spec.rb +18 -0
  25. data/spec/generators/rspec/integration/integration_generator_spec.rb +44 -0
  26. data/spec/generators/rspec/mailer/mailer_generator_spec.rb +48 -0
  27. data/spec/generators/rspec/model/model_generator_spec.rb +52 -0
  28. data/spec/generators/rspec/observer/observer_generator_spec.rb +21 -0
  29. data/spec/generators/rspec/scaffold/scaffold_generator_spec.rb +113 -0
  30. data/spec/generators/rspec/view/view_generator_spec.rb +41 -0
  31. data/spec/rspec/rails/example/controller_example_group_spec.rb +39 -3
  32. data/spec/rspec/rails/matchers/relation_match_array_spec.rb +19 -0
  33. data/spec/rspec/rails/matchers/route_to_spec.rb +25 -3
  34. data/spec/rspec/rails/mocks/mock_model_spec.rb +62 -2
  35. data/spec/rspec/rails/mocks/stub_model_spec.rb +0 -1
  36. data/spec/spec_helper.rb +2 -1
  37. data/spec/{rspec/rails/mocks → support}/ar_classes.rb +5 -2
  38. metadata +102 -99
  39. data/.document +0 -5
  40. data/.gitignore +0 -14
  41. data/.rspec +0 -1
  42. data/.travis.yml +0 -11
  43. data/History.md +0 -1
  44. data/License.txt +0 -23
  45. data/README_DEV.md +0 -43
  46. data/Rakefile +0 -152
  47. data/Thorfile +0 -45
  48. data/Upgrade.md +0 -1
  49. data/cucumber.yml +0 -3
  50. data/features/.nav +0 -35
  51. data/features/Changelog.md +0 -162
  52. data/gemfiles/.bundle/config +0 -2
  53. data/gemfiles/base.rb +0 -60
  54. data/gemfiles/rails-3-0-stable +0 -6
  55. data/gemfiles/rails-3.0.0 +0 -5
  56. data/gemfiles/rails-3.0.1 +0 -5
  57. data/gemfiles/rails-3.0.2 +0 -5
  58. data/gemfiles/rails-3.0.3 +0 -5
  59. data/gemfiles/rails-3.0.4 +0 -5
  60. data/gemfiles/rails-3.0.5 +0 -5
  61. data/gemfiles/rails-3.0.6 +0 -5
  62. data/gemfiles/rails-3.0.7 +0 -5
  63. data/gemfiles/rails-3.1.0.rc1 +0 -5
  64. data/gemfiles/rails-master +0 -5
  65. data/rspec-rails.gemspec +0 -34
  66. data/templates/generate_stuff.rb +0 -21
  67. data/templates/run_specs.rb +0 -9
@@ -0,0 +1,20 @@
1
+ Feature: ActiveRecord::Relation match array
2
+
3
+ The `=~` matcher can be used with an `ActiveRecord::Relation` (scope). The
4
+ assertion will pass if the scope would return all of the elements specified
5
+ in the array on the right hand side.
6
+
7
+ Scenario: example spec with relation =~ matcher
8
+ Given a file named "spec/models/widget_spec.rb" with:
9
+ """
10
+ require "spec_helper"
11
+
12
+ describe Widget do
13
+ let!(:widgets) { Array.new(3) { Widget.create } }
14
+ subject { Widget.scoped }
15
+
16
+ it { should =~ widgets }
17
+ end
18
+ """
19
+ When I run `rspec spec/models/widget_spec.rb`
20
+ Then the examples should all pass
@@ -1,13 +1,13 @@
1
1
  Feature: mock_model
2
2
 
3
- The mock_model method generates a test double that acts like an Active Model
4
- model. This is different from the stub_model method which generates an
5
- instance of a real ActiveModel class.
3
+ The `mock_model` method generates a test double that acts like an instance of
4
+ `ActiveModel`. This is different from the `stub_model` method which generates
5
+ an instance of a real model class.
6
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
7
+ The benefit of `mock_model` over `stub_model` is that it is a true double, so
8
+ the examples are not dependent on the behavior (or mis-behavior), or even the
9
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
10
+ need a model that doesn't exist, you can pass `mock_model` a string and the
11
11
  generated object will act as though its an instance of the class named by
12
12
  that string.
13
13
 
@@ -2,14 +2,14 @@ require 'aruba/cucumber'
2
2
 
3
3
  module ArubaExt
4
4
  def run(cmd)
5
- super(cmd =~ /^rspec/ ? "bundle exec #{cmd}" : cmd)
5
+ super(cmd =~ /^rspec/ ? "bin/#{cmd}" : cmd)
6
6
  end
7
7
  end
8
8
 
9
9
  World(ArubaExt)
10
10
 
11
11
  Before do
12
- @aruba_timeout_seconds = 10
12
+ @aruba_timeout_seconds = 15
13
13
  end
14
14
 
15
15
  unless File.directory?('./tmp/example_app')
@@ -134,7 +134,7 @@ Feature: view spec
134
134
  When I run `rspec spec/views`
135
135
  Then the examples should all pass
136
136
 
137
- Scenario: spec with view that accesses helper_method helpers
137
+ Scenario: passing view spec that stubs a helper method
138
138
  Given a file named "app/views/secrets/index.html.erb" with:
139
139
  """
140
140
  <%- if admin? %>
@@ -147,13 +147,7 @@ Feature: view spec
147
147
 
148
148
  describe 'secrets/index.html.erb' do
149
149
  before do
150
- controller.singleton_class.class_eval do
151
- protected
152
- def admin?
153
- true
154
- end
155
- helper_method :admin?
156
- end
150
+ view.stub(:admin?).and_return(true)
157
151
  end
158
152
 
159
153
  it 'checks for admin access' do
@@ -42,7 +42,7 @@ class Autotest::RailsRspec2 < Autotest::Rspec2
42
42
  add_mapping(%r%^(test|spec)/fixtures/(.*).yml$%) { |_, m|
43
43
  ["spec/models/#{m[2].singularize}_spec.rb"] + files_matching(%r%^spec\/views\/#{m[2]}/.*_spec\.rb$%)
44
44
  }
45
- add_mapping(%r%^spec/(models|controllers|routing|views|helpers|mailers|requests|lib)/.*rb$%) { |filename, _|
45
+ add_mapping(%r%^spec/.*_spec\.rb$%) { |filename, _|
46
46
  filename
47
47
  }
48
48
  add_mapping(%r%^app/models/(.*)\.rb$%) { |_, m|
@@ -4,7 +4,7 @@ describe <%= class_name %>Controller do
4
4
 
5
5
  <% for action in actions -%>
6
6
  describe "GET '<%= action %>'" do
7
- it "should be successful" do
7
+ it "returns http success" do
8
8
  get '<%= action %>'
9
9
  response.should be_success
10
10
  end
@@ -2,6 +2,7 @@
2
2
  ENV["RAILS_ENV"] ||= 'test'
3
3
  require File.expand_path("../../config/environment", __FILE__)
4
4
  require 'rspec/rails'
5
+ require 'rspec/autorun'
5
6
 
6
7
  # Requires supporting ruby files with custom matchers and macros, etc,
7
8
  # in spec/support/ and its subdirectories.
@@ -24,4 +25,9 @@ RSpec.configure do |config|
24
25
  # examples within a transaction, remove the following line or assign false
25
26
  # instead of true.
26
27
  config.use_transactional_fixtures = true
28
+
29
+ # If true, the base class of anonymous controllers will be inferred
30
+ # automatically. This will be the default behavior in future versions of
31
+ # rspec-rails.
32
+ config.infer_base_class_for_anonymous_controllers = false
27
33
  end
@@ -40,7 +40,7 @@ describe <%= controller_class_name %>Controller do
40
40
  describe "GET show" do
41
41
  it "assigns the requested <%= ns_file_name %> as @<%= ns_file_name %>" do
42
42
  <%= file_name %> = <%= class_name %>.create! valid_attributes
43
- get :show, :id => <%= file_name %>.id.to_s
43
+ get :show, :id => <%= file_name %>.id
44
44
  assigns(:<%= ns_file_name %>).should eq(<%= file_name %>)
45
45
  end
46
46
  end
@@ -55,7 +55,7 @@ describe <%= controller_class_name %>Controller do
55
55
  describe "GET edit" do
56
56
  it "assigns the requested <%= ns_file_name %> as @<%= ns_file_name %>" do
57
57
  <%= file_name %> = <%= class_name %>.create! valid_attributes
58
- get :edit, :id => <%= file_name %>.id.to_s
58
+ get :edit, :id => <%= file_name %>.id
59
59
  assigns(:<%= ns_file_name %>).should eq(<%= file_name %>)
60
60
  end
61
61
  end
@@ -127,7 +127,7 @@ describe <%= controller_class_name %>Controller do
127
127
  <%= file_name %> = <%= class_name %>.create! valid_attributes
128
128
  # Trigger the behavior that occurs when invalid params are submitted
129
129
  <%= class_name %>.any_instance.stub(:save).and_return(false)
130
- put :update, :id => <%= file_name %>.id.to_s, :<%= ns_file_name %> => {}
130
+ put :update, :id => <%= file_name %>.id, :<%= ns_file_name %> => {}
131
131
  assigns(:<%= ns_file_name %>).should eq(<%= file_name %>)
132
132
  end
133
133
 
@@ -135,7 +135,7 @@ describe <%= controller_class_name %>Controller do
135
135
  <%= file_name %> = <%= class_name %>.create! valid_attributes
136
136
  # Trigger the behavior that occurs when invalid params are submitted
137
137
  <%= class_name %>.any_instance.stub(:save).and_return(false)
138
- put :update, :id => <%= file_name %>.id.to_s, :<%= ns_file_name %> => {}
138
+ put :update, :id => <%= file_name %>.id, :<%= ns_file_name %> => {}
139
139
  response.should render_template("edit")
140
140
  end
141
141
  end
@@ -145,13 +145,13 @@ describe <%= controller_class_name %>Controller do
145
145
  it "destroys the requested <%= ns_file_name %>" do
146
146
  <%= file_name %> = <%= class_name %>.create! valid_attributes
147
147
  expect {
148
- delete :destroy, :id => <%= file_name %>.id.to_s
148
+ delete :destroy, :id => <%= file_name %>.id
149
149
  }.to change(<%= class_name %>, :count).by(-1)
150
150
  end
151
151
 
152
152
  it "redirects to the <%= table_name %> list" do
153
153
  <%= file_name %> = <%= class_name %>.create! valid_attributes
154
- delete :destroy, :id => <%= file_name %>.id.to_s
154
+ delete :destroy, :id => <%= file_name %>.id
155
155
  response.should redirect_to(<%= index_helper %>_url)
156
156
  end
157
157
  end
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "<%= file_name %>/<%= @action %>.html.<%= options[:template_engine] %>" do
3
+ describe "<%= file_path %>/<%= @action %>.html.<%= options[:template_engine] %>" do
4
4
  pending "add some examples to (or delete) #{__FILE__}"
5
5
  end
@@ -1,3 +1,7 @@
1
+ RSpec.configure do |config|
2
+ config.add_setting :infer_base_class_for_anonymous_controllers, :default => false
3
+ end
4
+
1
5
  module RSpec::Rails
2
6
  # Extends ActionController::TestCase::Behavior to work with RSpec.
3
7
  #
@@ -124,7 +128,11 @@ module RSpec::Rails
124
128
  # +controller+ method. Any instance methods, filters, etc, that are
125
129
  # defined in +ApplicationController+, however, are accessible from within
126
130
  # the block.
127
- def controller(base_class = ApplicationController, &body)
131
+ def controller(base_class = nil, &body)
132
+ base_class ||= RSpec.configuration.infer_base_class_for_anonymous_controllers? ?
133
+ controller_class :
134
+ ApplicationController
135
+
128
136
  metadata[:example_group][:describes] = Class.new(base_class, &body)
129
137
  metadata[:example_group][:describes].singleton_class.class_eval do
130
138
  def name; "AnonymousController" end
@@ -144,6 +152,16 @@ module RSpec::Rails
144
152
  module InstanceMethods
145
153
  attr_reader :controller, :routes
146
154
 
155
+ module BypassRescue
156
+ def rescue_with_handler(exception)
157
+ raise exception
158
+ end
159
+ end
160
+
161
+ def bypass_rescue
162
+ controller.extend(BypassRescue)
163
+ end
164
+
147
165
  def method_missing(method, *args, &block)
148
166
  if @orig_routes && @orig_routes.named_routes.helpers.include?(method)
149
167
  controller.send(method, *args, &block)
@@ -9,6 +9,17 @@ module RSpec
9
9
  include ActiveRecord::TestFixtures
10
10
 
11
11
  included do
12
+ # TODO (DC 2011-06-25) this is necessary because fixture_file_upload
13
+ # accesses fixture_path directly on ActiveSupport::TestCase. This is
14
+ # fixed in rails by https://github.com/rails/rails/pull/1861, which
15
+ # should be part of the 3.1 release, at which point we can include
16
+ # these lines for rails < 3.1.
17
+ ActiveSupport::TestCase.class_eval do
18
+ include ActiveRecord::TestFixtures
19
+ self.fixture_path = RSpec.configuration.fixture_path
20
+ end
21
+ # /TODO
22
+
12
23
  self.fixture_path = RSpec.configuration.fixture_path
13
24
  self.use_transactional_fixtures = RSpec.configuration.use_transactional_fixtures
14
25
  self.use_instantiated_fixtures = RSpec.configuration.use_instantiated_fixtures
@@ -23,3 +23,4 @@ require 'rspec/rails/matchers/routing_matchers'
23
23
  require 'rspec/rails/matchers/be_new_record'
24
24
  require 'rspec/rails/matchers/be_a_new'
25
25
  require 'rspec/rails/matchers/have_extension'
26
+ require 'rspec/rails/matchers/relation_match_array'
@@ -0,0 +1,3 @@
1
+ if defined?(ActiveRecord)
2
+ RSpec::Matchers::OperatorMatcher.register(ActiveRecord::Relation, '=~', RSpec::Matchers::MatchArray)
3
+ end
@@ -2,26 +2,28 @@ module RSpec::Rails::Matchers
2
2
  module RoutingMatchers
3
3
  extend RSpec::Matchers::DSL
4
4
 
5
- matcher :route_to do |*route_options|
6
- match_unless_raises ActiveSupport::TestCase::Assertion do |path|
7
- assertion_path = { :method => path.keys.first, :path => path.values.first }
8
-
9
- path, options = *route_options
10
-
11
- if path.is_a?(String)
12
- controller, action = path.split("#")
13
- options ||= {}
14
- options.merge!(:controller => controller, :action => action)
15
- else
16
- options = path
17
- end
5
+ matcher :route_to do |*expected|
6
+ expected_options = expected[1] || {}
7
+ if Hash === expected[0]
8
+ expected_options.merge!(expected[0])
9
+ else
10
+ controller, action = expected[0].split('#')
11
+ expected_options.merge!(:controller => controller, :action => action)
12
+ end
18
13
 
19
- assert_recognizes(options, assertion_path)
14
+ match_unless_raises ActiveSupport::TestCase::Assertion do |verb_to_path_map|
15
+ path, query = *verb_to_path_map.values.first.split('?')
16
+ assert_recognizes(
17
+ expected_options,
18
+ {:method => verb_to_path_map.keys.first, :path => path},
19
+ Rack::Utils::parse_query(query)
20
+ )
20
21
  end
21
22
 
22
23
  failure_message_for_should do
23
24
  rescued_exception.message
24
25
  end
26
+
25
27
  end
26
28
 
27
29
  matcher :be_routable do
@@ -63,6 +63,7 @@ module RSpec
63
63
  else
64
64
  model_class = Object.const_set(string_or_model_class, Class.new do
65
65
  extend ActiveModel::Naming
66
+ def self.primary_key; :id; end
66
67
  end)
67
68
  end
68
69
  else
@@ -101,22 +102,27 @@ EOM
101
102
  m.__send__(:__mock_proxy).instance_eval(<<-CODE, __FILE__, __LINE__)
102
103
  def @object.is_a?(other)
103
104
  #{model_class}.ancestors.include?(other)
104
- end
105
+ end unless #{stubs.has_key?(:is_a?)}
106
+
105
107
  def @object.kind_of?(other)
106
108
  #{model_class}.ancestors.include?(other)
107
- end
109
+ end unless #{stubs.has_key?(:kind_of?)}
110
+
108
111
  def @object.instance_of?(other)
109
112
  other == #{model_class}
110
- end
113
+ end unless #{stubs.has_key?(:instance_of?)}
114
+
111
115
  def @object.respond_to?(method_name, include_private=false)
112
116
  #{model_class}.respond_to?(:column_names) && #{model_class}.column_names.include?(method_name.to_s) || super
113
- end
117
+ end unless #{stubs.has_key?(:respond_to?)}
118
+
114
119
  def @object.class
115
120
  #{model_class}
116
- end
121
+ end unless #{stubs.has_key?(:class)}
122
+
117
123
  def @object.to_s
118
124
  "#{model_class.name}_#{to_param}"
119
- end
125
+ end unless #{stubs.has_key?(:to_s)}
120
126
  CODE
121
127
  yield m if block_given?
122
128
  end
@@ -153,7 +159,6 @@ EOM
153
159
  # stub_model(Model)
154
160
  # stub_model(Model).as_new_record
155
161
  # stub_model(Model, hash_of_stubs)
156
- # stub_model(Model, instance_variable_name, hash_of_stubs)
157
162
  #
158
163
  # Creates an instance of +Model+ with +to_param+ stubbed using a
159
164
  # generated value that is unique to each object.. If +Model+ is an
@@ -1,7 +1,7 @@
1
1
  module RSpec # :nodoc:
2
2
  module Rails # :nodoc:
3
3
  module Version # :nodoc:
4
- STRING = '2.6.1'
4
+ STRING = '2.7.0.rc1'
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ # Generators are not automatically loaded by Rails
4
+ require 'generators/rspec/controller/controller_generator'
5
+
6
+ describe Rspec::Generators::ControllerGenerator do
7
+ # Tell the generator where to put its output (what it thinks of as Rails.root)
8
+ destination File.expand_path("../../../../../tmp", __FILE__)
9
+
10
+ before { prepare_destination }
11
+
12
+ describe 'controller specs' do
13
+ subject { file('spec/controllers/posts_controller_spec.rb') }
14
+ describe 'generated by default' do
15
+ before do
16
+ run_generator %w(posts)
17
+ end
18
+
19
+ describe 'the spec' do
20
+ it { should exist }
21
+ it { should contain /require 'spec_helper'/ }
22
+ it { should contain /describe PostsController/ }
23
+ end
24
+ end
25
+ describe 'skipped with a flag' do
26
+ before do
27
+ run_generator %w(posts --no-controller_specs)
28
+ end
29
+ it { should_not exist }
30
+ end
31
+ end
32
+
33
+ describe 'view specs' do
34
+ describe 'are not generated' do
35
+ describe 'with no-view-spec flag' do
36
+ before do
37
+ run_generator %w(posts index show --no-view-specs)
38
+ end
39
+ describe 'index.html.erb' do
40
+ subject { file('spec/views/posts/index.html.erb_spec.rb') }
41
+ it { should_not exist }
42
+ end
43
+ end
44
+ describe 'with no actions' do
45
+ before do
46
+ run_generator %w(posts)
47
+ end
48
+ describe 'index.html.erb' do
49
+ subject { file('spec/views/posts/index.html.erb_spec.rb') }
50
+ it { should_not exist }
51
+ end
52
+ end
53
+ end
54
+
55
+ describe 'are generated' do
56
+ describe 'with default template engine' do
57
+ before do
58
+ run_generator %w(posts index show)
59
+ end
60
+ describe 'index.html.erb' do
61
+ subject { file('spec/views/posts/index.html.erb_spec.rb') }
62
+ it { should exist }
63
+ it { should contain /require 'spec_helper'/ }
64
+ it { should contain /describe "posts\/index.html.erb"/ }
65
+ end
66
+ describe 'show.html.erb' do
67
+ subject { file('spec/views/posts/show.html.erb_spec.rb') }
68
+ it { should exist }
69
+ it { should contain /require 'spec_helper'/ }
70
+ it { should contain /describe "posts\/show.html.erb"/ }
71
+ end
72
+ end
73
+ describe 'with haml' do
74
+ before do
75
+ run_generator %w(posts index --template_engine haml)
76
+ end
77
+ describe 'index.html.haml' do
78
+ subject { file('spec/views/posts/index.html.haml_spec.rb') }
79
+ it { should exist }
80
+ it { should contain /require 'spec_helper'/ }
81
+ it { should contain /describe "posts\/index.html.haml"/ }
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ # Generators are not automatically loaded by Rails
4
+ require 'generators/rspec/helper/helper_generator'
5
+
6
+ describe Rspec::Generators::HelperGenerator do
7
+ # Tell the generator where to put its output (what it thinks of as Rails.root)
8
+ destination File.expand_path("../../../../../tmp", __FILE__)
9
+
10
+ before { prepare_destination }
11
+
12
+ subject { file('spec/helpers/posts_helper_spec.rb') }
13
+ describe 'generated by default' do
14
+ before do
15
+ run_generator %w(posts)
16
+ end
17
+
18
+ describe 'the spec' do
19
+ it { should exist }
20
+ it { should contain /require 'spec_helper'/ }
21
+ it { should contain /describe PostsHelper/ }
22
+ end
23
+ end
24
+ describe 'skipped with a flag' do
25
+ before do
26
+ run_generator %w(posts --no-helper_specs)
27
+ end
28
+ it { should_not exist }
29
+ end
30
+ end