aquarium 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/CHANGES +59 -2
  2. data/README +33 -16
  3. data/RELEASE-PLAN +28 -5
  4. data/UPGRADE +11 -0
  5. data/examples/aspect_design_example.rb +2 -2
  6. data/examples/aspect_design_example_spec.rb +2 -2
  7. data/examples/design_by_contract_example.rb +4 -4
  8. data/examples/design_by_contract_example_spec.rb +4 -4
  9. data/examples/method_missing_example.rb +4 -1
  10. data/examples/method_missing_example_spec.rb +4 -1
  11. data/examples/method_tracing_example.rb +2 -2
  12. data/examples/method_tracing_example_spec.rb +16 -16
  13. data/lib/aquarium/aspects/advice.rb +47 -25
  14. data/lib/aquarium/aspects/aspect.rb +81 -39
  15. data/lib/aquarium/aspects/dsl/aspect_dsl.rb +1 -1
  16. data/lib/aquarium/aspects/exclusion_handler.rb +2 -2
  17. data/lib/aquarium/aspects/join_point.rb +28 -28
  18. data/lib/aquarium/aspects/pointcut.rb +61 -15
  19. data/lib/aquarium/extras/design_by_contract.rb +7 -7
  20. data/lib/aquarium/finders.rb +0 -1
  21. data/lib/aquarium/finders/method_finder.rb +10 -20
  22. data/lib/aquarium/finders/type_finder.rb +141 -75
  23. data/lib/aquarium/utils.rb +1 -0
  24. data/lib/aquarium/utils/logic_error.rb +9 -0
  25. data/lib/aquarium/utils/method_utils.rb +4 -3
  26. data/lib/aquarium/utils/nil_object.rb +1 -0
  27. data/lib/aquarium/utils/type_utils.rb +19 -0
  28. data/lib/aquarium/version.rb +2 -2
  29. data/spec/aquarium/aspects/advice_chain_node_spec.rb +2 -2
  30. data/spec/aquarium/aspects/advice_spec.rb +28 -5
  31. data/spec/aquarium/aspects/aspect_invocation_spec.rb +522 -289
  32. data/spec/aquarium/aspects/aspect_spec.rb +59 -41
  33. data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +7 -7
  34. data/spec/aquarium/aspects/aspect_with_subtypes_spec.rb +2 -2
  35. data/spec/aquarium/aspects/concurrent_aspects_spec.rb +1 -2
  36. data/spec/aquarium/aspects/concurrent_aspects_with_objects_and_types_spec.rb +1 -1
  37. data/spec/aquarium/aspects/dsl/aspect_dsl_spec.rb +34 -34
  38. data/spec/aquarium/aspects/join_point_spec.rb +79 -0
  39. data/spec/aquarium/aspects/pointcut_or_composition_spec.rb +13 -3
  40. data/spec/aquarium/aspects/pointcut_spec.rb +310 -63
  41. data/spec/aquarium/extras/design_by_contract_spec.rb +4 -4
  42. data/spec/aquarium/finders/method_finder_spec.rb +208 -54
  43. data/spec/aquarium/finders/type_finder_spec.rb +24 -88
  44. data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +206 -0
  45. data/spec/aquarium/spec_example_classes.rb +75 -12
  46. data/spec/aquarium/utils/logic_error_spec.rb +10 -0
  47. data/spec/aquarium/utils/type_utils_sample_classes.rb +203 -0
  48. data/spec/aquarium/utils/type_utils_spec.rb +47 -1
  49. metadata +48 -39
  50. data/lib/aquarium/finders/object_finder.rb +0 -75
  51. data/spec/aquarium/finders/object_finder_spec.rb +0 -231
@@ -7,7 +7,7 @@ describe Aquarium::Extras::DesignByContract, "precondition" do
7
7
  def action *args
8
8
  end
9
9
 
10
- precondition :method => :action, :message => "Must pass more than one argument." do |jp, *args|
10
+ precondition :method => :action, :message => "Must pass more than one argument." do |jp, obj, *args|
11
11
  args.size > 0
12
12
  end
13
13
  end
@@ -27,7 +27,7 @@ describe Aquarium::Extras::DesignByContract, "postcondition" do
27
27
  def action *args
28
28
  end
29
29
 
30
- postcondition :method => :action, :message => "Must pass more than one argument and first argument must be non-empty." do |jp, *args|
30
+ postcondition :method => :action, :message => "Must pass more than one argument and first argument must be non-empty." do |jp, obj, *args|
31
31
  args.size > 0 && ! args[0].empty?
32
32
  end
33
33
  end
@@ -58,8 +58,8 @@ describe Aquarium::Extras::DesignByContract, "invariant" do
58
58
  "bad"
59
59
  end
60
60
 
61
- invariant :methods => /action$/, :message => "Must not change the @invar value." do |jp, *args|
62
- jp.context.advised_object.invar == 0
61
+ invariant :methods => /action$/, :message => "Must not change the @invar value." do |jp, obj, *args|
62
+ obj.invar == 0
63
63
  end
64
64
  end
65
65
 
@@ -15,6 +15,18 @@ module M
15
15
  end
16
16
  def mmodule2
17
17
  end
18
+ def self.cmmodule1
19
+ end
20
+ end
21
+
22
+ module M2
23
+ include M
24
+ def mmodule3
25
+ end
26
+ def mmodule4
27
+ end
28
+ def self.cmmodule3
29
+ end
18
30
  end
19
31
 
20
32
  class Derived < Base
@@ -25,8 +37,24 @@ class Derived < Base
25
37
  end
26
38
  def mmodule1
27
39
  end
40
+ def mmodule2b
41
+ end
42
+ end
43
+
44
+ class Derived2 < Base
45
+ include M2
46
+ def mbase1
47
+ end
48
+ def mderived1
49
+ end
50
+ def mmodule1
51
+ end
52
+ def mmodule2b
53
+ end
28
54
  def mmodule3
29
55
  end
56
+ def mmodule4b
57
+ end
30
58
  end
31
59
 
32
60
  # :startdoc:
@@ -203,30 +231,75 @@ describe Aquarium::Finders::MethodFinder, "#find (behavior for derived classes)"
203
231
  before_method_finder_spec
204
232
  end
205
233
 
206
- it "should find Base and Derived methods in the specified class, by default." do
234
+ it "should find base and derived methods in the specified class, by default." do
207
235
  actual = Aquarium::Finders::MethodFinder.new.find :types => Derived, :methods => [/^mbase/, /^mmodule/]
208
236
  actual.matched.size.should == 1
209
- actual.matched[Derived].should == Set.new([:mbase1, :mbase2, :mmodule1, :mmodule2, :mmodule3])
237
+ actual.matched[Derived].should == Set.new([:mbase1, :mbase2, :mmodule1, :mmodule2, :mmodule2b])
210
238
  end
211
239
 
212
- it "should find Base and Derived methods in the specified object, by default." do
240
+ it "should find base and derived methods in the specified object, by default." do
213
241
  child = Derived.new
214
242
  actual = Aquarium::Finders::MethodFinder.new.find :object => child, :methods => [/^mbase/, /^mderived/, /^mmodule/]
215
243
  actual.matched.size.should == 1
216
- actual.matched[child].should == Set.new([:mbase1, :mbase2, :mderived1, :mmodule1, :mmodule2, :mmodule3])
244
+ actual.matched[child].should == Set.new([:mbase1, :mbase2, :mderived1, :mmodule1, :mmodule2, :mmodule2b])
217
245
  end
218
246
 
219
- it "should find Derived methods only for a type when ancestor methods are suppressed, which also suppresses method overrides." do
247
+ it "should only find Derived methods for a type when ancestor methods are excluded, which also excludes method overrides." do
220
248
  actual = Aquarium::Finders::MethodFinder.new.find :types => Derived, :methods => [/^mder/, /^mmod/], :options => [:exclude_ancestor_methods]
221
249
  actual.matched.size.should == 1
222
- actual.matched[Derived].should == Set.new([:mderived1, :mmodule3])
250
+ actual.matched[Derived].should == Set.new([:mderived1, :mmodule2b])
223
251
  end
224
252
 
225
- it "should find Derived methods only for an object when ancestor methods are suppressed, which also suppresses method overrides." do
253
+ it "should only find Derived methods for an object when ancestor methods are excluded, which also excludes method overrides." do
226
254
  child = Derived.new
227
255
  actual = Aquarium::Finders::MethodFinder.new.find :object => child, :methods => [/^mder/, /^mmodule/], :options => [:exclude_ancestor_methods]
228
256
  actual.matched.size.should == 1
