jeeves 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/jeeves/resolve_dependency.rb +28 -2
- data/lib/jeeves/version.rb +1 -1
- data/lib/jeeves.rb +5 -3
- data/spec/integration/import_spec.rb +7 -2
- data/spec/integration/rspec_spec.rb +19 -2
- data/spec/unit/resolve_dependency_spec.rb +2 -8
- metadata +8 -7
- data/lib/jeeves/resolve_mock.rb +0 -22
@@ -1,13 +1,39 @@
|
|
1
1
|
module Jeeves
|
2
|
+
class UnresolvedDependency < StandardError
|
3
|
+
end
|
4
|
+
|
2
5
|
class ResolveDependency
|
3
|
-
RESOLVERS = [ResolveMethod, ResolveCallable, ResolveConstant
|
6
|
+
RESOLVERS = [ResolveMethod, ResolveCallable, ResolveConstant]
|
4
7
|
|
5
8
|
def self.call(scope, name)
|
6
9
|
delegator = nil
|
7
10
|
RESOLVERS.each do |resolver|
|
8
11
|
break if delegator = resolver.call(scope, name)
|
9
12
|
end
|
10
|
-
delegator
|
13
|
+
delegator = mock(delegator, scope, name) if in_test_framework?
|
14
|
+
delegator or unresolved(scope, name)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def self.in_test_framework?
|
20
|
+
defined?(RSpec) || defined?(Test::Unit)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.mock(delegator, scope, name)
|
24
|
+
lambda do |*args, &block|
|
25
|
+
if Jeeves.respond_to?(name)
|
26
|
+
Jeeves.send(name, *args, &block)
|
27
|
+
elsif delegator
|
28
|
+
delegator.call(*args, &block)
|
29
|
+
else
|
30
|
+
unresolved(scope, name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.unresolved(scope, name)
|
36
|
+
raise UnresolvedDependency, "Dependency '#{name}' was not found in #{scope}"
|
11
37
|
end
|
12
38
|
end
|
13
39
|
end
|
data/lib/jeeves/version.rb
CHANGED
data/lib/jeeves.rb
CHANGED
@@ -3,7 +3,6 @@ module Jeeves
|
|
3
3
|
autoload :ResolveMethod, "jeeves/resolve_method"
|
4
4
|
autoload :ResolveCallable, "jeeves/resolve_callable"
|
5
5
|
autoload :ResolveConstant, "jeeves/resolve_constant"
|
6
|
-
autoload :ResolveMock, "jeeves/resolve_mock"
|
7
6
|
|
8
7
|
def import(*args)
|
9
8
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
@@ -18,16 +17,19 @@ module Jeeves
|
|
18
17
|
external_name = internal_name = name
|
19
18
|
end
|
20
19
|
if options[:lazy]
|
21
|
-
define_method
|
20
|
+
self.class.send(:define_method, internal_name) do |*args, &block|
|
22
21
|
delegator = ResolveDependency.call(scope, external_name)
|
23
22
|
delegator.call(*args, &block)
|
24
23
|
end
|
25
24
|
else
|
26
25
|
delegator = ResolveDependency.call(scope, external_name)
|
27
|
-
define_method
|
26
|
+
self.class.send(:define_method, internal_name) do |*args, &block|
|
28
27
|
delegator.call(*args, &block)
|
29
28
|
end
|
30
29
|
end
|
30
|
+
define_method(internal_name) do |*args, &block|
|
31
|
+
self.class.send(internal_name, *args, &block)
|
32
|
+
end
|
31
33
|
end
|
32
34
|
end
|
33
35
|
end
|
@@ -76,10 +76,15 @@ describe "import" do
|
|
76
76
|
subject.say_polo.should == :polo
|
77
77
|
end
|
78
78
|
|
79
|
+
it "also imports into as a class method" do
|
80
|
+
result = subject.class.my_method(:foo, :bar, :baz) { |s| s.upcase }
|
81
|
+
result.should == "FOO-BAR-BAZ"
|
82
|
+
end
|
83
|
+
|
79
84
|
it "raises an error if no importers can find the dependency" do
|
80
|
-
Jeeves::
|
85
|
+
Jeeves::ResolveDependency.stub(:in_test_framework?) { false } # to avoid RSpec integration
|
81
86
|
expect { subject.class.import :unknown, from: JeevesTestApp::OtherScope }.
|
82
|
-
to raise_error(
|
87
|
+
to raise_error(Jeeves::UnresolvedDependency,
|
83
88
|
"Dependency 'unknown' was not found in JeevesTestApp::OtherScope")
|
84
89
|
end
|
85
90
|
end
|
@@ -2,13 +2,21 @@ require "jeeves"
|
|
2
2
|
|
3
3
|
module JeevesTestApp
|
4
4
|
module InnerScope
|
5
|
+
def self.loaded_dependency
|
6
|
+
:real_value
|
7
|
+
end
|
8
|
+
|
5
9
|
class TestSubject
|
6
10
|
extend Jeeves
|
7
|
-
import :my_mock
|
11
|
+
import :my_mock, :loaded_dependency
|
8
12
|
|
9
13
|
def call
|
10
14
|
my_mock(42)
|
11
15
|
end
|
16
|
+
|
17
|
+
def call_integrated
|
18
|
+
loaded_dependency
|
19
|
+
end
|
12
20
|
end
|
13
21
|
end
|
14
22
|
end
|
@@ -22,8 +30,17 @@ describe "rspec integration" do
|
|
22
30
|
end
|
23
31
|
|
24
32
|
it "raises an error if the dependency is not mocked" do
|
25
|
-
expect { subject.call }.to raise_error(
|
33
|
+
expect { subject.call }.to raise_error(Jeeves::UnresolvedDependency,
|
26
34
|
"Dependency 'my_mock' was not found in JeevesTestApp::InnerScope")
|
27
35
|
end
|
36
|
+
|
37
|
+
it "overrides loaded dependencies with mocked methdos on Jeeves" do
|
38
|
+
Jeeves.stub(:loaded_dependency) { :stubbed_value }
|
39
|
+
subject.call_integrated.should == :stubbed_value
|
40
|
+
end
|
41
|
+
|
42
|
+
it "uses loaded dependencies if they are not mocked on Jeeves" do
|
43
|
+
subject.call_integrated.should == :real_value
|
44
|
+
end
|
28
45
|
end
|
29
46
|
|
@@ -2,7 +2,6 @@ module Jeeves
|
|
2
2
|
class ResolveMethod; end
|
3
3
|
class ResolveCallable; end
|
4
4
|
class ResolveConstant; end
|
5
|
-
class ResolveMock; end
|
6
5
|
end
|
7
6
|
require "jeeves/resolve_dependency"
|
8
7
|
|
@@ -12,6 +11,7 @@ module Jeeves
|
|
12
11
|
let(:delegator) { stub("delegator") }
|
13
12
|
|
14
13
|
before do
|
14
|
+
Jeeves::ResolveDependency.stub(:in_test_framework?) { false } # to avoid RSpec integration
|
15
15
|
ResolveMethod.stub(:call)
|
16
16
|
ResolveCallable.stub(:call)
|
17
17
|
ResolveConstant.stub(:call)
|
@@ -32,15 +32,9 @@ module Jeeves
|
|
32
32
|
ResolveDependency.call(scope, :my_dependency).should be(delegator)
|
33
33
|
end
|
34
34
|
|
35
|
-
it "uses ResolveMock as a last resort" do
|
36
|
-
ResolveMock.stub(:call).with(scope, :my_dependency) { delegator }
|
37
|
-
ResolveDependency.call(scope, :my_dependency).should be(delegator)
|
38
|
-
end
|
39
|
-
|
40
35
|
it "raises an error if all importers fail" do
|
41
|
-
Jeeves::ResolveMock.stub(:call) # to avoid RSpec integration
|
42
36
|
expect { ResolveDependency.call(scope, :my_dependency) }.
|
43
|
-
to raise_error(
|
37
|
+
to raise_error(Jeeves::UnresolvedDependency,
|
44
38
|
"Dependency 'my_dependency' was not found in ScopeStub")
|
45
39
|
end
|
46
40
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jeeves
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -27,9 +27,10 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '2.8'
|
30
|
-
description:
|
31
|
-
|
32
|
-
|
30
|
+
description: Jeeves is a personal valet for your Ruby code. It is used to manage dependencies
|
31
|
+
between loosely coupled classes via explicit declaraion. It is _not_ a traditional
|
32
|
+
dependency injection framework, although it can easily fill that role.
|
33
|
+
email: rchopper@gmail.com
|
33
34
|
executables: []
|
34
35
|
extensions: []
|
35
36
|
extra_rdoc_files: []
|
@@ -39,7 +40,6 @@ files:
|
|
39
40
|
- lib/jeeves/version.rb
|
40
41
|
- lib/jeeves/resolve_constant.rb
|
41
42
|
- lib/jeeves/resolve_method.rb
|
42
|
-
- lib/jeeves/resolve_mock.rb
|
43
43
|
- lib/jeeves/resolve_callable.rb
|
44
44
|
- spec/integration/rspec_spec.rb
|
45
45
|
- spec/integration/import_spec.rb
|
@@ -48,7 +48,8 @@ files:
|
|
48
48
|
- spec/unit/resolve_constant_spec.rb
|
49
49
|
- spec/unit/resolve_dependency_spec.rb
|
50
50
|
homepage: http://github.com/ronhopper/jeeves
|
51
|
-
licenses:
|
51
|
+
licenses:
|
52
|
+
- MIT
|
52
53
|
post_install_message:
|
53
54
|
rdoc_options: []
|
54
55
|
require_paths:
|
data/lib/jeeves/resolve_mock.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
module Jeeves
|
2
|
-
class ResolveMock
|
3
|
-
def self.call(scope, name)
|
4
|
-
if in_test_framework?
|
5
|
-
lambda do |*args, &block|
|
6
|
-
if Jeeves.respond_to?(name)
|
7
|
-
Jeeves.public_send(name, *args, &block)
|
8
|
-
else
|
9
|
-
raise ArgumentError, "Dependency '#{name}' was not found in #{scope}"
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
def self.in_test_framework?
|
18
|
-
defined?(RSpec) || defined?(Test::Unit)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|