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.
Files changed (80) hide show
  1. data/CHANGES +4 -0
  2. data/EXAMPLES.rd +4 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README +250 -0
  5. data/RELEASE-PLAN +1 -0
  6. data/Rakefile +236 -0
  7. data/UPGRADE +3 -0
  8. data/examples/aspect_design_example.rb +36 -0
  9. data/examples/design_by_contract_example.rb +88 -0
  10. data/examples/method_missing_example.rb +44 -0
  11. data/examples/method_tracing_example.rb +64 -0
  12. data/lib/aquarium.rb +7 -0
  13. data/lib/aquarium/aspects.rb +6 -0
  14. data/lib/aquarium/aspects/advice.rb +189 -0
  15. data/lib/aquarium/aspects/aspect.rb +577 -0
  16. data/lib/aquarium/aspects/default_object_handler.rb +27 -0
  17. data/lib/aquarium/aspects/dsl.rb +1 -0
  18. data/lib/aquarium/aspects/dsl/aspect_dsl.rb +61 -0
  19. data/lib/aquarium/aspects/join_point.rb +158 -0
  20. data/lib/aquarium/aspects/pointcut.rb +254 -0
  21. data/lib/aquarium/aspects/pointcut_composition.rb +36 -0
  22. data/lib/aquarium/extensions.rb +5 -0
  23. data/lib/aquarium/extensions/hash.rb +85 -0
  24. data/lib/aquarium/extensions/regexp.rb +20 -0
  25. data/lib/aquarium/extensions/set.rb +49 -0
  26. data/lib/aquarium/extensions/string.rb +13 -0
  27. data/lib/aquarium/extensions/symbol.rb +22 -0
  28. data/lib/aquarium/extras.rb +4 -0
  29. data/lib/aquarium/extras/design_by_contract.rb +64 -0
  30. data/lib/aquarium/finders.rb +4 -0
  31. data/lib/aquarium/finders/finder_result.rb +121 -0
  32. data/lib/aquarium/finders/method_finder.rb +228 -0
  33. data/lib/aquarium/finders/object_finder.rb +74 -0
  34. data/lib/aquarium/finders/type_finder.rb +127 -0
  35. data/lib/aquarium/utils.rb +9 -0
  36. data/lib/aquarium/utils/array_utils.rb +29 -0
  37. data/lib/aquarium/utils/hash_utils.rb +28 -0
  38. data/lib/aquarium/utils/html_escaper.rb +17 -0
  39. data/lib/aquarium/utils/invalid_options.rb +9 -0
  40. data/lib/aquarium/utils/method_utils.rb +18 -0
  41. data/lib/aquarium/utils/nil_object.rb +13 -0
  42. data/lib/aquarium/utils/set_utils.rb +32 -0
  43. data/lib/aquarium/version.rb +30 -0
  44. data/rake_tasks/examples.rake +7 -0
  45. data/rake_tasks/examples_specdoc.rake +8 -0
  46. data/rake_tasks/examples_with_rcov.rake +8 -0
  47. data/rake_tasks/verify_rcov.rake +7 -0
  48. data/spec/aquarium/aspects/advice_chain_node_spec.rb +34 -0
  49. data/spec/aquarium/aspects/advice_spec.rb +103 -0
  50. data/spec/aquarium/aspects/aspect_invocation_spec.rb +111 -0
  51. data/spec/aquarium/aspects/aspect_spec.rb +978 -0
  52. data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +129 -0
  53. data/spec/aquarium/aspects/concurrent_aspects_spec.rb +423 -0
  54. data/spec/aquarium/aspects/concurrent_aspects_with_objects_and_types_spec.rb +103 -0
  55. data/spec/aquarium/aspects/concurrently_accessed.rb +21 -0
  56. data/spec/aquarium/aspects/dsl/aspect_dsl_spec.rb +514 -0
  57. data/spec/aquarium/aspects/join_point_spec.rb +302 -0
  58. data/spec/aquarium/aspects/pointcut_and_composition_spec.rb +131 -0
  59. data/spec/aquarium/aspects/pointcut_or_composition_spec.rb +111 -0
  60. data/spec/aquarium/aspects/pointcut_spec.rb +800 -0
  61. data/spec/aquarium/extensions/hash_spec.rb +187 -0
  62. data/spec/aquarium/extensions/regex_spec.rb +40 -0
  63. data/spec/aquarium/extensions/set_spec.rb +105 -0
  64. data/spec/aquarium/extensions/string_spec.rb +25 -0
  65. data/spec/aquarium/extensions/symbol_spec.rb +37 -0
  66. data/spec/aquarium/extras/design_by_contract_spec.rb +68 -0
  67. data/spec/aquarium/finders/finder_result_spec.rb +359 -0
  68. data/spec/aquarium/finders/method_finder_spec.rb +878 -0
  69. data/spec/aquarium/finders/method_sorting_spec.rb +16 -0
  70. data/spec/aquarium/finders/object_finder_spec.rb +230 -0
  71. data/spec/aquarium/finders/type_finder_spec.rb +210 -0
  72. data/spec/aquarium/spec_example_classes.rb +117 -0
  73. data/spec/aquarium/spec_helper.rb +3 -0
  74. data/spec/aquarium/utils/array_utils_spec.rb +47 -0
  75. data/spec/aquarium/utils/hash_utils_spec.rb +48 -0
  76. data/spec/aquarium/utils/html_escaper_spec.rb +18 -0
  77. data/spec/aquarium/utils/method_utils_spec.rb +50 -0
  78. data/spec/aquarium/utils/nil_object_spec.rb +19 -0
  79. data/spec/aquarium/utils/set_utils_spec.rb +60 -0
  80. 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