conject 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ Conject v0.1.8
2
+ * Fixed: bug in class finder when resolving module-namespaced objects
3
+ * Added: LICENSE
4
+
1
5
  Conject v0.1.7
2
6
  * Added :class and :specialize object configurations
3
7
  * Fixed a bug in the error handler that catches exceptions in object constructors
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 David Crosby
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -6,29 +6,29 @@ Retrieve and relate objects within contexts. Provides dependency injection conv
6
6
 
7
7
  Declare required component objects for a class using .construct_with
8
8
 
9
+ ```ruby
10
+ require 'conject'
9
11
 
10
- require 'conject'
12
+ class Wood
13
+ def to_s; "Wood"; end
14
+ end
11
15
 
12
- class Wood
13
- def to_s; "Wood"; end
14
- end
15
-
16
- class Nails
17
- def to_s; "Nails"; end
18
- end
16
+ class Nails
17
+ def to_s; "Nails"; end
18
+ end
19
19
 
20
- class Fence
21
- construct_with :wood, :nails
20
+ class Fence
21
+ construct_with :wood, :nails
22
22
 
23
- def to_s
24
- "I'm made of #{wood} and #{nails}"
25
- end
26
- end
27
-
28
- fence = Conject.default_object_context.get(:fence)
29
- puts fence
30
- #=> "I'm made of Wood and Nails"
23
+ def to_s
24
+ "I'm made of #{wood} and #{nails}"
25
+ end
26
+ end
31
27
 
28
+ fence = Conject.default_object_context.get(:fence)
29
+ puts fence
30
+ #=> "I'm made of Wood and Nails"
31
+ ```
32
32
  # Configuring objects #
33
33
 
34
34
  Call #configure_object or #configure_objects to configure one or more objects wrt
@@ -47,39 +47,43 @@ Eg.
47
47
 
48
48
  # Modules as namespaces #
49
49
 
50
- module Chart
51
- class Presenter
52
- construct_with 'chart/model', 'chart/view'
50
+ ```ruby
51
+ module Chart
52
+ class Presenter
53
+ construct_with 'chart/model', 'chart/view'
53
54
 
54
- def to_s
55
- "I'm a Chart::Presenter composed of a #{model} and a #{view}"
56
- end
57
- end
55
+ def to_s
56
+ "I'm a Chart::Presenter composed of a #{model} and a #{view}"
58
57
  end
59
-
58
+ end
59
+ end
60
+ ```
60
61
  # Subcontexts #
61
62
 
62
- first_fence = nil
63
- second_fence = nil
63
+ ```ruby
64
+ first_fence = nil
65
+ second_fence = nil
64
66
 
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
67
+ Conject.default_object_context.in_subcontext do |sub|
68
+ first_fence = sub[:fence]
69
+ end
72
70
 
73
- # second_fence != first_fence
71
+ Conject.default_object_context.in_subcontext do |sub|
72
+ second_fence = sub[:fence]
73
+ end
74
74
 
75
+ # second_fence != first_fence
76
+ ```
75
77
  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
78
  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
79
  object peers within the class definition of that owner object. This ensures that collaborators in the subcontext will not cause the peer
78
80
  objects to be instantiated in those subcontexts as well.
79
81
 
80
- class Game
81
- object_peers: :missile_coordinator, :wind_affector
82
- end
82
+ ```ruby
83
+ class Game
84
+ object_peers: :missile_coordinator, :wind_affector
85
+ end
86
+ ```
83
87
 
84
88
  In this example, the instantiation of a Game instance in an object context will cause missile coordinator and wind affector to be "anchored"
85
89
  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
@@ -94,12 +98,16 @@ is available as early as the call to #initialize.
94
98
  The following will cause one object to be fulfilled by another. In this case, 'album' is not expected to be built
95
99
  as an instance of the Album class, but rather will be set up as another name for 'and_justice_for_all':
96
100
 
97
- context.configure_objects album: { is: 'and_justice_for_all' }
101
+ ```ruby
102
+ context.configure_objects album: { is: 'and_justice_for_all' }
103
+ ```
98
104
 
99
105
  Both 'album' and 'and_justice_for_all' will be built in the context when 'album' is first requested.
100
106
  This is more or less expressive shorthand for:
101
107
 
102
- context['album'] = context['and_justice_for_all']
108
+ ```ruby
109
+ context['album'] = context['and_justice_for_all']
110
+ ```
103
111
 
