detest 3.1.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.
@@ -0,0 +1,17 @@
1
+ # Provides painless, automatic configuration of Detest.
2
+ #
3
+ # Simply require() this file and Detest will be available for use anywhere
4
+ # in your program and will execute all tests before your program exits.
5
+
6
+ require 'detest'
7
+ include Detest
8
+
9
+ at_exit do
10
+ Detest.start
11
+
12
+ # reflect number of failures in exit status
13
+ stats = Detest.stats
14
+ fails = stats[:fail] + stats[:error]
15
+
16
+ exit [fails, 255].min
17
+ end
@@ -0,0 +1,93 @@
1
+ module Detest
2
+
3
+ ##
4
+ # Official name of this project.
5
+ #
6
+ PROJECT = 'Detest'
7
+
8
+ ##
9
+ # Short single-line description of this project.
10
+ #
11
+ TAGLINE = 'Assertion testing library for Ruby'
12
+
13
+ ##
14
+ # Address of this project's official home page.
15
+ #
16
+ WEBSITE = 'http://snk.tuxfamily.org/lib/detest/'
17
+
18
+ ##
19
+ # Number of this release of this project.
20
+ #
21
+ VERSION = '3.1.0'
22
+
23
+ ##
24
+ # Date of this release of this project.
25
+ #
26
+ RELDATE = '2010-07-25'
27
+
28
+ ##
29
+ # Description of this release of this project.
30
+ #
31
+ def self.inspect
32
+ "#{PROJECT} #{VERSION} (#{RELDATE})"
33
+ end
34
+
35
+ ##
36
+ # Location of this release of this project.
37
+ #
38
+ INSTDIR = File.expand_path('../../..', __FILE__)
39
+
40
+ ##
41
+ # RubyGems required by this project during runtime.
42
+ #
43
+ # @example
44
+ #
45
+ # RUNTIME = {
46
+ # # this project needs exactly version 1.2.3 of the "an_example" gem
47
+ # "an_example" => [ "1.2.3" ],
48
+ #
49
+ # # this project needs at least version 1.2 (but not
50
+ # # version 1.2.4 or newer) of the "another_example" gem
51
+ # "another_example" => [ ">= 1.2" , "< 1.2.4" ],
52
+ #
53
+ # # this project needs any version of the "yet_another_example" gem
54
+ # "yet_another_example" => [],
55
+ # }
56
+ #
57
+ RUNTIME = {}
58
+
59
+ ##
60
+ # RubyGems required by this project during development.
61
+ #
62
+ # @example
63
+ #
64
+ # DEVTIME = {
65
+ # # this project needs exactly version 1.2.3 of the "an_example" gem
66
+ # "an_example" => [ "1.2.3" ],
67
+ #
68
+ # # this project needs at least version 1.2 (but not
69
+ # # version 1.2.4 or newer) of the "another_example" gem
70
+ # "another_example" => [ ">= 1.2" , "< 1.2.4" ],
71
+ #
72
+ # # this project needs any version of the "yet_another_example" gem
73
+ # "yet_another_example" => [],
74
+ # }
75
+ #
76
+ DEVTIME = {
77
+ 'inochi' => [ '>= 4.0.0', '< 5' ],
78
+ }
79
+
80
+ # establish gem version dependencies
81
+ if respond_to? :gem
82
+ [RUNTIME, DEVTIME].each do |deps|
83
+ deps.each do |gem_name, gem_version|
84
+ begin
85
+ gem gem_name, *Array(gem_version)
86
+ rescue LoadError => error
87
+ warn "#{self.inspect}: #{error}"
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ end
@@ -0,0 +1,25 @@
1
+ # Provides long name aliases for Detest's default abbreviated vocabulary.
2
+
3
+ require 'detest'
4
+
5
+ module Detest
6
+ short_to_long = {
7
+ 'D' => 'Describe',
8
+ 'T' => 'True',
9
+ 'F' => 'False',
10
+ 'E' => 'Error',
11
+ 'C' => 'Catch',
12
+ 'S' => 'Share',
13
+ 'I' => 'Inform',
14
+ }
15
+
16
+ short_to_long.each do |src, dst|
17
+ instance_methods(false).grep(/^#{src}\b/).each do |short|
18
+ long = short.to_s.sub(src, dst)
19
+ alias_method long, short
20
+ end
21
+ end
22
+
23
+ # for hooks
24
+ Describe = D
25
+ end
@@ -0,0 +1,92 @@
1
+ # MiniTest emulation layer.
2
+
3
+ require 'detest'
4
+ require 'detest/spec'
5
+ require 'detest/unit'
6
+
7
+ module Detest
8
+ instance_methods(false).each do |meth|
9
+ if meth =~ /^assert_not/
10
+ alias_method 'refute' + $', meth
11
+ end
12
+ end
13
+ end
14
+
15
+ {
16
+ :must => '::Detest.assert',
17
+ :wont => '::Detest.refute',
18
+ }.
19
+ each do |outer, inner|
20
+ #
21
+ # XXX: using eval() because Ruby 1.8 does
22
+ # not support default values and
23
+ # block parameters in define_method()
24
+ #
25
+ file, line = __FILE__, __LINE__ ; eval %{
26
+ class Object
27
+ def #{outer}_be_close_to other, message = nil
28
+ #{inner}_in_delta self, other, nil, message
29
+ end
30
+
31
+ def #{outer}_be_empty message = nil
32
+ #{inner}_empty self, message
33
+ end
34
+
35
+ def #{outer}_be_instance_of klass, message = nil
36
+ #{inner}_instance_of klass, self, message
37
+ end
38
+
39
+ def #{outer}_be_kind_of klass, message = nil
40
+ #{inner}_kind_of klass, self, message
41
+ end
42
+
43
+ def #{outer}_be_nil message = nil
44
+ #{inner}_nil self, message
45
+ end
46
+
47
+ def #{outer}_be_same_as other, message = nil
48
+ #{inner}_same self, other, message
49
+ end
50
+
51
+ def #{outer}_be_within_delta other, delta = nil, message = nil
52
+ #{inner}_in_delta self, other, delta, message
53
+ end
54
+
55
+ alias #{outer}_be_within_epsilon #{outer}_be_within_delta
56
+
57
+ def #{outer}_equal expected, message = nil
58
+ #{inner}_equal expected, self, message
59
+ end
60
+
61
+ def #{outer}_include item, message = nil
62
+ #{inner}_include item, self, message
63
+ end
64
+
65
+ def #{outer}_match pattern, message = nil
66
+ #{inner}_match pattern, self, message
67
+ end
68
+
69
+ def #{outer}_raise *args, &block
70
+ #{inner}_raise(*args, &block)
71
+ end
72
+
73
+ def #{outer}_respond_to query, message = nil
74
+ #{inner}_respond_to self, query, message
75
+ end
76
+
77
+ def #{outer}_send query, *args
78
+ #{inner}_send self, query, *args
79
+ end
80
+ end
81
+
82
+ class Proc
83
+ def #{outer}_raise *args
84
+ #{inner}_raise(*args, &self)
85
+ end
86
+
87
+ def #{outer}_throw symbol, message = nil
88
+ #{inner}_throw symbol, message, &self
89
+ end
90
+ end
91
+ }, TOPLEVEL_BINDING, file, line
92
+ end
@@ -0,0 +1,31 @@
1
+ # RSpec emulation layer.
2
+
3
+ require 'detest'
4
+
5
+ module Detest
6
+ alias describe D
7
+ alias context D
8
+ alias it D
9
+
10
+ def before what, &block
11
+ meth =
12
+ case what
13
+ when :each then :<
14
+ when :all then :<<
15
+ else raise ArgumentError, what
16
+ end
17
+
18
+ send meth, &block
19
+ end
20
+
21
+ def after what, &block
22
+ meth =
23
+ case what
24
+ when :each then :>
25
+ when :all then :>>
26
+ else raise ArgumentError, what
27
+ end
28
+
29
+ send meth, &block
30
+ end
31
+ end
@@ -0,0 +1,101 @@
1
+ # Test::Unit emulation layer.
2
+
3
+ require 'detest'
4
+
5
+ module Detest
6
+ alias test D
7
+ alias setup <
8
+ alias setup! <<
9
+ alias teardown >
10
+ alias teardown! >>
11
+
12
+ [
13
+ [:assert, nil, nil ],
14
+ [:assert_not, '!', 'not '],
15
+ ].
16
+ each do |prefix, polarity, action|
17
+ #
18
+ # XXX: using eval() because Ruby 1.8 does
19
+ # not support default values and
20
+ # block parameters in define_method()
21
+ #
22
+ file, line = __FILE__, __LINE__ ; module_eval %{
23
+ alias #{prefix} T#{polarity}
24
+ alias #{prefix} T#{polarity}
25
+
26
+ def #{prefix}_empty collection, message = nil
27
+ message ||= 'collection must #{action}be empty'
28
+ T#{polarity}(message) { collection.empty? }
29
+ end
30
+
31
+ def #{prefix}_equal expected, actual, message = nil
32
+ message ||= 'actual must #{action}equal expected'
33
+ T#{polarity}(message) { actual == expected }
34
+ end
35
+
36
+ def #{prefix}_in_delta expected, actual, delta = nil, message = nil
37
+ message ||= 'actual must #{action}be within delta of expected'
38
+ delta ||= 0.001
39
+
40
+ T#{polarity}(message) do
41
+ Math.abs(expected - actual) <= Math.abs(delta)
42
+ end
43
+ end
44
+
45
+ alias #{prefix}_in_epsilon #{prefix}_in_delta
46
+
47
+ def #{prefix}_include item, collection, message = nil
48
+ message ||= 'collection must #{action}include item'
49
+ T#{polarity}(messsage) { collection.include? item }
50
+ end
51
+
52
+ def #{prefix}_instance_of klass, object, message = nil
53
+ message ||= 'object must #{action}be an instance of class'
54
+ T#{polarity}(message) { object.instance_of? klass }
55
+ end
56
+
57
+ def #{prefix}_kind_of klass, object, message = nil
58
+ message ||= 'object must #{action}be a kind of class'
59
+ T#{polarity}(message) { object.kind_of? klass }
60
+ end
61
+
62
+ def #{prefix}_nil object, message = nil
63
+ message ||= 'object must #{action}be nil'
64
+ T#{polarity}(message) { object == nil }
65
+ end
66
+
67
+ def #{prefix}_match pattern, string, message = nil
68
+ message ||= 'string must #{action}match pattern'
69
+ T#{polarity}(message) { string =~ pattern }
70
+ end
71
+
72
+ def #{prefix}_same expected, actual, message = nil
73
+ message ||= 'actual must #{action}be same as expected'
74
+ T#{polarity}(message) { actual.equal? expected }
75
+ end
76
+
77
+ def #{prefix}_operator object, operator, operand, message = nil
78
+ message ||= 'object must #{action}support operator with operand'
79
+ T#{polarity} { object.__send__ operator, operand }
80
+ end
81
+
82
+ def #{prefix}_raise *args, &block
83
+ E#{polarity}(args.pop, *args, &block)
84
+ end
85
+
86
+ def #{prefix}_respond_to object, query, message = nil
87
+ message ||= 'object must #{action}respond to query'
88
+ T#{polarity}(message) { object.respond_to? query }
89
+ end
90
+
91
+ def #{prefix}_throw symbol, message = nil, &block
92
+ C#{polarity}(message, symbol, &block)
93
+ end
94
+
95
+ def #{prefix}_send object, query, *args
96
+ response = object.__send__(query, *args)
97
+ T#{polarity} { response }
98
+ end
99
+ }, file, line
100
+ end
101
+ end
@@ -0,0 +1,1298 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv='content-type' value='text/html;charset=utf8'>
5
+ <meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
6
+ <title>detest(1) - Assertion testing library for Ruby</title>
7
+ <style type='text/css' media='all'>
8
+ /* style: man */
9
+ body#manpage {margin:0}
10
+ .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
11
+ .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
12
+ .mp h2 {margin:10px 0 0 0}
13
+ .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
14
+ .mp h3 {margin:0 0 0 4ex}
15
+ .mp dt {margin:0;clear:left}
16
+ .mp dt.flush {float:left;width:8ex}
17
+ .mp dd {margin:0 0 0 9ex}
18
+ .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
19
+ .mp pre {margin-bottom:20px}
20
+ .mp pre+h2,.mp pre+h3 {margin-top:22px}
21
+ .mp h2+pre,.mp h3+pre {margin-top:5px}
22
+ .mp img {display:block;margin:auto}
23
+ .mp h1.man-title {display:none}
24
+ .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
25
+ .mp h2 {font-size:16px;line-height:1.25}
26
+ .mp h1 {font-size:20px;line-height:2}
27
+ .mp {text-align:justify;background:#fff}
28
+ .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
29
+ .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
30
+ .mp u {text-decoration:underline}
31
+ .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
32
+ .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
33
+ .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
34
+ .mp b.man-ref {font-weight:normal;color:#434241}
35
+ .mp pre {padding:5px 1ex;background:#edeceb;border-left:1ex solid #ddd}
36
+ .mp pre code {font-weight:normal;color:#434241}
37
+ .mp h2+pre,h3+pre {padding-left:0}
38
+ ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
39
+ ol.man-decor {width:100%}
40
+ ol.man-decor li.tl {text-align:left}
41
+ ol.man-decor li.tc {text-align:center;letter-spacing:4px}
42
+ ol.man-decor li.tr {text-align:right;float:right}
43
+ </style>
44
+ <style type='text/css' media='all'>
45
+ /* style: toc */
46
+ .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:36px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
47
+ .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 20px;color:#999;text-decoration:none}
48
+ .man-navigation a:hover {color:#111;text-decoration:underline}
49
+ </style>
50
+ <style type='text/css' media='all'>
51
+ /* style: 80c */
52
+ .mp {max-width:78ex}
53
+
54
+ .man-navigation {left:91ex}
55
+ </style>
56
+ </head>
57
+ <!--
58
+ The following styles are deprecated and will be removed at some point:
59
+ div#man, div#man ol.man, div#man ol.head, div#man ol.man.
60
+
61
+ The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
62
+ .man-navigation should be used instead.
63
+ -->
64
+ <body id='manpage'>
65
+ <div class='mp' id='man'>
66
+
67
+ <div class='man-navigation' style='display:none'>
68
+ <a href="#NAME">NAME</a>
69
+ <a href="#SYNOPSIS">SYNOPSIS</a>
70
+ <a href="#DESCRIPTION">DESCRIPTION</a>
71
+ <a href="#OPTIONS">OPTIONS</a>
72
+ <a href="#TESTS">TESTS</a>
73
+ <a href="#ASSERTIONS">ASSERTIONS</a>
74
+ <a href="#EMULATION">EMULATION</a>
75
+ <a href="#EXAMPLES">EXAMPLES</a>
76
+ <a href="#HACKING">HACKING</a>
77
+ <a href="#HISTORY">HISTORY</a>
78
+ <a href="#AUTHORS">AUTHORS</a>
79
+ <a href="#CREDITS">CREDITS</a>
80
+ <a href="#LICENSE">LICENSE</a>
81
+ <a href="#SEE-ALSO">SEE ALSO</a>
82
+ </div>
83
+
84
+ <ol class='man-decor man-head man head'>
85
+ <li class='tl'>detest(1)</li>
86
+ <li class='tc'>Version 3.1.0</li>
87
+ <li class='tr'>detest(1)</li>
88
+ </ol>
89
+
90
+ <h2 id="NAME">NAME</h2>
91
+ <p class="man-name">
92
+ <code>detest</code> - <span class="man-whatis">Assertion testing library for Ruby</span>
93
+ </p>
94
+
95
+ <p>Detest is an assertion testing library for <a href="http://ruby-lang.org">Ruby</a> that emphasizes a simple
96
+ assertion vocabulary, instant debuggability of failures, and flexibility in
97
+ composing tests.</p>
98
+
99
+ <h3 id="Features">Features</h3>
100
+
101
+ <ul>
102
+ <li><p>Adds only 8 mnemonic method names to your memory:</p>
103
+
104
+ <p><code>T</code>rue, <code>F</code>alse, <code>N</code>il, <code>E</code>rror, <code>C</code>atch, <code>I</code>nform, <code>S</code>hare, <code>D</code>escribe</p></li>
105
+ <li><p>Lets you debug assertion failures interactively.</p></li>
106
+ <li><p>Lets you nest tests, assertions, and execution hooks.</p></li>
107
+ <li><p>Maintains a detailed report of assertion failures.</p></li>
108
+ <li><p>Implemented in 436 lines of pure Ruby.</p></li>
109
+ </ul>
110
+
111
+
112
+ <h3 id="Resources">Resources</h3>
113
+
114
+ <dl>
115
+ <dt>Issue tracker (report bugs, request features, get help)</dt><dd><p><a href="http://github.com/sunaku/detest/issues" data-bare-link="true">http://github.com/sunaku/detest/issues</a></p></dd>
116
+ <dt>Source code (browse online or obtain with <a href="http://git-scm.com">Git</a>)</dt><dd><p><a href="http://github.com/sunaku/detest" data-bare-link="true">http://github.com/sunaku/detest</a></p></dd>
117
+ <dt>API documentation</dt><dd><p><a href="http://snk.tuxfamily.org/lib/detest/api/" data-bare-link="true">http://snk.tuxfamily.org/lib/detest/api/</a></p></dd>
118
+ <dt>Announcements feed</dt><dd><p><a href="http://snk.tuxfamily.org/lib/detest/ann.xml" data-bare-link="true">http://snk.tuxfamily.org/lib/detest/ann.xml</a></p></dd>
119
+ <dt>Official website</dt><dd><p><a href="http://snk.tuxfamily.org/lib/detest/" data-bare-link="true">http://snk.tuxfamily.org/lib/detest/</a></p></dd>
120
+ </dl>
121
+
122
+
123
+ <h3 id="Setup">Setup</h3>
124
+
125
+ <p>Prerequisites:</p>
126
+
127
+ <ul>
128
+ <li><p><a href="http://ruby-lang.org">Ruby</a> 1.8.6 or newer.</p></li>
129
+ <li><p><a href="http://rubygems.org">RubyGems</a> 1.3.6 or newer.</p></li>
130
+ </ul>
131
+
132
+
133
+ <p>Installing:</p>
134
+
135
+ <pre><code>gem install detest
136
+ </code></pre>
137
+
138
+ <p>Upgrading:</p>
139
+
140
+ <pre><code>gem update detest
141
+ </code></pre>
142
+
143
+ <p>Removing:</p>
144
+
145
+ <pre><code>gem uninstall detest
146
+ </code></pre>
147
+
148
+ <h2 id="SYNOPSIS">SYNOPSIS</h2>
149
+
150
+ <p><code>detest</code> [<var>OPTIONS</var>] (<var>FILE</var>|<var>GLOB</var>) ...</p>
151
+
152
+ <h2 id="DESCRIPTION">DESCRIPTION</h2>
153
+
154
+ <p>Executes the given test <var>FILE</var>s and <var>GLOB</var> patterns that describe test files.</p>
155
+
156
+ <p>The exit status of this command reflects the number of errors and assertion
157
+ failures (up to a maximum of 255 to avoid 8-bit unsigned integer overflow).</p>
158
+
159
+ <h2 id="OPTIONS">OPTIONS</h2>
160
+
161
+ <dl>
162
+ <dt><code>-d</code>, <code>--debug</code></dt><dd><p>Launch interactive debugger upon assertion failures.</p></dd>
163
+ <dt><code>-h</code>, <code>--help</code></dt><dd><p>Display this manual and exit.</p></dd>
164
+ <dt><code>-v</code>, <code>--version</code></dt><dd><p>Print version number and exit.</p></dd>
165
+ </dl>
166
+
167
+
168
+ <h2 id="TESTS">TESTS</h2>
169
+
170
+ <p>The <code>D()</code> method creates a new <strong>test</strong>, which is analagous to the <code>describe</code>
171
+ keyword in <a href="http://rspec.info">RSpec</a> and the concept of a "test case" in <a href="http://en.wikipedia.org/wiki/XUnit">xUnit</a>. A test may
172
+ contain nested tests (see <strong>Insulation</strong> below).</p>
173
+
174
+ <pre><code>D "outer test" do
175
+ # assertions and logic here
176
+
177
+ D "inner test" do
178
+ # more assertions and logic here
179
+ end
180
+ end
181
+ </code></pre>
182
+
183
+ <h3 id="Hooks">Hooks</h3>
184
+
185
+ <p>A <strong>hook</strong> is a scheduled point of entry into the test execution process. The
186
+ following <strong>hook methods</strong> allow you to register a block of code to execute
187
+ when a hook occurs:</p>
188
+
189
+ <dl>
190
+ <dt class="flush"><code>D.&lt;()</code></dt><dd><p>Calls the given block <em>before each</em> child test.</p></dd>
191
+ <dt class="flush"><code>D.&gt;()</code></dt><dd><p>Calls the given block <em>after each</em> child test.</p></dd>
192
+ <dt class="flush"><code>D.&lt;&lt;()</code></dt><dd><p>Calls the given block <em>before all</em> child tests.</p></dd>
193
+ <dt class="flush"><code>D.&gt;&gt;()</code></dt><dd><p>Calls the given block <em>after all</em> child tests.</p></dd>
194
+ </dl>
195
+
196
+
197
+ <p>A hook method can be called multiple times. Each additional call schedules
198
+ more logic to be executed during the hook:</p>
199
+
200
+ <pre><code>D .&lt; { puts "do something" }
201
+ D .&lt; { puts "do something more!" }
202
+ </code></pre>
203
+
204
+ <h3 id="Insulation">Insulation</h3>
205
+
206
+ <p>The <code>D!()</code> method defines a new test that is explicitly insulated from the
207
+ tests that contain it and also from the top-level Ruby environment.
208
+ Root-level calls to the <code>D()</code> method are insulated by default.</p>
209
+
210
+ <p>Inside an insulated test, you are free to mix-in (using the <code>extend</code> keyword,
211
+ not the <code>include</code> keyword) any modules your test logic needs. You can also
212
+ define your own constants, methods, and classes.</p>
213
+
214
+ <h3 id="Sharing">Sharing</h3>
215
+
216
+ <dl>
217
+ <dt class="flush"><code>S()</code></dt><dd><p>Mechanism for sharing code. When called with a block, it shares the given
218
+ block (under a given identifier) for injection into other tests. When
219
+ called without a block, it injects a previously shared block (under a given
220
+ identifier) into the environment where it is called.</p></dd>
221
+ <dt class="flush"><code>S!()</code></dt><dd><p>Combination of the two uses of the <code>S()</code> method: it lets you simultaneously
222
+ share a block of code while injecting it into the environment where that
223
+ method is called.</p></dd>
224
+ <dt class="flush"><code>S?()</code></dt><dd><p>Checks whether any code has been shared under a given identifier.</p></dd>
225
+ </dl>
226
+
227
+
228
+ <h3 id="Information">Information</h3>
229
+
230
+ <dl>
231
+ <dt class="flush"><code>I()</code></dt><dd><p>Mechanism for inserting arbitrary Ruby objects into the test execution
232
+ report. You can think of this method as being a way to <em>inform</em> someone.</p></dd>
233
+ <dt class="flush"><code>I!()</code></dt><dd><p>Starts the interactive debugger at the location where it is called.</p></dd>
234
+ </dl>
235
+
236
+
237
+ <h3 id="Execution">Execution</h3>
238
+
239
+ <p>Tests are executed in depth-first search (DFS) order.</p>
240
+
241
+ <p>You can configure the test execution process using:</p>
242
+
243
+ <pre><code>Detest.debug = your_choice_here
244
+ </code></pre>
245
+
246
+ <p>You can execute all tests defined thus far using:</p>
247
+
248
+ <pre><code>Detest.start
249
+ </code></pre>
250
+
251
+ <p>You can stop the execution at any time using:</p>
252
+
253
+ <pre><code>Detest.stop
254
+ </code></pre>
255
+
256
+ <p>You can view the results of execution using:</p>
257
+
258
+ <pre><code>puts Detest.trace.to_yaml
259
+ puts Detest.stats.to_yaml
260
+ </code></pre>
261
+
262
+ <p>You can mix-in the <code>Detest</code> module into your program and execute all tests
263
+ defined by your program before it terminates by simply adding the following
264
+ line at the top of your program:</p>
265
+
266
+ <pre><code>require 'detest/auto'
267
+ </code></pre>
268
+
269
+ <p>See the API documentation for more information and examples.</p>
270
+
271
+ <h2 id="ASSERTIONS">ASSERTIONS</h2>
272
+
273
+ <p>The following methods accept a block parameter and assert something about the
274
+ result of executing that block. They also accept an optional message, which
275
+ is shown in failure reports (see <strong>Failures</strong> below) if they fail.</p>
276
+
277
+ <dl>
278
+ <dt class="flush"><code>T()</code></dt><dd><p>assert true (not <code>nil</code> and not <code>false</code>)</p></dd>
279
+ <dt class="flush"><code>F()</code></dt><dd><p>assert not true (<code>nil</code> or <code>false</code>)</p></dd>
280
+ <dt class="flush"><code>N()</code></dt><dd><p>assert that the value is <code>nil</code></p></dd>
281
+ <dt class="flush"><code>E()</code></dt><dd><p>assert that an execption is raised</p></dd>
282
+ <dt class="flush"><code>C()</code></dt><dd><p>assert that a symbol is thrown</p></dd>
283
+ </dl>
284
+
285
+
286
+ <p>For the <code>T()</code> and <code>F()</code> methods, you may alternatively pass the condition to
287
+ be asserted as the first argument (instead of passing it as a block). This
288
+ might result in a more pleasing syntax, depending on your taste:</p>
289
+
290
+ <pre><code>D "Lottery" do
291
+ winning_ticket = rand()
292
+
293
+ D "My chances of winning" do
294
+ my_ticket = rand()
295
+
296
+ # passing the condition as a block:
297
+ F("I won?! Dream on.") { my_ticket == winning_ticket }
298
+
299
+ # passing the condition as an argument:
300
+ F my_ticket == winning_ticket, "I won?! Dream on."
301
+
302
+ end
303
+ end
304
+ </code></pre>
305
+
306
+ <h3 id="Negation">Negation</h3>
307
+
308
+ <p>The following methods are the <em>opposite</em> of normal assertions.</p>
309
+
310
+ <dl>
311
+ <dt class="flush"><code>T!()</code></dt><dd><p>same as <code>F()</code></p></dd>
312
+ <dt class="flush"><code>F!()</code></dt><dd><p>same as <code>T()</code></p></dd>
313
+ <dt class="flush"><code>N!()</code></dt><dd><p>assert that value is not <code>nil</code></p></dd>
314
+ <dt class="flush"><code>E!()</code></dt><dd><p>assert that an exception is <em>not</em> raised</p></dd>
315
+ <dt class="flush"><code>C!()</code></dt><dd><p>assert that a symbol is <em>not</em> thrown</p></dd>
316
+ </dl>
317
+
318
+
319
+ <h3 id="Sampling">Sampling</h3>
320
+
321
+ <p>The following methods let you <em>check the outcome</em> of an assertion without
322
+ recording a success or failure in the test execution report.</p>
323
+
324
+ <dl>
325
+ <dt class="flush"><code>T?()</code></dt><dd><p>returns true if <code>T()</code> passes; false otherwise</p></dd>
326
+ <dt class="flush"><code>F?()</code></dt><dd><p>returns true if <code>F()</code> passes; false otherwise</p></dd>
327
+ <dt class="flush"><code>N?()</code></dt><dd><p>returns true if <code>N()</code> passes; false otherwise</p></dd>
328
+ <dt class="flush"><code>E?()</code></dt><dd><p>returns true if <code>E()</code> passes; false otherwise</p></dd>
329
+ <dt class="flush"><code>C?()</code></dt><dd><p>returns true if <code>C()</code> passes; false otherwise</p></dd>
330
+ </dl>
331
+
332
+
333
+ <h3 id="Failures">Failures</h3>
334
+
335
+ <p>Assertions failures are reported in the following manner:</p>
336
+
337
+ <pre><code>- fail: block must yield true (!nil &amp;&amp; !false)
338
+ call:
339
+ - test/simple.rb:17
340
+ - test/simple.rb:3
341
+ code: |-
342
+ [12..22] in test/simple.rb
343
+ 12
344
+ 13 D "with more nested tests" do
345
+ 14 x = 5
346
+ 15
347
+ 16 T { x &gt; 2 } # passes
348
+ =&gt; 17 F { x &gt; 2 } # fails
349
+ 18 E { x.hello } # passes
350
+ 19 end
351
+ 20 end
352
+ 21
353
+ 22 # equivalent of before(:each) or setup()
354
+ bind: test/simple.rb:17
355
+ vars:
356
+ x: (Fixnum) 5
357
+ y: (Fixnum) 83
358
+ </code></pre>
359
+
360
+ <p>Failure reports are composed of the following sections:</p>
361
+
362
+ <dl>
363
+ <dt class="flush"><code>:fail</code></dt><dd><p>Description of the assertion failure.</p></dd>
364
+ <dt class="flush"><code>:call</code></dt><dd><p>Stack trace leading to the point of failure.</p></dd>
365
+ <dt class="flush"><code>:code</code></dt><dd><p>Source code surrounding the point of failure.</p></dd>
366
+ <dt class="flush"><code>:bind</code></dt><dd><p>Location where local variables (in the "vars" section) were extracted.</p></dd>
367
+ <dt class="flush"><code>:vars</code></dt><dd><p>Local variables visible at the point of failure.</p></dd>
368
+ </dl>
369
+
370
+
371
+ <p>After the failure is reported, you will be placed into a debugger to
372
+ investigate the failure if the <code>Detest.debug</code> option is enabled.</p>
373
+
374
+ <p>Assertion failure reports can be accessed at any time within the test
375
+ execution trace provided by the <code>Detest.trace()</code> method.</p>
376
+
377
+ <h2 id="EMULATION">EMULATION</h2>
378
+
379
+ <p>Detest can emulate several popular testing libraries:</p>
380
+
381
+ <dl>
382
+ <dt>detest/spec</dt><dd><p><a href="http://rspec.info">RSpec</a> emulation layer</p></dd>
383
+ <dt>detest/unit</dt><dd><p><a href="http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html">Test::Unit</a> emulation layer</p></dd>
384
+ <dt>detest/mini</dt><dd><p><a href="http://blog.zenspider.com/minitest/">Minitest</a> emulation layer</p></dd>
385
+ <dt>detest/long</dt><dd><p>Readability emulation layer</p></dd>
386
+ </dl>
387
+
388
+
389
+ <p>Simply require one of these emulation layers into your test suite and you can
390
+ write your tests using the familiar syntax of the testing library it emulates.</p>
391
+
392
+ <h3 id="detest-spec">detest/spec</h3>
393
+
394
+ <p>This library emulates <a href="http://rspec.info">RSpec</a> by adding the following methods to the
395
+ <code>Detest</code> module.</p>
396
+
397
+ <dl>
398
+ <dt><code>after</code>(<em>what</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/spec.rb#L21">lib/detest/spec.rb:21</a>.</p></dd>
399
+ <dt><code>before</code>(<em>what</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/spec.rb#L10">lib/detest/spec.rb:10</a>.</p></dd>
400
+ <dt><code>context</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
401
+ <dt><code>describe</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
402
+ <dt><code>it</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
403
+ </dl>
404
+
405
+
406
+ <h3 id="detest-unit">detest/unit</h3>
407
+
408
+ <p>This library emulates <a href="http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html">Test::Unit</a> by adding the following methods to the
409
+ <code>Detest</code> module.</p>
410
+
411
+ <dl>
412
+ <dt><code>assert</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
413
+ <dt><code>assert_empty</code>(<em>collection</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L26">lib/detest/unit.rb:26</a>.</p></dd>
414
+ <dt><code>assert_equal</code>(<em>expected</em>, <em>actual</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L31">lib/detest/unit.rb:31</a>.</p></dd>
415
+ <dt><code>assert_in_delta</code>(<em>expected</em>, <em>actual</em>, <em>delta</em>=nil, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L36">lib/detest/unit.rb:36</a>.</p></dd>
416
+ <dt><code>assert_in_epsilon</code>(<em>expected</em>, <em>actual</em>, <em>delta</em>=nil, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L36">lib/detest/unit.rb:36</a>.</p></dd>
417
+ <dt><code>assert_include</code>(<em>item</em>, <em>collection</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L47">lib/detest/unit.rb:47</a>.</p></dd>
418
+ <dt><code>assert_instance_of</code>(<em>klass</em>, <em>object</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L52">lib/detest/unit.rb:52</a>.</p></dd>
419
+ <dt><code>assert_kind_of</code>(<em>klass</em>, <em>object</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L57">lib/detest/unit.rb:57</a>.</p></dd>
420
+ <dt><code>assert_match</code>(<em>pattern</em>, <em>string</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L67">lib/detest/unit.rb:67</a>.</p></dd>
421
+ <dt><code>assert_nil</code>(<em>object</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L62">lib/detest/unit.rb:62</a>.</p></dd>
422
+ <dt><code>assert_not</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
423
+ <dt><code>assert_not_empty</code>(<em>collection</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L26">lib/detest/unit.rb:26</a>.</p></dd>
424
+ <dt><code>assert_not_equal</code>(<em>expected</em>, <em>actual</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L31">lib/detest/unit.rb:31</a>.</p></dd>
425
+ <dt><code>assert_not_in_delta</code>(<em>expected</em>, <em>actual</em>, <em>delta</em>=nil, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L36">lib/detest/unit.rb:36</a>.</p></dd>
426
+ <dt><code>assert_not_in_epsilon</code>(<em>expected</em>, <em>actual</em>, <em>delta</em>=nil, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L36">lib/detest/unit.rb:36</a>.</p></dd>
427
+ <dt><code>assert_not_include</code>(<em>item</em>, <em>collection</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L47">lib/detest/unit.rb:47</a>.</p></dd>
428
+ <dt><code>assert_not_instance_of</code>(<em>klass</em>, <em>object</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L52">lib/detest/unit.rb:52</a>.</p></dd>
429
+ <dt><code>assert_not_kind_of</code>(<em>klass</em>, <em>object</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L57">lib/detest/unit.rb:57</a>.</p></dd>
430
+ <dt><code>assert_not_match</code>(<em>pattern</em>, <em>string</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L67">lib/detest/unit.rb:67</a>.</p></dd>
431
+ <dt><code>assert_not_nil</code>(<em>object</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L62">lib/detest/unit.rb:62</a>.</p></dd>
432
+ <dt><code>assert_not_operator</code>(<em>object</em>, <em>operator</em>, <em>operand</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L77">lib/detest/unit.rb:77</a>.</p></dd>
433
+ <dt><code>assert_not_raise</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L82">lib/detest/unit.rb:82</a>.</p></dd>
434
+ <dt><code>assert_not_respond_to</code>(<em>object</em>, <em>query</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L86">lib/detest/unit.rb:86</a>.</p></dd>
435
+ <dt><code>assert_not_same</code>(<em>expected</em>, <em>actual</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L72">lib/detest/unit.rb:72</a>.</p></dd>
436
+ <dt><code>assert_not_send</code>(<em>object</em>, <em>query</em>, *<em>args</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L95">lib/detest/unit.rb:95</a>.</p></dd>
437
+ <dt><code>assert_not_throw</code>(<em>symbol</em>, <em>message</em>=nil, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L91">lib/detest/unit.rb:91</a>.</p></dd>
438
+ <dt><code>assert_operator</code>(<em>object</em>, <em>operator</em>, <em>operand</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L77">lib/detest/unit.rb:77</a>.</p></dd>
439
+ <dt><code>assert_raise</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L82">lib/detest/unit.rb:82</a>.</p></dd>
440
+ <dt><code>assert_respond_to</code>(<em>object</em>, <em>query</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L86">lib/detest/unit.rb:86</a>.</p></dd>
441
+ <dt><code>assert_same</code>(<em>expected</em>, <em>actual</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L72">lib/detest/unit.rb:72</a>.</p></dd>
442
+ <dt><code>assert_send</code>(<em>object</em>, <em>query</em>, *<em>args</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L95">lib/detest/unit.rb:95</a>.</p></dd>
443
+ <dt><code>assert_throw</code>(<em>symbol</em>, <em>message</em>=nil, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L91">lib/detest/unit.rb:91</a>.</p></dd>
444
+ <dt><code>setup</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
445
+ <dt><code>setup!</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
446
+ <dt><code>teardown</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
447
+ <dt><code>teardown!</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
448
+ <dt><code>test</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
449
+ </dl>
450
+
451
+
452
+ <h3 id="detest-mini">detest/mini</h3>
453
+
454
+ <p>This library emulates <a href="http://blog.zenspider.com/minitest/">Minitest</a> by adding the following methods to the
455
+ <code>Detest</code> module.</p>
456
+
457
+ <dl>
458
+ <dt><code>refute</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
459
+ <dt><code>refute_empty</code>(<em>collection</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L26">lib/detest/unit.rb:26</a>.</p></dd>
460
+ <dt><code>refute_equal</code>(<em>expected</em>, <em>actual</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L31">lib/detest/unit.rb:31</a>.</p></dd>
461
+ <dt><code>refute_in_delta</code>(<em>expected</em>, <em>actual</em>, <em>delta</em>=nil, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L36">lib/detest/unit.rb:36</a>.</p></dd>
462
+ <dt><code>refute_in_epsilon</code>(<em>expected</em>, <em>actual</em>, <em>delta</em>=nil, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L36">lib/detest/unit.rb:36</a>.</p></dd>
463
+ <dt><code>refute_include</code>(<em>item</em>, <em>collection</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L47">lib/detest/unit.rb:47</a>.</p></dd>
464
+ <dt><code>refute_instance_of</code>(<em>klass</em>, <em>object</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L52">lib/detest/unit.rb:52</a>.</p></dd>
465
+ <dt><code>refute_kind_of</code>(<em>klass</em>, <em>object</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L57">lib/detest/unit.rb:57</a>.</p></dd>
466
+ <dt><code>refute_match</code>(<em>pattern</em>, <em>string</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L67">lib/detest/unit.rb:67</a>.</p></dd>
467
+ <dt><code>refute_nil</code>(<em>object</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L62">lib/detest/unit.rb:62</a>.</p></dd>
468
+ <dt><code>refute_operator</code>(<em>object</em>, <em>operator</em>, <em>operand</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L77">lib/detest/unit.rb:77</a>.</p></dd>
469
+ <dt><code>refute_raise</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L82">lib/detest/unit.rb:82</a>.</p></dd>
470
+ <dt><code>refute_respond_to</code>(<em>object</em>, <em>query</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L86">lib/detest/unit.rb:86</a>.</p></dd>
471
+ <dt><code>refute_same</code>(<em>expected</em>, <em>actual</em>, <em>message</em>=nil)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L72">lib/detest/unit.rb:72</a>.</p></dd>
472
+ <dt><code>refute_send</code>(<em>object</em>, <em>query</em>, *<em>args</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L95">lib/detest/unit.rb:95</a>.</p></dd>
473
+ <dt><code>refute_throw</code>(<em>symbol</em>, <em>message</em>=nil, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest/unit.rb#L91">lib/detest/unit.rb:91</a>.</p></dd>
474
+ </dl>
475
+
476
+
477
+ <h3 id="detest-long">detest/long</h3>
478
+
479
+ <p>This library emulates Readability by adding the following methods to the
480
+ <code>Detest</code> module.</p>
481
+
482
+ <dl>
483
+ <dt><code>Catch</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
484
+ <dt><code>Catch!</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
485
+ <dt><code>Catch?</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
486
+ <dt><code>Describe</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
487
+ <dt><code>Describe!</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
488
+ <dt><code>Error</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
489
+ <dt><code>Error!</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
490
+ <dt><code>Error?</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
491
+ <dt><code>False</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
492
+ <dt><code>False!</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
493
+ <dt><code>False?</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
494
+ <dt><code>Inform</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
495
+ <dt><code>Inform!</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
496
+ <dt><code>Share</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
497
+ <dt><code>Share!</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
498
+ <dt><code>Share?</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
499
+ <dt><code>True</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
500
+ <dt><code>True!</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
501
+ <dt><code>True?</code>(*<em>args</em>, &amp;<em>block</em>)</dt><dd><p>This method is defined at <a href="http://github.com/sunaku/detest/tree/master/lib/detest.rb#L1168">lib/detest.rb:1168</a>.</p></dd>
502
+ </dl>
503
+
504
+
505
+ <h2 id="EXAMPLES">EXAMPLES</h2>
506
+
507
+ <p>Begin by loading Detest into your program:</p>
508
+
509
+ <pre><code>require 'rubygems' # might not be necessary; see HACKING
510
+ require 'detest'
511
+ </code></pre>
512
+
513
+ <p>You now have access to the <code>Detest</code> module, whose methods can be called
514
+ directly:</p>
515
+
516
+ <pre><code>Detest.D "hello" do # D() is a class method
517
+ puts "world"
518
+ end
519
+ </code></pre>
520
+
521
+ <p>or mixed-in and called implicitly:</p>
522
+
523
+ <pre><code>include Detest # mix-in the Detest module
524
+
525
+ D "hello" do # D() is an instance method
526
+ puts "world"
527
+ end
528
+ </code></pre>
529
+
530
+ <p>according to your preference.</p>
531
+
532
+ <h3 id="Logging-information-in-the-execution-report">Logging information in the execution report</h3>
533
+
534
+ <p>When the following test is run:</p>
535
+
536
+ <pre><code>require 'detest/auto'
537
+
538
+ D 'Wizard' do
539
+ I 'Preparing spell to defeat mortal foes...'
540
+ end
541
+
542
+ D 'Magician' do
543
+ I 'Preparing rabbits to pull from hat...', rand(15)
544
+ end
545
+
546
+ D 'Calculator' do
547
+ I Math::PI, [1, 2, 3, ['a', 'b', 'c']], {:foo =&gt; 'bar!'}
548
+ end
549
+ </code></pre>
550
+
551
+ <p>Detest will output the following:</p>
552
+
553
+ <pre><code>---
554
+ - Wizard:
555
+ - Preparing spell to defeat mortal foes...
556
+ - Magician:
557
+ - Preparing rabbits to pull from hat...
558
+ - 14
559
+ - Calculator:
560
+ - 3.141592653589793
561
+ - - 1
562
+ - 2
563
+ - 3
564
+ - - a
565
+ - b
566
+ - c
567
+ - foo: bar!
568
+ ---
569
+ time: 0.002826916
570
+ </code></pre>
571
+
572
+ <h3 id="Using-hooks-to-perform-before-and-after-actions">Using hooks to perform before and after actions</h3>
573
+
574
+ <p>When the following test is run:</p>
575
+
576
+ <pre><code>require 'detest/auto'
577
+
578
+ D "outer test" do
579
+ D .&lt; { I "(outer hook) before each" }
580
+ D .&gt; { I "(outer hook) after each" }
581
+ D .&lt;&lt; { I "(outer hook) before all" }
582
+ D .&gt;&gt; { I "(outer hook) after all" }
583
+
584
+ D "inner test 1" do
585
+ D .&lt; { I "(inner hook) before each" }
586
+ D .&gt; { I "(inner hook) after each" }
587
+ D .&lt;&lt; { I "(inner hook) before all" }
588
+ D .&gt;&gt; { I "(inner hook) after all" }
589
+
590
+ D "inner test 1.1" do
591
+ I "hello world"
592
+ end
593
+ end
594
+
595
+ D "inner test 2" do
596
+ I "goodbye world"
597
+ end
598
+
599
+ D .&lt; { I "(outer hook) before each, again" }
600
+ D .&gt; { I "(outer hook) after each, again" }
601
+ end
602
+ </code></pre>
603
+
604
+ <p>Detest will output the following:</p>
605
+
606
+ <pre><code>---
607
+ - outer test:
608
+ - (outer hook) before all
609
+ - (outer hook) before each
610
+ - (outer hook) before each, again
611
+ - inner test 1:
612
+ - (inner hook) before all
613
+ - (inner hook) before each
614
+ - inner test 1.1:
615
+ - hello world
616
+ - (inner hook) after each
617
+ - (inner hook) after all
618
+ - (outer hook) after each
619
+ - (outer hook) after each, again
620
+ - (outer hook) before each
621
+ - (outer hook) before each, again
622
+ - inner test 2:
623
+ - goodbye world
624
+ - (outer hook) after each
625
+ - (outer hook) after each, again
626
+ - (outer hook) after all
627
+ ---
628
+ time: 0.007525086
629
+ </code></pre>
630
+
631
+ <h3 id="Sharing-code-between-tests">Sharing code between tests</h3>
632
+
633
+ <p>When the following test is run:</p>
634
+
635
+ <pre><code>require 'detest/auto'
636
+
637
+ S :knowledge do
638
+ I 'Knowledge is power!'
639
+ end
640
+
641
+ D 'Healer' do
642
+ S :knowledge
643
+ end
644
+
645
+ D 'Warrior' do
646
+ S! :strength do
647
+ I 'Strength is power!'
648
+ end
649
+ end
650
+
651
+ D 'Wizard' do
652
+ S :knowledge
653
+ S :strength
654
+ end
655
+
656
+ D 'King' do
657
+ T { S? :knowledge }
658
+ T { S? :strength }
659
+ F { S? :power }
660
+ I 'Power is power!'
661
+ end
662
+ </code></pre>
663
+
664
+ <p>Detest will output the following:</p>
665
+
666
+ <pre><code>---
667
+ - Healer:
668
+ - Knowledge is power!
669
+ - Warrior:
670
+ - Strength is power!
671
+ - Wizard:
672
+ - Knowledge is power!
673
+ - Strength is power!
674
+ - King:
675
+ - Power is power!
676
+ ---
677
+ pass: 3
678
+ time: 0.007643321
679
+ </code></pre>
680
+
681
+ <h3 id="Insulated-and-uninsulated-tests">Insulated and uninsulated tests</h3>
682
+
683
+ <p>When the following test is run:</p>
684
+
685
+ <pre><code>require 'detest/auto'
686
+
687
+ D "a root-level test" do
688
+ @outside = 1
689
+ T { defined? @outside }
690
+ T { @outside == 1 }
691
+
692
+ D "an inner, non-insulated test" do
693
+ T { defined? @outside }
694
+ T { @outside == 1 }
695
+ end
696
+
697
+ D! "an inner, insulated test" do
698
+ F { defined? @outside }
699
+ F { @outside == 1 }
700
+
701
+ @inside = 2
702
+ T { defined? @inside }
703
+ T { @inside == 2 }
704
+ end
705
+
706
+ F { defined? @inside }
707
+ F { @inside == 2 }
708
+ end
709
+ </code></pre>
710
+
711
+ <p>Detest will output the following:</p>
712
+
713
+ <pre><code>---
714
+ - a root-level test:
715
+ - an inner, non-insulated test:
716
+ - an inner, insulated test:
717
+ ---
718
+ pass: 10
719
+ time: 0.009236844
720
+ </code></pre>
721
+
722
+ <h2 id="HACKING">HACKING</h2>
723
+
724
+ <p>This section is meant for people who want to develop Detest's source code.</p>
725
+
726
+ <h3 id="Prerequisites">Prerequisites</h3>
727
+
728
+ <p>Install Ruby libraries necessary for development:</p>
729
+
730
+ <pre><code>gem install detest --development
731
+ </code></pre>
732
+
733
+ <h3 id="Infrastructure">Infrastructure</h3>
734
+
735
+ <p><a href="http://snk.tuxfamily.org/lib/inochi/">Inochi</a> serves as the project infrastructure for Detest. It handles tasks
736
+ such as building this help manual and API documentation, and packaging,
737
+ announcing, and publishing new releases. See its help manual and list of
738
+ tasks to get started:</p>
739
+
740
+ <pre><code>inochi --help # display help manual
741
+ inochi --tasks # list available tasks
742
+ </code></pre>
743
+
744
+ <h3 id="-LOAD_PATH-setup">$LOAD_PATH setup</h3>
745
+
746
+ <p>Ensure that the <code>lib/</code> directory is listed in Ruby's <code>$LOAD_PATH</code> before you
747
+ use any libraries therein or run any executables in the <code>bin/</code> directory.</p>
748
+
749
+ <p>This can be achieved by passing an option to Ruby:</p>
750
+
751
+ <pre><code>ruby -Ilib bin/detest
752
+ irb -Ilib -r detest
753
+ </code></pre>
754
+
755
+ <p>Or by setting the <code>$RUBYLIB</code> environment variable:</p>
756
+
757
+ <pre><code>export RUBYLIB=lib # bash, ksh, zsh
758
+ setenv RUBYLIB lib # csh
759
+ set -x RUBYLIB lib # fish
760
+
761
+ ruby bin/detest
762
+ irb -r detest
763
+ </code></pre>
764
+
765
+ <p>Or by running Ruby through the <a href="http://github.com/chneukirchen/rup/blob/master/ruby-wrapper">ruby-wrapper</a> tool.</p>
766
+
767
+ <h3 id="RubyGems-setup">RubyGems setup</h3>
768
+
769
+ <p>If you use Ruby 1.8 or older, then ensure that RubyGems is activated before
770
+ you use any libraries in the <code>lib/</code> directory or run any executables in the
771
+ <code>bin/</code> directory.</p>
772
+
773
+ <p>This can be achieved by passing an option to Ruby:</p>
774
+
775
+ <pre><code>ruby -rubygems bin/detest
776
+ irb -rubygems -r detest
777
+ </code></pre>
778
+
779
+ <p>Or by setting the <code>$RUBYOPT</code> environment variable:</p>
780
+
781
+ <pre><code>export RUBYOPT=-rubygems # bash, ksh, zsh
782
+ setenv RUBYOPT -rubygems # csh
783
+ set -x RUBYOPT -rubygems # fish
784
+ </code></pre>
785
+
786
+ <h3 id="Running-tests">Running tests</h3>
787
+
788
+ <p>Simply execute the included test runner, which sets up Ruby's <code>$LOAD_PATH</code> for
789
+ testing, loads the <code>test/helper.rb</code> file, and then evaluates all
790
+ <code>test/**/*_test.rb</code> files:</p>
791
+
792
+ <pre><code>ruby test/runner
793
+ </code></pre>
794
+
795
+ <p>Its exit status will indicate whether all tests have passed. It may also
796
+ print additional pass/fail information depending on the testing library used
797
+ in the <code>test/helper.rb</code> file.</p>
798
+
799
+ <h3 id="Contributing">Contributing</h3>
800
+
801
+ <p>Fork this project on GitHub (see <strong>Resources</strong> above) and send a pull request.</p>
802
+
803
+ <h2 id="HISTORY">HISTORY</h2>
804
+
805
+ <p>This section contains release notes of current and past releases.</p>
806
+
807
+ <h3 id="Version-3-1-0-2010-07-25-">Version 3.1.0 (2010-07-25)</h3>
808
+
809
+ <p>This release adds <code>N()</code> methods for nil value assertions and renames the
810
+ project from "DIFECTS" to "Detest" to avoid forming a habit of intentional
811
+ misspellings.</p>
812
+
813
+ <p>New features:</p>
814
+
815
+ <ul>
816
+ <li>Add <code>N()</code>, <code>N!()</code>, and <code>N?()</code> methods for asserting that a value is nil.
817
+ This idea comes from Gavin Sinclair's <a href="http://gsinclair.github.com/attest.html">Attest</a> assertion testing
818
+ library.</li>
819
+ </ul>
820
+
821
+
822
+ <p>Housekeeping:</p>
823
+
824
+ <ul>
825
+ <li><p>Rename project from "DIFECTS" to "Detest".</p></li>
826
+ <li><p>Upgrade project to Inochi 4.0.0 infrastructure.</p></li>
827
+ <li><p>Minor code refactoring and manual revisions.</p></li>
828
+ </ul>
829
+
830
+
831
+ <h3 id="Version-3-0-1-2010-07-25-">Version 3.0.1 (2010-07-25)</h3>
832
+
833
+ <p>This release fixes a bug in Ruby 1.8, refactors the code, and better documents
834
+ test hooks in the manual.</p>
835
+
836
+ <p>Bug fixes:</p>
837
+
838
+ <ul>
839
+ <li>Ruby 1.8 does not pass value to <code>Hash#delete_if()</code>. All failure details
840
+ were being omitted, instead of just the unavailable ones, as a result.</li>
841
+ </ul>
842
+
843
+
844
+ <p>Housekeeping:</p>
845
+
846
+ <ul>
847
+ <li><p>Refactor variable values hash calculation and pretty printing logic.</p></li>
848
+ <li><p>Put FailureDetails pretty-printing modules into their own namespace.</p></li>
849
+ <li><p>Raise error if closest insulated test cannot be not found.</p></li>
850
+ <li><p>Describe all test hooks and add example to manual, plus small revisions.</p></li>
851
+ </ul>
852
+
853
+
854
+ <h3 id="Version-3-0-0-2010-07-24-">Version 3.0.0 (2010-07-24)</h3>
855
+
856
+ <p>This release renames the project from "Dfect" to "DIFECTS", reduces cruft,
857
+ improves the presentation and debuggability of assertion failures, and revises
858
+ the manual.</p>
859
+
860
+ <p>Thank you:</p>
861
+
862
+ <ul>
863
+ <li>Gavin Sinclair inspired me to work on this project again!</li>
864
+ </ul>
865
+
866
+
867
+ <p>Incompatible changes:</p>
868
+
869
+ <ul>
870
+ <li><p>Rename project from "Dfect" to "DIFECTS", which stands for:</p>
871
+
872
+ <p><code>D</code>escribe, <code>I</code>nform, <code>F</code>alse, <code>E</code>rror, <code>C</code>atch, <code>T</code>rue, <code>S</code>hare</p></li>
873
+ <li><p>Remove ruby-debug integration because it is only helpful if you run a
874
+ program inside it from the very start! That is, you cannot start
875
+ ruby-debug in the middle of a program and expect it to know about the
876
+ call stack that lead up to that point in the program. Instead, we now
877
+ use IRB to inspect program state at the point of failure only.</p></li>
878
+ <li><p>Remove <code>--quiet</code> option because user can pipe to /dev/null instead.</p></li>
879
+ <li><p>Rename <code>run()</code> to <code>start()</code> to better complement <code>stop()</code>. The <code>run()</code>
880
+ method no longer clears test results; use <code>reset()</code> for that.</p></li>
881
+ <li><p>Rename <code>L()</code> to <code>I()</code> as in "inform" the user.</p></li>
882
+ <li><p>Replace <code>options()</code> with <code>debug()</code>.</p></li>
883
+ <li><p>Replace <code>report()</code> with <code>trace()</code> and <code>stats()</code>.</p></li>
884
+ <li><p>Rename the <code>difects/full</code> library to <code>difects/long</code>.</p></li>
885
+ <li><p>Do not report instance variables in assertion failures.</p></li>
886
+ </ul>
887
+
888
+
889
+ <p>New features:</p>
890
+
891
+ <ul>
892
+ <li><p>Improve debuggability by tracking the bindings of all lines of code
893
+ executed leading up to the point of failure using Ruby's
894
+ awesome <code>set_trace_func</code> facility.</p>
895
+
896
+ <p>This allows block-less assertions to be debugged with the same level of
897
+ accuracy as normal block-given assertions:</p>
898
+
899
+ <pre><code>x = 1
900
+ y = 3
901
+ T { x == y } # a block-given assertion
902
+ T x == y # a block-less assertion
903
+ </code></pre>
904
+
905
+ <p>In both cases, you will be able to inspect the local variables x and y!</p></li>
906
+ <li><p>Add <code>I!()</code> method to start the interactive debugger anywhere in your tests.</p></li>
907
+ <li><p>Add <code>reset()</code> to manually clear previous test results.</p></li>
908
+ <li><p>Alias <code>test()</code> to <code>D()</code> in <a href="http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html">Test::Unit</a> emulation layer.</p></li>
909
+ <li><p>Fallback to <code>pp()</code> if <code>to_yaml()</code> fails while reporting failures.</p></li>
910
+ <li><p>Use <a href="http://rubygems.org/gems/orderedhash">OrderedHash</a> library in Ruby versions older than 1.9 for
911
+ consistent presentation of information in assertion failures.</p></li>
912
+ <li><p>Show full failure details before starting debugger instead of omitting
913
+ the backtrace and local variables listing.</p></li>
914
+ <li><p>Use PP to pretty-print variable values in failure details.</p></li>
915
+ <li><p>Omit unavailable information from failure details.</p></li>
916
+ <li><p>Put backtrace above code listing and variables in failure details.</p></li>
917
+ <li><p>Prevent empty array leaf nodes in execution trace.</p></li>
918
+ </ul>
919
+
920
+
921
+ <p>Bug fixes:</p>
922
+
923
+ <ul>
924
+ <li><p>Make <code>DIFECTS</code> module's instance methods available as class methods.</p></li>
925
+ <li><p>Always display fail trace before entering debugger.</p></li>
926
+ <li><p>Always clear test execution internals after <code>start()</code>.</p></li>
927
+ <li><p>Prevent IRB re-initialization errors when starting debugger.</p></li>
928
+ </ul>
929
+
930
+
931
+ <p>Housekeeping:</p>
932
+
933
+ <ul>
934
+ <li><p>Clarify how to mix-in modules inside insulated tests in the manual.</p>
935
+
936
+ <p>Thanks to Gavin Sinclair for reporting this issue.</p></li>
937
+ <li><p>Document methods (with hyperlinks to the location in the source code
938
+ where they are defined) provided by emulation layers in manual.</p></li>
939
+ <li><p>Talk about passing condition as first argument to <code>T</code> and <code>F</code> assertions
940
+ and provide a code example in the manual.</p></li>
941
+ <li><p>Clean up the code and revise the manual. Yay!</p></li>
942
+ </ul>
943
+
944
+
945
+ <h3 id="Version-2-2-0-2010-04-28-">Version 2.2.0 (2010-04-28)</h3>
946
+
947
+ <p>This release adds a UNIX manual page and a sub-library for full method names.</p>
948
+
949
+ <p>New features:</p>
950
+
951
+ <ul>
952
+ <li><p>Add <code>dfect/full</code> sub-library that provides full name aliases to Dfect's
953
+ abbreviated vocabulary:</p>
954
+
955
+ <p><code>D</code>escribe, <code>T</code>rue, <code>F</code>alse, <code>E</code>rror, <code>C</code>atch, <code>S</code>hare, and <code>L</code>og.</p></li>
956
+ <li><p>Run <code>dfect --help</code> to see the UNIX manual page!</p></li>
957
+ </ul>
958
+
959
+
960
+ <p>Housekeeping:</p>
961
+
962
+ <ul>
963
+ <li>Upgrade to Inochi 3.0.0 and revise the help manual.</li>
964
+ </ul>
965
+
966
+
967
+ <h3 id="Version-2-1-0-2010-03-31-">Version 2.1.0 (2010-03-31)</h3>
968
+
969
+ <p>This release adds a command-line test runner and performs some minor
970
+ housekeeping.</p>
971
+
972
+ <p>New features:</p>
973
+
974
+ <ul>
975
+ <li>Add <code>bin/dfect</code> executable as command-line interface to this library.</li>
976
+ </ul>
977
+
978
+
979
+ <p>Housekeeping:</p>
980
+
981
+ <ul>
982
+ <li><p>Do not <code>require 'rubygems'</code> before loading the "ruby-debug" library.</p></li>
983
+ <li><p>Upgrade to Inochi 2.0.0-rc2 for managing this project.</p></li>
984
+ </ul>
985
+
986
+
987
+ <h3 id="Version-2-0-0-2010-03-21-">Version 2.0.0 (2010-03-21)</h3>
988
+
989
+ <p>This release adds the ability to insulate tests from each other, share code
990
+ between them, makes the order of parameters consistent in the API, improves
991
+ user interactivity, fixes some bugs, and revises the user manual.</p>
992
+
993
+ <p>Incompatible changes:</p>
994
+
995
+ <ul>
996
+ <li><p>Root-level calls to the <code>Dfect::D()</code>
997
+ method are automatically insulated now.</p></li>
998
+ <li><p>The <code>Dfect::E()</code> methods now expects its optional message
999
+ parameter to be the <em>last parameter</em> in the parameter list.</p></li>
1000
+ <li><p>The <code>Dfect::C()</code> methods now expect their first parameter to
1001
+ be a symbol instead of the optional message to be shown in
1002
+ case of assertion failure.</p></li>
1003
+ <li><p>The <code>Dfect::R()</code> has been renamed to <code>Dfect::L()</code>,
1004
+ which is a mnemonic for "Logging".</p></li>
1005
+ <li><p>Shorten names of hash keys in the execution trace for brevity
1006
+ and rename <code>:raise</code> key in report statistics to <code>:error</code>.</p></li>
1007
+ <li><p>Only the most helpful subset of the failure details is shown before
1008
+ placing the user into a debugger because they can query the omitted
1009
+ information (on demand) inside the debugger.</p></li>
1010
+ <li><p>The execution trace is only shown if all tests passed in <code>Dfect::run()</code>.</p></li>
1011
+ <li><p>The <code>:debug</code> option is now set to Ruby's <code>$DEBUG</code> global by default.</p></li>
1012
+ </ul>
1013
+
1014
+
1015
+ <p>New features:</p>
1016
+
1017
+ <ul>
1018
+ <li><p>Print failures as they occur instead of waiting until the end.</p></li>
1019
+ <li><p>Allow passing condition as argument to true/false assertions instead
1020
+ of requiring the condition to be passed as a code block, and also fall
1021
+ back to the binding of inner-most enclosing test or hook when
1022
+ debugging or constructing a failure report for an assertion that was
1023
+ not given a block.</p>
1024
+
1025
+ <p>This allows you to reduce "line noise" in your tests:</p>
1026
+
1027
+ <pre><code>D "Lottery" do
1028
+ winning_ticket = rand()
1029
+
1030
+ D "My chances of winning" do
1031
+ my_ticket = rand()
1032
+ F my_ticket == winning_ticket, "I won?! Dream on."
1033
+ end
1034
+ end
1035
+ </code></pre></li>
1036
+ <li><p>Add <code>Dfect::S()</code> methods for sharing code between tests.</p></li>
1037
+ <li><p>Add <code>Dfect::D!()</code> method to explicitly insulate a test from other
1038
+ tests, the top-level Ruby environment, and the code being tested.</p></li>
1039
+ <li><p>Add <code>Dfect::info()</code> method which returns the details of
1040
+ the failure that is currently being debugged by the user.</p></li>
1041
+ <li><p>Add instance variables to the <code>:vars</code> section of a failure report.</p></li>
1042
+ <li><p>Add <code>setup!()</code> and <code>teardown!()</code> methods for before-all and
1043
+ after-all hooks in the dfect/unit emulation library.</p></li>
1044
+ <li><p>Add test execution time to statistics hash (under the <code>:time</code> key).</p></li>
1045
+ </ul>
1046
+
1047
+
1048
+ <p>Bug fixes:</p>
1049
+
1050
+ <ul>
1051
+ <li><p>Do not print any output when <code>:quiet</code> option is active.</p></li>
1052
+ <li><p>Allow passing multiple strings/objects to <code>Dfect::D()</code> like in RSpec.</p></li>
1053
+ <li><p>Make before and after hook methods mixin-able like assertions.</p></li>
1054
+ <li><p>Do not assume that <code>Module#to_s</code> is the same as <code>Module#name</code>.</p></li>
1055
+ </ul>
1056
+
1057
+
1058
+ <p>Housekeeping:</p>
1059
+
1060
+ <ul>
1061
+ <li><p>Upgrade to Inochi 2.0.0-rc1 for managing this project.</p></li>
1062
+ <li><p>Make emulation libraries modify Dfect module instead of Kernel.</p></li>
1063
+ <li><p>Do not pollute the user's output with our <code>Class#to_yaml</code> workaround.</p></li>
1064
+ <li><p>Remove "Motivation" section from user manual. It was too fanatic!</p></li>
1065
+ </ul>
1066
+
1067
+
1068
+ <h3 id="Version-1-1-0-2009-10-27-">Version 1.1.0 (2009-10-27)</h3>
1069
+
1070
+ <p>This release adds a new method for emitting status messages and does some
1071
+ internal housekeeping.</p>
1072
+
1073
+ <p>Thank you:</p>
1074
+
1075
+ <ul>
1076
+ <li>Iñaki Baz Castillo used Dfect and suggested new features.</li>
1077
+ </ul>
1078
+
1079
+
1080
+ <p>New features:</p>
1081
+
1082
+ <ul>
1083
+ <li>Add <code>Dfect::S()</code> method for adding status messages to the
1084
+ execution report. This feature was <a href="http://github.com/sunaku/dfect/issues/1">requested
1085
+ by</a> Iñaki Baz Castillo.</li>
1086
+ </ul>
1087
+
1088
+
1089
+ <p>Housekeeping:</p>
1090
+
1091
+ <ul>
1092
+ <li><p>Remove unused require of 'delegate' standard library in 'dfect/spec'
1093
+ RSpec emulation layer.</p></li>
1094
+ <li><p>Mention emulation layers for popular testing libraries.</p></li>
1095
+ <li><p>Mention that assertions take an optional message parameter.</p></li>
1096
+ <li><p>Replace sample unit test with Dfect test suite.</p></li>
1097
+ <li><p>Upgrade user manual to ERBook 9.0.0.</p></li>
1098
+ </ul>
1099
+
1100
+
1101
+ <h3 id="Version-1-0-1-2009-10-07-">Version 1.0.1 (2009-10-07)</h3>
1102
+
1103
+ <p>This release fixes a bug in the <a href="http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html">Test::Unit</a> emulation library and revises the
1104
+ user manual.</p>
1105
+
1106
+ <p>Bug fixes:</p>
1107
+
1108
+ <ul>
1109
+ <li>The parameters for the <code>assert_equal()</code> method in the
1110
+ dfect/unit library were in the wrong order.</li>
1111
+ </ul>
1112
+
1113
+
1114
+ <p>Housekeeping:</p>
1115
+
1116
+ <ul>
1117
+ <li><p>Revise user manual to better fit jQuery UI tabs.</p></li>
1118
+ <li><p>Justify the use of <code>eval()</code> in emulation libraries.</p></li>
1119
+ <li><p>Use simpler Copyright reminder at the top of every file.</p></li>
1120
+ <li><p>Make SLOC count in user manual reflect the <em>core</em> library only.</p></li>
1121
+ <li><p>Mark code spans with <code>{:lang=ruby}</code> instead of HTML <code>&lt;code/&gt;</code> tags.</p></li>
1122
+ <li><p>Open source is for fun, so <a href="http://loiclemeur.com/english/2009/03/never-criticize-your-competitors.html">be nice</a> and speak of "related works" instead of "competitors".</p></li>
1123
+ </ul>
1124
+
1125
+
1126
+ <h3 id="Version-1-0-0-2009-05-03-">Version 1.0.0 (2009-05-03)</h3>
1127
+
1128
+ <p>This release improves default choices, adds emulation layers to mimic other
1129
+ testing libraries, and fixes some bugs.</p>
1130
+
1131
+ <p>Incompatible changes:</p>
1132
+
1133
+ <ul>
1134
+ <li><p>The <code>:debug</code> option is now enabled by default and is no longer linked to
1135
+ the value of <code>$DEBUG</code>.</p></li>
1136
+ <li><p><code>Dfect.run()</code> now appends to previous results by default.</p>
1137
+
1138
+ <p>This behavior can be disabled by passing <code>false</code> to the method.</p></li>
1139
+ </ul>
1140
+
1141
+
1142
+ <p>New features:</p>
1143
+
1144
+ <ul>
1145
+ <li>Add emulation layers to mimic other testing libraries:
1146
+
1147
+ <ul>
1148
+ <li>dfect/unit --- <a href="http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html">Test::Unit</a></li>
1149
+ <li>dfect/mini --- <a href="http://blog.zenspider.com/minitest/">Minitest</a></li>
1150
+ <li>dfect/spec --- <a href="http://rspec.info">RSpec</a></li>
1151
+ </ul>
1152
+ </li>
1153
+ </ul>
1154
+
1155
+
1156
+ <p>Bug fixes:</p>
1157
+
1158
+ <ul>
1159
+ <li>Do not blindly replace <code>Class#to_yaml</code>; it might be fixed someday.</li>
1160
+ </ul>
1161
+
1162
+
1163
+ <p>Housekeeping:</p>
1164
+
1165
+ <ul>
1166
+ <li><p>Add "Motivation" section in user manual to promote interactive
1167
+ debugging.</p></li>
1168
+ <li><p>Add brief History of this project's inception.</p></li>
1169
+ <li><p>Remove redundant assertions for F!() and T!() methods in test suite.</p></li>
1170
+ <li><p>Add copyright notice at the top of every file.</p></li>
1171
+ </ul>
1172
+
1173
+
1174
+ <h3 id="Version-0-1-0-2009-04-28-">Version 0.1.0 (2009-04-28)</h3>
1175
+
1176
+ <p>This release adds new variations to assertion methods, fixes several bugs,
1177
+ and improves test coverage.</p>
1178
+
1179
+ <p>Thank you:</p>
1180
+
1181
+ <ul>
1182
+ <li>François Beausoleil contributed patches for both code <em>and</em> tests! :-)</li>
1183
+ </ul>
1184
+
1185
+
1186
+ <p>New features:</p>
1187
+
1188
+ <ul>
1189
+ <li><p>Added negation (m!) and sampling (m?) variations to normal assertion
1190
+ methods. These new methods implement assertion functionality missing so
1191
+ far (previously we could not assert that a given exception was NOT thrown)
1192
+ and thereby allow us to fully test Dfect using itself.</p></li>
1193
+ <li><p>Added documentation on how to insulate tests from the global Ruby
1194
+ namespace.</p></li>
1195
+ </ul>
1196
+
1197
+
1198
+ <p>Bug fixes:</p>
1199
+
1200
+ <ul>
1201
+ <li><p>The <code>E()</code> method did not consider the case where a block does not raise
1202
+ anything as a failure. ---<em>François Beausoleil</em></p></li>
1203
+ <li><p>When creating a report about an assertion failure, an exception would be
1204
+ thrown if any local variables pointed to an empty array.</p></li>
1205
+ <li><p>The <code>Dfect::&lt;()</code> method broke the inheritance-checking behavior of the &lt;
1206
+ class method.</p>
1207
+
1208
+ <p>Added a bypass to the originial behavior so that <code>RCov::XX</code> can properly
1209
+ generate a report about code that uses Dfect.</p></li>
1210
+ <li><p>Added workaround for YAML error when serializing a class object:</p>
1211
+
1212
+ <pre><code>TypeError: can't dump anonymous class Class
1213
+ </code></pre></li>
1214
+ </ul>
1215
+
1216
+
1217
+ <p>Housekeeping:</p>
1218
+
1219
+ <ul>
1220
+ <li>Filled the big holes in test coverage. Everything except the runtime
1221
+ debugging logic is now covered by the unit tests.</li>
1222
+ </ul>
1223
+
1224
+
1225
+ <h3 id="Version-0-0-0-2009-04-13-">Version 0.0.0 (2009-04-13)</h3>
1226
+
1227
+ <p>For the longest time, I took <a href="http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html">Test::Unit</a> and <a href="http://rspec.info">RSpec</a> for granted. They were
1228
+ the epitomy of modern Ruby practice; the insurmountable status quo;
1229
+ immortalized in books, conferences, and blogs alike.</p>
1230
+
1231
+ <p>Why would <em>anyone</em> think of using anything remotely different, let alone be
1232
+ foolish enough to write an alternative testing library when these are clearly
1233
+ <em>good enough</em>?</p>
1234
+
1235
+ <p>Recent experiments in assertion testing libraries smashed my world view:</p>
1236
+
1237
+ <ul>
1238
+ <li><a href="http://assert2.rubyforge.org">assert{ 2.0 }</a></li>
1239
+ <li><a href="http://github.com/ahoward/testy/tree/master">Testy</a></li>
1240
+ <li><a href="http://www.ruby-forum.com/topic/183354">Verify</a></li>
1241
+ </ul>
1242
+
1243
+
1244
+ <p>The status quo was certainly <em>not</em> "good enough", as I had so blindly
1245
+ believed all these years. In fact, they were <em>verbose</em> behemoths that chose
1246
+ to encode endless permutations of conjecture into methods.</p>
1247
+
1248
+ <p>Empowered by this revelation and inspired by <a href="http://www.ruby-forum.com/topic/183354#801895">Sean O'Halpin's musing</a> on alternative names for
1249
+ assertion methods, I rose to challenge the status quo.</p>
1250
+
1251
+ <p>And so I present to you the first public release of "Dfect".</p>
1252
+
1253
+ <h2 id="AUTHORS">AUTHORS</h2>
1254
+
1255
+ <p>Suraj N. Kurapati</p>
1256
+
1257
+ <h2 id="CREDITS">CREDITS</h2>
1258
+
1259
+ <p>François Beausoleil,
1260
+ Gavin Sinclair,
1261
+ Iñaki Baz Castillo,
1262
+ Sean O'Halpin</p>
1263
+
1264
+ <h2 id="LICENSE">LICENSE</h2>
1265
+
1266
+ <p>(the ISC license)</p>
1267
+
1268
+ <p>Copyright 2009 Suraj N. Kurapati <a href="&#x6d;&#x61;&#x69;&#x6c;&#x74;&#x6f;&#58;&#115;&#x75;&#110;&#x61;&#107;&#117;&#x40;&#x67;&#109;&#x61;&#105;&#108;&#x2e;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#x73;&#117;&#110;&#x61;&#107;&#x75;&#64;&#x67;&#109;&#97;&#105;&#108;&#x2e;&#99;&#111;&#x6d;</a></p>
1269
+
1270
+ <p>Permission to use, copy, modify, and/or distribute this software for any
1271
+ purpose with or without fee is hereby granted, provided that the above
1272
+ copyright notice and this permission notice appear in all copies.</p>
1273
+
1274
+ <p>THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1275
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1276
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1277
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1278
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1279
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1280
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.</p>
1281
+
1282
+ <h2 id="SEE-ALSO">SEE ALSO</h2>
1283
+
1284
+ <p><a href="http://assert2.rubyforge.org">assert{ 2.0 }</a>,
1285
+ <a href="http://gsinclair.github.com/attest.html">Attest</a>,
1286
+ <a href="http://github.com/ahoward/testy/tree/master">Testy</a>,
1287
+ <a href="http://www.ruby-forum.com/topic/183354">Verify</a></p>
1288
+
1289
+
1290
+ <ol class='man-decor man-foot man foot'>
1291
+ <li class='tl'></li>
1292
+ <li class='tc'>July 2010</li>
1293
+ <li class='tr'>detest(1)</li>
1294
+ </ol>
1295
+
1296
+ </div>
1297
+ </body>
1298
+ </html>