aquarium 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|