diy 1.0.3 → 1.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.
Files changed (40) hide show
  1. data/History.txt +3 -0
  2. data/Manifest.txt +33 -0
  3. data/README.txt +11 -0
  4. data/Rakefile +9 -8
  5. data/TODO.txt +9 -0
  6. data/homepage/Notes.txt +27 -0
  7. data/homepage/Rakefile +14 -0
  8. data/homepage/diy_example.png +0 -0
  9. data/homepage/index.erb +36 -0
  10. data/homepage/index.html +45 -0
  11. data/homepage/objects_yml.png +0 -0
  12. data/homepage/page_header.graffle +0 -0
  13. data/homepage/page_header.html +9 -0
  14. data/homepage/page_header.png +0 -0
  15. data/lib/diy.rb +40 -12
  16. data/sample_code/car.rb +7 -0
  17. data/sample_code/chassis.rb +5 -0
  18. data/sample_code/diy_example.rb +26 -0
  19. data/sample_code/engine.rb +5 -0
  20. data/sample_code/objects.yml +10 -0
  21. data/test/constructor.rb +119 -0
  22. data/test/diy_test.rb +41 -3
  23. data/test/files/functions/invalid_method.yml +5 -0
  24. data/test/files/functions/nonsingleton_objects.yml +6 -0
  25. data/test/files/functions/objects.yml +5 -0
  26. data/test/files/functions/thing.rb +3 -0
  27. data/test/files/functions/thing_builder.rb +21 -0
  28. data/test/files/namespace/animal/bird.rb +5 -0
  29. data/test/files/namespace/animal/cat.rb +5 -0
  30. data/test/files/namespace/animal/reptile/hardshell/turtle.rb +8 -0
  31. data/test/files/namespace/animal/reptile/lizard.rb +7 -0
  32. data/test/files/namespace/bad_module_specified.yml +8 -0
  33. data/test/files/namespace/class_name_combine.yml +8 -0
  34. data/test/files/namespace/hello.txt +1 -0
  35. data/test/files/namespace/no_module_specified.yml +8 -0
  36. data/test/files/namespace/objects.yml +21 -0
  37. data/test/files/namespace/road.rb +2 -0
  38. data/test/files/namespace/sky.rb +2 -0
  39. data/test/files/namespace/subcontext.yml +22 -0
  40. metadata +41 -5
@@ -1,3 +1,6 @@
1
+ == 1.1 / 2008-05-20
2
+ * Added 'method' directive for building a bounded method from an object defined in diy
3
+
1
4
  == 1.0.3 / 2007-12-11
2
5
 
3
6
  * The 1.0.1 release had a load-path search in it that resulted in requiring files with full path names (rooted in loadpath entries). This is unintuitive, and will almost always result in a double "require" if the application code ever requires a library. The "require" for library loading now relies implicitly on the load path (just like normal human-coded requires.)
@@ -2,7 +2,23 @@ History.txt
2
2
  Manifest.txt
3
3
  README.txt
4
4
  Rakefile
5
+ TODO.txt
6
+ homepage/Notes.txt
7
+ homepage/Rakefile
8
+ homepage/diy_example.png
9
+ homepage/index.erb
10
+ homepage/index.html
11
+ homepage/objects_yml.png
12
+ homepage/page_header.graffle
13
+ homepage/page_header.html
14
+ homepage/page_header.png
5
15
  lib/diy.rb
16
+ sample_code/car.rb
17
+ sample_code/chassis.rb
18
+ sample_code/diy_example.rb
19
+ sample_code/engine.rb
20
+ sample_code/objects.yml
21
+ test/constructor.rb
6
22
  test/diy_test.rb
7
23
  test/files/broken_construction.yml
8
24
  test/files/cat/cat.rb
@@ -20,6 +36,11 @@ test/files/donkey/foo.rb
20
36
  test/files/donkey/foo/bar/qux.rb
21
37
  test/files/fud/objects.yml
22
38
  test/files/fud/toy.rb
39
+ test/files/functions/invalid_method.yml
40
+ test/files/functions/nonsingleton_objects.yml
41
+ test/files/functions/objects.yml
42
+ test/files/functions/thing.rb
43
+ test/files/functions/thing_builder.rb
23
44
  test/files/gnu/objects.yml