229
- actual.matched[child].should == Set.new([:mderived1, :mmodule3])
257
+ actual.matched[child].should == Set.new([:mderived1, :mmodule2b])
258
+ end
259
+ end
260
+
261
+ describe Aquarium::Finders::MethodFinder, "#find (behavior for included modules)" do
262
+ before(:each) do
263
+ before_method_finder_spec
264
+ end
265
+
266
+ it "should find included and defined methods in the specified modules, by default." do
267
+ actual = Aquarium::Finders::MethodFinder.new.find :type => [M, M2], :methods => /^mmodule/
268
+ actual.matched.size.should == 2
269
+ actual.matched[M].should == Set.new([:mmodule1, :mmodule2])
270
+ actual.matched[M2].should == Set.new([:mmodule1, :mmodule2, :mmodule3, :mmodule4])
271
+ end
272
+
273
+ it "should find included and overridden methods in classes that include the specified modules, by default." do
274
+ actual = Aquarium::Finders::MethodFinder.new.find :types => [Derived, Derived2], :methods => /^mmodule/
275
+ actual.matched.size.should == 2
276
+ actual.matched[Derived].should == Set.new([:mmodule1, :mmodule2, :mmodule2b])
277
+ actual.matched[Derived2].should == Set.new([:mmodule1, :mmodule2, :mmodule2b, :mmodule3, :mmodule4, :mmodule4b])
278
+ end
279
+
280
+ it "should find included and overridden methods in instances of classes that include the specified modules, by default." do
281
+ child = Derived.new
282
+ child2 = Derived2.new
283
+ actual = Aquarium::Finders::MethodFinder.new.find :objects => [child, child2], :methods => /^mmodule/
284
+ actual.matched.size.should == 2
285
+ actual.matched[child].should == Set.new([:mmodule1, :mmodule2, :mmodule2b])
286
+ actual.matched[child2].should == Set.new([:mmodule1, :mmodule2, :mmodule2b, :mmodule3, :mmodule4, :mmodule4b])
287
+ end
288
+
289
+ it "should only find defined methods for a module when ancestor methods are excluded, which also excludes method overrides." do
290
+ actual = Aquarium::Finders::MethodFinder.new.find :type => [M, M2], :methods => /^mmod/, :options => [:exclude_ancestor_methods]
291
+ actual.matched.size.should == 2
292
+ actual.matched[M].should == Set.new([:mmodule1, :mmodule2])
293
+ actual.matched[M2].should == Set.new([:mmodule3, :mmodule4])
294
+ end
295
+
296
+ it "should not find any methods from included modules in classes when ancestor methods are excluded, which also excludes method overrides." do
297
+ child = Derived.new
298
+ child2 = Derived2.new
299
+ actual = Aquarium::Finders::MethodFinder.new.find :objects => [child, child2], :methods => /^mmodule/, :options => [:exclude_ancestor_methods]
300
+ actual.matched.size.should == 2
301
+ actual.matched[child].should == Set.new([:mmodule2b])
302
+ actual.matched[child2].should == Set.new([:mmodule2b, :mmodule4b])
230
303
  end
231
304
  end
232
305
 
@@ -235,7 +308,7 @@ describe Aquarium::Finders::MethodFinder, "#find (searching for class methods)"
235
308
  before_method_finder_spec
236
309
  end
237
310
 
238
- it "should find all class methods matching a regular expression for types when :class is used." do
311
+ it "should find all class methods specified by regular expression for types when :class is used." do
239
312
  # Have to add some rspec methods to the expected lists!
240
313
  expected = {}
241
314
  expected[Kernel] = [:chomp!, :chop!, :respond_to?]
@@ -266,12 +339,60 @@ describe Aquarium::Finders::MethodFinder, "#find (searching for class methods)"
266
339
  end
267
340
  end
268
341
 
342
+ describe Aquarium::Finders::MethodFinder, "#find (searching for class methods defined in modules)" do
343
+ before(:each) do
344
+ before_method_finder_spec
345
+ end
346
+
347
+ def do_class_methods_for_modules method_spec, options_spec
348
+ actual = Aquarium::Finders::MethodFinder.new.find :type => [M, M2], :methods => method_spec, :options => options_spec
349
+ actual.matched.size.should == 2
350
+ actual.matched[M].should == Set.new([:cmmodule1])
351
+ actual.matched[M2].should == Set.new([:cmmodule3])
352
+ end
353
+
354
+ it "should find all class methods specified by regular expression for modules when :class is used." do
355
+ do_class_methods_for_modules /^cmmodule/, [:class]
356
+ end
357
+
358
+ it "should find all class methods specified by name for modules when :class is used." do
359
+ do_class_methods_for_modules [:cmmodule1, :cmmodule3], [:class]
360
+ end
361
+
362
+ it "should not find class methods defined in included modules, because they do not become class methods in the including module." do
363
+ do_class_methods_for_modules /^cmmodule/, [:class]
364
+ end
365
+
366
+ it "should not find class methods defined in included modules, if ancestor methods are excluded explicitly." do
367
+ do_class_methods_for_modules /^cmmodule/, [:class, :exclude_ancestor_methods]
368
+ end
369
+
370
+ it "should find all public class methods in types when searching with the :all method specification and the :class option." do
371
+ actual = Aquarium::Finders::MethodFinder.new.find :type => [M, M2], :methods => :all, :options => [:class]
372
+ actual.matched.size.should == 2
373
+ actual.matched[M].should == Set.new(M.public_methods.sort.map{|m| m.intern})
374
+ actual.matched[M2].should == Set.new(M2.public_methods.sort.map{|m| m.intern})
375
+ end
376
+
377
+ it "should not find any module-defined class methods in classes that include the modules." do
378
+ actual = Aquarium::Finders::MethodFinder.new.find :types => [Derived, Derived2], :methods => /^cmmodule/, :options => [:class]
379
+ actual.matched.size.should == 0
380
+ end
381
+
382
+ it "should not find any module-defined class methods in instances of classes that include the modules." do
383
+ child = Derived.new
384
+ child2 = Derived2.new
385
+ actual = Aquarium::Finders::MethodFinder.new.find :objects => [child, child2], :methods => /^cmmodule/, :options => [:class]
386
+ actual.matched.size.should == 0
387
+ end
388
+ end
389
+
269
390
  describe Aquarium::Finders::MethodFinder, "#find (searching for instance methods)" do
