aquarium 0.1.0
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/CHANGES +4 -0
- data/EXAMPLES.rd +4 -0
- data/MIT-LICENSE +20 -0
- data/README +250 -0
- data/RELEASE-PLAN +1 -0
- data/Rakefile +236 -0
- data/UPGRADE +3 -0
- data/examples/aspect_design_example.rb +36 -0
- data/examples/design_by_contract_example.rb +88 -0
- data/examples/method_missing_example.rb +44 -0
- data/examples/method_tracing_example.rb +64 -0
- data/lib/aquarium.rb +7 -0
- data/lib/aquarium/aspects.rb +6 -0
- data/lib/aquarium/aspects/advice.rb +189 -0
- data/lib/aquarium/aspects/aspect.rb +577 -0
- data/lib/aquarium/aspects/default_object_handler.rb +27 -0
- data/lib/aquarium/aspects/dsl.rb +1 -0
- data/lib/aquarium/aspects/dsl/aspect_dsl.rb +61 -0
- data/lib/aquarium/aspects/join_point.rb +158 -0
- data/lib/aquarium/aspects/pointcut.rb +254 -0
- data/lib/aquarium/aspects/pointcut_composition.rb +36 -0
- data/lib/aquarium/extensions.rb +5 -0
- data/lib/aquarium/extensions/hash.rb +85 -0
- data/lib/aquarium/extensions/regexp.rb +20 -0
- data/lib/aquarium/extensions/set.rb +49 -0
- data/lib/aquarium/extensions/string.rb +13 -0
- data/lib/aquarium/extensions/symbol.rb +22 -0
- data/lib/aquarium/extras.rb +4 -0
- data/lib/aquarium/extras/design_by_contract.rb +64 -0
- data/lib/aquarium/finders.rb +4 -0
- data/lib/aquarium/finders/finder_result.rb +121 -0
- data/lib/aquarium/finders/method_finder.rb +228 -0
- data/lib/aquarium/finders/object_finder.rb +74 -0
- data/lib/aquarium/finders/type_finder.rb +127 -0
- data/lib/aquarium/utils.rb +9 -0
- data/lib/aquarium/utils/array_utils.rb +29 -0
- data/lib/aquarium/utils/hash_utils.rb +28 -0
- data/lib/aquarium/utils/html_escaper.rb +17 -0
- data/lib/aquarium/utils/invalid_options.rb +9 -0
- data/lib/aquarium/utils/method_utils.rb +18 -0
- data/lib/aquarium/utils/nil_object.rb +13 -0
- data/lib/aquarium/utils/set_utils.rb +32 -0
- data/lib/aquarium/version.rb +30 -0
- data/rake_tasks/examples.rake +7 -0
- data/rake_tasks/examples_specdoc.rake +8 -0
- data/rake_tasks/examples_with_rcov.rake +8 -0
- data/rake_tasks/verify_rcov.rake +7 -0
- data/spec/aquarium/aspects/advice_chain_node_spec.rb +34 -0
- data/spec/aquarium/aspects/advice_spec.rb +103 -0
- data/spec/aquarium/aspects/aspect_invocation_spec.rb +111 -0
- data/spec/aquarium/aspects/aspect_spec.rb +978 -0
- data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +129 -0
- data/spec/aquarium/aspects/concurrent_aspects_spec.rb +423 -0
- data/spec/aquarium/aspects/concurrent_aspects_with_objects_and_types_spec.rb +103 -0
- data/spec/aquarium/aspects/concurrently_accessed.rb +21 -0
- data/spec/aquarium/aspects/dsl/aspect_dsl_spec.rb +514 -0
- data/spec/aquarium/aspects/join_point_spec.rb +302 -0
- data/spec/aquarium/aspects/pointcut_and_composition_spec.rb +131 -0
- data/spec/aquarium/aspects/pointcut_or_composition_spec.rb +111 -0
- data/spec/aquarium/aspects/pointcut_spec.rb +800 -0
- data/spec/aquarium/extensions/hash_spec.rb +187 -0
- data/spec/aquarium/extensions/regex_spec.rb +40 -0
- data/spec/aquarium/extensions/set_spec.rb +105 -0
- data/spec/aquarium/extensions/string_spec.rb +25 -0
- data/spec/aquarium/extensions/symbol_spec.rb +37 -0
- data/spec/aquarium/extras/design_by_contract_spec.rb +68 -0
- data/spec/aquarium/finders/finder_result_spec.rb +359 -0
- data/spec/aquarium/finders/method_finder_spec.rb +878 -0
- data/spec/aquarium/finders/method_sorting_spec.rb +16 -0
- data/spec/aquarium/finders/object_finder_spec.rb +230 -0
- data/spec/aquarium/finders/type_finder_spec.rb +210 -0
- data/spec/aquarium/spec_example_classes.rb +117 -0
- data/spec/aquarium/spec_helper.rb +3 -0
- data/spec/aquarium/utils/array_utils_spec.rb +47 -0
- data/spec/aquarium/utils/hash_utils_spec.rb +48 -0
- data/spec/aquarium/utils/html_escaper_spec.rb +18 -0
- data/spec/aquarium/utils/method_utils_spec.rb +50 -0
- data/spec/aquarium/utils/nil_object_spec.rb +19 -0
- data/spec/aquarium/utils/set_utils_spec.rb +60 -0
- metadata +132 -0
@@ -0,0 +1,187 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
require File.dirname(__FILE__) + '/../spec_example_classes'
|
3
|
+
require 'aquarium/extensions/hash'
|
4
|
+
require 'aquarium/utils/array_utils'
|
5
|
+
require 'aquarium/utils/hash_utils'
|
6
|
+
require 'set'
|
7
|
+
|
8
|
+
describe Hash, "#intersection" do
|
9
|
+
include Aquarium::Utils::ArrayUtils
|
10
|
+
include Aquarium::Utils::HashUtils
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
@hash = {:a => 'a', :b => [:b1, :b2], :c => 'c'}
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return the same hash if intersected with itself." do
|
17
|
+
@hash.intersection(@hash).should == @hash
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return the same hash if intersected with an equivalent hash." do
|
21
|
+
@hash.intersection({:a => 'a', :b => [:b1, :b2], :c => 'c'}).should == @hash
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return an empty hash if one of the input hashes is empty." do
|
25
|
+
{}.intersection(@hash).should == {}
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return the common subset hash for two, non-equivalent hashes." do
|
29
|
+
hash2 = {:b =>:b1, :c => 'c', :d => 'd'}
|
30
|
+
@hash.intersection(hash2){|values1, values2| Set.new(make_array(values1)).intersection(Set.new(make_array(values2)))}.should == {:b =>Set.new([:b1]), :c => 'c'}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "intersection of hashes", :shared => true do
|
35
|
+
include Aquarium::Utils::ArrayUtils
|
36
|
+
include Aquarium::Utils::HashUtils
|
37
|
+
|
38
|
+
before(:each) do
|
39
|
+
@hash = {:a => 'a', :b => [:b1, :b2], :c => 'c'}
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should return the same hash if intersected with itself." do
|
43
|
+
@hash.intersection(@hash).should == @hash
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should return the same hash if intersected with an equivalent hash." do
|
47
|
+
@hash.intersection({:a => 'a', :b => [:b1, :b2], :c => 'c'}).should == @hash
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should return an empty hash if one of the input hashes is empty." do
|
51
|
+
{}.intersection(@hash).should == {}
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return the common subset hash for two, non-equivalent hashes." do
|
55
|
+
hash2 = {:b =>:b1, :c => 'c', :d => 'd'}
|
56
|
+
@hash.intersection(hash2){|value1, value2| Set.new(make_array(value1)).intersection(Set.new(make_array(value2)))}.should == {:b =>Set.new([:b1]), :c => 'c'}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe Hash, "#intersection" do
|
61
|
+
it_should_behave_like "intersection of hashes"
|
62
|
+
end
|
63
|
+
|
64
|
+
describe Hash, "#and" do
|
65
|
+
it_should_behave_like "intersection of hashes"
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "union of hashes", :shared => true do
|
69
|
+
include Aquarium::Utils::ArrayUtils
|
70
|
+
include Aquarium::Utils::HashUtils
|
71
|
+
|
72
|
+
before(:each) do
|
73
|
+
@hash = {:a => 'a', :b => [:b1, :b2], :c => 'c'}
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should return the same hash if unioned with itself." do
|
77
|
+
@hash.union(@hash).should == @hash
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should return the same hash if unioned with an equivalent hash." do
|
81
|
+
@hash.union({:a => 'a', :b => [:b1, :b2], :c => 'c'}).should == @hash
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should return a hash that is equivalent to the non-empty hash if the other hash is empty." do
|
85
|
+
{}.union(@hash).should == @hash
|
86
|
+
@hash.union({}).should == @hash
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should return the same hash if unioned with nil." do
|
90
|
+
@hash.union(nil).should == @hash
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should return a hash equivalent to the output of Hash#merge for two, non-equivalent hashes, with no block given." do
|
94
|
+
hash2 = {:b =>:b3, :c => 'c2', :d => 'd'}
|
95
|
+
@hash.union(hash2).should == {:a => 'a', :b => :b3, :c => 'c2', :d => 'd'}
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should return the combined hashes for two, non-equivalent hashes, with a block given to merge values into an array." do
|
99
|
+
hash2 = {:b =>:b3, :c => 'c2', :d => 'd'}
|
100
|
+
@hash.union(hash2){|value1, value2| Set.new(make_array(value1)).union(Set.new(make_array(value2)))}.should == {:a => 'a', :b => Set.new([:b1, :b2, :b3]), :c => Set.new(['c', 'c2']), :d => 'd'}
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe Hash, "#union" do
|
105
|
+
it_should_behave_like "union of hashes"
|
106
|
+
end
|
107
|
+
|
108
|
+
describe Hash, "#or" do
|
109
|
+
it_should_behave_like "union of hashes"
|
110
|
+
end
|
111
|
+
|
112
|
+
describe Hash, "#eql_when_keys_compared?" do
|
113
|
+
include Aquarium::Utils::ArrayUtils
|
114
|
+
include Aquarium::Utils::HashUtils
|
115
|
+
|
116
|
+
it "should return true when comparing a hash to itself." do
|
117
|
+
h1={"1" => :a1, "2" => :a2, "3" => :a3}
|
118
|
+
h1.eql_when_keys_compared?(h1).should == true
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should return true for hashes with string keys that satisfy String#==." do
|
122
|
+
h1={"1" => :a1, "2" => :a2, "3" => :a3}
|
123
|
+
h2={"1" => :a1, "2" => :a2, "3" => :a3}
|
124
|
+
h1.eql_when_keys_compared?(h2).should == true
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should return false for hashes with matching keys, but different values." do
|
128
|
+
h1={"1" => :a1, "2" => :a2, "3" => /a/}
|
129
|
+
h2={"1" => :a1, "2" => :a2, "3" => /b/}
|
130
|
+
h1.eql_when_keys_compared?(h2).should == false
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should return false for hashes where one hash is a subset of the other." do
|
134
|
+
h1={"1" => :a1, "2" => :a2}
|
135
|
+
h2={"1" => :a1, "2" => :a2, "3" => :a3}
|
136
|
+
h1.eql_when_keys_compared?(h2).should == false
|
137
|
+
h2.eql_when_keys_compared?(h1).should == false
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should return true for hashes with Object keys that define a #<=> method, while Hash#eql? would return false." do
|
141
|
+
class Key
|
142
|
+
def initialize key
|
143
|
+
@key = key
|
144
|
+
end
|
145
|
+
attr_reader :key
|
146
|
+
def eql? other
|
147
|
+
key.eql? other.key
|
148
|
+
end
|
149
|
+
def <=> other
|
150
|
+
key <=> other.key
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
h1 = {}; h2 = {}
|
155
|
+
(0...4).each do |index|
|
156
|
+
h1[Key.new(index)] = {index.to_s => [index, index+1]}
|
157
|
+
h2[Key.new(index)] = {index.to_s => [index, index+1]}
|
158
|
+
end
|
159
|
+
h1.eql_when_keys_compared?(h2).should == true
|
160
|
+
h1.eql?(h2).should == false
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe Hash, "#equivalent_key" do
|
165
|
+
it "should return the key in the hash for which input_value#==(key) is true." do
|
166
|
+
class Key
|
167
|
+
def initialize key
|
168
|
+
@key = key
|
169
|
+
end
|
170
|
+
attr_reader :key
|
171
|
+
def eql? other
|
172
|
+
key.eql? other.key
|
173
|
+
end
|
174
|
+
alias :== :eql?
|
175
|
+
end
|
176
|
+
|
177
|
+
h1 = {}; h2 = {}
|
178
|
+
(0...4).each do |index|
|
179
|
+
h1[Key.new(index)] = {index.to_s => [index, index+1]}
|
180
|
+
h2[Key.new(index)] = {index.to_s => [index, index+1]}
|
181
|
+
end
|
182
|
+
h1[Key.new(0)].should be_nil
|
183
|
+
h1.equivalent_key(Key.new(0)).should_not be_nil
|
184
|
+
h1.equivalent_key(Key.new(5)).should be_nil
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
require 'aquarium/extensions/regexp'
|
3
|
+
|
4
|
+
describe Regexp, "#empty?" do
|
5
|
+
|
6
|
+
it "should return true for an empty regular expression" do
|
7
|
+
//.empty?.should be_true
|
8
|
+
Regexp.new("").empty?.should be_true
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should return true for an empty regular expression with whitespace" do
|
12
|
+
/ /.empty?.should be_true
|
13
|
+
Regexp.new(" ").empty?.should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return false for a non-empty regular expression" do
|
17
|
+
/x/.empty?.should be_false
|
18
|
+
Regexp.new("x").empty?.should be_false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe Regexp, "#strip" do
|
23
|
+
it "should return equivalent Regexp if there is no leading or trailing whitespace." do
|
24
|
+
re = /^.{3}.*[a-z]$/
|
25
|
+
re.strip.should == re
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return new Regexp with removed leading and/or trailing whitespace, when present." do
|
29
|
+
re_string = "^.{3}.*[a-z]$"
|
30
|
+
re = Regexp.new " #{re_string} "
|
31
|
+
re.strip.source.should == re_string
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe Regexp, "#<=>" do
|
36
|
+
it "should sort by the output of #to_s" do
|
37
|
+
ary = [/^x/, /x/, /x$/]
|
38
|
+
ary.sort.should == [/^x/, /x$/, /x/]
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
require File.dirname(__FILE__) + '/../spec_example_classes'
|
3
|
+
require 'aquarium/extensions/set'
|
4
|
+
|
5
|
+
class Foo
|
6
|
+
def initialize name
|
7
|
+
@name = name
|
8
|
+
end
|
9
|
+
attr_reader :name
|
10
|
+
def eql? other
|
11
|
+
name.eql? other.name
|
12
|
+
end
|
13
|
+
alias :== :eql?
|
14
|
+
end
|
15
|
+
class Bar
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "set comparison", :shared => true do
|
19
|
+
it "should return true for the same set" do
|
20
|
+
s = Set.new [Foo.new("f1"), Foo.new("f2")]
|
21
|
+
s.should eql(s)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return true for equivalent sets" do
|
25
|
+
s1 = Set.new [Foo.new("f1"), Foo.new("f2")]
|
26
|
+
s2 = Set.new [Foo.new("f2"), Foo.new("f1")]
|
27
|
+
s1.should eql(s2)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should return false for sets where one is a subset of, but not equivalent to, the other set" do
|
31
|
+
s1 = Set.new [Foo.new("f1")]
|
32
|
+
s2 = Set.new [Foo.new("f2"), Foo.new("f1")]
|
33
|
+
s1.should_not eql(s2)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should return false for sets where some element pairs are of different types" do
|
37
|
+
s1 = Set.new [Foo.new("f1"), Bar.new]
|
38
|
+
s2 = Set.new [Foo.new("f1"), Foo.new("f2")]
|
39
|
+
s1.should_not eql(s2)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe Set, "#==" do
|
44
|
+
it_should_behave_like "set comparison"
|
45
|
+
end
|
46
|
+
|
47
|
+
describe Set, "#eql?" do
|
48
|
+
it_should_behave_like "set comparison"
|
49
|
+
end
|
50
|
+
|
51
|
+
describe Set, "#union_using_eql_comparison" do
|
52
|
+
it "should return an equivalent set if unioned with itself" do
|
53
|
+
s = Set.new [Foo.new("f1"), Foo.new("f2")]
|
54
|
+
s.union_using_eql_comparison(s).should eql(s)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return an equivalent set if unioned with another equivalent set" do
|
58
|
+
s1 = Set.new [Foo.new("f1"), Foo.new("f2")]
|
59
|
+
s2 = Set.new [Foo.new("f1"), Foo.new("f2")]
|
60
|
+
s1.union_using_eql_comparison(s2).should eql(s1)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return an equivalent set if unioned with subset" do
|
64
|
+
s1 = Set.new [Foo.new("f1"), Foo.new("f2")]
|
65
|
+
s2 = Set.new [Foo.new("f1")]
|
66
|
+
s1.union_using_eql_comparison(s2).should eql(s1)
|
67
|
+
s2.union_using_eql_comparison(s1).should eql(s1)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should return a combined set if unioned with a disjoint set" do
|
71
|
+
s1 = Set.new [Foo.new("f1"), Foo.new("f2")]
|
72
|
+
s2 = Set.new [Foo.new("f3")]
|
73
|
+
s3 = Set.new [Foo.new("f1"), Foo.new("f2"), Foo.new("f3")]
|
74
|
+
s1.union_using_eql_comparison(s2).should eql(s3)
|
75
|
+
s2.union_using_eql_comparison(s1).should eql(s3)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe Set, "#intersection_using_eql_comparison" do
|
80
|
+
it "should return an equivalent set if intersectioned with itself" do
|
81
|
+
s = Set.new [Foo.new("f1"), Foo.new("f2")]
|
82
|
+
s.intersection_using_eql_comparison(s).should eql(s)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should return an equivalent set if intersectioned with another equivalent set" do
|
86
|
+
s1 = Set.new [Foo.new("f1"), Foo.new("f2")]
|
87
|
+
s2 = Set.new [Foo.new("f1"), Foo.new("f2")]
|
88
|
+
s1.intersection_using_eql_comparison(s2).should eql(s1)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should return a subset if intersectioned with an equivalent subset" do
|
92
|
+
s1 = Set.new [Foo.new("f1"), Foo.new("f2")]
|
93
|
+
s2 = Set.new [Foo.new("f1")]
|
94
|
+
s1.intersection_using_eql_comparison(s2).should eql(s2)
|
95
|
+
s2.intersection_using_eql_comparison(s1).should eql(s2)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should return an empty set if intersectioned with a disjoint set" do
|
99
|
+
s1 = Set.new [Foo.new("f1"), Foo.new("f2")]
|
100
|
+
s2 = Set.new [Foo.new("f3")]
|
101
|
+
s1.intersection_using_eql_comparison(s2).should eql(Set.new)
|
102
|
+
s2.intersection_using_eql_comparison(s1).should eql(Set.new)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
require 'aquarium/extensions/string'
|
3
|
+
|
4
|
+
describe String, "#to_camel_case" do
|
5
|
+
it "should return a camel-case string unchanged" do
|
6
|
+
"CamelCaseString".to_camel_case.should == "CamelCaseString"
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return a camel-case string from an input string with substrings separated by underscores" do
|
10
|
+
"camel_case_string".to_camel_case.should == "CamelCaseString"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return a camel-case string with the first letters of each substring in uppercase and the rest of the letters in each substring unchanged" do
|
14
|
+
"cAmEl_cASE_stRinG".to_camel_case.should == "CAmElCASEStRinG"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should remove leading and trailing underscores" do
|
18
|
+
"camel_case_string_".to_camel_case.should == "CamelCaseString"
|
19
|
+
"_camel_case_string".to_camel_case.should == "CamelCaseString"
|
20
|
+
"camel_case_string__".to_camel_case.should == "CamelCaseString"
|
21
|
+
"__camel_case_string".to_camel_case.should == "CamelCaseString"
|
22
|
+
"_camel_case_string_".to_camel_case.should == "CamelCaseString"
|
23
|
+
"__camel_case_string__".to_camel_case.should == "CamelCaseString"
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
require 'aquarium/extensions/symbol'
|
3
|
+
|
4
|
+
describe "Symbol#empty?" do
|
5
|
+
|
6
|
+
it "should return true for an empty symbol with whitespace" do
|
7
|
+
:" \t ".empty?.should be_true
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should return false for a non-empty symbol" do
|
11
|
+
:x.empty?.should be_false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "Symbol#strip" do
|
16
|
+
it "should return equivalent Symbol if there is no leading or trailing whitespace." do
|
17
|
+
:a.strip.should == :a
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return new Symbol with removed leading and/or trailing whitespace, when present." do
|
21
|
+
:" \ta\t ".strip.should == :a
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "Symbol#<=>" do
|
26
|
+
it "should return < 0 if the string representation of the left-hand side symbol is less than the string representation of the right-hand side symbol." do
|
27
|
+
(:a <=> :b).should == -1
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should return > 0 if the string representation of the left-hand side symbol is greater than the string representation of the right-hand side symbol." do
|
31
|
+
(:b <=> :a).should == 1
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should return 0 if the string representation of the left-hand side symbol is equal to the string representation of the right-hand side symbol." do
|
35
|
+
(:a <=> :a).should == 0
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
require 'aquarium/extras/design_by_contract'
|
3
|
+
|
4
|
+
describe Aquarium::Extras::DesignByContract, "precondition" do
|
5
|
+
class PreCond
|
6
|
+
def action *args
|
7
|
+
end
|
8
|
+
|
9
|
+
precondition :method => :action, :message => "Must pass more than one argument." do |jp, *args|
|
10
|
+
args.size > 0
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should add advice that raises if the precondition is not satisfied" do
|
15
|
+
lambda {PreCond.new.action}.should raise_error(Aquarium::Extras::DesignByContract::ContractError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should add advice that does not raise if the precondition is satisfied" do
|
19
|
+
PreCond.new.action(:a1)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe Aquarium::Extras::DesignByContract, "postcondition" do
|
24
|
+
class PostCond
|
25
|
+
def action *args
|
26
|
+
end
|
27
|
+
|
28
|
+
postcondition :method => :action, :message => "Must pass more than one argument and first argument must be non-empty." do |jp, *args|
|
29
|
+
args.size > 0 && ! args[0].empty?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should add advice that raises if the postcondition is not satisfied" do
|
34
|
+
lambda {PostCond.new.action}.should raise_error(Aquarium::Extras::DesignByContract::ContractError)
|
35
|
+
lambda {PostCond.new.action("")}.should raise_error(Aquarium::Extras::DesignByContract::ContractError)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should add advice that does not raise if the postcondition is satisfied" do
|
39
|
+
PostCond.new.action(:a1)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
describe Aquarium::Extras::DesignByContract, "invariant" do
|
45
|
+
class InvarCond
|
46
|
+
def initialize
|
47
|
+
@invar = 0
|
48
|
+
end
|
49
|
+
attr_reader :invar
|
50
|
+
def good_action
|
51
|
+
end
|
52
|
+
def bad_action
|
53
|
+
@invar = 1
|
54
|
+
end
|
55
|
+
|
56
|
+
invariant :methods => /action$/, :message => "Must not change the @invar value." do |jp, *args|
|
57
|
+
jp.context.advised_object.invar == 0
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should add advice that raises if the invariant is not satisfied" do
|
62
|
+
lambda {InvarCond.new.bad_action}.should raise_error(Aquarium::Extras::DesignByContract::ContractError)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should add advice that does not raise if the invariant is satisfied" do
|
66
|
+
InvarCond.new.good_action
|
67
|
+
end
|
68
|
+
end
|