jeeves 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+
@@ -1,4 +1,4 @@
1
1
  module Jeeves
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
4
4
 
data/lib/jeeves.rb CHANGED
@@ -1,23 +1,19 @@
1
1
  module Jeeves
2
- autoload :ImportMethod, "jeeves/import_method"
3
- autoload :ImportCallable, "jeeves/import_callable"
4
- autoload :ImportConstant, "jeeves/import_constant"
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(name, options={})
7
- scope = options.fetch(:from)
8
- if not define_delegator(name, scope)
9
- raise ArgumentError, "Dependency '#{name}' was not found in #{scope}"
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
- end
12
-
13
- private
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 :my_callable, from: OtherScope
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
- callable = ImportCallable.call(:my_callable, JeevesTestApp::CallableTest)
18
- result = callable.call(:foo, :bar, :baz) { |s| s.upcase }
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
- callable = ImportCallable.call(:undefined_callable, JeevesTestApp::CallableTest)
24
- callable.should be(nil)
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
- callable = ImportConstant.call(:my_constant, JeevesTestApp::ConstantTest)
14
- callable.call.should == "MY VALUE"
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
- callable = ImportConstant.call(:undefined_constant, JeevesTestApp::ConstantTest)
19
- callable.should be(nil)
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
- callable = ImportMethod.call(:my_method, JeevesTestApp::MethodTest)
16
- result = callable.call(:foo, :bar, :baz) { |s| s.upcase }
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
- callable = ImportMethod.call(:undefined_method, JeevesTestApp::MethodTest)
22
- callable.should be(nil)
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.1
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-15 00:00:00.000000000 Z
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