104
112
  ...EXCEPT that it's a lazy approach: using 'is' means nothing actually gets built or set in the context before it
105
113
  is requested or composed into another object.
@@ -109,18 +117,20 @@ is requested or composed into another object.
109
117
  To declare objects as instances of a specific class, you may specify the :class of the object via #configure_objects.
110
118
  Furthermore, you can specialize the instance by indicating which specific objects you would like to supply as the object's collaborators:
111
119
 
112
- context.configure_objects({
113
- adventure_time: {
114
- class: Team,
115
- specialize: {
116
- hero: "finn",
117
- sidekick: "jake" }},
118
- dark_knight: {
119
- class: Team,
120
- specialize: {
121
- hero: "batman",
122
- sidekick: "robin" }}
123
- })
120
+ ```ruby
121
+ context.configure_objects({
122
+ adventure_time: {
123
+ class: Team,
124
+ specialize: {
125
+ hero: "finn",
126
+ sidekick: "jake" }},
127
+ dark_knight: {
128
+ class: Team,
129
+ specialize: {
130
+ hero: "batman",
131
+ sidekick: "robin" }}
132
+ })
133
+ ```
124
134
 
125
135
  The keys in :specialize match some or all of the keys defined in the class (in this case, the Team class is defined to be #construct_with :hero, :sidekick, :clock.
126
136
  The values are object names within the ObjectContext; they will be resolved in the usual manner.
@@ -28,8 +28,8 @@ module Conject
28
28
  end
29
29
 
30
30
  def get_constant(within, name)
31
- if within.const_defined?(name)
32
- within.const_get(name)
31
+ if within.const_defined?(name, false)
32
+ within.const_get(name, false)
33
33
  else
34
34
  raise "Could not find class or module named #{name} within #{within}"
35
35
  end
@@ -1,3 +1,3 @@
1
1
  module Conject
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.8"
3
3
  end
@@ -10,6 +10,9 @@ describe "module scoping" do
10
10
  require 'chart/model'
11
11
  require 'chart/presenter'
12
12
  require 'chart/view'
13
+ require 'showing/no/subject'
14
+ require 'showing/ancestor'
15
+ require 'showing/no/fear/fear'
13
16
  end
14
17
 
15
18
  after do
@@ -28,6 +31,12 @@ describe "module scoping" do
28
31
  obj.class.should == Chart::Model
29
32
  end
30
33
 
34
+ it "correctly finds a dependency for modules at different levels" do
35
+ obj1 = subject.get('showing/no/subject')
36
+ obj2 = subject.get('showing/no/fear/fear')
37
+ obj1.send(:ancestor).should == obj2.send(:ancestor)
38
+ end
39
+
31
40
  it "lets objects depend on module-namespaced components" do
32
41
  obj = subject.get('chart/presenter')
33
42
  obj.should_not be_nil
@@ -8,6 +8,8 @@ describe Conject::ClassFinder do
8
8
  require 'some_random_class'
9
9
  require 'chart/model'
10
10
  require 'somewhere/deep/inside/the/earth'
11
+ require 'showing/no/subject'
12
+ require 'showing/ancestor'
11
13
  end
12
14
 
13
15
  after do
@@ -51,6 +53,12 @@ describe Conject::ClassFinder do
51
53
  c.should == Somewhere::Deep::Inside::The::Earth
52
54
  end
53
55
 
56
+ it "does not search for ancestors" do
57
+ lambda do
58
+ subject.find_class("showing/no/showing/ancestor")
59
+ end.should raise_error(/Could not find class.*/)
60
+ end
61
+
54
62
  it "raises an error for a misstep along the way" do
55
63
  lambda do
56
64
  subject.find_class("somewhere/deep/above/the/earth")
@@ -24,7 +24,7 @@ describe Conject::DependencyResolver do
24
24
 
25
25
  let :object_context do StubbedObjectContext.new(oc_objects) end
26
26
 
27
- let :class_finder do mock("class finder") end
27
+ let :class_finder do double("class finder") end
28
28
 
29
29
  before do
30
30
  class_finder.stub(:get_module_path)
@@ -5,8 +5,8 @@ describe Conject::ObjectContext do
5
5
  Conject::ObjectContext.new(:parent_context => parent_context, :object_factory => object_factory)
6
6
  end
7
7
 
8
- let :parent_context do mock(:parent_context) end
9
- let :object_factory do mock(:object_factory) end
8
+ let :parent_context do double(:parent_context) end
9
+ let :object_factory do double(:object_factory) end
10
10
 
11
11
  describe "#get" do
12
12
  describe "when an object has been #put" do
@@ -12,14 +12,14 @@ describe Conject::ObjectFactory do
12
12
 
13
13
  let :my_object_name do :my_object_name end
14
14
 
15
- let :class_finder do mock(:class_finder) end
16
- let :dependency_resolver do mock(:dependency_resolver) end
15
+ let :class_finder do double(:class_finder) end
16
+ let :dependency_resolver do double(:dependency_resolver) end
17
17
 
18
- let :object_context do mock(:object_context) end
18
+ let :object_context do double(:object_context) end
19
19
 
20
20
  let :my_object_class do Class.new end
21
- let :my_object do mock(:my_object) end
22
- let :my_objects_components do mock(:my_objects_components) end
21
+ let :my_object do double(:my_object) end
22
+ let :my_objects_components do double(:my_objects_components) end
23
23
 
24
24
  describe "#construct_new" do
25
25
  describe "for Type 1 object construction" do
@@ -0,0 +1,4 @@
1
+ module Showing
2
+ class Ancestor
3
+ end
4
+ end
@@ -0,0 +1,9 @@
1
+ module Showing
2
+ module No
3
+ module Fear
4
+ class Fear
5
+ construct_with "showing/ancestor"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module Showing
2
+ module No
3
+ class Subject
4
+ construct_with "showing/ancestor"
5
+ end
6
+ end
7
+ end
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.1.7
4
+ version: 0.1.8
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: 2013-02-15 00:00:00.000000000 Z
12
+ date: 2014-03-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -84,6 +84,7 @@ extra_rdoc_files: []
84
84
  files:
85
85
  - CHANGELOG
86
86
  - Gemfile
87
+ - LICENSE
87
88
  - README.md
88
89
  - Rakefile
89
90
  - conject.gemspec
@@ -177,6 +178,9 @@ files:
177
178
  - spec/test_data/namespace/deeply_nested/ez_chart/model.rb
178
179
  - spec/test_data/namespace/deeply_nested/ez_chart/presenter.rb
179
180
  - spec/test_data/namespace/deeply_nested/ez_chart/view.rb
181
+ - spec/test_data/namespace/showing/ancestor.rb
182
+ - spec/test_data/namespace/showing/no/fear/fear.rb
183
+ - spec/test_data/namespace/showing/no/subject.rb
180
184
  - spec/test_data/namespace/somewhere/deep/inside/the/earth.rb
181
185
  - spec/test_data/object_peers/alt_game.rb
182
186
  - spec/test_data/object_peers/bullet.rb
@@ -206,21 +210,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
206
210
  - - ! '>='
207
211
  - !ruby/object:Gem::Version
208
212
  version: '0'
209
- segments:
210
- - 0
211
- hash: -2747476053760078928
212
213
  required_rubygems_version: !ruby/object:Gem::Requirement
213
214
  none: false
214
215
  requirements:
215
216
  - - ! '>='
216
217
  - !ruby/object:Gem::Version
217
218
  version: '0'
218
- segments:
219
- - 0
220
- hash: -2747476053760078928
221
219
  requirements: []
222
220
  rubyforge_project:
223
- rubygems_version: 1.8.24
221
+ rubygems_version: 1.8.23
224
222
  signing_key:
225
223
  specification_version: 3
226
224
  summary: Enable Guice-like dependency injection and contextual object interactions.
@@ -284,6 +282,9 @@ test_files:
284
282
  - spec/test_data/namespace/deeply_nested/ez_chart/model.rb
285
283
  - spec/test_data/namespace/deeply_nested/ez_chart/presenter.rb
286
284
  - spec/test_data/namespace/deeply_nested/ez_chart/view.rb
285
+ - spec/test_data/namespace/showing/ancestor.rb
286
+ - spec/test_data/namespace/showing/no/fear/fear.rb
287
+ - spec/test_data/namespace/showing/no/subject.rb
287
288
  - spec/test_data/namespace/somewhere/deep/inside/the/earth.rb
288
289
  - spec/test_data/object_peers/alt_game.rb
289
290
  - spec/test_data/object_peers/bullet.rb