270
391
  before(:each) do
271
392
  before_method_finder_spec
272
393
  end
273
394
 
274
- it "should find all public instance methods in types when searching with the :all method specification." do
395
+ it "should find all public instance methods in classes when searching with the :all method specification." do
275
396
  actual = Aquarium::Finders::MethodFinder.new.find :types => [ClassWithPublicInstanceMethod, ClassWithProtectedInstanceMethod, ClassWithPrivateInstanceMethod], :methods => :all
276
397
  actual.matched.size.should == 3
277
398
  [ClassWithPublicInstanceMethod, ClassWithProtectedInstanceMethod, ClassWithPrivateInstanceMethod].each do |c|
@@ -279,6 +400,13 @@ describe Aquarium::Finders::MethodFinder, "#find (searching for instance methods
279
400
  end
280
401
  end
281
402
 
403
+ it "should find all public instance methods in modules when searching with the :all method specification." do
404
+ actual = Aquarium::Finders::MethodFinder.new.find :types => [M, M2], :methods => :all
405
+ actual.matched.size.should == 2
406
+ actual.matched[M].should == Set.new([:mmodule1, :mmodule2])
407
+ actual.matched[M2].should == Set.new([:mmodule1, :mmodule2, :mmodule3, :mmodule4])
408
+ end
409
+
282
410
  it "should find all public instance methods in objects when searching with the :all method specification." do
283
411
  pub = ClassWithPublicInstanceMethod.new
284
412
  pro = ClassWithProtectedInstanceMethod.new
@@ -290,6 +418,22 @@ describe Aquarium::Finders::MethodFinder, "#find (searching for instance methods
290
418
  end
291
419
  end
292
420
 
421
+ it "should find the module-defined public instance methods in when searching a class with the :all method specification." do
422
+ actual = Aquarium::Finders::MethodFinder.new.find :types => [Derived, Derived2], :methods => :all
423
+ actual.matched.size.should == 2
424
+ [:mmodule1, :mmodule2].each {|m| actual.matched[Derived].should include(m)}
425
+ [:mmodule1, :mmodule2, :mmodule3, :mmodule4].each {|m| actual.matched[Derived2].should include(m)}
426
+ end
427
+
428
+ it "should find the module-defined public instance methods in when searching an instance of a class with the :all method specification." do
429
+ child = Derived.new
430
+ child2 = Derived2.new
431
+ actual = Aquarium::Finders::MethodFinder.new.find :types => [child, child2], :methods => :all
432
+ actual.matched.size.should == 2
433
+ [:mmodule1, :mmodule2].each {|m| actual.matched[child].should include(m)}
434
+ [:mmodule1, :mmodule2, :mmodule3, :mmodule4].each {|m| actual.matched[child2].should include(m)}
435
+ end
436
+
293
437
  it "should find only one instance method for a type when searching with a regexp matching one method." do
294
438
  actual = Aquarium::Finders::MethodFinder.new.find :types => ClassWithPublicInstanceMethod, :methods => /instance_test_method/
295
439
  actual.matched.size.should == 1
@@ -443,19 +587,41 @@ class ExcludeMethodTester
443
587
  end
444
588
 
445
589
  describe Aquarium::Finders::MethodFinder, "#find for types (using :exclude_methods)" do
446
- it "should return an empty result if :exclude_methods => :all specified." do
590
+ it "should return an empty result for classes if :exclude_methods => :all specified." do
447
591
  actual = Aquarium::Finders::MethodFinder.new.find :types => ExcludeMethodTester, :methods => :all, :exclude_methods => :all, :options => :exclude_ancestor_methods
448
592
  actual.matched.size.should == 0
449
593
  actual.not_matched.size.should == 0
450
594
  end
