qed 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,121 @@
1
+ module QED
2
+
3
+ require 'qed/expectation'
4
+
5
+ module Grammar
6
+
7
+ # = Expect Nomenclature
8
+ #
9
+ # Provides expect nomenclature. This is Quarry's "standard"
10
+ # nomenclature.
11
+ #
12
+ module Expect
13
+
14
+ # The +expect+ method is a powerful tool for defining
15
+ # expectations in your specifications.
16
+ #
17
+ # Like #should it can be used to designate an expectation
18
+ # via a *functor*.
19
+ #
20
+ # 4.expect == 3
21
+ #
22
+ # Or it can be used in block form.
23
+ #
24
+ # expect(4){ 3 }
25
+ #
26
+ # This compares the expected value and the actual
27
+ # value with <i>broad equality</i>. This is similar to
28
+ # case equality (#===) but also checks other forms of
29
+ # equality. See the #equate method.
30
+ #
31
+ # Of particluar utility is that #expect allows one to
32
+ # specify if the block raises the error.
33
+ #
34
+ # expect NoMethodError do
35
+ # not_a_method
36
+ # end
37
+ #
38
+ def expect(exp=Expectation, &block)
39
+ if exp == Expectation
40
+ Expectation.new(self, :backtrace=>caller)
41
+ elsif Exception >= exp
42
+ begin
43
+ act = block.call
44
+ test = exp.equate?(act)
45
+ msg = "#{exp}.equate? #{act}"
46
+ rescue exp => error
47
+ test = true
48
+ #msg = "#{exp} expected to be raised"
49
+ rescue Exception => error
50
+ test = false
51
+ msg = "#{exp} expected but #{error.class} was raised"
52
+ end
53
+ raise Assertion.new(msg, caller) unless test
54
+ else
55
+ act = block.call
56
+ test = exp.equate?(act)
57
+ msg = "#{exp}.equate? #{act}"
58
+ raise Assertion.new(msg, caller) unless test
59
+ end
60
+ end
61
+
62
+ # Designate a negated expectation. Read this as
63
+ # "expect not".
64
+ #
65
+ # 4.expect! == 4 #=> Expectation Error
66
+ #
67
+ # See #expect.
68
+ #
69
+ # Note that this method would not be necessary if
70
+ # Ruby would allow +!=+ to be defined as a method,
71
+ # or perhaps +!+ as a unary method.
72
+ #
73
+ def expect!(exp=Expectation, &block)
74
+ if exp == Expectation
75
+ Expectation.new(self, :negate=>true, :backtrace=>caller)
76
+ elsif Exception >= exp
77
+ begin
78
+ act = block.call
79
+ test = !exp.equate?(act)
80
+ msg = "! #{exp}.equate? #{act}"
81
+ rescue exp => error
82
+ test = false
83
+ msg = "#{exp} raised"
84
+ rescue Exception => error
85
+ test = true
86
+ #msg = "#{exp} expected but was #{error.class}"
87
+ end
88
+ raise Assertion.new(msg, caller) unless test
89
+ else
90
+ act = block.call
91
+ test = !exp.equate?(act)
92
+ msg = "! #{exp}.equate? #{act}"
93
+ raise Assertion.new(msg, caller) unless test
94
+ end
95
+ end
96
+
97
+ # See #expect! method.
98
+ #
99
+ alias_method :expect_not, :expect!
100
+
101
+ end
102
+
103
+ end
104
+
105
+ class ::Object #:nodoc:
106
+ include Grammar::Expect
107
+ end
108
+
109
+ module ::Kernel
110
+ # Broad equality.
111
+ #
112
+ def equate?(actual)
113
+ self.equal?(actual) ||
114
+ self.eql?(actual) ||
115
+ self == actual ||
116
+ self === actual
117
+ end
118
+ end
119
+
120
+ end
121
+
@@ -0,0 +1,291 @@
1
+ module QED
2
+
3
+ module Grammar #:nodoc:
4
+
5
+ module Legacy #:nodoc:
6
+
7
+ # = Test::Unit Legacy Assertions
8
+ #
9
+ # This module provides a compatibility layer for Test::Unit.
10
+ # This is an optional module and is intended for providing
11
+ # an easier transition from Test::Unit::TestCase to Quarry
12
+ # Specifications.
13
+ #
14
+ # Note that two methods are not provided, +#assert_nothing_raised+,
15
+ # and +#assert_nothing_thrown+.
16
+ #
17
+ module Assertions
18
+
19
+ # Private method upon which all of the legacy assertions are based
20
+ # (except for #assert itself).
21
+ #
22
+ def __assert__(test, msg=nil)
23
+ msg = "failed assertion (no message given)" unless msg
24
+ raise Assertion.new(msg, caller[1..-1]) unless test
25
+ end
26
+
27
+ private :__assert__
28
+
29
+ # The assertion upon which all other assertions are based.
30
+ #
31
+ # assert [1, 2].include?(5)
32
+ #
33
+ def assert(test=nil, msg=nil)
34
+ if test
35
+ msg = "failed assertion (no message given)" unless msg
36
+ raise Assertion.new(msg, caller) unless test
37
+ else
38
+ Expectation.new(self, :backtrace=>caller)
39
+ end
40
+ end
41
+
42
+ # Passes if the block yields true.
43
+ #
44
+ # assert_block "Couldn't do the thing" do
45
+ # do_the_thing
46
+ # end
47
+ #
48
+ def assert_block(msg=nil) # :yields:
49
+ test = ! yield
50
+ msg = "assertion failed" unless msg
51
+ __assert__(test, msg)
52
+ end
53
+
54
+ # Passes if expected == +actual.
55
+ #
56
+ # Note that the ordering of arguments is important,
57
+ # since a helpful error message is generated when this
58
+ # one fails that tells you the values of expected and actual.
59
+ #
60
+ # assert_equal 'MY STRING', 'my string'.upcase
61
+ #
62
+ def assert_equal(exp, act, msg=nil)
63
+ test = (exp == act)
64
+ msg = "Expected #{act.inspect} to be equal to #{exp.inspect}" unless msg
65
+ __assert__(test, msg)
66
+ end
67
+
68
+ # Passes if expected_float and actual_float are equal within delta tolerance.
69
+ #
70
+ # assert_in_delta 0.05, (50000.0 / 10**6), 0.00001
71
+ #
72
+ def assert_in_delta(exp, act, delta, msg=nil)
73
+ test = (exp.to_f - act.to_f).abs <= delta.to_f
74
+ msg = "Expected #{exp} to be within #{delta} of #{act}" unless msg
75
+ __assert__(test, msg)
76
+ end
77
+
78
+ # Passes if object .instance_of? klass
79
+ #
80
+ # assert_instance_of String, 'foo'
81
+ #
82
+ def assert_instance_of(cls, obj, msg=nil)
83
+ test = (cls === obj)
84
+ msg = "Expected #{obj} to be a #{cls}" unless msg
85
+ __assert__(test, msg)
86
+ end
87
+
88
+ # Passes if object .kind_of? klass
89
+ #
90
+ # assert_kind_of Object, 'foo'
91
+ #
92
+ def assert_kind_of(cls, obj, msg=nil)
93
+ test = obj.kind_of?(cls)
94
+ msg = "Expected #{obj.inspect} to be a kind of #{cls}" unless msg
95
+ __assert__(test, msg)
96
+ end
97
+
98
+ # Passes if string =~ pattern.
99
+ #
100
+ # assert_match(/\d+/, 'five, 6, seven')
101
+ #
102
+ def assert_match(exp, act, msg=nil)
103
+ test = (act =~ exp)
104
+ msg = "Expected #{act.inspect} to match #{exp.inspect}" unless msg
105
+ __assert__(test, msg)
106
+ end
107
+
108
+ # Passes if object is nil.
109
+ #
110
+ # assert_nil [1, 2].uniq!
111
+ #
112
+ def assert_nil(obj, msg=nil)
113
+ test = obj.nil?
114
+ msg = "Expected #{obj.inspect} to be nil" unless msg
115
+ __assert__(test, msg)
116
+ end
117
+
118
+ # Passes if regexp !~ string
119
+ #
120
+ # assert_no_match(/two/, 'one 2 three')
121
+ #
122
+ def assert_no_match(exp, act, msg=nil)
123
+ test = (act !~ exp)
124
+ msg = "Expected #{act.inspect} to match #{exp.inspect}" unless msg
125
+ __assert__(test, msg)
126
+ end
127
+
128
+ # Passes if expected != actual
129
+ #
130
+ # assert_not_equal 'some string', 5
131
+ #
132
+ def assert_not_equal(exp, act, msg=nil)
133
+ test = (exp != act)
134
+ msg = "Expected #{act.inspect} to not be equal to #{exp.inspect}" unless msg
135
+ __assert__(test, msg)
136
+ end
137
+
138
+ # Passes if ! object .nil?
139
+ #
140
+ # assert_not_nil '1 two 3'.sub!(/two/, '2')
141
+ #
142
+ def assert_not_nil(obj, msg=nil)
143
+ test = ! obj.nil?
144
+ msg = "Expected #{obj.inspect} to not be nil" unless msg
145
+ __assert__(test, msg)
146
+ end
147
+
148
+ # Passes if ! actual .equal? expected
149
+ #
150
+ # assert_not_same Object.new, Object.new
151
+ #
152
+ def assert_not_same(exp, act, msg=nil)
153
+ test = ! exp.equal?(act)
154
+ msg = "Expected #{act.inspect} to not be the same as #{exp.inspect}" unless msg
155
+ __assert__(test, msg)
156
+ end
157
+
158
+ # Compares the +object1+ with +object2+ using operator.
159
+ #
160
+ # Passes if object1.send(operator, object2) is true.
161
+ #
162
+ # assert_operator 5, :>=, 4
163
+ #
164
+ def assert_operator(o1, op, o2, msg="")
165
+ test = o1.__send__(op, o2)
166
+ msg = "Expected #{o1}.#{op}(#{o2}) to be true" unless msg
167
+ __assert__(test, msg)
168
+ end
169
+
170
+ # Passes if the block raises one of the given exceptions.
171
+ #
172
+ # assert_raise RuntimeError, LoadError do
173
+ # raise 'Boom!!!'
174
+ # end
175
+ #
176
+ def assert_raises(*args)
177
+ if msg = (Module === args.last ? nil : args.pop)
178
+ begin
179
+ yield
180
+ msg = "Expected #{exp} to be raised" unless msg
181
+ __assert__(false, msg)
182
+ rescue Exception => e
183
+ test = (exp === e)
184
+ msg = "Expected #{exp} to be raised, but got #{e.class}" unless msg
185
+ __assert__(test, msg)
186
+ return e
187
+ end
188
+ end
189
+
190
+ alias_method :assert_raise, :assert_raises
191
+
192
+ # Provides a way to assert that a procedure
193
+ # <i>does not</i> raise an exception.
194
+ #
195
+ # refute_raises(StandardError){ raise }
196
+ #
197
+ #def assert_raises!(exception, &block)
198
+ # begin
199
+ # block.call(*a)
200
+ # rescue exception
201
+ # raise Assertion
202
+ # end
203
+ #end
204
+ #alias_method :refute_raises, :assert_raises!
205
+
206
+ # Passes if +object+ respond_to? +method+.
207
+ #
208
+ # assert_respond_to 'bugbear', :slice
209
+ #
210
+ def assert_respond_to(obj, meth, msg=nil)
211
+ msg = "Expected #{obj} (#{obj.class}) to respond to ##{meth}" unless msg
212
+ #flip = (Symbol === obj) && ! (Symbol === meth) # HACK for specs
213
+ #obj, meth = meth, obj if flip
214
+ test = obj.respond_to?(meth)
215
+ __assert__(test, msg)
216
+ end
217
+
218
+ # Passes if +actual+ .equal? +expected+ (i.e. they are the same instance).
219
+ #
220
+ # o = Object.new
221
+ # assert_same(o, o)
222
+ #
223
+ def assert_same(exp, act, msg=nil)
224
+ msg = "Expected #{act.inspect} to be the same as #{exp.inspect}" unless msg
225
+ test = exp.equal?(act)
226
+ __assert__(test, msg)
227
+ end
228
+
229
+ # Passes if the method send returns a true value.
230
+ # The parameter +send_array+ is composed of:
231
+ #
232
+ # * A receiver
233
+ # * A method
234
+ # * Arguments to the method
235
+ #
236
+ # Example:
237
+ #
238
+ # assert_send [[1, 2], :include?, 4]
239
+ #
240
+ def assert_send(send_array, msg=nil)
241
+ r, m, *args = *send_array
242
+ test = r.__send__(m, *args)
243
+ msg = "Expected #{r}.#{m}(*#{args.inspect}) to return true" unless msg
244
+ __assert__(test, msg)
245
+ end
246
+
247
+ # Passes if the block throws expected_symbol
248
+ #
249
+ # assert_throws :done do
250
+ # throw :done
251
+ # end
252
+ #
253
+ def assert_throws(sym, msg=nil)
254
+ msg = "Expected #{sym} to have been thrown" unless msg
255
+ test = true
256
+ catch(sym) do
257
+ begin
258
+ yield
259
+ rescue ArgumentError => e # 1.9 exception
260
+ default += ", not #{e.message.split(/ /).last}"
261
+ rescue NameError => e # 1.8 exception
262
+ default += ", not #{e.name.inspect}"
263
+ end
264
+ test = false
265
+ end
266
+ __assert__(test, msg)
267
+ end
268
+
269
+ # Flunk always fails.
270
+ #
271
+ # flunk 'Not done testing yet.'
272
+ #
273
+ def flunk(msg=nil)
274
+ __assert__(false, msg)
275
+ end
276
+
277
+ end #module Assertions
278
+
279
+ end #module Legacy
280
+
281
+ end #module Grammar
282
+
283
+ # This could be in Object, but since they will only be needed in
284
+ # the context of a, well, Context...
285
+ #
286
+ class Context #:nodoc:
287
+ include Grammar::Legacy::Assertions
288
+ end
289
+
290
+ end #module Quarry
291
+
@@ -0,0 +1,52 @@
1
+ module QED
2
+
3
+ require 'qed/expectation'
4
+
5
+ module Grammar
6
+
7
+ # = Should Nomenclature
8
+ #
9
+ # The term *should* has become the defacto standard for
10
+ # BDD assertions, so Quarry supports this nomenclature.
11
+ #
12
+ module Should
13
+
14
+ # Same as #expect but only as a functor.
15
+ #
16
+ # 4.should == 3 #=> Expectation Error
17
+ #
18
+ def should
19
+ return Expectation.new(self, :backtrace=>caller)
20
+ end
21
+
22
+ # Designate a negated expectation via a *functor*.
23
+ # Read this as "should not".
24
+ #
25
+ # 4.should! == 4 #=> Expectation Error
26
+ #
27
+ # See also #expect!
28
+ #
29
+ def should!
30
+ return Expectation.new(self, :negate=>true, :backtrace=>caller)
31
+ end
32
+
33
+ # See #should! method.
34
+ #
35
+ alias_method :should_not, :should!
36
+
37
+ #
38
+ #alias_method :should_raise, :assert_raises
39
+
40
+ #
41
+ #alias_method :should_not_raise, :assert_raises!
42
+
43
+ end
44
+
45
+ end
46
+
47
+ class ::Object #:nodoc:
48
+ include Grammar::Should
49
+ end
50
+
51
+ end
52
+