24
45
  test/files/gnu/thinger.rb
25
46
  test/files/goat/base.rb
@@ -32,6 +53,18 @@ test/files/goat/shirt.rb
32
53
  test/files/goat/wings.rb
33
54
  test/files/horse/holder_thing.rb
34
55
  test/files/horse/objects.yml
56
+ test/files/namespace/animal/bird.rb
57
+ test/files/namespace/animal/cat.rb
58
+ test/files/namespace/animal/reptile/hardshell/turtle.rb
59
+ test/files/namespace/animal/reptile/lizard.rb
60
+ test/files/namespace/bad_module_specified.yml
61
+ test/files/namespace/class_name_combine.yml
62
+ test/files/namespace/hello.txt
63
+ test/files/namespace/no_module_specified.yml
64
+ test/files/namespace/objects.yml
65
+ test/files/namespace/road.rb
66
+ test/files/namespace/sky.rb
67
+ test/files/namespace/subcontext.yml
35
68
  test/files/non_singleton/air.rb
36
69
  test/files/non_singleton/fat_cat.rb
37
70
  test/files/non_singleton/objects.yml
data/README.txt CHANGED
@@ -182,6 +182,17 @@ a per-object override (handled in the context YAML):
182
182
  engine:
183
183
  auto_require: false
184
184
 
185
+ === Method Directive
186
+ This introduces the concept of first class methods. An object can now be constructed with a method bound to
187
+ a particular object in the diy context.
188
+
189
+ ---
190
+ trinket_builder:
191
+
192
+ method build_trinket:
193
+ object: trinket_builder
194
+ method: build
195
+
185
196
  == LICENSE:
186
197
 
187
198
  (The MIT License)
data/Rakefile CHANGED
@@ -16,13 +16,14 @@ Hoe.new('diy', DIY::VERSION) do |p|
16
16
  p.extra_deps << ['constructor', '>= 1.0.0']
17
17
  end
18
18
 
19
- load "../tools/tasks/homepage.rake"
19
+ if File.exists?("../tools/")
20
+ load "../tools/tasks/homepage.rake"
21
+ load "../tools/tasks/release_tagging.rake"
22
+ ReleaseTagging.new do |t|
23
+ t.package = "diy"
24
+ t.version = DIY::VERSION
25
+ end
20
26
 
21
- load "../tools/tasks/release_tagging.rake"
22
- ReleaseTagging.new do |t|
23
- t.package = "diy"
24
- t.version = DIY::VERSION
27
+ desc "Release package to Rubyforge, tag the release in svn, and publish documentation"
28
+ task :release_full => [ :release, :tag_release, :publish_docs ]
25
29
  end
