needle 0.5.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 +70 -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 +240 -0
- data/doc/manual/manual.yml +48 -0
- data/doc/manual/page.erb +86 -0
- data/doc/manual/parts/01_license.txt +5 -0
- data/doc/manual/parts/01_support.txt +1 -0
- data/doc/manual/parts/01_use_cases.txt +141 -0
- data/doc/manual/parts/01_what_is_needle.txt +1 -0
- data/doc/manual/parts/02_creating.txt +9 -0
- data/doc/manual/parts/02_namespaces.txt +47 -0
- data/doc/manual/parts/02_overview.txt +3 -0
- data/doc/manual/parts/02_services.txt +44 -0
- data/doc/manual/tutorial.erb +30 -0
- data/doc/manual-html/chapter-1.html +354 -0
- data/doc/manual-html/chapter-2.html +310 -0
- data/doc/manual-html/chapter-3.html +154 -0
- data/doc/manual-html/chapter-4.html +154 -0
- data/doc/manual-html/chapter-5.html +154 -0
- data/doc/manual-html/chapter-6.html +154 -0
- data/doc/manual-html/chapter-7.html +154 -0
- data/doc/manual-html/index.html +177 -0
- data/doc/manual-html/manual.css +192 -0
- data/lib/needle/container.rb +318 -0
- data/lib/needle/errors.rb +32 -0
- data/lib/needle/include-exclude.rb +116 -0
- data/lib/needle/interceptor-chain.rb +162 -0
- data/lib/needle/interceptor.rb +189 -0
- data/lib/needle/log-factory.rb +207 -0
- data/lib/needle/logger.rb +161 -0
- data/lib/needle/logging-interceptor.rb +62 -0
- data/lib/needle/models/prototype-deferred.rb +41 -0
- data/lib/needle/models/prototype.rb +39 -0
- data/lib/needle/models/proxy.rb +84 -0
- data/lib/needle/models/singleton-deferred.rb +57 -0
- data/lib/needle/models/singleton.rb +56 -0
- data/lib/needle/models.rb +44 -0
- data/lib/needle/registry.rb +110 -0
- data/lib/needle/service-point.rb +109 -0
- data/lib/needle/version.rb +28 -0
- data/lib/needle.rb +54 -0
- data/test/ALL-TESTS.rb +21 -0
- data/test/models/tc_prototype.rb +53 -0
- data/test/models/tc_prototype_deferred.rb +54 -0
- data/test/models/tc_proxy.rb +51 -0
- data/test/models/tc_singleton.rb +53 -0
- data/test/models/tc_singleton_deferred.rb +54 -0
- data/test/tc_container.rb +246 -0
- data/test/tc_interceptor.rb +92 -0
- data/test/tc_interceptor_chain.rb +181 -0
- data/test/tc_logger.rb +181 -0
- data/test/tc_models.rb +44 -0
- data/test/tc_registry.rb +34 -0
- data/test/tc_service_point.rb +100 -0
- metadata +107 -0
@@ -0,0 +1,51 @@
|
|
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/proxy"
|
20
|
+
require "test/unit"
|
21
|
+
|
22
|
+
class TC_ModelsProxy < Test::Unit::TestCase
|
23
|
+
|
24
|
+
def test_fail
|
25
|
+
proxy = Needle::Models::Proxy.new( nil ) { Bogus.new }
|
26
|
+
assert_raise( NameError ) do
|
27
|
+
proxy.hello
|
28
|
+
end
|
29
|
+
assert_nothing_raised do
|
30
|
+
proxy.hello
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_succeed
|
35
|
+
instantiated = false
|
36
|
+
proxy = Needle::Models::Proxy.new( nil ) { instantiated = true; Hash.new }
|
37
|
+
assert !instantiated
|
38
|
+
proxy[:test] = :value
|
39
|
+
assert instantiated
|
40
|
+
assert_equal :value, proxy[:test]
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_container
|
44
|
+
proxy = Needle::Models::Proxy.new( :container ) do |c|
|
45
|
+
assert_equal :container, c
|
46
|
+
Hash.new
|
47
|
+
end
|
48
|
+
proxy[:test] = :value
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -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/singleton"
|
20
|
+
require "test/unit"
|
21
|
+
|
22
|
+
class TC_ModelsSingleton < Test::Unit::TestCase
|
23
|
+
|
24
|
+
def test_instance
|
25
|
+
instantiated = false
|
26
|
+
model = Needle::Models::Singleton.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::Singleton.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::Singleton.new( nil ) { Hash.new }
|
48
|
+
p1 = model.instance
|
49
|
+
p2 = model.instance
|
50
|
+
assert_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/singleton-deferred"
|
20
|
+
require "test/unit"
|
21
|
+
|
22
|
+
class TC_ModelsSingletonDeferred < Test::Unit::TestCase
|
23
|
+
|
24
|
+
def test_instance
|
25
|
+
instantiated = false
|
26
|
+
model = Needle::Models::SingletonDeferred.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::SingletonDeferred.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::SingletonDeferred.new( nil ) { Hash.new }
|
49
|
+
p1 = model.instance
|
50
|
+
p2 = model.instance
|
51
|
+
assert_same p1, p2
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,246 @@
|
|
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/container'
|
20
|
+
require 'test/unit'
|
21
|
+
|
22
|
+
class TC_Container < Test::Unit::TestCase
|
23
|
+
|
24
|
+
class TC_RegistrationContext < Test::Unit::TestCase
|
25
|
+
class MockContainer
|
26
|
+
attr_reader :events
|
27
|
+
def initialize; @events = []; end
|
28
|
+
def method_missing(s,*a,&b)
|
29
|
+
@events << { :name => s, :args => a, :block => b }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def setup
|
34
|
+
@container = MockContainer.new
|
35
|
+
@ctx = Needle::Container::RegistrationContext.new( @container )
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_register
|
39
|
+
assert_nothing_raised do
|
40
|
+
@ctx.hello { "world" }
|
41
|
+
end
|
42
|
+
assert_equal :register, @container.events[0][:name]
|
43
|
+
assert_equal [ :hello ], @container.events[0][:args]
|
44
|
+
assert_not_nil @container.events[0][:block]
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_reference_bad
|
48
|
+
assert_raise( NoMethodError ) do
|
49
|
+
@ctx.hello( :arg )
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_register_good
|
54
|
+
assert_nothing_raised do
|
55
|
+
@ctx.hello
|
56
|
+
end
|
57
|
+
assert_equal :[], @container.events[0][:name]
|
58
|
+
assert_equal [ :hello ], @container.events[0][:args]
|
59
|
+
assert_nil @container.events[0][:block]
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_intercept
|
63
|
+
assert_nothing_raised do
|
64
|
+
@ctx.intercept( :foo )
|
65
|
+
end
|
66
|
+
assert_equal :intercept, @container.events[0][:name]
|
67
|
+
assert_equal [ :foo ], @container.events[0][:args]
|
68
|
+
assert_nil @container.events[0][:block]
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
class Model
|
74
|
+
def initialize( container, opts={}, &callback )
|
75
|
+
@container, @callback = container, callback
|
76
|
+
@inst = nil
|
77
|
+
end
|
78
|
+
def instance
|
79
|
+
return @inst if @inst
|
80
|
+
@inst = @callback.call( @container )
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_default
|
85
|
+
container = Needle::Container.new
|
86
|
+
assert_nil container.parent
|
87
|
+
assert_nil container.name
|
88
|
+
assert_equal container, container.root
|
89
|
+
assert_equal "", container.fullname
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_named
|
93
|
+
container = Needle::Container.new( nil, "name" )
|
94
|
+
assert_nil container.parent
|
95
|
+
assert_equal "name", container.name
|
96
|
+
assert_equal container, container.root
|
97
|
+
assert_equal "name", container.fullname
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_nested
|
101
|
+
outer = Needle::Container.new
|
102
|
+
inner = Needle::Container.new( outer )
|
103
|
+
assert_same outer, inner.parent
|
104
|
+
assert_equal outer, inner.root
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_root
|
108
|
+
outer = Needle::Container.new
|
109
|
+
middle = Needle::Container.new( outer )
|
110
|
+
inner = Needle::Container.new( middle )
|
111
|
+
assert_same middle, inner.parent
|
112
|
+
assert_equal outer, inner.root
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_nested_named
|
116
|
+
outer = Needle::Container.new( nil, "outer" )
|
117
|
+
inner = Needle::Container.new( outer, "inner" )
|
118
|
+
assert_equal "inner", inner.name
|
119
|
+
assert_equal "outer.inner", inner.fullname
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_service_not_found
|
123
|
+
container = Needle::Container.new
|
124
|
+
assert_raise( Needle::ServiceNotFound ) do
|
125
|
+
container[:test]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_register
|
130
|
+
container = Needle::Container.new
|
131
|
+
container.register( :test, :model=>Model ) { Hash.new }
|
132
|
+
|
133
|
+
assert_nothing_raised { container[:test] }
|
134
|
+
assert_nothing_raised { container.test }
|
135
|
+
|
136
|
+
assert_instance_of Hash, container[:test]
|
137
|
+
assert_instance_of Hash, container.test
|
138
|
+
|
139
|
+
assert container.respond_to?(:test)
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_register!
|
143
|
+
container = Needle::Container.new
|
144
|
+
|
145
|
+
container.register! do
|
146
|
+
test( :model=>Model ) { Hash.new }
|
147
|
+
namespace :subitem, :model=>Model do
|
148
|
+
test2( :model=>Model ) { Hash.new }
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
assert container.has_key?( :test )
|
153
|
+
assert_instance_of Hash, container.test
|
154
|
+
assert container.subitem.has_key?( :test2 )
|
155
|
+
assert_instance_of Hash, container.subitem.test2
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_namespace
|
159
|
+
container = Needle::Container.new
|
160
|
+
container.namespace( :test, :model=>Model )
|
161
|
+
assert_instance_of Needle::Container, container.test
|
162
|
+
|
163
|
+
container.namespace( :test2, :model=>Model ) do |ns|
|
164
|
+
assert_instance_of Needle::Container, ns
|
165
|
+
end
|
166
|
+
|
167
|
+
assert_instance_of Needle::Container, container.test2
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_multi_namespace
|
171
|
+
container = Needle::Container.new
|
172
|
+
container.namespace( :test, :test2, :test3, :model=>Model )
|
173
|
+
assert_instance_of Needle::Container, container.test
|
174
|
+
assert_instance_of Needle::Container, container.test.test2
|
175
|
+
assert_instance_of Needle::Container, container.test.test2.test3
|
176
|
+
|
177
|
+
container.namespace( :test, :test2, :test3, :model=>Model ) do |ns|
|
178
|
+
assert_same ns, container.test.test2.test3
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_has_key
|
183
|
+
container = Needle::Container.new
|
184
|
+
|
185
|
+
assert !container.has_key?(:test)
|
186
|
+
container.register( :test, :model=>Model ) { Hash.new }
|
187
|
+
assert container.has_key?(:test)
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_knows_key
|
191
|
+
container = Needle::Container.new
|
192
|
+
|
193
|
+
assert !container.knows_key?(:test)
|
194
|
+
container.register( :test, :model=>Model ) { Hash.new }
|
195
|
+
assert container.knows_key?(:test)
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_parent_knows_key
|
199
|
+
outer = Needle::Container.new
|
200
|
+
inner = Needle::Container.new( outer )
|
201
|
+
|
202
|
+
outer.register( :test, :model=>Model ) { Hash.new }
|
203
|
+
assert !inner.has_key?(:test)
|
204
|
+
assert inner.knows_key?(:test)
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_service_in_parent
|
208
|
+
outer = Needle::Container.new
|
209
|
+
inner = Needle::Container.new( outer )
|
210
|
+
|
211
|
+
outer.register( :test, :model=>Model ) { Hash.new }
|
212
|
+
assert_nothing_raised do
|
213
|
+
inner[:test]
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_service_not_in_parent
|
218
|
+
outer = Needle::Container.new
|
219
|
+
inner = Needle::Container.new( outer )
|
220
|
+
|
221
|
+
assert_raise( Needle::ServiceNotFound ) do
|
222
|
+
inner[:test]
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def test_intercept_not_found
|
227
|
+
container = Needle::Container.new
|
228
|
+
assert_raise( Needle::ServiceNotFound ) do
|
229
|
+
container.intercept( :test )
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def test_intercept
|
234
|
+
container = Needle::Container.new
|
235
|
+
container.register( :test, :model=>Model ) { Hash.new }
|
236
|
+
|
237
|
+
filtered = false
|
238
|
+
container.intercept( :test ).doing { |chain,ctx| filtered = true; chain.process_next(ctx) }
|
239
|
+
|
240
|
+
assert !filtered
|
241
|
+
svc = container.test
|
242
|
+
svc[:hello] = :world
|
243
|
+
assert filtered
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
@@ -0,0 +1,92 @@
|
|
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/interceptor'
|
20
|
+
require 'test/unit'
|
21
|
+
|
22
|
+
class TC_Interceptor < Test::Unit::TestCase
|
23
|
+
|
24
|
+
def test_empty
|
25
|
+
i = Needle::Interceptor.new
|
26
|
+
assert_equal [ :priority ], i.options.keys
|
27
|
+
assert_equal 0, i.options[:priority]
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_missing_action
|
31
|
+
i = Needle::Interceptor.new
|
32
|
+
|
33
|
+
assert_raise( Needle::InterceptorConfigurationError ) do
|
34
|
+
i.action
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_with_redefined
|
39
|
+
i = Needle::Interceptor.new
|
40
|
+
|
41
|
+
assert_raise( Needle::InterceptorConfigurationError ) do
|
42
|
+
i.with { :a }.with { :a }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_doing_redefined
|
47
|
+
i = Needle::Interceptor.new
|
48
|
+
|
49
|
+
assert_raise( Needle::InterceptorConfigurationError ) do
|
50
|
+
i.doing { :a }.doing { :a }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_with_doing
|
55
|
+
i = Needle::Interceptor.new
|
56
|
+
|
57
|
+
assert_raise( Needle::InterceptorConfigurationError ) do
|
58
|
+
i.with { :a }.doing { :a }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_doing_with
|
63
|
+
i = Needle::Interceptor.new
|
64
|
+
|
65
|
+
assert_raise( Needle::InterceptorConfigurationError ) do
|
66
|
+
i.doing { :a }.with { :a }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_options
|
71
|
+
i = Needle::Interceptor.new.
|
72
|
+
with_options(
|
73
|
+
:priority => 5,
|
74
|
+
:exclude => [ /^__/ ],
|
75
|
+
:include => [ /^__foo/ ] )
|
76
|
+
|
77
|
+
assert_equal 5, i[:priority]
|
78
|
+
assert_equal [ /^__/ ], i[:exclude]
|
79
|
+
assert_equal [ /^__foo/ ], i[:include]
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_with
|
83
|
+
i = Needle::Interceptor.new.with { |c| Hash.new }
|
84
|
+
assert_instance_of Hash, i.action.call(nil)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_doing
|
88
|
+
i = Needle::Interceptor.new.doing { |ch,ctx| ch.process_next(ctx) }
|
89
|
+
assert_instance_of Needle::Interceptor::DynamicInterceptor, i.action.call(nil)
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,181 @@
|
|
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/interceptor-chain'
|
20
|
+
require 'test/unit'
|
21
|
+
require 'ostruct'
|
22
|
+
|
23
|
+
class TC_InterceptorChainElement < Test::Unit::TestCase
|
24
|
+
|
25
|
+
class Interceptor
|
26
|
+
attr_reader :next_obj
|
27
|
+
attr_reader :context
|
28
|
+
|
29
|
+
def process( next_obj, context )
|
30
|
+
@next_obj = next_obj
|
31
|
+
@context = context
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_process_next
|
36
|
+
interceptor = Interceptor.new
|
37
|
+
element =
|
38
|
+
Needle::InterceptorChainBuilder::InterceptorChainElement.new interceptor
|
39
|
+
|
40
|
+
element.next = :next_obj
|
41
|
+
element.process_next :context
|
42
|
+
|
43
|
+
assert_equal :next_obj, interceptor.next_obj
|
44
|
+
assert_equal :context, interceptor.context
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
class TC_ProxyObjectChainElement < Test::Unit::TestCase
|
50
|
+
|
51
|
+
Context = Struct.new( :sym, :args, :block )
|
52
|
+
|
53
|
+
class ProxyObject
|
54
|
+
attr_reader :args
|
55
|
+
attr_reader :value
|
56
|
+
|
57
|
+
def invoke( *args, &block )
|
58
|
+
@args = args
|
59
|
+
@value = block.call
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_process_next
|
64
|
+
obj = ProxyObject.new
|
65
|
+
element = Needle::InterceptorChainBuilder::ProxyObjectChainElement.new obj
|
66
|
+
ctx = Context.new( :invoke, [ 1, 2, 3 ], proc { "value" } )
|
67
|
+
element.process_next( ctx )
|
68
|
+
|
69
|
+
assert_equal [ 1, 2, 3 ], obj.args
|
70
|
+
assert_equal "value", obj.value
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
class TC_InterceptorChainBuilder < Test::Unit::TestCase
|
76
|
+
|
77
|
+
class Interceptor
|
78
|
+
def initialize( point, opts, name=nil )
|
79
|
+
@opts = opts
|
80
|
+
@name = name
|
81
|
+
end
|
82
|
+
|
83
|
+
def process( chain, context )
|
84
|
+
@opts[:hash][:chain] << @opts[:name]
|
85
|
+
@opts[:hash][:sym] = context.sym
|
86
|
+
@opts[:hash][:args] = context.args.length
|
87
|
+
@opts[:hash][:has_block] = !context.block.nil?
|
88
|
+
chain.process_next( context )
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def setup
|
93
|
+
@point = OpenStruct.new
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_nil
|
97
|
+
service = Object.new
|
98
|
+
service2 = Needle::InterceptorChainBuilder.build( @point, service, nil )
|
99
|
+
assert_same service, service2
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_none
|
103
|
+
service = Object.new
|
104
|
+
service2 = Needle::InterceptorChainBuilder.build( @point, service, [] )
|
105
|
+
assert_same service, service2
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_one
|
109
|
+
service = Hash.new
|
110
|
+
data = { :chain=>[] }
|
111
|
+
interceptors = [
|
112
|
+
OpenStruct.new( :action=>proc { Interceptor },
|
113
|
+
:options=> { :hash=>data } )
|
114
|
+
]
|
115
|
+
|
116
|
+
service2 = Needle::InterceptorChainBuilder.build( @point, service, interceptors )
|
117
|
+
|
118
|
+
assert_instance_of(
|
119
|
+
Needle::InterceptorChainBuilder::InterceptedServiceProxy, service2 )
|
120
|
+
|
121
|
+
service2.length
|
122
|
+
assert_equal :length, data[:sym]
|
123
|
+
assert_equal 0, data[:args]
|
124
|
+
assert !data[:has_block]
|
125
|
+
|
126
|
+
service2[:hello] = :something
|
127
|
+
assert_equal :[]=, data[:sym]
|
128
|
+
assert_equal 2, data[:args]
|
129
|
+
assert !data[:has_block]
|
130
|
+
|
131
|
+
service2.each_key { |k| }
|
132
|
+
assert_equal :each_key, data[:sym]
|
133
|
+
assert_equal 0, data[:args]
|
134
|
+
assert data[:has_block]
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_many
|
138
|
+
service = Hash.new
|
139
|
+
chain = []
|
140
|
+
data = Array.new( 4 ) { { :chain=>chain } }
|
141
|
+
interceptors = [
|
142
|
+
OpenStruct.new( :action=>proc { Interceptor },
|
143
|
+
:options=>{ :hash=>data[0], :priority=>5, :name=>"A" } ),
|
144
|
+
OpenStruct.new( :action=>proc { Interceptor },
|
145
|
+
:options=>{ :hash=>data[1], :priority=>3, :name=>"B" } ),
|
146
|
+
OpenStruct.new( :action=>proc { Interceptor },
|
147
|
+
:options=>{ :hash=>data[2], :priority=>7, :name=>"C" } ),
|
148
|
+
OpenStruct.new( :action=>proc { Interceptor },
|
149
|
+
:options=>{ :hash=>data[3], :priority=>5, :name=>"D" } )
|
150
|
+
]
|
151
|
+
|
152
|
+
service2 = Needle::InterceptorChainBuilder.build( @point, service, interceptors )
|
153
|
+
expect_chain = [ "B", "A", "D", "C" ]
|
154
|
+
|
155
|
+
service2.length
|
156
|
+
4.times do |i|
|
157
|
+
assert_equal :length, data[i][:sym]
|
158
|
+
assert_equal 0, data[i][:args]
|
159
|
+
assert !data[i][:has_block]
|
160
|
+
end
|
161
|
+
assert_equal expect_chain, chain
|
162
|
+
chain.clear
|
163
|
+
|
164
|
+
service2[:hello] = :something
|
165
|
+
4.times do |i|
|
166
|
+
assert_equal :[]=, data[i][:sym]
|
167
|
+
assert_equal 2, data[i][:args]
|
168
|
+
assert !data[i][:has_block]
|
169
|
+
end
|
170
|
+
assert_equal expect_chain, chain
|
171
|
+
chain.clear
|
172
|
+
|
173
|
+
service2.each_key { |k| }
|
174
|
+
4.times do |i|
|
175
|
+
assert_equal :each_key, data[i][:sym]
|
176
|
+
assert_equal 0, data[i][:args]
|
177
|
+
assert data[i][:has_block]
|
178
|
+
end
|
179
|
+
assert_equal expect_chain, chain
|
180
|
+
end
|
181
|
+
end
|