diy 1.0.3 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
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.