26
-
27
- desc "Release package to Rubyforge, tag the release in svn, and publish documentation"
28
- task :release_full => [ :release, :tag_release, :publish_docs ]
@@ -0,0 +1,9 @@
1
+ Sun Dec 2 19:59:16 EST 2007
2
+ crosby
3
+
4
+ Features from FRE's rogue diy.rb (inside Injection) that need to be
5
+ incorporated into trunk:
6
+
7
+ * auto_require
8
+ * use_class_directly
9
+
@@ -0,0 +1,27 @@
1
+ Wed Nov 21 21:49:27 EST 2007
2
+ crosby
3
+
4
+ 1. Edit page_header.graffle
5
+ 2. Export as HTML imagemap
6
+ 3. Open ../sample_code/synopsis.rb
7
+ 4. Screen shot, save as sample_code.png
8
+ 5. rake (rewrites index.html)
9
+ 6. cd ..
10
+ 7. rake publish_docs
11
+
12
+ page_header.graffle
13
+ Export-as-HTML-Imagemap
14
+ Use png
15
+ Use 125% scale
16
+ Remember to use the style inspector to assign actions to things that should be links.
17
+
18
+ rake index
19
+ Rewrites index.html using index.erb and page_header.html (and some values in the Rakefile)
20
+
21
+ The code sample screenshot:
22
+ Taken with Snapz Pro X (this is important, as Snapz is providing the
23
+ dropshadow and about 28 extra pixels widthwise)
24
+
25
+ Should be 650 px wide to line up with the page header.
26
+
27
+ Transparency: be conscious of WHAT'S IN THE BACKGROUND
@@ -0,0 +1,14 @@
1
+ desc "Rewrite index.html using index.erb and publisher_homepage.html"
2
+ task :index do
3
+ require 'erb'
4
+ @title = "DIY - atomicobject.rb"
5
+ @header_html = File.read("page_header.html")
6
+ html = ERB.new(File.read("index.erb")).result(binding)
7
+ fname = "index.html"
8
+ File.open(fname,"w") do |f|
9
+ f.print html
10
+ end
11
+ puts "Wrote #{fname}"
12
+ end
13
+
14
+ task :default => :index
Binary file
@@ -0,0 +1,36 @@
1
+ <html>
2
+ <head>
3
+ <title><%= @title %></title>
4
+ <style>
5
+ .code_sample_title {
6
+ border-top: 1px solid grey;
7
+ width: 625px;
8
+ font: bold 12pt Trebuchet MS;
9
+ text-align:left;
10
+ margin: 5px;
11
+ padding-top: 5px;
12
+ }
13
+ </style>
14
+ </head>
15
+
16
+ <body>
17
+
18
+ <div align="center">
19
+
20
+ <%= @header_html %>
21
+
22
+ <div class="code_sample_title">
23
+ objects.yml:
24
+ </div>
25
+ <a href="rdoc/index.html"><img border="0" src="objects_yml.png"></a>
26
+
27
+ <div class="code_sample_title">
28
+ diy_example.rb:
29
+ </div>
30
+ <a href="rdoc/index.html"><img border="0" src="diy_example.png"></a>
31
+ </div>
32
+
33
+
34
+
35
+ </body>
36
+ </html>
@@ -0,0 +1,45 @@
1
+ <html>
2
+ <head>
3
+ <title>DIY - atomicobject.rb</title>
4
+ <style>
5
+ .code_sample_title {
6
+ border-top: 1px solid grey;
7
+ width: 625px;
8
+ font: bold 12pt Trebuchet MS;
9
+ text-align:left;
10
+ margin: 5px;
11
+ padding-top: 5px;
12
+ }
13
+ </style>
14
+ </head>
15
+
16
+ <body>
17
+
18
+ <div align="center">
19
+
20
+ <map name="GraffleExport">
21
+ <area shape=rect coords="486,91,635,108" href="http://atomicobjectrb.rubyforge.org/">
22
+ <area shape=rect coords="485,120,635,187" href="rdoc/index.html">
23
+ <area shape=rect coords="310,120,463,187" href="http://rubyforge.org/frs/?group_id=4897&release_id=16546">
24
+ <area shape=rect coords="14,91,206,108" href="http://atomicobject.com">
25
+ <area shape=rect coords="572,16,627,71" href="http://atomicobjectrb.rubyforge.org/">
26
+ <area shape=rect coords="21,13,83,75" href="http://atomicobject.com">
27
+ </map>
28
+ <img border=0 src="page_header.png" usemap="#GraffleExport">
29
+
30
+
31
+ <div class="code_sample_title">
32
+ objects.yml:
33
+ </div>
34
+ <a href="rdoc/index.html"><img border="0" src="objects_yml.png"></a>
35
+
36
+ <div class="code_sample_title">
37
+ diy_example.rb:
38
+ </div>
39
+ <a href="rdoc/index.html"><img border="0" src="diy_example.png"></a>
40
+ </div>
41
+
42
+
43
+
44
+ </body>
45
+ </html>
Binary file
@@ -0,0 +1,9 @@
1
+ <map name="GraffleExport">
2
+ <area shape=rect coords="486,91,635,108" href="http://atomicobjectrb.rubyforge.org/">
3
+ <area shape=rect coords="485,120,635,187" href="rdoc/index.html">
4
+ <area shape=rect coords="310,120,463,187" href="http://rubyforge.org/frs/?group_id=4897&release_id=16546">
5
+ <area shape=rect coords="14,91,206,108" href="http://atomicobject.com">
6
+ <area shape=rect coords="572,16,627,71" href="http://atomicobjectrb.rubyforge.org/">
7
+ <area shape=rect coords="21,13,83,75" href="http://atomicobject.com">
8
+ </map>
9
+ <img border=0 src="page_header.png" usemap="#GraffleExport">
Binary file
data/lib/diy.rb CHANGED
@@ -2,7 +2,7 @@ require 'yaml'
2
2
  require 'set'
