needle-extras 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ require 'needle/extras/require-library'
2
+
3
+ module Needle
4
+ module Extras
5
+
6
+ def register_services( container )
7
+ container.define do |b|
8
+ b.require 'needle/extras/attr-inject', 'Needle::Extras::AttrInject'
9
+ b.require 'needle/extras/multicast', 'Needle::Extras::Multicast'
10
+ end
11
+ end
12
+ module_function :register_services
13
+
14
+ end
15
+
16
+ register_library "needle/extras", Needle::Extras
17
+ end
@@ -0,0 +1,73 @@
1
+ require 'needle/pipeline/element'
2
+
3
+ class Class
4
+
5
+ # Add a hook for declaring properties of an object that should be injected
6
+ # into instances of this class. See Object#inject_attributes.
7
+ def attr_inject( *properties )
8
+ ( @injectable_attributes ||= [] ).concat properties.map { |p| p.to_sym }
9
+ end
10
+ private :attr_inject
11
+
12
+ # Returns an array of attributes of the class that have been declared to
13
+ # be injectable. See #attr_inject and Object#inject_attributes.
14
+ def injectable_attributes
15
+ if defined?(@injectable_attributes)
16
+ @injectable_attributes
17
+ else
18
+ []
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ class Object
25
+
26
+ # Injects all injectable attributes of the instance's class with the
27
+ # corresponding services from the given container. Each attribute is
28
+ # injected into an identically named instance variable of the object,
29
+ # from an identically named service in the container.
30
+ #
31
+ # This returns the object itself.
32
+ def inject_attributes( container )
33
+ self.class.injectable_attributes.each do |attribute|
34
+ instance_variable_set "@#{attribute}", container.get( attribute )
35
+ end
36
+ self
37
+ end
38
+
39
+ end
40
+
41
+ module Needle
42
+ module Extras
43
+ module AttrInject
44
+
45
+ # A specialized pipeline element that injects the constructed service
46
+ # with dependent services from the point's container.
47
+ class InjectorElement < Needle::Pipeline::Element
48
+ set_default_priority 0
49
+
50
+ def call( *args )
51
+ succ.
52
+ call( *args ).
53
+ inject_attributes( service_point.container )
54
+ end
55
+
56
+ end
57
+
58
+ # Registers the InjectorElement pipeline element, and adds some new
59
+ # service models (multiton_inject, prototype_inject, and
60
+ # singleton_inject).
61
+ def register_services( container )
62
+ container.pipeline_elements[ :attr_inject ] = InjectorElement
63
+ container.service_models.update(
64
+ :multiton_inject => [ :multiton, :attr_inject ],
65
+ :prototype_inject => [ :attr_injector ],
66
+ :singleton_inject => [ :singleton, :attr_inject ]
67
+ )
68
+ end
69
+ module_function :register_services
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,42 @@
1
+ module Needle
2
+ module Extras
3
+ module Multicast
4
+
5
+ # A proxy that wraps an array of other objects. Whenever a message
6
+ # is received by this proxy, it delegates the call to the objects in the
7
+ # array.
8
+ class Target
9
+
10
+ # Creates a new Target object that acts as a proxy for the given list
11
+ # of delegates.
12
+ def initialize( *delegates )
13
+ @delegates = delegates
14
+ end
15
+
16
+ # Forwards the method to each object in the array. It does no checking
17
+ # to ensure that the receiver can understand the message before sending
18
+ # it. This will return an array of the results of calling each of the
19
+ # other messages.
20
+ def method_missing( sym, *args, &block )
21
+ @delegates.inject( [] ) do |a,d|
22
+ a << d.__send__( sym, *args, &block )
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ # Register the multicast factory service in the given container. The
29
+ # multicast service is a parameterized service which accepts a single
30
+ # parameter--an array of the targets to apply to the multicaster. It
31
+ # will then return an instance of a multicast service.
32
+ def register_services( container )
33
+ container.define.multicast :model => :prototype do |c,p,*targets|
34
+ Multicast::Target.new( *targets )
35
+ end
36
+ end
37
+ module_function :register_services
38
+
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,34 @@
1
+ require 'needle/container'
2
+
3
+ module Needle
4
+
5
+ # This constant represents the collection of registered libraries. Each
6
+ # value in it must respond to the #call method, accepting a single
7
+ # parameter (the container to register the library with).
8
+ LIBRARIES = Hash.new
9
+
10
+ class Container
11
+
12
+ # Require the library registered under the given name. A Kernel.require
13
+ # is done on the name, and then if a library has been registered under
14
+ # that name, its #call method is invoked with the container as the
15
+ # parameter.
16
+ def require_library( name )
17
+ Kernel.require name
18
+ LIBRARIES[ name ].call( self ) if LIBRARIES[ name ]
19
+ end
20
+
21
+ end
22
+
23
+ # A convenience method for registering libraries with the "require-library"
24
+ # subsystem. +name+ must correspond to a file to require with Kernel.require.
25
+ # +mod+ is a module containing the registration method named by the
26
+ # +registration_method+ parameter (defaulting to <tt>:register_library</tt>).
27
+ def register_library( name, mod, registration_method=:register_services )
28
+ LIBRARIES[ name ] = lambda do |container|
29
+ mod.__send__( registration_method, container )
30
+ end
31
+ end
32
+ module_function :register_library
33
+
34
+ end
@@ -0,0 +1,13 @@
1
+ module Needle
2
+ module Extras
3
+ module Version
4
+
5
+ MAJOR = 1
6
+ MINOR = 0
7
+ TINY = 0
8
+
9
+ STRING = [MAJOR,MINOR,TINY].join('.')
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ $:.unshift "../lib"
2
+
3
+ begin
4
+ require 'rubygems'
5
+ rescue LoadError
6
+ end
7
+
8
+ Dir.chdir File.dirname(__FILE__)
9
+ Dir["**/tc_*.rb"].each { |file| load file }
@@ -0,0 +1,115 @@
1
+ $:.unshift "../lib"
2
+
3
+ require 'test/unit'
4
+ require 'needle'
5
+ require 'needle/extras/attr-inject'
6
+
7
+ class TC_AttrInject_Class < Test::Unit::TestCase
8
+
9
+ def test_attr_inject
10
+ assert_nothing_raised do
11
+ Class.new do
12
+ attr_inject :foo
13
+ attr_inject :bar, :baz
14
+ attr_inject "test"
15
+ end
16
+ end
17
+ end
18
+
19
+ def test_injectable_attributes
20
+ klass = Class.new do
21
+ attr_inject :foo
22
+ attr_inject :bar, :baz
23
+ attr_inject "test"
24
+ end
25
+ assert_equal [ :foo, :bar, :baz, :test ], klass.injectable_attributes
26
+ end
27
+
28
+ end
29
+
30
+
31
+ class AttrInject_MockContainer
32
+ def get( attribute )
33
+ attribute
34
+ end
35
+ end
36
+
37
+
38
+ class TC_AttrInject_Object < Test::Unit::TestCase
39
+
40
+ def test_inject_attributes
41
+ klass = Class.new { attr_inject :foo, :bar }
42
+ obj = klass.new.inject_attributes( AttrInject_MockContainer.new )
43
+ assert_equal :foo, obj.instance_variable_get( "@foo" )
44
+ assert_equal :bar, obj.instance_variable_get( "@bar" )
45
+ end
46
+
47
+ end
48
+
49
+
50
+ class TC_AttrInject_InjectorElement < Test::Unit::TestCase
51
+
52
+ def setup
53
+ point = Class.new do
54
+ attr_reader :container
55
+ def initialize( c ); @container = c; end
56
+ end.new( AttrInject_MockContainer.new )
57
+
58
+ klass = Class.new { attr_inject :foo, :bar }
59
+
60
+ @element = Needle::Extras::AttrInject::InjectorElement.new( point )
61
+ @element.succ = proc { klass.new }
62
+ end
63
+
64
+ def test_default_priority
65
+ assert_equal 0, @element.priority
66
+ end
67
+
68
+ def test_call_multiargs
69
+ assert_nothing_raised do
70
+ @element.call( 1, 2, 3 )
71
+ end
72
+ end
73
+
74
+ def test_call
75
+ obj = @element.call( 1, 2, 3 )
76
+ assert_equal :foo, obj.instance_variable_get( "@foo" )
77
+ assert_equal :bar, obj.instance_variable_get( "@bar" )
78
+ end
79
+
80
+ end
81
+
82
+
83
+ class TC_AttrInject_Services < Test::Unit::TestCase
84
+
85
+ def setup
86
+ @reg = Needle::Registry.new
87
+ Needle::Extras::AttrInject.register_services( @reg )
88
+ @reg.register( :foo ) { "foo is wizard!" }
89
+ @reg.register( :bar ) { "bar is teh bomb!" }
90
+ end
91
+
92
+ def test_no_inject
93
+ @reg.register( :hit_me, :model => :singleton_inject ) do
94
+ Class.new { def hello; "hello"; end }.new
95
+ end
96
+ hit_me = nil
97
+ assert_nothing_raised do
98
+ hit_me = @reg.hit_me
99
+ end
100
+ assert_equal "hello", hit_me.hello
101
+ end
102
+
103
+ def test_inject
104
+ @reg.register( :hit_me, :model => :singleton_inject ) do
105
+ Class.new { attr_inject :foo, :bar; attr_reader :foo, :bar }.new
106
+ end
107
+ hit_me = nil
108
+ assert_nothing_raised do
109
+ hit_me = @reg.hit_me
110
+ end
111
+ assert_equal "foo is wizard!", hit_me.foo
112
+ assert_equal "bar is teh bomb!", hit_me.bar
113
+ end
114
+
115
+ end
@@ -0,0 +1,46 @@
1
+ $:.unshift "../lib"
2
+
3
+ require 'test/unit'
4
+ require 'needle'
5
+ require 'needle/extras/multicast'
6
+
7
+ class TC_Multicast_Target < Test::Unit::TestCase
8
+
9
+ def test_empty_delegation
10
+ target = Needle::Extras::Multicast::Target.new
11
+ assert_equal [], target.length
12
+ end
13
+
14
+ def test_non_empty_delegation
15
+ target = Needle::Extras::Multicast::Target.new( "foo", "bar baz",
16
+ [ 1, 2, 3, 4, 5 ] )
17
+ assert_equal [ 3, 7, 5 ], target.length
18
+ end
19
+
20
+ def test_send_bad_message
21
+ target = Needle::Extras::Multicast::Target.new( 5 )
22
+ assert_raise( NoMethodError ) do
23
+ target.length
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ class TC_Multicast_Service < Test::Unit::TestCase
30
+
31
+ def test_service
32
+ reg = Needle::Registry.define do |b|
33
+ b.require 'needle/extras/multicast', Needle::Extras::Multicast
34
+
35
+ b.a { "a" }
36
+ b.b { "b" }
37
+ b.c { |c,| [ c.a, c.b, "c" ] }
38
+
39
+ b.sender { |c,| c.multicast( c.a, c.c ) }
40
+ end
41
+
42
+ sender = reg.sender
43
+ assert_equal [ 1, 3 ], sender.length
44
+ end
45
+
46
+ end
@@ -0,0 +1,70 @@
1
+ $:.unshift "../lib"
2
+
3
+ require 'test/unit'
4
+ require 'needle'
5
+ require 'needle/extras/require-library'
6
+
7
+ class TC_RequireLibrary_Container < Test::Unit::TestCase
8
+
9
+ def test_require_library_registered
10
+ reg = Needle::Registry.new
11
+ assert !reg.keys.include?( :multicast )
12
+ reg.require_library "needle/extras"
13
+ assert reg.keys.include?( :multicast )
14
+ end
15
+
16
+ def test_require_library_unregistered
17
+ reg = Needle::Registry.new
18
+ assert_nothing_raised do
19
+ reg.require_library "rational"
20
+ end
21
+ end
22
+
23
+ def test_require_library_custom_hook
24
+ called_by = nil
25
+ Needle::LIBRARIES['yaml'] = lambda { |container| called_by = container }
26
+ reg = Needle::Registry.new
27
+ reg.require_library "yaml"
28
+ assert_same called_by, reg
29
+ end
30
+
31
+ end
32
+
33
+ class TC_RequireLibrary_Needle < Test::Unit::TestCase
34
+
35
+ Klass = Class.new do
36
+ attr_reader :events
37
+
38
+ def method_missing( sym, *args )
39
+ @events ||= []
40
+ @events << [ sym, *args ]
41
+ end
42
+ end
43
+
44
+ def test_register_library
45
+ mod = Klass.new
46
+
47
+ assert !Needle::LIBRARIES.has_key?( "openssl" )
48
+ Needle.register_library( "openssl", mod )
49
+ assert Needle::LIBRARIES.has_key?( "openssl" )
50
+
51
+ reg = Needle::Registry.new
52
+ reg.require_library "openssl"
53
+
54
+ assert_equal [ [ :register_services, reg ] ], mod.events
55
+ end
56
+
57
+ def test_register_library_custom_method
58
+ mod = Klass.new
59
+
60
+ assert !Needle::LIBRARIES.has_key?( "net/http" )
61
+ Needle.register_library( "net/http", mod, :register_foo )
62
+ assert Needle::LIBRARIES.has_key?( "net/http" )
63
+
64
+ reg = Needle::Registry.new
65
+ reg.require_library "net/http"
66
+
67
+ assert_equal [ [ :register_foo, reg ] ], mod.events
68
+ end
69
+
70
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.1
3
+ specification_version: 1
4
+ name: needle-extras
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2004-11-18
8
+ summary: Needle-Extras is a collection of additional services that can be used with Needle. This is basically a test-bed of services that may eventually find their way into Needle itself.
9
+ require_paths:
10
+ - lib
11
+ author: Jamis Buck
12
+ email: jgb3@email.byu.edu
13
+ homepage: http://needle.rubyforge.org
14
+ rubyforge_project:
15
+ description:
16
+ autorequire: needle/extras
17
+ default_executable:
18
+ bindir: bin
19
+ has_rdoc: true
20
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
21
+ requirements:
22
+ -
23
+ - ">"
24
+ - !ruby/object:Gem::Version
25
+ version: 0.0.0
26
+ version:
27
+ platform: ruby
28
+ files:
29
+ - doc/README
30
+ - doc/LICENSE-RUBY
31
+ - doc/manual-html
32
+ - doc/LICENSE-BSD
33
+ - doc/LICENSE-GPL
34
+ - doc/manual
35
+ - doc/manual-html/manual.css
36
+ - doc/manual-html/chapter-1.html
37
+ - doc/manual-html/chapter-2.html
38
+ - doc/manual-html/chapter-3.html
39
+ - doc/manual-html/chapter-4.html
40
+ - doc/manual-html/index.html
41
+ - doc/manual/manual.css
42
+ - doc/manual/manual.yml
43
+ - doc/manual/parts
44
+ - doc/manual/chapter.erb
45
+ - doc/manual/page.erb
46
+ - doc/manual/index.erb
47
+ - doc/manual/manual.rb
48
+ - doc/manual/parts/multicast_usage.txt
49
+ - doc/manual/parts/multicast_overview.txt
50
+ - doc/manual/parts/intro_usage.txt
51
+ - doc/manual/parts/attrinject_usage.txt
52
+ - doc/manual/parts/requirelibrary_overview.txt
53
+ - doc/manual/parts/intro_license.txt
54
+ - doc/manual/parts/attrinject_overview.txt
55
+ - doc/manual/parts/intro_support.txt
56
+ - doc/manual/parts/requirelibrary_usage.txt
57
+ - doc/manual/parts/intro_what_is_extras.txt
58
+ - lib/needle
59
+ - lib/needle/extras
60
+ - lib/needle/extras.rb
61
+ - lib/needle/extras/attr-inject.rb
62
+ - lib/needle/extras/multicast.rb
63
+ - lib/needle/extras/version.rb
64
+ - lib/needle/extras/require-library.rb
65
+ - test/ALL-TESTS.rb
66
+ - test/tc_attr-inject.rb
67
+ - test/tc_multicast.rb
68
+ - test/tc_require-library.rb
69
+ test_files:
70
+ - test/ALL-TESTS.rb
71
+ rdoc_options:
72
+ - "--title"
73
+ - "Needle-Extras -- Services for Needle"
74
+ - "--main"
75
+ - doc/README
76
+ extra_rdoc_files:
77
+ - doc/README
78
+ executables: []
79
+ extensions: []
80
+ requirements: []
81
+ dependencies:
82
+ - !ruby/object:Gem::Dependency
83
+ name: needle
84
+ version_requirement:
85
+ version_requirements: !ruby/object:Gem::Version::Requirement
86
+ requirements:
87
+ -
88
+ - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 1.2.0
91
+ version: