assay 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby +44 -0
- data/APACHE2.txt +205 -0
- data/HISTORY.rdoc +26 -0
- data/NOTICE.rdoc +18 -0
- data/README.rdoc +50 -0
- data/lib/assay.rb +44 -0
- data/lib/assay.yml +44 -0
- data/lib/assay/adapters/minitest.rb +25 -0
- data/lib/assay/adapters/testunit.rb +42 -0
- data/lib/assay/assertion.rb +148 -0
- data/lib/assay/assertions/compare_failure.rb +60 -0
- data/lib/assay/assertions/delta_failure.rb +80 -0
- data/lib/assay/assertions/empty_failure.rb +76 -0
- data/lib/assay/assertions/equality_failure.rb +105 -0
- data/lib/assay/assertions/execution_failure.rb +91 -0
- data/lib/assay/assertions/false_failure.rb +73 -0
- data/lib/assay/assertions/identity_failure.rb +86 -0
- data/lib/assay/assertions/instance_failure.rb +77 -0
- data/lib/assay/assertions/kind_failure.rb +80 -0
- data/lib/assay/assertions/match_failure.rb +86 -0
- data/lib/assay/assertions/nil_failure.rb +75 -0
- data/lib/assay/assertions/raise_failure.rb +133 -0
- data/lib/assay/assertions/response_failure.rb +87 -0
- data/lib/assay/assertions/same_failure.rb +83 -0
- data/lib/assay/assertions/throw_failure.rb +123 -0
- data/lib/assay/assertions/true_failure.rb +80 -0
- data/lib/assay/matcher.rb +48 -0
- data/qed/01_failure_classes.rdoc +75 -0
- data/qed/02_assertives.rdoc +118 -0
- data/qed/03_matchers.rdoc +118 -0
- data/qed/04_lookup.rdoc +10 -0
- metadata +143 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
module Test #:nodoc:
|
2
|
+
module Unit #:nodoc:
|
3
|
+
class TestCase #:nodoc:
|
4
|
+
# Runs the individual test method represented by this
|
5
|
+
# instance of the fixture, collecting statistics, failures
|
6
|
+
# and errors in result.
|
7
|
+
def run(result)
|
8
|
+
yield(STARTED, name)
|
9
|
+
@_result = result
|
10
|
+
begin
|
11
|
+
setup
|
12
|
+
__send__(@method_name)
|
13
|
+
rescue AssertionFailedError => e
|
14
|
+
add_failure(e.message, e.backtrace)
|
15
|
+
rescue Exception => e
|
16
|
+
if e.respond_to?(:assertion?) && e.assertion?
|
17
|
+
add_failure(e.message, e.backtrace)
|
18
|
+
else
|
19
|
+
raise if PASSTHROUGH_EXCEPTIONS.include? $!.class
|
20
|
+
add_error($!)
|
21
|
+
end
|
22
|
+
ensure
|
23
|
+
begin
|
24
|
+
teardown
|
25
|
+
rescue AssertionFailedError => e
|
26
|
+
add_failure(e.message, e.backtrace)
|
27
|
+
rescue Exception => e
|
28
|
+
if e.respond_to?(:assertion?) && e.assertion?
|
29
|
+
add_failure(e.message, e.backtrace)
|
30
|
+
else
|
31
|
+
raise if PASSTHROUGH_EXCEPTIONS.include? $!.class
|
32
|
+
add_error($!)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
result.add_run
|
37
|
+
yield(FINISHED, name)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'ansi/diff'
|
2
|
+
require 'assay/matcher'
|
3
|
+
|
4
|
+
module Assay
|
5
|
+
|
6
|
+
#
|
7
|
+
class Assertion < Exception
|
8
|
+
|
9
|
+
# When displaying errors, use this as a rule of thumb
|
10
|
+
# for determining when the inspected object will be too
|
11
|
+
# big for a single line message.
|
12
|
+
SIZE_LIMIT = 13
|
13
|
+
|
14
|
+
# Returns Matcher for the failure class.
|
15
|
+
def self.to_matcher(*args, &blk)
|
16
|
+
Matcher.new(self, *args, &blk)
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
def self.assertable_method
|
21
|
+
"assert_#{assertion_name}"
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
def self.assert(*args, &blk)
|
26
|
+
opts = Hash === args.last ? args.pop : {}
|
27
|
+
|
28
|
+
backtrace = opts[:backtrace] || caller
|
29
|
+
message = opts[:message]
|
30
|
+
|
31
|
+
err = new(message, *args, &blk)
|
32
|
+
err.set_backtrace(backtrace)
|
33
|
+
err.assert
|
34
|
+
|
35
|
+
#chk = check(*args, &blk)
|
36
|
+
#msg = fail_message(*args, &blk)
|
37
|
+
#if !chk
|
38
|
+
# msg = opts[:message]
|
39
|
+
# btr = opts[:backtrace] || caller
|
40
|
+
# err = new(msg, *args)
|
41
|
+
# err.set_backtrace(btr)
|
42
|
+
# fail err
|
43
|
+
#end
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
def self.refute(*args, &blk)
|
48
|
+
opts = Hash === args.last ? args.pop : {}
|
49
|
+
|
50
|
+
backtrace = opts[:backtrace] || caller
|
51
|
+
message = opts[:message]
|
52
|
+
|
53
|
+
err = new(message, *args, &blk)
|
54
|
+
err.set_backtrace(backtrace)
|
55
|
+
err.refute
|
56
|
+
|
57
|
+
#opts = Hash === args.last ? args.pop : {}
|
58
|
+
#chk = check!(*args, &blk)
|
59
|
+
##msg = fail_message!(*args, &blk)
|
60
|
+
#if !chk
|
61
|
+
# msg = opts[:message]
|
62
|
+
# btr = opts[:backtrace] || caller
|
63
|
+
# err = new(msg, :backtrace=>btr, :arguments=>args)
|
64
|
+
# fail err
|
65
|
+
#end
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
def self.pass?(*args, &blk)
|
70
|
+
raise NotImplementedError
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
def self.fail?(*args, &blk)
|
75
|
+
! pass?(*args, &blk)
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
def initialize(message=nil, *arguments, &block)
|
80
|
+
message ? super(message % arguments) : super()
|
81
|
+
|
82
|
+
@arguments = arguments
|
83
|
+
@block = block
|
84
|
+
|
85
|
+
#set_arguments options[:arguments] if options[:arguments]
|
86
|
+
#set_negative options[:negated] if options[:negated]
|
87
|
+
#set_backtrace options[:backtrace] if options[:backtrace]
|
88
|
+
end
|
89
|
+
|
90
|
+
# Failure is always a type of assertion.
|
91
|
+
#
|
92
|
+
# This method allows Assay's classes to work in any test framework
|
93
|
+
# that supports this interface.
|
94
|
+
def assertion?
|
95
|
+
true # @assertion = true if @assertion.nil?
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
def pass?
|
100
|
+
self.class.pass?(*@arguments, &@block) #^ @negative
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
def fail?
|
105
|
+
not pass?
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
def assert
|
110
|
+
#@negative = false
|
111
|
+
raise self unless pass?
|
112
|
+
end
|
113
|
+
|
114
|
+
#
|
115
|
+
def refute
|
116
|
+
#@negative = true
|
117
|
+
raise self unless fail?
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
def negative?
|
122
|
+
@negative
|
123
|
+
end
|
124
|
+
|
125
|
+
# Set whether this failure was the inverse of it's normal meaning.
|
126
|
+
# For example, `!=` rather than `==`.
|
127
|
+
def set_negative(negative)
|
128
|
+
@negative = !!negative
|
129
|
+
end
|
130
|
+
|
131
|
+
# Set arguments used to make assertion.
|
132
|
+
def set_arguments(arguments)
|
133
|
+
@arguments = arguments
|
134
|
+
#@block = block
|
135
|
+
end
|
136
|
+
|
137
|
+
#
|
138
|
+
def to_s
|
139
|
+
if @negative
|
140
|
+
"NOT " + super()
|
141
|
+
else
|
142
|
+
super()
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'assay/assertion'
|
2
|
+
|
3
|
+
module Assay
|
4
|
+
|
5
|
+
class CompareFailure < Assertion
|
6
|
+
|
7
|
+
def self.assertion_name
|
8
|
+
:like
|
9
|
+
end
|
10
|
+
|
11
|
+
# Test assertion.
|
12
|
+
def self.pass?(exp, act)
|
13
|
+
exp.equal?(act) ||
|
14
|
+
exp.eq?(act) ||
|
15
|
+
exp.==(act) ||
|
16
|
+
exp.===(act)
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
def to_s
|
21
|
+
return super unless @arguments.size == 2
|
22
|
+
|
23
|
+
iexp = @arguments[0].inspect
|
24
|
+
iact = @arguments[1].inspect
|
25
|
+
|
26
|
+
if @_negated
|
27
|
+
"Expected #{iact} to NOT be like #{iexp}"
|
28
|
+
else
|
29
|
+
"Expected #{iact} to be like #{iexp}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
module Assertives
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
module Matchers
|
42
|
+
#
|
43
|
+
#
|
44
|
+
# object1.should be_like(object2)
|
45
|
+
#
|
46
|
+
def be_like(act)
|
47
|
+
CompareFailure.to_matcher(act)
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
#
|
52
|
+
# object1.should be_like(object2)
|
53
|
+
#
|
54
|
+
def is_like(act)
|
55
|
+
CompareFailure.to_matcher(act)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'assay/assertions/compare_failure'
|
2
|
+
|
3
|
+
module Assay
|
4
|
+
|
5
|
+
# TODO: Support Range
|
6
|
+
class DeltaFailure < CompareFailure
|
7
|
+
|
8
|
+
#
|
9
|
+
def self.assertion_name
|
10
|
+
:in_delta
|
11
|
+
end
|
12
|
+
|
13
|
+
# Check assertion.
|
14
|
+
def self.pass?(exp, act, delta)
|
15
|
+
case delta
|
16
|
+
when Numeric
|
17
|
+
(exp.to_f - act.to_f).abs <= delta.to_f
|
18
|
+
else
|
19
|
+
exp - act <= delta
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
def to_s
|
25
|
+
return super unless @arguments.size == 3
|
26
|
+
|
27
|
+
exp = @arguments[0].inspect
|
28
|
+
act = @arguments[1].inspect
|
29
|
+
delta = @arguments[2].inspect
|
30
|
+
|
31
|
+
if @_negated
|
32
|
+
"Expected #{exp} to NOT be within #{delta} of #{act}"
|
33
|
+
else
|
34
|
+
"Expected #{exp} to be within #{delta} of #{act}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
module Assertives
|
42
|
+
# Passes if expected and actual are equal within delta tolerance.
|
43
|
+
#
|
44
|
+
# assert_in_delta 0.05, (50000.0 / 10**6), 0.00001
|
45
|
+
#
|
46
|
+
def assert_in_delta(exp, act, delta, opts={})
|
47
|
+
opts[:backtrace] ||= caller
|
48
|
+
DeltaFailure.assert(exp, act, delta, opts)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Passes if expected and actual are equal not within delta tolerance.
|
52
|
+
#
|
53
|
+
# assert_not_in_delta 0.05, (50000.0 / 10**6), 0.00001
|
54
|
+
#
|
55
|
+
def self.not_in_delta(exp, act, delta, opts)
|
56
|
+
opts[:backtrace] ||= caller
|
57
|
+
DeltaFailure.refute(exp, act, delta, opts)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
module Matchers
|
63
|
+
#
|
64
|
+
#
|
65
|
+
# value1.should be_within(delta, value2)
|
66
|
+
#
|
67
|
+
def is_within(delta, act)
|
68
|
+
DeltaFailure.to_matcher(act, delta)
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
#
|
73
|
+
# value1.assert is_within(delta, value2)
|
74
|
+
#
|
75
|
+
def be_within(delta, act)
|
76
|
+
DeltaFailure.to_matcher(act, delta)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'assay/assertion'
|
2
|
+
|
3
|
+
module Assay
|
4
|
+
|
5
|
+
class EmptyFailure < Assertion
|
6
|
+
|
7
|
+
def self.assertion_name
|
8
|
+
:empty
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.assertion_operator
|
12
|
+
:empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
# Check assertion.
|
16
|
+
def self.pass?(exp)
|
17
|
+
exp.empty?
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
def to_s
|
22
|
+
return super unless @arguments.size == 1
|
23
|
+
|
24
|
+
exp = @arguments.first.inspect
|
25
|
+
|
26
|
+
if @_negated
|
27
|
+
"Expected #{exp} to NOT be empty"
|
28
|
+
else
|
29
|
+
"Expected #{exp} to be empty"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
module Assertives
|
37
|
+
# Passed if object is +true+.
|
38
|
+
#
|
39
|
+
def assert_empty(exp, opts={})
|
40
|
+
opts[:backtrace] ||= caller
|
41
|
+
EmptyFailure.assert(exp, opts)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Passed if object is not +true+.
|
45
|
+
#
|
46
|
+
# assert_not_true(false)
|
47
|
+
#
|
48
|
+
def refute_empty(exp, opts={})
|
49
|
+
opts[:backtrace] ||= caller
|
50
|
+
EmptyFailure.refute(exp, opts)
|
51
|
+
end
|
52
|
+
|
53
|
+
alias_method :assert_not_empty, :refute_empty
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
module Matchers
|
58
|
+
# Empty?
|
59
|
+
#
|
60
|
+
# object.assert is_true
|
61
|
+
#
|
62
|
+
def is_empty
|
63
|
+
EmptyFailure.to_matcher
|
64
|
+
end
|
65
|
+
|
66
|
+
# Empty?
|
67
|
+
#
|
68
|
+
# object.should be_empty
|
69
|
+
#
|
70
|
+
def be_empty
|
71
|
+
EmptyFailure.to_matcher
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'assay/assertions/compare_failure'
|
2
|
+
|
3
|
+
module Assay
|
4
|
+
|
5
|
+
#
|
6
|
+
class EqualityFailure < CompareFailure
|
7
|
+
|
8
|
+
#
|
9
|
+
def self.assertion_name
|
10
|
+
:equal
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
def self.assertion_operator
|
15
|
+
:==
|
16
|
+
end
|
17
|
+
|
18
|
+
# Check assertion.
|
19
|
+
def self.pass?(exp, act)
|
20
|
+
exp == act
|
21
|
+
end
|
22
|
+
|
23
|
+
# Check negated assertion.
|
24
|
+
def self.fail?(exp, act)
|
25
|
+
exp != act
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
def to_s
|
30
|
+
return super unless @arguments.size == 2
|
31
|
+
|
32
|
+
oper = @_negated ? "!=" : "=="
|
33
|
+
iexp = @arguments[0].inspect
|
34
|
+
iact = @arguments[1].inspect
|
35
|
+
|
36
|
+
if iexp.size > SIZE_LIMIT or iact.size > SIZE_LIMIT
|
37
|
+
diff = ANSI::Diff.new(iact, iexp)
|
38
|
+
"a #{oper} b\na) #{diff.diff1}\nb) #{diff.diff2}"
|
39
|
+
else
|
40
|
+
"#{iact} #{oper} #{iexp}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
module Assertives
|
48
|
+
# Passes if expected == +actual.
|
49
|
+
#
|
50
|
+
# Note that the ordering of arguments is important,
|
51
|
+
# since a helpful error message is generated when this
|
52
|
+
# one fails that tells you the values of expected and actual.
|
53
|
+
#
|
54
|
+
# assert_equal 'MY STRING', 'my string'.upcase
|
55
|
+
#
|
56
|
+
def assert_equal(exp, act, opts={})
|
57
|
+
opts[:backtrace] ||= caller
|
58
|
+
#message = opts[:message]
|
59
|
+
EqualityFailure.assert(exp, act, opts)
|
60
|
+
#err = EqualityFailure.new(message, exp, act)
|
61
|
+
#err.set_backtrace(backtrace)
|
62
|
+
#err.assert(opts)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Passes if expected != actual
|
66
|
+
#
|
67
|
+
# assert_not_equal 'some string', 5
|
68
|
+
#
|
69
|
+
def assert_not_equal(exp, act, opts)
|
70
|
+
opts[:backtrace] ||= caller
|
71
|
+
EqualityFailure.refute(exp, act, opts)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
module Matchers
|
77
|
+
# Passes if +expected+ == +actual+.
|
78
|
+
#
|
79
|
+
# 'MY STRING'.assert is_equal_to('my string'.upcase)
|
80
|
+
# 'MY STRING'.refute is_equal_to('another string')
|
81
|
+
#
|
82
|
+
def is_equal_to(exp, opts={})
|
83
|
+
EqualityFailure.to_matcher(exp)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Passes if +expected+ == +actual+.
|
87
|
+
#
|
88
|
+
# 'MY STRING'.should be_equal_to('my string'.upcase)
|
89
|
+
# 'MY STRING'.should_not be_equal_to('another string')
|
90
|
+
#
|
91
|
+
def be_equal_to(exp)
|
92
|
+
EqualityFailure.to_matcher(exp)
|
93
|
+
end
|
94
|
+
|
95
|
+
## # Passes if expected != actual
|
96
|
+
## #
|
97
|
+
## # 'some string'.should not_be_equal_to('foo')
|
98
|
+
## #
|
99
|
+
## def not_be_equal_to(exp, act, opts)
|
100
|
+
## opts[:backtrace] ||= caller
|
101
|
+
## EqualityFailure.to_matcher!(exp, opts)
|
102
|
+
## end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|