assay 0.2.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/.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
|