needle 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|