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.
Files changed (52) hide show
  1. data/.gitignore +2 -1
  2. data/Gemfile +7 -0
  3. data/Gotchas.markdown +14 -0
  4. data/README.markdown +49 -9
  5. data/Rakefile +1 -2
  6. data/Upgrade.markdown +7 -0
  7. data/VERSION +1 -1
  8. data/features/controller_specs/anonymous_controller.feature +57 -19
  9. data/features/controller_specs/isolation_from_views.feature +2 -2
  10. data/features/controller_specs/readers.feature +1 -1
  11. data/features/controller_specs/render_views.feature +4 -4
  12. data/features/helper_specs/helper_spec.feature +53 -0
  13. data/features/mailer_specs/url_helpers.feature +2 -2
  14. data/features/matchers/new_record_matcher.feature +46 -1
  15. data/features/matchers/redirect_to_matcher.feature +41 -0
  16. data/features/matchers/render_template_matcher.feature +25 -0
  17. data/features/mocks/mock_model.feature +131 -0
  18. data/features/mocks/stub_model.feature +58 -0
  19. data/features/routing_specs/access_to_named_routes.feature +15 -0
  20. data/features/support/env.rb +1 -0
  21. data/features/view_specs/inferred_controller_path.feature +44 -0
  22. data/lib/generators/rspec/install/templates/spec/spec_helper.rb +4 -5
  23. data/lib/generators/rspec/scaffold/templates/routing_spec.rb +2 -2
  24. data/lib/rspec/rails.rb +1 -4
  25. data/lib/rspec/rails/adapters.rb +32 -6
  26. data/lib/rspec/rails/browser_simulators.rb +30 -0
  27. data/lib/rspec/rails/example.rb +2 -1
  28. data/lib/rspec/rails/example/controller_example_group.rb +36 -16
  29. data/lib/rspec/rails/example/helper_example_group.rb +8 -4
  30. data/lib/rspec/rails/example/mailer_example_group.rb +11 -2
  31. data/lib/rspec/rails/example/model_example_group.rb +1 -1
  32. data/lib/rspec/rails/example/rails_example_group.rb +11 -0
  33. data/lib/rspec/rails/example/request_example_group.rb +17 -6
  34. data/lib/rspec/rails/example/routing_example_group.rb +6 -1
  35. data/lib/rspec/rails/example/view_example_group.rb +18 -14
  36. data/lib/rspec/rails/matchers/be_a_new.rb +36 -1
  37. data/lib/rspec/rails/mocks.rb +9 -8
  38. data/lib/rspec/rails/tasks/rspec.rake +7 -0
  39. data/lib/rspec/rails/view_rendering.rb +8 -2
  40. data/rspec-rails.gemspec +21 -14
  41. data/spec/rspec/rails/assertion_adapter_spec.rb +28 -0
  42. data/spec/rspec/rails/example/helper_example_group_spec.rb +2 -0
  43. data/spec/rspec/rails/example/routing_example_group_spec.rb +17 -0
  44. data/spec/rspec/rails/example/view_rendering_spec.rb +56 -15
  45. data/spec/rspec/rails/matchers/be_a_new_spec.rb +98 -0
  46. data/spec/rspec/rails/matchers/errors_on_spec.rb +4 -4
  47. data/spec/rspec/rails/mocks/ar_classes.rb +17 -0
  48. data/spec/rspec/rails/mocks/stub_model_spec.rb +36 -15
  49. data/templates/Gemfile +2 -0
  50. metadata +23 -34
  51. data/lib/rspec/rails/monkey.rb +0 -1
  52. 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"
@@ -1,4 +1,5 @@
1
1
  require 'aruba'
2
+ require 'webrat'
2
3
 
3
4
  unless File.directory?('./tmp/example_app')
4
5
  system "rake generate:app generate:stuff"
@@ -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 ~/spec when you run 'ruby script/generate rspec'
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 ./support/ and its subdirectories.
9
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
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
- <% unless options[:singleton] -%>
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
- <% end -%>
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
@@ -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
-
@@ -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
- def method_name
23
- @example
28
+
29
+ class AssertionDelegate
30
+ include Test::Unit::Assertions
24
31
  end
25
32
 
26
- include Test::Unit::Assertions
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
- included do
29
- before do
30
- @_result = Struct.new(:add_assertion).new
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