assay 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby +46 -41
- data/COPYING.rdoc +38 -0
- data/HISTORY.rdoc +18 -1
- data/QED.rdoc +1100 -0
- data/README.rdoc +139 -16
- data/lib/assay.rb +82 -29
- data/lib/assay.yml +46 -41
- data/lib/assay/{adapters → adapter}/minitest.rb +0 -0
- data/lib/assay/{adapters → adapter}/testunit.rb +0 -0
- data/lib/assay/assertable.rb +174 -0
- data/lib/assay/assertion.rb +98 -124
- data/lib/assay/assertor.rb +187 -0
- data/lib/assay/boolean_assay.rb +15 -0
- data/lib/assay/case_assay.rb +17 -0
- data/lib/assay/compare_assay.rb +38 -0
- data/lib/assay/core_ext/kernel.rb +52 -0
- data/lib/assay/core_ext/na.rb +9 -0
- data/lib/assay/directory_assay.rb +20 -0
- data/lib/assay/empty_assay.rb +17 -0
- data/lib/assay/equal_assay.rb +35 -0
- data/lib/assay/equality_assay.rb +18 -0
- data/lib/assay/execution_assay.rb +59 -0
- data/lib/assay/false_assay.rb +17 -0
- data/lib/assay/file_assay.rb +17 -0
- data/lib/assay/identity_assay.rb +49 -0
- data/lib/assay/include_assay.rb +17 -0
- data/lib/assay/instance_assay.rb +17 -0
- data/lib/assay/kind_assay.rb +18 -0
- data/lib/assay/less_assay.rb +18 -0
- data/lib/assay/less_equal_assay.rb +25 -0
- data/lib/assay/like_assay.rb +17 -0
- data/lib/assay/match_assay.rb +17 -0
- data/lib/assay/more_assay.rb +18 -0
- data/lib/assay/more_equal_assay.rb +25 -0
- data/lib/assay/nil_assay.rb +15 -0
- data/lib/assay/nomatch_assay.rb +17 -0
- data/lib/assay/output_assay.rb +35 -0
- data/lib/assay/path_assay.rb +17 -0
- data/lib/assay/raise_assay.rb +109 -0
- data/lib/assay/rescue_assay.rb +55 -0
- data/lib/assay/respond_assay.rb +17 -0
- data/lib/assay/return_assay.rb +46 -0
- data/lib/assay/silent_assay.rb +59 -0
- data/lib/assay/stderr_assay.rb +30 -0
- data/lib/assay/stdout_assay.rb +30 -0
- data/lib/assay/throw_assay.rb +89 -0
- data/lib/assay/true_assay.rb +20 -0
- data/lib/assay/unequal_assay.rb +37 -0
- data/lib/assay/within_assay.rb +39 -0
- data/test/case_compare_assay.rb +59 -0
- data/test/case_empty_assay.rb +51 -0
- data/test/case_equal_assay.rb +53 -0
- data/test/case_equality_assay.rb +55 -0
- data/test/case_false_assay.rb +48 -0
- data/test/case_identity_assay.rb +51 -0
- data/test/case_include_assay.rb +51 -0
- data/test/case_instance_assay.rb +51 -0
- data/test/case_kind_assay.rb +51 -0
- data/test/case_less_assay.rb +53 -0
- data/test/case_less_equal_assay.rb +53 -0
- data/test/case_like_assay.rb +57 -0
- data/test/case_match_assay.rb +45 -0
- data/test/case_more_assay.rb +53 -0
- data/test/case_more_equal_assay.rb +53 -0
- data/test/case_nil_assay.rb +48 -0
- data/test/case_nomatch_assay.rb +47 -0
- data/test/case_raise_assay.rb +51 -0
- data/test/case_respond_assay.rb +51 -0
- data/test/case_throw_assay.rb +51 -0
- data/test/case_true_assay.rb +48 -0
- data/test/case_unequal_assay.rb +55 -0
- data/test/case_within_assay.rb +61 -0
- data/test/helper.rb +36 -0
- metadata +135 -108
- data/APACHE2.txt +0 -205
- data/NOTICE.rdoc +0 -18
- data/lib/assay/assertions/compare_failure.rb +0 -61
- data/lib/assay/assertions/delta_failure.rb +0 -80
- data/lib/assay/assertions/empty_failure.rb +0 -76
- data/lib/assay/assertions/equality_failure.rb +0 -100
- data/lib/assay/assertions/execution_failure.rb +0 -90
- data/lib/assay/assertions/false_failure.rb +0 -72
- data/lib/assay/assertions/identity_failure.rb +0 -85
- data/lib/assay/assertions/instance_failure.rb +0 -76
- data/lib/assay/assertions/kind_failure.rb +0 -80
- data/lib/assay/assertions/match_failure.rb +0 -85
- data/lib/assay/assertions/nil_failure.rb +0 -75
- data/lib/assay/assertions/raise_failure.rb +0 -134
- data/lib/assay/assertions/response_failure.rb +0 -86
- data/lib/assay/assertions/same_failure.rb +0 -82
- data/lib/assay/assertions/throw_failure.rb +0 -122
- data/lib/assay/assertions/true_failure.rb +0 -79
- data/lib/assay/matcher.rb +0 -48
- data/qed/01_failure_classes.rdoc +0 -75
- data/qed/02_assertives.rdoc +0 -118
- data/qed/03_matchers.rdoc +0 -118
- data/qed/04_lookup.rdoc +0 -10
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'equality_assay'
|
2
|
+
|
3
|
+
# Equality assertion using `#===`, the case equality method.
|
4
|
+
#
|
5
|
+
class CaseAssay < EqualityAssay
|
6
|
+
|
7
|
+
register :===, :case
|
8
|
+
|
9
|
+
#
|
10
|
+
# Check assertion via `#===` method.
|
11
|
+
#
|
12
|
+
def self.pass?(subject, criterion)
|
13
|
+
subject === criterion
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative 'assertion'
|
2
|
+
|
3
|
+
# Compare assertion serves primarily as a base class
|
4
|
+
# for other more specific comparison assertions.
|
5
|
+
#
|
6
|
+
# In itself it can be used to test a comparision
|
7
|
+
# made by #<=>.
|
8
|
+
#
|
9
|
+
class CompareAssay < Assertion
|
10
|
+
|
11
|
+
# TODO: What about #cmp alias?
|
12
|
+
|
13
|
+
register :<=>, :compare
|
14
|
+
|
15
|
+
#
|
16
|
+
# Check assertion using `<=>`.
|
17
|
+
#
|
18
|
+
def self.pass?(subject, criterion, result=0)
|
19
|
+
(subject <=> criterion) == result
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Error message for campare assertion.
|
24
|
+
#
|
25
|
+
def self.assert_message(subject, criterion, result=0)
|
26
|
+
a = subject.inspect
|
27
|
+
b = criterion.inspect
|
28
|
+
r = result.inspect
|
29
|
+
|
30
|
+
if a.size > SIZE_LIMIT or b.size > SIZE_LIMIT
|
31
|
+
"a <=> b == #{r}\na) #{a}\nb) #{b}"
|
32
|
+
else
|
33
|
+
"#{a} <=> #{b} == #{r}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Kernel
|
2
|
+
|
3
|
+
# Do two references have the same `#object_id`, and hence are the
|
4
|
+
# same object.
|
5
|
+
#
|
6
|
+
# @param [Object] other
|
7
|
+
# Any object reference.
|
8
|
+
#
|
9
|
+
def identical?(other)
|
10
|
+
object_id == other.object_id
|
11
|
+
end
|
12
|
+
|
13
|
+
# Ascertain likeness, returns true if any of `equal?`, `eql?`, `==`,
|
14
|
+
# `===` or `=~` evaluate truthfully, either with `self` as the receiver
|
15
|
+
# or `other` as the receiver.
|
16
|
+
#
|
17
|
+
# @todo Should `#=~` be apart of this comparison?
|
18
|
+
#
|
19
|
+
# @param [Object] other
|
20
|
+
# Any object reference.
|
21
|
+
#
|
22
|
+
# @return [Boolean] +true+ if alike.
|
23
|
+
#
|
24
|
+
def like?(other)
|
25
|
+
self.equal?(other) ||
|
26
|
+
self.eql?(other) ||
|
27
|
+
self.==(other) ||
|
28
|
+
self.===(other) ||
|
29
|
+
self.=~(other) ||
|
30
|
+
other.equal?(self) ||
|
31
|
+
other.eql?(self) ||
|
32
|
+
other.==(self) ||
|
33
|
+
other.===(self) ||
|
34
|
+
other.=~(self)
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
def true?
|
39
|
+
TrueClass === self
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
def false?
|
44
|
+
FalseClass === self
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
def boolean?
|
49
|
+
true? || false?
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'path_assay'
|
2
|
+
|
3
|
+
# Assert the existance of a directory with `File.directory?` call.
|
4
|
+
#
|
5
|
+
class DirectoryAssay < PathAssay
|
6
|
+
|
7
|
+
register :directory
|
8
|
+
|
9
|
+
#
|
10
|
+
# Check assertion using `File.file?` method.
|
11
|
+
#
|
12
|
+
def self.pass?(path)
|
13
|
+
File.directory?(path)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
# I would prefer this name.
|
19
|
+
#FolderAssay = DirectoryAssay
|
20
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'include_assay'
|
2
|
+
|
3
|
+
# Empty assertion tests an object with `#empty?` method.
|
4
|
+
#
|
5
|
+
class EmptyAssay < IncludeAssay
|
6
|
+
|
7
|
+
register :empty
|
8
|
+
|
9
|
+
#
|
10
|
+
# Check assertion with `#empty?`.
|
11
|
+
#
|
12
|
+
def self.pass?(subject)
|
13
|
+
subject.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative 'like_assay'
|
2
|
+
|
3
|
+
# EqualAssay coers the assertion comparing two objects with `#==` operator.
|
4
|
+
#
|
5
|
+
class EqualAssay < LikeAssay
|
6
|
+
|
7
|
+
register :==, :equal
|
8
|
+
|
9
|
+
#
|
10
|
+
# Test assertion of `#==` method.
|
11
|
+
#
|
12
|
+
def self.pass?(subject, criterion)
|
13
|
+
subject == criterion
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Error message for equal assertion.
|
18
|
+
#
|
19
|
+
def self.assert_message(subject, criterion)
|
20
|
+
a = subject.inspect
|
21
|
+
b = criterion.inspect
|
22
|
+
|
23
|
+
if a.size > SIZE_LIMIT or b.size > SIZE_LIMIT
|
24
|
+
if $ansi
|
25
|
+
d = ANSI::Diff.new(a, b)
|
26
|
+
a, b = d.diff1, d.diff2 # *d.to_a
|
27
|
+
end
|
28
|
+
"a == b\na) #{a}\nb) #{b}"
|
29
|
+
else
|
30
|
+
"#{a} == #{b}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'equal_assay'
|
2
|
+
|
3
|
+
# EqualityAssay defines the assertion for the `#eql?`, the strict
|
4
|
+
# equality method.
|
5
|
+
#
|
6
|
+
class EqualityAssay < EqualAssay
|
7
|
+
|
8
|
+
register :eql
|
9
|
+
|
10
|
+
#
|
11
|
+
# Check assertion via `#eql?` method.
|
12
|
+
#
|
13
|
+
def self.pass?(subject, criterion)
|
14
|
+
subject.eql?(criterion)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative 'assertion'
|
2
|
+
|
3
|
+
# Assert that a block of coded executes without error and does
|
4
|
+
# not return +nil+ or +false+.
|
5
|
+
#
|
6
|
+
# NOTE: To test only for successful execution regardless of return value
|
7
|
+
# use a negated {RaiseAssay} on the Exception class. But generally
|
8
|
+
# this would be pretty silly, if you think about it, this is exactly
|
9
|
+
# what testing is for!
|
10
|
+
#
|
11
|
+
class ExecutionAssay < Assertion
|
12
|
+
|
13
|
+
register :executes
|
14
|
+
|
15
|
+
#
|
16
|
+
# Check assertion.
|
17
|
+
#
|
18
|
+
def self.pass?(*arguments, &block)
|
19
|
+
begin
|
20
|
+
block.call(*arguments)
|
21
|
+
rescue Exception
|
22
|
+
false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Check negated assertion.
|
28
|
+
#
|
29
|
+
def self.fail?(*arguments, &block)
|
30
|
+
begin
|
31
|
+
! block.call(*arguments)
|
32
|
+
rescue Exception
|
33
|
+
true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
#def self.assert!(*criteria, &block)
|
39
|
+
# options = (Hash === criteria.last ? criteria.pop : {})
|
40
|
+
# assay = new(nil, *criteria) #, &block)
|
41
|
+
# assay.assert!(options, &block)
|
42
|
+
#end
|
43
|
+
|
44
|
+
#
|
45
|
+
#def self.refute!(*criteria, &block)
|
46
|
+
# options = (Hash === criteria.last ? criteria.pop : {})
|
47
|
+
# assay = new(nil, *criteria) #, &block)
|
48
|
+
# assay.refute!(options, &block)
|
49
|
+
#end
|
50
|
+
|
51
|
+
#
|
52
|
+
#
|
53
|
+
#
|
54
|
+
def self.assert_message(*arguments, &block)
|
55
|
+
"#{block}.call(*#{arguments.inspect})"
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'boolean_assay'
|
2
|
+
|
3
|
+
# Assert and object if strictly `false`.
|
4
|
+
#
|
5
|
+
class FalseAssay < BooleanAssay
|
6
|
+
|
7
|
+
register :false
|
8
|
+
|
9
|
+
#
|
10
|
+
# Check assertion.
|
11
|
+
#
|
12
|
+
def self.pass?(subject)
|
13
|
+
subject.false? #FalseClass === subject
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'path_assay'
|
2
|
+
|
3
|
+
# Assert the existance of a file with `File.file?` call.
|
4
|
+
#
|
5
|
+
class FileAssay < PathAssay
|
6
|
+
|
7
|
+
register :file
|
8
|
+
|
9
|
+
#
|
10
|
+
# Check assertion using `File.file?` method.
|
11
|
+
#
|
12
|
+
def self.pass?(path)
|
13
|
+
File.file?(path)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative 'equality_assay'
|
2
|
+
|
3
|
+
# Check that two objects are one and the same object.
|
4
|
+
#
|
5
|
+
# NOTE: Ruby defines #equal? to mean #identical? but I believe
|
6
|
+
# this to be a misnomer, at the very least. So we use the term
|
7
|
+
# `identical` instead.
|
8
|
+
#
|
9
|
+
class IdentityAssay < EqualityAssay
|
10
|
+
|
11
|
+
register :identical
|
12
|
+
|
13
|
+
#
|
14
|
+
# Check assertion using `object_id == object_id`.
|
15
|
+
#
|
16
|
+
def self.pass?(subject, criterion)
|
17
|
+
subject.identical?(criterion) #subject.object_id == criterion.object_id
|
18
|
+
end
|
19
|
+
|
20
|
+
# #
|
21
|
+
# #
|
22
|
+
# #
|
23
|
+
# def assert_message(subject)
|
24
|
+
# a = subject.inspect
|
25
|
+
# b = criteria.first.inspect
|
26
|
+
#
|
27
|
+
# if a.size > SIZE_LIMIT or b.size > SIZE_LIMIT
|
28
|
+
# "a.identical?object_id == b.object.id\na) #{criterion}\nb) #{actual}"
|
29
|
+
# else
|
30
|
+
# "#{criterion}.object_id == #{actual}.object.id"
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# #
|
35
|
+
# #
|
36
|
+
# #
|
37
|
+
# def refute_message(subject)
|
38
|
+
# actual = subject.inspect
|
39
|
+
# criterion = criteria.first.inspect
|
40
|
+
#
|
41
|
+
# if actual.size > SIZE_LIMIT or criterion.size > SIZE_LIMIT
|
42
|
+
# "a.object_id != b.object.id\na) #{criterion}\nb) #{actual}"
|
43
|
+
# else
|
44
|
+
# "#{criterion}.object_id != #{actual}.object.id"
|
45
|
+
# end
|
46
|
+
# end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'assertion'
|
2
|
+
|
3
|
+
# Assert that a container includes some object.
|
4
|
+
#
|
5
|
+
class IncludeAssay < Assertion
|
6
|
+
|
7
|
+
register :include
|
8
|
+
|
9
|
+
#
|
10
|
+
# Check assertion using `#include?` method.
|
11
|
+
#
|
12
|
+
def self.pass?(container, member)
|
13
|
+
container.include?(member)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'kind_assay'
|
2
|
+
|
3
|
+
# Assert that an object is an instance of a class.
|
4
|
+
#
|
5
|
+
class InstanceAssay < KindAssay
|
6
|
+
|
7
|
+
register :instance_of
|
8
|
+
|
9
|
+
#
|
10
|
+
# Check assertion.
|
11
|
+
#
|
12
|
+
def self.pass?(object, class_type)
|
13
|
+
object.instance_of?(class_type)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'assertion'
|
2
|
+
|
3
|
+
# Comparison assertion for #kind_of?
|
4
|
+
#
|
5
|
+
# KindAssay.pass?(1, Integer) #=> true
|
6
|
+
# KindAssay.fail?(1, String) #=> true
|
7
|
+
#
|
8
|
+
class KindAssay < Assertion
|
9
|
+
|
10
|
+
register :kind_of
|
11
|
+
|
12
|
+
# Check assertion.
|
13
|
+
def self.pass?(object, class_type)
|
14
|
+
object.kind_of?(class_type)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'compare_assay'
|
2
|
+
|
3
|
+
# Compare assertion is used to test a comparision
|
4
|
+
# made by `#<`.
|
5
|
+
#
|
6
|
+
class LessAssay < CompareAssay
|
7
|
+
|
8
|
+
register :<, :less_than
|
9
|
+
|
10
|
+
#
|
11
|
+
# Check assertion.
|
12
|
+
#
|
13
|
+
def self.pass?(subject, criterion)
|
14
|
+
subject < criterion
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'compare_assay'
|
2
|
+
|
3
|
+
# Compare assertion is used to test a comparision made by `#<=`.
|
4
|
+
#
|
5
|
+
# NOTE: We are taking some leeway here with the name of this class,
|
6
|
+
# which ordinarily would be called `LesserThanOrEqualAssay`.
|
7
|
+
# However, such a name is a bit winded. The shortest name then,
|
8
|
+
# without resorting to abbreviations, is _less-equal_, a monosyllabic
|
9
|
+
# reading of the operator itself. Since it is ordinarily meaningless
|
10
|
+
# to say something is "more equal" than something else, why not allow
|
11
|
+
# it to be meaningful and save ourselves all that uneccessary verbage?
|
12
|
+
#
|
13
|
+
class LessEqualAssay < CompareAssay
|
14
|
+
|
15
|
+
register :<=, :less_equal
|
16
|
+
|
17
|
+
#
|
18
|
+
# Check assertion.
|
19
|
+
#
|
20
|
+
def self.pass?(subject, criterion)
|
21
|
+
subject <= criterion
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|