3
3
 
4
4
  module DIY #:nodoc:#
5
- VERSION = '1.0.3'
5
+ VERSION = '1.1'
6
6
  class Context
7
7
 
8
8
  class << self
@@ -24,7 +24,7 @@ module DIY #:nodoc:#
24
24
 
25
25
  # store extra inputs
26
26
  if extra_inputs.kind_of?(Hash)
27
- @extra_inputs = {}
27
+ @extra_inputs= {}
28
28
  extra_inputs.each { |k,v| @extra_inputs[k.to_s] = v } # smooth out the names
29
29
  else
30
30
  @extra_inputs = extra_inputs
@@ -62,8 +62,13 @@ module DIY #:nodoc:#
62
62
  end
63
63
  end
64
64
  unless obj
65
- obj = construct_object(key)
66
- @cache[key] = obj if @defs[key].singleton?
65
+ case @defs[key]
66
+ when MethodDef
67
+ @cache[key] = construct_method(key)
68
+ else
69
+ obj = construct_object(key)
70
+ @cache[key] = obj if @defs[key].singleton?
71
+ end
67
72
  end
68
73
  obj
69
74
  end
@@ -130,7 +135,11 @@ module DIY #:nodoc:#
130
135
  # namespace: use a module(s) prefix for the classname of contained object defs
131
136
  # NOTE: namespacing is NOT scope... it's just a convenient way to setup class names for a group of objects.
132
137
  get_defs_from info, parse_namespace(name)
133
-
138
+ when /^method/
139
+ key_name = name.gsub(/^method\s/, "")
140
+ @defs[key_name] = MethodDef.new(:name => key_name,
141
+ :object => info['object'],
142
+ :method => info['method'])
134
143
  else
135
144
  # Normal object def
136
145
  info ||= {}
@@ -154,14 +163,21 @@ module DIY #:nodoc:#
154
163
  end
155
164
  end
156
165
 
157
-
166
+
167
+ def construct_method(key)
168
+ method_definition = @defs[key]
169
+ object = get_object(method_definition.object)
170
+ return object.method(method_definition.method)
171
+ rescue Exception => oops
172
+ build_and_raise_construction_error(key, oops)
173
+ end
174
+
158
175
  def construct_object(key)
159
176
  # Find the object definition
160
177
  obj_def = @defs[key]
161
178
  raise "No object definition for '#{key}'" unless obj_def
162
-
163
179
  # If object def mentions a library, load it
164
- require obj_def.library if obj_def.library
180
+ require obj_def.library if obj_def.library
165
181
 
166
182
  # Resolve all components for the object
167
183
  arg_hash = {}
@@ -186,11 +202,15 @@ module DIY #:nodoc:#
186
202
  return big_c.new
187
203
  end
188
204
  rescue Exception => oops
189
- cerr = ConstructionError.new(key,oops)
205
+ build_and_raise_construction_error(key, oops)
206
+ end
207
+
208
+ def build_and_raise_construction_error(key, oops)
209
+ cerr = ConstructionError.new(key,oops)
190
210
  cerr.set_backtrace(oops.backtrace)
191
211
  raise cerr
192
212
  end
193
-
213
+
194
214
  def get_class_for_name_with_module_delimeters(class_name)
195
215
  class_name.split(/::/).inject(Object) do |mod,const_name| mod.const_get(const_name) end
196
216
  end
@@ -206,7 +226,7 @@ module DIY #:nodoc:#
206
226
  Namespace.new(str)
207
227
  end
208
228
  end
209
-
229
+
210
230
  class Namespace #:nodoc:#
211
231
  def initialize(str)
212
232
  # 'using_namespace Animal Reptile'
@@ -234,7 +254,15 @@ module DIY #:nodoc:#
234
254
  @name = obj_name
235
255
  end
236
256
  end