595
+ it "should return an empty result for modules if :exclude_methods => :all specified." do
596
+ actual = Aquarium::Finders::MethodFinder.new.find :types => M2, :methods => :all, :exclude_methods => :all, :options => :exclude_ancestor_methods
597
+ actual.matched.size.should == 0
598
+ actual.not_matched.size.should == 0
599
+ end
600
+ it "should return an empty result for classes including modules if :exclude_methods => :all specified." do
601
+ actual = Aquarium::Finders::MethodFinder.new.find :types => Derived2, :methods => :all, :exclude_methods => :all, :options => :exclude_ancestor_methods
602
+ actual.matched.size.should == 0
603
+ actual.not_matched.size.should == 0
604
+ end
451
605
 
452
- it "should remove excluded methods from the result where a single excluded methods is specified by name." do
606
+ it "should remove excluded methods from the result for classes where a single excluded methods is specified by name." do
453
607
  actual = Aquarium::Finders::MethodFinder.new.find :types => ExcludeMethodTester, :methods => :all, :exclude_method => :method1, :options => :exclude_ancestor_methods
454
608
  actual.matched.size.should == 1
455
609
  actual.matched[ExcludeMethodTester].size.should == 2
456
610
  actual.matched[ExcludeMethodTester].should == Set.new([:method2, :method3])
457
611
  actual.not_matched.size.should == 0
458
612
  end
613
+ it "should remove excluded methods from the result for modules where a single excluded methods is specified by name." do
614
+ actual = Aquarium::Finders::MethodFinder.new.find :types => M, :methods => :all, :exclude_method => :mmodule1
615
+ actual.matched.size.should == 1
616
+ actual.matched[M].size.should == 1
617
+ actual.matched[M].should == Set.new([:mmodule2])
618
+ actual.not_matched.size.should == 0
619
+ end
620
+ it "should remove excluded methods from the result for classes that include modules where a single excluded methods is specified by name." do
621
+ actual = Aquarium::Finders::MethodFinder.new.find :types => Derived, :methods => :all, :exclude_method => :mmodule1
622
+ actual.matched.size.should == 1
623
+ actual.matched[Derived].should_not include(:mmodule1)
624
+ end
459
625
 
460
626
  it "should remove excluded methods from the result where the excluded methods are specified by an array of names." do
461
627
  actual = Aquarium::Finders::MethodFinder.new.find :types => ExcludeMethodTester, :methods => :all, :exclude_methods => [:method1, :method2], :options => :exclude_ancestor_methods
@@ -488,11 +654,16 @@ describe Aquarium::Finders::MethodFinder, "#find for types (using :exclude_metho
488
654
  end
489
655
 
490
656
  describe Aquarium::Finders::MethodFinder, "#find for objects (using :exclude_methods)" do
491
- it "should return an empty result if :exclude_methods => :all specified." do
657
+ it "should return an empty result for instances of classes if :exclude_methods => :all specified." do
492
658
  actual = Aquarium::Finders::MethodFinder.new.find :object => ExcludeMethodTester.new, :methods => :all, :exclude_methods => :all, :options => :exclude_ancestor_methods
493
659
  actual.matched.size.should == 0
494
660
  actual.not_matched.size.should == 0
495
661
  end
662
+ it "should return an empty result for for instances of classes that include modules if :exclude_methods => :all specified." do
663
+ actual = Aquarium::Finders::MethodFinder.new.find :object => Derived2.new, :methods => :all, :exclude_methods => :all, :options => :exclude_ancestor_methods
664
+ actual.matched.size.should == 0
665
+ actual.not_matched.size.should == 0
666
+ end
496
667
 
497
668
  it "should remove excluded methods from the result where a single excluded methods is specified by name." do
498
669
  emt = ExcludeMethodTester.new
@@ -542,7 +713,7 @@ describe Aquarium::Finders::MethodFinder, "#find (using :options => :exclude_anc
542
713
  before_method_finder_spec
543
714
  end
544
715
 
545
- it "should suppress ancestor methods for types when :exclude_ancestor_methods is specified." do
716
+ it "should suppress ancestor methods for classes when :exclude_ancestor_methods is specified." do
546
717
  actual = Aquarium::Finders::MethodFinder.new.find :types => @test_classes, :methods => /test_method/, :options => [:public, :instance, :exclude_ancestor_methods]
547
718
  actual.matched.size.should == 1
548
719
  actual.matched[ClassWithPublicInstanceMethod].should == Set.new([:public_instance_test_method])
@@ -552,7 +723,6 @@ describe Aquarium::Finders::MethodFinder, "#find (using :options => :exclude_anc
552
723
  actual.not_matched[ClassWithPublicClassMethod].should == Set.new([/test_method/])
553
724
  actual.not_matched[ClassWithPrivateClassMethod].should == Set.new([/test_method/])
