ae 1.6.1 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby +33 -0
- data/{LICENSE → Apache2.txt} +3 -1
- data/{HISTORY.rdoc → History.rdoc} +18 -0
- data/NOTICE.rdoc +30 -0
- data/README.rdoc +38 -11
- data/Syckfile +82 -0
- data/lib/ae.rb +22 -19
- data/lib/ae.yml +33 -0
- data/lib/ae/adapters/minitest.rb +10 -17
- data/lib/ae/adapters/rspec.rb +1 -11
- data/lib/ae/adapters/testunit.rb +21 -20
- data/lib/ae/assert.rb +15 -8
- data/lib/ae/assertion.rb +36 -60
- data/lib/ae/assertor.rb +250 -178
- data/lib/ae/basic_object.rb +6 -10
- data/lib/ae/core_ext.rb +2 -208
- data/lib/ae/core_ext/exception.rb +13 -0
- data/lib/ae/core_ext/helpers.rb +198 -0
- data/lib/ae/expect.rb +2 -2
- data/lib/ae/must.rb +5 -1
- data/lib/ae/subjunctive.rb +1 -1
- data/lib/ae/version.rb +19 -0
- data/qed/01_overview.rdoc +1 -1
- data/qed/06_counts.rdoc +11 -7
- metadata +18 -17
- data/NOTICE +0 -14
- data/lib/ae/meta/data.rb +0 -29
- data/lib/ae/meta/package +0 -8
- data/lib/ae/meta/profile +0 -23
data/lib/ae/assert.rb
CHANGED
@@ -2,8 +2,10 @@ require 'ae/assertor'
|
|
2
2
|
|
3
3
|
module AE
|
4
4
|
|
5
|
-
#
|
5
|
+
# The Assert module is simple a conatiner module for the core
|
6
|
+
# extension methods: #assert, #expect, etc.
|
6
7
|
#
|
8
|
+
# This module is included directory into the Object class.
|
7
9
|
module Assert
|
8
10
|
|
9
11
|
# Assert a operational relationship.
|
@@ -31,30 +33,35 @@ module AE
|
|
31
33
|
Assertor.new(self, :backtrace=>caller).assert == cmp
|
32
34
|
end
|
33
35
|
|
34
|
-
#
|
35
|
-
# Read it as "assert not".
|
36
|
+
# Opposite of assert.
|
36
37
|
#
|
37
38
|
# 4.refute == 4 #=> Assertion Error
|
38
39
|
#
|
39
|
-
# See #assert.
|
40
40
|
def refute(*args, &block)
|
41
41
|
Assertor.new(self, :backtrace=>caller).not.assert(*args, &block)
|
42
42
|
end
|
43
43
|
|
44
|
-
# Same as 'object.
|
44
|
+
# Same as 'object.refute == other'.
|
45
45
|
def refute=(cmp)
|
46
46
|
Assertor.new(self, :backtrace=>caller).not.assert == cmp
|
47
47
|
end
|
48
48
|
|
49
|
-
# Alias for #assert
|
49
|
+
# Alias for #refute. Read it as "assert not".
|
50
50
|
#
|
51
51
|
# 4.assert! == 4
|
52
52
|
#
|
53
53
|
# NOTE: This method would not be necessary if Ruby would allow
|
54
54
|
# +!=+ to be define as a method, or at least +!+ as a unary method.
|
55
|
-
#
|
55
|
+
# Looks like this is possible in Ruby 1.9, but we will wait until
|
56
|
+
# Ruby 1.9 is the norm.
|
56
57
|
alias_method :assert!, :refute
|
57
|
-
|
58
|
+
|
59
|
+
# Directly raise an Assertion failure.
|
60
|
+
def flunk(message=nil, backtrace=nil)
|
61
|
+
#Assertor.new(self, :backtrace=>caller).assert(false, message)
|
62
|
+
Assertor.assert(false, message, caller)
|
63
|
+
end
|
64
|
+
|
58
65
|
end
|
59
66
|
|
60
67
|
end
|
data/lib/ae/assertion.rb
CHANGED
@@ -1,77 +1,53 @@
|
|
1
|
-
|
1
|
+
# Copyright (c) 2008,2010 Thomas Sawyer
|
2
2
|
|
3
|
-
|
4
|
-
#
|
5
|
-
# "The reserve of modern assertions is sometimes pushed to extremes,
|
6
|
-
# in which the fear of being contradicted leads the writer to strip
|
7
|
-
# himself of almost all sense and meaning."
|
8
|
-
# -- Sir Winston Churchill (1874 - 1965)
|
9
|
-
#
|
10
|
-
# This is the underlying Exception class of the whole system.
|
11
|
-
#
|
12
|
-
class Assertion < Exception
|
3
|
+
require 'ae/core_ext'
|
13
4
|
|
14
|
-
|
15
|
-
@count = 0
|
16
|
-
@fails = 0
|
5
|
+
module AE
|
17
6
|
|
18
|
-
class
|
19
|
-
|
20
|
-
|
7
|
+
# The Assertion class is simply a subclass of Exception that is used
|
8
|
+
# by AE as the default error raised when an assertion fails.
|
9
|
+
#
|
10
|
+
# "The reserve of modern assertions is sometimes pushed to extremes,
|
11
|
+
# in which the fear of being contradicted leads the writer to strip
|
12
|
+
# himself of almost all sense and meaning."
|
13
|
+
# -- Sir Winston Churchill (1874 - 1965)
|
14
|
+
#
|
15
|
+
#
|
16
|
+
class Assertion < Exception
|
21
17
|
|
22
|
-
#
|
23
|
-
def
|
24
|
-
|
25
|
-
increment(true)
|
26
|
-
else
|
27
|
-
framework_flunk(options)
|
28
|
-
end
|
29
|
-
test
|
18
|
+
# DEPRECATE: This will be removed in favor of Assertor#counts.
|
19
|
+
def self.counts
|
20
|
+
AE::Assertor.counts
|
30
21
|
end
|
31
22
|
|
23
|
+
# New assertion (failure).
|
32
24
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
fail ::Assertion.new(message, options)
|
25
|
+
# message - the failure message
|
26
|
+
# options - such as :backtrace
|
27
|
+
#
|
28
|
+
def initialize(message=nil, options={})
|
29
|
+
super(message)
|
30
|
+
backtrace = options[:backtrace]
|
31
|
+
set_backtrace(backtrace) if backtrace
|
32
|
+
set_assertion(true)
|
42
33
|
end
|
43
34
|
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
@fails += 1 unless pass
|
35
|
+
# Technically any object that affirmatively responds to #assertion?
|
36
|
+
# can be taken to be an Assertion. This makes it easier for various
|
37
|
+
# libraries to work together without having to depend upon a common
|
38
|
+
# Assertion base class.
|
39
|
+
def assertion?
|
40
|
+
true
|
51
41
|
end
|
52
42
|
|
53
|
-
#
|
54
|
-
def
|
55
|
-
|
56
|
-
@count = 0
|
57
|
-
@fails = 0
|
58
|
-
return f, c
|
43
|
+
#
|
44
|
+
def to_s
|
45
|
+
'(assertion) ' + super
|
59
46
|
end
|
60
|
-
end
|
61
47
|
|
62
|
-
#
|
63
|
-
def initialize(message=nil, options={})
|
64
|
-
super(message)
|
65
|
-
backtrace = options[:backtrace]
|
66
|
-
set_backtrace(backtrace) if backtrace
|
67
|
-
self.class.increment(false)
|
68
|
-
end
|
69
|
-
|
70
|
-
#
|
71
|
-
def to_s
|
72
|
-
'fail ' + super
|
73
48
|
end
|
74
49
|
|
75
50
|
end
|
76
51
|
|
77
|
-
#
|
52
|
+
# Set top-level Assertion to AE::Assertion
|
53
|
+
Assertion = AE::Assertion
|
data/lib/ae/assertor.rb
CHANGED
@@ -1,215 +1,287 @@
|
|
1
1
|
require 'ae/assertion'
|
2
2
|
require 'ae/basic_object'
|
3
3
|
|
4
|
-
|
5
|
-
#
|
6
|
-
# == What is a Functor?
|
7
|
-
#
|
8
|
-
# A Functor is a succinct name for what is also know as a
|
9
|
-
# Higher Order Function. In other words, it is a function
|
10
|
-
# that acts on a function. It is very similiar to a delegator
|
11
|
-
# in most respects, but is conditioned on the operation applied,
|
12
|
-
# rather then simply passing-off to an alternate reciever.
|
13
|
-
#
|
14
|
-
class Assertor < AE::BasicObject
|
4
|
+
module AE
|
15
5
|
|
6
|
+
# Assertor is the underlying class of the whole system. It implements
|
7
|
+
# the flutent assertion notation.
|
16
8
|
#
|
17
|
-
#
|
9
|
+
# An Assertor is an Assertion Functor. A Functor is a succinct name for what
|
10
|
+
# is also known as Higher Order Function. In other words, it is a function
|
11
|
+
# that acts on a function. It is very similiar to a delegator in most
|
12
|
+
# respects, but is conditioned on the operation applied, rather then simply
|
13
|
+
# passing-off to an alternate reciever.
|
14
|
+
#
|
15
|
+
class Assertor < AE::BasicObject
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
end
|
17
|
+
# Initial settings of assertion counts.
|
18
|
+
ZERO_COUNTS = {:total=>0,:pass=>0,:fail=>0}
|
22
19
|
|
23
|
-
|
24
|
-
|
25
|
-
def initialize(delegate, opts={}) #, backtrace)
|
26
|
-
@delegate = delegate
|
27
|
-
@message = opts[:message]
|
28
|
-
@backtrace = opts[:backtrace] || caller #[1..-1]
|
29
|
-
@negated = !!opts[:negated]
|
30
|
-
end
|
20
|
+
# Initialize assertion counts global variable.
|
21
|
+
$assertion_counts = ZERO_COUNTS.dup
|
31
22
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
@negated = !@negated
|
37
|
-
@message = msg if msg
|
38
|
-
self
|
39
|
-
end
|
23
|
+
# Returns Hash used to track assertion counts.
|
24
|
+
def self.counts
|
25
|
+
$assertion_counts
|
26
|
+
end
|
40
27
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
# instead of
|
51
|
-
#
|
52
|
-
# assert something, parameter
|
53
|
-
#
|
54
|
-
def assert(*args, &block)
|
55
|
-
return self if args.empty? && !block
|
56
|
-
|
57
|
-
target = block || args.shift
|
58
|
-
|
59
|
-
if ::Proc === target || target.respond_to?(:to_proc)
|
60
|
-
block = target.to_proc
|
61
|
-
match = args.shift
|
62
|
-
result = block.arity > 0 ? block.call(@delegate) : block.call
|
63
|
-
if match
|
64
|
-
pass = (match == result)
|
65
|
-
msg = @message || "#{match.inspect} == #{result.inspect}"
|
28
|
+
# Reset assertion counts.
|
29
|
+
#
|
30
|
+
# reset - Hash which will be used to set counts manually (optional).
|
31
|
+
#
|
32
|
+
# Returns the Hash of previous counts.
|
33
|
+
def self.recount(reset={})
|
34
|
+
old_counts = counts.dup
|
35
|
+
if reset.empty?
|
36
|
+
counts.replace(ZERO_COUNTS.dup)
|
66
37
|
else
|
67
|
-
|
68
|
-
|
38
|
+
reset.each do |type, value|
|
39
|
+
counts[type.to_sym] = value
|
40
|
+
end
|
69
41
|
end
|
70
|
-
|
71
|
-
pass = target.matches?(@delegate)
|
72
|
-
msg = @message || matcher_message(target) || target.inspect
|
73
|
-
else
|
74
|
-
pass = target # truthiness
|
75
|
-
msg = args.shift # optional mesage for TestUnit compatiability
|
42
|
+
return old_counts
|
76
43
|
end
|
77
44
|
|
78
|
-
|
79
|
-
|
45
|
+
# Increment assertion counts. If +pass+ is +true+ then +:total+
|
46
|
+
# and +:pass+ are increased. If +pass+ if +false+ then +:total+
|
47
|
+
# and +:fail+ are incremented.
|
48
|
+
def self.increment_counts(pass)
|
49
|
+
counts[:total] += 1
|
50
|
+
if pass
|
51
|
+
counts[:pass] += 1
|
52
|
+
else
|
53
|
+
counts[:fail] += 1
|
54
|
+
end
|
55
|
+
return counts
|
56
|
+
end
|
80
57
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
58
|
+
# Basic assertion. This method by-passes all the Assertor fluent
|
59
|
+
# constructs and performs the underlying assertion procedure. It
|
60
|
+
# is used by Assertor as the end result of an assertion.
|
61
|
+
def self.assert(pass, message=nil, backtrace=nil)
|
62
|
+
increment_counts(pass)
|
63
|
+
if !pass
|
64
|
+
backtrace = backtrace || caller
|
65
|
+
message = message || 'flunk'
|
66
|
+
raise_assertion(message, backtrace)
|
67
|
+
end
|
68
|
+
return pass
|
69
|
+
end
|
70
|
+
|
71
|
+
# This method can be replaced to support alternate frameworks.
|
72
|
+
# The intent of the method is to raise the assertion failure
|
73
|
+
# class that the framework uses.
|
74
|
+
def self.raise_assertion(message, backtrace=nil)
|
75
|
+
backtrace = backtrace || caller
|
76
|
+
|
77
|
+
error = assertion_error.new(message)
|
78
|
+
error.set_backtrace(backtrace)
|
79
|
+
error.set_assertion(true)
|
80
|
+
fail error
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns the Exception class to be raised when an assertion fails.
|
84
|
+
def self.assertion_error
|
85
|
+
::Assertion
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
if ::RUBY_VERSION >= '1.9'
|
90
|
+
eval "private :==, :!, :!=" # using eval here b/c it's a syntax error in 1.8-
|
91
|
+
end
|
92
|
+
|
93
|
+
# New Assertor.
|
94
|
+
#
|
95
|
+
def initialize(delegate, opts={}) #, backtrace)
|
96
|
+
@delegate = delegate
|
97
|
+
@message = opts[:message]
|
98
|
+
@backtrace = opts[:backtrace] || caller #[1..-1]
|
99
|
+
@negated = !!opts[:negated]
|
100
|
+
end
|
101
|
+
|
102
|
+
# Negate the meaning of the assertion.
|
103
|
+
#
|
104
|
+
#--
|
105
|
+
# TODO: Should this return a new Assertor instead of in place negation?
|
106
|
+
#++
|
107
|
+
def not(msg=nil)
|
108
|
+
@negated = !@negated
|
109
|
+
@message = msg if msg
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
113
|
+
# Internal assert, provides all functionality associated
|
114
|
+
# with external #assert method. (See Assert#assert)
|
115
|
+
#
|
116
|
+
# NOTE: I'm calling YAGNI on using extra arguments to pass
|
117
|
+
# to the block. The interface is much nicer if a macro is
|
118
|
+
# created to handle any neccessry arguments. Eg.
|
119
|
+
#
|
120
|
+
# assert something(parameter)
|
121
|
+
#
|
122
|
+
# instead of
|
123
|
+
#
|
124
|
+
# assert something, parameter
|
125
|
+
#
|
126
|
+
# Returns +true+ or +false+ based on assertions success.
|
127
|
+
def assert(*args, &block)
|
128
|
+
return self if args.empty? && !block
|
129
|
+
|
130
|
+
target = block || args.shift
|
131
|
+
|
132
|
+
if ::Proc === target || target.respond_to?(:to_proc)
|
133
|
+
block = target.to_proc
|
134
|
+
match = args.shift
|
135
|
+
result = block.arity > 0 ? block.call(@delegate) : block.call
|
136
|
+
if match
|
137
|
+
pass = (match == result)
|
138
|
+
msg = @message || "#{match.inspect} == #{result.inspect}"
|
139
|
+
else
|
140
|
+
pass = result
|
141
|
+
msg = @message || block.inspect # "#{result.inspect}"
|
110
142
|
end
|
143
|
+
elsif target.respond_to?(:matches?)
|
144
|
+
pass = target.matches?(@delegate)
|
145
|
+
msg = @message || matcher_message(target) || target.inspect
|
111
146
|
else
|
112
|
-
|
113
|
-
|
114
|
-
msg = @message || "#{match.inspect} === #{result.inspect}"
|
147
|
+
pass = target # truthiness
|
148
|
+
msg = args.shift # optional mesage for TestUnit compatiability
|
115
149
|
end
|
116
|
-
|
117
|
-
pass
|
118
|
-
msg = @message || matcher_message(target) || target.inspect
|
119
|
-
else
|
120
|
-
pass = (target === @delegate)
|
121
|
-
msg = @message || "#{target.inspect} === #{@delegate.inspect}"
|
150
|
+
|
151
|
+
__assert__(pass, msg)
|
122
152
|
end
|
123
153
|
|
124
|
-
|
125
|
-
|
154
|
+
# Internal expect, provides all functionality associated
|
155
|
+
# with external #expect method. (See Expect#expect)
|
156
|
+
#
|
157
|
+
#--
|
158
|
+
# TODO: Should we deprecate the receiver matches in favor of #expected ?
|
159
|
+
# In other words, should the <code>|| @delegate</code> be dropped?
|
160
|
+
#++
|
161
|
+
def expect(*args, &block)
|
162
|
+
return self if args.empty? && !block # same as #assert
|
126
163
|
|
127
|
-
|
128
|
-
#--
|
129
|
-
# TODO: Should we use a more libreral determination of exception.
|
130
|
-
# e.g. <code>respond_to?(:exception)</code>.
|
131
|
-
#++
|
132
|
-
def exception?(object)
|
133
|
-
::Exception === object or ::Class === object and object.ancestors.include?(::Exception)
|
134
|
-
end
|
164
|
+
target = block || args.shift
|
135
165
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
166
|
+
if ::Proc === target #|| target.respond_to?(:to_proc)
|
167
|
+
#block = target.to_proc
|
168
|
+
match = args.shift || @delegate
|
169
|
+
if exception?(match)
|
170
|
+
$DEBUG, debug = false, $DEBUG # b/c it always spits-out a NameError
|
171
|
+
begin
|
172
|
+
block.arity > 0 ? block.call(@delegate) : block.call
|
173
|
+
pass = false
|
174
|
+
msg = "#{match} not raised"
|
175
|
+
rescue match => error
|
176
|
+
pass = true
|
177
|
+
msg = "#{match} raised"
|
178
|
+
rescue ::Exception => error
|
179
|
+
pass = false
|
180
|
+
msg = "#{match} expected but #{error.class} was raised"
|
181
|
+
ensure
|
182
|
+
$DEBUG = debug
|
183
|
+
end
|
184
|
+
else
|
185
|
+
result = block.arity > 0 ? block.call(@delegte) : block.call
|
186
|
+
pass = (match === result)
|
187
|
+
msg = @message || "#{match.inspect} === #{result.inspect}"
|
188
|
+
end
|
189
|
+
elsif target.respond_to?(:matches?)
|
190
|
+
pass = target.matches?(@delegate)
|
191
|
+
msg = @message || matcher_message(target) || target.inspect
|
192
|
+
else
|
193
|
+
pass = (target === @delegate)
|
194
|
+
msg = @message || "#{target.inspect} === #{@delegate.inspect}"
|
195
|
+
end
|
140
196
|
|
141
|
-
|
142
|
-
|
143
|
-
# skips #method_missing.
|
144
|
-
def =~(match)
|
145
|
-
method_missing(:"=~", match)
|
146
|
-
end
|
197
|
+
__assert__(pass, msg)
|
198
|
+
end
|
147
199
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
200
|
+
#
|
201
|
+
def flunk(message=nil, backtrace=nil)
|
202
|
+
__assert__(false, message || @message)
|
203
|
+
end
|
152
204
|
|
153
|
-
|
205
|
+
# Ruby seems to have a quark in it's implementation whereby
|
206
|
+
# this must be defined explicitly, otherwise it somehow
|
207
|
+
# skips #method_missing.
|
208
|
+
def =~(match)
|
209
|
+
method_missing(:"=~", match)
|
210
|
+
end
|
154
211
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
#pass = @delegate.public_send(sym, *a, &b)
|
160
|
-
__assert__(pass, @message || __msg__(sym, *a, &b))
|
161
|
-
end
|
212
|
+
#
|
213
|
+
def send(op, *a, &b)
|
214
|
+
method_missing(op, *a, &b)
|
215
|
+
end
|
162
216
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
if @negated
|
168
|
-
"! #{inspection} #{m} #{a.collect{|x| x.inspect}.join(',')}"
|
169
|
-
else
|
170
|
-
"#{inspection} #{m} #{a.collect{|x| x.inspect}.join(',')}"
|
171
|
-
end
|
172
|
-
#self.class.message(m)[@delegate, *a] )
|
173
|
-
end
|
217
|
+
#
|
218
|
+
def inspect
|
219
|
+
@delegate.inspect
|
220
|
+
end
|
174
221
|
|
175
|
-
|
176
|
-
#--
|
177
|
-
# TODO: Can the handling of the message be simplified/improved?
|
178
|
-
#++
|
179
|
-
def __assert__(pass, message=nil)
|
180
|
-
pass = @negated ^ pass
|
181
|
-
# msg = message || @message
|
182
|
-
::Assertion.test(pass, :message=>message, :backtrace=>@backtrace)
|
183
|
-
return pass
|
184
|
-
end
|
222
|
+
private
|
185
223
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
224
|
+
# Is the +object+ an Exception or an instance of one?
|
225
|
+
#--
|
226
|
+
# TODO: Should we use a more libreral determination of exception.
|
227
|
+
# e.g. <code>respond_to?(:exception)</code>.
|
228
|
+
#++
|
229
|
+
def exception?(object)
|
230
|
+
::Exception === object or ::Class === object and object.ancestors.include?(::Exception)
|
231
|
+
end
|
191
232
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
233
|
+
# Converts a missing method into an Assertion.
|
234
|
+
#
|
235
|
+
# TODO: In future should probably be `@delegate.public_send(sym, *a, &b)`.
|
236
|
+
def method_missing(sym, *a, &b)
|
237
|
+
pass = @delegate.__send__(sym, *a, &b)
|
238
|
+
__assert__(pass, @message || __msg__(sym, *a, &b))
|
239
|
+
end
|
240
|
+
|
241
|
+
# Puts together a suitable error message.
|
242
|
+
#
|
243
|
+
def __msg__(m, *a, &b)
|
244
|
+
inspection = @delegate.send(:inspect)
|
245
|
+
if @negated
|
246
|
+
"! #{inspection} #{m} #{a.collect{|x| x.inspect}.join(',')}"
|
247
|
+
else
|
248
|
+
"#{inspection} #{m} #{a.collect{|x| x.inspect}.join(',')}"
|
197
249
|
end
|
250
|
+
#self.class.message(m)[@delegate, *a] )
|
198
251
|
end
|
199
|
-
|
200
|
-
|
252
|
+
|
253
|
+
# Simple assert.
|
254
|
+
#--
|
255
|
+
# TODO: Can the handling of the message be simplified/improved?
|
256
|
+
#++
|
257
|
+
def __assert__(pass, message=nil)
|
258
|
+
pass = @negated ^ pass
|
259
|
+
Assertor.assert(pass, message, @backtrace)
|
201
260
|
end
|
202
|
-
|
261
|
+
|
262
|
+
#
|
263
|
+
def matcher_message(matcher)
|
264
|
+
if @negated
|
265
|
+
if matcher.respond_to?(:negative_failure_message)
|
266
|
+
return matcher.failure_message
|
267
|
+
end
|
268
|
+
end
|
269
|
+
if matcher.respond_to?(:failure_message)
|
270
|
+
return matcher.failure_message
|
271
|
+
end
|
272
|
+
false
|
273
|
+
end
|
274
|
+
|
275
|
+
# TODO: Ultimately better messages might be nice.
|
276
|
+
#
|
277
|
+
#def self.message(op,&block)
|
278
|
+
# @message ||= {}
|
279
|
+
# block ? @message[op.to_sym] = block : @message[op.to_sym]
|
280
|
+
#end
|
281
|
+
#
|
282
|
+
#message(:==){ |*a| "Expected #{a[0].inspect} to be equal to #{a[1].inspect}" }
|
203
283
|
end
|
204
284
|
|
205
|
-
# TODO: Ultimately better messages might be nice.
|
206
|
-
#
|
207
|
-
#def self.message(op,&block)
|
208
|
-
# @message ||= {}
|
209
|
-
# block ? @message[op.to_sym] = block : @message[op.to_sym]
|
210
|
-
#end
|
211
|
-
#
|
212
|
-
#message(:==){ |*a| "Expected #{a[0].inspect} to be equal to #{a[1].inspect}" }
|
213
285
|
end
|
214
286
|
|
215
287
|
# DO WE MAKE THESE EXCEPTIONS?
|