assay 0.3.0 → 0.4.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.
Files changed (97) hide show
  1. data/.ruby +46 -41
  2. data/COPYING.rdoc +38 -0
  3. data/HISTORY.rdoc +18 -1
  4. data/QED.rdoc +1100 -0
  5. data/README.rdoc +139 -16
  6. data/lib/assay.rb +82 -29
  7. data/lib/assay.yml +46 -41
  8. data/lib/assay/{adapters → adapter}/minitest.rb +0 -0
  9. data/lib/assay/{adapters → adapter}/testunit.rb +0 -0
  10. data/lib/assay/assertable.rb +174 -0
  11. data/lib/assay/assertion.rb +98 -124
  12. data/lib/assay/assertor.rb +187 -0
  13. data/lib/assay/boolean_assay.rb +15 -0
  14. data/lib/assay/case_assay.rb +17 -0
  15. data/lib/assay/compare_assay.rb +38 -0
  16. data/lib/assay/core_ext/kernel.rb +52 -0
  17. data/lib/assay/core_ext/na.rb +9 -0
  18. data/lib/assay/directory_assay.rb +20 -0
  19. data/lib/assay/empty_assay.rb +17 -0
  20. data/lib/assay/equal_assay.rb +35 -0
  21. data/lib/assay/equality_assay.rb +18 -0
  22. data/lib/assay/execution_assay.rb +59 -0
  23. data/lib/assay/false_assay.rb +17 -0
  24. data/lib/assay/file_assay.rb +17 -0
  25. data/lib/assay/identity_assay.rb +49 -0
  26. data/lib/assay/include_assay.rb +17 -0
  27. data/lib/assay/instance_assay.rb +17 -0
  28. data/lib/assay/kind_assay.rb +18 -0
  29. data/lib/assay/less_assay.rb +18 -0
  30. data/lib/assay/less_equal_assay.rb +25 -0
  31. data/lib/assay/like_assay.rb +17 -0
  32. data/lib/assay/match_assay.rb +17 -0
  33. data/lib/assay/more_assay.rb +18 -0
  34. data/lib/assay/more_equal_assay.rb +25 -0
  35. data/lib/assay/nil_assay.rb +15 -0
  36. data/lib/assay/nomatch_assay.rb +17 -0
  37. data/lib/assay/output_assay.rb +35 -0
  38. data/lib/assay/path_assay.rb +17 -0
  39. data/lib/assay/raise_assay.rb +109 -0
  40. data/lib/assay/rescue_assay.rb +55 -0
  41. data/lib/assay/respond_assay.rb +17 -0
  42. data/lib/assay/return_assay.rb +46 -0
  43. data/lib/assay/silent_assay.rb +59 -0
  44. data/lib/assay/stderr_assay.rb +30 -0
  45. data/lib/assay/stdout_assay.rb +30 -0
  46. data/lib/assay/throw_assay.rb +89 -0
  47. data/lib/assay/true_assay.rb +20 -0
  48. data/lib/assay/unequal_assay.rb +37 -0
  49. data/lib/assay/within_assay.rb +39 -0
  50. data/test/case_compare_assay.rb +59 -0
  51. data/test/case_empty_assay.rb +51 -0
  52. data/test/case_equal_assay.rb +53 -0
  53. data/test/case_equality_assay.rb +55 -0
  54. data/test/case_false_assay.rb +48 -0
  55. data/test/case_identity_assay.rb +51 -0
  56. data/test/case_include_assay.rb +51 -0
  57. data/test/case_instance_assay.rb +51 -0
  58. data/test/case_kind_assay.rb +51 -0
  59. data/test/case_less_assay.rb +53 -0
  60. data/test/case_less_equal_assay.rb +53 -0
  61. data/test/case_like_assay.rb +57 -0
  62. data/test/case_match_assay.rb +45 -0
  63. data/test/case_more_assay.rb +53 -0
  64. data/test/case_more_equal_assay.rb +53 -0
  65. data/test/case_nil_assay.rb +48 -0
  66. data/test/case_nomatch_assay.rb +47 -0
  67. data/test/case_raise_assay.rb +51 -0
  68. data/test/case_respond_assay.rb +51 -0
  69. data/test/case_throw_assay.rb +51 -0
  70. data/test/case_true_assay.rb +48 -0
  71. data/test/case_unequal_assay.rb +55 -0
  72. data/test/case_within_assay.rb +61 -0
  73. data/test/helper.rb +36 -0
  74. metadata +135 -108
  75. data/APACHE2.txt +0 -205
  76. data/NOTICE.rdoc +0 -18
  77. data/lib/assay/assertions/compare_failure.rb +0 -61
  78. data/lib/assay/assertions/delta_failure.rb +0 -80
  79. data/lib/assay/assertions/empty_failure.rb +0 -76
  80. data/lib/assay/assertions/equality_failure.rb +0 -100
  81. data/lib/assay/assertions/execution_failure.rb +0 -90
  82. data/lib/assay/assertions/false_failure.rb +0 -72
  83. data/lib/assay/assertions/identity_failure.rb +0 -85
  84. data/lib/assay/assertions/instance_failure.rb +0 -76
  85. data/lib/assay/assertions/kind_failure.rb +0 -80
  86. data/lib/assay/assertions/match_failure.rb +0 -85
  87. data/lib/assay/assertions/nil_failure.rb +0 -75
  88. data/lib/assay/assertions/raise_failure.rb +0 -134
  89. data/lib/assay/assertions/response_failure.rb +0 -86
  90. data/lib/assay/assertions/same_failure.rb +0 -82
  91. data/lib/assay/assertions/throw_failure.rb +0 -122
  92. data/lib/assay/assertions/true_failure.rb +0 -79
  93. data/lib/assay/matcher.rb +0 -48
  94. data/qed/01_failure_classes.rdoc +0 -75
  95. data/qed/02_assertives.rdoc +0 -118
  96. data/qed/03_matchers.rdoc +0 -118
  97. data/qed/04_lookup.rdoc +0 -10