554
725
  end
555
-
556
726
  it "should suppress ancestor methods for objects when :exclude_ancestor_methods is specified." do
557
727
  actual = Aquarium::Finders::MethodFinder.new.find :objects => @test_objects, :methods => /test_method/, :options => [:public, :instance, :exclude_ancestor_methods]
558
728
  actual.matched.size.should == 1
@@ -563,6 +733,29 @@ describe Aquarium::Finders::MethodFinder, "#find (using :options => :exclude_anc
563
733
  actual.not_matched[@cpub].should == Set.new([/test_method/])
564
734
  actual.not_matched[@cpri].should == Set.new([/test_method/])
565
735
  end
736
+
737
+ it "should suppress ancestor methods for modules when :exclude_ancestor_methods is specified." do
738
+ actual = Aquarium::Finders::MethodFinder.new.find :type => M2, :methods => /^mmodule/, :options => [:instance, :exclude_ancestor_methods]
739
+ actual.matched.size.should == 1
740
+ actual.matched[M2].should == Set.new([:mmodule3, :mmodule4])
741
+ actual.not_matched.size.should == 0
742
+ end
743
+ it "should suppress ancestor methods for classes including modules when :exclude_ancestor_methods is specified." do
744
+ actual = Aquarium::Finders::MethodFinder.new.find :types => [Derived, Derived2], :methods => /^mmodule/, :options => [:instance, :exclude_ancestor_methods]
745
+ actual.matched.size.should == 2
746
+ actual.matched[Derived].should == Set.new([:mmodule2b])
747
+ actual.matched[Derived2].should == Set.new([:mmodule2b, :mmodule4b])
748
+ actual.not_matched.size.should == 0
749
+ end
750
+ it "should suppress ancestor methods for instances of classes including modules when :exclude_ancestor_methods is specified." do
751
+ child = Derived.new
752
+ child2 = Derived2.new
753
+ actual = Aquarium::Finders::MethodFinder.new.find :types => [child, child2], :methods => /^mmodule/, :options => [:instance, :exclude_ancestor_methods]
754
+ actual.matched.size.should == 2
755
+ actual.matched[child].should == Set.new([:mmodule2b])
756
+ actual.matched[child2].should == Set.new([:mmodule2b, :mmodule4b])
757
+ actual.not_matched.size.should == 0
758
+ end
566
759
  end
567
760
 
568
761
  describe Aquarium::Finders::MethodFinder, "#find (using :options => [:public, :instance])" do
@@ -925,45 +1118,6 @@ describe "Aquarium::Finders::MethodFinder#find (looking for methods that end in
925
1118
  end
926
1119
  end
927
1120
 
928
- describe "Aquarium::Finders::MethodFinder#find_all_by" do
929
- it "should accept :all for the methods argument." do
930
- actual = Aquarium::Finders::MethodFinder.new.find_all_by ClassWithPublicInstanceMethod, :all, :exclude_ancestor_methods
931
- actual.matched.size.should == 1
932
- actual.matched[ClassWithPublicInstanceMethod].should == Set.new([:public_instance_test_method])
933
- actual.not_matched.size.should == 0
934
- pub = ClassWithPublicInstanceMethod.new
935
- actual = Aquarium::Finders::MethodFinder.new.find_all_by pub, :all, :exclude_ancestor_methods
936
- actual.matched.size.should == 1
937
- actual.matched[pub].should == Set.new([:public_instance_test_method])
938
- actual.not_matched.size.should == 0
939
- end
940
-
941
- it "should behave like Aquarium::Finders::MethodFinder#find with an explicit parameter list rather than a hash." do
942
- expected = Aquarium::Finders::MethodFinder.new.find :types => ClassWithPrivateInstanceMethod,
943
- :methods => /test_method/, :options => [:private, :instance, :exclude_ancestor_methods]
944
- actual = Aquarium::Finders::MethodFinder.new.find_all_by ClassWithPrivateInstanceMethod,
945
- /test_method/, :private, :instance, :exclude_ancestor_methods
946
- actual.should == expected
947
-
948
- expected = Aquarium::Finders::MethodFinder.new.find :objects => @pub,
949
- :methods => /test_method/, :options => [:private, :instance, :exclude_ancestor_methods]
950
- actual = Aquarium::Finders::MethodFinder.new.find_all_by @pub,
951
- /test_method/, :private, :instance, :exclude_ancestor_methods
952
- actual.should == expected
953
-
954
- expected = Aquarium::Finders::MethodFinder.new.find :types => [ClassWithPublicInstanceMethod, ClassWithPrivateInstanceMethod],
955
- :methods => ["foo", /test_method/], :options => [:instance, :exclude_ancestor_methods]
956
- actual = Aquarium::Finders::MethodFinder.new.find_all_by [ClassWithPublicInstanceMethod, ClassWithPrivateInstanceMethod],
957
- ["foo", /test_method/], :instance, :exclude_ancestor_methods
958
- actual.should == expected
959
-
960
- expected = Aquarium::Finders::MethodFinder.new.find :objects => [@pub, @pri],
961
- :methods => ["foo", /test_method/], :options => [:instance, :exclude_ancestor_methods]
962
- actual = Aquarium::Finders::MethodFinder.new.find_all_by [@pub, @pri],
963
- ["foo", /test_method/], :instance, :exclude_ancestor_methods
964
- actual.should == expected
965
- end
966
- end
967
1121
 
