needle 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/doc/LICENSE-BSD +27 -0
  2. data/doc/LICENSE-GPL +280 -0
  3. data/doc/LICENSE-RUBY +56 -0
  4. data/doc/README +70 -0
  5. data/doc/manual/chapter.erb +18 -0
  6. data/doc/manual/index.erb +29 -0
  7. data/doc/manual/manual.css +192 -0
  8. data/doc/manual/manual.rb +240 -0
  9. data/doc/manual/manual.yml +48 -0
  10. data/doc/manual/page.erb +86 -0
  11. data/doc/manual/parts/01_license.txt +5 -0
  12. data/doc/manual/parts/01_support.txt +1 -0
  13. data/doc/manual/parts/01_use_cases.txt +141 -0
  14. data/doc/manual/parts/01_what_is_needle.txt +1 -0
  15. data/doc/manual/parts/02_creating.txt +9 -0
  16. data/doc/manual/parts/02_namespaces.txt +47 -0
  17. data/doc/manual/parts/02_overview.txt +3 -0
  18. data/doc/manual/parts/02_services.txt +44 -0
  19. data/doc/manual/tutorial.erb +30 -0
  20. data/doc/manual-html/chapter-1.html +354 -0
  21. data/doc/manual-html/chapter-2.html +310 -0
  22. data/doc/manual-html/chapter-3.html +154 -0
  23. data/doc/manual-html/chapter-4.html +154 -0
  24. data/doc/manual-html/chapter-5.html +154 -0
  25. data/doc/manual-html/chapter-6.html +154 -0
  26. data/doc/manual-html/chapter-7.html +154 -0
  27. data/doc/manual-html/index.html +177 -0
  28. data/doc/manual-html/manual.css +192 -0
  29. data/lib/needle/container.rb +318 -0
  30. data/lib/needle/errors.rb +32 -0
  31. data/lib/needle/include-exclude.rb +116 -0
  32. data/lib/needle/interceptor-chain.rb +162 -0
  33. data/lib/needle/interceptor.rb +189 -0
  34. data/lib/needle/log-factory.rb +207 -0
  35. data/lib/needle/logger.rb +161 -0
  36. data/lib/needle/logging-interceptor.rb +62 -0
  37. data/lib/needle/models/prototype-deferred.rb +41 -0
  38. data/lib/needle/models/prototype.rb +39 -0
  39. data/lib/needle/models/proxy.rb +84 -0
  40. data/lib/needle/models/singleton-deferred.rb +57 -0
  41. data/lib/needle/models/singleton.rb +56 -0
  42. data/lib/needle/models.rb +44 -0
  43. data/lib/needle/registry.rb +110 -0
  44. data/lib/needle/service-point.rb +109 -0
  45. data/lib/needle/version.rb +28 -0
  46. data/lib/needle.rb +54 -0
  47. data/test/ALL-TESTS.rb +21 -0
  48. data/test/models/tc_prototype.rb +53 -0
  49. data/test/models/tc_prototype_deferred.rb +54 -0
  50. data/test/models/tc_proxy.rb +51 -0
  51. data/test/models/tc_singleton.rb +53 -0
  52. data/test/models/tc_singleton_deferred.rb +54 -0
  53. data/test/tc_container.rb +246 -0
  54. data/test/tc_interceptor.rb +92 -0
  55. data/test/tc_interceptor_chain.rb +181 -0
  56. data/test/tc_logger.rb +181 -0
  57. data/test/tc_models.rb +44 -0
  58. data/test/tc_registry.rb +34 -0
  59. data/test/tc_service_point.rb +100 -0
  60. metadata +107 -0
