conject 0.0.7 → 0.0.8
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/README.md +55 -2
- data/TODO +9 -4
- data/conject.gemspec +1 -0
- data/lib/conject.rb +1 -0
- data/lib/conject/class_ext_object_peers.rb +9 -0
- data/lib/conject/object_context.rb +12 -6
- data/lib/conject/object_factory.rb +53 -7
- data/lib/conject/version.rb +1 -1
- data/spec/acceptance/dev/object_peers_spec.rb +87 -0
- data/spec/acceptance/regression/basic_composition_spec.rb +4 -1
- data/spec/acceptance/regression/basic_object_creation_spec.rb +9 -1
- data/spec/acceptance/regression/custom_constructor_spec.rb +9 -6
- data/spec/acceptance/regression/inject_object_context_spec.rb +33 -1
- data/spec/acceptance/regression/nested_contexts_spec.rb +14 -1
- data/spec/acceptance/regression/non_singleton_spec.rb +0 -4
- data/spec/conject/object_factory_spec.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/test_data/basic_composition/and_justice_for_all.rb +9 -0
- data/spec/test_data/basic_composition/ride_the_lightning.rb +7 -0
- data/spec/test_data/object_peers/alt_game.rb +3 -0
- data/spec/test_data/object_peers/bullet.rb +4 -0
- data/spec/test_data/object_peers/bullet_coordinator.rb +2 -0
- data/spec/test_data/object_peers/game.rb +3 -0
- data/spec/test_data/simple_stuff/class_that_uses_context_in_init.rb +7 -0
- metadata +63 -10
- data/TODO.txt +0 -4
data/README.md
CHANGED
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
Retrieve and relate objects within contexts. Provides dependency injection convenience inspired by the simplicity of Google's Guice.
|
4
4
|
|
5
|
-
#
|
5
|
+
# Basic composition #
|
6
|
+
|
7
|
+
Declare required component objects for a class using .construct_with
|
8
|
+
|
6
9
|
|
7
10
|
require 'conject'
|
8
11
|
|
@@ -26,7 +29,23 @@ Retrieve and relate objects within contexts. Provides dependency injection conv
|
|
26
29
|
puts fence
|
27
30
|
#=> "I'm made of Wood and Nails"
|
28
31
|
|
29
|
-
#
|
32
|
+
# Configuring objects #
|
33
|
+
|
34
|
+
Call #configure_object or #configure_objects to configure one or more objects wrt
|
35
|
+
their construction or handling.
|
36
|
+
|
37
|
+
* :cache [true|false] - Enable/disable object caching in context. If false, a new instance is created for every request for an object with the given name. Default true.
|
38
|
+
* :construct [Proc|Lambda] - Anonymous function to call to provide the named object. Will be cached like any other object, subject to :cache configuration for this context.
|
39
|
+
|
40
|
+
Eg.
|
41
|
+
context.configure_objects({
|
42
|
+
:wood => { :cache => false },
|
43
|
+
:nails => { :construct => lambda do "The nails" end},
|
44
|
+
})
|
45
|
+
# context[:wood] != context[:wood]
|
46
|
+
# context[:nails] == "The nails"
|
47
|
+
|
48
|
+
# Modules as namespaces #
|
30
49
|
|
31
50
|
module Chart
|
32
51
|
class Presenter
|
@@ -38,3 +57,37 @@ Retrieve and relate objects within contexts. Provides dependency injection conv
|
|
38
57
|
end
|
39
58
|
end
|
40
59
|
|
60
|
+
# Subcontexts #
|
61
|
+
|
62
|
+
first_fence = nil
|
63
|
+
second_fence = nil
|
64
|
+
|
65
|
+
Conject.default_object_context.in_subcontext do |sub|
|
66
|
+
first_fence = sub[:fence]
|
67
|
+
end
|
68
|
+
|
69
|
+
Conject.default_object_context.in_subcontext do |sub|
|
70
|
+
second_fence = sub[:fence]
|
71
|
+
end
|
72
|
+
|
73
|
+
# second_fence != first_fence
|
74
|
+
|
75
|
+
If you'd like to ensure that certain dependencies needed by objects built in subcontexts are actually housed in the parent context, but they
|
76
|
+
have not necessarily been cached or injected in advance, AND you've got an "owner"-like object living in that context, you can declare
|
77
|
+
object peers within the class definition of that owner object. This ensures that collaborators in the subcontext will not cause the peer
|
78
|
+
objects to be instantiated in those subcontexts as well.
|
79
|
+
|
80
|
+
class Game
|
81
|
+
peer_objects :missile_coordinator, :wind_affector
|
82
|
+
end
|
83
|
+
|
84
|
+
In this example, the instantiation of a Game instance in an object context will cause missile coordinator and wind affector to be "anchored"
|
85
|
+
in the same context as the game instance, meaning they prefer to be instantiated here, if needed by any objects in this same context or any
|
86
|
+
subcontexts thereof. It also means that they will be preferred over any objects of the same name in a super context.
|
87
|
+
|
88
|
+
# My ObjectContext #
|
89
|
+
|
90
|
+
All classes built within an ObjectContext are able to reference the context directly via the private accessor method "#object_context", which
|
91
|
+
is available as early as the call to #initialize.
|
92
|
+
|
93
|
+
|
data/TODO
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
ISSUE 2012-04-25: construct_with cyclic dependency checking! Eg. Presenter construc_with :presenter -> stack overlow
|
2
|
-
|
2
|
+
ISSUE 2012-04-30: prevent #put for already-existant objects
|
3
|
+
ISSUE 2012-04-30: prevent #configure_object(s) for already-existant objects
|
3
4
|
|
4
5
|
Features:
|
5
6
|
customer construction lambda via configure_objects
|
@@ -16,8 +17,12 @@ Features:
|
|
16
17
|
|
17
18
|
Support classes namespaced to modules
|
18
19
|
|
20
|
+
Conject.new_object_context (support no-args, default parent context to nil)
|
21
|
+
|
22
|
+
|
23
|
+
Tasks:
|
24
|
+
GET GOING IN TRAVIS CI
|
25
|
+
|
26
|
+
Cleanup meta programming in .construct_with it's NASTY
|
19
27
|
|
20
|
-
Move / copy test data (loadable classes) into spec/acceptance/testdata
|
21
|
-
Make helpers for accessing that folder
|
22
|
-
Make helper to set load path for a specific test
|
23
28
|
|
data/conject.gemspec
CHANGED
data/lib/conject.rb
CHANGED
@@ -3,6 +3,7 @@ require "conject/version"
|
|
3
3
|
require 'conject/object_definition'
|
4
4
|
require 'conject/extended_metaid'
|
5
5
|
require 'conject/class_ext_construct_with'
|
6
|
+
require 'conject/class_ext_object_peers'
|
6
7
|
require 'conject/object_context'
|
7
8
|
require 'conject/object_factory'
|
8
9
|
require 'conject/class_finder'
|
@@ -23,7 +23,7 @@ module Conject
|
|
23
23
|
name = name.to_sym
|
24
24
|
return @cache[name] if @cache.keys.include?(name)
|
25
25
|
|
26
|
-
if parent_context and parent_context.has?(name)
|
26
|
+
if !has_config?(name) and parent_context and parent_context.has?(name)
|
27
27
|
return parent_context.get(name)
|
28
28
|
else
|
29
29
|
object = object_factory.construct_new(name,self)
|
@@ -50,7 +50,11 @@ module Conject
|
|
50
50
|
# Indicates if this context has the requested object in its own personal cache.
|
51
51
|
# (Does not consult any parent contexts.)
|
52
52
|
def directly_has?(name)
|
53
|
-
@cache.keys.include?(name.to_sym)
|
53
|
+
@cache.keys.include?(name.to_sym) or has_config?(name.to_sym)
|
54
|
+
end
|
55
|
+
|
56
|
+
def has_config?(name)
|
57
|
+
@object_configs.keys.include?(name.to_sym)
|
54
58
|
end
|
55
59
|
|
56
60
|
# Create and yield a new ObjectContext with this ObjectContext as its parent
|
@@ -62,9 +66,11 @@ module Conject
|
|
62
66
|
#
|
63
67
|
# Allow configuration options to be set for named objects.
|
64
68
|
#
|
65
|
-
def configure_objects(
|
66
|
-
|
67
|
-
|
69
|
+
def configure_objects(confs={})
|
70
|
+
confs.each do |key,opts|
|
71
|
+
key = key.to_sym
|
72
|
+
@object_configs[key] ={} unless has_config?(key)
|
73
|
+
@object_configs[key].merge!(opts)
|
68
74
|
end
|
69
75
|
end
|
70
76
|
|
@@ -72,7 +78,7 @@ module Conject
|
|
72
78
|
# Get the object configuration options for the given name
|
73
79
|
#
|
74
80
|
def get_object_config(name)
|
75
|
-
@object_configs[name.to_sym]
|
81
|
+
@object_configs[name.to_sym] || {}
|
76
82
|
end
|
77
83
|
|
78
84
|
private
|
@@ -4,21 +4,36 @@ module Conject
|
|
4
4
|
construct_with :class_finder, :dependency_resolver
|
5
5
|
|
6
6
|
def construct_new(name, object_context)
|
7
|
-
|
7
|
+
object = nil
|
8
|
+
config = object_context.get_object_config(name)
|
9
|
+
lambda_constructor = config[:construct]
|
8
10
|
if lambda_constructor
|
9
11
|
case lambda_constructor.arity
|
10
12
|
when 0
|
11
|
-
|
13
|
+
object = lambda_constructor[]
|
12
14
|
when 1
|
13
|
-
|
15
|
+
object = lambda_constructor[object_context]
|
14
16
|
when 2
|
15
|
-
|
17
|
+
object = lambda_constructor[name, object_context]
|
16
18
|
else
|
17
19
|
raise "Constructor lambda takes 0, 1 or 2 params; this lambda takes #{lambda_constructor.arity}"
|
18
20
|
end
|
21
|
+
|
22
|
+
# Provide a private accessor to the assigned object context
|
23
|
+
class << object
|
24
|
+
private
|
25
|
+
def object_context
|
26
|
+
@_conject_object_context #|| Conject.default_object_context
|
27
|
+
end
|
28
|
+
end
|
19
29
|
else
|
20
|
-
|
30
|
+
object = type_1_constructor(name, object_context)
|
21
31
|
end
|
32
|
+
|
33
|
+
# Stuff an internal back reference to the object context into the new object:
|
34
|
+
object.send(:instance_variable_set, :@_conject_object_context, object_context)
|
35
|
+
|
36
|
+
return object
|
22
37
|
end
|
23
38
|
|
24
39
|
private
|
@@ -31,18 +46,49 @@ module Conject
|
|
31
46
|
def type_1_constructor(name, object_context)
|
32
47
|
klass = class_finder.find_class(name)
|
33
48
|
|
49
|
+
if !klass.object_peers.empty?
|
50
|
+
anchor_object_peers object_context, klass.object_peers
|
51
|
+
end
|
52
|
+
|
53
|
+
# Provide a private accessor to the assigned object context
|
54
|
+
klass.class_def_private :object_context do
|
55
|
+
@_conject_object_context || Thread.current[:current_object_context] #|| Conject.default_object_context
|
56
|
+
end
|
57
|
+
|
58
|
+
constructor_func = nil
|
34
59
|
if klass.has_object_definition?
|
35
60
|
object_map = dependency_resolver.resolve_for_class(klass, object_context)
|
36
|
-
|
61
|
+
constructor_func = lambda do klass.new(object_map) end
|
37
62
|
|
38
63
|
elsif Utilities.has_zero_arg_constructor?(klass)
|
39
64
|
# Default construction
|
40
|
-
|
65
|
+
constructor_func = lambda do klass.new end
|
66
|
+
Thread.current[:current_object_context] = object_context
|
67
|
+
begin
|
68
|
+
ensure
|
69
|
+
Thread.current[:current_object_context] = nil
|
70
|
+
end
|
41
71
|
else
|
42
72
|
# Oops, out of ideas on how to build.
|
43
73
|
raise ArgumentError.new("Class #{klass} has no special component needs, but neither does it have a zero-argument constructor.");
|
44
74
|
end
|
45
75
|
|
76
|
+
object = nil
|
77
|
+
Thread.current[:current_object_context] = object_context
|
78
|
+
begin
|
79
|
+
object = constructor_func.call
|
80
|
+
ensure
|
81
|
+
Thread.current[:current_object_context] = nil
|
82
|
+
end
|
83
|
+
|
84
|
+
return object
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
def anchor_object_peers(object_context, object_peers)
|
89
|
+
object_peers.each do |name|
|
90
|
+
object_context.configure_objects(name => {})
|
91
|
+
end
|
46
92
|
end
|
47
93
|
end
|
48
94
|
end
|
data/lib/conject/version.rb
CHANGED
@@ -0,0 +1,87 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
|
+
|
3
|
+
describe "object_peers" do
|
4
|
+
subject { new_object_context }
|
5
|
+
|
6
|
+
before do
|
7
|
+
append_test_load_path "object_peers"
|
8
|
+
require 'game'
|
9
|
+
require 'alt_game'
|
10
|
+
require 'bullet'
|
11
|
+
require 'bullet_coordinator'
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
restore_load_path
|
16
|
+
end
|
17
|
+
|
18
|
+
it "establishes objects that should, when summoned (even from objects in sub contexts), be constructed in the declarer's context" do
|
19
|
+
subject.has?(:bullet_coordinator).should be_false
|
20
|
+
subject.instance_variable_get(:@cache).keys.should_not include(:bullet_coordinator)
|
21
|
+
|
22
|
+
subject[:game]
|
23
|
+
|
24
|
+
subject.has?(:bullet_coordinator).should be_true
|
25
|
+
subject.instance_variable_get(:@cache).keys.should_not include(:bullet_coordinator) # shouldn't actually be there
|
26
|
+
|
27
|
+
sub1 = nil
|
28
|
+
bullet1 = nil
|
29
|
+
subject.in_subcontext do |sub|
|
30
|
+
sub1 = sub
|
31
|
+
bullet1 = sub[:bullet]
|
32
|
+
end
|
33
|
+
|
34
|
+
bullet1.should be
|
35
|
+
|
36
|
+
sub2 = nil
|
37
|
+
bullet2 = nil
|
38
|
+
subject.in_subcontext do |sub|
|
39
|
+
sub2 = sub
|
40
|
+
bullet2 = sub[:bullet]
|
41
|
+
end
|
42
|
+
|
43
|
+
bullet2.should be
|
44
|
+
|
45
|
+
bullet1.should_not == bullet2
|
46
|
+
sub1.should_not == subject
|
47
|
+
sub1.should_not == sub2
|
48
|
+
|
49
|
+
subject.has?(:bullet_coordinator).should be_true
|
50
|
+
subject.instance_variable_get(:@cache).keys.should include(:bullet_coordinator)
|
51
|
+
|
52
|
+
bullet1.bullet_coordinator.should be
|
53
|
+
bullet1.bullet_coordinator.should == subject[:bullet_coordinator]
|
54
|
+
|
55
|
+
bullet2.bullet_coordinator.should be
|
56
|
+
bullet2.bullet_coordinator.should == subject[:bullet_coordinator]
|
57
|
+
|
58
|
+
sub1[:bullet_coordinator].should == subject[:bullet_coordinator]
|
59
|
+
sub2[:bullet_coordinator].should == subject[:bullet_coordinator]
|
60
|
+
end
|
61
|
+
|
62
|
+
it "allows subcontexts to shadow parent context objects" do
|
63
|
+
# Instantiate objs in super context
|
64
|
+
game = subject[:game]
|
65
|
+
# See it working normally: bullets in subcontexts should cause the bc to be built in the super
|
66
|
+
bullet1 = nil
|
67
|
+
subject.in_subcontext do |sub|
|
68
|
+
bullet1 = sub[:bullet]
|
69
|
+
end
|
70
|
+
bc1 = subject[:bullet_coordinator]
|
71
|
+
bc1.should be
|
72
|
+
bullet1.bullet_coordinator.should == bc1
|
73
|
+
|
74
|
+
# Now try a shadow:
|
75
|
+
game2 = nil
|
76
|
+
bc2 = nil
|
77
|
+
subject.in_subcontext do |sub|
|
78
|
+
game2 = sub[:alt_game] # This class declares bullet_coordinator as an object peer, so we should be getting a newly built coord...
|
79
|
+
bc2 = sub[:bullet_coordinator]
|
80
|
+
end
|
81
|
+
game2.should be
|
82
|
+
bc2.should be
|
83
|
+
|
84
|
+
bc2.should_not == bc1
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
2
|
|
3
3
|
describe "basic object composition" do
|
4
|
-
subject {
|
4
|
+
subject { new_object_context }
|
5
5
|
|
6
6
|
before do
|
7
7
|
append_test_load_path "basic_composition"
|
@@ -17,12 +17,15 @@ describe "basic object composition" do
|
|
17
17
|
it "constructs objects by providing necessary object components" do
|
18
18
|
fence = subject.get('fence')
|
19
19
|
fence.should_not be_nil
|
20
|
+
fence.send(:object_context).should == subject
|
20
21
|
|
21
22
|
fence.wood.should_not be_nil
|
22
23
|
fence.wood.object_id.should == subject.get('wood').object_id
|
24
|
+
fence.wood.send(:object_context).should == subject
|
23
25
|
|
24
26
|
fence.nails.should_not be_nil
|
25
27
|
fence.nails.object_id.should == subject.get('nails').object_id
|
28
|
+
fence.nails.send(:object_context).should == subject
|
26
29
|
end
|
27
30
|
|
28
31
|
end
|
@@ -2,11 +2,12 @@ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
|
2
2
|
|
3
3
|
|
4
4
|
describe "simple object creation" do
|
5
|
-
subject {
|
5
|
+
subject { new_object_context }
|
6
6
|
|
7
7
|
before do
|
8
8
|
append_test_load_path "simple_stuff"
|
9
9
|
require 'some_random_class'
|
10
|
+
require 'class_that_uses_context_in_init'
|
10
11
|
end
|
11
12
|
|
12
13
|
after do
|
@@ -17,6 +18,7 @@ describe "simple object creation" do
|
|
17
18
|
obj = subject.get('some_random_class')
|
18
19
|
obj.should_not be_nil
|
19
20
|
obj.class.should == SomeRandomClass
|
21
|
+
obj.send(:object_context).should == subject
|
20
22
|
end
|
21
23
|
|
22
24
|
it "caches and returns references to same objects once built" do
|
@@ -38,5 +40,11 @@ describe "simple object creation" do
|
|
38
40
|
obj.object_id.should == obj2.object_id
|
39
41
|
end
|
40
42
|
|
43
|
+
it "ensures access to object_context in initializer" do
|
44
|
+
obj = subject.get('class_that_uses_context_in_init')
|
45
|
+
obj.init_time_object_context.should == subject
|
46
|
+
obj.send(:object_context).should == subject
|
47
|
+
end
|
48
|
+
|
41
49
|
end
|
42
50
|
|
@@ -12,11 +12,11 @@ describe "configuring objects to be built with a lambda" do
|
|
12
12
|
|
13
13
|
let :wood_substitute do
|
14
14
|
Class.new do
|
15
|
-
attr_reader :name, :
|
15
|
+
attr_reader :name, :my_object_context
|
16
16
|
|
17
|
-
def initialize(name,
|
17
|
+
def initialize(name,my_object_context)
|
18
18
|
@name = name
|
19
|
-
@
|
19
|
+
@my_object_context = my_object_context
|
20
20
|
end
|
21
21
|
|
22
22
|
def to_s
|
@@ -35,9 +35,9 @@ describe "configuring objects to be built with a lambda" do
|
|
35
35
|
|
36
36
|
subject.configure_objects(
|
37
37
|
:wood => {
|
38
|
-
:construct => lambda do |name,
|
38
|
+
:construct => lambda do |name,the_object_context|
|
39
39
|
wood_constructs += 1
|
40
|
-
wood_substitute.new name,
|
40
|
+
wood_substitute.new name,the_object_context
|
41
41
|
end
|
42
42
|
}
|
43
43
|
)
|
@@ -46,11 +46,14 @@ describe "configuring objects to be built with a lambda" do
|
|
46
46
|
fence.wood.should be
|
47
47
|
fence.wood.to_s.should == "MDF"
|
48
48
|
fence.wood.name.should == :wood
|
49
|
-
fence.wood.
|
49
|
+
fence.wood.my_object_context.should == subject # shows the context was passed along to the lambda
|
50
|
+
fence.wood.send(:object_context).should == subject # shows Conject assigned the object context on its own
|
50
51
|
wood_constructs.should == 1
|
51
52
|
|
52
53
|
subject.get(:wood).should == fence.wood
|
53
54
|
wood_constructs.should == 1
|
55
|
+
|
56
|
+
|
54
57
|
end
|
55
58
|
|
56
59
|
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
2
|
|
3
3
|
describe "object referencing its own context" do
|
4
|
-
subject {
|
4
|
+
subject { new_object_context }
|
5
5
|
|
6
6
|
before do
|
7
7
|
append_test_load_path "basic_composition"
|
8
8
|
require 'master_of_puppets'
|
9
|
+
require 'ride_the_lightning'
|
10
|
+
require 'and_justice_for_all'
|
9
11
|
end
|
10
12
|
|
11
13
|
after do
|
@@ -23,6 +25,36 @@ describe "object referencing its own context" do
|
|
23
25
|
master.this_object_context.get('master_of_puppets').should == master
|
24
26
|
end
|
25
27
|
|
28
|
+
describe "NEW AND IMPROVED" do
|
29
|
+
|
30
|
+
describe "classes with object definitions" do
|
31
|
+
let(:justice) { subject.get('and_justice_for_all') }
|
32
|
+
let(:ride) { subject.get('ride_the_lightning') }
|
33
|
+
|
34
|
+
it "automatically get a private accessor for object_context, even if not requested" do
|
35
|
+
justice.send(:object_context).should == subject
|
36
|
+
ride.send(:object_context).should == subject # watching out for interaction bugs wrt dependency construction
|
37
|
+
end
|
38
|
+
|
39
|
+
it "can use object_context in initialize" do
|
40
|
+
justice.init_time_object_context.should == subject
|
41
|
+
ride.init_time_object_context.should == subject # watching out for interaction bugs wrt dependency construction
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "classes WITHOUT object definitions" do
|
46
|
+
let(:ride) { subject.get('ride_the_lightning') }
|
47
|
+
|
48
|
+
it "automatically get a private accessor for object_context, even if not requested" do
|
49
|
+
ride.send(:object_context).should == subject
|
50
|
+
end
|
51
|
+
|
52
|
+
it "can use object_context in initialize" do
|
53
|
+
ride.init_time_object_context.should == subject
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
26
58
|
|
27
59
|
end
|
28
60
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
3
3
|
|
4
4
|
describe "nested contexts" do
|
5
|
-
subject {
|
5
|
+
subject { new_object_context }
|
6
6
|
|
7
7
|
let(:root_context) { subject }
|
8
8
|
|
@@ -12,6 +12,7 @@ describe "nested contexts" do
|
|
12
12
|
require 'front_desk'
|
13
13
|
require 'guest'
|
14
14
|
require 'tv'
|
15
|
+
require 'grass'
|
15
16
|
end
|
16
17
|
|
17
18
|
after do
|
@@ -82,5 +83,17 @@ describe "nested contexts" do
|
|
82
83
|
end
|
83
84
|
end
|
84
85
|
|
86
|
+
it "assigns the correct object context to objects at each level" do
|
87
|
+
grass = root_context[:grass]
|
88
|
+
grass.should be
|
89
|
+
grass.send(:object_context).should == root_context
|
90
|
+
|
91
|
+
root_context.in_subcontext do |hotel|
|
92
|
+
hotel.should_not == root_context
|
93
|
+
front_desk = hotel[:front_desk]
|
94
|
+
front_desk.send(:object_context).should == hotel
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
85
98
|
end
|
86
99
|
|
@@ -31,10 +31,6 @@ describe "configuring objects to be non-cacheable" do
|
|
31
31
|
# nails should also be unique:
|
32
32
|
f1.nails.should_not == f2.nails
|
33
33
|
|
34
|
-
# context should not retain references to fence or nails:
|
35
|
-
subject.has?(:fence).should == false
|
36
|
-
subject.has?(:nails).should == false
|
37
|
-
|
38
34
|
# wood should remain cached as usual, and shared
|
39
35
|
f1.wood.should == f2.wood
|
40
36
|
subject.has?(:wood).should == true
|
@@ -25,6 +25,8 @@ describe Conject::ObjectFactory do
|
|
25
25
|
describe "for Type 1 object construction" do
|
26
26
|
before do
|
27
27
|
object_context.stub(:get_object_config).and_return({})
|
28
|
+
my_object_class.stub(:class_def_private) # the effect of this is tested in acceptance tests
|
29
|
+
my_object_class.stub(:object_peers).and_return([]) # the effect of this is tested in acceptance tests
|
28
30
|
|
29
31
|
class_finder.should_receive(:find_class).with(my_object_name).and_return my_object_class
|
30
32
|
Conject::Utilities.stub(:has_zero_arg_constructor?).and_return true
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: conject
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: rspec
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,31 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :development
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: simplecov
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: pry
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
39
65
|
none: false
|
40
66
|
requirements:
|
41
67
|
- - ! '>='
|
@@ -43,7 +69,12 @@ dependencies:
|
|
43
69
|
version: '0'
|
44
70
|
type: :development
|
45
71
|
prerelease: false
|
46
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
47
78
|
description: Enable Guice-like dependency injection and contextual object interactions.
|
48
79
|
email:
|
49
80
|
- david.crosby@atomicobject.com
|
@@ -59,12 +90,12 @@ files:
|
|
59
90
|
- README.md
|
60
91
|
- Rakefile
|
61
92
|
- TODO
|
62
|
-
- TODO.txt
|
63
93
|
- conject.gemspec
|
64
94
|
- doc/inheritance_woes.txt
|
65
95
|
- lib/conject.rb
|
66
96
|
- lib/conject/borrowed_active_support_inflector.rb
|
67
97
|
- lib/conject/class_ext_construct_with.rb
|
98
|
+
- lib/conject/class_ext_object_peers.rb
|
68
99
|
- lib/conject/class_finder.rb
|
69
100
|
- lib/conject/composition_error.rb
|
70
101
|
- lib/conject/dependency_resolver.rb
|
@@ -87,6 +118,7 @@ files:
|
|
87
118
|
- scratch/sample.rb
|
88
119
|
- scratch/special_construct.rb
|
89
120
|
- spec/acceptance/dev/README
|
121
|
+
- spec/acceptance/dev/object_peers_spec.rb
|
90
122
|
- spec/acceptance/regression/README
|
91
123
|
- spec/acceptance/regression/basic_composition_spec.rb
|
92
124
|
- spec/acceptance/regression/basic_object_creation_spec.rb
|
@@ -111,6 +143,7 @@ files:
|
|
111
143
|
- spec/support/SPEC_HELPERS_GO_HERE
|
112
144
|
- spec/support/conject_helpers.rb
|
113
145
|
- spec/support/load_path_helpers.rb
|
146
|
+
- spec/test_data/basic_composition/and_justice_for_all.rb
|
114
147
|
- spec/test_data/basic_composition/fence.rb
|
115
148
|
- spec/test_data/basic_composition/front_desk.rb
|
116
149
|
- spec/test_data/basic_composition/grass.rb
|
@@ -118,6 +151,7 @@ files:
|
|
118
151
|
- spec/test_data/basic_composition/lobby.rb
|
119
152
|
- spec/test_data/basic_composition/master_of_puppets.rb
|
120
153
|
- spec/test_data/basic_composition/nails.rb
|
154
|
+
- spec/test_data/basic_composition/ride_the_lightning.rb
|
121
155
|
- spec/test_data/basic_composition/special_guest.rb
|
122
156
|
- spec/test_data/basic_composition/tv.rb
|
123
157
|
- spec/test_data/basic_composition/very_special_guest.rb
|
@@ -132,6 +166,11 @@ files:
|
|
132
166
|
- spec/test_data/namespace/chart/presenter.rb
|
133
167
|
- spec/test_data/namespace/chart/view.rb
|
134
168
|
- spec/test_data/namespace/somewhere/deep/inside/the/earth.rb
|
169
|
+
- spec/test_data/object_peers/alt_game.rb
|
170
|
+
- spec/test_data/object_peers/bullet.rb
|
171
|
+
- spec/test_data/object_peers/bullet_coordinator.rb
|
172
|
+
- spec/test_data/object_peers/game.rb
|
173
|
+
- spec/test_data/simple_stuff/class_that_uses_context_in_init.rb
|
135
174
|
- spec/test_data/simple_stuff/some_random_class.rb
|
136
175
|
- src/user_model.rb
|
137
176
|
- src/user_presenter.rb
|
@@ -148,20 +187,27 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
148
187
|
- - ! '>='
|
149
188
|
- !ruby/object:Gem::Version
|
150
189
|
version: '0'
|
190
|
+
segments:
|
191
|
+
- 0
|
192
|
+
hash: -3446257381673869502
|
151
193
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
194
|
none: false
|
153
195
|
requirements:
|
154
196
|
- - ! '>='
|
155
197
|
- !ruby/object:Gem::Version
|
156
198
|
version: '0'
|
199
|
+
segments:
|
200
|
+
- 0
|
201
|
+
hash: -3446257381673869502
|
157
202
|
requirements: []
|
158
203
|
rubyforge_project:
|
159
|
-
rubygems_version: 1.8.
|
204
|
+
rubygems_version: 1.8.24
|
160
205
|
signing_key:
|
161
206
|
specification_version: 3
|
162
207
|
summary: Enable Guice-like dependency injection and contextual object interactions.
|
163
208
|
test_files:
|
164
209
|
- spec/acceptance/dev/README
|
210
|
+
- spec/acceptance/dev/object_peers_spec.rb
|
165
211
|
- spec/acceptance/regression/README
|
166
212
|
- spec/acceptance/regression/basic_composition_spec.rb
|
167
213
|
- spec/acceptance/regression/basic_object_creation_spec.rb
|
@@ -186,6 +232,7 @@ test_files:
|
|
186
232
|
- spec/support/SPEC_HELPERS_GO_HERE
|
187
233
|
- spec/support/conject_helpers.rb
|
188
234
|
- spec/support/load_path_helpers.rb
|
235
|
+
- spec/test_data/basic_composition/and_justice_for_all.rb
|
189
236
|
- spec/test_data/basic_composition/fence.rb
|
190
237
|
- spec/test_data/basic_composition/front_desk.rb
|
191
238
|
- spec/test_data/basic_composition/grass.rb
|
@@ -193,6 +240,7 @@ test_files:
|
|
193
240
|
- spec/test_data/basic_composition/lobby.rb
|
194
241
|
- spec/test_data/basic_composition/master_of_puppets.rb
|
195
242
|
- spec/test_data/basic_composition/nails.rb
|
243
|
+
- spec/test_data/basic_composition/ride_the_lightning.rb
|
196
244
|
- spec/test_data/basic_composition/special_guest.rb
|
197
245
|
- spec/test_data/basic_composition/tv.rb
|
198
246
|
- spec/test_data/basic_composition/very_special_guest.rb
|
@@ -207,4 +255,9 @@ test_files:
|
|
207
255
|
- spec/test_data/namespace/chart/presenter.rb
|
208
256
|
- spec/test_data/namespace/chart/view.rb
|
209
257
|
- spec/test_data/namespace/somewhere/deep/inside/the/earth.rb
|
258
|
+
- spec/test_data/object_peers/alt_game.rb
|
259
|
+
- spec/test_data/object_peers/bullet.rb
|
260
|
+
- spec/test_data/object_peers/bullet_coordinator.rb
|
261
|
+
- spec/test_data/object_peers/game.rb
|
262
|
+
- spec/test_data/simple_stuff/class_that_uses_context_in_init.rb
|
210
263
|
- spec/test_data/simple_stuff/some_random_class.rb
|
data/TODO.txt
DELETED