detest 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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>