aquarium 0.5.1 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +240 -215
  3. data/README +61 -44
  4. data/RELEASE-PLAN +21 -23
  5. data/Rakefile +64 -94
  6. data/UPGRADE +45 -35
  7. data/aquarium.gemspec +50 -0
  8. data/examples/README.txt +6 -0
  9. data/examples/aspect_design_example_spec.rb +2 -2
  10. data/examples/design_by_contract_example_spec.rb +3 -3
  11. data/examples/exception_wrapping_example_spec.rb +2 -2
  12. data/examples/introductions_example_spec.rb +1 -1
  13. data/examples/method_tracing_example_spec.rb +17 -16
  14. data/examples/reusable_aspect_hack_example_spec.rb +5 -5
  15. data/jruby/Rakefile +61 -0
  16. data/jruby/java/example/Worker.java +9 -0
  17. data/jruby/java/example/sorter/StringListSorter.java +22 -0
  18. data/jruby/java/example/sorter/converter/StringListCaseConverterAndSorter.java +42 -0
  19. data/jruby/java/example/visibility/Visibility.java +13 -0
  20. data/jruby/spec/java_class_aspects_spec.rb +434 -0
  21. data/jruby/spec/java_visibility_spec.rb +122 -0
  22. data/jruby/spec/spec_helper.rb +5 -0
  23. data/lib/aquarium/aspects/aspect.rb +8 -4
  24. data/lib/aquarium/utils/type_utils.rb +4 -1
  25. data/lib/aquarium/version.rb +29 -28
  26. data/previous_failures.txt +0 -0
  27. data/rspec.watchr +60 -0
  28. data/spec/aquarium/aspects/advice_spec.rb +10 -10
  29. data/spec/aquarium/aspects/aspect_invocation_spec.rb +79 -79
  30. data/spec/aquarium/aspects/aspect_spec.rb +73 -73
  31. data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +5 -5
  32. data/spec/aquarium/aspects/concurrent_aspects_spec.rb +1 -1
  33. data/spec/aquarium/aspects/default_objects_handler_spec.rb +5 -5
  34. data/spec/aquarium/aspects/join_point_spec.rb +40 -40
  35. data/spec/aquarium/aspects/pointcut_and_composition_spec.rb +8 -8
  36. data/spec/aquarium/aspects/pointcut_spec.rb +25 -25
  37. data/spec/aquarium/extensions/regex_spec.rb +6 -6
  38. data/spec/aquarium/extras/design_by_contract_spec.rb +6 -6
  39. data/spec/aquarium/finders/finder_result_spec.rb +2 -2
  40. data/spec/aquarium/finders/method_finder_spec.rb +24 -24
  41. data/spec/aquarium/finders/pointcut_finder_spec.rb +10 -10
  42. data/spec/aquarium/finders/pointcut_finder_spec_test_classes.rb +4 -4
  43. data/spec/aquarium/finders/type_finder_spec.rb +5 -5
  44. data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +6 -5
  45. data/spec/aquarium/finders/type_finder_with_nested_types_spec.rb +2 -2
  46. data/spec/aquarium/utils/logic_error_spec.rb +1 -1
  47. data/spec/aquarium/utils/method_utils_spec.rb +38 -38
  48. data/spec/aquarium/utils/nil_object_spec.rb +11 -11
  49. data/spec/aquarium/utils/options_utils_spec.rb +8 -8
  50. data/spec/aquarium/utils/type_utils_spec.rb +3 -3
  51. metadata +238 -57
