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.
@@ -1,13 +1,39 @@
1
1
  module Jeeves
2
+ class UnresolvedDependency < StandardError
3
+ end
4
+
2
5
  class ResolveDependency
3
- RESOLVERS = [ResolveMethod, ResolveCallable, ResolveConstant, ResolveMock]
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 or raise ArgumentError, "Dependency '#{name}' was not found in #{scope}"
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
@@ -1,4 +1,4 @@
1
1
  module Jeeves
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
4
4
 
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(internal_name) do |*args, &block|
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(internal_name) do |*args, &block|
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::ResolveMock.stub(:call) # to avoid RSpec integration
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(ArgumentError,
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(ArgumentError,
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(ArgumentError,
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.0
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-16 00:00:00.000000000 Z
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
- email:
32
- - rchopper@gmail.com
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:
@@ -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
-