jeeves 0.0.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.
@@ -0,0 +1,17 @@
1
+ module Jeeves
2
+ class ImportCallable
3
+ def self.call(name, scope)
4
+ class_name = camelize(name)
5
+ if scope.const_defined?(class_name)
6
+ scope.const_get(class_name).new
7
+ end
8
+ end
9
+
10
+ private
11
+
12
+ def self.camelize(s)
13
+ s.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,12 @@
1
+ module Jeeves
2
+ class ImportConstant
3
+ def self.call(name, scope)
4
+ const_name = name.upcase
5
+ if scope.const_defined?(const_name)
6
+ const_value = scope.const_get(const_name)
7
+ lambda { const_value }
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,10 @@
1
+ module Jeeves
2
+ class ImportMethod
3
+ def self.call(name, scope)
4
+ if scope.respond_to?(name)
5
+ scope.method(name)
6
+ end
7
+ end
8
+ end
9
+ end
10
+
@@ -0,0 +1,4 @@
1
+ module Jeeves
2
+ VERSION = "0.0.1"
3
+ end
4
+
data/lib/jeeves.rb ADDED
@@ -0,0 +1,24 @@
1
+ module Jeeves
2
+ autoload :ImportMethod, "jeeves/import_method"
3
+ autoload :ImportCallable, "jeeves/import_callable"
4
+ autoload :ImportConstant, "jeeves/import_constant"
5
+
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}"
10
+ 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) }
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,51 @@
1
+ require "jeeves"
2
+
3
+ module JeevesTestApp
4
+ module OtherScope
5
+ def self.my_method(*args, &block)
6
+ block.call(args.map(&:to_s).join("-"))
7
+ end
8
+
9
+ class MyCallable
10
+ def call(*args, &block)
11
+ block.call(args.map(&:to_s).join("+"))
12
+ end
13
+ end
14
+
15
+ MY_CONSTANT = "MY VALUE"
16
+ end
17
+
18
+ module InnerScope
19
+ class TestSubject
20
+ extend Jeeves
21
+ import :my_method, from: OtherScope
22
+ import :my_callable, from: OtherScope
23
+ import :my_constant, from: OtherScope
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "import" do
29
+ subject { JeevesTestApp::InnerScope::TestSubject.new }
30
+
31
+ it "imports a method" do
32
+ result = subject.my_method(:foo, :bar, :baz) { |s| s.upcase }
33
+ result.should == "FOO-BAR-BAZ"
34
+ end
35
+
36
+ it "imports a callable" do
37
+ result = subject.my_callable(:foo, :bar, :baz) { |s| s.reverse }
38
+ result.should == "zab+rab+oof"
39
+ end
40
+
41
+ it "imports a constant" do
42
+ subject.my_constant.should == "MY VALUE"
43
+ end
44
+
45
+ it "raises an error if no importers can find the dependency" do
46
+ expect { subject.class.import :unknown, from: JeevesTestApp::OtherScope }.
47
+ to raise_error(ArgumentError,
48
+ "Dependency 'unknown' was not found in JeevesTestApp::OtherScope")
49
+ end
50
+ end
51
+
@@ -0,0 +1,29 @@
1
+ require "jeeves/import_callable"
2
+
3
+ module JeevesTestApp
4
+ module CallableTest
5
+ class MyCallable
6
+ def call(*args, &block)
7
+ block.call(args.map(&:to_s).join("-"))
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ module Jeeves
14
+ describe ImportCallable do
15
+
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 }
19
+ result.should == "FOO-BAR-BAZ"
20
+ end
21
+
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)
25
+ end
26
+
27
+ end
28
+ end
29
+
@@ -0,0 +1,24 @@
1
+ require "jeeves/import_constant"
2
+
3
+ module JeevesTestApp
4
+ module ConstantTest
5
+ MY_CONSTANT = "MY VALUE"
6
+ end
7
+ end
8
+
9
+ module Jeeves
10
+ describe ImportConstant do
11
+
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"
15
+ end
16
+
17
+ it "returns nil if the constant is not defined" do
18
+ callable = ImportConstant.call(:undefined_constant, JeevesTestApp::ConstantTest)
19
+ callable.should be(nil)
20
+ end
21
+
22
+ end
23
+ end
24
+
@@ -0,0 +1,27 @@
1
+ require "jeeves/import_method"
2
+
3
+ module JeevesTestApp
4
+ module MethodTest
5
+ def self.my_method(*args, &block)
6
+ block.call(args.map(&:to_s).join("-"))
7
+ end
8
+ end
9
+ end
10
+
11
+ module Jeeves
12
+ describe ImportMethod do
13
+
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 }
17
+ result.should == "FOO-BAR-BAZ"
18
+ end
19
+
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)
23
+ end
24
+
25
+ end
26
+ end
27
+
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jeeves
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ron Hopper
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.8'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.8'
30
+ description:
31
+ email:
32
+ - rchopper@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - lib/jeeves.rb
38
+ - lib/jeeves/import_callable.rb
39
+ - lib/jeeves/import_constant.rb
40
+ - lib/jeeves/import_method.rb
41
+ - lib/jeeves/version.rb
42
+ - spec/acceptance/import_spec.rb
43
+ - spec/unit/import_callable_spec.rb
44
+ - spec/unit/import_method_spec.rb
45
+ - spec/unit/import_constant_spec.rb
46
+ homepage: http://github.com/ronhopper/jeeves
47
+ licenses: []
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubyforge_project:
66
+ rubygems_version: 1.8.24
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Jeeves is a dependency management library for Ruby.
70
+ test_files:
71
+ - spec/acceptance/import_spec.rb
72
+ - spec/unit/import_callable_spec.rb
73
+ - spec/unit/import_method_spec.rb
74
+ - spec/unit/import_constant_spec.rb