needle-extras 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/LICENSE-BSD +27 -0
- data/doc/LICENSE-GPL +280 -0
- data/doc/LICENSE-RUBY +56 -0
- data/doc/README +50 -0
- data/doc/manual-html/chapter-1.html +214 -0
- data/doc/manual-html/chapter-2.html +180 -0
- data/doc/manual-html/chapter-3.html +168 -0
- data/doc/manual-html/chapter-4.html +184 -0
- data/doc/manual-html/index.html +155 -0
- data/doc/manual-html/manual.css +192 -0
- data/doc/manual/chapter.erb +18 -0
- data/doc/manual/index.erb +29 -0
- data/doc/manual/manual.css +192 -0
- data/doc/manual/manual.rb +202 -0
- data/doc/manual/manual.yml +45 -0
- data/doc/manual/page.erb +71 -0
- data/doc/manual/parts/attrinject_overview.txt +1 -0
- data/doc/manual/parts/attrinject_usage.txt +34 -0
- data/doc/manual/parts/intro_license.txt +5 -0
- data/doc/manual/parts/intro_support.txt +1 -0
- data/doc/manual/parts/intro_usage.txt +30 -0
- data/doc/manual/parts/intro_what_is_extras.txt +7 -0
- data/doc/manual/parts/multicast_overview.txt +1 -0
- data/doc/manual/parts/multicast_usage.txt +22 -0
- data/doc/manual/parts/requirelibrary_overview.txt +5 -0
- data/doc/manual/parts/requirelibrary_usage.txt +34 -0
- data/lib/needle/extras.rb +17 -0
- data/lib/needle/extras/attr-inject.rb +73 -0
- data/lib/needle/extras/multicast.rb +42 -0
- data/lib/needle/extras/require-library.rb +34 -0
- data/lib/needle/extras/version.rb +13 -0
- data/test/ALL-TESTS.rb +9 -0
- data/test/tc_attr-inject.rb +115 -0
- data/test/tc_multicast.rb +46 -0
- data/test/tc_require-library.rb +70 -0
- metadata +91 -0
@@ -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
|
data/test/ALL-TESTS.rb
ADDED
@@ -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:
|