237
-
257
+
258
+ class MethodDef
259
+ attr_accessor :name, :object, :method
260
+
261
+ def initialize(opts)
262
+ @name, @object, @method = opts[:name], opts[:object], opts[:method]
263
+ end
264
+ end
265
+
238
266
  class ObjectDef #:nodoc:
239
267
  attr_accessor :name, :class_name, :library, :components
240
268
  def initialize(opts)
@@ -0,0 +1,7 @@
1
+ class Car
2
+ attr_reader :engine, :chassis
3
+ def initialize(arg_hash)
4
+ @engine = arg_hash[:engine]
5
+ @chassis = arg_hash[:chassis]
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class Chassis
2
+ def to_s
3
+ "Chassis"
4
+ end
5
+ end
@@ -0,0 +1,26 @@
1
+ require "rubygems"
2
+ require "diy"
3
+
4
+ class Car
5
+ attr_reader :engine, :chassis
6
+ def initialize(arg_hash)
7
+ @engine = arg_hash[:engine]
8
+ @chassis = arg_hash[:chassis]
9
+ end
10
+ end
11
+
12
+ class Chassis
13
+ def to_s
14
+ "Chassis"
15
+ end
16
+ end
17
+
18
+ class Engine
19
+ def to_s
20
+ "Engine"
21
+ end
22
+ end
23
+
24
+ context = DIY::Context.from_file("objects.yml")
25
+ car = context['car']
26
+ puts "Car is made of: #{car.engine} and #{car.chassis}"
@@ -0,0 +1,5 @@
1
+ class Engine
2
+ def to_s
3
+ "Engine"
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ ---
2
+ car:
3
+ compose:
4
+ - engine
5
+ - chassis
6
+
7
+ engine:
8
+
9
+ chassis:
10
+
@@ -0,0 +1,119 @@
1
+ CONSTRUCTOR_VERSION = '1.0.2' #:nodoc:#
2
+
3
+ class Class #:nodoc:#
4
+ def constructor(*attrs, &block)
5
+ call_block = ''
6
+ if block_given?
7
+ @constructor_block = block
8
+ call_block = 'self.instance_eval(&self.class.constructor_block)'
9
+ end
10
+ # Look for embedded options in the listing:
11
+ opts = attrs.find { |a| a.kind_of?(Hash) and attrs.delete(a) }
12
+ do_acc = opts.nil? ? false : opts[:accessors] == true
13
+ require_args = opts.nil? ? true : opts[:strict] != false
14
+ super_args = opts.nil? ? nil : opts[:super]
15
+
16
+ # Incorporate superclass's constructor keys, if our superclass
17
+ if superclass.constructor_keys
18
+ similar_keys = superclass.constructor_keys & attrs
19
+ raise "Base class already has keys #{similar_keys.inspect}" unless similar_keys.empty?
20
+ attrs = [attrs,superclass.constructor_keys].flatten
21
+ end
22
+ # Generate ivar assigner code lines
23
+ assigns = ''
24
+ attrs.each do |k|
25
+ assigns += "@#{k.to_s} = args[:#{k.to_s}]\n"
26
+ end
27
+
28
+ # If accessors option is on, declare accessors for the attributes:
29
+ if do_acc
30
+ self.class_eval "attr_accessor " + attrs.map {|x| ":#{x.to_s}"}.join(',')
31
+ end
32
+
33
+ # If user supplied super-constructor hints:
34
+ super_call = ''
35
+ if super_args
36
+ list = super_args.map do |a|
37
+ case a
38
+ when String
39
+ %|"#{a}"|
40
+ when Symbol
41
+ %|:#{a}|
42
+ end
43
+ end
44
+ super_call = %|super(#{list.join(',')})|
45
+ end
46
+
47
+ # If strict is on, define the constructor argument validator method,
48
+ # and setup the initializer to invoke the validator method.
49
+ # Otherwise, insert lax code into the initializer.
50
+ validation_code = "return if args.nil?"
51
+ if require_args
52
+ self.class_eval do
53
+ def _validate_constructor_args(args)
54
+ # First, make sure we've got args of some kind
55
+ unless args and args.keys and args.keys.size > 0
56
+ raise ConstructorArgumentError.new(self.class.constructor_keys)
57
+ end
58
+ # Scan for missing keys in the argument hash
59
+ a_keys = args.keys
60
+ missing = []
61
+ self.class.constructor_keys.each do |ck|
62
+ unless a_keys.member?(ck)
63
+ missing << ck
64
+ end
65
+ a_keys.delete(ck) # Delete inbound keys as we address them
66
+ end
67
+ if missing.size > 0 || a_keys.size > 0
68
+ raise ConstructorArgumentError.new(missing,a_keys)
69
+ end
70
+ end
71
+ end
72
+ # Setup the code to insert into the initializer:
73
+ validation_code = "_validate_constructor_args args "
74
+ end
75
+
76
+ # Generate the initializer code
77
+ self.class_eval %{
78
+ def initialize(args=nil)
79
+ #{super_call}
80
+ #{validation_code}
81
+ #{assigns}
82
+ setup if respond_to?(:setup)
83
+ #{call_block}
84
+ end
85
+ }
86
+
87
+ # Remember our constructor keys
88
+ @_ctor_keys = attrs
89
+ end
90
+
91
+ # Access the constructor keys for this class
92
+ def constructor_keys; @_ctor_keys ||=[]; end
93
+
94
+ def constructor_block #:nodoc:#
95
+ @constructor_block
96
+ end
97
+
98
+ end
99
+
100
+ # Fancy validation exception, based on missing and extraneous keys.
101
+ class ConstructorArgumentError < RuntimeError #:nodoc:#
102
+ def initialize(missing,rejected=[])
103
+ err_msg = ''
104
+ if missing.size > 0
105
+ err_msg = "Missing constructor args [#{missing.join(',')}]"
106
+ end
107
+ if rejected.size > 0
108
+ # Some inbound keys were not addressed earlier; this means they're unwanted
109
+ if err_msg
110
+ err_msg << "; " # Appending to earlier message about missing items
111
+ else
112
+ err_msg = ''
113
+ end
114
+ # Enumerate the rejected key names
115
+ err_msg << "Rejected constructor args [#{rejected.join(',')}]"
116
+ end
117
+ super err_msg
118
+ end
119
+ end
@@ -7,7 +7,7 @@ class DIYTest < Test::Unit::TestCase
7
7
 
8
8
  def setup
9
9
  # Add load paths:
10
- %w|gnu dog cat yak donkey goat horse fud non_singleton namespace|.each do |p|
10
+ %w|gnu dog cat yak donkey goat horse fud non_singleton namespace functions|.each do |p|
11
11
  libdir = path_to_test_file(p)
12
12
  $: << libdir unless $:.member?(libdir)
13
13
  end
@@ -74,7 +74,7 @@ class DIYTest < Test::Unit::TestCase
74
74
  @diy.build_everything
75
75
  assert_not_nil @diy['foo/bar/qux'], "Should have got my qux (which is hiding in a couple modules)"
76
76
  end
77
-
77
+
78
78
  def test_keys
79
79
  load_context "dog/simple.yml"
80
80
  assert_equal %w|dog_model dog_presenter dog_view file_resolver other_thing|, @diy.keys.sort
@@ -492,7 +492,7 @@ class DIYTest < Test::Unit::TestCase
492
492
  assert_same sky, bird.sky, "Bird has wrong Sky"
493
493
  assert_same bird, lizard.bird, "Lizard has wrong Bird"
494
494
  end
495
-
495
+
496
496
  def test_should_combine_a_given_class_name_with_the_namespace
497
497
  load_context "namespace/class_name_combine.yml"
498
498
  assert_not_nil @diy['garfield'], "No garfield"
@@ -533,6 +533,44 @@ class DIYTest < Test::Unit::TestCase
533
533
  assert_match(/no such file to load -- fuzzy_creature\/bird/, ex.message)
534
534
  end
535
535
 
536
+ def test_should_be_able_define_and_access_bounded_methods
537
+ load_context "functions/objects.yml"
538
+ @diy.build_everything
539
+ build_thing = @diy['build_thing']
540
+
541
+ assert_not_nil build_thing, "should not be nil"
542
+ assert_kind_of(Method, build_thing)
543
+ assert_same(build_thing, @diy['build_thing'])
544
+ end
545
+
546
+ def test_bounded_method_can_be_used
547
+ load_context "functions/objects.yml"
548
+ @diy.build_everything
549
+ build_thing = @diy['build_thing']
550
+
551
+ thing = build_thing["the name", "flying"]
552
+
553
+ assert_equal("the name", thing.name)
554
+ assert_equal("flying", thing.ability)
555
+ end
556
+
557
+ def test_building_bounded_method_uses_object_in_diy_context_correctly
558
+ load_context "functions/objects.yml"
559
+ @diy.build_everything
560
+ assert_equal(@diy['build_thing'], @diy['thing_builder'].method(:build))
561
+
562
+ load_context "functions/nonsingleton_objects.yml"
563
+ @diy.build_everything
564
+ assert_not_equal(@diy['build_thing'], @diy['thing_builder'].method(:build))
565
+ end
566
+
567
+ def test_raises_construction_error_if_invalid_method_specified
568
+ load_context "functions/invalid_method.yml"
569
+ assert_raises DIY::ConstructionError do
570
+ @diy.build_everything
571
+ end
572
+ end
573
+
536
574
  #
537
575
  # HELPERS
538
576
  #
@@ -0,0 +1,5 @@
1
+ thing_builder:
2
+
3
+ method build_thing:
4
+ object: thing_builder
5
+ method: no_exist
@@ -0,0 +1,6 @@
1
+ thing_builder:
2
+ singleton: false
3
+
4
+ method build_thing:
5
+ object: thing_builder
6
+ method: build
@@ -0,0 +1,5 @@
1
+ thing_builder:
2
+
3
+ method build_thing:
4
+ object: thing_builder
5
+ method: build
@@ -0,0 +1,3 @@
1
+ class Thing
2
+ constructor :name, :ability, :accessors => true
3
+ end
@@ -0,0 +1,21 @@
1
+ require 'thing'
2
+
3
+ class ThingBuilder
4
+ @@builder_count = 0
5
+
6
+ def self.reset_builder_count
7
+ @@builder_count = 0
8
+ end
9
+
10
+ def self.builder_count
11
+ @@builder_count
12
+ end
13
+
14
+ def initialize
15
+ @@builder_count += 1
16
+ end
17
+
18
+ def build(name, ability)
19
+ Thing.new(:name => name, :ability => ability)
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ module Animal
2
+ class Bird
3
+ constructor :sky, :accessors => true
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Animal
2
+ class Cat
3
+ constructor :road, :accessors => true
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ module Animal
2
+ module Reptile
3
+ module Hardshell
4
+ class Turtle
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ module Animal
2
+ module Reptile
3
+ class Lizard
4
+ constructor :bird, :accessors => true
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+
2
+ sky:
3
+
4
+ using_namespace FuzzyCreature:
5
+
6
+ bird:
7
+ compose: sky
8
+
@@ -0,0 +1,8 @@
1
+ road:
2
+
3
+ using_namespace Animal:
4
+
5
+ garfield:
6
+ class: Cat
7
+ compose: road
8
+
@@ -0,0 +1 @@
1
+ this is the info
@@ -0,0 +1,8 @@
1
+
2
+ sky:
3
+
4
+ using_namespace:
5
+
6
+ bird:
7
+ compose: sky
8
+
@@ -0,0 +1,21 @@
1
+ road:
2
+
3
+ sky:
4
+
5
+ using_namespace Animal:
6
+
7
+ cat:
8
+ compose: road
9
+
10
+ bird:
11
+ compose: sky
12
+
13
+ using_namespace Animal Reptile:
14
+
15
+ lizard:
16
+ compose: bird
17
+
18
+ using_namespace Animal::Reptile::Hardshell:
19
+
20
+ turtle:
21
+
@@ -0,0 +1,2 @@
1
+ class Road
2
+ end
@@ -0,0 +1,2 @@
1
+ class Sky
2
+ end
@@ -0,0 +1,22 @@
1
+ road:
2
+
3
+ sky:
4
+
5
+ using_namespace Animal:
6
+
7
+ cat:
8
+ compose: road
9
+
10
+
11
+ +aviary:
12
+ using_namespace Animal:
13
+ bird:
14
+ compose: sky
15
+
16
+ using_namespace Animal Reptile:
17
+ lizard:
18
+ compose: bird
19
+
20
+ using_namespace Animal::Reptile::Hardshell:
21
+ turtle:
22
+
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
5
- platform: ""
4
+ version: "1.1"
5
+ platform: ruby
6
6
  authors:
7
7
  - Atomic Object
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2007-12-11 00:00:00 -05:00
12
+ date: 2008-05-20 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -28,7 +28,7 @@ dependencies:
28
28
  requirements:
29
29
  - - ">="
30
30
  - !ruby/object:Gem::Version
31
- version: 1.3.0
31
+ version: 1.5.1
32
32
  version:
33
33
  description: "== DESCRIPTION: DIY (Dependency Injection in YAML) is a simple dependency injection library which focuses on declarative composition of objects through constructor injection. == INSTALL: * gem install diy"
34
34
  email: dev@atomicobject.com
@@ -40,12 +40,31 @@ extra_rdoc_files:
40
40
  - History.txt
41
41
  - Manifest.txt
42
42
  - README.txt
43
+ - TODO.txt
44
+ - homepage/Notes.txt
45
+ - test/files/namespace/hello.txt
43
46
  files:
44
47
  - History.txt
45
48
  - Manifest.txt
46
49
  - README.txt
47
50
  - Rakefile
51
+ - TODO.txt
52
+ - homepage/Notes.txt
53
+ - homepage/Rakefile
54
+ - homepage/diy_example.png
55
+ - homepage/index.erb
56
+ - homepage/index.html
57
+ - homepage/objects_yml.png
58
+ - homepage/page_header.graffle
59
+ - homepage/page_header.html
60
+ - homepage/page_header.png
48
61
  - lib/diy.rb
62
+ - sample_code/car.rb
63
+ - sample_code/chassis.rb
64
+ - sample_code/diy_example.rb
65
+ - sample_code/engine.rb
66
+ - sample_code/objects.yml
67
+ - test/constructor.rb
49
68
  - test/diy_test.rb
50
69
  - test/files/broken_construction.yml
51
70
  - test/files/cat/cat.rb
@@ -63,6 +82,11 @@ files:
63
82
  - test/files/donkey/foo/bar/qux.rb
64
83
  - test/files/fud/objects.yml
65
84
  - test/files/fud/toy.rb
85
+ - test/files/functions/invalid_method.yml
86
+ - test/files/functions/nonsingleton_objects.yml
87
+ - test/files/functions/objects.yml
88
+ - test/files/functions/thing.rb
89
+ - test/files/functions/thing_builder.rb
66
90
  - test/files/gnu/objects.yml
67
91
  - test/files/gnu/thinger.rb
68
92
  - test/files/goat/base.rb
@@ -75,6 +99,18 @@ files:
75
99
  - test/files/goat/wings.rb
76
100
  - test/files/horse/holder_thing.rb
77
101
  - test/files/horse/objects.yml
102
+ - test/files/namespace/animal/bird.rb
103
+ - test/files/namespace/animal/cat.rb
104
+ - test/files/namespace/animal/reptile/hardshell/turtle.rb
105
+ - test/files/namespace/animal/reptile/lizard.rb
106
+ - test/files/namespace/bad_module_specified.yml
107
+ - test/files/namespace/class_name_combine.yml
108
+ - test/files/namespace/hello.txt
109
+ - test/files/namespace/no_module_specified.yml
110
+ - test/files/namespace/objects.yml
111
+ - test/files/namespace/road.rb
112
+ - test/files/namespace/sky.rb
113
+ - test/files/namespace/subcontext.yml
78
114
  - test/files/non_singleton/air.rb
79
115
  - test/files/non_singleton/fat_cat.rb
80
116
  - test/files/non_singleton/objects.yml
@@ -117,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
153
  requirements: []
118
154
 
119
155
  rubyforge_project: atomicobjectrb
120
- rubygems_version: 0.9.5
156
+ rubygems_version: 1.1.1
121
157
  signing_key:
122
158
  specification_version: 2
123
159
  summary: Constructor-based dependency injection container using YAML input.