968
1122
  describe "Aquarium::Finders::MethodFinder.is_recognized_method_option" do
969
1123
 
@@ -1,7 +1,14 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper.rb'
2
2
  require 'aquarium/finders/type_finder'
3
3
 
4
- describe Aquarium::Finders::TypeFinder, "#find" do
4
+ class Outside
5
+ class Inside1; end
6
+ class Inside2
7
+ class ReallyInside; end
8
+ end
9
+ end
10
+
11
+ describe Aquarium::Finders::TypeFinder, "#find invocation parameters" do
5
12
 
6
13
  it "should raise if an uknown option is specified." do
7
14
  lambda { Aquarium::Finders::TypeFinder.new.find :foo => 'bar', :baz => ''}.should raise_error(Aquarium::Utils::InvalidOptions)
@@ -11,6 +18,10 @@ describe Aquarium::Finders::TypeFinder, "#find" do
11
18
  lambda { Aquarium::Finders::TypeFinder.new.find "foo" }.should raise_error(Aquarium::Utils::InvalidOptions)
12
19
  end
13
20
 
21
+ it "should raise if the input type value is nil." do
22
+ lambda { Aquarium::Finders::TypeFinder.new.find :type => nil }.should raise_error(Aquarium::Utils::InvalidOptions)
23
+ end
24
+
14
25
  it "should return no matched types and no unmatched type expressions by default (i.e., the input is empty)." do
15
26
  actual = Aquarium::Finders::TypeFinder.new.find
16
27
  actual.matched.should == {}
@@ -40,6 +51,15 @@ describe Aquarium::Finders::TypeFinder, "#find" do
40
51
  actual.matched.should == {}
41
52
  actual.not_matched.should == {}
42
53
  end
54
+
55
+ it "should accept a hash and treat it as equivalent to an explicit list parameters." do
56
+ expected_found_types = [Outside::Inside1, Outside::Inside2]
57
+ expected_unfound_exps = %w[Foo::Bar::Baz]
58
+ hash = {:names => (expected_found_types.map {|t| t.to_s} + expected_unfound_exps)}
59
+ actual = Aquarium::Finders::TypeFinder.new.find hash
60
+ actual.matched_keys.sort_by {|x| x.to_s}.should == expected_found_types.sort_by {|x| x.to_s}
61
+ actual.not_matched_keys.sort.should == expected_unfound_exps.sort
62
+ end
43
63
  end
44
64
 
45
65
  describe Aquarium::Finders::TypeFinder, "#is_recognized_option" do
@@ -59,12 +79,6 @@ describe Aquarium::Finders::TypeFinder, "#is_recognized_option" do
59
79
  end
60
80
  end
61
81
 
62
- class Outside
63
- class Inside1; end
64
- class Inside2
65
- class ReallyInside; end
66
- end
67
- end
68
82
 
69
83
  describe Aquarium::Finders::TypeFinder, "#find with :type or :name used to specify a single type" do
70
84
  it "should find a type matching a simple name (without :: namespace delimiters) using its name and the :type option." do
@@ -123,7 +137,8 @@ describe Aquarium::Finders::TypeFinder, "#find with :types, :names, :type, and :
123
137
  expected_found_types = [FalseClass, Module, TrueClass]
124
138
  expected_unfound_exps = []
125
139
  actual = Aquarium::Finders::TypeFinder.new.find :types => [/eClass$/, /^Modu/]
126
- actual.matched_keys.sort_by {|x| x.to_s}.should == expected_found_types.sort_by {|x| x.to_s}
140
+ expected_found_types.each {|t| actual.matched_keys.should include(t)}
141
+ # actual.matched_keys.sort_by {|x| x.to_s}.should == expected_found_types.sort_by {|x| x.to_s}
127
142
  actual.not_matched_keys.sort.should == expected_unfound_exps.sort
128
143
  end
129
144
 
@@ -209,87 +224,8 @@ describe Aquarium::Finders::TypeFinder, "#find" do
209
224
  end
210
225
  end
211
226
 