@@ -0,0 +1,13 @@
1
+ package example.visibility;
2
+ import java.util.ArrayList;
3
+
4
+ public class Visibility {
5
+ private ArrayList<String> messages = new ArrayList<String>();
6
+ public ArrayList<String> getMessages() { return messages; }
7
+
8
+ public void publicMethod (String s, int i) { protectedMethod("public: "+s, i); }
9
+ protected void protectedMethod(String s, int i) { privateMethod("protected: "+s, i); }
10
+ private void privateMethod (String s, int i) {
11
+ messages.add("private: "+s+", i="+i);
12
+ }
13
+ }
@@ -0,0 +1,434 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ include Aquarium::Aspects
4
+
5
+ # The Aquarium README summarizes the known bugs and limitations of the JRuby integration.
6
+
7
+ class StringLengthListComparator
8
+ include java.util.Comparator
9
+ def compare s1, s2
10
+ s1.length <=> s2.length
11
+ end
12
+ end
13
+
14
+ class StringListCaseConverterAndSorterWithConvertCaseOverride < Java::example.sorter.converter.StringListCaseConverterAndSorter
15
+ def convertCase *args; super *args; end
16
+ end
17
+
18
+ java_example_types = [
19
+ Java::example.Worker,
20
+ Java::example.sorter.StringListSorter,
21
+ Java::example.sorter.converter.StringListCaseConverterAndSorter,
22
+ StringListCaseConverterAndSorterWithConvertCaseOverride]
23
+
24
+ def do_sort list_sorter, method_name = :do_work
25
+ orig_list = %w[now is the time for all good men to come to the aid of their country]
26
+ sorted_list = list_sorter.send(method_name,orig_list)
27
+ sorted_list.should_not eql(orig_list)
28
+ sorted_list.size.should == orig_list.size
29
+ expected = %w[is to to of now the for all men the aid time good come their country]
30
+ sorted_list.to_a.should eql(expected)
31
+ end
32
+
33
+ def is_java_interface? type
34
+ type.java_class.interface?
35
+ end
36
+
37
+ def log_should_contain_entries
38
+ @@aspect_log.should_not be_empty
39
+ @@aspect_log.should include("entering do_work")
40
+ @@aspect_log.should include("leaving do_work")
41
+ end
42
+
43
+ # def make_advice
44
+ # return Proc.new { |jp, object, *args|
45
+ # @@aspect_log += "entering do_work(#{args.inspect})\n"
46
+ # result = jp.proceed
47
+ # @@aspect_log += "leaving do_work(#{args.inspect})\n"
48
+ # result
49
+ # }
50
+ # end
51
+
52
+ canned_advice = Proc.new { |jp, object, *args|
53
+ @@aspect_log += "entering do_work(#{args.inspect})\n"
54
+ result = jp.proceed
55
+ @@aspect_log += "leaving do_work(#{args.inspect})\n"
56
+ result
57
+ }
58
+
59
+
60
+ describe "Java type without advice" do
61
+ it "should not be advised" do
62
+ do_sort Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
63
+ do_sort Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
64
+ end
65
+ end
66
+
67
+ describe "Java instance with advice" do
68
+ before :each do
69
+ @@aspect_log = ""
70
+ end
71
+
72
+ it "should invoke the advice when the advised methods on the same instance are called" do
73
+ list_sorter = Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
74
+ aspect = Aspect.new :around, :calls_to => :do_work, :object => list_sorter, :advice => canned_advice
75
+ do_sort list_sorter
76
+ log_should_contain_entries
77
+
78
+ list_sorter2 = Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
79
+ aspect = Aspect.new :around, :calls_to => :do_work, :object => list_sorter2, :advice => canned_advice
80
+ @@aspect_log = ""
81
+ do_sort list_sorter2
82
+ log_should_contain_entries
83
+ aspect.unadvise
84
+ end
85
+ end
86
+
87
+ describe "Second Java instance of the same type" do
88
+ it "should not be advised by the advice applied to a different instance" do
89
+ aspect = Aspect.new :around, :calls_to => :do_work, :object => Java::example.sorter.StringListSorter.new(StringLengthListComparator.new), :advice => canned_advice
90
+ list_sorter2 = Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
91
+ @@aspect_log = ""
92
+ do_sort list_sorter2
93
+ @@aspect_log.should be_empty
94
+ aspect.unadvise
95
+ end
96
+ end
97
+
98
+ describe "Second Java instance of a derived type" do
99
+ it "should not be advised by the advice applied to an instance of a parent type" do
100
+ aspect = Aspect.new :around, :calls_to => :do_work, :object => Java::example.sorter.StringListSorter.new(StringLengthListComparator.new), :advice => canned_advice
101
+ list_sorter2 = Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
102
+ @@aspect_log = ""
103
+ do_sort list_sorter2
104
+ @@aspect_log.should be_empty
105
+ aspect.unadvise
106
+ end
107
+ end
108
+
109
+ describe "Java instance with advice added then removed" do
110
+ it "should not be advised after the advice is removed" do
111
+ list_sorter = Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
112
+ aspect = Aspect.new :around, :calls_to => :do_work, :object => list_sorter, :advice => canned_advice
113
+ do_sort list_sorter
114
+ @@aspect_log = ""
115
+ aspect.unadvise
116
+ do_sort list_sorter
117
+ @@aspect_log.should be_empty
118
+
119
+ list_sorter2 = Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
120
+ aspect2 = Aspect.new :around, :calls_to => :do_work, :object => list_sorter2, :advice => canned_advice
121
+ do_sort list_sorter2
122
+ @@aspect_log = ""
123
+ aspect2.unadvise
124
+ do_sort list_sorter2
125
+ @@aspect_log.should be_empty
126
+ end
127
+ end
128
+
129
+ describe "Java interface used with :type => ... (or synonym)" do
130
+ it "should never match join points; you must use :type(s)_and_descendents, instead" do
131
+ aspect = Aspect.new :around, :calls_to => [:do_work, :doWork], :type => Java::example.Worker, :ignore_no_matching_join_points => true do; end
132
+ aspect.join_points_matched.should be_empty
133
+ end
134
+ end
135
+
136
+ describe "Java interface used with :type_and_descendents => ... (or synonym)" do
137
+ before :each do
138
+ @aspect = Aspect.new :around, :calls_to => :do_work, :type_and_descendents => Java::example.Worker,
139
+ # :advice => canned_advice
140
+ :exclude_type => StringListCaseConverterAndSorterWithConvertCaseOverride, :advice => canned_advice
141
+ @@aspect_log = ""
142
+ end
143
+ after :each do
144
+ @aspect.unadvise unless @aspect.nil?
145
+ end
146
+
147
+ it "should invoke the advice when the advised methods of directly-implementing subclasses are called" do
148
+ list_sorter = Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
149
+ do_sort list_sorter
150
+ log_should_contain_entries
151
+ end
152
+
153
+ it "should invoke the advice when the advised methods of indirectly-implementing subclasses are called" do
154
+ list_sorter = Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
155
+ do_sort list_sorter
156
+ log_should_contain_entries
157
+ end
158
+
159
+ it "should not invoke the advice after the advice is removed" do
160
+ list_sorter = Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
161
+ do_sort list_sorter
162
+ log_should_contain_entries
163
+ @aspect.unadvise
164
+ @@aspect_log = ""
165
+ do_sort list_sorter
166
+ do_sort Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
167
+ @@aspect_log.should be_empty
168
+ end
169
+
170
+ it "should allow #unadvise to be called repeatedly" do
171
+ expect {@aspect.unadvise}.should_not raise_error
172
+ expect {@aspect.unadvise}.should_not raise_error
173
+ end
174
+ end
175
+
176
+ describe "Java class used with :type_and_descendents => ..." do
177
+ before :each do
178
+ @aspect = Aspect.new :around, :calls_to => :do_work, :type_and_descendents => Java::example.sorter.StringListSorter,
179
+ :exclude_type => StringListCaseConverterAndSorterWithConvertCaseOverride, :advice => canned_advice
180
+ @@aspect_log = ""
181
+ end
182
+
183
+ it "should invoke the advice when the advised methods of the class are called" do
184
+ list_sorter = Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
185
+ do_sort list_sorter
186
+ log_should_contain_entries
187
+ @aspect.unadvise
188
+ end
189
+
190
+ it "should invoke the advice when the advised methods of extending subclasses are called" do
191
+ list_sorter = Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
192
+ do_sort list_sorter
193
+ log_should_contain_entries
194
+ @aspect.unadvise
195
+ end
196
+
197
+ it "should not invoke the advice after the advice is removed" do
198
+ list_sorter = Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
199
+ do_sort list_sorter
200
+ log_should_contain_entries
201
+ @aspect.unadvise
202
+ @@aspect_log = ""
203
+ do_sort list_sorter
204
+ do_sort Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
205
+ @@aspect_log.should be_empty
206
+ end
207
+ end
208
+
209
+ describe "Derived Java class used with :type_and_descendents => ..." do
210
+ before :each do
211
+ @@aspect_log = ""
212
+ @aspect = Aspect.new :around, :calls_to => :do_work, :type_and_descendents => Java::example.sorter.converter.StringListCaseConverterAndSorter,
213
+ :exclude_type => StringListCaseConverterAndSorterWithConvertCaseOverride, :advice => canned_advice
214
+ end
215
+
216
+ it "should not invoke the advice when the advised methods of parent classes are called" do
217
+ list_sorter = Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
218
+ do_sort list_sorter
219
+ @@aspect_log.should be_empty
220
+ @aspect.unadvise
221
+ end
222
+
223
+ it "should invoke the advice when the advised methods of the same class are called" do
224
+ list_sorter = Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
225
+ do_sort list_sorter
226
+ log_should_contain_entries
227
+ @aspect.unadvise
228
+ end
229
+
230
+ it "should not invoke the advice after the advice is removed" do
231
+ list_sorter = Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
232
+ do_sort list_sorter
233
+ log_should_contain_entries
234
+ @aspect.unadvise
235
+ @@aspect_log = ""
236
+ do_sort list_sorter
237
+ @@aspect_log.should be_empty
238
+ end
239
+ end
240
+
241
+ describe "Derived Java class used with :type_and_ancestors => ..." do
242
+ before :each do
243
+ @@aspect_log = ""
244
+ @aspect = Aspect.new :around, :calls_to => :do_work, :type_and_ancestors => Java::example.sorter.converter.StringListCaseConverterAndSorter, :advice => canned_advice
245
+ end
246
+
247
+ it "should invoke the advice when the advised methods of parent classes are called" do
248
+ list_sorter = Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
249
+ do_sort list_sorter
250
+ log_should_contain_entries
251
+ @aspect.unadvise
252
+ end
253
+
254
+ it "should invoke the advice when the advised methods of the same class are called" do
255
+ list_sorter = Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
256
+ do_sort list_sorter
257
+ log_should_contain_entries
258
+ @aspect.unadvise
259
+ end
260
+
261
+ it "should not invoke the advice after the advice is removed" do
262
+ list_sorter = Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
263
+ do_sort list_sorter
264
+ log_should_contain_entries
265
+ @aspect.unadvise
266
+ @@aspect_log = ""
267
+ do_sort list_sorter
268
+ @@aspect_log.should be_empty
269
+ end
270
+ end
271
+
272
+ describe "Java camel-case method name 'doFooBar'" do
273
+ before :each do
274
+ @@aspect_log = ""
275
+ end
276
+
277
+ it "should be matched when using the camel-case form of the name 'doFooBar'" do
278
+ aspect = Aspect.new :around, :calls_to => :doWork, :type_and_descendents => Java::example.sorter.StringListSorter,
279
+ :restricting_methods_to => [:exclude_ancestor_methods], :advice => canned_advice
280
+ list_sorter = Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
281
+ do_sort list_sorter, :doWork
282
+ log_should_contain_entries
283
+ aspect.unadvise
284
+ end
285
+
286
+ it "should be matched when using the underscore form of the name 'do_foo_bar'" do
287
+ aspect = Aspect.new :around, :calls_to => :do_work, :type_and_descendents => Java::example.sorter.StringListSorter,
288
+ :restricting_methods_to => [:exclude_ancestor_methods], :advice => canned_advice
289
+ list_sorter = Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
290
+ do_sort list_sorter
291
+ log_should_contain_entries
292
+ aspect.unadvise
293
+ end
294
+
295
+ it "should advise 'doFooBar' separately from 'do_foo_bar', so that invoking 'do_foo_bar' will not invoke the advice!" do
296
+ aspect = Aspect.new :around, :calls_to => :doWork, :type_and_descendents => Java::example.sorter.StringListSorter,
297
+ :restricting_methods_to => [:exclude_ancestor_methods], :advice => canned_advice
298
+ list_sorter = Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
299
+ do_sort list_sorter, :do_work
300
+ @@aspect_log.should be_empty
301
+ aspect.unadvise
302
+ end
303
+ it "should advise 'do_foo_bar' separately from 'doFooBar', so that invoking 'doFooBar' will not invoke the advice!" do
304
+ aspect = Aspect.new :around, :calls_to => :do_work, :type_and_descendents => Java::example.sorter.StringListSorter,
305
+ :restricting_methods_to => [:exclude_ancestor_methods], :advice => canned_advice
306
+ list_sorter = Java::example.sorter.StringListSorter.new(StringLengthListComparator.new)
307
+ do_sort list_sorter, :doWork
308
+ @@aspect_log.should be_empty
309
+ aspect.unadvise
310
+ end
311
+ end
312
+
313
+ describe "Java method advice" do
314
+ it "will not be invoked when the method is called by other Java methods" do
315
+ list_sorter = Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
316
+ @advise_called = false
317
+ aspect = Aspect.new :before, :calls_to => :convertCase, :in_type => Java::example.sorter.converter.StringListCaseConverterAndSorter do
318
+ @advise_called = true
319
+ end
320
+ do_sort list_sorter
321
+ @advise_called.should be_falsey
322
+ aspect.unadvise
323
+ end
324
+
325
+ it "should be invoked when the method is called by other Java methods, using a ruby subclass that overrides the advised method" do
326
+ list_sorter = StringListCaseConverterAndSorterWithConvertCaseOverride.new(StringLengthListComparator.new)
327
+ @advise_called = false
328
+ aspect = Aspect.new :before, :calls_to => :convertCase, :in_type => Java::example.sorter.converter.StringListCaseConverterAndSorter do
329
+ @advise_called = true
330
+ end
331
+ do_sort list_sorter
332
+ @advise_called.should be_truthy
333
+ aspect.unadvise
334
+ end
335
+
336
+ it "should be invoked when the method is called by a Ruby method" do
337
+ list_sorter = Java::example.sorter.converter.StringListCaseConverterAndSorter.new(StringLengthListComparator.new)
338
+ @advise_called = false
339
+ aspect = Aspect.new :before, :calls_to => :convertCase, :in_type => Java::example.sorter.converter.StringListCaseConverterAndSorter do
340
+ @advise_called = true
341
+ end
342
+ list_sorter.convertCase(java.util.ArrayList.new)
343
+ @advise_called.should be_truthy
344
+ aspect.unadvise
345
+ end
346
+ end
347
+
348
+ describe "Ruby subclass with advice on method in a Java parent class" do
349
+ it "should be invoked, but isn't, when the method is advised using the Java form of its name (doFoo), rather than the Ruby form (do_foo) -- BUG #18326" do
350
+ list_sorter = StringListCaseConverterAndSorterWithConvertCaseOverride.new(StringLengthListComparator.new)
351
+ @advise_called = false
352
+ aspect = Aspect.new :before, :calls_to => :doWork, :in_type => StringListCaseConverterAndSorterWithConvertCaseOverride do
353
+ @advise_called = true
354
+ end
355
+ do_sort list_sorter
356
+ @advise_called.should be_falsey
357
+ # @advise_called.should be_truthy
358
+ aspect.unadvise
359
+ end
360
+
361
+ it "should be invoked when the method is called by a Ruby method" do
362
+ list_sorter = StringListCaseConverterAndSorterWithConvertCaseOverride.new(StringLengthListComparator.new)
363
+ @advise_called = false
364
+ aspect = Aspect.new :before, :calls_to => :do_work, :in_type => StringListCaseConverterAndSorterWithConvertCaseOverride do
365
+ @advise_called = true
366
+ end
367
+ do_sort list_sorter
368
+ @advise_called.should be_truthy
369
+ aspect.unadvise
370
+ end
371
+
372
+ it "should be removed cleanly when aspect#unadvise is called" do
373
+ list_sorter = StringListCaseConverterAndSorterWithConvertCaseOverride.new(StringLengthListComparator.new)
374
+ @advise_called = false
375
+ aspect = Aspect.new :before, :calls_to => :do_work, :in_type => StringListCaseConverterAndSorterWithConvertCaseOverride do
376
+ @advise_called = true
377
+ end
378
+ do_sort list_sorter
379
+ @advise_called.should be_truthy
380
+ aspect.unadvise
381
+ @advise_called = false
382
+ do_sort list_sorter
383
+ @advise_called.should be_falsey
384
+ end
385
+ end
386
+
387
+ describe "JDK classes" do
388
+ it "should be advisable by Aquarium aspects" do
389
+ @@aspect_log = ""
390
+ aspect = Aspect.new :before, :calls_to => :add, :on_type => java.util.ArrayList do |jp, obj, *args|
391
+ @@aspect_log << "adding: #{args[0]}\n"
392
+ end
393
+ list = java.util.ArrayList.new
394
+ list.add(1)
395
+ list.add(2)
396
+ @@aspect_log.should include("adding: 1")
397
+ @@aspect_log.should include("adding: 2")
398
+ aspect.unadvise
399
+ @@aspect_log = ""
400
+ list.add(1)
401
+ list.add(2)
402
+ @@aspect_log.should be_empty
403
+ end
404
+ end
405
+
406
+
407
+ include Aquarium::Utils
408
+
409
+ describe TypeUtils, ".descendents" do
410
+ it "should return Java classes implementing a Java interface" do
411
+ actual = TypeUtils.descendents Java::example.Worker
412
+ actual.size.should == java_example_types.size
413
+ java_example_types.each {|x| actual.should include(x)}
414
+ end
415
+
416
+ it "should return Java classes extending a Java class" do
417
+ expected = [
418
+ Java::example.sorter.StringListSorter,
419
+ Java::example.sorter.converter.StringListCaseConverterAndSorter,
420
+ StringListCaseConverterAndSorterWithConvertCaseOverride]
421
+ actual = TypeUtils.descendents Java::example.sorter.StringListSorter
422
+ actual.size.should == expected.size
423
+ expected.each {|x| actual.should include(x)}
424
+ end
425
+ end
426
+
427
+ describe "Java::Packages::Type.ancestors" do
428
+ it "should return Java classes and interfaces that are ancestors of a Java class" do
429
+ anc = Java::example.sorter.converter.StringListCaseConverterAndSorter.ancestors
430
+ [Java::example.Worker, Java::example.sorter.StringListSorter, Java::example.sorter.converter.StringListCaseConverterAndSorter].each do |t|
431
+ anc.should include(t)
432
+ end
433
+ end
434
+ end
@@ -0,0 +1,122 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ include Aquarium::Aspects
4
+
5
+ # The Aquarium README summarizes the known bugs and limitations of the JRuby integration.
6
+
7
+ class VisibilityWrapper < Java::example.visibility.Visibility
8
+ def public_method(s, i); super; end
9
+ protected
10
+ def protected_method(s, i); super; end
11
+ private
12
+ def private_method(s, i); super; end
13
+ end
14
+
15
+ describe "Matching on a private method in a Java type" do
16
+ before :each do
17
+ @visibility = Java::example.visibility.Visibility.new
18
+ end
19
+
20
+ it "will not match on a private Java method when the default public access method option is used" do
21
+ aspect = Aspect.new :around, :calls_to => "private_method", :in_object => @visibility,
22
+ :ignore_no_matching_join_points => true do |jp|
23
+ end
24
+ aspect.join_points_matched.should be_empty
25
+ aspect.unadvise
26
+ end
27
+
28
+ it "will not match on a private Java method, even when the private method option specifier is used" do
29
+ aspect = Aspect.new :around, :calls_to => "private_method", :in_object => @visibility,
30
+ :method_options => [:private], :ignore_no_matching_join_points => true do |jp|
31
+ end
32
+ aspect.join_points_matched.should be_empty
33
+ aspect.unadvise
34
+ end
35
+ end
36
+
37
+ describe "Matching on a protected method in a Java type" do
38
+ before :each do
39
+ @visibility = Java::example.visibility.Visibility.new
40
+ end
41
+
42
+ it "will treat a protected Java method as publicly visible" do
43
+ aspect = Aspect.new :around, :calls_to => "protected_method", :in_object => @visibility,
44
+ :ignore_no_matching_join_points => false do |jp|
45
+ end
46
+ aspect.join_points_matched.size.should eql(1)
47
+ aspect.join_points_matched.each {|jp| jp.method_name.should eql(:protected_method) }
48
+ aspect.unadvise
49
+ end
50
+
51
+ it "will NOT match on a protected Java method, even when the :protected method option specifier is used" do
52
+ aspect = Aspect.new :around, :calls_to => "protected_method", :in_object => @visibility,
53
+ :method_options => [:protected], :ignore_no_matching_join_points => true do |jp|
54
+ end
55
+ aspect.join_points_matched.should be_empty
56
+ aspect.unadvise
57
+ end
58
+
59
+ end
60
+
61
+ describe "Matching on a public method in a Java type" do
62
+ before :each do
63
+ @visibility = Java::example.visibility.Visibility.new
64
+ end
65
+
66
+ it "should match on a public method when the default public access is used" do
67
+ aspect = Aspect.new :around, :calls_to => "public_method", :in_object => @visibility,
68
+ :ignore_no_matching_join_points => false do |jp|
69
+ end
70
+ aspect.join_points_matched.size.should eql(1)
71
+ aspect.join_points_matched.each {|jp| jp.method_name.should eql(:public_method) }
72
+ aspect.unadvise
73
+ end
74
+
75
+ it "should match on a public method when the public method option specifier is used" do
76
+ aspect = Aspect.new :around, :calls_to => "public_method", :in_object => @visibility,
77
+ :method_options => [:public], :ignore_no_matching_join_points => false do |jp|
78
+ end
79
+ aspect.join_points_matched.size.should eql(1)
80
+ aspect.join_points_matched.each {|jp| jp.method_name.should eql(:public_method) }
81
+ aspect.unadvise
82
+ end
83
+ end
84
+
85
+ %w[private protected public].each do |vis|
86
+ if vis == "public"
87
+ not_string = ""
88
+ ignore_no_matches = false
89
+ else
90
+ not_string = "not "
91
+ ignore_no_matches = true
92
+ end
93
+
94
+ describe "Matching on a #{vis} method in a Ruby type wrapping a Java type where the Ruby type is advised" do
95
+ before :each do
96
+ @visibility = VisibilityWrapper.new
97
+ end
98
+
99
+ it "should #{not_string}advise #{vis} methods when the default public access is used" do
100
+ aspect = Aspect.new :around, :calls_to => "#{vis}_method", :in_object => @visibility,
101
+ :ignore_no_matching_join_points => ignore_no_matches do |jp|
102
+ end
103
+ if vis == "public"
104
+ aspect.join_points_matched.size.should eql(1)
105
+ aspect.join_points_matched.each {|jp| jp.method_name.should eql("#{vis}_method".intern) }
106
+ else
107
+ aspect.join_points_matched.should be_empty
108
+ end
109
+ aspect.unadvise
110
+ end
111
+
112
+ it "should advise #{vis} methods when the same access method option specifier is used" do
113
+ aspect = Aspect.new :around, :calls_to => "#{vis}_method", :in_object => @visibility,
114
+ :method_options => [vis.intern], :ignore_no_matching_join_points => ignore_no_matches do |jp|
115
+ end
116
+ aspect.join_points_matched.size.should eql(1)
117
+ aspect.join_points_matched.each {|jp| jp.method_name.should eql("#{vis}_method".intern) }
118
+ aspect.unadvise
119
+ end
120
+ end
121
+ end
122
+