aquarium 0.1.8 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +59 -2
- data/README +33 -16
- data/RELEASE-PLAN +28 -5
- data/UPGRADE +11 -0
- data/examples/aspect_design_example.rb +2 -2
- data/examples/aspect_design_example_spec.rb +2 -2
- data/examples/design_by_contract_example.rb +4 -4
- data/examples/design_by_contract_example_spec.rb +4 -4
- data/examples/method_missing_example.rb +4 -1
- data/examples/method_missing_example_spec.rb +4 -1
- data/examples/method_tracing_example.rb +2 -2
- data/examples/method_tracing_example_spec.rb +16 -16
- data/lib/aquarium/aspects/advice.rb +47 -25
- data/lib/aquarium/aspects/aspect.rb +81 -39
- data/lib/aquarium/aspects/dsl/aspect_dsl.rb +1 -1
- data/lib/aquarium/aspects/exclusion_handler.rb +2 -2
- data/lib/aquarium/aspects/join_point.rb +28 -28
- data/lib/aquarium/aspects/pointcut.rb +61 -15
- data/lib/aquarium/extras/design_by_contract.rb +7 -7
- data/lib/aquarium/finders.rb +0 -1
- data/lib/aquarium/finders/method_finder.rb +10 -20
- data/lib/aquarium/finders/type_finder.rb +141 -75
- data/lib/aquarium/utils.rb +1 -0
- data/lib/aquarium/utils/logic_error.rb +9 -0
- data/lib/aquarium/utils/method_utils.rb +4 -3
- data/lib/aquarium/utils/nil_object.rb +1 -0
- data/lib/aquarium/utils/type_utils.rb +19 -0
- data/lib/aquarium/version.rb +2 -2
- data/spec/aquarium/aspects/advice_chain_node_spec.rb +2 -2
- data/spec/aquarium/aspects/advice_spec.rb +28 -5
- data/spec/aquarium/aspects/aspect_invocation_spec.rb +522 -289
- data/spec/aquarium/aspects/aspect_spec.rb +59 -41
- data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +7 -7
- data/spec/aquarium/aspects/aspect_with_subtypes_spec.rb +2 -2
- data/spec/aquarium/aspects/concurrent_aspects_spec.rb +1 -2
- data/spec/aquarium/aspects/concurrent_aspects_with_objects_and_types_spec.rb +1 -1
- data/spec/aquarium/aspects/dsl/aspect_dsl_spec.rb +34 -34
- data/spec/aquarium/aspects/join_point_spec.rb +79 -0
- data/spec/aquarium/aspects/pointcut_or_composition_spec.rb +13 -3
- data/spec/aquarium/aspects/pointcut_spec.rb +310 -63
- data/spec/aquarium/extras/design_by_contract_spec.rb +4 -4
- data/spec/aquarium/finders/method_finder_spec.rb +208 -54
- data/spec/aquarium/finders/type_finder_spec.rb +24 -88
- data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +206 -0
- data/spec/aquarium/spec_example_classes.rb +75 -12
- data/spec/aquarium/utils/logic_error_spec.rb +10 -0
- data/spec/aquarium/utils/type_utils_sample_classes.rb +203 -0
- data/spec/aquarium/utils/type_utils_spec.rb +47 -1
- metadata +48 -39
- data/lib/aquarium/finders/object_finder.rb +0 -75
- 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
|
-
|
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
|
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, :
|
237
|
+
actual.matched[Derived].should == Set.new([:mbase1, :mbase2, :mmodule1, :mmodule2, :mmodule2b])
|
210
238
|
end
|
211
239
|
|
212
|
-
it "should find
|
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, :
|
244
|
+
actual.matched[child].should == Set.new([:mbase1, :mbase2, :mderived1, :mmodule1, :mmodule2, :mmodule2b])
|
217
245
|
end
|
218
246
|
|
219
|
-
it "should find Derived methods
|
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, :
|
250
|
+
actual.matched[Derived].should == Set.new([:mderived1, :mmodule2b])
|
223
251
|
end
|
224
252
|
|
225
|
-
it "should find Derived methods
|
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, :
|
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
|
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
|
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
|
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
|
-
|
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
|
-
|
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)
|