police-dataflow 0.0.1 → 0.0.2
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.
- checksums.yaml +15 -0
- data/Gemfile +8 -7
- data/Gemfile.lock +57 -18
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/lib/police/dataflow.rb +2 -1
- data/lib/police/dataflow/core_extensions.rb +18 -4
- data/lib/police/dataflow/gate_profiles/ruby1.9.3 +167 -0
- data/lib/police/dataflow/gating.rb +70 -0
- data/lib/police/dataflow/label.rb +19 -14
- data/lib/police/dataflow/labeling.rb +103 -22
- data/lib/police/dataflow/proxies.rb +33 -5
- data/lib/police/dataflow/proxy_base.rb +80 -40
- data/lib/police/dataflow/proxy_numeric.rb +22 -0
- data/lib/police/dataflow/proxying.rb +215 -40
- data/police-dataflow.gemspec +11 -15
- data/tasks/info.rake +43 -0
- data/test/dataflow/core_extensions_test.rb +8 -8
- data/test/dataflow/labeling_test.rb +324 -15
- data/test/dataflow/proxies_test.rb +7 -11
- data/test/dataflow/proxy_base_test.rb +199 -72
- data/test/dataflow/proxy_numeric_test.rb +45 -0
- data/test/dataflow/proxying_test.rb +333 -80
- data/test/helper.rb +2 -2
- data/test/helpers/hooks_flow_fixture.rb +22 -0
- data/test/helpers/no_flow_fixture.rb +4 -4
- data/test/helpers/proxying_fixture.rb +11 -7
- data/test/helpers/sticky_fixture.rb +14 -0
- metadata +12 -12
- data/lib/police/dataflow/guarding.rb +0 -16
- data/test/helpers/auto_flow_fixture.rb +0 -6
@@ -2,144 +2,271 @@ require File.expand_path('../helper.rb', File.dirname(__FILE__))
|
|
2
2
|
|
3
3
|
describe Police::DataFlow::ProxyBase do
|
4
4
|
before do
|
5
|
-
|
6
|
-
|
7
|
-
@
|
8
|
-
|
9
|
-
|
5
|
+
Police::DataFlow::Proxies.clear_cache
|
6
|
+
|
7
|
+
@sticky_label = StickyFixture.new
|
8
|
+
@hook_label = HooksFlowFixture.new
|
9
|
+
|
10
10
|
@proxied = ProxyingFixture.new
|
11
|
-
|
12
|
-
@
|
11
|
+
|
12
|
+
@sticky_label_set = {}
|
13
|
+
Police::DataFlow::Labeling.add_label_to_set @sticky_label,
|
14
|
+
@sticky_label_set
|
15
|
+
@sticky_proxy_class = ::Police::DataFlow::Proxies.for ProxyingFixture,
|
16
|
+
@sticky_label_set
|
17
|
+
@sticky_proxy = @sticky_proxy_class.new @proxied, @sticky_proxy_class,
|
18
|
+
@sticky_label_set
|
19
|
+
|
20
|
+
@hook_label_set = {}
|
21
|
+
Police::DataFlow::Labeling.add_label_to_set @hook_label, @hook_label_set
|
22
|
+
@hook_proxy_class = ::Police::DataFlow::Proxies.for ProxyingFixture,
|
23
|
+
@hook_label_set
|
24
|
+
@hook_proxy = @hook_proxy_class.new @proxied, @hook_proxy_class,
|
25
|
+
@hook_label_set
|
13
26
|
end
|
14
27
|
after { Police::DataFlow::Proxies.clear_cache }
|
15
|
-
|
16
|
-
it 'proxies public methods' do
|
17
|
-
# NOTE: this test exercises the
|
18
|
-
@
|
28
|
+
|
29
|
+
it 'proxies public methods through sticky labels' do
|
30
|
+
# NOTE: this test exercises the define-and-call path in method_missing
|
31
|
+
@sticky_proxy.route('One', 'Two').must_equal ['One', 'Two']
|
19
32
|
end
|
20
|
-
|
21
|
-
it '
|
22
|
-
# NOTE: this test exercises the
|
23
|
-
|
33
|
+
|
34
|
+
it 'proxies public methods through hook labels' do
|
35
|
+
# NOTE: this test exercises the define-and-call path in method_missing
|
36
|
+
@hook_proxy.route('One', 'Two').must_equal ['One', 'Two']
|
24
37
|
end
|
25
|
-
|
38
|
+
|
39
|
+
it 'allows labels to stick to the return value of public methods' do
|
40
|
+
# NOTE: this test exercises the define-and-call path in method_missing
|
41
|
+
Police::DataFlow.labels(@sticky_proxy.route('One', 'Two')).must_equal(
|
42
|
+
[@sticky_label])
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'allows labels to hook into the return value of public methods' do
|
46
|
+
# NOTE: this test exercises the define-and-call path in method_missing
|
47
|
+
Police::DataFlow.labels(@hook_proxy.route('One', 'Two')).must_equal(
|
48
|
+
[@hook_label])
|
49
|
+
end
|
50
|
+
|
26
51
|
describe 'after proxying public methods' do
|
27
|
-
before
|
28
|
-
|
52
|
+
before do
|
53
|
+
@sticky_proxy.route 'One', 'Two'
|
54
|
+
@hook_proxy.route 'One', 'Two'
|
55
|
+
end
|
56
|
+
|
29
57
|
it 'defines proxied methods on the fly' do
|
30
|
-
@
|
31
|
-
@
|
58
|
+
@sticky_proxy_class.public_method_defined?(:route).must_equal true
|
59
|
+
@sticky_proxy_class.instance_method(:route).owner.must_equal(
|
60
|
+
@sticky_proxy_class)
|
61
|
+
@hook_proxy_class.public_method_defined?(:route).must_equal true
|
62
|
+
@hook_proxy_class.instance_method(:route).owner.must_equal(
|
63
|
+
@hook_proxy_class)
|
32
64
|
end
|
33
65
|
|
34
66
|
it 'still proxies public methods' do
|
35
67
|
# NOTE: this test exercises the auto-generated proxy method's fast path
|
36
|
-
@
|
68
|
+
@sticky_proxy.route('One', 'Two').must_equal ['One', 'Two']
|
69
|
+
@hook_proxy.route('One', 'Two').must_equal ['One', 'Two']
|
37
70
|
end
|
38
|
-
|
39
|
-
it 'still allows labels to
|
71
|
+
|
72
|
+
it 'still allows labels to stick to the return value of methods' do
|
73
|
+
# NOTE: this test exercises the auto-generated proxy method's fast path
|
74
|
+
Police::DataFlow.labels(@sticky_proxy.route('One', 'Two')).must_equal(
|
75
|
+
[@sticky_label])
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'still allows labels to hook into the return value of methods' do
|
40
79
|
# NOTE: this test exercises the auto-generated proxy method's fast path
|
41
|
-
Police::DataFlow.labels(@
|
80
|
+
Police::DataFlow.labels(@hook_proxy.route('One', 'Two')).must_equal(
|
81
|
+
[@hook_label])
|
42
82
|
end
|
43
83
|
|
44
84
|
it 'can still build proxies' do
|
45
|
-
|
46
|
-
@
|
47
|
-
|
85
|
+
other_sticky_proxy = @sticky_proxy_class.new ProxyingFixture.new,
|
86
|
+
@proxy_class, @sticky_label_set
|
87
|
+
other_sticky_proxy.route('One', 'Two').must_equal ['One', 'Two']
|
88
|
+
|
89
|
+
other_hook_proxy = @hook_proxy_class.new ProxyingFixture.new,
|
90
|
+
@proxy_class, @hook_label_set
|
91
|
+
other_hook_proxy.route('One', 'Two').must_equal ['One', 'Two']
|
48
92
|
end
|
49
93
|
end
|
50
|
-
|
51
|
-
it 'proxies public methods with blocks' do
|
94
|
+
|
95
|
+
it 'proxies public methods with blocks through sticky labels' do
|
52
96
|
# NOTE: this test exercises the slow path in method_missing
|
53
97
|
result = []
|
54
|
-
@
|
98
|
+
@sticky_proxy.route('One', 'Two') { |*args| result << args }
|
55
99
|
result.must_equal [['One', 'Two']]
|
56
100
|
end
|
57
|
-
|
58
|
-
it '
|
101
|
+
|
102
|
+
it 'proxies public methods with blocks through hook labels' do
|
103
|
+
result = []
|
104
|
+
@hook_proxy.route('One', 'Two') { |*args| result << args }
|
105
|
+
result.must_equal [['One', 'Two']]
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'allows labels to stick to the yielded values of public methods' do
|
109
|
+
# NOTE: this test exercises the slow path in method_missing
|
110
|
+
@sticky_proxy.route('One', 'Two') do |*args|
|
111
|
+
args.each do |arg|
|
112
|
+
Police::DataFlow.labels(arg).must_equal [@sticky_label]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'allows labels to hook into the yielded values of public methods' do
|
59
118
|
# NOTE: this test exercises the slow path in method_missing
|
60
|
-
@
|
61
|
-
args.each { |arg| Police::DataFlow.labels(arg).must_equal [@
|
119
|
+
@hook_proxy.route('One', 'Two') do |*args|
|
120
|
+
args.each { |arg| Police::DataFlow.labels(arg).must_equal [@hook_label] }
|
62
121
|
end
|
63
122
|
end
|
64
123
|
|
65
124
|
describe 'after proxying public methods with blocks' do
|
66
|
-
before
|
67
|
-
|
125
|
+
before do
|
126
|
+
@sticky_proxy.route('One', 'Two') { |*args| }
|
127
|
+
@hook_proxy.route('One', 'Two') { |*args| }
|
128
|
+
end
|
129
|
+
|
68
130
|
it 'defines proxied methods on the fly' do
|
69
|
-
@
|
70
|
-
@
|
131
|
+
@sticky_proxy_class.public_method_defined?(:route).must_equal true
|
132
|
+
@sticky_proxy_class.instance_method(:route).owner.must_equal(
|
133
|
+
@sticky_proxy_class)
|
134
|
+
@hook_proxy_class.public_method_defined?(:route).must_equal true
|
135
|
+
@hook_proxy_class.instance_method(:route).owner.must_equal(
|
136
|
+
@hook_proxy_class)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'still proxies public methods with blocks through sticky labels' do
|
140
|
+
# NOTE: this test exercises the auto-generated proxy method's fast path
|
141
|
+
result = []
|
142
|
+
@sticky_proxy.route('One', 'Two') { |*args| result << args }
|
143
|
+
result.must_equal [['One', 'Two']]
|
71
144
|
end
|
72
145
|
|
73
|
-
it 'still proxies public methods with blocks' do
|
146
|
+
it 'still proxies public methods with blocks through hook labels' do
|
74
147
|
# NOTE: this test exercises the auto-generated proxy method's fast path
|
75
148
|
result = []
|
76
|
-
@
|
149
|
+
@hook_proxy.route('One', 'Two') { |*args| result << args }
|
77
150
|
result.must_equal [['One', 'Two']]
|
78
151
|
end
|
79
152
|
|
80
|
-
it 'still allows labels to
|
153
|
+
it 'still allows labels to stick to the yielded values of methods' do
|
154
|
+
# NOTE: this test exercises the auto-generated proxy method's fast path
|
155
|
+
@hook_proxy.route('One', 'Two') do |*args|
|
156
|
+
args.each do |arg|
|
157
|
+
Police::DataFlow.labels(arg).must_equal [@hook_label]
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'still allows labels to hook into the yielded values of methods' do
|
81
163
|
# NOTE: this test exercises the auto-generated proxy method's fast path
|
82
|
-
@
|
83
|
-
args.each
|
164
|
+
@hook_proxy.route('One', 'Two') do |*args|
|
165
|
+
args.each do |arg|
|
166
|
+
Police::DataFlow.labels(arg).must_equal [@hook_label]
|
167
|
+
end
|
84
168
|
end
|
85
169
|
end
|
86
|
-
end
|
170
|
+
end
|
87
171
|
|
88
172
|
it 'proxies protected methods' do
|
89
173
|
# NOTE: this test exercises the slow path in method_missing
|
90
|
-
@
|
174
|
+
@sticky_proxy.__send__(:add, 'One', 'Two').must_equal 'One, Two'
|
175
|
+
@hook_proxy.__send__(:add, 'One', 'Two').must_equal 'One, Two'
|
91
176
|
end
|
92
177
|
|
93
|
-
it 'allows labels to
|
178
|
+
it 'allows labels to hook into the return value of protected methods' do
|
94
179
|
# NOTE: this test exercises the slow path in method_missing
|
95
|
-
Police::DataFlow.labels(@
|
96
|
-
must_equal [@
|
180
|
+
Police::DataFlow.labels(@sticky_proxy.__send__(:add, 'One', 'Two')).
|
181
|
+
must_equal [@sticky_label]
|
97
182
|
end
|
98
|
-
|
99
|
-
|
183
|
+
|
184
|
+
it 'allows labels to hook into the return value of protected methods' do
|
185
|
+
# NOTE: this test exercises the slow path in method_missing
|
186
|
+
Police::DataFlow.labels(@hook_proxy.__send__(:add, 'One', 'Two')).
|
187
|
+
must_equal [@hook_label]
|
188
|
+
end
|
189
|
+
|
100
190
|
describe 'after proxying protected methods' do
|
101
|
-
before
|
102
|
-
|
191
|
+
before do
|
192
|
+
@sticky_proxy.__send__ :add, 'One', 'Two'
|
193
|
+
@hook_proxy.__send__ :add, 'One', 'Two'
|
194
|
+
end
|
195
|
+
|
103
196
|
it 'defines proxied methods on the fly' do
|
104
|
-
@
|
105
|
-
@
|
197
|
+
@sticky_proxy_class.protected_method_defined?(:add).must_equal true
|
198
|
+
@sticky_proxy_class.instance_method(:add).owner.must_equal(
|
199
|
+
@sticky_proxy_class)
|
200
|
+
@hook_proxy_class.protected_method_defined?(:add).must_equal true
|
201
|
+
@hook_proxy_class.instance_method(:add).owner.must_equal(
|
202
|
+
@hook_proxy_class)
|
106
203
|
end
|
107
204
|
|
108
205
|
it 'still proxies protected methods' do
|
109
206
|
# NOTE: this test exercises the auto-generated proxy method's fast path
|
110
|
-
@
|
207
|
+
@sticky_proxy.__send__(:add, 'One', 'Two').must_equal 'One, Two'
|
208
|
+
@hook_proxy.__send__(:add, 'One', 'Two').must_equal 'One, Two'
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'still allows labels to sticky into protected methods' do
|
212
|
+
Police::DataFlow.labels(@sticky_proxy.__send__(:add, 'One', 'Two')).
|
213
|
+
must_equal [@sticky_label]
|
111
214
|
end
|
112
215
|
|
113
|
-
it 'still allows labels to
|
216
|
+
it 'still allows labels to hook into protected methods' do
|
114
217
|
# NOTE: this test exercises the auto-generated proxy method's fast path
|
115
|
-
Police::DataFlow.labels(@
|
116
|
-
must_equal [@
|
218
|
+
Police::DataFlow.labels(@hook_proxy.__send__(:add, 'One', 'Two')).
|
219
|
+
must_equal [@hook_label]
|
117
220
|
end
|
118
221
|
end
|
119
|
-
|
120
|
-
it 'proxies
|
121
|
-
|
222
|
+
|
223
|
+
it 'proxies method_missing methods' do
|
224
|
+
# NOTE: this test exercises the method_missing+send slow proxying path.
|
225
|
+
@sticky_proxy.magic_meth('One', 'Two').must_equal ['meth', 'One', 'Two']
|
226
|
+
@hook_proxy.magic_meth('One', 'Two').must_equal ['meth', 'One', 'Two']
|
122
227
|
end
|
123
228
|
|
124
|
-
it '
|
125
|
-
|
229
|
+
it 'proxies method_missing methods with blocks' do
|
230
|
+
# NOTE: this test exercises the method_missing+send slow proxying path.
|
231
|
+
@sticky_proxy.magic_meth('One', 'Two') { |*args|
|
232
|
+
args.must_equal ['One', 'Two']
|
233
|
+
args
|
234
|
+
}.must_equal ['meth', ['One', 'Two']]
|
235
|
+
@hook_proxy.magic_meth('One', 'Two') { |*args|
|
236
|
+
args.must_equal ['One', 'Two']
|
237
|
+
args
|
238
|
+
}.must_equal ['meth', ['One', 'Two']]
|
126
239
|
end
|
127
240
|
|
128
|
-
|
241
|
+
it 'allows labels to stick to method_missing methods return values' do
|
242
|
+
Police::DataFlow.labels(@sticky_proxy.magic_meth('One', 'Two')).
|
243
|
+
must_equal [@sticky_label]
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'allows labels to hook into method_missing methods' do
|
247
|
+
Police::DataFlow.labels(@hook_proxy.magic_meth('One', 'Two')).
|
248
|
+
must_equal [@hook_label]
|
249
|
+
end
|
250
|
+
|
251
|
+
describe 'after proxying method_missing methods' do
|
129
252
|
before do
|
130
|
-
@
|
253
|
+
@sticky_proxy.magic_meth 'One', 'Two'
|
254
|
+
@hook_proxy.magic_meth 'One', 'Two'
|
131
255
|
end
|
132
256
|
|
133
|
-
it 'does not define
|
134
|
-
@
|
135
|
-
|
257
|
+
it 'does not define proxied methods' do
|
258
|
+
@sticky_proxy_class.public_method_defined?(:magic_meth).must_equal false
|
259
|
+
@hook_proxy_class.public_method_defined?(:magic_meth).must_equal false
|
260
|
+
end
|
136
261
|
end
|
137
|
-
|
262
|
+
|
138
263
|
it 'proxies ==' do
|
139
|
-
(@
|
264
|
+
(@sticky_proxy == nil).must_equal '== proxied'
|
265
|
+
(@hook_proxy == nil).must_equal '== proxied'
|
140
266
|
end
|
141
267
|
|
142
268
|
it 'proxies !=' do
|
143
|
-
(@
|
144
|
-
|
269
|
+
(@sticky_proxy != nil).must_equal '!= proxied'
|
270
|
+
(@hook_proxy != nil).must_equal '!= proxied'
|
271
|
+
end
|
145
272
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path('../helper.rb', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe Police::DataFlow::ProxyNumeric do
|
4
|
+
before do
|
5
|
+
Police::DataFlow::Proxies.clear_cache
|
6
|
+
@label = StickyFixture.new
|
7
|
+
@label_set = {}
|
8
|
+
Police::DataFlow::Labeling.add_label_to_set @label, @label_set
|
9
|
+
@proxied = 21
|
10
|
+
@proxy_class = Police::DataFlow::Proxies.for @proxied.class, @label_set
|
11
|
+
@proxy = @proxy_class.new @proxied, @proxy_class, @label_set
|
12
|
+
end
|
13
|
+
after { Police::DataFlow::Proxies.clear_cache }
|
14
|
+
|
15
|
+
it 'defines coerce' do
|
16
|
+
@proxy_class.instance_methods.must_include :coerce
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns a two-element Array from coerce' do
|
20
|
+
coerced = @proxy.coerce 42
|
21
|
+
coerced.class.must_equal Array
|
22
|
+
coerced.length.must_equal 2
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'proxies the argument when coercing' do
|
26
|
+
coerced = @proxy.coerce 42
|
27
|
+
coerced[0].must_equal 42
|
28
|
+
coerced[0].__id__.wont_equal 42.__id__
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns self correctly when coercing' do
|
32
|
+
coerced = @proxy.coerce 42
|
33
|
+
coerced[1].__id__.must_equal @proxy.__id__
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'does not double-proxy' do
|
37
|
+
@proxied2 = 22
|
38
|
+
@proxy2 = @proxy_class.new @proxied2, @proxy_class, @label_set
|
39
|
+
coerced = @proxy.coerce @proxy2
|
40
|
+
coerced[0].__id__.must_equal @proxy2.__id__
|
41
|
+
coerced[1].__id__.must_equal @proxy.__id__
|
42
|
+
coerced.class.must_equal Array
|
43
|
+
coerced.length.must_equal 2
|
44
|
+
end
|
45
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.expand_path('../helper.rb', File.dirname(__FILE__))
|
2
2
|
|
3
3
|
describe Police::DataFlow::Proxying do
|
4
|
-
describe '#
|
4
|
+
describe '#add_instance_methods' do
|
5
5
|
before do
|
6
6
|
@proxy_class = Class.new BasicObject do
|
7
7
|
def self.__police_classes__
|
@@ -13,9 +13,10 @@ describe Police::DataFlow::Proxying do
|
|
13
13
|
@proxy = @proxy_class.new
|
14
14
|
@proxy.instance_exec(@proxied) { |p| @__police_proxied__ = p }
|
15
15
|
|
16
|
-
Police::DataFlow::Proxying.
|
16
|
+
Police::DataFlow::Proxying.add_instance_methods @proxy_class,
|
17
|
+
ProxyingFixture
|
17
18
|
end
|
18
|
-
|
19
|
+
|
19
20
|
it 'adds public methods' do
|
20
21
|
@proxy_class.public_method_defined?(:length).must_equal true
|
21
22
|
@proxy_class.public_method_defined?(:==).must_equal true
|
@@ -25,13 +26,13 @@ describe Police::DataFlow::Proxying do
|
|
25
26
|
it 'adds a protected method' do
|
26
27
|
@proxy_class.protected_method_defined?(:add).must_equal true
|
27
28
|
end
|
28
|
-
|
29
|
+
|
29
30
|
it 'adds a private method' do
|
30
31
|
@proxy_class.private_method_defined?(:log).must_equal true
|
31
32
|
end
|
32
33
|
end
|
33
|
-
|
34
|
-
describe '#
|
34
|
+
|
35
|
+
describe '#add_instance_method' do
|
35
36
|
before do
|
36
37
|
@proxy_class = Class.new BasicObject do
|
37
38
|
def self.__police_classes__
|
@@ -42,42 +43,42 @@ describe Police::DataFlow::Proxying do
|
|
42
43
|
@proxy = @proxy_class.new
|
43
44
|
@proxy.instance_exec(@proxied) { |p| @__police_proxied__ = p }
|
44
45
|
end
|
45
|
-
|
46
|
+
|
46
47
|
describe 'with protected method with arguments' do
|
47
48
|
before do
|
48
49
|
@method = ProxyingFixture.instance_method :add
|
49
|
-
Police::DataFlow::Proxying.
|
50
|
-
|
50
|
+
Police::DataFlow::Proxying.add_instance_method @proxy_class, @method,
|
51
|
+
:protected
|
51
52
|
end
|
52
|
-
|
53
|
+
|
53
54
|
it 'defines the proxying method' do
|
54
|
-
@proxy_class.protected_method_defined?(:add).must_equal true
|
55
|
+
@proxy_class.protected_method_defined?(:add).must_equal true
|
55
56
|
end
|
56
|
-
|
57
|
+
|
57
58
|
it "has the proxying method's arity match the original" do
|
58
|
-
@proxy_class.instance_method(:add).arity.must_equal @method.arity
|
59
|
+
@proxy_class.instance_method(:add).arity.must_equal @method.arity
|
59
60
|
end
|
60
|
-
|
61
|
+
|
61
62
|
it 'proxies the method' do
|
62
63
|
@proxy.__send__(:add, 'One', 'Two').must_equal 'One, Two'
|
63
64
|
end
|
64
65
|
end
|
65
|
-
|
66
|
+
|
66
67
|
describe 'with public method with variable arguments and blocks' do
|
67
68
|
before do
|
68
69
|
@method = ProxyingFixture.instance_method :route
|
69
|
-
Police::DataFlow::Proxying.
|
70
|
-
|
70
|
+
Police::DataFlow::Proxying.add_instance_method @proxy_class, @method,
|
71
|
+
:public
|
71
72
|
end
|
72
|
-
|
73
|
+
|
73
74
|
it 'defines the proxying method' do
|
74
|
-
@proxy_class.public_method_defined?(:route).must_equal true
|
75
|
+
@proxy_class.public_method_defined?(:route).must_equal true
|
75
76
|
end
|
76
|
-
|
77
|
+
|
77
78
|
it "has the proxying method's arity match the original" do
|
78
|
-
@proxy_class.instance_method(:route).arity.must_equal @method.arity
|
79
|
+
@proxy_class.instance_method(:route).arity.must_equal @method.arity
|
79
80
|
end
|
80
|
-
|
81
|
+
|
81
82
|
it 'proxies the method without a block' do
|
82
83
|
@proxy.route('One', 'Two').must_equal ['One', 'Two']
|
83
84
|
end
|
@@ -90,124 +91,171 @@ describe Police::DataFlow::Proxying do
|
|
90
91
|
end
|
91
92
|
|
92
93
|
it 'proxies protected methods' do
|
93
|
-
Police::DataFlow::Proxying.
|
94
|
+
Police::DataFlow::Proxying.add_instance_method @proxy_class,
|
94
95
|
ProxyingFixture.instance_method(:add), :protected
|
95
96
|
@proxy_class.protected_method_defined?(:add).must_equal true
|
96
97
|
@proxy.__send__(:add, 'One', 'Two').must_equal 'One, Two'
|
97
98
|
end
|
98
99
|
end
|
99
|
-
|
100
|
+
|
100
101
|
describe '#proxy_method_definition' do
|
101
102
|
it 'returns a non-empty string for a public method' do
|
102
|
-
Police::DataFlow::Proxying.proxy_method_definition([
|
103
|
+
Police::DataFlow::Proxying.proxy_method_definition([StickyFixture],
|
103
104
|
ProxyingFixture.instance_method(:length), :public).length.wont_equal 0
|
104
105
|
end
|
105
106
|
|
106
107
|
it 'returns a non-empty string for a private method' do
|
107
|
-
Police::DataFlow::Proxying.proxy_method_definition([
|
108
|
+
Police::DataFlow::Proxying.proxy_method_definition([StickyFixture],
|
108
109
|
ProxyingFixture.instance_method(:length), :private).length.
|
109
110
|
wont_equal 0
|
110
111
|
end
|
111
|
-
|
112
|
+
|
112
113
|
# NOTE: testing the actual behavior would just duplicate the tests for
|
113
|
-
#
|
114
|
+
# add_instance_method
|
114
115
|
end
|
115
|
-
|
116
|
+
|
116
117
|
describe '#proxy_method_call' do
|
117
|
-
it 'works for a public method
|
118
|
+
it 'works for a public method' do
|
118
119
|
Police::DataFlow::Proxying.proxy_method_call(
|
119
|
-
ProxyingFixture.instance_method(:length), :public
|
120
|
+
ProxyingFixture.instance_method(:length), :public).
|
120
121
|
must_equal '@__police_proxied__.length()'
|
121
122
|
end
|
122
123
|
|
123
|
-
it 'works for a protected method
|
124
|
+
it 'works for a protected method' do
|
124
125
|
Police::DataFlow::Proxying.proxy_method_call(
|
125
|
-
ProxyingFixture.instance_method(:add), :protected
|
126
|
+
ProxyingFixture.instance_method(:add), :protected).
|
126
127
|
must_equal '@__police_proxied__.__send__(:add, arg1, arg2)'
|
127
128
|
end
|
128
129
|
|
129
|
-
it 'works for a
|
130
|
-
Police::DataFlow::Proxying.proxy_method_call(
|
131
|
-
ProxyingFixture.instance_method(:length), :public, true).
|
132
|
-
must_equal '@__police_proxied__.length(&block)'
|
133
|
-
end
|
134
|
-
|
135
|
-
it 'works for a private method with a block' do
|
130
|
+
it 'works for a private method' do
|
136
131
|
Police::DataFlow::Proxying.proxy_method_call(
|
137
|
-
ProxyingFixture.instance_method(:length), :private
|
138
|
-
must_equal '@__police_proxied__.__send__(:length
|
132
|
+
ProxyingFixture.instance_method(:length), :private).
|
133
|
+
must_equal '@__police_proxied__.__send__(:length)'
|
139
134
|
end
|
140
135
|
|
141
|
-
it 'works for a private method with arguments
|
136
|
+
it 'works for a private method with arguments' do
|
142
137
|
Police::DataFlow::Proxying.proxy_method_call(
|
143
|
-
ProxyingFixture.instance_method(:log), :private
|
144
|
-
'@__police_proxied__.__send__(:log, arg1, arg2, *args
|
138
|
+
ProxyingFixture.instance_method(:log), :private).must_equal(
|
139
|
+
'@__police_proxied__.__send__(:log, arg1, arg2, *args)')
|
145
140
|
end
|
146
141
|
end
|
147
|
-
|
142
|
+
|
148
143
|
describe '#proxy_yield_args_decorating' do
|
149
144
|
let(:method) { ProxyingFixture.instance_method(:add) }
|
150
|
-
|
151
|
-
it 'is empty if no label class is
|
145
|
+
|
146
|
+
it 'is empty if no label class is hooking or auto-flowing' do
|
152
147
|
Police::DataFlow::Proxying.proxy_yield_args_decorating([NoFlowFixture],
|
153
148
|
method).must_equal ''
|
154
149
|
end
|
155
|
-
|
156
|
-
it 'works for one
|
150
|
+
|
151
|
+
it 'works for one hooking label class' do
|
152
|
+
label2_class = Class.new BasicObject do
|
153
|
+
def self.yield_args_hook(method_name)
|
154
|
+
raise RuntimeError, 'Wrong method name' unless method_name == :add
|
155
|
+
:add_yield_args_hook
|
156
|
+
end
|
157
|
+
def self.sticky?
|
158
|
+
raise RuntimeError, 'sticky? should not be called'
|
159
|
+
end
|
160
|
+
end
|
161
|
+
golden = 'labels = @__police_labels__; ' \
|
162
|
+
"labels[#{label2_class.__id__}].each { |label, _| " \
|
163
|
+
"label.add_yield_args_hook(self, yield_args, arg1, arg2) }"
|
164
|
+
Police::DataFlow::Proxying.proxy_yield_args_decorating(
|
165
|
+
[NoFlowFixture, label2_class], method).must_equal golden
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'works for one sticky label class' do
|
169
|
+
label2_class = Class.new BasicObject do
|
170
|
+
def self.yield_args_hook(method_name)
|
171
|
+
raise RuntimeError, 'Wrong method name' unless method_name == :add
|
172
|
+
nil
|
173
|
+
end
|
174
|
+
def self.sticky?
|
175
|
+
true
|
176
|
+
end
|
177
|
+
end
|
157
178
|
golden = 'labels = @__police_labels__; ' \
|
158
|
-
"labels[#{
|
159
|
-
"
|
179
|
+
"labels[#{label2_class.__id__}].each { |label, _| " \
|
180
|
+
"yield_args.map! { |arg| ::Police::DataFlow.label(arg, label) } " \
|
181
|
+
"}"
|
160
182
|
Police::DataFlow::Proxying.proxy_yield_args_decorating(
|
161
|
-
[NoFlowFixture,
|
183
|
+
[NoFlowFixture, label2_class], method).must_equal golden
|
162
184
|
end
|
163
185
|
|
164
|
-
it 'works for two
|
186
|
+
it 'works for two hooking label classes' do
|
165
187
|
label2_class = Class.new BasicObject do
|
166
188
|
def self.yield_args_hook(method_name)
|
167
189
|
:"#{method_name}_ah"
|
168
190
|
end
|
169
191
|
end
|
170
192
|
golden = 'labels = @__police_labels__; ' \
|
171
|
-
"labels[#{
|
172
|
-
"label.
|
193
|
+
"labels[#{HooksFlowFixture.__id__}].each { |label, _| " \
|
194
|
+
"label.generic_yield_args_hook(self, yield_args, arg1, arg2) }; " \
|
173
195
|
"labels[#{label2_class.__id__}].each { |label, _| " \
|
174
196
|
"label.add_ah(self, yield_args, arg1, arg2) }"
|
175
197
|
Police::DataFlow::Proxying.proxy_yield_args_decorating([NoFlowFixture,
|
176
|
-
|
198
|
+
HooksFlowFixture, label2_class], method).must_equal golden
|
177
199
|
end
|
178
200
|
end
|
179
201
|
|
180
202
|
describe '#proxy_return_decorating' do
|
181
203
|
let(:method) { ProxyingFixture.instance_method(:add) }
|
182
|
-
|
183
|
-
it 'is empty if no label class is
|
204
|
+
|
205
|
+
it 'is empty if no label class is hooking or auto-flowing' do
|
184
206
|
Police::DataFlow::Proxying.proxy_return_decorating([NoFlowFixture],
|
185
207
|
method).must_equal ''
|
186
208
|
end
|
187
|
-
|
188
|
-
it 'works for one
|
209
|
+
|
210
|
+
it 'works for one hooking label class' do
|
211
|
+
label2_class = Class.new BasicObject do
|
212
|
+
def self.return_hook(method_name)
|
213
|
+
raise RuntimeError, 'Wrong method name' unless method_name == :add
|
214
|
+
'add_return_hook'
|
215
|
+
end
|
216
|
+
def self.sticky?(method_name)
|
217
|
+
raise RuntimeError, 'sticky? should not be called'
|
218
|
+
end
|
219
|
+
end
|
220
|
+
golden = 'labels = @__police_labels__; ' \
|
221
|
+
"labels[#{label2_class.__id__}].each { |label, _| " \
|
222
|
+
"return_value = label.add_return_hook(return_value, self, arg1, " \
|
223
|
+
"arg2) }"
|
224
|
+
Police::DataFlow::Proxying.proxy_return_decorating(
|
225
|
+
[NoFlowFixture, label2_class], method).must_equal golden
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'works for one sticky label class' do
|
229
|
+
label2_class = Class.new BasicObject do
|
230
|
+
def self.return_hook(method_name)
|
231
|
+
raise RuntimeError, 'Wrong method name' unless method_name == :add
|
232
|
+
nil
|
233
|
+
end
|
234
|
+
def self.sticky?
|
235
|
+
true
|
236
|
+
end
|
237
|
+
end
|
189
238
|
golden = 'labels = @__police_labels__; ' \
|
190
|
-
"labels[#{
|
191
|
-
"return_value = label
|
192
|
-
"arg2) }"
|
239
|
+
"labels[#{label2_class.__id__}].each { |label, _| " \
|
240
|
+
"return_value = ::Police::DataFlow.label(return_value, label) }"
|
193
241
|
Police::DataFlow::Proxying.proxy_return_decorating(
|
194
|
-
[NoFlowFixture,
|
242
|
+
[NoFlowFixture, label2_class], method).must_equal golden
|
195
243
|
end
|
196
244
|
|
197
|
-
it 'works for two
|
245
|
+
it 'works for two hooking label classes' do
|
198
246
|
label2_class = Class.new BasicObject do
|
199
247
|
def self.return_hook(method_name)
|
200
248
|
:"#{method_name}_rh"
|
201
249
|
end
|
202
250
|
end
|
203
251
|
golden = 'labels = @__police_labels__; ' \
|
204
|
-
"labels[#{
|
205
|
-
"return_value = label.
|
206
|
-
|
252
|
+
"labels[#{HooksFlowFixture.__id__}].each { |label, _| " \
|
253
|
+
"return_value = label.generic_return_hook(return_value, self, "\
|
254
|
+
"arg1, arg2) }; " \
|
207
255
|
"labels[#{label2_class.__id__}].each { |label, _| " \
|
208
256
|
"return_value = label.add_rh(return_value, self, arg1, arg2) }"
|
209
257
|
Police::DataFlow::Proxying.proxy_return_decorating([NoFlowFixture,
|
210
|
-
|
258
|
+
HooksFlowFixture, label2_class], method).must_equal golden
|
211
259
|
end
|
212
260
|
end
|
213
261
|
|
@@ -217,29 +265,29 @@ describe Police::DataFlow::Proxying do
|
|
217
265
|
Police::DataFlow::Proxying.proxy_argument_list(
|
218
266
|
ProxyingFixture.instance_method(:length), false).must_equal ''
|
219
267
|
end
|
220
|
-
|
268
|
+
|
221
269
|
it 'works for a one-argument method' do
|
222
270
|
Police::DataFlow::Proxying.proxy_argument_list(
|
223
271
|
ProxyingFixture.instance_method(:==), false).must_equal 'arg1'
|
224
272
|
end
|
225
|
-
|
273
|
+
|
226
274
|
it 'works for a two-argument method' do
|
227
275
|
Police::DataFlow::Proxying.proxy_argument_list(
|
228
276
|
ProxyingFixture.instance_method(:add), false).
|
229
277
|
must_equal 'arg1, arg2'
|
230
278
|
end
|
231
|
-
|
279
|
+
|
232
280
|
it 'works for a variable-argument method' do
|
233
281
|
Police::DataFlow::Proxying.proxy_argument_list(
|
234
282
|
ProxyingFixture.instance_method(:route), false).must_equal '*args'
|
235
283
|
end
|
236
|
-
|
284
|
+
|
237
285
|
it 'works for one fixed + variable-argument method' do
|
238
286
|
Police::DataFlow::Proxying.proxy_argument_list(
|
239
287
|
ProxyingFixture.instance_method(:<=>), false).
|
240
288
|
must_equal 'arg1, *args'
|
241
289
|
end
|
242
|
-
|
290
|
+
|
243
291
|
it 'works for two fixed + variable-argument method' do
|
244
292
|
Police::DataFlow::Proxying.proxy_argument_list(
|
245
293
|
ProxyingFixture.instance_method(:log), false).
|
@@ -252,31 +300,31 @@ describe Police::DataFlow::Proxying do
|
|
252
300
|
Police::DataFlow::Proxying.proxy_argument_list(
|
253
301
|
ProxyingFixture.instance_method(:length), true).must_equal '&block'
|
254
302
|
end
|
255
|
-
|
303
|
+
|
256
304
|
it 'works for a one-argument method' do
|
257
305
|
Police::DataFlow::Proxying.proxy_argument_list(
|
258
306
|
ProxyingFixture.instance_method(:==), true).
|
259
307
|
must_equal 'arg1, &block'
|
260
308
|
end
|
261
|
-
|
309
|
+
|
262
310
|
it 'works for a two-argument method' do
|
263
311
|
Police::DataFlow::Proxying.proxy_argument_list(
|
264
312
|
ProxyingFixture.instance_method(:add), true).
|
265
313
|
must_equal 'arg1, arg2, &block'
|
266
314
|
end
|
267
|
-
|
315
|
+
|
268
316
|
it 'works for a variable-argument method' do
|
269
317
|
Police::DataFlow::Proxying.proxy_argument_list(
|
270
318
|
ProxyingFixture.instance_method(:route), true).
|
271
319
|
must_equal '*args, &block'
|
272
320
|
end
|
273
|
-
|
321
|
+
|
274
322
|
it 'works for one fixed + variable-argument method' do
|
275
323
|
Police::DataFlow::Proxying.proxy_argument_list(
|
276
324
|
ProxyingFixture.instance_method(:<=>), true).
|
277
325
|
must_equal 'arg1, *args, &block'
|
278
326
|
end
|
279
|
-
|
327
|
+
|
280
328
|
it 'works for two fixed + variable-argument method' do
|
281
329
|
Police::DataFlow::Proxying.proxy_argument_list(
|
282
330
|
ProxyingFixture.instance_method(:log), true).
|
@@ -284,4 +332,209 @@ describe Police::DataFlow::Proxying do
|
|
284
332
|
end
|
285
333
|
end
|
286
334
|
end
|
335
|
+
|
336
|
+
describe '#proxy_call_argument_list' do
|
337
|
+
it 'uses proxy_argument_list for Ruby methods' do
|
338
|
+
Police::DataFlow::Proxying.proxy_call_argument_list(
|
339
|
+
ProxyingFixture.instance_method(:==)).must_equal 'arg1'
|
340
|
+
end
|
341
|
+
|
342
|
+
it 'uses low_level_call_argument_list for native methods' do
|
343
|
+
golden =
|
344
|
+
'(nil == arg1.__police_labels__) ? arg1 : arg1.__police_proxied__'
|
345
|
+
Police::DataFlow::Proxying.proxy_call_argument_list(
|
346
|
+
Object.instance_method(:==)).must_equal golden
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
describe '#proxy_low_level_call_argument_list' do
|
351
|
+
it 'works for an argument-less method' do
|
352
|
+
Police::DataFlow::Proxying.proxy_low_level_call_argument_list(
|
353
|
+
ProxyingFixture.instance_method(:length)).must_equal ''
|
354
|
+
end
|
355
|
+
|
356
|
+
it 'works for a one-argument method' do
|
357
|
+
golden =
|
358
|
+
'(nil == arg1.__police_labels__) ? arg1 : arg1.__police_proxied__'
|
359
|
+
Police::DataFlow::Proxying.proxy_low_level_call_argument_list(
|
360
|
+
ProxyingFixture.instance_method(:==)).must_equal golden
|
361
|
+
end
|
362
|
+
|
363
|
+
it 'works for a two-argument method' do
|
364
|
+
golden =
|
365
|
+
'(nil == arg1.__police_labels__) ? arg1 : arg1.__police_proxied__, ' +
|
366
|
+
'(nil == arg2.__police_labels__) ? arg2 : arg2.__police_proxied__'
|
367
|
+
Police::DataFlow::Proxying.proxy_low_level_call_argument_list(
|
368
|
+
ProxyingFixture.instance_method(:add)).must_equal golden
|
369
|
+
end
|
370
|
+
|
371
|
+
it 'works for a variable-argument method' do
|
372
|
+
golden = '*(args.map { |a| (nil == a.__police_labels__) ? a : ' +
|
373
|
+
'a.__police_proxied__ })'
|
374
|
+
Police::DataFlow::Proxying.proxy_low_level_call_argument_list(
|
375
|
+
ProxyingFixture.instance_method(:route)).must_equal golden
|
376
|
+
end
|
377
|
+
|
378
|
+
it 'works for one fixed + variable-argument method' do
|
379
|
+
golden =
|
380
|
+
'(nil == arg1.__police_labels__) ? arg1 : arg1.__police_proxied__, ' +
|
381
|
+
'*(args.map { |a| (nil == a.__police_labels__) ? a : ' +
|
382
|
+
'a.__police_proxied__ })'
|
383
|
+
Police::DataFlow::Proxying.proxy_low_level_call_argument_list(
|
384
|
+
ProxyingFixture.instance_method(:<=>)).must_equal golden
|
385
|
+
end
|
386
|
+
|
387
|
+
it 'works for two fixed + variable-argument method' do
|
388
|
+
golden =
|
389
|
+
'(nil == arg1.__police_labels__) ? arg1 : arg1.__police_proxied__, ' +
|
390
|
+
'(nil == arg2.__police_labels__) ? arg2 : arg2.__police_proxied__, ' +
|
391
|
+
'*(args.map { |a| (nil == a.__police_labels__) ? a : ' +
|
392
|
+
'a.__police_proxied__ })'
|
393
|
+
Police::DataFlow::Proxying.proxy_low_level_call_argument_list(
|
394
|
+
ProxyingFixture.instance_method(:log)).must_equal golden
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
describe '#proxy_sticky_fastpath_check' do
|
399
|
+
it 'works for an argument-less method' do
|
400
|
+
Police::DataFlow::Proxying.proxy_sticky_fastpath_check(
|
401
|
+
ProxyingFixture.instance_method(:length)).must_equal ''
|
402
|
+
end
|
403
|
+
|
404
|
+
it 'works for a one-argument method' do
|
405
|
+
golden =
|
406
|
+
'fast_sticky = (nil == arg1.__police_stickies__)'
|
407
|
+
Police::DataFlow::Proxying.proxy_sticky_fastpath_check(
|
408
|
+
ProxyingFixture.instance_method(:==)).must_equal golden
|
409
|
+
end
|
410
|
+
|
411
|
+
it 'works for a two-argument method' do
|
412
|
+
golden = 'fast_sticky = ' +
|
413
|
+
'(nil == arg1.__police_stickies__) && ' +
|
414
|
+
'(nil == arg2.__police_stickies__)'
|
415
|
+
Police::DataFlow::Proxying.proxy_sticky_fastpath_check(
|
416
|
+
ProxyingFixture.instance_method(:add)).must_equal golden
|
417
|
+
end
|
418
|
+
|
419
|
+
it 'works for a variable-argument method' do
|
420
|
+
golden = 'fast_sticky = (args.all? { |a| nil == a.__police_stickies__ })'
|
421
|
+
Police::DataFlow::Proxying.proxy_sticky_fastpath_check(
|
422
|
+
ProxyingFixture.instance_method(:route)).must_equal golden
|
423
|
+
end
|
424
|
+
|
425
|
+
it 'works for one fixed + variable-argument method' do
|
426
|
+
golden =
|
427
|
+
'fast_sticky = (nil == arg1.__police_stickies__) && ' +
|
428
|
+
'(args.all? { |a| nil == a.__police_stickies__ })'
|
429
|
+
Police::DataFlow::Proxying.proxy_sticky_fastpath_check(
|
430
|
+
ProxyingFixture.instance_method(:<=>)).must_equal golden
|
431
|
+
end
|
432
|
+
|
433
|
+
it 'works for two fixed + variable-argument method' do
|
434
|
+
golden =
|
435
|
+
'fast_sticky = (nil == arg1.__police_stickies__) && ' +
|
436
|
+
'(nil == arg2.__police_stickies__) && ' +
|
437
|
+
'(args.all? { |a| nil == a.__police_stickies__ })'
|
438
|
+
Police::DataFlow::Proxying.proxy_sticky_fastpath_check(
|
439
|
+
ProxyingFixture.instance_method(:log)).must_equal golden
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
describe '#proxy_sticky_gathering' do
|
444
|
+
it 'works for an argument-less method' do
|
445
|
+
Police::DataFlow::Proxying.proxy_sticky_gathering(
|
446
|
+
ProxyingFixture.instance_method(:length)).must_equal ''
|
447
|
+
end
|
448
|
+
|
449
|
+
it 'works for a one-argument method' do
|
450
|
+
golden = 'unless fast_sticky; sticky_labels = {}; ' +
|
451
|
+
'unless nil == arg1.__police_stickies__; ' +
|
452
|
+
'::Police::DataFlow::Labeling.merge_sets!(sticky_labels, ' +
|
453
|
+
'arg1.__police_stickies__); end; end'
|
454
|
+
Police::DataFlow::Proxying.proxy_sticky_gathering(
|
455
|
+
ProxyingFixture.instance_method(:==)).must_equal golden
|
456
|
+
end
|
457
|
+
|
458
|
+
it 'works for a two-argument method' do
|
459
|
+
golden = 'unless fast_sticky; sticky_labels = {}; ' +
|
460
|
+
'unless nil == arg1.__police_stickies__; ' +
|
461
|
+
'::Police::DataFlow::Labeling.merge_sets!(sticky_labels, ' +
|
462
|
+
'arg1.__police_stickies__); end; ' +
|
463
|
+
'unless nil == arg2.__police_stickies__; ' +
|
464
|
+
'::Police::DataFlow::Labeling.merge_sets!(sticky_labels, ' +
|
465
|
+
'arg2.__police_stickies__); end; end'
|
466
|
+
|
467
|
+
Police::DataFlow::Proxying.proxy_sticky_gathering(
|
468
|
+
ProxyingFixture.instance_method(:add)).must_equal golden
|
469
|
+
end
|
470
|
+
|
471
|
+
it 'works for a variable-argument method' do
|
472
|
+
golden = 'unless fast_sticky; sticky_labels = {}; ' +
|
473
|
+
'args.each do |a|; ' +
|
474
|
+
'unless nil == a.__police_stickies__; ' +
|
475
|
+
'::Police::DataFlow::Labeling.merge_sets!(sticky_labels, ' +
|
476
|
+
'a.__police_stickies__); end; end; end'
|
477
|
+
Police::DataFlow::Proxying.proxy_sticky_gathering(
|
478
|
+
ProxyingFixture.instance_method(:route)).must_equal golden
|
479
|
+
end
|
480
|
+
|
481
|
+
it 'works for one fixed + variable-argument method' do
|
482
|
+
golden = 'unless fast_sticky; sticky_labels = {}; ' +
|
483
|
+
'unless nil == arg1.__police_stickies__; ' +
|
484
|
+
'::Police::DataFlow::Labeling.merge_sets!(sticky_labels, ' +
|
485
|
+
'arg1.__police_stickies__); end; ' +
|
486
|
+
'args.each do |a|; ' +
|
487
|
+
'unless nil == a.__police_stickies__; ' +
|
488
|
+
'::Police::DataFlow::Labeling.merge_sets!(sticky_labels, ' +
|
489
|
+
'a.__police_stickies__); end; end; end'
|
490
|
+
Police::DataFlow::Proxying.proxy_sticky_gathering(
|
491
|
+
ProxyingFixture.instance_method(:<=>)).must_equal golden
|
492
|
+
end
|
493
|
+
|
494
|
+
it 'works for two fixed + variable-argument method' do
|
495
|
+
golden = 'unless fast_sticky; sticky_labels = {}; ' +
|
496
|
+
'unless nil == arg1.__police_stickies__; ' +
|
497
|
+
'::Police::DataFlow::Labeling.merge_sets!(sticky_labels, ' +
|
498
|
+
'arg1.__police_stickies__); end; ' +
|
499
|
+
'unless nil == arg2.__police_stickies__; ' +
|
500
|
+
'::Police::DataFlow::Labeling.merge_sets!(sticky_labels, ' +
|
501
|
+
'arg2.__police_stickies__); end; ' +
|
502
|
+
'args.each do |a|; ' +
|
503
|
+
'unless nil == a.__police_stickies__; ' +
|
504
|
+
'::Police::DataFlow::Labeling.merge_sets!(sticky_labels, ' +
|
505
|
+
'a.__police_stickies__); end; end; end'
|
506
|
+
Police::DataFlow::Proxying.proxy_sticky_gathering(
|
507
|
+
ProxyingFixture.instance_method(:log)).must_equal golden
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
describe '#proxy_yield_sticky_decorating' do
|
512
|
+
it 'works for an argument-less method' do
|
513
|
+
Police::DataFlow::Proxying.proxy_yield_sticky_decorating(
|
514
|
+
ProxyingFixture.instance_method(:length)).must_equal ''
|
515
|
+
end
|
516
|
+
|
517
|
+
it 'works for a one-argument method' do
|
518
|
+
golden = 'unless fast_sticky; yield_args.map! do |a|; ' +
|
519
|
+
'::Police::DataFlow::Labeling.bulk_sticky_label(' +
|
520
|
+
'a, sticky_labels); end; end'
|
521
|
+
Police::DataFlow::Proxying.proxy_yield_sticky_decorating(
|
522
|
+
ProxyingFixture.instance_method(:==)).must_equal golden
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
describe '#proxy_return_sticky_decorating' do
|
527
|
+
it 'works for an argument-less method' do
|
528
|
+
Police::DataFlow::Proxying.proxy_return_sticky_decorating(
|
529
|
+
ProxyingFixture.instance_method(:length)).must_equal ''
|
530
|
+
end
|
531
|
+
|
532
|
+
it 'works for a one-argument method' do
|
533
|
+
golden = 'unless fast_sticky; return_value = ' +
|
534
|
+
'::Police::DataFlow::Labeling.bulk_sticky_label(' +
|
535
|
+
'return_value, sticky_labels); end'
|
536
|
+
Police::DataFlow::Proxying.proxy_return_sticky_decorating(
|
537
|
+
ProxyingFixture.instance_method(:==)).must_equal golden
|
538
|
+
end
|
539
|
+
end
|
287
540
|
end
|