aquarium 0.5.1 → 0.7.1

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.
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
+