@@ -0,0 +1,84 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Needle dependency injection
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Needle
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # needle website : http://needle.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/needle
14
+ # =============================================================================
15
+ #++
16
+
17
+ require 'thread'
18
+
19
+ module Needle
20
+ module Models
21
+
22
+ # A proxy class to aid in deferred instantiation of service points. This is
23
+ # used primarily by the "deferred" service models.
24
+ class Proxy
25
+
26
+ # Create a new proxy that wraps the given service point.
27
+ def initialize( container, &callback )
28
+ @container = container
29
+ @callback = callback
30
+ @mutex = Mutex.new
31
+ @instantiation_failed = false
32
+ @instance = nil
33
+ end
34
+
35
+ # Attempts to invoke the given message on the service. If the service has
36
+ # not yet been instantiated, it will be instantiated and stored.
37
+ def method_missing( sym, *args, &block )
38
+ unless @instance || @instantiation_failed
39
+ @mutex.synchronize do
40
+ unless @instance || @instantiation_failed
41
+ begin
42
+ @instance = @callback.call( @container )
43
+ rescue Exception
44
+ @instantiation_failed = true
45
+ raise
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ unless @instantiation_failed
52
+ @instance.__send__ sym, *args, &block
53
+ else
54
+ # just return nil... this way, a failed instantiation won't barf
55
+ # more than once... I hope...
56
+ end
57
+ end
58
+
59
+ # Override some "standard" methods so that they are routed to the
60
+ # service instead of to the proxy.
61
+ [ "is_a?", "respond_to?", "to_s", "to_str",
62
+ "to_i", "to_int", "to_io", "===", "==", "=~",
63
+ "send" ].each do |method|
64
+ #begin
65
+ class_eval <<-EOF
66
+ def #{method}( *args, &block )
67
+ unless @instantiation_failed
68
+ method_missing '#{method}', *args, &block
69
+ else
70
+ super
71
+ end
72
+ end
73
+ EOF
74
+ end
75
+
76
+ def inspect
77
+ "#<#{self.class.name}:#{"0x%08x"%self.id}:" +
78
+ "instantiated=>#{@instance ? true : false}>"
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1,57 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Needle dependency injection
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Needle
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # needle website : http://needle.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/needle
14
+ # =============================================================================
15
+ #++
16
+
17
+ require 'needle/models/proxy'
18
+ require 'thread'
19
+
20
+ module Needle
21
+ module Models
22
+
23
+ # The definition of the "singleton-deferred" lifecycle service model.
24
+ # This will result in deferred instantiation of the requested service,
25
+ # with a new instance being returned the first time #instance is invoked,
26
+ # and that same instance returned every time thereafter.
27
+ #
28
+ # This model is thread-safe.
29
+ class SingletonDeferred
30
+
31
+ # Create a new SingletonDeferred service model.
32
+ def initialize( container, opts={}, &callback )
33
+ @container = container
34
+ @callback = callback
35
+ @mutex = Mutex.new
36
+ @instance = nil
37
+ end
38
+
39
+ # Return the cached instance, if it exists. Otherwise, create new
40
+ # Proxy instance that wraps the container and callback references of
41
+ # this service model, and cache it. Then return that instance.
42
+ #
43
+ # This method is thread-safe.
44
+ def instance
45
+ return @instance if @instance
46
+
47
+ @mutex.synchronize do
48
+ return @instance if @instance
49
+ @instance = Proxy.new( @container, &@callback )
50
+ end
51
+
52
+ return @instance
53
+ end
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,56 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Needle dependency injection
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Needle
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # needle website : http://needle.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/needle
14
+ # =============================================================================
15
+ #++
16
+
17
+ require 'thread'
18
+
19
+ module Needle
20
+ module Models
21
+
22
+ # The definition of the "singleton" lifecycle service model. This will
23
+ # result in immediate instantiation of the requested service, with a new
24
+ # instance being returned the first time #instance is invoked, and that
25
+ # same instance returned every time thereafter.
26
+ #
27
+ # This model is thread-safe.
28
+ class Singleton
29
+
30
+ # Create a new instance of the singleton service model.
31
+ def initialize( container, opts={}, &callback )
32
+ @container = container
33
+ @callback = callback
34
+ @mutex = Mutex.new
35
+ @instance = nil
36
+ end
37
+
38
+ # Return the cached instance, if it exists. Otherwise, create new
39
+ # instance by invoking the registered callback, caching the result.
40
+ # Then return that instance.
41
+ #
42
+ # This method is thread-safe.
43
+ def instance
44
+ return @instance if @instance
45
+
46
+ @mutex.synchronize do
47
+ return @instance if @instance
48
+ @instance = @callback.call( @container )
49
+ end
50
+
51
+ return @instance
52
+ end
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,44 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Needle dependency injection
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Needle
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # needle website : http://needle.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/needle
14
+ # =============================================================================
15
+ #++
16
+
17
+ require 'needle/models/prototype'
18
+ require 'needle/models/prototype-deferred'
19
+ require 'needle/models/singleton'
20
+ require 'needle/models/singleton-deferred'
21
+
22
+ module Needle
23
+ module Models
24
+
25
+ # A convenience method for registering all standard service models with
26
+ # a container. This also defines a <tt>:service_models</tt> service,
27
+ # implemented as a Hash, which is used for keeping the references to
28
+ # installed service models.
29
+ #
30
+ # This method is called internally by Registry when it is instantiated,
31
+ # and should never be called directly.
32
+ def register( registry )
33
+ registry.register( :service_models, :model => Singleton ) { Hash.new }
34
+ registry[:service_models].update(
35
+ :singleton => Singleton,
36
+ :singleton_deferred => SingletonDeferred,
37
+ :prototype => Prototype,
38
+ :prototype_deferred => PrototypeDeferred
39
+ )
40
+ end
41
+ module_function :register
42
+
43
+ end
44
+ end
@@ -0,0 +1,110 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Needle dependency injection
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Needle
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # needle website : http://needle.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/needle
14
+ # =============================================================================
15
+ #++
16
+
17
+ require 'needle/container'
18
+ require 'needle/errors'
19
+ require 'needle/log-factory'
20
+ require 'needle/logging-interceptor'
21
+ require 'needle/models'
22
+
23
+ module Needle
24
+
25
+ # Registry is a specialization of Container, with additional functionality
26
+ # for bootstrapping basic services into a new registry. It also supports a
27
+ # #new! method for easily registering new services.
28
+ #
29
+ # Usage:
30
+ #
31
+ # require 'needle'
32
+ #
33
+ # registry = Needle::Registry.new
34
+ # registry.register( :foo ) { Foo.new }
35
+ # registry.register( :bar ) { |c| Bar.new( c.foo ) }
36
+ #
37
+ # bar = registry.bar
38
+ class Registry < Container
39
+
40
+ # This is the default name given to a registry. If you have multiple
41
+ # independent registries in the same application, it can help to given them
42
+ # each names. By default, the name is empty.
43
+ DEFAULT_REGISTRY_NAME = ""
44
+
45
+ # Instantiate a new Registry (via #new) and immediately invoke #register!
46
+ # using the given block.
47
+ #
48
+ # Usage:
49
+ #
50
+ # registry = Needle::Registry.new! do
51
+ # add { Adder.new }
52
+ # ...
53
+ # end
54
+ #
55
+ # adder = registry.add
56
+ def self.new!( *parms, &block )
57
+ raise NeedleError, "needs a block" if block.nil?
58
+ new( *parms ) { |reg| reg.register!( &block ) }
59
+ end
60
+
61
+ # Instantiate a new Registry. If the first parameter is a string, it will
62
+ # be used as the name of this registry. If the next parameter is a Hash,
63
+ # it will be used as the options to use when bootstrapping the registry.
64
+ # (This includes options used to initialize the logger factory.
65
+ #
66
+ # If a block is given, the constructed registry instance is yielded to it.
67
+ #
68
+ # Usage:
69
+ #
70
+ # registry = Needle::Registry.new
71
+ #
72
+ # or
73
+ #
74
+ # registry = Needle::Registry.new do |reg|
75
+ # reg.register( :add ) { Adder.new }
76
+ # end
77
+ def initialize( *parms )
78
+ raise ArgumentError, "expected <= 2 arguments" if parms.length > 2
79
+ name = ( parms.first.is_a?( String ) ? parms.shift :
80
+ DEFAULT_REGISTRY_NAME )
81
+ opts = ( parms.first.is_a?( Hash ) ? parms.shift : {} )
82
+
83
+ if parms.length > 0
84
+ raise ArgumentError, "invalid parameter(s): #{parms.inspect}"
85
+ end
86
+
87
+ super( nil, name )
88
+ bootstrap( opts )
89
+
90
+ yield( self ) if block_given?
91
+ end
92
+
93
+ # Return the name of this registry, enclosed in square braces.
94
+ def fullname
95
+ "[#{super}]"
96
+ end
97
+
98
+ # Bootstraps the service models, logger factory, and logging interceptor
99
+ # services into the current registry. This is only called when a new
100
+ # registry is created.
101
+ def bootstrap( opts )
102
+ Models.register( self )
103
+ register( :logs ) { LogFactory.new( opts[:logs] || {} ) }
104
+ register( :logging_interceptor ) { LoggingInterceptor }
105
+ end
106
+ private :bootstrap
107
+
108
+ end
109
+
110
+ end
@@ -0,0 +1,109 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Needle dependency injection
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Needle
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # needle website : http://needle.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/needle
14
+ # =============================================================================
15
+ #++
16
+
17
+ require 'needle/interceptor-chain'
18
+
19
+ module Needle
20
+
21
+ # A "service point" is a definition of a service. Just as a class defines the
22
+ # behavior of an object, so does a service point describes a service. In
23
+ # particular, a service point also knows how to instantiate a service.
24
+ #
25
+ # A ServicePoint should never be directly instantiated. Instead, define
26
+ # services via the Container#register and Container#register! interfaces.
27
+ class ServicePoint
28
+
29
+ # The name of this service point, as it is known to the container that it
30
+ # was registered in.
31
+ attr_reader :name
32
+
33
+ # A reference to the container that contains this service point.
34
+ attr_reader :container
35
+
36
+ # Create a new service point that references the given container and has
37
+ # the given name. The associated callback will be used to instantiate the
38
+ # service on demand.
39
+ #
40
+ # The <tt>:model</tt> option is used to tell Needle which style of
41
+ # life-cycle management should be used for the service. It defaults to
42
+ # <tt>:singleton</tt>. The model should either be a class (which implements
43
+ # the necessary interface to be a service model), a symbol (in which case
44
+ # it refers to a service model that has been registered in the root
45
+ # <tt>:service_models</tt> service), or a string (in which case it is
46
+ # internalized and converted to a symbol). All other values are converted
47
+ # to strings and then internalized.
48
+ def initialize( container, name, opts={}, &callback )
49
+ @name = name
50
+ @container = container
51
+ @callback = callback
52
+ @interceptors = nil
53
+
54
+ model = opts[:model] || :singleton
55
+
56
+ case model
57
+ when Class then
58
+ model_factory = model
59
+ when Symbol then
60
+ model_factory = @container.root.service_models[model]
61
+ when String then
62
+ model = model.intern
63
+ model_factory = @container.root.service_models[model]
64
+ else
65
+ model = model.to_s.intern
66
+ model_factory = @container.root.service_models[model]
67
+ end
68
+
69
+ @model = model_factory.new( @container, opts ) { instantiate }
70
+ end
71
+
72
+ # Returns the fully-qualified name of the service point, with the point's
73
+ # name, its container's name, and all of its container's ancestors' names
74
+ # concatenated together with dot characters, i.e. "one.two.three".
75
+ def fullname
76
+ "#{@container.fullname}.#{@name}"
77
+ end
78
+
79
+ # Adds the given interceptor definition to this service point. The
80
+ # parameter should act like an instance of Interceptor.
81
+ def interceptor( interceptor )
82
+ @interceptors ||= []
83
+ @interceptors.push interceptor
84
+ end
85
+
86
+ # Return the service instance represented by this service point. Depending
87
+ # on the style of lifecycle management chosen for this service point, this
88
+ # may or may not be a new instance for every invocation of this method.
89
+ def instance
90
+ @model.instance
91
+ end
92
+
93
+ # Do the dirty-work of instantiating this service point. This invokes the
94
+ # callback that was registered for this service point, installs any
95
+ # requested interceptors, and returns the new instance.
96
+ def instantiate
97
+ instance = @callback.call( @container )
98
+
99
+ if @interceptors
100
+ instance = InterceptorChainBuilder.build( self, instance, @interceptors )
101
+ end
102
+
103
+ instance
104
+ end
105
+ private :instantiate
106
+
107
+ end
108
+
109
+ end
@@ -0,0 +1,28 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Needle dependency injection
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Needle
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # needle website : http://needle.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/needle
14
+ # =============================================================================
15
+ #++
16
+
17
+ module Needle
18
+ module Version
19
+
20
+ MAJOR = 0
21
+ MINOR = 5
22
+ TINY = 0
23
+
24
+ # The version of the Needle library in use.
25
+ STRING = [ MAJOR, MINOR, TINY ].join( "." )
26
+
27
+ end
28
+ end
data/lib/needle.rb ADDED
@@ -0,0 +1,54 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Needle dependency injection
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Needle
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # needle website : http://needle.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/needle
14
+ # =============================================================================
15
+ #++
16
+
17
+ #--
18
+ # Documentation Roadmap:
19
+ #
20
+ # The following items will given you sufficient background to understand how to
21
+ # use the Needle API in your own programs.
22
+ #
23
+ # 1. Start with needle/registry.rb. This describes how to create a new
24
+ # service registry.
25
+ #
26
+ # 2. Then, read needle/container.rb. This describes the interface of the
27
+ # registry and namespaces.
28
+ #
29
+ # The following items are only necessary if you want to understand how Needle
30
+ # works internally. You will rarely (if ever) need to use these interfaces
31
+ # directly in your own programs:
32
+ #
33
+ # 1. needle/service-point.rb. This describes how services are instantiated.
34
+ #
35
+ # 2. needle/models.rb and needle/models/*.rb. These describe the service
36
+ # models that are available, which are used to manage the lifecycles of
37
+ # instantiated services.
38
+ #
39
+ # 3. needle/interceptor.rb. This describes the interface for configuring
40
+ # interceptors on services.
41
+ #
42
+ # 4. needle/interceptor-builder.rb. This describes the routines for
43
+ # constructing the proxy objects and interceptor chains around services.
44
+ #
45
+ # 5. needle/log-factory.rb and needle/logger.rb. These define the logging
46
+ # interface for needle.
47
+ #
48
+ # 6. needle/logging-interceptor.rb. This defines the logging interceptor
49
+ # service, which wraps every method of a service and logs tracing
50
+ # information.
51
+ #++
52
+
53
+ require 'needle/errors'
54
+ require 'needle/registry'
data/test/ALL-TESTS.rb ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ #--
3
+ # =============================================================================
4
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
5
+ # All rights reserved.
6
+ #
7
+ # This source file is distributed as part of the Needle dependency injection
8
+ # library for Ruby. This file (and the library as a whole) may be used only as
9
+ # allowed by either the BSD license, or the Ruby license (or, by association
10
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Needle
11
+ # distribution for the texts of these licenses.
12
+ # -----------------------------------------------------------------------------
13
+ # needle website : http://needle.rubyforge.org
14
+ # project website: http://rubyforge.org/projects/needle
15
+ # =============================================================================
16
+ #++
17
+
18
+ $:.unshift "../lib"
19
+
20
+ Dir.chdir File.dirname(__FILE__)
21
+ Dir["**/tc_*.rb"].each { |file| load file }
@@ -0,0 +1,53 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Needle dependency injection
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Needle
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # needle website : http://needle.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/needle
14
+ # =============================================================================
15
+ #++
16
+
17
+ $:.unshift "../../lib"
18
+
19
+ require "needle/models/prototype"
20
+ require "test/unit"
21
+
22
+ class TC_ModelsPrototype < Test::Unit::TestCase
23
+
24
+ def test_instance
25
+ instantiated = false
26
+ model = Needle::Models::Prototype.new( nil ) {
27
+ instantiated = true
28
+ Hash.new
29
+ }
30
+
31
+ assert !instantiated
32
+ proto = model.instance
33
+ assert instantiated
34
+ proto[:test] = :value
35
+ assert_equal :value, proto[:test]
36
+ end
37
+
38
+ def test_container
39
+ model = Needle::Models::Prototype.new( :container ) { |c|
40
+ assert_equal :container, c
41
+ Hash.new
42
+ }
43
+ model.instance
44
+ end
45
+
46
+ def test_model
47
+ model = Needle::Models::Prototype.new( nil ) { Hash.new }
48
+ p1 = model.instance
49
+ p2 = model.instance
50
+ assert_not_same p1, p2
51
+ end
52
+
53
+ end
@@ -0,0 +1,54 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Needle dependency injection
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Needle
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # needle website : http://needle.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/needle
14
+ # =============================================================================
15
+ #++
16
+
17
+ $:.unshift "../../lib"
18
+
19
+ require "needle/models/prototype-deferred"
20
+ require "test/unit"
21
+
22
+ class TC_ModelsPrototypeDeferred < Test::Unit::TestCase
23
+
24
+ def test_instance
25
+ instantiated = false
26
+ model = Needle::Models::PrototypeDeferred.new( nil ) {
27
+ instantiated = true
28
+ Hash.new
29
+ }
30
+
31
+ assert !instantiated
32
+ proto = model.instance
33
+ assert !instantiated
34
+ proto[:test] = :value
35
+ assert instantiated
36
+ assert_equal :value, proto[:test]
37
+ end
38
+
39
+ def test_container
40
+ model = Needle::Models::PrototypeDeferred.new( :container ) { |c|
41
+ assert_equal :container, c
42
+ Hash.new
43
+ }
44
+ model.instance[:test] = :value
45
+ end
46
+
47
+ def test_model
48
+ model = Needle::Models::PrototypeDeferred.new( nil ) { Hash.new }
49
+ p1 = model.instance
50
+ p2 = model.instance
51
+ assert_not_same p1, p2
52
+ end
53
+
54
+ end