jeeves 0.2.0 → 0.2.1
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/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
|
-
|