212
- describe Aquarium::Finders::TypeFinder, "#find_all_by" do
213
- it "should find types with :: namespace delimiters using lists of regular expressions." do
214
- expected_found_types = [Outside::Inside1, Outside::Inside2]
215
- expected_unfound_exps = [/^.*Fo+::.*Bar+::Baz.$/]
216
- actual = Aquarium::Finders::TypeFinder.new.find_all_by [/^.*Fo+::.*Bar+::Baz.$/, /Outside::.*1$/, /Out.*::In.*2/]
217
- actual.matched_keys.sort_by {|x| x.to_s}.should == expected_found_types.sort_by {|x| x.to_s}
218
- actual.not_matched_keys.should == expected_unfound_exps
219
- end
220
-
221
- it "should find types with :: namespace delimiters using their names." do
222
- expected_found_types = [Outside::Inside1, Outside::Inside2]
223
- expected_unfound_exps = %w[Foo::Bar::Baz]
224
- actual = Aquarium::Finders::TypeFinder.new.find_all_by(expected_found_types.map {|t| t.to_s} + expected_unfound_exps)
225
- actual.matched_keys.sort_by {|x| x.to_s}.should == expected_found_types.sort_by {|x| x.to_s}
226
- actual.not_matched_keys.should == expected_unfound_exps
227
- end
228
-
229
- it "should find types when types given." do
230
- expected_found_types = [Outside::Inside1, Outside::Inside2]
231
- actual = Aquarium::Finders::TypeFinder.new.find_all_by expected_found_types
232
- actual.matched_keys.sort_by {|x| x.to_s}.should == expected_found_types.sort_by {|x| x.to_s}
233
- actual.not_matched_keys.should == []
234
- end
235
- end
236
-
237
- describe Aquarium::Finders::TypeFinder, "#find_by_name" do
238
- it "should find a single type when given a single type name." do
239
- tf = Aquarium::Finders::TypeFinder.new
240
- actual = tf.find_by_name("String")
241
- actual.matched_keys.should == [String]
242
- actual.not_matched_keys.should == []
243
- actual = tf.find_by_name("Kernel")
244
- actual.matched_keys.should == [Kernel]
245
- actual.not_matched_keys.should == []
246
- actual = tf.find_by_name("Module")
247
- actual.matched_keys.should == [Module]
248
- actual.not_matched_keys.should == []
249
- end
250
-
251
- it "should find a single type when given a valid type name with :: separators." do
252
- tf = Aquarium::Finders::TypeFinder.new
253
- actual = tf.find_by_name "Outside::Inside1"
254
- actual.matched_keys.should == [Outside::Inside1]
255
- actual.not_matched_keys.should == []
256
- end
257
-
258
- it "should find a single type when given that type." do
259
- tf = Aquarium::Finders::TypeFinder.new
260
- actual = tf.find_by_name Outside::Inside1
261
- actual.matched_keys.should == [Outside::Inside1]
262
- actual.not_matched_keys.should == []
263
- end
264
-
265
- it "should return no matches if the type can't be found." do
266
- tf = Aquarium::Finders::TypeFinder.new
267
- actual = tf.find_by_name "UnknownClass1::UnknownClass2"
268
- actual.matched_keys.should == []
269
- actual.not_matched_keys.should == ["UnknownClass1::UnknownClass2"]
270
- end
271
-
272
- it "should return no matches if the type name is invalid." do
273
- tf = Aquarium::Finders::TypeFinder.new
274
- actual = tf.find_by_name "$foo:bar"
275
- actual.matched_keys.should == []
276
- actual.not_matched_keys.should == ["$foo:bar"]
277
- end
278
- end
279
-
280
- describe Aquarium::Finders::TypeFinder, "#find_by_type" do
281
- it "is synonymous with find_by_name." do
282
- tf = Aquarium::Finders::TypeFinder.new
283
- actual = tf.find_by_name "Outside::Inside1"
284
- actual.matched_keys.should == [Outside::Inside1]
285
- actual.not_matched_keys.should == []
286
- actual = tf.find_by_name Outside::Inside1
287
- actual.matched_keys.should == [Outside::Inside1]
288
- actual.not_matched_keys.should == []
289
- end
290
- end
291
227
 
292
- # This is a spec for a protected method.
228
+ # This is a spec for a protected method. It's primarily to keep the code coverage 100%, because there is rarely-invoked error handling code...
293
229
  describe Aquarium::Finders::TypeFinder, "#get_type_from_parent should" do
294
230
  it "should raise if a type doesn't exist that matches the constant" do
295
231
  lambda {Aquarium::Finders::TypeFinder.new.send(:get_type_from_parent, Aquarium::Finders, "Nonexistent", /Non/)}.should raise_error(NameError)