jeeves 0.0.1 → 0.1.0
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/find_dependencies.rb +22 -0
- data/lib/jeeves/version.rb +1 -1
- data/lib/jeeves.rb +13 -17
- data/spec/acceptance/import_spec.rb +10 -3
- data/spec/unit/find_dependencies_spec.rb +57 -0
- data/spec/unit/import_callable_spec.rb +4 -4
- data/spec/unit/import_constant_spec.rb +4 -4
- data/spec/unit/import_method_spec.rb +4 -4
- metadata +5 -2
@@ -0,0 +1,22 @@
|
|
1
|
+
module Jeeves
|
2
|
+
class FindDependencies
|
3
|
+
def self.call(scope, *names)
|
4
|
+
names.inject({}) do |dependencies, name|
|
5
|
+
dependencies.update(name => delegator_for(name, scope))
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
IMPORTERS = [ImportMethod, ImportCallable, ImportConstant]
|
12
|
+
|
13
|
+
def self.delegator_for(name, scope)
|
14
|
+
delegator = nil
|
15
|
+
IMPORTERS.each do |importer|
|
16
|
+
break if delegator = importer.call(name, scope)
|
17
|
+
end
|
18
|
+
delegator or raise ArgumentError, "Dependency '#{name}' was not found in #{scope}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/lib/jeeves/version.rb
CHANGED
data/lib/jeeves.rb
CHANGED
@@ -1,23 +1,19 @@
|
|
1
1
|
module Jeeves
|
2
|
-
autoload :
|
3
|
-
autoload :
|
4
|
-
autoload :
|
2
|
+
autoload :FindDependencies, "jeeves/find_dependencies"
|
3
|
+
autoload :ImportMethod, "jeeves/import_method"
|
4
|
+
autoload :ImportCallable, "jeeves/import_callable"
|
5
|
+
autoload :ImportConstant, "jeeves/import_constant"
|
5
6
|
|
6
|
-
def import(
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
def import(*args)
|
8
|
+
options = args.last.respond_to?(:fetch) ? args.pop : {}
|
9
|
+
scope = options.fetch(:from) do
|
10
|
+
module_names = ancestors.first.to_s.split('::')[0..-2]
|
11
|
+
module_names.inject(Object) { |m, c| m.const_get(c) }
|
10
12
|
end
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
IMPORTERS = [ImportMethod, ImportCallable, ImportConstant]
|
16
|
-
|
17
|
-
def define_delegator(name, scope)
|
18
|
-
callable = IMPORTERS.reduce(nil) { |c, i| c ||= i.call(name, scope) }
|
19
|
-
if callable
|
20
|
-
define_method(name) { |*args, &block| callable.call(*args, &block) }
|
13
|
+
FindDependencies.call(scope, *args).each do |name, delegator|
|
14
|
+
define_method(name) do |*args, &block|
|
15
|
+
delegator.call(*args, &block)
|
16
|
+
end
|
21
17
|
end
|
22
18
|
end
|
23
19
|
end
|
@@ -16,11 +16,14 @@ module JeevesTestApp
|
|
16
16
|
end
|
17
17
|
|
18
18
|
module InnerScope
|
19
|
+
def self.marco
|
20
|
+
:polo
|
21
|
+
end
|
22
|
+
|
19
23
|
class TestSubject
|
20
24
|
extend Jeeves
|
21
|
-
import :my_method, from: OtherScope
|
22
|
-
import :
|
23
|
-
import :my_constant, from: OtherScope
|
25
|
+
import :my_method, :my_callable, :my_constant, from: OtherScope
|
26
|
+
import :marco
|
24
27
|
end
|
25
28
|
end
|
26
29
|
end
|
@@ -42,6 +45,10 @@ describe "import" do
|
|
42
45
|
subject.my_constant.should == "MY VALUE"
|
43
46
|
end
|
44
47
|
|
48
|
+
it "defaults to the current class's scope" do
|
49
|
+
subject.marco.should == :polo
|
50
|
+
end
|
51
|
+
|
45
52
|
it "raises an error if no importers can find the dependency" do
|
46
53
|
expect { subject.class.import :unknown, from: JeevesTestApp::OtherScope }.
|
47
54
|
to raise_error(ArgumentError,
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Jeeves
|
2
|
+
class ImportMethod; end
|
3
|
+
class ImportCallable; end
|
4
|
+
class ImportConstant; end
|
5
|
+
end
|
6
|
+
require "jeeves/find_dependencies"
|
7
|
+
|
8
|
+
module Jeeves
|
9
|
+
describe FindDependencies do
|
10
|
+
let(:scope) { stub("scope", to_s: "ScopeStub") }
|
11
|
+
let(:delegator) { stub("delegator") }
|
12
|
+
|
13
|
+
before do
|
14
|
+
ImportMethod.stub(:call)
|
15
|
+
ImportCallable.stub(:call)
|
16
|
+
ImportConstant.stub(:call)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "maps dependency names to anonymous delegator functions" do
|
20
|
+
ImportMethod.stub(:call).with(:my_dependency, scope) { delegator }
|
21
|
+
FindDependencies.call(scope, :my_dependency).should == {
|
22
|
+
my_dependency: delegator
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
it "maps multiple dependencies" do
|
27
|
+
delegator2 = stub("delegator 2")
|
28
|
+
ImportMethod.stub(:call).with(:my_dep_1, scope) { delegator }
|
29
|
+
ImportMethod.stub(:call).with(:my_dep_2, scope) { delegator2 }
|
30
|
+
FindDependencies.call(scope, :my_dep_1, :my_dep_2).should == {
|
31
|
+
my_dep_1: delegator,
|
32
|
+
my_dep_2: delegator2
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
it "uses ImportCallable if ImportMethod fails" do
|
37
|
+
ImportCallable.stub(:call).with(:my_dependency, scope) { delegator }
|
38
|
+
FindDependencies.call(scope, :my_dependency).should == {
|
39
|
+
my_dependency: delegator
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
it "uses ImportConstant if ImportMethod and ImportCallable fail" do
|
44
|
+
ImportConstant.stub(:call).with(:my_dependency, scope) { delegator }
|
45
|
+
FindDependencies.call(scope, :my_dependency).should == {
|
46
|
+
my_dependency: delegator
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
it "raises an error if all importers fail" do
|
51
|
+
expect { FindDependencies.call(scope, :my_dependency) }.
|
52
|
+
to raise_error(ArgumentError,
|
53
|
+
"Dependency 'my_dependency' was not found in ScopeStub")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -14,14 +14,14 @@ module Jeeves
|
|
14
14
|
describe ImportCallable do
|
15
15
|
|
16
16
|
it "returns an anonymous function which delegates to a new instance of the callable" do
|
17
|
-
|
18
|
-
result =
|
17
|
+
delegator = ImportCallable.call(:my_callable, JeevesTestApp::CallableTest)
|
18
|
+
result = delegator.call(:foo, :bar, :baz) { |s| s.upcase }
|
19
19
|
result.should == "FOO-BAR-BAZ"
|
20
20
|
end
|
21
21
|
|
22
22
|
it "returns nil if the the callable class is not defined" do
|
23
|
-
|
24
|
-
|
23
|
+
delegator = ImportCallable.call(:undefined_callable, JeevesTestApp::CallableTest)
|
24
|
+
delegator.should be(nil)
|
25
25
|
end
|
26
26
|
|
27
27
|
end
|
@@ -10,13 +10,13 @@ module Jeeves
|
|
10
10
|
describe ImportConstant do
|
11
11
|
|
12
12
|
it "returns an anonymous function which returns the constant" do
|
13
|
-
|
14
|
-
|
13
|
+
delegator = ImportConstant.call(:my_constant, JeevesTestApp::ConstantTest)
|
14
|
+
delegator.call.should == "MY VALUE"
|
15
15
|
end
|
16
16
|
|
17
17
|
it "returns nil if the constant is not defined" do
|
18
|
-
|
19
|
-
|
18
|
+
delegator = ImportConstant.call(:undefined_constant, JeevesTestApp::ConstantTest)
|
19
|
+
delegator.should be(nil)
|
20
20
|
end
|
21
21
|
|
22
22
|
end
|
@@ -12,14 +12,14 @@ module Jeeves
|
|
12
12
|
describe ImportMethod do
|
13
13
|
|
14
14
|
it "returns an anonymous function which delegates to the method" do
|
15
|
-
|
16
|
-
result =
|
15
|
+
delegator = ImportMethod.call(:my_method, JeevesTestApp::MethodTest)
|
16
|
+
result = delegator.call(:foo, :bar, :baz) { |s| s.upcase }
|
17
17
|
result.should == "FOO-BAR-BAZ"
|
18
18
|
end
|
19
19
|
|
20
20
|
it "returns nil if the scope does not respond to the method" do
|
21
|
-
|
22
|
-
|
21
|
+
delegator = ImportMethod.call(:undefined_method, JeevesTestApp::MethodTest)
|
22
|
+
delegator.should be(nil)
|
23
23
|
end
|
24
24
|
|
25
25
|
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.0
|
4
|
+
version: 0.1.0
|
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-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -37,11 +37,13 @@ files:
|
|
37
37
|
- lib/jeeves.rb
|
38
38
|
- lib/jeeves/import_callable.rb
|
39
39
|
- lib/jeeves/import_constant.rb
|
40
|
+
- lib/jeeves/find_dependencies.rb
|
40
41
|
- lib/jeeves/import_method.rb
|
41
42
|
- lib/jeeves/version.rb
|
42
43
|
- spec/acceptance/import_spec.rb
|
43
44
|
- spec/unit/import_callable_spec.rb
|
44
45
|
- spec/unit/import_method_spec.rb
|
46
|
+
- spec/unit/find_dependencies_spec.rb
|
45
47
|
- spec/unit/import_constant_spec.rb
|
46
48
|
homepage: http://github.com/ronhopper/jeeves
|
47
49
|
licenses: []
|
@@ -71,4 +73,5 @@ test_files:
|
|
71
73
|
- spec/acceptance/import_spec.rb
|
72
74
|
- spec/unit/import_callable_spec.rb
|
73
75
|
- spec/unit/import_method_spec.rb
|
76
|
+
- spec/unit/find_dependencies_spec.rb
|
74
77
|
- spec/unit/import_constant_spec.rb
|