@@ -0,0 +1,17 @@
1
+ require_relative 'assertion'
2
+
3
+ # LikeAssay defines an assertion for broad equality.
4
+ #
5
+ class LikeAssay < Assertion
6
+
7
+ register :like
8
+
9
+ #
10
+ # Test assertion for `#like?`.
11
+ #
12
+ def self.pass?(subject, criterion)
13
+ subject.like?(criterion)
14
+ end
15
+
16
+ end
17
+
@@ -0,0 +1,17 @@
1
+ require_relative 'like_assay'
2
+
3
+ #
4
+ #
5
+ #
6
+ class MatchAssay < LikeAssay
7
+
8
+ register :=~, :match
9
+
10
+ #
11
+ # Check assertion for `#=~` method.
12
+ #
13
+ def self.pass?(matcher, matchee)
14
+ matcher =~ matchee
15
+ end
16
+
17
+ end
@@ -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 MoreAssay < CompareAssay
7
+
8
+ register :>, :more_than
9
+
10
+ #
11
+ # Check assertion using `#>` method call.
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 `GreaterThanOrEqualAssay`.
7
+ # However, such a name is a bit winded. The shortest name then,
8
+ # without resorting to abbreviations, is _more-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 MoreEqualAssay < CompareAssay
14
+
15
+ register :>=, :more_equal
16
+
17
+ #
18
+ # Check assertion using `#>=` method.
19
+ #
20
+ def self.pass?(subject, criterion)
21
+ subject >= criterion
22
+ end
23
+
24
+ end
25
+
@@ -0,0 +1,15 @@
1
+ require_relative 'assertion'
2
+
3
+ class NilAssay < Assertion
4
+
5
+ register :nil
6
+
7
+ #
8
+ # Check assertion.
9
+ #
10
+ def self.pass?(subject)
11
+ subject.nil?
12
+ end
13
+
14
+ end
15
+
@@ -0,0 +1,17 @@
1
+ require_relative 'match_assay'
2
+
3
+ # Ruby 1.9+ allows #!~ to redfined as it's own method, so a corresponding
4
+ # assay is required to cover it.
5
+ #
6
+ class NoMatchAssay < MatchAssay
7
+
8
+ register :!~, :nomatch
9
+
10
+ #
11
+ # Check no match assertion with `#!~` method.
12
+ #
13
+ def self.pass?(matcher, matchee)
14
+ matcher !~ matchee
15
+ end
16
+
17
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'assertion'
2
+
3
+ # Assert that there is output, either from stdout or stderr.
4
+ #
5
+ # OutputAssay.pass?(/foo/){ puts 'foo!' } #=> true
6
+ #
7
+ class OutputAssay < Assertion
8
+
9
+ register :output
10
+
11
+ #
12
+ # Compare +match+ against $stdout and $stderr via `#===` method.
13
+ #
14
+ # Note that $stdout and $stderr are temporarily reouted to StringIO
15
+ # objects and the results have any trailing newline chomped off.
16
+ #
17
+ def self.pass?(match, &block)
18
+ require 'stringio'
19
+
20
+ begin
21
+ stdout, stderr = $stdout, $stderr
22
+ newout, newerr = StringIO.new, StringIO.new
23
+ $stdout, $stderr = newout, newerr
24
+ yield
25
+ ensure
26
+ $stdout, $stderr = stdout, stderr
27
+ end
28
+
29
+ newout, newerr = newout.string.chomp("\n"), newerr.string.chomp("\n")
30
+
31
+ match === newout || match === newerr
32
+ end
33
+
34
+ end
35
+
@@ -0,0 +1,17 @@
1
+ require_relative 'assertion'
2
+
3
+ # Assert the existance of a file with `File.file?` call.
4
+ #
5
+ class PathAssay < Assertion
6
+
7
+ register :path
8
+
9
+ #
10
+ # Check assertion using `File.exist?` method.
11
+ #
12
+ def self.pass?(path)
13
+ File.exist?(path)
14
+ end
15
+
16
+ end
17
+
@@ -0,0 +1,109 @@
1
+ require_relative 'rescue_assay'
2
+
3
+ #
4
+ class RaiseAssay < RescueAssay
5
+
6
+ register :raised
7
+
8
+ #
9
+ # Check assertion.
10
+ #
11
+ def self.pass?(*exceptions)
12
+ exceptions = [RuntimeError] if exceptions.empty?
13
+ begin
14
+ yield
15
+ false
16
+ rescue Exception => e
17
+ exceptions.any? do |x|
18
+ x.instance_of?(Module) ? x === e : e.class == x
19
+ end
20
+ end
21
+ end
22
+
23
+ #
24
+ # Check negated assertion.
25
+ #
26
+ def self.fail?(*exceptions)
27
+ exceptions = [RuntimeError] if exceptions.empty?
28
+ begin
29
+ yield
30
+ true
31
+ rescue Exception => e
32
+ !exceptions.any? do |x|
33
+ x.instance_of?(Module) ? x === e : e.class == x
34
+ end
35
+ end
36
+ end
37
+
38
+ # TODO: How to add `but got class` to message?
39
+ # May have to override `#assert!` and `#refute!`.
40
+
41
+ #
42
+ #
43
+ #
44
+ def self.assert_message(*exceptions)
45
+ exp = exceptions.map{ |e| e.inspect }.join(' or ')
46
+ "raise #{exp}" #, but was #{err} instead."
47
+ end
48
+
49
+ #
50
+ #
51
+ #
52
+ def self.refute_message(*exceptions)
53
+ exp = exceptions.map{ |e| e.inspect }.join(' or ')
54
+ "! raise #{exp}" #, but was #{err} instead."
55
+ end
56
+
57
+ =begin
58
+ #
59
+ #
60
+ #
61
+ def self.assert!(*exp) #:yeild:
62
+ options = (Hash === exp.last ? exp.pop : {})
63
+
64
+ exp = exp.first
65
+
66
+ begin
67
+ yield
68
+ test = false
69
+ arguments = [exp]
70
+ rescue Exception => err
71
+ test = (exp === err)
72
+ arguments = [exp, err]
73
+ end
74
+
75
+ message = options[:message] || pass_message(*arguments)
76
+ backtrace = options[:backtrace] || caller
77
+
78
+ if !test
79
+ fail self, message, backtrace
80
+ end
81
+ end
82
+
83
+ #
84
+ #
85
+ #
86
+ def self.refute!(*exp) #:yield:
87
+ options = (Hash === exp.last ? exp.pop : {})
88
+
89
+ #exp = exp.first
90
+
91
+ begin
92
+ yield
93
+ test = true
94
+ arguments = exp
95
+ rescue Exception => err
96
+ test = !exp.any?{ |e| e === err }
97
+ arguments = exp #+ [err]
98
+ end
99
+
100
+ message = options[:message] || fail_message(*arguments)
101
+ backtrace = options[:backtrace] || caller
102
+
103
+ if !test
104
+ fail self, message, backtrace
105
+ end
106
+ end
107
+ =end
108
+
109
+ end
@@ -0,0 +1,55 @@
1
+ require_relative 'assertion'
2
+
3
+ # Assert that a kind of exception class is rescued
4
+ # from the execution of a block.
5
+ #
6
+ class RescueAssay < Assertion
7
+
8
+ register :rescue
9
+
10
+ #
11
+ # Check assertion.
12
+ #
13
+ def self.pass?(*exceptions)
14
+ exceptions = [RuntimeError] if exceptions.empty?
15
+ begin
16
+ yield
17
+ false
18
+ rescue Exception => e
19
+ exceptions.any? do |x|
20
+ x === e
21
+ end
22
+ end
23
+ end
24
+
25
+ #
26
+ # Check negated assertion.
27
+ #
28
+ def self.fail?(*exceptions)
29
+ exceptions = [RuntimeError] if exceptions.empty?
30
+ begin
31
+ yield
32
+ true
33
+ rescue Exception => e
34
+ !exceptions.any? do |x|
35
+ x === e
36
+ end
37
+ end
38
+ end
39
+
40
+ # TODO: How to add `but got class` message to error?
41
+ # May have to override #assert! and #refute! method.
42
+
43
+ #
44
+ def self.assert_message(*exceptions)
45
+ exp = exceptions.map{ |e| e.inspect }.join(' or ')
46
+ "raise #{exp}" #, but was #{err} instead."
47
+ end
48
+
49
+ #
50
+ def self.refute_message(*exceptions)
51
+ exp = exceptions.map{ |e| e.inspect }.join(' or ')
52
+ "! raise #{exp}" #, but was #{err} instead."
53
+ end
54
+
55
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'assertion'
2
+
3
+ # Does an object #respond_to? a method call.
4
+ #
5
+ class RespondAssay < Assertion
6
+
7
+ register :respond_to
8
+
9
+ # Check assertion.
10
+ def self.pass?(reciever, method_name)
11
+ #flip = (Symbol === obj) && ! (Symbol === meth) # HACK for specs
12
+ #obj, meth = meth, obj if flip
13
+ reciever.respond_to?(method_name)
14
+ end
15
+
16
+ end
17
+
@@ -0,0 +1,46 @@
1
+ require_relative 'execution_assay'
2
+
3
+ # Assert that a block of code returns a specific result, also
4
+ # fails if an error is raised in the block.
5
+ #
6
+ class ReturnAssay < ExecutionAssay
7
+
8
+ register :returns
9
+
10
+ #
11
+ # Check that a block returns a specific value comparing
12
+ # the +returns+ argument and actual returned value with
13
+ # the `#==` operator.
14
+ #
15
+ def self.pass?(returns, *arguments) #:yield:
16
+ begin
17
+ result = yield(*arguments)
18
+ returns == result
19
+ rescue Exception
20
+ false
21
+ end
22
+ end
23
+
24
+ #
25
+ # Check that a block does NOT return a specific value comparing
26
+ # the +returns+ argument and actual returned value with
27
+ # the `#==` operator.
28
+ #
29
+ def self.fail?(returns, *arguments) #:yield:
30
+ begin
31
+ result = yield(*arguments)
32
+ returns != result
33
+ rescue Exception
34
+ true
35
+ end
36
+ end
37
+
38
+ ##
39
+ ##
40
+ ##
41
+ #def self.assert_message(*arguments, &block)
42
+ # "#{block}.call(*#{arguments.inspect})"
43
+ #end
44
+
45
+ end
46
+
@@ -0,0 +1,59 @@
1
+ require_relative 'output_assay'
2
+
3
+ # Assert that there is no output, either from stdout or stderr.
4
+ #
5
+ # SilentAssay.pass?{ puts 'foo!' } #=> false
6
+ #
7
+ class SilentAssay < OutputAssay
8
+
9
+ register :silent
10
+
11
+ #
12
+ # Compare +match+ against $stdout and $stderr via `#===` method.
13
+ #
14
+ # Note that $stdout and $stderr are temporarily reouted to StringIO
15
+ # objects and the results have any trailing newline chomped off.
16
+ #
17
+ def self.pass?(&block)
18
+ require 'stringio'
19
+
20
+ begin
21
+ stdout, stderr = $stdout, $stderr
22
+ newout, newerr = StringIO.new, StringIO.new
23
+ $stdout, $stderr = newout, newerr
24
+ yield
25
+ ensure
26
+ $stdout, $stderr = stdout, stderr
27
+ end
28
+
29
+ newout, newerr = newout.string.chomp("\n"), newerr.string.chomp("\n")
30
+
31
+ newout.empty? && newerr.empty?
32
+ end
33
+
34
+ # TODO: Assertable isn't dealing with no-argument assertions well,
35
+ # see if this can be improved.
36
+
37
+ #
38
+ # Opposite of `SilentAssay.pass?`.
39
+ #
40
+ def self.fail?(&block)
41
+ ! pass?(&block)
42
+ end
43
+
44
+ #
45
+ #
46
+ #
47
+ def self.assert_message(*)
48
+ "unexpected output"
49
+ end
50
+
51
+ #
52
+ #
53
+ #
54
+ def self.refute_message(*)
55
+ "expected output"
56
+ end
57
+
58
+ end
59
+