rspec-rails23 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,45 @@
1
+ Copyright (c) 2010 Rob Sanheim & Chad Humphries
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+
23
+ The matchers and expectations are licensed:
24
+ (The MIT License)
25
+
26
+ Copyright (c) 2005-2008 The RSpec Development Team
27
+
28
+ Permission is hereby granted, free of charge, to any person obtaining
29
+ a copy of this software and associated documentation files (the
30
+ "Software"), to deal in the Software without restriction, including
31
+ without limitation the rights to use, copy, modify, merge, publish,
32
+ distribute, sublicense, and/or sell copies of the Software, and to
33
+ permit persons to whom the Software is furnished to do so, subject to
34
+ the following conditions:
35
+
36
+ The above copyright notice and this permission notice shall be
37
+ included in all copies or substantial portions of the Software.
38
+
39
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
40
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
41
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
42
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
43
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
44
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
45
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,25 @@
1
+ = Rspec-Rails23
2
+
3
+ Rspec 2 (prerelease) support for Rails 2.3.5.
4
+
5
+ This is being released based on production development and use at Relevance (http://thinkrelevance.com), based on an extraction from micronaut-rails that was developed for Rails 2.3.x As such, and based on Rails 2.3 days being numbered, it will most likely never have much of the features of the legacy rspec-rails (such as fixtures, integration tests, etc).
6
+
7
+ == DESCRIPTION:
8
+
9
+ == REQUIREMENTS:
10
+
11
+ * Ruby 1.8.6+
12
+ * Rails 2.3.5
13
+ * Rspec 2 (get it with "gem install rspec --prerelease")
14
+
15
+ == ISSUES
16
+
17
+ * No support for pure Rails fixtures at all, and no plans to add it - we use Factory Girl/Fixture Replacement instead.
18
+ * No support for Rails integration tests -- use Cucumber (http://github.com/aslakhellesoy/cucumber) instead!
19
+ * No support for < 2.3.5 - it may work, it may not. Not tested.
20
+
21
+ == CREDITS:
22
+
23
+ * RSpec for the great ideas and matchers
24
+ * Chad Humphries for Micronaut
25
+ * David Chelimsky and the Rspec-core team for Rspec
data/RSPEC-LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2005-2008 The RSpec Development Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |s|
4
+ s.name = "rspec-rails23"
5
+ s.summary = "Rspec Rails for 2.3.5"
6
+ s.email = "rsanheim@gmail.com"
7
+ s.homepage = "http://github.com/rsanheim/rspec-rails23"
8
+ s.description = "Rails 2.3.5 Extension for Rspec 2"
9
+ s.authors = ["Rob Sanheim"]
10
+ s.files = FileList["[A-Z]*", "{bin,lib,spec}/**/*"]
11
+ s.add_dependency "actionpack", '~> 2.3.0'
12
+ s.add_dependency "rspec", '~> 2.0.0.beta'
13
+ end
14
+ Jeweler::GemcutterTasks.new
15
+ rescue LoadError
16
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: gem install jeweler"
17
+ end
18
+
19
+ require 'rspec/core/rake_task'
20
+
21
+ desc "Run all specs"
22
+ Rspec::Core::RakeTask.new :spec do |t|
23
+ t.pattern = "spec/**/*_spec.rb"
24
+ end
25
+
26
+ namespace :spec do
27
+ desc "Run all specs using rcov"
28
+ Rspec::Core::RakeTask.new :coverage do |t|
29
+ t.pattern = "spec/**/*_spec.rb"
30
+ t.rcov = true
31
+ t.rcov_opts = %[--exclude "spec/*,gems/*,db/*,/Library/Ruby/*,config/*" --text-summary --sort coverage]
32
+ end
33
+ end
34
+
35
+ task :default => [:check_dependencies, :spec]
36
+
37
+ begin
38
+ %w{sdoc sdoc-helpers rdiscount}.each { |name| gem name }
39
+ require 'sdoc_helpers'
40
+ rescue LoadError => ex
41
+ puts "sdoc support not enabled:"
42
+ puts ex.inspect
43
+ end
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ''
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "Rspec-Rails #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
53
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,48 @@
1
+ module Rspec
2
+ module Rails23
3
+
4
+ module Configuration
5
+
6
+ def rails
7
+ self
8
+ end
9
+
10
+ # :behaviour => { :describes => lambda { |dt| dt < ActiveRecord::Base }
11
+ def enable_active_record_transactional_support(filter_options={})
12
+ Rspec.configuration.extend(::Rspec::Rails23::TransactionalDatabaseSupport, filter_options)
13
+ end
14
+
15
+ # :behaviour => { :describes => lambda { |dt| dt.to_s.ends_with?('Helper') }
16
+ def enable_helper_support(filter_options={})
17
+ Rspec.configuration.extend(::Rspec::Rails23::Helpers, filter_options)
18
+ end
19
+
20
+ # :behaviour => { :describes => lambda { |dt| dt < ActionController::Base }
21
+ def enable_controller_support(filter_options={})
22
+ Rspec.configuration.extend(::Rspec::Rails23::Controllers, filter_options)
23
+ end
24
+
25
+ def enable_rails_specific_mocking_extensions(filter_options={})
26
+ case Rspec.configuration.options[:mock_framework].to_s
27
+ when /mocha/i
28
+ require 'rspec/rails23/mocking/with_mocha'
29
+ Rspec.configuration.include(::Rspec::Rails23::Mocking::WithMocha, filter_options)
30
+ when /rr/i
31
+ require 'rspec/rails23/mocking/with_rr'
32
+ Rspec.configuration.include(::Rspec::Rails23::Mocking::WithRR, filter_options)
33
+ end
34
+ end
35
+
36
+ def enable_reasonable_defaults!
37
+ enable_active_record_transactional_support
38
+ enable_helper_support :behaviour => { :describes => lambda { |dt| dt.to_s.ends_with?('Helper') } }
39
+ enable_controller_support :behaviour => { :describes => lambda { |dt| dt < ::ActionController::Base } }
40
+ enable_rails_specific_mocking_extensions
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+ end
47
+
48
+ ::Rspec::Core::Configuration.send(:include, ::Rspec::Rails23::Configuration)
@@ -0,0 +1,86 @@
1
+ require 'action_controller'
2
+ require 'action_controller/test_process'
3
+
4
+ module Rspec
5
+ module Rails23
6
+ module Controllers
7
+
8
+ module InstanceMethods
9
+ attr_reader :request, :response, :controller
10
+
11
+ def route_for(options)
12
+ ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty?
13
+ ActionController::Routing::Routes.generate(options)
14
+ end
15
+
16
+ def params_from(method, path)
17
+ ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty?
18
+ ActionController::Routing::Routes.recognize_path(path, :method => method)
19
+ end
20
+
21
+ end
22
+
23
+ module TemplateIsolationExtensions
24
+ def file_exists?(ignore); true; end
25
+
26
+ def render_file(*args)
27
+ @first_render ||= args[0] unless args[0] =~ /^layouts/
28
+ end
29
+
30
+ def render(*args)
31
+ return super if Hash === args.last && args.last[:inline]
32
+ record_render(args[0])
33
+ end
34
+
35
+ private
36
+
37
+ def record_render(opts)
38
+ @_rendered ||= {}
39
+ (@_rendered[:template] ||= opts[:file]) if opts[:file]
40
+ (@_rendered[:partials][opts[:partial]] += 1) if opts[:partial]
41
+ end
42
+
43
+ end
44
+
45
+
46
+ module RenderOverrides
47
+
48
+ def render_views!
49
+ @render_views = true
50
+ end
51
+
52
+ def rendering_views?
53
+ @render_views
54
+ end
55
+
56
+ def render(options=nil, extra_options={}, &block)
57
+ unless block_given?
58
+ unless rendering_views?
59
+ @template.extend TemplateIsolationExtensions
60
+ end
61
+ end
62
+
63
+ super
64
+ end
65
+
66
+ end
67
+
68
+ def self.extended(extended_behaviour)
69
+ extended_behaviour.send :include, ::ActionController::TestProcess, InstanceMethods, ::Rspec::Rails23::Matchers::Controllers
70
+ extended_behaviour.describes.send :include, RenderOverrides, ::ActionController::TestCase::RaiseActionExceptions
71
+
72
+ extended_behaviour.before do
73
+ @request = ::ActionController::TestRequest.new
74
+ @response = ::ActionController::TestResponse.new
75
+ @controller = self.class.describes.new
76
+
77
+ @controller.request = @request
78
+ @controller.params = {}
79
+ @controller.send(:initialize_current_url)
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,19 @@
1
+ module Rspec
2
+ module Rails23
3
+ module Extensions
4
+
5
+ module ActiveRecord
6
+ def errors_on(attribute)
7
+ self.valid?
8
+ [self.errors.on(attribute)].flatten.compact
9
+ end
10
+ alias :error_on :errors_on
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+
17
+ if defined?(::ActiveRecord::Base)
18
+ ::ActiveRecord::Base.send(:include, ::Rspec::Rails23::Extensions::ActiveRecord)
19
+ end
@@ -0,0 +1,99 @@
1
+ module Rspec
2
+ module Rails23
3
+ module Helpers
4
+
5
+ class HelperController < ActionController::Base; end
6
+
7
+ module InstanceMethods
8
+
9
+ class HelperObject < ActionView::Base
10
+ def protect_against_forgery?
11
+ false
12
+ end
13
+
14
+ def session=(session)
15
+ @session = session
16
+ end
17
+
18
+ def request=(request)
19
+ @request = request
20
+ end
21
+
22
+ def flash=(flash)
23
+ @flash = flash
24
+ end
25
+
26
+ def params=(params)
27
+ @params = params
28
+ end
29
+
30
+ def controller=(controller)
31
+ @controller = controller
32
+ end
33
+
34
+ private
35
+ attr_reader :session, :request, :flash, :params, :controller
36
+ end
37
+
38
+ def helper
39
+ @helper_object ||= returning HelperObject.new do |helper_object|
40
+ if self.class.describes.class == Module
41
+ helper_object.extend self.class.describes
42
+ end
43
+ end
44
+ end
45
+
46
+ def params
47
+ request.parameters
48
+ end
49
+
50
+ def flash
51
+ response.flash
52
+ end
53
+
54
+ def session
55
+ response.session
56
+ end
57
+
58
+ def method_missing(sym, *args)
59
+ if helper.respond_to?(sym)
60
+ helper.send(sym, *args)
61
+ else
62
+ super
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ def self.extended(kls)
69
+ kls.send(:include, InstanceMethods)
70
+
71
+ kls.send(:attr_reader, :request, :response)
72
+
73
+ ActionView::Base.included_modules.reverse.each do |mod|
74
+ kls.send(:include, mod) if mod.parents.include?(ActionView::Helpers)
75
+ end
76
+
77
+ kls.before do
78
+ @controller = ::Rspec::Rails23::Helpers::HelperController.new
79
+ @request = ActionController::TestRequest.new
80
+ @response = ActionController::TestResponse.new
81
+ @response.session = @request.session
82
+ @controller.request = @request
83
+ @flash = ActionController::Flash::FlashHash.new
84
+ @response.session['flash'] = @flash
85
+
86
+ ActionView::Helpers::AssetTagHelper::reset_javascript_include_default
87
+
88
+ helper.session = @response.session
89
+ helper.request = @request
90
+ helper.flash = @flash
91
+ helper.params = params
92
+ helper.controller = @controller
93
+ end
94
+
95
+ end
96
+
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,115 @@
1
+ module Rspec
2
+ module Rails23
3
+ module Matchers
4
+ module Controllers
5
+
6
+ class RedirectTo #:nodoc:
7
+
8
+ def initialize(request, expected)
9
+ @expected = expected
10
+ @request = request
11
+ end
12
+
13
+ def matches?(response)
14
+ @redirected = response.redirect?
15
+ @actual = response.redirect_url
16
+ return false unless @redirected
17
+ if @expected.instance_of? Hash
18
+ return false unless @actual =~ %r{^\w+://#{@request.host}}
19
+ return false unless actual_redirect_to_valid_route
20
+ return actual_hash == expected_hash
21
+ else
22
+ return @actual == expected_url
23
+ end
24
+ end
25
+
26
+ def actual_hash
27
+ hash_from_url @actual
28
+ end
29
+
30
+ def expected_hash
31
+ hash_from_url expected_url
32
+ end
33
+
34
+ def actual_redirect_to_valid_route
35
+ actual_hash
36
+ end
37
+
38
+ def hash_from_url(url)
39
+ query_hash(url).merge(path_hash(url)).with_indifferent_access
40
+ end
41
+
42
+ def path_hash(url)
43
+ path = url.sub(%r{^\w+://#{@request.host}(?::\d+)?}, "").split("?", 2)[0]
44
+ ActionController::Routing::Routes.recognize_path path
45
+ end
46
+
47
+ def query_hash(url)
48
+ query = url.split("?", 2)[1] || ""
49
+ QueryParameterParser.parse_query_parameters(query, @request)
50
+ end
51
+
52
+ def expected_url
53
+ case @expected
54
+ when Hash
55
+ return ActionController::UrlRewriter.new(@request, {}).rewrite(@expected)
56
+ when :back
57
+ return @request.env['HTTP_REFERER']
58
+ when %r{^\w+://.*}
59
+ return @expected
60
+ else
61
+ return "http://#{@request.host}" + (@expected.split('')[0] == '/' ? '' : '/') + @expected
62
+ end
63
+ end
64
+
65
+ def failure_message
66
+ if @redirected
67
+ return %Q{expected redirect to #{@expected.inspect}, got redirect to #{@actual.inspect}}
68
+ else
69
+ return %Q{expected redirect to #{@expected.inspect}, got no redirect}
70
+ end
71
+ end
72
+
73
+ def negative_failure_message
74
+ return %Q{expected not to be redirected to #{@expected.inspect}, but was} if @redirected
75
+ end
76
+
77
+ def description
78
+ "redirect to #{@actual.inspect}"
79
+ end
80
+
81
+ class QueryParameterParser
82
+ def self.parse_query_parameters(query, request)
83
+ if defined?(CGIMethods)
84
+ CGIMethods.parse_query_parameters(query)
85
+ else
86
+ request.class.parse_query_parameters(query)
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ # :call-seq:
93
+ # response.should redirect_to(url)
94
+ # response.should redirect_to(:action => action_name)
95
+ # response.should redirect_to(:controller => controller_name, :action => action_name)
96
+ # response.should_not redirect_to(url)
97
+ # response.should_not redirect_to(:action => action_name)
98
+ # response.should_not redirect_to(:controller => controller_name, :action => action_name)
99
+ #
100
+ # Passes if the response is a redirect to the url, action or controller/action.
101
+ # Useful in controller specs (integration or isolation mode).
102
+ #
103
+ # == Examples
104
+ #
105
+ # response.should redirect_to("path/to/action")
106
+ # response.should redirect_to("http://test.host/path/to/action")
107
+ # response.should redirect_to(:action => 'list')
108
+ def redirect_to(opts)
109
+ RedirectTo.new(request, opts)
110
+ end
111
+
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,116 @@
1
+ module Rspec
2
+ module Rails23
3
+ module Matchers
4
+ module Controllers
5
+
6
+ class RenderTemplate #:nodoc:
7
+
8
+ def initialize(expected, controller)
9
+ @controller = controller
10
+ @expected = expected
11
+ end
12
+
13
+ def matches?(response_or_controller)
14
+ response = response_or_controller.respond_to?(:response) ?
15
+ response_or_controller.response :
16
+ response_or_controller
17
+
18
+ if response.respond_to?(:rendered_file)
19
+ @actual = response.rendered_file
20
+ elsif response.respond_to?(:rendered)
21
+ case template = response.rendered[:template]
22
+ when nil
23
+ unless response.rendered[:partials].empty?
24
+ @actual = path_and_file(response.rendered[:partials].keys.first).join("/_")
25
+ end
26
+ when ActionView::Template
27
+ @actual = template.path
28
+ when String
29
+ @actual = template
30
+ end
31
+ else
32
+ @actual = response.rendered_template.to_s
33
+ end
34
+ return false if @actual.blank?
35
+ given_controller_path, given_file = path_and_file(@actual)
36
+ expected_controller_path, expected_file = path_and_file(@expected)
37
+ given_controller_path == expected_controller_path && given_file.match(expected_file)
38
+ end
39
+
40
+ def failure_message
41
+ "expected #{@expected.inspect}, got #{@actual.inspect}"
42
+ end
43
+
44
+ def negative_failure_message
45
+ "expected not to render #{@expected.inspect}, but did"
46
+ end
47
+
48
+ def description
49
+ "render template #{@expected.inspect}"
50
+ end
51
+
52
+ private
53
+ def path_and_file(path)
54
+ parts = path.split('/')
55
+ file = parts.pop
56
+ controller = parts.empty? ? current_controller_path : parts.join('/')
57
+ return controller, file
58
+ end
59
+
60
+ def controller_path_from(path)
61
+ parts = path.split('/')
62
+ parts.pop
63
+ parts.join('/')
64
+ end
65
+
66
+ def current_controller_path
67
+ @controller.class.to_s.underscore.gsub(/_controller$/,'')
68
+ end
69
+
70
+ end
71
+
72
+ # :call-seq:
73
+ # response.should render_template(template)
74
+ # response.should_not render_template(template)
75
+ #
76
+ # For use in controller code examples (integration or isolation mode).
77
+ #
78
+ # Passes if the specified template (view file) is rendered by the
79
+ # response. This file can be any view file, including a partial. However
80
+ # if it is a partial it must be rendered directly i.e. you can't detect
81
+ # that a partial has been rendered as part of a view using
82
+ # render_template. For that you should use a message expectation
83
+ # (mock) instead:
84
+ #
85
+ # controller.should_receive(:render).with(:partial => 'path/to/partial')
86
+ #
87
+ # <code>template</code> can include the controller path. It can also
88
+ # include an optional extension, which you only need to use when there
89
+ # is ambiguity.
90
+ #
91
+ # Note that partials must be spelled with the preceding underscore.
92
+ #
93
+ # == Examples
94
+ #
95
+ # response.should render_template('list')
96
+ # response.should render_template('same_controller/list')
97
+ # response.should render_template('other_controller/list')
98
+ #
99
+ # # with extensions
100
+ # response.should render_template('list.rjs')
101
+ # response.should render_template('list.haml')
102
+ # response.should render_template('same_controller/list.rjs')
103
+ # response.should render_template('other_controller/list.rjs')
104
+ #
105
+ # # partials
106
+ # response.should render_template('_a_partial')
107
+ # response.should render_template('same_controller/_a_partial')
108
+ # response.should render_template('other_controller/_a_partial')
109
+ def render_template(path)
110
+ RenderTemplate.new(path.to_s, @controller)
111
+ end
112
+
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,24 @@
1
+ module Rspec
2
+ module Rails23
3
+ module Mocking
4
+
5
+ module ModelStubber
6
+
7
+ def connection
8
+ raise ::Rspec::Rails23::IllegalDataAccessException.new("stubbed/mocked models are not allowed to access the database")
9
+ end
10
+
11
+ def new_record?
12
+ id.nil?
13
+ end
14
+
15
+ def as_new_record
16
+ self.id = nil
17
+ self
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,72 @@
1
+ module Rspec
2
+ module Rails23
3
+ module Mocking
4
+ module WithMocha
5
+
6
+ def stub_model(model_class, params = {})
7
+ params = params.dup
8
+ model = model_class.new
9
+ model.id = params.delete(:id) || next_id
10
+ model.extend ::Rspec::Rails23::Mocking::ModelStubber
11
+
12
+ params.keys.each do |prop|
13
+ model[prop] = params.delete(prop) if model.has_attribute?(prop)
14
+ end
15
+ add_stubs(model, params)
16
+
17
+ yield model if block_given?
18
+ model
19
+ end
20
+
21
+ # Stubs methods on +object+ (if +object+ is a symbol or string a new mock
22
+ # with that name will be created). +stubs+ is a Hash of +method=>value+
23
+ def add_stubs(object, params) # :nodoc:
24
+ m = [String, Symbol].include?(object.class) ? mock(object.to_s) : object
25
+ params.each { |prop, value| m.stubs(prop).returns(value) }
26
+ m
27
+ end
28
+
29
+ def mock_model(model_class, params = {})
30
+ id = params[:id] || next_id
31
+ model = stub("#{model_class.name}_#{id}", {
32
+ :id => id,
33
+ :to_param => id.to_s,
34
+ :new_record? => false,
35
+ :errors => stub("errors", :count => 0)
36
+ }.update(params))
37
+
38
+ model.instance_eval <<-CODE
39
+ def as_new_record
40
+ self.stubs(:id).returns(nil)
41
+ self.stubs(:to_param).returns(nil)
42
+ self.stubs(:new_record?).returns(true)
43
+ self
44
+ end
45
+ def is_a?(other)
46
+ #{model_class}.ancestors.include?(other)
47
+ end
48
+ def kind_of?(other)
49
+ #{model_class}.ancestors.include?(other)
50
+ end
51
+ def instance_of?(other)
52
+ other == #{model_class}
53
+ end
54
+ def class
55
+ #{model_class}
56
+ end
57
+ CODE
58
+
59
+ yield model if block_given?
60
+ return model
61
+ end
62
+
63
+ private
64
+ @@model_id = 1000
65
+ def next_id
66
+ @@model_id += 1
67
+ end
68
+
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,44 @@
1
+ module Rspec
2
+ module Rails23
3
+ module Mocking
4
+
5
+ module WithRR
6
+ # Creates a mock object instance for a +model_class+ with common
7
+ # methods stubbed out. Additional methods may be easily stubbed (via
8
+ # add_stubs) if +stubs+ is passed.
9
+ def mock_or_stub_model(model_class, mock_or_stub, options = {})
10
+ model = model_class.new
11
+ model.extend ::Rspec::Rails23::Mocking::ModelStubber
12
+ model_id = next_id
13
+
14
+ stub(errors_stub = Object.new).count.returns(0)
15
+ full_params = { :id => model_id, :new_record? => false, :errors => errors_stub }.update(options)
16
+
17
+ full_params.each do |method, value|
18
+ eval "#{mock_or_stub}(model).#{method}.returns(value)", binding, __FILE__, __LINE__
19
+ end
20
+
21
+ yield model if block_given?
22
+ model
23
+ end
24
+
25
+ def mock_model(model_class, options = {})
26
+ mock_or_stub_model(model_class, 'mock', options)
27
+ end
28
+
29
+ def stub_model(model_class, options = {})
30
+ mock_or_stub_model(model_class, 'stub', options)
31
+ end
32
+
33
+ private
34
+
35
+ @@model_id = 1000
36
+ def next_id
37
+ @@model_id += 1
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,39 @@
1
+ module Rspec
2
+ module Rails23
3
+ module TransactionalDatabaseSupport
4
+
5
+ module InstanceMethods
6
+
7
+ def active_record_configured?
8
+ defined?(::ActiveRecord) && !::ActiveRecord::Base.configurations.blank?
9
+ end
10
+
11
+ def transactional_protection_start
12
+ return unless active_record_configured?
13
+
14
+ ::ActiveRecord::Base.connection.increment_open_transactions
15
+ ::ActiveRecord::Base.connection.begin_db_transaction
16
+ end
17
+
18
+ def transactional_protection_cleanup
19
+ return unless active_record_configured?
20
+
21
+ if ::ActiveRecord::Base.connection.open_transactions != 0
22
+ ::ActiveRecord::Base.connection.rollback_db_transaction
23
+ ::ActiveRecord::Base.connection.decrement_open_transactions
24
+ end
25
+
26
+ ::ActiveRecord::Base.clear_active_connections!
27
+ end
28
+
29
+ end
30
+
31
+ def self.extended(kls)
32
+ kls.send(:include, InstanceMethods)
33
+ kls.before { transactional_protection_start }
34
+ kls.after { transactional_protection_cleanup }
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,17 @@
1
+ require 'rspec/core'
2
+ require 'rspec/rails23/configuration'
3
+ require 'rspec/rails23/matchers/controllers/redirect_to'
4
+ require 'rspec/rails23/matchers/controllers/render_template'
5
+ require 'rspec/rails23/transactional_database_support'
6
+ require 'rspec/rails23/controllers'
7
+ require 'rspec/rails23/helpers'
8
+ require 'rspec/rails23/extensions/active_record'
9
+ require 'rspec/rails23/mocking/model_stubber'
10
+
11
+ module Rspec
12
+ module Rails23
13
+ class IllegalDataAccessException < StandardError; end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,46 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../spec_helper")
2
+
3
+ describe Rspec::Core::Configuration do
4
+
5
+ example "loading rspec rails23 includes it in the configuration class" do
6
+ Rspec::Core::Configuration.included_modules.should include(Rspec::Rails23::Configuration)
7
+ end
8
+
9
+ it "adds a #rails method" do
10
+ Rspec::Core::Configuration.new.should respond_to(:rails)
11
+ end
12
+
13
+ it "adds an #enable_active_record_transactional_support method" do
14
+ Rspec::Core::Configuration.new.should respond_to(:enable_active_record_transactional_support)
15
+ end
16
+
17
+ describe "helpers for standard Rails23 testing support" do
18
+ Rspec::Core::Configuration.class_eval do
19
+ attr_reader :include_or_extend_modules
20
+ end
21
+ method_to_modules = { :enable_helper_support => Rspec::Rails23::Helpers,
22
+ :enable_active_record_transactional_support => Rspec::Rails23::TransactionalDatabaseSupport,
23
+ :enable_controller_support => Rspec::Rails23::Controllers
24
+ }
25
+ method_to_modules.each do |method, mod|
26
+ example "##{method} with no filter options" do
27
+ Rspec.configuration.send(method)
28
+ Rspec.configuration.include_or_extend_modules.should include([:extend, mod, {}])
29
+ end
30
+
31
+ example "##{method} with filter options" do
32
+ filter_options = {:options => { "foo" => "bar" } }
33
+ Rspec.configuration.send(method, filter_options)
34
+ Rspec.configuration.include_or_extend_modules.should include([:extend, mod, filter_options])
35
+ end
36
+ end
37
+
38
+ example "#enable_Rails23_specific_mocking_extensions for mocha with no filter options" do
39
+ Rspec.configuration.mock_with :mocha
40
+ Rspec.configuration.enable_rails_specific_mocking_extensions
41
+ Rspec.configuration.include_or_extend_modules.should include([:include, Rspec::Rails23::Mocking::WithMocha, {}])
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,48 @@
1
+ lib_path = File.expand_path(File.dirname(__FILE__) + "/../lib")
2
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
3
+
4
+ require 'rubygems'
5
+ gem "actionpack", '~> 2.3'
6
+ require 'action_controller'
7
+
8
+ gem "rspec-core", "~> 2.0.0.beta"
9
+ require 'rspec/core'
10
+ require 'rspec-rails23'
11
+
12
+ gem "mocha"
13
+
14
+ module Rspec
15
+ module Core
16
+ module Matchers
17
+ def fail
18
+ raise_error(::Rspec::Expectations::ExpectationNotMetError)
19
+ end
20
+
21
+ def fail_with(message)
22
+ raise_error(::Rspec::Expectations::ExpectationNotMetError, message)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def remove_last_describe_from_world
29
+ Rspec::Core.world.example_groups.pop
30
+ end
31
+
32
+ class DummyFormatter < Rspec::Core::Formatters::BaseTextFormatter; end
33
+
34
+ def dummy_reporter
35
+ DummyFormatter.new({}, StringIO.new)
36
+ end
37
+
38
+ def use_color?
39
+ !ENV.has_key?('TM_MODE')
40
+ end
41
+
42
+ Rspec.configure do |config|
43
+ config.mock_with :mocha
44
+ config.color_enabled = use_color?
45
+ config.formatter = :documentation
46
+ config.filter_run :focused => true
47
+ config.run_all_when_everything_filtered = true
48
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-rails23
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Rob Sanheim
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-06 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: actionpack
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 3
30
+ - 0
31
+ version: 2.3.0
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: rspec
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 2
43
+ - 0
44
+ - 0
45
+ - beta
46
+ version: 2.0.0.beta
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ description: Rails 2.3.5 Extension for Rspec 2
50
+ email: rsanheim@gmail.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files:
56
+ - LICENSE
57
+ - README
58
+ files:
59
+ - LICENSE
60
+ - README
61
+ - RSPEC-LICENSE
62
+ - Rakefile
63
+ - VERSION
64
+ - lib/rspec-rails23.rb
65
+ - lib/rspec/rails23/configuration.rb
66
+ - lib/rspec/rails23/controllers.rb
67
+ - lib/rspec/rails23/extensions/active_record.rb
68
+ - lib/rspec/rails23/helpers.rb
69
+ - lib/rspec/rails23/matchers/controllers/redirect_to.rb
70
+ - lib/rspec/rails23/matchers/controllers/render_template.rb
71
+ - lib/rspec/rails23/mocking/model_stubber.rb
72
+ - lib/rspec/rails23/mocking/with_mocha.rb
73
+ - lib/rspec/rails23/mocking/with_rr.rb
74
+ - lib/rspec/rails23/transactional_database_support.rb
75
+ - spec/lib/rspec/rails23/configuration_spec.rb
76
+ - spec/spec_helper.rb
77
+ has_rdoc: true
78
+ homepage: http://github.com/rsanheim/rspec-rails23
79
+ licenses: []
80
+
81
+ post_install_message:
82
+ rdoc_options:
83
+ - --charset=UTF-8
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ segments:
98
+ - 0
99
+ version: "0"
100
+ requirements: []
101
+
102
+ rubyforge_project:
103
+ rubygems_version: 1.3.6
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Rspec Rails for 2.3.5
107
+ test_files:
108
+ - spec/lib/rspec/rails23/configuration_spec.rb
109
+ - spec/spec_helper.rb