collaborator 0.0.1 → 0.0.2
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/VERSION +1 -1
- data/collaborator.gemspec +1 -1
- data/lib/collaborator.rb +29 -17
- data/readme.markdown +68 -1
- data/spec/collaborator_spec.rb +78 -13
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/collaborator.gemspec
CHANGED
data/lib/collaborator.rb
CHANGED
@@ -1,24 +1,36 @@
|
|
1
1
|
module Collaborator
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
# a dependecy might be a class, an instance or a lambda
|
4
|
+
# evaluate the lambda if necessary
|
5
|
+
def evaluate_dependency(dependency)
|
6
|
+
if dependency.is_a?(Proc)
|
7
|
+
return dependency.call
|
8
|
+
else
|
9
|
+
dependency
|
5
10
|
end
|
11
|
+
end
|
6
12
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
define_method("reset_#{name}") do
|
19
|
-
instance_variable_set("@#{name}", default_dep)
|
20
|
-
end
|
21
|
-
end
|
13
|
+
def dependency(name, default_dep)
|
14
|
+
|
15
|
+
define_method(name) do
|
16
|
+
cached = instance_variable_get("@#{name}")
|
17
|
+
return cached if cached
|
18
|
+
self.send "reset_#{name}"
|
19
|
+
end
|
20
|
+
|
21
|
+
define_method("#{name}=") do |injected|
|
22
|
+
self.prepare_collaborator(name, injected) if self.respond_to?(:prepare_collaborator)
|
23
|
+
instance_variable_set("@#{name}", injected)
|
22
24
|
end
|
23
25
|
|
26
|
+
define_method("reset_#{name}") do
|
27
|
+
evaluated = self.class.evaluate_dependency(default_dep)
|
28
|
+
self.prepare_collaborator(name, evaluated) if self.respond_to?(:prepare_collaborator)
|
29
|
+
instance_variable_set("@#{name}", evaluated)
|
30
|
+
evaluated
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
|
24
36
|
end
|
data/readme.markdown
CHANGED
@@ -1,7 +1,74 @@
|
|
1
1
|
Collaborator
|
2
2
|
==========
|
3
3
|
|
4
|
-
A simple gem for injecting dependencies into classes
|
4
|
+
A simple gem for injecting dependencies into classes. I got bored of copying the same code again and again so I made this simple gem.
|
5
|
+
|
6
|
+
Usage
|
7
|
+
-----
|
8
|
+
|
9
|
+
class BugFinder
|
10
|
+
...
|
11
|
+
end
|
12
|
+
|
13
|
+
class BugKiller
|
14
|
+
# mixing the Collaborator module
|
15
|
+
extend Collaborator
|
16
|
+
|
17
|
+
# declare a dependency, pass an instance of the collaborator object
|
18
|
+
dependency :bug_finder, BugFinder.new
|
19
|
+
end
|
20
|
+
|
21
|
+
The dependecy method just creates a couple of attribute accesors, so you can use the dependecy like this:
|
22
|
+
|
23
|
+
class BugKiller
|
24
|
+
extend Collaborator
|
25
|
+
dependency :bug_finder, BugFinder.new
|
26
|
+
|
27
|
+
def run
|
28
|
+
bugs = bug_finder.run
|
29
|
+
...
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
### Injecting dependencies
|
35
|
+
|
36
|
+
In your test you just inject a new dependency like so:
|
37
|
+
|
38
|
+
bug_killer = BugKiller.new
|
39
|
+
bug_killer.bug_finder = mocked_bug_finder
|
40
|
+
|
41
|
+
### Lazy evaluation
|
42
|
+
|
43
|
+
You can also pass a lambda as the second argument, this will defer evaluation of the dependecy until it is actually used
|
44
|
+
|
45
|
+
class BugKiller
|
46
|
+
extend Collaborator
|
47
|
+
dependency :bug_finder, ->{ BugFinder.new }
|
48
|
+
|
49
|
+
def run
|
50
|
+
bugs = bug_finder.run
|
51
|
+
...
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
### Preparing collaborators
|
57
|
+
|
58
|
+
Sometimes it is useful to prepare the collaborators in some way before actually using them. To do this just create a method in your class called 'prepare_collaborator'.
|
59
|
+
|
60
|
+
class BugKiller
|
61
|
+
extend Collaborator
|
62
|
+
dependency :bug_finder, ->{ BugFinder.new }
|
63
|
+
|
64
|
+
# this function receives the name of the collaborator e.g. :bug_finder and the collaborator itself
|
65
|
+
def prepare_collaborator(name, collaborator)
|
66
|
+
collaborator.log_enable = true
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
When a dependency is injected e.g. bug_killer.bug_finder = mocked_bug_finder this method is also called on the injected dependency
|
5
72
|
|
6
73
|
Copyright
|
7
74
|
----------
|
data/spec/collaborator_spec.rb
CHANGED
@@ -1,17 +1,23 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'collaborator'
|
3
|
+
require 'ostruct'
|
3
4
|
|
4
5
|
describe 'Collaborator' do
|
5
6
|
|
6
7
|
let(:injected_collaborator) { double.as_null_object }
|
7
8
|
let(:subject) { Subject.new }
|
8
9
|
|
9
|
-
class
|
10
|
+
class Collaborator1
|
11
|
+
attr_accessor :foo
|
12
|
+
def run
|
13
|
+
true
|
14
|
+
end
|
10
15
|
end
|
11
16
|
|
12
17
|
class Subject
|
13
|
-
|
14
|
-
dependency :
|
18
|
+
extend Collaborator
|
19
|
+
dependency :collaborator1, Collaborator1.new
|
20
|
+
dependency :collaborator2, ->{ Collaborator1.new }
|
15
21
|
end
|
16
22
|
|
17
23
|
it "mixes in the module" do
|
@@ -19,30 +25,89 @@ describe 'Collaborator' do
|
|
19
25
|
end
|
20
26
|
|
21
27
|
it "creates a getter method" do
|
22
|
-
expect(subject).to respond_to(:
|
28
|
+
expect(subject).to respond_to(:collaborator1)
|
23
29
|
end
|
24
30
|
|
25
31
|
it "creates a setter method" do
|
26
|
-
expect(subject).to respond_to(:
|
32
|
+
expect(subject).to respond_to(:collaborator1=)
|
27
33
|
end
|
28
34
|
|
29
35
|
it "creates a reset method" do
|
30
|
-
expect(subject).to respond_to(:
|
36
|
+
expect(subject).to respond_to(:reset_collaborator1)
|
31
37
|
end
|
32
38
|
|
33
|
-
it "
|
34
|
-
expect(subject.
|
39
|
+
it "reached the collaborator object" do
|
40
|
+
expect(subject.collaborator1.run).to be_true
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns the default collaborator1" do
|
44
|
+
expect(subject.collaborator1).to be_instance_of(Collaborator1)
|
35
45
|
end
|
36
46
|
|
37
47
|
it "can inject the dependency" do
|
38
|
-
subject.
|
39
|
-
expect(subject.
|
48
|
+
subject.collaborator1 = injected_collaborator
|
49
|
+
expect(subject.collaborator1).to eq(injected_collaborator)
|
40
50
|
end
|
41
51
|
|
42
52
|
it "can reset the dependency" do
|
43
|
-
subject.
|
44
|
-
subject.
|
45
|
-
expect(subject.
|
53
|
+
subject.collaborator1 = injected_collaborator
|
54
|
+
subject.reset_collaborator1
|
55
|
+
expect(subject.collaborator1).to be_instance_of(Collaborator1)
|
46
56
|
end
|
47
57
|
|
58
|
+
it "accepts a lambda" do
|
59
|
+
expect(subject).to respond_to(:collaborator2)
|
60
|
+
expect(subject.collaborator2.run).to be_true
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#prepare_collaborator" do
|
64
|
+
|
65
|
+
let(:subject2) { SubjectWithPrepareCollaborator.new }
|
66
|
+
|
67
|
+
class SubjectWithPrepareCollaborator
|
68
|
+
extend Collaborator
|
69
|
+
dependency :collaborator1, Collaborator1.new
|
70
|
+
|
71
|
+
def prepare_collaborator(name, collaborator)
|
72
|
+
collaborator.foo = 9
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'gets call when using the dependency' do
|
77
|
+
subject2.should_receive(:prepare_collaborator)
|
78
|
+
subject2.collaborator1
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'passes the name of the collaborator' do
|
82
|
+
subject2.stub(:prepare_collaborator) do |name, collaborator|
|
83
|
+
expect(name).to eq(:collaborator1)
|
84
|
+
end
|
85
|
+
subject2.collaborator1
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'passes the reference to the collaborator' do
|
89
|
+
subject2.stub(:prepare_collaborator) do |name, collaborator|
|
90
|
+
expect(collaborator).to be_instance_of(Collaborator1)
|
91
|
+
end
|
92
|
+
subject2.collaborator1
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'gets call when a dependency is injected' do
|
96
|
+
subject2.should_receive(:prepare_collaborator)
|
97
|
+
subject2.collaborator1 = injected_collaborator
|
98
|
+
end
|
99
|
+
|
100
|
+
it "runs the code in the method" do
|
101
|
+
expect(subject2.collaborator1.foo).to eq(9)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "runs the code in the method for an injected collaborator" do
|
105
|
+
injected = OpenStruct.new
|
106
|
+
subject2.collaborator1 = injected
|
107
|
+
expect(injected.foo).to eq(9)
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
|
48
113
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: collaborator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -125,7 +125,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
125
125
|
version: '0'
|
126
126
|
segments:
|
127
127
|
- 0
|
128
|
-
hash:
|
128
|
+
hash: 2528418177998634082
|
129
129
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
130
|
none: false
|
131
131
|
requirements:
|