micronaut-rails 0.3.3

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) 2008 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
+ = Micronaut Rails
2
+
3
+ * http://github.com/spicycode/micronaut-rails
4
+ * http://relevance.lighthouseapp.com/projects/22819-micronaut
5
+
6
+ == DESCRIPTION:
7
+
8
+ Micronaut Rails is a set of extension to deal with rails mode testing. For the moment think of it is a prototype of
9
+ RSpec lite. Definitely pre alpha at the moment.
10
+
11
+ == REQUIREMENTS:
12
+
13
+ * Ruby 1.8.6+
14
+ * ActionPack
15
+ * Micronaut (via spicycode-micronaut on GitHub)
16
+
17
+ == ISSUES
18
+
19
+ * No support for pure Rails fixtures, and no plans to add it - we use Factory Girl/Fixture Replacement instead, so send a patch if you want support for this).
20
+ * No support for Rails integration tests -- use Cucumber (http://github.com/aslakhellesoy/cucumber) instead!
21
+ * In use in real-world projects on Rails 2.3+ - older versions may have issues.
22
+
23
+ == CREDITS:
24
+
25
+ * RSpec for the great ideas and matchers
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,37 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |s|
4
+ s.name = "micronaut-rails"
5
+ s.summary = "An excellent replacement for the wheel on rails..."
6
+ s.email = "chad@spicycode.com"
7
+ s.homepage = "http://github.com/spicycode/micronaut-rails"
8
+ s.description = "An excellent replacement for the wheel on rails..."
9
+ s.authors = ["Chad Humphries"]
10
+ s.files = FileList["[A-Z]*", "{bin,lib,examples}/**/*"]
11
+ s.add_dependency "actionpack", '>= 2.3.0'
12
+ s.add_dependency "micronaut", '>= 0.3.0'
13
+ end
14
+ rescue LoadError
15
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
16
+ end
17
+
18
+ gem 'micronaut'
19
+ require 'micronaut/rake_task'
20
+
21
+ desc "Run all micronaut examples"
22
+ Micronaut::RakeTask.new :examples do |t|
23
+ t.pattern = "examples/**/*_example.rb"
24
+ end
25
+
26
+ namespace :examples do
27
+
28
+ desc "Run all micronaut examples using rcov"
29
+ Micronaut::RakeTask.new :coverage do |t|
30
+ t.pattern = "examples/**/*_example.rb"
31
+ t.rcov = true
32
+ t.rcov_opts = %[--exclude "examples/*,gems/*,db/*,/Library/Ruby/*,config/*" --text-summary --sort coverage]
33
+ end
34
+
35
+ end
36
+
37
+ task :default => 'examples:coverage'
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 3
3
+ :major: 0
4
+ :minor: 3
@@ -0,0 +1,56 @@
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
+
6
+ begin
7
+ gem "micronaut", ">= 0.3.0"
8
+ rescue LoadError => e
9
+ puts "\nERROR - This version of micronaut-rails requires micronaut 0.2.2 or higher."
10
+ puts "gem install micronaut --version 0.2.2"
11
+ puts
12
+ exit(1)
13
+ end
14
+ require 'action_controller'
15
+ require 'micronaut'
16
+ require 'micronaut-rails'
17
+
18
+ gem "mocha"
19
+
20
+ module Micronaut
21
+ module Matchers
22
+ def fail
23
+ raise_error(::Micronaut::Expectations::ExpectationNotMetError)
24
+ end
25
+
26
+ def fail_with(message)
27
+ raise_error(::Micronaut::Expectations::ExpectationNotMetError, message)
28
+ end
29
+ end
30
+ end
31
+
32
+ def remove_last_describe_from_world
33
+ Micronaut.world.behaviours.pop
34
+ end
35
+
36
+ class DummyFormatter < Micronaut::Formatters::BaseTextFormatter; end
37
+
38
+ def dummy_reporter
39
+ DummyFormatter.new({}, StringIO.new)
40
+ end
41
+
42
+ def use_color?
43
+ !ENV.has_key?('TM_MODE')
44
+ end
45
+
46
+ # allow including links to lighthouse tickets in examples, for regression tests, pending features, etc.
47
+ def ticket(number)
48
+ %[http://relevance.lighthouseapp.com/projects/22819-micronaut/tickets/#{number}]
49
+ end
50
+
51
+ Micronaut.configure do |config|
52
+ config.mock_with :mocha
53
+ config.color_enabled = use_color?
54
+ config.formatter = :documentation
55
+ config.filter_run :focused => true
56
+ end
@@ -0,0 +1,44 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../example_helper")
2
+
3
+ describe Micronaut::Rails::Configuration do
4
+
5
+ example "loading micronaut rails include it in the micronaut configuration class" do
6
+ Micronaut::Configuration.included_modules.should include(Micronaut::Rails::Configuration)
7
+ end
8
+
9
+ it "should add a #rails method" do
10
+ Micronaut.configuration.should respond_to(:rails)
11
+ end
12
+
13
+ it "should add an #enable_active_record_transactional_support method" do
14
+ Micronaut.configuration.should respond_to(:enable_active_record_transactional_support)
15
+ end
16
+
17
+ describe "helpers for standard Rails testing support" do
18
+
19
+ method_to_modules = { :enable_helper_support => Micronaut::Rails::Helpers,
20
+ :enable_active_record_transactional_support => Micronaut::Rails::TransactionalDatabaseSupport,
21
+ :enable_controller_support => Micronaut::Rails::Controllers
22
+ }
23
+ method_to_modules.each do |method, mod|
24
+ example "##{method} with no filter options" do
25
+ Micronaut.configuration.send(method)
26
+ Micronaut.configuration.include_or_extend_modules.should include([:extend, mod, {}])
27
+ end
28
+
29
+ example "##{method} with filter options" do
30
+ filter_options = {:options => { "foo" => "bar" } }
31
+ Micronaut.configuration.send(method, filter_options)
32
+ Micronaut.configuration.include_or_extend_modules.should include([:extend, mod, filter_options])
33
+ end
34
+ end
35
+
36
+ example "#enable_rails_specific_mocking_extensions for mocha with no filter options" do
37
+ Micronaut.configuration.mock_with :mocha
38
+ Micronaut.configuration.enable_rails_specific_mocking_extensions
39
+ Micronaut.configuration.include_or_extend_modules.should include([:include, Micronaut::Rails::Mocking::WithMocha, {}])
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../example_helper")
2
+
3
+ describe Micronaut::Rails do
4
+
5
+ pending "should never include lib/autotest in the gemspec, as it breaks autotest for Micronaut - see #{ticket 4}
6
+ PENDING due to jeweler changing the gemspec tasks..." do
7
+ # We jump through hoops to make sure the Rake deprecation notice doesn't show up in the build (via stderr) or
8
+ # in the gemspec itself
9
+ silence_stream(STDERR) do
10
+ @spec_string = `rake --silent gemspec`
11
+ end
12
+ @spec_string.gsub! /Gem::manage_gems is deprecated/, ""
13
+ gem_spec = eval(@spec_string)
14
+ gem_spec.files.each { |f| f.should_not match(%r|lib/autotest|) }
15
+ end
16
+ end
@@ -0,0 +1,48 @@
1
+ module Micronaut
2
+ module Rails
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
+ ::Micronaut.configuration.extend(::Micronaut::Rails::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
+ ::Micronaut.configuration.extend(::Micronaut::Rails::Helpers, filter_options)
18
+ end
19
+
20
+ # :behaviour => { :describes => lambda { |dt| dt < ActionController::Base }
21
+ def enable_controller_support(filter_options={})
22
+ ::Micronaut.configuration.extend(::Micronaut::Rails::Controllers, filter_options)
23
+ end
24
+
25
+ def enable_rails_specific_mocking_extensions(filter_options={})
26
+ case ::Micronaut.configuration.mock_framework.to_s
27
+ when /mocha/i
28
+ require 'micronaut/rails/mocking/with_mocha'
29
+ ::Micronaut.configuration.include(::Micronaut::Rails::Mocking::WithMocha, filter_options)
30
+ when /rr/i
31
+ require 'micronaut/rails/mocking/with_rr'
32
+ ::Micronaut.configuration.include(::Micronaut::Rails::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
+ ::Micronaut::Configuration.send(:include, ::Micronaut::Rails::Configuration)
@@ -0,0 +1,86 @@
1
+ require 'action_controller'
2
+ require 'action_controller/test_process'
3
+
4
+ module Micronaut
5
+ module Rails
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, ::Micronaut::Rails::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 Micronaut
2
+ module Rails
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, ::Micronaut::Rails::Extensions::ActiveRecord)
19
+ end
@@ -0,0 +1,99 @@
1
+ module Micronaut
2
+ module Rails
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 = ::Micronaut::Rails::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 Micronaut
2
+ module Rails
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 Micronaut
2
+ module Rails
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 Micronaut
2
+ module Rails
3
+ module Mocking
4
+
5
+ module ModelStubber
6
+
7
+ def connection
8
+ raise ::Micronaut::Rails::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 Micronaut
2
+ module Rails
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 ::Micronaut::Rails::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 Micronaut
2
+ module Rails
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 ::Micronaut::Rails::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 Micronaut
2
+ module Rails
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,16 @@
1
+ require 'micronaut/rails/configuration'
2
+ require 'micronaut/rails/matchers/controllers/redirect_to'
3
+ require 'micronaut/rails/matchers/controllers/render_template'
4
+ require 'micronaut/rails/transactional_database_support'
5
+ require 'micronaut/rails/controllers'
6
+ require 'micronaut/rails/helpers'
7
+ require 'micronaut/rails/extensions/active_record'
8
+ require 'micronaut/rails/mocking/model_stubber'
9
+
10
+ module Micronaut
11
+ module Rails
12
+ class IllegalDataAccessException < StandardError; end
13
+
14
+ end
15
+
16
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: micronaut-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.3
5
+ platform: ruby
6
+ authors:
7
+ - Chad Humphries
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-09 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: actionpack
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.3.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: micronaut
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.0
34
+ version:
35
+ description: An excellent replacement for the wheel on rails...
36
+ email: chad@spicycode.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README
44
+ files:
45
+ - LICENSE
46
+ - README
47
+ - RSPEC-LICENSE
48
+ - Rakefile
49
+ - VERSION.yml
50
+ - examples/example_helper.rb
51
+ - examples/lib/micronaut-rails_example.rb
52
+ - examples/lib/micronaut/rails/configuration_example.rb
53
+ - lib/micronaut-rails.rb
54
+ - lib/micronaut/rails/configuration.rb
55
+ - lib/micronaut/rails/controllers.rb
56
+ - lib/micronaut/rails/extensions/active_record.rb
57
+ - lib/micronaut/rails/helpers.rb
58
+ - lib/micronaut/rails/matchers/controllers/redirect_to.rb
59
+ - lib/micronaut/rails/matchers/controllers/render_template.rb
60
+ - lib/micronaut/rails/mocking/model_stubber.rb
61
+ - lib/micronaut/rails/mocking/with_mocha.rb
62
+ - lib/micronaut/rails/mocking/with_rr.rb
63
+ - lib/micronaut/rails/transactional_database_support.rb
64
+ has_rdoc: true
65
+ homepage: http://github.com/spicycode/micronaut-rails
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options:
70
+ - --charset=UTF-8
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ requirements: []
86
+
87
+ rubyforge_project:
88
+ rubygems_version: 1.3.5
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: An excellent replacement for the wheel on rails...
92
+ test_files:
93
+ - examples/example_helper.rb
94
+ - examples/lib/micronaut/rails/configuration_example.rb
95
+ - examples/lib/micronaut-rails_example.rb