aquarium 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Aquarium.ipr +253 -0
- data/Aquarium.iws +629 -0
- data/CHANGES +43 -0
- data/UPGRADE +13 -7
- data/examples/method_tracing_example_spec.rb +4 -1
- data/lib/aquarium/aspects/aspect.rb +28 -11
- data/lib/aquarium/aspects/exclusion_handler.rb +1 -1
- data/lib/aquarium/aspects/join_point.rb +58 -14
- data/lib/aquarium/aspects/pointcut.rb +5 -6
- data/lib/aquarium/extras/design_by_contract.rb +1 -1
- data/lib/aquarium/finders/method_finder.rb +1 -4
- data/lib/aquarium/finders/type_finder.rb +8 -1
- data/lib/aquarium/utils.rb +1 -0
- data/lib/aquarium/utils/default_logger.rb +20 -0
- data/lib/aquarium/utils/options_utils.rb +74 -12
- data/lib/aquarium/utils/type_utils.rb +1 -7
- data/lib/aquarium/version.rb +1 -1
- data/spec/aquarium/aspects/advice_chain_node_spec.rb +1 -1
- data/spec/aquarium/aspects/advice_spec.rb +1 -1
- data/spec/aquarium/aspects/aspect_invocation_spec.rb +1531 -1465
- data/spec/aquarium/aspects/aspect_spec.rb +22 -27
- data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +1 -1
- data/spec/aquarium/aspects/aspect_with_subtypes_spec.rb +1 -1
- data/spec/aquarium/aspects/concurrent_aspects_spec.rb +1 -1
- data/spec/aquarium/aspects/concurrent_aspects_with_objects_and_types_spec.rb +1 -1
- data/spec/aquarium/aspects/dsl/aspect_dsl_spec.rb +434 -424
- data/spec/aquarium/aspects/join_point_spec.rb +27 -4
- data/spec/aquarium/aspects/pointcut_and_composition_spec.rb +98 -102
- data/spec/aquarium/aspects/pointcut_or_composition_spec.rb +95 -107
- data/spec/aquarium/aspects/pointcut_spec.rb +1365 -1382
- data/spec/aquarium/extensions/hash_spec.rb +1 -1
- data/spec/aquarium/extensions/set_spec.rb +1 -1
- data/spec/aquarium/finders/finder_result_spec.rb +1 -1
- data/spec/aquarium/finders/method_finder_spec.rb +1 -1
- data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +63 -145
- data/spec/aquarium/{spec_example_classes.rb → spec_example_types.rb} +35 -0
- data/spec/aquarium/utils/default_logger_spec.rb +28 -0
- data/spec/aquarium/utils/hash_utils_spec.rb +1 -1
- data/spec/aquarium/utils/logic_error_spec.rb +1 -1
- data/spec/aquarium/utils/name_utils_spec.rb +1 -1
- data/spec/aquarium/utils/nil_object_spec.rb +1 -1
- data/spec/aquarium/utils/options_utils_spec.rb +122 -0
- data/spec/aquarium/utils/set_utils_spec.rb +1 -1
- metadata +9 -4
@@ -1,5 +1,5 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
-
require File.dirname(__FILE__) + '/../
|
2
|
+
require File.dirname(__FILE__) + '/../spec_example_types'
|
3
3
|
|
4
4
|
require 'aquarium/extensions/hash'
|
5
5
|
require 'aquarium/aspects/join_point'
|
@@ -22,18 +22,41 @@ end
|
|
22
22
|
|
23
23
|
describe Aquarium::Aspects::JoinPoint, "#initialize with invalid parameters" do
|
24
24
|
|
25
|
-
it "should require either a :type or an :object parameter
|
25
|
+
it "should require either a :type or an :object parameter, but not both." do
|
26
26
|
lambda { Aquarium::Aspects::JoinPoint.new :method_name => :count }.should raise_error(Aquarium::Utils::InvalidOptions)
|
27
27
|
lambda { Aquarium::Aspects::JoinPoint.new :type => String, :object => "", :method_name => :count }.should raise_error(Aquarium::Utils::InvalidOptions)
|
28
28
|
end
|
29
29
|
|
30
|
-
it "should require a :method_name
|
30
|
+
it "should require a :method_name." do
|
31
31
|
lambda { Aquarium::Aspects::JoinPoint.new :type => String }.should raise_error(Aquarium::Utils::InvalidOptions)
|
32
32
|
end
|
33
33
|
|
34
|
-
it "should except :method as a synonym for
|
34
|
+
it "should except :method as a synonym for :method_name." do
|
35
35
|
lambda { Aquarium::Aspects::JoinPoint.new :type => String, :method => :split }.should_not raise_error(Aquarium::Utils::InvalidOptions)
|
36
36
|
end
|
37
|
+
|
38
|
+
it "should require a valid type name if a name is specified." do
|
39
|
+
lambda { Aquarium::Aspects::JoinPoint.new :type => "String", :method => :split }.should_not raise_error(Aquarium::Utils::InvalidOptions)
|
40
|
+
lambda { Aquarium::Aspects::JoinPoint.new :type => "Stringgy", :method => :split }.should raise_error(Aquarium::Utils::InvalidOptions)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should require a valid type name symbol if a name is specified." do
|
44
|
+
lambda { Aquarium::Aspects::JoinPoint.new :type => :String, :method => :split }.should_not raise_error(Aquarium::Utils::InvalidOptions)
|
45
|
+
lambda { Aquarium::Aspects::JoinPoint.new :type => :Stringgy, :method => :split }.should raise_error(Aquarium::Utils::InvalidOptions)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should require a valid type name regular expression if one is specified." do
|
49
|
+
lambda { Aquarium::Aspects::JoinPoint.new :type => /^String$/, :method => :split }.should_not raise_error(Aquarium::Utils::InvalidOptions)
|
50
|
+
lambda { Aquarium::Aspects::JoinPoint.new :type => /^Stringgy$/, :method => :split }.should raise_error(Aquarium::Utils::InvalidOptions)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should reject a regular expression that matches no types." do
|
54
|
+
lambda { Aquarium::Aspects::JoinPoint.new :type => /^Stringgy$/, :method => :split }.should raise_error(Aquarium::Utils::InvalidOptions)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should reject a regular expression that matches more than one type." do
|
58
|
+
lambda { Aquarium::Aspects::JoinPoint.new :type => /^M/, :method => :split }.should raise_error(Aquarium::Utils::InvalidOptions)
|
59
|
+
end
|
37
60
|
end
|
38
61
|
|
39
62
|
describe Aquarium::Aspects::JoinPoint, "#initialize with parameters that specify class vs. instance methods" do
|
@@ -1,14 +1,39 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
-
require File.dirname(__FILE__) + '/../
|
2
|
+
require File.dirname(__FILE__) + '/../spec_example_types'
|
3
3
|
require 'aquarium/utils'
|
4
4
|
require 'aquarium/extensions'
|
5
5
|
require 'aquarium/aspects/pointcut'
|
6
6
|
require 'aquarium/aspects/pointcut_composition'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
include Aquarium::Utils::HashUtils
|
9
|
+
include Aquarium::Aspects
|
10
|
+
|
11
|
+
describe Pointcut, "#and" do
|
12
|
+
it "should return a new Pointcut." do
|
13
|
+
pc1 = Pointcut.new
|
14
|
+
pc2 = Pointcut.new :types => ClassWithPublicInstanceMethod, :method_options => :exclude_ancestor_methods
|
15
|
+
pc12 = (pc1.and(pc2))
|
16
|
+
pc12.should_not equal(pc1)
|
17
|
+
pc12.should_not equal(pc2)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe Pointcut, "#and (when one pointcut is empty)" do
|
22
|
+
before :all do
|
23
|
+
@pc1 = Pointcut.new
|
24
|
+
@pc2 = Pointcut.new :types => ClassWithPublicInstanceMethod, :method_options => :exclude_ancestor_methods
|
25
|
+
end
|
11
26
|
|
27
|
+
it "should return a new empty Pointcut if the left-hand Pointcut is empty, independent of the right-hand Pointcut." do
|
28
|
+
(@pc1.and(@pc2)).should == @pc1
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return a new empty Pointcut if the right-hand Pointcut is empty, independent of the left-hand Pointcut." do
|
32
|
+
(@pc2.and(@pc1)).should == @pc1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe Pointcut, "#and (when both pointcuts are not empty)" do
|
12
37
|
before(:each) do
|
13
38
|
@example_types = {}
|
14
39
|
[ClassWithPublicInstanceMethod, ClassWithProtectedInstanceMethod, ClassWithPrivateInstanceMethod,
|
@@ -16,145 +41,116 @@ describe "Intersection of Pointcuts", :shared => true do
|
|
16
41
|
@empty_set = Set.new
|
17
42
|
end
|
18
43
|
|
19
|
-
it "should return
|
20
|
-
pc1 =
|
21
|
-
pc2 =
|
22
|
-
(pc1.and(pc2)).should == pc1
|
23
|
-
pc3 = Aquarium::Aspects::Pointcut.new :object => ClassWithPublicInstanceMethod.new
|
24
|
-
(pc1.and(pc3)).should == pc1
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should return an empty Aquarium::Aspects::Pointcut if the second pointcut has no join points." do
|
28
|
-
pc1 = Aquarium::Aspects::Pointcut.new :types => /Class.*Method/
|
29
|
-
pc2 = Aquarium::Aspects::Pointcut.new
|
30
|
-
(pc1.and(pc2)).should == pc2
|
31
|
-
pc3 = Aquarium::Aspects::Pointcut.new :object => ClassWithPublicInstanceMethod.new
|
32
|
-
(pc3.and(pc2)).should == pc2
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should return a new Aquarium::Aspects::Pointcut whose join points are the intersection of the left- and right-hand side Aquarium::Aspects::Pointcuts, each with multiple types." do
|
36
|
-
pc1 = Aquarium::Aspects::Pointcut.new :types => [ClassWithAttribs, ClassWithPublicInstanceMethod, ClassWithPrivateInstanceMethod], :attributes => [/^attr/], :attribute_options => [:readers]
|
37
|
-
pc2 = Aquarium::Aspects::Pointcut.new :types => [ClassWithAttribs, ClassWithPublicInstanceMethod, ClassWithProtectedInstanceMethod], :attributes => :attrRW_ClassWithAttribs
|
44
|
+
it "should return a new Pointcut whose join points are the intersection of the left- and right-hand side Pointcuts, each with multiple types." do
|
45
|
+
pc1 = Pointcut.new :types => [ClassWithAttribs, ClassWithPublicInstanceMethod, ClassWithPrivateInstanceMethod], :attributes => [/^attr/], :attribute_options => [:readers]
|
46
|
+
pc2 = Pointcut.new :types => [ClassWithAttribs, ClassWithPublicInstanceMethod, ClassWithProtectedInstanceMethod], :attributes => :attrRW_ClassWithAttribs, :attribute_options => [:exclude_ancestor_methods]
|
38
47
|
pc = pc1.and pc2
|
39
|
-
expected_jp =
|
48
|
+
expected_jp = JoinPoint.new :type => ClassWithAttribs, :method => :attrRW_ClassWithAttribs
|
40
49
|
pc.join_points_matched.should == Set.new([expected_jp])
|
41
50
|
pc.join_points_not_matched.should == @empty_set
|
42
51
|
end
|
43
52
|
|
44
|
-
it "should return a new
|
53
|
+
it "should return a new Pointcut whose join points are the intersection of the left- and right-hand side Pointcuts, each with multiple objects." do
|
45
54
|
cwa = ClassWithAttribs.new
|
46
55
|
pub = ClassWithPublicInstanceMethod.new
|
47
56
|
pri = ClassWithPrivateInstanceMethod.new
|
48
57
|
pro = ClassWithProtectedInstanceMethod.new
|
49
|
-
pc1 =
|
50
|
-
pc2 =
|
58
|
+
pc1 = Pointcut.new :objects => [cwa, pub, pri], :attributes => [/^attr/], :attribute_options => [:readers, :exclude_ancestor_methods]
|
59
|
+
pc2 = Pointcut.new :objects => [cwa, pub, pro], :attributes => :attrRW_ClassWithAttribs
|
51
60
|
pc = pc1.and pc2
|
52
|
-
expected_jp =
|
61
|
+
expected_jp = JoinPoint.new :object => cwa, :method => :attrRW_ClassWithAttribs
|
53
62
|
pc.join_points_matched.should == Set.new([expected_jp])
|
54
63
|
pc.join_points_not_matched.should == @empty_set
|
55
64
|
end
|
56
65
|
|
57
|
-
it "should return a new
|
58
|
-
pc1 =
|
59
|
-
pc2 =
|
66
|
+
it "should return a new Pointcut whose join points are the intersection of the left- and right-hand side Pointcuts, each with a single type." do
|
67
|
+
pc1 = Pointcut.new :types => "ClassWithAttribs", :attributes => [/^attr/], :attribute_options => [:readers]
|
68
|
+
pc2 = Pointcut.new :types => "ClassWithAttribs", :attributes => :attrRW_ClassWithAttribs
|
60
69
|
pc = pc1.and pc2
|
61
|
-
expected_jp =
|
70
|
+
expected_jp = JoinPoint.new :type => ClassWithAttribs, :method => :attrRW_ClassWithAttribs
|
62
71
|
pc.join_points_matched.should == Set.new([expected_jp])
|
63
72
|
pc.join_points_not_matched.should == @empty_set
|
64
73
|
end
|
65
74
|
|
66
|
-
it "should return a new
|
75
|
+
it "should return a new Pointcut whose join points are the intersection of the left- and right-hand side Pointcuts, each with a single object." do
|
67
76
|
cwa = ClassWithAttribs.new
|
68
|
-
pc1 =
|
69
|
-
pc2 =
|
77
|
+
pc1 = Pointcut.new :object => cwa, :attributes => [/^attr/], :attribute_options => [:readers]
|
78
|
+
pc2 = Pointcut.new :object => cwa, :attributes => :attrRW_ClassWithAttribs
|
70
79
|
pc = pc1.and pc2
|
71
|
-
expected_jp =
|
80
|
+
expected_jp = JoinPoint.new :object => cwa, :method => :attrRW_ClassWithAttribs
|
72
81
|
pc.join_points_matched.should == Set.new([expected_jp])
|
73
82
|
pc.join_points_not_matched.should == @empty_set
|
74
83
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
84
|
+
end
|
85
|
+
|
86
|
+
describe Pointcut, "#and (algebraic properties for type-based pointcuts)" do
|
87
|
+
before :all do
|
88
|
+
@pc1 = Pointcut.new :types => ClassWithAttribs, :attributes => [/^attr/], :attribute_options => [:writers]
|
89
|
+
@pc2 = Pointcut.new :types => ClassWithAttribs, :attributes => [/^attr/], :attribute_options => [:writers]
|
90
|
+
@pc3 = Pointcut.new :types => ClassWithAttribs, :attributes => [/^attr/]
|
82
91
|
end
|
83
92
|
|
84
|
-
it "should be unitary for
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
pc = pc1.and pc2
|
89
|
-
pc.should == pc1
|
90
|
-
pc.should == pc2
|
93
|
+
it "should be unitary for type-based Pointcuts." do
|
94
|
+
pc = @pc1.and @pc2
|
95
|
+
pc.should == @pc1
|
96
|
+
pc.should == @pc2
|
91
97
|
end
|
92
|
-
|
93
|
-
it "should be commutative for type-based
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
pc21 = pc2.and pc1
|
98
|
-
pc12.should == pc21
|
98
|
+
|
99
|
+
it "should be commutative for type-based Pointcuts." do
|
100
|
+
pc13 = @pc1.and @pc3
|
101
|
+
pc31 = @pc3.and @pc1
|
102
|
+
pc13.should == pc31
|
99
103
|
end
|
100
104
|
|
101
|
-
it "should be
|
105
|
+
it "should be associativity for type-based Pointcuts." do
|
106
|
+
pc123a = (@pc1.and(@pc2)).and(@pc3)
|
107
|
+
pc123b = @pc1.and(@pc2.and(@pc3))
|
108
|
+
pc123a.should == pc123b
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe Pointcut, "#and (algebraic properties for object-based pointcuts)" do
|
113
|
+
before :all do
|
102
114
|
cwa = ClassWithAttribs.new
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
115
|
+
@pc1 = Pointcut.new :objects => cwa, :attributes => [/^attr/], :attribute_options => [:writers]
|
116
|
+
@pc2 = Pointcut.new :objects => cwa, :attributes => [/^attr/], :attribute_options => [:writers]
|
117
|
+
@pc3 = Pointcut.new :objects => cwa, :attributes => [/^attr/]
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should be unitary for object-based Pointcuts." do
|
121
|
+
pc = @pc1.and @pc2
|
122
|
+
pc.should == @pc1
|
123
|
+
pc.should == @pc2
|
109
124
|
end
|
110
125
|
|
111
|
-
it "should be
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
pc123a = (pc1.and(pc2)).and(pc3)
|
116
|
-
pc123b = pc1.and(pc2.and(pc3))
|
117
|
-
pc123a.should == pc123b
|
126
|
+
it "should be commutative for object-based Pointcuts." do
|
127
|
+
pc13 = @pc1.and @pc3
|
128
|
+
pc31 = @pc3.and @pc1
|
129
|
+
pc13.should == pc31
|
118
130
|
end
|
119
|
-
|
120
|
-
it "should be associativity for object-based
|
121
|
-
|
122
|
-
|
123
|
-
pc1 = Aquarium::Aspects::Pointcut.new :objects => cwa, :attributes => [/^attr/], :attribute_options => [:writers]
|
124
|
-
pc2 = Aquarium::Aspects::Pointcut.new :objects => cwa, :attributes => [/^attr/], :attribute_options => [:readers]
|
125
|
-
pc3 = Aquarium::Aspects::Pointcut.new :objects => pub
|
126
|
-
pc123a = (pc1.and(pc2)).and(pc3)
|
127
|
-
pc123b = pc1.and(pc2.and(pc3))
|
131
|
+
|
132
|
+
it "should be associativity for object-based Pointcuts." do
|
133
|
+
pc123a = (@pc1.and(@pc2)).and(@pc3)
|
134
|
+
pc123b = @pc1.and(@pc2.and(@pc3))
|
128
135
|
pc123a.should == pc123b
|
129
136
|
end
|
130
137
|
end
|
131
138
|
|
132
|
-
describe
|
133
|
-
it_should_behave_like "Intersection of Pointcuts"
|
134
|
-
end
|
135
|
-
|
136
|
-
describe Aquarium::Aspects::Pointcut, "#&" do
|
137
|
-
include Aquarium::Utils::HashUtils
|
139
|
+
describe Pointcut, "#&" do
|
138
140
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
pc2 = Aquarium::Aspects::Pointcut.new :types => ClassWithAttribs, :attributes => [/^attr/], :attribute_options => [:readers]
|
144
|
-
pc3 = Aquarium::Aspects::Pointcut.new :types => /Class.*Method/
|
141
|
+
it "should be a synonym for #and." do
|
142
|
+
pc1 = Pointcut.new :types => ClassWithAttribs, :attributes => [/^attr/], :attribute_options => [:writers]
|
143
|
+
pc2 = Pointcut.new :types => ClassWithAttribs, :attributes => [/^attr/], :attribute_options => [:writers]
|
144
|
+
pc3 = Pointcut.new :types => ClassWithAttribs, :attributes => [/^attr/]
|
145
145
|
pc123a = (pc1 & pc2) & pc3
|
146
146
|
pc123b = pc1 & (pc2 & pc3)
|
147
147
|
pc123a.should == pc123b
|
148
|
-
end
|
149
|
-
|
150
|
-
it "should be associativity for object-based Aquarium::Aspects::Pointcuts." do
|
151
148
|
cwa = ClassWithAttribs.new
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
pc123a.should == pc123b
|
149
|
+
pca = Pointcut.new :objects => cwa, :attributes => [/^attr/], :attribute_options => [:writers]
|
150
|
+
pcb = Pointcut.new :objects => cwa, :attributes => [/^attr/], :attribute_options => [:writers]
|
151
|
+
pcc = Pointcut.new :objects => cwa, :attributes => [/^attr/]
|
152
|
+
pcabc1 = (pca & pcb) & pcc
|
153
|
+
pcabc2 = pca & (pcb & pcc)
|
154
|
+
pcabc1.should == pcabc2
|
159
155
|
end
|
160
156
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
-
require File.dirname(__FILE__) + '/../
|
2
|
+
require File.dirname(__FILE__) + '/../spec_example_types'
|
3
3
|
require 'aquarium/utils'
|
4
4
|
require 'aquarium/extensions'
|
5
5
|
require 'aquarium/aspects/pointcut'
|
@@ -8,148 +8,136 @@ require 'aquarium/aspects/pointcut_composition'
|
|
8
8
|
include Aquarium::Utils::HashUtils
|
9
9
|
include Aquarium::Aspects
|
10
10
|
|
11
|
-
describe
|
11
|
+
describe Pointcut, "#or" do
|
12
12
|
|
13
|
-
before
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
ClassWithPublicClassMethod,
|
18
|
-
ClassWithPrivateClassMethod,
|
19
|
-
ClassIncludingModuleWithPrivateClassMethod,
|
20
|
-
ClassIncludingModuleWithPublicClassMethod,
|
21
|
-
ClassIncludingModuleWithProtectedInstanceMethod,
|
22
|
-
ClassIncludingModuleWithPrivateInstanceMethod]
|
23
|
-
jps_array = classes.map {|c| Aquarium::Aspects::JoinPoint.new :type => c, :method => :all}
|
24
|
-
@not_matched_jps = Set.new(jps_array)
|
13
|
+
before :all do
|
14
|
+
@pc1 = Pointcut.new
|
15
|
+
@pc2 = Pointcut.new :types => /Class.*Public.*Method/, :method_options => [:exclude_ancestor_methods]
|
16
|
+
@pc3 = Pointcut.new :object => ClassWithProtectedInstanceMethod.new, :method_options => [:protected, :exclude_ancestor_methods]
|
25
17
|
end
|
26
|
-
|
27
|
-
it "should return a Pointcut equal to the second, appended, non-empty Pointcut if self is empty (has no join points)." do
|
28
|
-
pc1
|
29
|
-
|
30
|
-
pc1.or(pc2).should eql(pc2)
|
31
|
-
pc3 = Pointcut.new :object => ClassWithPublicInstanceMethod.new
|
32
|
-
pc1.or(pc3).should eql(pc3)
|
18
|
+
|
19
|
+
it "should return a new Pointcut equal to the second, appended, non-empty Pointcut if self is empty (has no join points)." do
|
20
|
+
@pc1.or(@pc2).should eql(@pc2)
|
21
|
+
@pc1.or(@pc3).should eql(@pc3)
|
33
22
|
end
|
34
23
|
|
35
|
-
it "should return a Pointcut equal to self if the second pointcut is empty." do
|
36
|
-
pc1
|
37
|
-
|
38
|
-
pc1.or(pc2).should eql(pc1)
|
39
|
-
pc3 = Pointcut.new :object => ClassWithPublicInstanceMethod.new
|
40
|
-
pc3.or(pc2).should eql(pc3)
|
24
|
+
it "should return a new Pointcut equal to self if the second pointcut is empty." do
|
25
|
+
@pc2.or(@pc1).should eql(@pc2)
|
26
|
+
@pc3.or(@pc1).should eql(@pc3)
|
41
27
|
end
|
28
|
+
end
|
42
29
|
|
30
|
+
describe Pointcut, "#or (with two non-empty pointcuts)" do
|
31
|
+
|
43
32
|
it "should return a new Pointcut whose join points are the union of the left- and right-hand side Pointcuts for type-based Pointcuts." do
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
pc.join_points_matched.should == Set.new([jp1, jp2, jp3
|
55
|
-
pc.join_points_not_matched.should ==
|
33
|
+
pc4 = Pointcut.new :type => ClassWithPublicInstanceMethod, :method_options => :exclude_ancestor_methods
|
34
|
+
pc5 = Pointcut.new :type => ClassWithAttribs, :methods => /^attr.*=$/, :method_options => :exclude_ancestor_methods
|
35
|
+
jp_np1 = JoinPoint.new :type => ClassIncludingModuleWithPublicInstanceMethod, :method => :public_instance_class_including_module_test_method
|
36
|
+
jp_np2 = JoinPoint.new :type => ModuleWithPublicInstanceMethod, :method => :public_instance_module_test_method
|
37
|
+
pc4.join_points_not_matched << jp_np1
|
38
|
+
pc5.join_points_not_matched << jp_np2
|
39
|
+
pc = pc4.or pc5
|
40
|
+
jp1 = JoinPoint.new :type => ClassWithAttribs, :method => :attrRW_ClassWithAttribs=
|
41
|
+
jp2 = JoinPoint.new :type => ClassWithAttribs, :method => :attrW_ClassWithAttribs=
|
42
|
+
jp3 = JoinPoint.new :type => ClassWithPublicInstanceMethod, :method => :public_instance_test_method
|
43
|
+
pc.join_points_matched.should == Set.new([jp1, jp2, jp3])
|
44
|
+
pc.join_points_not_matched.should == Set.new([jp_np1, jp_np2])
|
56
45
|
end
|
57
46
|
|
58
47
|
it "should return a new Pointcut whose join points are the union of the left- and right-hand side Pointcuts for object-based Pointcuts." do
|
59
48
|
cwa = ClassWithAttribs.new
|
60
49
|
pub = ClassWithPublicInstanceMethod.new
|
61
|
-
|
62
|
-
|
63
|
-
pc =
|
64
|
-
jp1 =
|
65
|
-
jp2 =
|
66
|
-
jp3 =
|
50
|
+
pc4 = Pointcut.new :objects => [cwa], :attributes => [/^attr/], :attribute_options => [:writers, :exclude_ancestor_methods]
|
51
|
+
pc5 = Pointcut.new :object => pub, :method_options => :exclude_ancestor_methods
|
52
|
+
pc = pc4.or pc5
|
53
|
+
jp1 = JoinPoint.new :object => cwa, :method => :attrRW_ClassWithAttribs=
|
54
|
+
jp2 = JoinPoint.new :object => cwa, :method => :attrW_ClassWithAttribs=
|
55
|
+
jp3 = JoinPoint.new :object => pub, :method => :public_instance_test_method
|
67
56
|
pc.join_points_matched.sort.should == [jp1, jp2, jp3].sort
|
68
57
|
pc.join_points_not_matched.sort.should == []
|
69
58
|
end
|
70
|
-
|
59
|
+
end
|
60
|
+
|
61
|
+
describe Pointcut, "#or (algebraic properties for type-based pointcuts)" do
|
62
|
+
before :all do
|
63
|
+
@pc1 = Pointcut.new :types => "ClassWithAttribs", :attributes => [/^attr/], :attribute_options => [:writers, :exclude_ancestor_methods]
|
64
|
+
@pc2 = Pointcut.new :types => "ClassWithAttribs", :attributes => [/^attr/], :attribute_options => [:writers, :exclude_ancestor_methods]
|
65
|
+
@pc3 = Pointcut.new :types => /Class.*Public.*Method/, :method_options => [:public, :exclude_ancestor_methods]
|
66
|
+
end
|
67
|
+
|
71
68
|
it "should be unitary for type-based Pointcuts." do
|
72
|
-
|
73
|
-
|
74
|
-
pc
|
75
|
-
pc.should eql(pc1)
|
76
|
-
pc.should eql(pc2)
|
69
|
+
pc = @pc1.or @pc2
|
70
|
+
pc.should eql(@pc1)
|
71
|
+
pc.should eql(@pc2)
|
77
72
|
end
|
78
73
|
|
79
|
-
it "should be
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
pc = pc1.or pc2
|
84
|
-
pc.should eql(pc1)
|
85
|
-
pc.should eql(pc2)
|
74
|
+
it "should be commutative for type-based Pointcuts." do
|
75
|
+
pc13 = @pc1.or @pc3
|
76
|
+
pc31 = @pc3.or @pc1
|
77
|
+
pc13.should eql(pc31)
|
86
78
|
end
|
87
79
|
|
88
|
-
it "should be
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
pc21 = pc2.or pc1
|
93
|
-
pc12.should eql(pc21)
|
80
|
+
it "should be associativity for type-based Pointcuts." do
|
81
|
+
pc123a = (@pc1.or(@pc2)).or(@pc3)
|
82
|
+
pc123b = @pc1.or(@pc2.or(@pc3))
|
83
|
+
pc123a.should eql(pc123b)
|
94
84
|
end
|
85
|
+
end
|
95
86
|
|
96
|
-
|
87
|
+
describe Pointcut, "#or (algebraic properties for object-based pointcuts)" do
|
88
|
+
before :all do
|
97
89
|
cwa = ClassWithAttribs.new
|
98
90
|
pub = ClassWithPublicInstanceMethod.new
|
99
|
-
pc1 = Pointcut.new :
|
100
|
-
pc2 = Pointcut.new :
|
101
|
-
|
102
|
-
|
103
|
-
|
91
|
+
@pc1 = Pointcut.new :object => cwa, :attributes => [/^attr/], :attribute_options => [:writers, :exclude_ancestor_methods]
|
92
|
+
@pc2 = Pointcut.new :object => cwa, :attributes => [/^attr/], :attribute_options => [:writers, :exclude_ancestor_methods]
|
93
|
+
@pc3 = Pointcut.new :objects => pub, :attributes => [/^attr/], :attribute_options => [:writers, :exclude_ancestor_methods]
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should be unitary for object-based Pointcuts." do
|
97
|
+
pc12 = @pc1.or @pc2
|
98
|
+
pc12.should eql(@pc1)
|
99
|
+
pc12.should eql(@pc2)
|
104
100
|
end
|
105
101
|
|
106
|
-
it "should be
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
pc123a = (pc1.or(pc2)).or(pc3)
|
111
|
-
pc123b = pc1.or(pc2.or(pc3))
|
112
|
-
pc123a.should eql(pc123b)
|
102
|
+
it "should be commutative for object-based Pointcuts." do
|
103
|
+
pc13 = @pc1.or @pc3
|
104
|
+
pc31 = @pc3.or @pc1
|
105
|
+
pc13.should eql(pc31)
|
113
106
|
end
|
114
107
|
|
115
108
|
it "should be associativity for object-based Pointcuts." do
|
116
|
-
|
117
|
-
|
118
|
-
pc1 = Pointcut.new :objects => cwa, :attributes => [/^attr/], :attribute_options => [:writers]
|
119
|
-
pc2 = Pointcut.new :objects => cwa, :attributes => [/^attr/], :attribute_options => [:readers]
|
120
|
-
pc3 = Pointcut.new :objects => pub
|
121
|
-
pc123a = (pc1.or(pc2)).or(pc3)
|
122
|
-
pc123b = pc1.or(pc2.or(pc3))
|
109
|
+
pc123a = (@pc1.or(@pc2)).or(@pc3)
|
110
|
+
pc123b = @pc1.or(@pc2.or(@pc3))
|
123
111
|
pc123a.should eql(pc123b)
|
124
112
|
end
|
125
|
-
|
126
113
|
end
|
127
114
|
|
128
|
-
describe Pointcut, "#or" do
|
129
|
-
it_should_behave_like "Union of Pointcuts"
|
130
|
-
end
|
131
115
|
|
132
116
|
describe Pointcut, "#|" do
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
117
|
+
it "should be a synonym for #or." do
|
118
|
+
pc1 = Pointcut.new
|
119
|
+
pc2 = Pointcut.new :types => /Class.*Public.*Method/, :method_options => [:public, :exclude_ancestor_methods]
|
120
|
+
pc3 = Pointcut.new :object => ClassWithPublicInstanceMethod.new, :method_options => [:exclude_ancestor_methods]
|
121
|
+
pc12 = pc1 | pc2
|
122
|
+
pc32 = pc3 | pc2
|
123
|
+
pc23 = pc2 | pc3
|
124
|
+
pc12.should_not equal(pc1)
|
125
|
+
pc12.should_not equal(pc2)
|
126
|
+
pc12.should eql(pc2)
|
127
|
+
pc32.should eql(pc23)
|
128
|
+
pca = Pointcut.new :types => "ClassWithAttribs", :attributes => [/^attr/], :attribute_options => [:writers, :exclude_ancestor_methods]
|
129
|
+
pcb = Pointcut.new :types => "ClassWithAttribs", :attributes => [/^attr/], :attribute_options => [:readers, :exclude_ancestor_methods]
|
130
|
+
pcc = Pointcut.new :types => /Class.*Method/, :method_options => [:exclude_ancestor_methods]
|
131
|
+
pcabc1 = (pca | pcb) | pcc
|
132
|
+
pcabc2 = pca | (pcb | pcc)
|
133
|
+
pcabc1.should eql(pcabc2)
|
146
134
|
cwa = ClassWithAttribs.new
|
147
135
|
pub = ClassWithPublicInstanceMethod.new
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
136
|
+
pcd = Pointcut.new :objects => cwa, :attributes => [/^attr/], :attribute_options => [:writers, :exclude_ancestor_methods]
|
137
|
+
pce = Pointcut.new :objects => cwa, :attributes => [/^attr/], :attribute_options => [:readers, :exclude_ancestor_methods]
|
138
|
+
pcf = Pointcut.new :objects => pub, :method_options => [:exclude_ancestor_methods]
|
139
|
+
pcdef1 = (pcd | pce) | pcf
|
140
|
+
pcdef2 = pcd | (pce | pcf)
|
141
|
+
pcdef1.should eql(pcdef2)
|
154
142
|
end
|
155
143
|
end
|