micronaut-rails 0.3.3
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.
- data/LICENSE +45 -0
- data/README +25 -0
- data/RSPEC-LICENSE +23 -0
- data/Rakefile +37 -0
- data/VERSION.yml +4 -0
- data/examples/example_helper.rb +56 -0
- data/examples/lib/micronaut/rails/configuration_example.rb +44 -0
- data/examples/lib/micronaut-rails_example.rb +16 -0
- data/lib/micronaut/rails/configuration.rb +48 -0
- data/lib/micronaut/rails/controllers.rb +86 -0
- data/lib/micronaut/rails/extensions/active_record.rb +19 -0
- data/lib/micronaut/rails/helpers.rb +99 -0
- data/lib/micronaut/rails/matchers/controllers/redirect_to.rb +115 -0
- data/lib/micronaut/rails/matchers/controllers/render_template.rb +116 -0
- data/lib/micronaut/rails/mocking/model_stubber.rb +24 -0
- data/lib/micronaut/rails/mocking/with_mocha.rb +72 -0
- data/lib/micronaut/rails/mocking/with_rr.rb +44 -0
- data/lib/micronaut/rails/transactional_database_support.rb +39 -0
- data/lib/micronaut-rails.rb +16 -0
- metadata +95 -0
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,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
|