injectable_dependencies 0.0.1 → 1.0.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.
- checksums.yaml +4 -4
- data/Rakefile +5 -0
- data/injectable_dependencies.gemspec +2 -0
- data/lib/injectable_dependencies/version.rb +1 -1
- data/lib/injectable_dependencies.rb +41 -2
- data/spec/injectable_dependencies_spec.rb +49 -0
- metadata +32 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8f1b46e73121f4e9722086542e7fcad5c374d73
|
4
|
+
data.tar.gz: 96f3836a8ba0532a3c549fad639ec68a16cd83dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32817c025f48f7ab4b2c2d1ca30c7ffaa9c41ef785120b74cc0534b9a186d26b6278b11a30a100f830b2e260279e69de7c5088864d4964907846453d35d5e3f6
|
7
|
+
data.tar.gz: 054b2933e6443a529ca9ac6258efb6bf0c9df694c8911577879badc597236ee6b9192f274635cd57d8dbd4bd3629d0c8b3932e5a4a5c1e2b7e61d0a27f8d2e00
|
data/Rakefile
CHANGED
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_dependency 'activesupport'
|
21
22
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
23
|
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "rspec"
|
23
25
|
end
|
@@ -1,5 +1,44 @@
|
|
1
|
-
require
|
1
|
+
require 'active_support/concern'
|
2
2
|
|
3
|
+
# Allows classes to define instance methods that will be evaluated at
|
4
|
+
# runtime. (The implementation exploits Ruby's method lookup.)
|
5
|
+
#
|
6
|
+
# By default, dependencies declared at the class level will be made
|
7
|
+
# available to all instances of the class (note the call to
|
8
|
+
# .define_method in ClassMethods::Dependency).
|
9
|
+
#
|
10
|
+
# Individual instances of including classes, however, may define their
|
11
|
+
# own singleton methods based on values provided when the object is
|
12
|
+
# initialized. NOTE: For this behavior to work, including classes
|
13
|
+
# must invoke #initialize_dependencies before the dependency methods
|
14
|
+
# are called. (A good place to do this is probably in your
|
15
|
+
# #initialize method, but if you want to do something weird, hey, you
|
16
|
+
# can.)
|
17
|
+
#
|
3
18
|
module InjectableDependencies
|
4
|
-
|
19
|
+
UndeclaredDependencyError = Class.new(StandardError)
|
20
|
+
extend ActiveSupport::Concern
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
def dependency(name, &proc)
|
24
|
+
dependencies << name
|
25
|
+
define_method(name, &proc) # available to all instances
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def dependencies
|
31
|
+
@dependencies ||= []
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize_dependencies(overrides = {})
|
36
|
+
return unless overrides
|
37
|
+
overrides.each do |k,v|
|
38
|
+
unless self.class.send(:dependencies).include?(k)
|
39
|
+
raise UndeclaredDependencyError, "Cannot override undeclared dependency '#{k}'."
|
40
|
+
end
|
41
|
+
singleton_class.send(:define_method, k) { v } # available to this instance only
|
42
|
+
end
|
43
|
+
end
|
5
44
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'injectable_dependencies'
|
2
|
+
|
3
|
+
describe InjectableDependencies do
|
4
|
+
FooDependency = :foo_dependency
|
5
|
+
|
6
|
+
let(:dependant_class) {
|
7
|
+
Class.new do
|
8
|
+
include InjectableDependencies
|
9
|
+
dependency(:foo) { FooDependency }
|
10
|
+
dependency(:bar) { IfThisConstantIsEverDefinedSomeoneIsGettingFiredAndItWontBeMe }
|
11
|
+
def initialize(options = {})
|
12
|
+
initialize_dependencies options[:dependencies]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
}
|
16
|
+
|
17
|
+
let(:dependant) {
|
18
|
+
dependant_class.new
|
19
|
+
}
|
20
|
+
|
21
|
+
it 'allows the class to declare dependencies' do
|
22
|
+
expect(dependant.foo).to eq FooDependency
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'does not evaluate dependencies declared by the class until they are requested' do
|
26
|
+
expect{ dependant.bar }.to raise_error(NameError)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'provides a convenience method for setting dependencies from the initializer' do
|
30
|
+
dependant = dependant_class.new(:dependencies => {:bar => :bar_dependency})
|
31
|
+
expect(dependant.bar).to eq :bar_dependency
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'does not persist dependencies between instances' do
|
35
|
+
s0 = dependant_class.new
|
36
|
+
s1 = dependant_class.new(:dependencies => { :foo => :s1_dep })
|
37
|
+
s2 = dependant_class.new(:dependencies => { :foo => :s2_dep })
|
38
|
+
|
39
|
+
expect(s0.foo).to eq FooDependency
|
40
|
+
expect(s1.foo).to eq :s1_dep
|
41
|
+
expect(s2.foo).to eq :s2_dep
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'does not allow undeclared dependencies to be specified in initializer' do
|
45
|
+
expect{ dependant_class.new(:dependencies => {:undeclared_thing => :oops}) } \
|
46
|
+
.to raise_error(InjectableDependencies::UndeclaredDependencyError,
|
47
|
+
"Cannot override undeclared dependency 'undeclared_thing'.")
|
48
|
+
end
|
49
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: injectable_dependencies
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Wilger
|
@@ -10,6 +10,20 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2013-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +52,20 @@ dependencies:
|
|
38
52
|
- - '>='
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
41
69
|
description: Lightweight Ruby Dependency Injection
|
42
70
|
email:
|
43
71
|
- johnwilger@gmail.com
|
@@ -53,6 +81,7 @@ files:
|
|
53
81
|
- injectable_dependencies.gemspec
|
54
82
|
- lib/injectable_dependencies.rb
|
55
83
|
- lib/injectable_dependencies/version.rb
|
84
|
+
- spec/injectable_dependencies_spec.rb
|
56
85
|
homepage: http://github.com/jwilger/injectable_dependencies
|
57
86
|
licenses:
|
58
87
|
- MIT
|
@@ -77,4 +106,5 @@ rubygems_version: 2.0.3
|
|
77
106
|
signing_key:
|
78
107
|
specification_version: 4
|
79
108
|
summary: Make your object's collaborators injectable so you can test them.
|
80
|
-
test_files:
|
109
|
+
test_files:
|
110
|
+
- spec/injectable_dependencies_spec.rb
|