test-unit-ext 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS.en +6 -0
- data/NEWS.ja +6 -0
- data/README.en +180 -2
- data/README.ja +180 -2
- data/html/news.html +2 -11
- data/html/news.html.en +2 -11
- data/html/news.html.ja +2 -11
- data/html/readme.html +1 -1
- data/html/readme.html.en +1 -1
- data/html/readme.html.ja +1 -1
- data/lib/test-unit-ext.rb +3 -1
- data/lib/test-unit-ext/assertions.rb +2 -2
- data/lib/test-unit-ext/attributes.rb +19 -4
- data/lib/test-unit-ext/colorized-runner.rb +10 -1
- data/lib/test-unit-ext/diff.rb +26 -14
- data/lib/test-unit-ext/notification.rb +81 -0
- data/lib/test-unit-ext/pending.rb +99 -0
- data/lib/test-unit-ext/priority.rb +4 -37
- data/lib/test-unit-ext/version.rb +1 -1
- data/test/test_attributes.rb +3 -0
- data/test/test_diff.rb +38 -2
- data/test/test_notification.rb +32 -0
- data/test/test_pending.rb +64 -0
- data/test/test_priority.rb +88 -0
- metadata +11 -3
data/NEWS.en
CHANGED
data/NEWS.ja
CHANGED
data/README.en
CHANGED
@@ -14,9 +14,12 @@ TestUnitExt provides some useful features:
|
|
14
14
|
|
15
15
|
* Emacs friendly backtrace format.
|
16
16
|
* runs tests depending on priority.
|
17
|
-
* supports
|
17
|
+
* supports attributes for each test.
|
18
18
|
* always shows tests result even if tests are interrupted.
|
19
19
|
* colorized output.
|
20
|
+
* outputs diff between expected and actual value.
|
21
|
+
* reports test result as XML format.
|
22
|
+
* adds pending/notification methods.
|
20
23
|
|
21
24
|
== Author
|
22
25
|
|
@@ -42,10 +45,185 @@ None
|
|
42
45
|
|
43
46
|
require 'test-unit-ext'
|
44
47
|
|
45
|
-
|
48
|
+
== Reference
|
46
49
|
|
47
50
|
=== Attributes
|
48
51
|
|
52
|
+
You can add attributes to your test to get more useful
|
53
|
+
information on failure. For example, you can add Bug ID like
|
54
|
+
the following
|
55
|
+
|
56
|
+
class MyTest < Test::Unit::TestCase
|
57
|
+
bug 123
|
58
|
+
def test_invalid_input
|
59
|
+
assert_equal("OK", input)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
In the above example, test_invalid_input test has an
|
64
|
+
attribute that the test is for Bug #123.
|
65
|
+
|
66
|
+
You can also write like the following:
|
67
|
+
|
68
|
+
class MyTest < Test::Unit::TestCase
|
69
|
+
attribute :bug, 123
|
70
|
+
def test_invalid_input
|
71
|
+
assert_equal("OK", input)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
That is, bug method is a convenience method. You can add any
|
76
|
+
attributes to your test if you use attribute method.
|
77
|
+
|
78
|
+
=== Priority
|
79
|
+
|
80
|
+
It will be difficult that you drop into test and develop
|
81
|
+
cycle when you have many tests and the tests take much
|
82
|
+
time. To reduce the problem, you can select some tests from
|
83
|
+
all tests and reduce elapsed time each test. It's a problem
|
84
|
+
that which tests are selected in each test.
|
85
|
+
|
86
|
+
In TestUnitExt, each test has its priority and runs tests
|
87
|
+
are selected by probabilistic method. --priority command
|
88
|
+
line option enables this feature.
|
89
|
+
|
90
|
+
A test that has higher priority will be ran in higher
|
91
|
+
ratio. Each test doesn't run all tests but tests that are
|
92
|
+
ran each test are changed in each test. All tests will be
|
93
|
+
ran after some test and develop cycles.
|
94
|
+
|
95
|
+
Tests that aren't succeeded in the previous test are ran in
|
96
|
+
the current test in spite of its priority. This means that
|
97
|
+
important tests are ran without you do something. You will
|
98
|
+
keep your lightweight test and develop cycles without
|
99
|
+
additional works.
|
100
|
+
|
101
|
+
Here are a sample priority specification. Priority
|
102
|
+
specification effects followed tests like public and
|
103
|
+
private.
|
104
|
+
|
105
|
+
class MyTest < Test::Unit::TestCase
|
106
|
+
priority :must
|
107
|
+
def test_must
|
108
|
+
# will be always ran
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_must2
|
112
|
+
# will be always ran too
|
113
|
+
end
|
114
|
+
|
115
|
+
priority :import
|
116
|
+
def test_import
|
117
|
+
# will be almost ran
|
118
|
+
end
|
119
|
+
|
120
|
+
priority :high
|
121
|
+
def test_high
|
122
|
+
# will be ran in high probability
|
123
|
+
end
|
124
|
+
|
125
|
+
priority :normal
|
126
|
+
def test_normal
|
127
|
+
# will be ran in fifty-fifty probability
|
128
|
+
# tests without priority specification has normal priority
|
129
|
+
end
|
130
|
+
|
131
|
+
priority :low
|
132
|
+
def test_low
|
133
|
+
# will be sometimes ran
|
134
|
+
end
|
135
|
+
|
136
|
+
priority :never
|
137
|
+
def test_never
|
138
|
+
# never be ran
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
=== Pending
|
143
|
+
|
144
|
+
You may write a test for a function that is not
|
145
|
+
implemented. In the case, the test will be failed. It's
|
146
|
+
correct that the test is failed but the test means 'the
|
147
|
+
function is not implemented'. To state your intent, pend
|
148
|
+
method is provided.
|
149
|
+
|
150
|
+
Please state your intent by your test code by using the
|
151
|
+
method.
|
152
|
+
|
153
|
+
class MyTest < Test::Unit::TestCase
|
154
|
+
def test_minor_function
|
155
|
+
pend("Should implement")
|
156
|
+
assert_equal("Good!", MyModule.minor_function)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
=== Notification
|
161
|
+
|
162
|
+
You may put some messages in test. For example, "this test
|
163
|
+
is omitted because XXX module is not found on the
|
164
|
+
environment."
|
165
|
+
|
166
|
+
Those messages can be displayed by puts but it causes test
|
167
|
+
result output. To prevent this, notify method is
|
168
|
+
provided. notify method doesn't display those messages in
|
169
|
+
the place but display those messages in test result summary
|
170
|
+
like "failure", "error" and so on. You can leave those
|
171
|
+
messages without breaking test result output by using notify
|
172
|
+
method.
|
173
|
+
|
174
|
+
class MyTest < Test::Unit::TestCase
|
175
|
+
def test_with_other_module
|
176
|
+
unless MyModule.have_XXX?
|
177
|
+
notify("XXX module isn't found. skip this test.")
|
178
|
+
return
|
179
|
+
end
|
180
|
+
assert_equal("XXX Module!!!", MyModule.use_XXX)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
=== XML report
|
185
|
+
|
186
|
+
Test result can be reported as XML format if --xml-report
|
187
|
+
option is specified. A reported XML has the following
|
188
|
+
structure:
|
189
|
+
|
190
|
+
<report>
|
191
|
+
<result>
|
192
|
+
<test-case>
|
193
|
+
<name>TEST CASE NAME</name>
|
194
|
+
<description>DESCRIPTION OF TEST CASE (if exists)</description>
|
195
|
+
</test-case>
|
196
|
+
<test>
|
197
|
+
<name>TEST NAME</name>
|
198
|
+
<description>DESCRIPTION OF TEST CASE (if exists)</description>
|
199
|
+
<option><!-- ATTRIBUTE INFORMATION (if exists) -->
|
200
|
+
<name>ATTRIBUTE NAME (e.g.: bug)</name>
|
201
|
+
<value>ATTRIBUTE VALUE (e.g.: 1234)</value>
|
202
|
+
</option>
|
203
|
+
<option>
|
204
|
+
...
|
205
|
+
</option>
|
206
|
+
</test>
|
207
|
+
<status>TEST RESULT ([success|failure|error|pending|notification])</status>
|
208
|
+
<detail>DETAIL OF TEST RESULT (if exists)</detail>
|
209
|
+
<backtrace><!-- BACKTRACE (if exists) -->
|
210
|
+
<entry>
|
211
|
+
<file>FILE NAME</file>
|
212
|
+
<line>LINE</line>
|
213
|
+
<info>ADDITIONAL INFORMATION</info>
|
214
|
+
</entry>
|
215
|
+
<entry>
|
216
|
+
...
|
217
|
+
</entry>
|
218
|
+
</backtrace>
|
219
|
+
<elapsed>ELAPSED TIME (e.g.: 0.000010)</elapsed>
|
220
|
+
</result>
|
221
|
+
<result>
|
222
|
+
...
|
223
|
+
</result>
|
224
|
+
...
|
225
|
+
</report>
|
226
|
+
|
49
227
|
== Thanks
|
50
228
|
|
51
229
|
* ...
|
data/README.ja
CHANGED
@@ -14,9 +14,12 @@ TestUnitExtはいくつかの有用な機能を提供します。
|
|
14
14
|
|
15
15
|
* Emacsにやさしいバックトレースフォーマット
|
16
16
|
* 優先度に応じたテストの実行
|
17
|
-
*
|
17
|
+
* 各テストへの属性の付加
|
18
18
|
* テストを途中終了(Ctrl+C)しても結果を表示
|
19
19
|
* 色付き出力
|
20
|
+
* テスト結果のdiff出力
|
21
|
+
* テスト結果のXMLでの出力
|
22
|
+
* 保留(pending)・通知(notification)用メソッドの追加
|
20
23
|
|
21
24
|
== 作者
|
22
25
|
|
@@ -42,10 +45,185 @@ Ruby's.
|
|
42
45
|
|
43
46
|
require 'test-unit-ext'
|
44
47
|
|
45
|
-
|
48
|
+
== リファレンス
|
46
49
|
|
47
50
|
=== 属性
|
48
51
|
|
52
|
+
テストに属性を加えて、テスト失敗時により有益な情報を利用する
|
53
|
+
ことができます。例えば、以下のようにテストにBug IDの情報を付
|
54
|
+
加することができます。
|
55
|
+
|
56
|
+
class MyTest < Test::Unit::TestCase
|
57
|
+
bug 123
|
58
|
+
def test_invalid_input
|
59
|
+
assert_equal("OK", input)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
この例では、test_invalid_inputテストがBug #123のテストである
|
64
|
+
という情報を付加しています。
|
65
|
+
|
66
|
+
これは以下のように書くこともできます。
|
67
|
+
|
68
|
+
class MyTest < Test::Unit::TestCase
|
69
|
+
attribute :bug, 123
|
70
|
+
def test_invalid_input
|
71
|
+
assert_equal("OK", input)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
つまり、bugメソッドは便利のために用意されたメソッドです。
|
76
|
+
attributeメソッドを使うことで任意の属性を付加することができ
|
77
|
+
ます。
|
78
|
+
|
79
|
+
=== 優先度
|
80
|
+
|
81
|
+
テストが多くなるとテスト時間が長くなり、テストと開発をリズム
|
82
|
+
良く繰り返すことが難しくなります。それを軽減するために、開発
|
83
|
+
時のテストでは毎回全てのテストを実行するのではなく、一部のテ
|
84
|
+
ストのみ実行して1回のテスト時間を短くすることができます。問題
|
85
|
+
は各テストでどのテストを実行するかです。
|
86
|
+
|
87
|
+
TestUnitExtでは属性としてテストに優先度を付け、それに従って毎
|
88
|
+
回実行するテストを確率的に選択します。コマンドラインオプショ
|
89
|
+
ンで--priorityを指定するとこの機能が有効になります。
|
90
|
+
|
91
|
+
優先度が高いテスト程高い確率で実行され、そうではないテストは
|
92
|
+
低い頻度で実行されます。各テストでは全てのテストは実行しない
|
93
|
+
が、各テストで実行するテストがその都度変わるため、何度も走ら
|
94
|
+
せることにより結果的にテスト全体を実行することになります。
|
95
|
+
|
96
|
+
また、前回成功しなかったテストは確実に実行するため、明示的に
|
97
|
+
優先度を上げなくても失敗している(現在注目すべき重要な)テス
|
98
|
+
トは毎回必ず実行します。これにより、プログラマの負荷をあげる
|
99
|
+
ことなくテストのメリットを受けたまま、テストと開発のリズムを
|
100
|
+
保つことができます。
|
101
|
+
|
102
|
+
優先度は以下のように指定します。優先度指定はpublicやprivateの
|
103
|
+
ように、以降のメソッド定義に影響します。
|
104
|
+
|
105
|
+
class MyTest < Test::Unit::TestCase
|
106
|
+
priority :must
|
107
|
+
def test_must
|
108
|
+
# 必ず実行
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_must2
|
112
|
+
# これも必ず実行
|
113
|
+
end
|
114
|
+
|
115
|
+
priority :import
|
116
|
+
def test_import
|
117
|
+
# 高い確率で実行
|
118
|
+
end
|
119
|
+
|
120
|
+
priority :high
|
121
|
+
def test_high
|
122
|
+
# やや高い確率で実行
|
123
|
+
end
|
124
|
+
|
125
|
+
priority :normal
|
126
|
+
def test_normal
|
127
|
+
# 半々の確率で実行
|
128
|
+
# 優先度を指定していないときはnormal
|
129
|
+
end
|
130
|
+
|
131
|
+
priority :low
|
132
|
+
def test_low
|
133
|
+
# たまに実行
|
134
|
+
end
|
135
|
+
|
136
|
+
priority :never
|
137
|
+
def test_never
|
138
|
+
# 実行しない
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
=== 保留
|
143
|
+
|
144
|
+
現在はまだ実装していない機能をテストとして書くことも場合もあ
|
145
|
+
ります。その場合、まだ実装していない機能のテストは失敗します。
|
146
|
+
たしかにテストは失敗なのですが、そのテストは「実装が間違って
|
147
|
+
いる」ではなく、「まだ実装していない」を意図しています。これ
|
148
|
+
を明示的に表現するために新しくpendというメソッドを用意してい
|
149
|
+
ます。
|
150
|
+
|
151
|
+
「現在はまだ実装していない」という場合はこのメソッドを使って、
|
152
|
+
その意図をコードで表現してください。
|
153
|
+
|
154
|
+
class MyTest < Test::Unit::TestCase
|
155
|
+
def test_minor_function
|
156
|
+
pend("Should implement")
|
157
|
+
assert_equal("Good!", MyModule.minor_function)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
=== 通知
|
162
|
+
|
163
|
+
テスト中で何らかのメッセージを残したいことがあります。例えば、
|
164
|
+
「この環境では○○モジュールがないからこのテストは省略しま
|
165
|
+
す」、という場合です。
|
166
|
+
|
167
|
+
それらのメッセージをputsで表示することもできますが、テスト結
|
168
|
+
果の表示が乱れてしまいます。これを防ぐために、新しくnotifyメ
|
169
|
+
ソッドを用意しています。notifyを使うとメッセージはその場では
|
170
|
+
表示されず、テスト終了後に他の「失敗」や「エラー」などと同じ
|
171
|
+
ように表示されます。これにより、テスト結果の表示を乱さずにメッ
|
172
|
+
セージを残すことができます。
|
173
|
+
|
174
|
+
class MyTest < Test::Unit::TestCase
|
175
|
+
def test_with_other_module
|
176
|
+
unless MyModule.have_XXX?
|
177
|
+
notify("XXX module isn't found. skip this test.")
|
178
|
+
return
|
179
|
+
end
|
180
|
+
assert_equal("XXX Module!!!", MyModule.use_XXX)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
=== XML出力
|
185
|
+
|
186
|
+
--xml-reportオプションを指定することでテスト結果をXML形式で出
|
187
|
+
力することができます。出力されるXMLは以下のような構造になって
|
188
|
+
います。
|
189
|
+
|
190
|
+
<report>
|
191
|
+
<result>
|
192
|
+
<test-case>
|
193
|
+
<name>テストケース名</name>
|
194
|
+
<description>テストケースの説明(もしあれば)</description>
|
195
|
+
</test-case>
|
196
|
+
<test>
|
197
|
+
<name>テスト名</name>
|
198
|
+
<description>テストの説明(もしあれば)</description>
|
199
|
+
<option><!-- 属性情報(もしあれば) -->
|
200
|
+
<name>属性名(例: bug)</name>
|
201
|
+
<value>属性値(例: 1234)</value>
|
202
|
+
</option>
|
203
|
+
<option>
|
204
|
+
...
|
205
|
+
</option>
|
206
|
+
</test>
|
207
|
+
<status>テスト結果([success|failure|error|pending|notification])</status>
|
208
|
+
<detail>テスト結果の詳細(もしあれば)</detail>
|
209
|
+
<backtrace><!-- バックトレース(もしあれば) -->
|
210
|
+
<entry>
|
211
|
+
<file>ファイル名</file>
|
212
|
+
<line>行</line>
|
213
|
+
<info>付加情報</info>
|
214
|
+
</entry>
|
215
|
+
<entry>
|
216
|
+
...
|
217
|
+
</entry>
|
218
|
+
</backtrace>
|
219
|
+
<elapsed>実行時間(例: 0.000010)</elapsed>
|
220
|
+
</result>
|
221
|
+
<result>
|
222
|
+
...
|
223
|
+
</result>
|
224
|
+
...
|
225
|
+
</report>
|
226
|
+
|
49
227
|
== 感謝
|
50
228
|
|
51
229
|
* ...
|
data/html/news.html
CHANGED
@@ -9,16 +9,7 @@
|
|
9
9
|
</head>
|
10
10
|
<body>
|
11
11
|
<h1><a name="label-0" id="label-0">NEWS</a></h1><!-- RDLabel: "NEWS" -->
|
12
|
-
<h2><a name="label-1" id="label-1">0.
|
13
|
-
<ul>
|
14
|
-
<li>Changed XML report format.</li>
|
15
|
-
</ul>
|
16
|
-
<h2><a name="label-2" id="label-2">0.3.0: 2008-03-10</a></h2><!-- RDLabel: "0.3.0: 2008-03-10" -->
|
17
|
-
<ul>
|
18
|
-
<li>Changed XML report format.</li>
|
19
|
-
<li>Improved search method to find test result directory.</li>
|
20
|
-
</ul>
|
21
|
-
<h2><a name="label-3" id="label-3">0.2.0: 2008-03-03</a></h2><!-- RDLabel: "0.2.0: 2008-03-03" -->
|
12
|
+
<h2><a name="label-1" id="label-1">0.2.0: 2008-03-03</a></h2><!-- RDLabel: "0.2.0: 2008-03-03" -->
|
22
13
|
<ul>
|
23
14
|
<li>Supported XML report.
|
24
15
|
<ul>
|
@@ -26,7 +17,7 @@
|
|
26
17
|
</ul></li>
|
27
18
|
<li>Supported diff output for assert_equal.</li>
|
28
19
|
</ul>
|
29
|
-
<h2><a name="label-
|
20
|
+
<h2><a name="label-2" id="label-2">0.1.0: 2008-02-21</a></h2><!-- RDLabel: "0.1.0: 2008-02-21" -->
|
30
21
|
<ul>
|
31
22
|
<li>Initial release.</li>
|
32
23
|
</ul>
|
data/html/news.html.en
CHANGED
@@ -9,16 +9,7 @@
|
|
9
9
|
</head>
|
10
10
|
<body>
|
11
11
|
<h1><a name="label-0" id="label-0">NEWS</a></h1><!-- RDLabel: "NEWS" -->
|
12
|
-
<h2><a name="label-1" id="label-1">0.
|
13
|
-
<ul>
|
14
|
-
<li>Changed XML report format.</li>
|
15
|
-
</ul>
|
16
|
-
<h2><a name="label-2" id="label-2">0.3.0: 2008-03-10</a></h2><!-- RDLabel: "0.3.0: 2008-03-10" -->
|
17
|
-
<ul>
|
18
|
-
<li>Changed XML report format.</li>
|
19
|
-
<li>Improved search method to find test result directory.</li>
|
20
|
-
</ul>
|
21
|
-
<h2><a name="label-3" id="label-3">0.2.0: 2008-03-03</a></h2><!-- RDLabel: "0.2.0: 2008-03-03" -->
|
12
|
+
<h2><a name="label-1" id="label-1">0.2.0: 2008-03-03</a></h2><!-- RDLabel: "0.2.0: 2008-03-03" -->
|
22
13
|
<ul>
|
23
14
|
<li>Supported XML report.
|
24
15
|
<ul>
|
@@ -26,7 +17,7 @@
|
|
26
17
|
</ul></li>
|
27
18
|
<li>Supported diff output for assert_equal.</li>
|
28
19
|
</ul>
|
29
|
-
<h2><a name="label-
|
20
|
+
<h2><a name="label-2" id="label-2">0.1.0: 2008-02-21</a></h2><!-- RDLabel: "0.1.0: 2008-02-21" -->
|
30
21
|
<ul>
|
31
22
|
<li>Initial release.</li>
|
32
23
|
</ul>
|
data/html/news.html.ja
CHANGED
@@ -9,16 +9,7 @@
|
|
9
9
|
</head>
|
10
10
|
<body>
|
11
11
|
<h1><a name="label-0" id="label-0">NEWS.ja</a></h1><!-- RDLabel: "NEWS.ja" -->
|
12
|
-
<h2><a name="label-1" id="label-1">0.
|
13
|
-
<ul>
|
14
|
-
<li>XML出力形式の変更</li>
|
15
|
-
</ul>
|
16
|
-
<h2><a name="label-2" id="label-2">0.3.0: 2008-03-10</a></h2><!-- RDLabel: "0.3.0: 2008-03-10" -->
|
17
|
-
<ul>
|
18
|
-
<li>XML出力形式の変更</li>
|
19
|
-
<li>テスト結果を保存するディレクトリの検索処理を改良</li>
|
20
|
-
</ul>
|
21
|
-
<h2><a name="label-3" id="label-3">0.2.0: 2008-03-03</a></h2><!-- RDLabel: "0.2.0: 2008-03-03" -->
|
12
|
+
<h2><a name="label-1" id="label-1">0.2.0: 2008-03-03</a></h2><!-- RDLabel: "0.2.0: 2008-03-03" -->
|
22
13
|
<ul>
|
23
14
|
<li>XML出力のサポート。
|
24
15
|
<ul>
|
@@ -26,7 +17,7 @@
|
|
26
17
|
</ul></li>
|
27
18
|
<li>assert_equal時のdiff出力のサポート。</li>
|
28
19
|
</ul>
|
29
|
-
<h2><a name="label-
|
20
|
+
<h2><a name="label-2" id="label-2">0.1.0: 2008-02-21</a></h2><!-- RDLabel: "0.1.0: 2008-02-21" -->
|
30
21
|
<ul>
|
31
22
|
<li>最初のリリース。</li>
|
32
23
|
</ul>
|
data/html/readme.html
CHANGED
@@ -32,7 +32,7 @@
|
|
32
32
|
<h2><a name="label-7" id="label-7">Usage</a></h2><!-- RDLabel: "Usage" -->
|
33
33
|
<pre>require 'test-unit-ext'</pre>
|
34
34
|
<h3><a name="label-8" id="label-8">Priority</a></h3><!-- RDLabel: "Priority" -->
|
35
|
-
<h3><a name="label-9" id="label-9">
|
35
|
+
<h3><a name="label-9" id="label-9">Metadata</a></h3><!-- RDLabel: "Metadata" -->
|
36
36
|
<h2><a name="label-10" id="label-10">Thanks</a></h2><!-- RDLabel: "Thanks" -->
|
37
37
|
<ul>
|
38
38
|
<li>...</li>
|
data/html/readme.html.en
CHANGED
@@ -32,7 +32,7 @@
|
|
32
32
|
<h2><a name="label-7" id="label-7">Usage</a></h2><!-- RDLabel: "Usage" -->
|
33
33
|
<pre>require 'test-unit-ext'</pre>
|
34
34
|
<h3><a name="label-8" id="label-8">Priority</a></h3><!-- RDLabel: "Priority" -->
|
35
|
-
<h3><a name="label-9" id="label-9">
|
35
|
+
<h3><a name="label-9" id="label-9">Metadata</a></h3><!-- RDLabel: "Metadata" -->
|
36
36
|
<h2><a name="label-10" id="label-10">Thanks</a></h2><!-- RDLabel: "Thanks" -->
|
37
37
|
<ul>
|
38
38
|
<li>...</li>
|
data/html/readme.html.ja
CHANGED
@@ -32,7 +32,7 @@
|
|
32
32
|
<h2><a name="label-7" id="label-7">使用法</a></h2><!-- RDLabel: "使用法" -->
|
33
33
|
<pre>require 'test-unit-ext'</pre>
|
34
34
|
<h3><a name="label-8" id="label-8">優先度</a></h3><!-- RDLabel: "優先度" -->
|
35
|
-
<h3><a name="label-9" id="label-9"
|
35
|
+
<h3><a name="label-9" id="label-9">メタデータ</a></h3><!-- RDLabel: "メタデータ" -->
|
36
36
|
<h2><a name="label-10" id="label-10">感謝</a></h2><!-- RDLabel: "感謝" -->
|
37
37
|
<ul>
|
38
38
|
<li>...</li>
|
data/lib/test-unit-ext.rb
CHANGED
@@ -5,9 +5,11 @@ require "test-unit-ext/color"
|
|
5
5
|
require "test-unit-ext/colorized-runner"
|
6
6
|
require "test-unit-ext/diff"
|
7
7
|
require "test-unit-ext/always-show-result"
|
8
|
+
require "test-unit-ext/attributes"
|
8
9
|
require "test-unit-ext/priority"
|
9
10
|
require "test-unit-ext/backtrace-filter"
|
10
11
|
require "test-unit-ext/long-display-for-emacs"
|
11
|
-
require "test-unit-ext/attributes"
|
12
12
|
require "test-unit-ext/xml-report"
|
13
13
|
require "test-unit-ext/assertions"
|
14
|
+
require "test-unit-ext/pending"
|
15
|
+
require "test-unit-ext/notification"
|
@@ -11,9 +11,9 @@ module Test
|
|
11
11
|
diff = Diff.readable(expected, actual)
|
12
12
|
if /^[\?\-\+].{79}/ =~ diff
|
13
13
|
folded_diff = Diff.readable(fold(expected), fold(actual))
|
14
|
-
diff = "#{diff}\nfolded diff:\n#{folded_diff}"
|
14
|
+
diff = "#{diff}\n\nfolded diff:\n#{folded_diff}"
|
15
15
|
end
|
16
|
-
raise $!, "#{$!.message}\ndiff:\n#{diff}", $@
|
16
|
+
raise $!, "#{$!.message}\n\ndiff:\n#{diff}", $@
|
17
17
|
end
|
18
18
|
|
19
19
|
def fold(string)
|
@@ -8,15 +8,25 @@ module Test
|
|
8
8
|
def method_added(name)
|
9
9
|
method_added_without_attributes(name)
|
10
10
|
if defined?(@current_attributes)
|
11
|
-
|
12
|
-
|
11
|
+
attributes = {}
|
12
|
+
kept_attributes = {}
|
13
|
+
@current_attributes.each do |attribute_name, attribute|
|
14
|
+
attributes[attribute_name] = attribute[:value]
|
15
|
+
kept_attributes[attribute_name] = attribute if attribute[:keep]
|
16
|
+
end
|
17
|
+
set_attributes(name, attributes)
|
18
|
+
@current_attributes = kept_attributes
|
13
19
|
end
|
14
20
|
end
|
15
21
|
|
16
|
-
def attribute(name, value, *tests)
|
22
|
+
def attribute(name, value, options={}, *tests)
|
23
|
+
unless options.is_a?(Hash)
|
24
|
+
tests << options
|
25
|
+
options = {}
|
26
|
+
end
|
17
27
|
@current_attributes ||= {}
|
18
28
|
if tests.empty?
|
19
|
-
@current_attributes[name] = value
|
29
|
+
@current_attributes[name] = options.merge(:value => value)
|
20
30
|
else
|
21
31
|
tests.each do |test|
|
22
32
|
set_attribute(test, {name => value})
|
@@ -41,6 +51,11 @@ module Test
|
|
41
51
|
@attributes ||= {}
|
42
52
|
@attributes[test_name]
|
43
53
|
end
|
54
|
+
|
55
|
+
private
|
56
|
+
def normalize_test_name(test_name)
|
57
|
+
"test_#{test_name.to_s.sub(/^test_/, '')}"
|
58
|
+
end
|
44
59
|
end
|
45
60
|
|
46
61
|
alias_method :run_without_attributes, :run
|
@@ -11,6 +11,8 @@ module Test
|
|
11
11
|
:default => {
|
12
12
|
"success" => Color.new("green", :bold => true),
|
13
13
|
"failure" => Color.new("red", :bold => true),
|
14
|
+
"pending" => Color.new("magenta", :bold => true),
|
15
|
+
"notification" => Color.new("cyan", :bold => true),
|
14
16
|
"error" => Color.new("yellow", :bold => true),
|
15
17
|
},
|
16
18
|
}
|
@@ -59,7 +61,13 @@ module Test
|
|
59
61
|
|
60
62
|
def result_color
|
61
63
|
if @result.passed?
|
62
|
-
@
|
64
|
+
if @result.pending_count > 0
|
65
|
+
@color_scheme["pending"]
|
66
|
+
elsif @result.notification_count > 0
|
67
|
+
@color_scheme["notification"]
|
68
|
+
else
|
69
|
+
@color_scheme["success"]
|
70
|
+
end
|
63
71
|
elsif @result.error_count > 0
|
64
72
|
@color_scheme["error"]
|
65
73
|
elsif @result.failure_count > 0
|
@@ -85,6 +93,7 @@ module Test
|
|
85
93
|
end
|
86
94
|
|
87
95
|
def guess_color_availability
|
96
|
+
return false unless @io.tty?
|
88
97
|
term = ENV["TERM"]
|
89
98
|
return true if term and (/term\z/ =~ term or term == "screen")
|
90
99
|
return true if ENV["EMACS"] == "t"
|
data/lib/test-unit-ext/diff.rb
CHANGED
@@ -153,9 +153,9 @@ module Test
|
|
153
153
|
best_from, best_to, best_size = best_info
|
154
154
|
while best_from > from_start and best_to > to_start and
|
155
155
|
(should_junk ?
|
156
|
-
@junks.has_key?(@to[best_to]) :
|
157
|
-
!@junks.has_key?(@to[best_to])) and
|
158
|
-
@from[best_from] == @to[best_to]
|
156
|
+
@junks.has_key?(@to[best_to - 1]) :
|
157
|
+
!@junks.has_key?(@to[best_to - 1])) and
|
158
|
+
@from[best_from - 1] == @to[best_to - 1]
|
159
159
|
best_from -= 1
|
160
160
|
best_to -= 1
|
161
161
|
best_size += 1
|
@@ -174,27 +174,31 @@ module Test
|
|
174
174
|
end
|
175
175
|
|
176
176
|
def matches
|
177
|
-
|
178
|
-
queue = [[0, @from.size
|
177
|
+
indexed_matches = []
|
178
|
+
queue = [[0, @from.size, 0, @to.size]]
|
179
179
|
until queue.empty?
|
180
180
|
from_start, from_end, to_start, to_end = queue.pop
|
181
|
-
match = longest_match(from_start, from_end, to_start, to_end)
|
181
|
+
match = longest_match(from_start, from_end - 1, to_start, to_end - 1)
|
182
182
|
match_from_index, match_to_index, size = match
|
183
183
|
unless size.zero?
|
184
|
-
_matches << match
|
185
184
|
if from_start < match_from_index and
|
186
185
|
to_start < match_to_index
|
187
|
-
queue.push([from_start, match_from_index
|
188
|
-
to_start, match_to_index
|
186
|
+
queue.push([from_start, match_from_index,
|
187
|
+
to_start, match_to_index])
|
189
188
|
end
|
190
|
-
|
191
|
-
|
189
|
+
indexed_matches << [match_from_index, match]
|
190
|
+
if match_from_index + size < from_end and
|
191
|
+
match_to_index + size < to_end
|
192
192
|
queue.push([match_from_index + size, from_end,
|
193
193
|
match_to_index + size, to_end])
|
194
194
|
end
|
195
195
|
end
|
196
196
|
end
|
197
|
-
|
197
|
+
indexed_matches.sort_by do |index, match|
|
198
|
+
index
|
199
|
+
end.collect do |index, match|
|
200
|
+
match
|
201
|
+
end
|
198
202
|
end
|
199
203
|
|
200
204
|
def determine_tag(from_index, to_index,
|
@@ -278,6 +282,10 @@ module Test
|
|
278
282
|
tag(" ", contents)
|
279
283
|
end
|
280
284
|
|
285
|
+
def tag_difference(contents)
|
286
|
+
tag("? ", contents)
|
287
|
+
end
|
288
|
+
|
281
289
|
def diff_lines(from_start, from_end, to_start, to_end)
|
282
290
|
best_ratio, cut_off = 0.74, 0.75
|
283
291
|
from_equal_index = to_equal_index = nil
|
@@ -368,9 +376,13 @@ module Test
|
|
368
376
|
to_tags = to_tags[common..-1].rstrip
|
369
377
|
|
370
378
|
result = tag_deleted([from_line])
|
371
|
-
|
379
|
+
unless from_tags.empty?
|
380
|
+
result.concat(tag_difference(["#{"\t" * common}#{from_tags}"]))
|
381
|
+
end
|
372
382
|
result.concat(tag_inserted([to_line]))
|
373
|
-
|
383
|
+
unless to_tags.empty?
|
384
|
+
result.concat(tag_difference(["#{"\t" * common}#{to_tags}"]))
|
385
|
+
end
|
374
386
|
result
|
375
387
|
end
|
376
388
|
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Test
|
2
|
+
module Unit
|
3
|
+
class TestResult
|
4
|
+
attr_reader :notifications
|
5
|
+
|
6
|
+
alias_method(:initialize_without_notifications, :initialize)
|
7
|
+
def initialize
|
8
|
+
initialize_without_notifications
|
9
|
+
@notifications = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_notification(notification)
|
13
|
+
@notifications << notification
|
14
|
+
notify_listeners(FAULT, notification)
|
15
|
+
notify_listeners(CHANGED, self)
|
16
|
+
end
|
17
|
+
|
18
|
+
def notification_count
|
19
|
+
@notifications.size
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method(:to_s_without_notifications, :to_s)
|
23
|
+
def to_s
|
24
|
+
to_s_without_notifications + ", #{notification_count} notifications"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Notification
|
29
|
+
attr_reader :test_name, :location, :message
|
30
|
+
|
31
|
+
SINGLE_CHARACTER = 'N'
|
32
|
+
|
33
|
+
# Creates a new Notification with the given location and
|
34
|
+
# message.
|
35
|
+
def initialize(test_name, location, message)
|
36
|
+
@test_name = test_name
|
37
|
+
@location = location
|
38
|
+
@message = message
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns a single character representation of a notification.
|
42
|
+
def single_character_display
|
43
|
+
SINGLE_CHARACTER
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns a brief version of the error description.
|
47
|
+
def short_display
|
48
|
+
"#@test_name: #{@message.split("\n")[0]}"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns a verbose version of the error description.
|
52
|
+
def long_display
|
53
|
+
if location.size == 1
|
54
|
+
location_display = location[0].sub(/\A(.+:\d+).*/, ' [\\1]')
|
55
|
+
else
|
56
|
+
location_display = "\n" + location.join("\n")
|
57
|
+
end
|
58
|
+
"Notification:\n#{@test_name}#{location_display}:\n#{@message}"
|
59
|
+
end
|
60
|
+
|
61
|
+
# Overridden to return long_display.
|
62
|
+
def to_s
|
63
|
+
long_display
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class NotifiedError < StandardError
|
68
|
+
end
|
69
|
+
|
70
|
+
module AssertionsWithNotify
|
71
|
+
def notify(message)
|
72
|
+
notification = Notification.new(name, caller[0, 1], message)
|
73
|
+
@_result.add_notification(notification)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class TestCase
|
78
|
+
include AssertionsWithNotify
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Test
|
2
|
+
module Unit
|
3
|
+
class TestResult
|
4
|
+
attr_reader :pendings
|
5
|
+
|
6
|
+
alias_method(:initialize_without_pendings, :initialize)
|
7
|
+
def initialize
|
8
|
+
initialize_without_pendings
|
9
|
+
@pendings = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_pending(pending)
|
13
|
+
@pendings << pending
|
14
|
+
notify_listeners(FAULT, pending)
|
15
|
+
notify_listeners(CHANGED, self)
|
16
|
+
end
|
17
|
+
|
18
|
+
def pending_count
|
19
|
+
@pendings.size
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method(:to_s_without_pendings, :to_s)
|
23
|
+
def to_s
|
24
|
+
to_s_without_pendings + ", #{pending_count} pendings"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Pending
|
29
|
+
attr_reader :test_name, :location, :message
|
30
|
+
|
31
|
+
SINGLE_CHARACTER = 'P'
|
32
|
+
|
33
|
+
# Creates a new Pending with the given location and
|
34
|
+
# message.
|
35
|
+
def initialize(test_name, location, message)
|
36
|
+
@test_name = test_name
|
37
|
+
@location = location
|
38
|
+
@message = message
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns a single character representation of a pending.
|
42
|
+
def single_character_display
|
43
|
+
SINGLE_CHARACTER
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns a brief version of the error description.
|
47
|
+
def short_display
|
48
|
+
"#@test_name: #{@message.split("\n")[0]}"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns a verbose version of the error description.
|
52
|
+
def long_display
|
53
|
+
if location.size == 1
|
54
|
+
location_display = location[0].sub(/\A(.+:\d+).*/, ' [\\1]')
|
55
|
+
else
|
56
|
+
location_display = "\n" + location.join("\n")
|
57
|
+
end
|
58
|
+
"Pending:\n#{@test_name}#{location_display}:\n#{@message}"
|
59
|
+
end
|
60
|
+
|
61
|
+
# Overridden to return long_display.
|
62
|
+
def to_s
|
63
|
+
long_display
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class PendedError < StandardError
|
68
|
+
end
|
69
|
+
|
70
|
+
module AssertionsWithPend
|
71
|
+
def pend(message="Pended", &block)
|
72
|
+
if block_given?
|
73
|
+
begin
|
74
|
+
yield
|
75
|
+
rescue Exception
|
76
|
+
raise PendedError, message, $!.backtrace
|
77
|
+
end
|
78
|
+
flunk("Pending block should not be passed: #{message}")
|
79
|
+
else
|
80
|
+
raise PendedError.new(message)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class TestCase
|
86
|
+
include AssertionsWithPend
|
87
|
+
|
88
|
+
alias_method(:add_error_without_pending, :add_error)
|
89
|
+
def add_error(exception)
|
90
|
+
if exception.is_a?(PendedError)
|
91
|
+
pending = Pending.new(name, exception.backtrace, exception.message)
|
92
|
+
@_result.add_pending(pending)
|
93
|
+
else
|
94
|
+
add_error_without_pending(exception)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -3,52 +3,23 @@ require "test/unit"
|
|
3
3
|
require "fileutils"
|
4
4
|
require "tmpdir"
|
5
5
|
|
6
|
+
require "test-unit-ext/attributes"
|
7
|
+
|
6
8
|
module Test
|
7
9
|
module Unit
|
8
10
|
class TestCase
|
9
11
|
class << self
|
10
|
-
def inherited(sub)
|
11
|
-
super
|
12
|
-
sub.instance_variable_set("@priority_initialized", true)
|
13
|
-
sub.instance_variable_set("@priority_table", {})
|
14
|
-
sub.priority :normal
|
15
|
-
end
|
16
|
-
|
17
|
-
def include(*args)
|
18
|
-
args.reverse_each do |mod|
|
19
|
-
super(mod)
|
20
|
-
next unless defined?(@priority_initialized)
|
21
|
-
mod.instance_methods(false).each do |name|
|
22
|
-
set_priority(name)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
alias_method :method_added_without_priority, :method_added
|
28
|
-
def method_added(name)
|
29
|
-
method_added_without_priority(name)
|
30
|
-
set_priority(name) if defined?(@priority_initialized)
|
31
|
-
end
|
32
|
-
|
33
12
|
def priority(name, *tests)
|
34
13
|
singleton_class = (class << self; self; end)
|
35
14
|
priority_check_method = priority_check_method_name(name)
|
36
15
|
unless singleton_class.private_method_defined?(priority_check_method)
|
37
16
|
raise ArgumentError, "unknown priority: #{name}"
|
38
17
|
end
|
39
|
-
|
40
|
-
@current_priority = name
|
41
|
-
else
|
42
|
-
tests.each do |test|
|
43
|
-
set_priority(test, name)
|
44
|
-
end
|
45
|
-
end
|
18
|
+
attribute(:priority, name, {:keep => true}, *tests)
|
46
19
|
end
|
47
20
|
|
48
21
|
def need_to_run?(test_name)
|
49
|
-
|
50
|
-
priority = @priority_table[normalized_test_name]
|
51
|
-
return true unless priority
|
22
|
+
priority = (attributes(test_name) || {})[:priority] || :normal
|
52
23
|
__send__(priority_check_method_name(priority), test_name)
|
53
24
|
end
|
54
25
|
|
@@ -57,10 +28,6 @@ module Test
|
|
57
28
|
"run_priority_#{priority_name}?"
|
58
29
|
end
|
59
30
|
|
60
|
-
def normalize_test_name(test_name)
|
61
|
-
"test_#{test_name.to_s.sub(/^test_/, '')}"
|
62
|
-
end
|
63
|
-
|
64
31
|
def set_priority(name, priority=@current_priority)
|
65
32
|
@priority_table[normalize_test_name(name)] = priority
|
66
33
|
end
|
data/test/test_attributes.rb
CHANGED
@@ -74,6 +74,7 @@ class TestAttributes < Test::Unit::TestCase
|
|
74
74
|
"#{__FILE__}:#{first_arg_end_line}:in `#{method_name}':\n" \
|
75
75
|
"<2> expected but was\n" \
|
76
76
|
"<1>.\n" \
|
77
|
+
"\n" \
|
77
78
|
"diff:\n" \
|
78
79
|
"- 2\n" \
|
79
80
|
"+ 1",
|
@@ -84,6 +85,7 @@ class TestAttributes < Test::Unit::TestCase
|
|
84
85
|
"#{__FILE__}:#{first_arg_end_line}:in `#{method_name}':\n" \
|
85
86
|
"<0> expected but was\n" \
|
86
87
|
"<11>.\n" \
|
88
|
+
"\n" \
|
87
89
|
"diff:\n" \
|
88
90
|
"- 0\n" \
|
89
91
|
"+ 11"],
|
@@ -101,6 +103,7 @@ class TestAttributes < Test::Unit::TestCase
|
|
101
103
|
"#{__FILE__}:#{first_arg_end_line}:in `#{method_name}':\n" \
|
102
104
|
"<1> expected but was\n" \
|
103
105
|
"<12>.\n" \
|
106
|
+
"\n" \
|
104
107
|
"diff:\n" \
|
105
108
|
"- 1\n" \
|
106
109
|
"+ 12"],
|
data/test/test_diff.rb
CHANGED
@@ -72,6 +72,24 @@ class TestDiff < Test::Unit::TestCase
|
|
72
72
|
[:equal, 4, 6, 3, 5],
|
73
73
|
[:insert, 6, 6, 5, 6]],
|
74
74
|
"qabxcd", "abycdf")
|
75
|
+
|
76
|
+
assert_operations([[:equal, 0, 23, 0, 23],
|
77
|
+
[:replace, 23, 24, 23, 24],
|
78
|
+
[:equal, 24, 35, 24, 35],
|
79
|
+
[:replace, 35, 36, 35, 36],
|
80
|
+
[:equal, 36, 45, 36, 45]],
|
81
|
+
"1 tests, 0 assertions, 1 failures, 0 pendings",
|
82
|
+
"1 tests, 0 assertions, 0 failures, 1 pendings")
|
83
|
+
|
84
|
+
assert_operations([[:equal, 0, 23, 0, 23],
|
85
|
+
[:replace, 23, 24, 23, 24],
|
86
|
+
[:equal, 24, 35, 24, 35],
|
87
|
+
[:replace, 35, 36, 35, 36],
|
88
|
+
[:equal, 36, 45, 36, 45]],
|
89
|
+
"1 tests, 0 assertions, 1 failures, 0 pendings",
|
90
|
+
"1 tests, 0 assertions, 0 failures, 1 pendings") do |x|
|
91
|
+
x == " "[0]
|
92
|
+
end
|
75
93
|
end
|
76
94
|
|
77
95
|
def test_grouped_operations
|
@@ -148,6 +166,15 @@ class TestDiff < Test::Unit::TestCase
|
|
148
166
|
["abcd abcd xyz abc"])
|
149
167
|
end
|
150
168
|
|
169
|
+
def test_difference_readable_diff
|
170
|
+
assert_readable_diff("- 1 tests, 0 assertions, 1 failures, 0 pendings\n" \
|
171
|
+
"? ^ ^\n" \
|
172
|
+
"+ 1 tests, 0 assertions, 0 failures, 1 pendings\n" \
|
173
|
+
"? ^ ^",
|
174
|
+
["1 tests, 0 assertions, 1 failures, 0 pendings"],
|
175
|
+
["1 tests, 0 assertions, 0 failures, 1 pendings"])
|
176
|
+
end
|
177
|
+
|
151
178
|
def test_complex_readable_diff
|
152
179
|
assert_readable_diff(" aaa\n" \
|
153
180
|
"- bbb\n" \
|
@@ -281,6 +308,15 @@ class TestDiff < Test::Unit::TestCase
|
|
281
308
|
assert_equal(expected, matcher.instance_variable_get("@to_indexes"))
|
282
309
|
end
|
283
310
|
|
311
|
+
def assert_find_best_match_position(expected, from, to,
|
312
|
+
from_start, from_end,
|
313
|
+
to_start, to_end, &junk_predicate)
|
314
|
+
matcher = Test::Diff::SequenceMatcher.new(from, to, &junk_predicate)
|
315
|
+
assert_equal(expected, matcher.send(:find_best_match_position,
|
316
|
+
from_start, from_end,
|
317
|
+
to_start, to_end))
|
318
|
+
end
|
319
|
+
|
284
320
|
def assert_longest_match(expected, from, to,
|
285
321
|
from_start, from_end,
|
286
322
|
to_start, to_end, &junk_predicate)
|
@@ -294,8 +330,8 @@ class TestDiff < Test::Unit::TestCase
|
|
294
330
|
assert_equal(expected, matcher.blocks)
|
295
331
|
end
|
296
332
|
|
297
|
-
def assert_operations(expected, from, to)
|
298
|
-
matcher = Test::Diff::SequenceMatcher.new(from, to)
|
333
|
+
def assert_operations(expected, from, to, &junk_predicate)
|
334
|
+
matcher = Test::Diff::SequenceMatcher.new(from, to, &junk_predicate)
|
299
335
|
assert_equal(expected, matcher.operations)
|
300
336
|
end
|
301
337
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'test-unit-ext'
|
2
|
+
|
3
|
+
class TestNotification < Test::Unit::TestCase
|
4
|
+
class TestCase < Test::Unit::TestCase
|
5
|
+
class << self
|
6
|
+
def suite
|
7
|
+
Test::Unit::TestSuite.new(name)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_notify
|
12
|
+
notify("1st notify")
|
13
|
+
notify("2nd notify. Reach here.")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_notify
|
18
|
+
result = run_test("test_notify")
|
19
|
+
assert_equal("1 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, " \
|
20
|
+
"2 notifications",
|
21
|
+
result.to_s)
|
22
|
+
assert_equal(["1st notify", "2nd notify. Reach here."],
|
23
|
+
result.notifications.collect {|n| n.message})
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def run_test(name)
|
28
|
+
result = Test::Unit::TestResult.new
|
29
|
+
TestCase.new(name).run(result) {}
|
30
|
+
result
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'test-unit-ext'
|
2
|
+
|
3
|
+
class TestPending < Test::Unit::TestCase
|
4
|
+
class TestCase < Test::Unit::TestCase
|
5
|
+
class << self
|
6
|
+
def suite
|
7
|
+
Test::Unit::TestSuite.new(name)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_pend
|
12
|
+
pend("1st pend")
|
13
|
+
pend("2nd pend. Not reached here.")
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_pend_with_failure_in_block
|
17
|
+
pend("Wait a minute") do
|
18
|
+
raise "Not implemented yet"
|
19
|
+
end
|
20
|
+
assert(true, "Not reached here.")
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_pend_with_no_failure_in_block
|
24
|
+
pend("Wait a minute") do
|
25
|
+
"Nothing raised"
|
26
|
+
end
|
27
|
+
assert(true, "Reached here.")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_pend
|
32
|
+
result = run_test("test_pend")
|
33
|
+
assert_equal("1 tests, 0 assertions, 0 failures, 0 errors, 1 pendings, " \
|
34
|
+
"0 notifications",
|
35
|
+
result.to_s)
|
36
|
+
assert_equal(["1st pend"],
|
37
|
+
result.pendings.collect {|pending| pending.message})
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_pend_with_failure_in_block
|
41
|
+
result = run_test("test_pend_with_failure_in_block")
|
42
|
+
assert_equal("1 tests, 0 assertions, 0 failures, 0 errors, 1 pendings, " \
|
43
|
+
"0 notifications",
|
44
|
+
result.to_s)
|
45
|
+
assert_equal(["Wait a minute"],
|
46
|
+
result.pendings.collect {|pending| pending.message})
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_pend_with_no_failure_in_block
|
50
|
+
result = run_test("test_pend_with_no_failure_in_block")
|
51
|
+
assert_equal("1 tests, 1 assertions, 1 failures, 0 errors, 0 pendings, " \
|
52
|
+
"0 notifications",
|
53
|
+
result.to_s)
|
54
|
+
assert_equal(["Pending block should not be passed: Wait a minute."],
|
55
|
+
result.failures.collect {|failure| failure.message})
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def run_test(name)
|
60
|
+
result = Test::Unit::TestResult.new
|
61
|
+
TestCase.new(name).run(result) {}
|
62
|
+
result
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'test-unit-ext'
|
2
|
+
|
3
|
+
class TestPriority < Test::Unit::TestCase
|
4
|
+
class TestCase < Test::Unit::TestCase
|
5
|
+
class << self
|
6
|
+
def suite
|
7
|
+
Test::Unit::TestSuite.new(name)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
priority :must
|
12
|
+
def test_must
|
13
|
+
assert(true)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_must_inherited
|
17
|
+
assert(true)
|
18
|
+
end
|
19
|
+
|
20
|
+
priority :important
|
21
|
+
def test_important
|
22
|
+
assert(true)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_important_inherited
|
26
|
+
assert(true)
|
27
|
+
end
|
28
|
+
|
29
|
+
priority :high
|
30
|
+
def test_high
|
31
|
+
assert(true)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_high_inherited
|
35
|
+
assert(true)
|
36
|
+
end
|
37
|
+
|
38
|
+
priority :normal
|
39
|
+
def test_normal
|
40
|
+
assert(true)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_normal_inherited
|
44
|
+
assert(true)
|
45
|
+
end
|
46
|
+
|
47
|
+
priority :low
|
48
|
+
def test_low
|
49
|
+
assert(true)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_low_inherited
|
53
|
+
assert(true)
|
54
|
+
end
|
55
|
+
|
56
|
+
priority :never
|
57
|
+
def test_never
|
58
|
+
assert(true)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_never_inherited
|
62
|
+
assert(true)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_priority
|
67
|
+
assert_priority("must", 1.0, 0.0001)
|
68
|
+
assert_priority("important", 0.9, 0.09)
|
69
|
+
assert_priority("high", 0.70, 0.1)
|
70
|
+
assert_priority("normal", 0.5, 0.1)
|
71
|
+
assert_priority("low", 0.25, 0.1)
|
72
|
+
assert_priority("never", 0.0, 0.0001)
|
73
|
+
end
|
74
|
+
|
75
|
+
def assert_priority(priority, expected, delta)
|
76
|
+
assert_need_to_run("test_#{priority}", expected, delta)
|
77
|
+
assert_need_to_run("test_#{priority}_inherited", expected, delta)
|
78
|
+
end
|
79
|
+
|
80
|
+
def assert_need_to_run(test_name, expected, delta)
|
81
|
+
n = 1000
|
82
|
+
n_need_to_run = 0
|
83
|
+
n.times do |i|
|
84
|
+
n_need_to_run +=1 if TestCase.need_to_run?(test_name)
|
85
|
+
end
|
86
|
+
assert_in_delta(expected, n_need_to_run.to_f / n, delta)
|
87
|
+
end
|
88
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: test-unit-ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kouhei Sutou
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-04-07 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -47,6 +47,8 @@ files:
|
|
47
47
|
- lib/test-unit-ext/colorized-runner.rb
|
48
48
|
- lib/test-unit-ext/diff.rb
|
49
49
|
- lib/test-unit-ext/long-display-for-emacs.rb
|
50
|
+
- lib/test-unit-ext/notification.rb
|
51
|
+
- lib/test-unit-ext/pending.rb
|
50
52
|
- lib/test-unit-ext/priority.rb
|
51
53
|
- lib/test-unit-ext/version.rb
|
52
54
|
- lib/test-unit-ext/xml-report.rb
|
@@ -55,6 +57,9 @@ files:
|
|
55
57
|
- test/test_attributes.rb
|
56
58
|
- test/test_color.rb
|
57
59
|
- test/test_diff.rb
|
60
|
+
- test/test_notification.rb
|
61
|
+
- test/test_pending.rb
|
62
|
+
- test/test_priority.rb
|
58
63
|
- test/test_xml_report.rb
|
59
64
|
has_rdoc: true
|
60
65
|
homepage: http://test-unit-ext.rubyforge.org/
|
@@ -84,7 +89,10 @@ signing_key:
|
|
84
89
|
specification_version: 2
|
85
90
|
summary: TestUnitExt extends the standard Test::Unit.
|
86
91
|
test_files:
|
92
|
+
- test/test_pending.rb
|
87
93
|
- test/test_diff.rb
|
94
|
+
- test/test_priority.rb
|
95
|
+
- test/test_notification.rb
|
96
|
+
- test/test_attributes.rb
|
88
97
|
- test/test_color.rb
|
89
98
|
- test/test_xml_report.rb
|
90
|
-
- test/test_attributes.rb
|