Skip to content

Commit

Permalink
map undefined scopes to the Jeeves module in test
Browse files Browse the repository at this point in the history
  • Loading branch information
ronhopper committed Jun 20, 2012
1 parent 30cef4e commit eaf1651
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 8 deletions.
3 changes: 3 additions & 0 deletions README.md
Expand Up @@ -225,6 +225,9 @@ If you're feeling reckless, you can monkey-patch Jeeves into your project with
History
-------

### Edge
* Mock undefined dependency scope within RSpec or Test::Unit

### Version 0.2.1
* Import dependencies as class methods (rather than just instance methods)
* Raise Jeeves::UnresolvedDependency when a dependency is not found
Expand Down
20 changes: 20 additions & 0 deletions lib/jeeves.rb
Expand Up @@ -32,5 +32,25 @@ def import(*args)
end
end
end

def const_missing(name)
return super unless Jeeves.in_test_framework?
Module.new do
@name = [name]
class << self
def const_missing(name)
@name << name
self
end
def to_s
@name.join("::")
end
end
end
end

def self.in_test_framework?
defined?(RSpec) || defined?(Test::Unit)
end
end

6 changes: 1 addition & 5 deletions lib/jeeves/resolve_dependency.rb
Expand Up @@ -10,16 +10,12 @@ def self.call(scope, name)
RESOLVERS.each do |resolver|
break if delegator = resolver.call(scope, name)
end
delegator = mock(delegator, scope, name) if in_test_framework?
delegator = mock(delegator, scope, name) if Jeeves.in_test_framework?
delegator or unresolved(scope, name)
end

private

def self.in_test_framework?
defined?(RSpec) || defined?(Test::Unit)
end

def self.mock(delegator, scope, name)
lambda do |*args, &block|
if Jeeves.respond_to?(name)
Expand Down
11 changes: 10 additions & 1 deletion spec/integration/import_spec.rb
Expand Up @@ -82,10 +82,19 @@ class TestSubject
end

it "raises an error if no importers can find the dependency" do
Jeeves::ResolveDependency.stub(:in_test_framework?) { false } # to avoid RSpec integration
Jeeves.stub(:in_test_framework?) { false } # to avoid RSpec integration
expect { subject.class.import :unknown, from: JeevesTestApp::OtherScope }.
to raise_error(Jeeves::UnresolvedDependency,
"Dependency 'unknown' was not found in JeevesTestApp::OtherScope")
end

it "raises an error if the scope is undefined" do
Jeeves.stub(:in_test_framework?) { false } # to avoid RSpec integration
expect do
class JeevesTestApp::InnerScope::TestSubject
import :unknown, from: MyUndefined::Scope
end
end.to raise_error(NameError)
end
end

17 changes: 16 additions & 1 deletion spec/integration/rspec_spec.rb
Expand Up @@ -9,6 +9,7 @@ def self.loaded_dependency
class TestSubject
extend Jeeves
import :my_mock, :loaded_dependency
import :external_mock, from: MyUndefined::Scope

def call
my_mock(42)
Expand All @@ -17,6 +18,10 @@ def call
def call_integrated
loaded_dependency
end

def call_external
external_mock
end
end
end
end
Expand All @@ -34,13 +39,23 @@ def call_integrated
"Dependency 'my_mock' was not found in JeevesTestApp::InnerScope")
end

it "overrides loaded dependencies with mocked methdos on Jeeves" do
it "overrides loaded dependencies with mocked methods on Jeeves" do
Jeeves.stub(:loaded_dependency) { :stubbed_value }
subject.call_integrated.should == :stubbed_value
end

it "uses loaded dependencies if they are not mocked on Jeeves" do
subject.call_integrated.should == :real_value
end

it "treats missing scope as Jeeves" do
Jeeves.stub(:external_mock) { :stubbed_value }
subject.call_external.should == :stubbed_value
end

it "raises an error if the dependency in missing scope is not mocked" do
expect { subject.call_external }.to raise_error(Jeeves::UnresolvedDependency,
"Dependency 'external_mock' was not found in MyUndefined::Scope")
end
end

2 changes: 1 addition & 1 deletion spec/unit/resolve_dependency_spec.rb
Expand Up @@ -11,7 +11,7 @@ module Jeeves
let(:delegator) { stub("delegator") }

before do
Jeeves::ResolveDependency.stub(:in_test_framework?) { false } # to avoid RSpec integration
Jeeves.stub(:in_test_framework?) { false } # to avoid RSpec integration
ResolveMethod.stub(:call)
ResolveCallable.stub(:call)
ResolveConstant.stub(:call)
Expand Down

0 comments on commit eaf1651

Please sign in to comment.