betatest 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,313 @@
1
+ require "betatest/autorun"
2
+ require_relative 'metametameta'
3
+
4
+ class TestBetatestReporter < Betatest::Test
5
+
6
+ attr_accessor :r, :io
7
+
8
+ def new_composite_reporter
9
+ reporter = Betatest::CompositeReporter.new
10
+ reporter << Betatest::SummaryReporter.new(self.io)
11
+ reporter << Betatest::ProgressReporter.new(self.io)
12
+
13
+ def reporter.first
14
+ reporters.first
15
+ end
16
+
17
+ def reporter.results
18
+ first.results
19
+ end
20
+
21
+ def reporter.count
22
+ first.count
23
+ end
24
+
25
+ def reporter.assertions
26
+ first.assertions
27
+ end
28
+
29
+ reporter
30
+ end
31
+
32
+ def setup
33
+ self.io = StringIO.new("")
34
+ self.r = new_composite_reporter
35
+ end
36
+
37
+ def error_test
38
+ unless defined? @et then
39
+ @et = Betatest::Test.new(:woot)
40
+ @et.failures << Betatest::UnexpectedError.new(begin
41
+ raise "no"
42
+ rescue => e
43
+ e
44
+ end)
45
+ end
46
+ @et
47
+ end
48
+
49
+ def fail_test
50
+ unless defined? @ft then
51
+ @ft = Betatest::Test.new(:woot)
52
+ @ft.failures << begin
53
+ raise Betatest::Assertion, "boo"
54
+ rescue Betatest::Assertion => e
55
+ e
56
+ end
57
+ end
58
+ @ft
59
+ end
60
+
61
+ def passing_test
62
+ @pt ||= Betatest::Test.new(:woot)
63
+ end
64
+
65
+ def skip_test
66
+ unless defined? @st then
67
+ @st = Betatest::Test.new(:woot)
68
+ @st.failures << begin
69
+ raise Betatest::Skip
70
+ rescue Betatest::Assertion => e
71
+ e
72
+ end
73
+ end
74
+ @st
75
+ end
76
+
77
+ def test_passed_eh_empty
78
+ assert r.passed?
79
+ end
80
+
81
+ def test_passed_eh_failure
82
+ r.results << fail_test
83
+
84
+ refute r.passed?
85
+ end
86
+
87
+ SKIP_MSG = "\n\nYou have skipped tests. Run with --verbose for details."
88
+
89
+ def test_passed_eh_error
90
+ r.start
91
+
92
+ r.results << error_test
93
+
94
+ refute r.passed?
95
+
96
+ r.report
97
+
98
+ refute_match SKIP_MSG, io.string
99
+ end
100
+
101
+ def test_passed_eh_skipped
102
+ r.start
103
+ r.results << skip_test
104
+ assert r.passed?
105
+
106
+ restore_env do
107
+ r.report
108
+ end
109
+
110
+ assert_match SKIP_MSG, io.string
111
+ end
112
+
113
+ def test_passed_eh_skipped_verbose
114
+ r.first.options[:verbose] = true
115
+
116
+ r.start
117
+ r.results << skip_test
118
+ assert r.passed?
119
+ r.report
120
+
121
+ refute_match SKIP_MSG, io.string
122
+ end
123
+
124
+ def test_start
125
+ r.start
126
+
127
+ exp = "Run options: \n\n# Running:\n\n"
128
+
129
+ assert_equal exp, io.string
130
+ end
131
+
132
+ def test_record_pass
133
+ r.record passing_test
134
+
135
+ assert_equal ".", io.string
136
+ assert_empty r.results
137
+ assert_equal 1, r.count
138
+ assert_equal 0, r.assertions
139
+ end
140
+
141
+ def test_record_fail
142
+ r.record fail_test
143
+
144
+ assert_equal "F", io.string
145
+ assert_equal [fail_test], r.results
146
+ assert_equal 1, r.count
147
+ assert_equal 0, r.assertions
148
+ end
149
+
150
+ def test_record_error
151
+ r.record error_test
152
+
153
+ assert_equal "E", io.string
154
+ assert_equal [error_test], r.results
155
+ assert_equal 1, r.count
156
+ assert_equal 0, r.assertions
157
+ end
158
+
159
+ def test_record_skip
160
+ r.record skip_test
161
+
162
+ assert_equal "S", io.string
163
+ assert_equal [skip_test], r.results
164
+ assert_equal 1, r.count
165
+ assert_equal 0, r.assertions
166
+ end
167
+
168
+ def normalize_output output
169
+ output.sub!(/Finished in .*/, "Finished in 0.00")
170
+ output.sub!(/Loaded suite .*/, 'Loaded suite blah')
171
+
172
+ output.gsub!(/ = \d+.\d\d s = /, ' = 0.00 s = ')
173
+ output.gsub!(/0x[A-Fa-f0-9]+/, '0xXXX')
174
+ output.gsub!(/ +$/, '')
175
+
176
+ if windows? then
177
+ output.gsub!(/\[(?:[A-Za-z]:)?[^\]:]+:\d+\]/, '[FILE:LINE]')
178
+ output.gsub!(/^(\s+)(?:[A-Za-z]:)?[^:]+:\d+:in/, '\1FILE:LINE:in')
179
+ else
180
+ output.gsub!(/\[[^\]:]+:\d+\]/, '[FILE:LINE]')
181
+ output.gsub!(/^(\s+)[^:]+:\d+:in/, '\1FILE:LINE:in')
182
+ end
183
+
184
+ output
185
+ end
186
+
187
+ def test_report_empty
188
+ r.start
189
+ r.report
190
+
191
+ exp = clean <<-EOM
192
+ Run options:
193
+
194
+ # Running:
195
+
196
+
197
+
198
+ Finished in 0.00
199
+
200
+ 0 runs, 0 assertions, 0 failures, 0 errors, 0 skips
201
+ EOM
202
+
203
+
204
+ assert_equal exp, normalize_output(io.string)
205
+ end
206
+
207
+ def test_report_passing
208
+ r.start
209
+ r.record passing_test
210
+ r.report
211
+
212
+ exp = clean <<-EOM
213
+ Run options:
214
+
215
+ # Running:
216
+
217
+ .
218
+
219
+ Finished in 0.00
220
+
221
+ 1 runs, 0 assertions, 0 failures, 0 errors, 0 skips
222
+ EOM
223
+
224
+
225
+ assert_equal exp, normalize_output(io.string)
226
+ end
227
+
228
+ def test_report_failure
229
+ r.start
230
+ r.record fail_test
231
+ r.report
232
+
233
+ exp = clean <<-EOM
234
+ Run options:
235
+
236
+ # Running:
237
+
238
+ F
239
+
240
+ Finished in 0.00
241
+
242
+ 1) Failure:
243
+ Betatest::Test#woot [FILE:LINE]:
244
+ boo
245
+
246
+ 1 runs, 0 assertions, 1 failures, 0 errors, 0 skips
247
+ EOM
248
+
249
+
250
+ assert_equal exp, normalize_output(io.string)
251
+ end
252
+
253
+ def test_report_error
254
+ r.start
255
+ r.record error_test
256
+ r.report
257
+
258
+ exp = clean <<-EOM
259
+ Run options:
260
+
261
+ # Running:
262
+
263
+ E
264
+
265
+ Finished in 0.00
266
+
267
+ 1) Error:
268
+ Betatest::Test#woot:
269
+ RuntimeError: no
270
+ FILE:LINE:in `error_test'
271
+ FILE:LINE:in `test_report_error'
272
+
273
+ 1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
274
+ EOM
275
+
276
+ assert_equal exp, normalize_output(io.string)
277
+ end
278
+
279
+ def restore_env
280
+ old_value = ENV["MT_NO_SKIP_MSG"]
281
+ ENV.delete "MT_NO_SKIP_MSG"
282
+
283
+ yield
284
+ ensure
285
+ ENV["MT_NO_SKIP_MSG"] = old_value
286
+ end
287
+
288
+
289
+ def test_report_skipped
290
+ r.start
291
+ r.record skip_test
292
+
293
+ restore_env do
294
+ r.report
295
+ end
296
+
297
+ exp = clean <<-EOM
298
+ Run options:
299
+
300
+ # Running:
301
+
302
+ S
303
+
304
+ Finished in 0.00
305
+
306
+ 1 runs, 0 assertions, 0 failures, 0 errors, 1 skips
307
+
308
+ You have skipped tests. Run with --verbose for details.
309
+ EOM
310
+
311
+ assert_equal exp, normalize_output(io.string)
312
+ end
313
+ end
@@ -0,0 +1,832 @@
1
+ # encoding: utf-8
2
+ require "betatest/autorun"
3
+ require "stringio"
4
+
5
+ class MiniSpecA < Betatest::Spec; end
6
+ class MiniSpecB < Betatest::Test; extend Betatest::Spec::DSL; end
7
+ class MiniSpecC < MiniSpecB; end
8
+ class NamedExampleA < MiniSpecA; end
9
+ class NamedExampleB < MiniSpecB; end
10
+ class NamedExampleC < MiniSpecC; end
11
+ class ExampleA; end
12
+ class ExampleB < ExampleA; end
13
+
14
+ describe Betatest::Spec do
15
+ # do not parallelize this suite... it just can"t handle it.
16
+
17
+ def assert_triggered expected = "blah", klass = Betatest::Assertion
18
+ @assertion_count += 2
19
+
20
+ e = assert_raises(klass) do
21
+ yield
22
+ end
23
+
24
+ msg = e.message.sub(/(---Backtrace---).*/m, '\1')
25
+ msg.gsub!(/\(oid=[-0-9]+\)/, "(oid=N)")
26
+
27
+ assert_equal expected, msg
28
+ end
29
+
30
+ before do
31
+ @assertion_count = 4
32
+ end
33
+
34
+ after do
35
+ self.assertions.must_equal @assertion_count if passed? and not skipped?
36
+ end
37
+
38
+ it "needs to be able to catch a Betatest::Assertion exception" do
39
+ @assertion_count = 1
40
+
41
+ assert_triggered "Expected 1 to not be equal to 1." do
42
+ 1.wont_equal 1
43
+ end
44
+ end
45
+
46
+ it "needs to be sensible about must_include order" do
47
+ @assertion_count += 3 # must_include is 2 assertions
48
+
49
+ [1, 2, 3].must_include(2).must_equal true
50
+
51
+ assert_triggered "Expected [1, 2, 3] to include 5." do
52
+ [1, 2, 3].must_include 5
53
+ end
54
+
55
+ assert_triggered "msg.\nExpected [1, 2, 3] to include 5." do
56
+ [1, 2, 3].must_include 5, "msg"
57
+ end
58
+ end
59
+
60
+ it "needs to be sensible about wont_include order" do
61
+ @assertion_count += 3 # wont_include is 2 assertions
62
+
63
+ [1, 2, 3].wont_include(5).must_equal false
64
+
65
+ assert_triggered "Expected [1, 2, 3] to not include 2." do
66
+ [1, 2, 3].wont_include 2
67
+ end
68
+
69
+ assert_triggered "msg.\nExpected [1, 2, 3] to not include 2." do
70
+ [1, 2, 3].wont_include 2, "msg"
71
+ end
72
+ end
73
+
74
+ it "needs to catch an expected exception" do
75
+ @assertion_count = 2
76
+
77
+ proc { raise "blah" }.must_raise RuntimeError
78
+ proc { raise Betatest::Assertion }.must_raise Betatest::Assertion
79
+ end
80
+
81
+ it "needs to catch an unexpected exception" do
82
+ @assertion_count -= 2 # no positive
83
+
84
+ msg = <<-EOM.gsub(/^ {6}/, "").chomp
85
+ [RuntimeError] exception expected, not
86
+ Class: <Betatest::Assertion>
87
+ Message: <"Betatest::Assertion">
88
+ ---Backtrace---
89
+ EOM
90
+
91
+ assert_triggered msg do
92
+ proc { raise Betatest::Assertion }.must_raise RuntimeError
93
+ end
94
+
95
+ assert_triggered "msg.\n#{msg}" do
96
+ proc { raise Betatest::Assertion }.must_raise RuntimeError, "msg"
97
+ end
98
+ end
99
+
100
+ it "needs to ensure silence" do
101
+ @assertion_count -= 1 # no msg
102
+ @assertion_count += 2 # assert_output is 2 assertions
103
+
104
+ proc { }.must_be_silent.must_equal true
105
+
106
+ assert_triggered "In stdout.\nExpected: \"\"\n Actual: \"xxx\"" do
107
+ proc { print "xxx" }.must_be_silent
108
+ end
109
+ end
110
+
111
+ it "needs to have all methods named well" do
112
+ @assertion_count = 2
113
+
114
+ methods = Object.public_instance_methods.find_all { |n| n =~ /^must|^wont/ }
115
+ methods.map! { |m| m.to_s } if Symbol === methods.first
116
+
117
+ musts, wonts = methods.sort.partition { |m| m =~ /^must/ }
118
+
119
+ expected_musts = %w(must_be
120
+ must_be_close_to
121
+ must_be_empty
122
+ must_be_instance_of
123
+ must_be_kind_of
124
+ must_be_nil
125
+ must_be_same_as
126
+ must_be_silent
127
+ must_be_within_delta
128
+ must_be_within_epsilon
129
+ must_equal
130
+ must_include
131
+ must_match
132
+ must_output
133
+ must_raise
134
+ must_respond_to
135
+ must_throw)
136
+
137
+ bad = %w[not raise throw send output be_silent]
138
+
139
+ expected_wonts = expected_musts.map { |m| m.sub(/^must/, "wont") }
140
+ expected_wonts.reject! { |m| m =~ /wont_#{Regexp.union(*bad)}/ }
141
+
142
+ musts.must_equal expected_musts
143
+ wonts.must_equal expected_wonts
144
+ end
145
+
146
+ it "needs to raise if an expected exception is not raised" do
147
+ @assertion_count -= 2 # no positive test
148
+
149
+ assert_triggered "RuntimeError expected but nothing was raised." do
150
+ proc { 42 }.must_raise RuntimeError
151
+ end
152
+
153
+ assert_triggered "msg.\nRuntimeError expected but nothing was raised." do
154
+ proc { 42 }.must_raise RuntimeError, "msg"
155
+ end
156
+ end
157
+
158
+ it "needs to verify binary messages" do
159
+ 42.wont_be(:<, 24).must_equal false
160
+
161
+ assert_triggered "Expected 24 to not be < 42." do
162
+ 24.wont_be :<, 42
163
+ end
164
+
165
+ assert_triggered "msg.\nExpected 24 to not be < 42." do
166
+ 24.wont_be :<, 42, "msg"
167
+ end
168
+ end
169
+
170
+ it "needs to verify emptyness" do
171
+ @assertion_count += 3 # empty is 2 assertions
172
+
173
+ [].must_be_empty.must_equal true
174
+
175
+ assert_triggered "Expected [42] to be empty." do
176
+ [42].must_be_empty
177
+ end
178
+
179
+ assert_triggered "msg.\nExpected [42] to be empty." do
180
+ [42].must_be_empty "msg"
181
+ end
182
+ end
183
+
184
+ it "needs to verify equality" do
185
+ (6 * 7).must_equal(42).must_equal true
186
+
187
+ assert_triggered "Expected: 42\n Actual: 54" do
188
+ (6 * 9).must_equal 42
189
+ end
190
+
191
+ assert_triggered "msg.\nExpected: 42\n Actual: 54" do
192
+ (6 * 9).must_equal 42, "msg"
193
+ end
194
+ end
195
+
196
+ it "needs to verify floats outside a delta" do
197
+ @assertion_count += 1 # extra test
198
+
199
+ 24.wont_be_close_to(42).must_equal false
200
+
201
+ assert_triggered "Expected |42 - 42.0| (0.0) to not be <= 0.001." do
202
+ (6 * 7.0).wont_be_close_to 42
203
+ end
204
+
205
+ x = maglev? ? "1.0000000000000001e-05" : "1.0e-05"
206
+ assert_triggered "Expected |42 - 42.0| (0.0) to not be <= #{x}." do
207
+ (6 * 7.0).wont_be_close_to 42, 0.00001
208
+ end
209
+
210
+ assert_triggered "msg.\nExpected |42 - 42.0| (0.0) to not be <= #{x}." do
211
+ (6 * 7.0).wont_be_close_to 42, 0.00001, "msg"
212
+ end
213
+ end
214
+
215
+ it "needs to verify floats outside an epsilon" do
216
+ @assertion_count += 1 # extra test
217
+
218
+ 24.wont_be_within_epsilon(42).must_equal false
219
+
220
+ x = maglev? ? "0.042000000000000003" : "0.042"
221
+ assert_triggered "Expected |42 - 42.0| (0.0) to not be <= #{x}." do
222
+ (6 * 7.0).wont_be_within_epsilon 42
223
+ end
224
+
225
+ x = maglev? ? "0.00042000000000000002" : "0.00042"
226
+ assert_triggered "Expected |42 - 42.0| (0.0) to not be <= #{x}." do
227
+ (6 * 7.0).wont_be_within_epsilon 42, 0.00001
228
+ end
229
+
230
+ assert_triggered "msg.\nExpected |42 - 42.0| (0.0) to not be <= #{x}." do
231
+ (6 * 7.0).wont_be_within_epsilon 42, 0.00001, "msg"
232
+ end
233
+ end
234
+
235
+ it "needs to verify floats within a delta" do
236
+ @assertion_count += 1 # extra test
237
+
238
+ (6.0 * 7).must_be_close_to(42.0).must_equal true
239
+
240
+ assert_triggered "Expected |0.0 - 0.01| (0.01) to be <= 0.001." do
241
+ (1.0 / 100).must_be_close_to 0.0
242
+ end
243
+
244
+ x = maglev? ? "9.9999999999999995e-07" : "1.0e-06"
245
+ assert_triggered "Expected |0.0 - 0.001| (0.001) to be <= #{x}." do
246
+ (1.0 / 1000).must_be_close_to 0.0, 0.000001
247
+ end
248
+
249
+ assert_triggered "msg.\nExpected |0.0 - 0.001| (0.001) to be <= #{x}." do
250
+ (1.0 / 1000).must_be_close_to 0.0, 0.000001, "msg"
251
+ end
252
+ end
253
+
254
+ it "needs to verify floats within an epsilon" do
255
+ @assertion_count += 1 # extra test
256
+
257
+ (6.0 * 7).must_be_within_epsilon(42.0).must_equal true
258
+
259
+ assert_triggered "Expected |0.0 - 0.01| (0.01) to be <= 0.0." do
260
+ (1.0 / 100).must_be_within_epsilon 0.0
261
+ end
262
+
263
+ assert_triggered "Expected |0.0 - 0.001| (0.001) to be <= 0.0." do
264
+ (1.0 / 1000).must_be_within_epsilon 0.0, 0.000001
265
+ end
266
+
267
+ assert_triggered "msg.\nExpected |0.0 - 0.001| (0.001) to be <= 0.0." do
268
+ (1.0 / 1000).must_be_within_epsilon 0.0, 0.000001, "msg"
269
+ end
270
+ end
271
+
272
+ it "needs to verify identity" do
273
+ 1.must_be_same_as(1).must_equal true
274
+
275
+ assert_triggered "Expected 1 (oid=N) to be the same as 2 (oid=N)." do
276
+ 1.must_be_same_as 2
277
+ end
278
+
279
+ assert_triggered "msg.\nExpected 1 (oid=N) to be the same as 2 (oid=N)." do
280
+ 1.must_be_same_as 2, "msg"
281
+ end
282
+ end
283
+
284
+ it "needs to verify inequality" do
285
+ 42.wont_equal(6 * 9).must_equal false
286
+
287
+ assert_triggered "Expected 1 to not be equal to 1." do
288
+ 1.wont_equal 1
289
+ end
290
+
291
+ assert_triggered "msg.\nExpected 1 to not be equal to 1." do
292
+ 1.wont_equal 1, "msg"
293
+ end
294
+ end
295
+
296
+ it "needs to verify instances of a class" do
297
+ 42.wont_be_instance_of(String).must_equal false
298
+
299
+ assert_triggered "Expected 42 to not be an instance of Fixnum." do
300
+ 42.wont_be_instance_of Fixnum
301
+ end
302
+
303
+ assert_triggered "msg.\nExpected 42 to not be an instance of Fixnum." do
304
+ 42.wont_be_instance_of Fixnum, "msg"
305
+ end
306
+ end
307
+
308
+ it "needs to verify kinds of a class" do
309
+ 42.wont_be_kind_of(String).must_equal false
310
+
311
+ assert_triggered "Expected 42 to not be a kind of Integer." do
312
+ 42.wont_be_kind_of Integer
313
+ end
314
+
315
+ assert_triggered "msg.\nExpected 42 to not be a kind of Integer." do
316
+ 42.wont_be_kind_of Integer, "msg"
317
+ end
318
+ end
319
+
320
+ it "needs to verify kinds of objects" do
321
+ @assertion_count += 2 # extra test
322
+
323
+ (6 * 7).must_be_kind_of(Fixnum).must_equal true
324
+ (6 * 7).must_be_kind_of(Numeric).must_equal true
325
+
326
+ assert_triggered "Expected 42 to be a kind of String, not Fixnum." do
327
+ (6 * 7).must_be_kind_of String
328
+ end
329
+
330
+ assert_triggered "msg.\nExpected 42 to be a kind of String, not Fixnum." do
331
+ (6 * 7).must_be_kind_of String, "msg"
332
+ end
333
+ end
334
+
335
+ it "needs to verify mismatch" do
336
+ @assertion_count += 3 # match is 2
337
+
338
+ "blah".wont_match(/\d+/).must_equal false
339
+
340
+ assert_triggered "Expected /\\w+/ to not match \"blah\"." do
341
+ "blah".wont_match(/\w+/)
342
+ end
343
+
344
+ assert_triggered "msg.\nExpected /\\w+/ to not match \"blah\"." do
345
+ "blah".wont_match(/\w+/, "msg")
346
+ end
347
+ end
348
+
349
+ it "needs to verify nil" do
350
+ nil.must_be_nil.must_equal true
351
+
352
+ assert_triggered "Expected 42 to be nil." do
353
+ 42.must_be_nil
354
+ end
355
+
356
+ assert_triggered "msg.\nExpected 42 to be nil." do
357
+ 42.must_be_nil "msg"
358
+ end
359
+ end
360
+
361
+ it "needs to verify non-emptyness" do
362
+ @assertion_count += 3 # empty is 2 assertions
363
+
364
+ ["some item"].wont_be_empty.must_equal false
365
+
366
+ assert_triggered "Expected [] to not be empty." do
367
+ [].wont_be_empty
368
+ end
369
+
370
+ assert_triggered "msg.\nExpected [] to not be empty." do
371
+ [].wont_be_empty "msg"
372
+ end
373
+ end
374
+
375
+ it "needs to verify non-identity" do
376
+ 1.wont_be_same_as(2).must_equal false
377
+
378
+ assert_triggered "Expected 1 (oid=N) to not be the same as 1 (oid=N)." do
379
+ 1.wont_be_same_as 1
380
+ end
381
+
382
+ assert_triggered "msg.\nExpected 1 (oid=N) to not be the same as 1 (oid=N)." do
383
+ 1.wont_be_same_as 1, "msg"
384
+ end
385
+ end
386
+
387
+ it "needs to verify non-nil" do
388
+ 42.wont_be_nil.must_equal false
389
+
390
+ assert_triggered "Expected nil to not be nil." do
391
+ nil.wont_be_nil
392
+ end
393
+
394
+ assert_triggered "msg.\nExpected nil to not be nil." do
395
+ nil.wont_be_nil "msg"
396
+ end
397
+ end
398
+
399
+ it "needs to verify objects not responding to a message" do
400
+ "".wont_respond_to(:woot!).must_equal false
401
+
402
+ assert_triggered "Expected \"\" to not respond to to_s." do
403
+ "".wont_respond_to :to_s
404
+ end
405
+
406
+ assert_triggered "msg.\nExpected \"\" to not respond to to_s." do
407
+ "".wont_respond_to :to_s, "msg"
408
+ end
409
+ end
410
+
411
+ it "needs to verify output in stderr" do
412
+ @assertion_count -= 1 # no msg
413
+
414
+ proc { $stderr.print "blah" }.must_output(nil, "blah").must_equal true
415
+
416
+ assert_triggered "In stderr.\nExpected: \"blah\"\n Actual: \"xxx\"" do
417
+ proc { $stderr.print "xxx" }.must_output(nil, "blah")
418
+ end
419
+ end
420
+
421
+ it "needs to verify output in stdout" do
422
+ @assertion_count -= 1 # no msg
423
+
424
+ proc { print "blah" }.must_output("blah").must_equal true
425
+
426
+ assert_triggered "In stdout.\nExpected: \"blah\"\n Actual: \"xxx\"" do
427
+ proc { print "xxx" }.must_output("blah")
428
+ end
429
+ end
430
+
431
+ it "needs to verify regexp matches" do
432
+ @assertion_count += 3 # must_match is 2 assertions
433
+
434
+ "blah".must_match(/\w+/).must_equal true
435
+
436
+ assert_triggered "Expected /\\d+/ to match \"blah\"." do
437
+ "blah".must_match(/\d+/)
438
+ end
439
+
440
+ assert_triggered "msg.\nExpected /\\d+/ to match \"blah\"." do
441
+ "blah".must_match(/\d+/, "msg")
442
+ end
443
+ end
444
+
445
+ it "needs to verify throw" do
446
+ @assertion_count += 2 # 2 extra tests
447
+
448
+ proc { throw :blah }.must_throw(:blah).must_equal true
449
+
450
+ assert_triggered "Expected :blah to have been thrown." do
451
+ proc { }.must_throw :blah
452
+ end
453
+
454
+ assert_triggered "Expected :blah to have been thrown, not :xxx." do
455
+ proc { throw :xxx }.must_throw :blah
456
+ end
457
+
458
+ assert_triggered "msg.\nExpected :blah to have been thrown." do
459
+ proc { }.must_throw :blah, "msg"
460
+ end
461
+
462
+ assert_triggered "msg.\nExpected :blah to have been thrown, not :xxx." do
463
+ proc { throw :xxx }.must_throw :blah, "msg"
464
+ end
465
+ end
466
+
467
+ it "needs to verify types of objects" do
468
+ (6 * 7).must_be_instance_of(Fixnum).must_equal true
469
+
470
+ exp = "Expected 42 to be an instance of String, not Fixnum."
471
+
472
+ assert_triggered exp do
473
+ (6 * 7).must_be_instance_of String
474
+ end
475
+
476
+ assert_triggered "msg.\n#{exp}" do
477
+ (6 * 7).must_be_instance_of String, "msg"
478
+ end
479
+ end
480
+
481
+ it "needs to verify using any (negative) predicate" do
482
+ @assertion_count -= 1 # doesn"t take a message
483
+
484
+ "blah".wont_be(:empty?).must_equal false
485
+
486
+ assert_triggered "Expected \"\" to not be empty?." do
487
+ "".wont_be :empty?
488
+ end
489
+ end
490
+
491
+ it "needs to verify using any binary operator" do
492
+ @assertion_count -= 1 # no msg
493
+
494
+ 41.must_be(:<, 42).must_equal true
495
+
496
+ assert_triggered "Expected 42 to be < 41." do
497
+ 42.must_be(:<, 41)
498
+ end
499
+ end
500
+
501
+ it "needs to verify using any predicate" do
502
+ @assertion_count -= 1 # no msg
503
+
504
+ "".must_be(:empty?).must_equal true
505
+
506
+ assert_triggered "Expected \"blah\" to be empty?." do
507
+ "blah".must_be :empty?
508
+ end
509
+ end
510
+
511
+ it "needs to verify using respond_to" do
512
+ 42.must_respond_to(:+).must_equal true
513
+
514
+ assert_triggered "Expected 42 (Fixnum) to respond to #clear." do
515
+ 42.must_respond_to :clear
516
+ end
517
+
518
+ assert_triggered "msg.\nExpected 42 (Fixnum) to respond to #clear." do
519
+ 42.must_respond_to :clear, "msg"
520
+ end
521
+ end
522
+
523
+ end
524
+
525
+ describe Betatest::Spec, :let do
526
+ i_suck_and_my_tests_are_order_dependent!
527
+
528
+ def _count
529
+ $let_count ||= 0
530
+ end
531
+
532
+ let :count do
533
+ $let_count += 1
534
+ $let_count
535
+ end
536
+
537
+ it "is evaluated once per example" do
538
+ _count.must_equal 0
539
+
540
+ count.must_equal 1
541
+ count.must_equal 1
542
+
543
+ _count.must_equal 1
544
+ end
545
+
546
+ it "is REALLY evaluated once per example" do
547
+ _count.must_equal 1
548
+
549
+ count.must_equal 2
550
+ count.must_equal 2
551
+
552
+ _count.must_equal 2
553
+ end
554
+
555
+ it 'raises an error if the name begins with "test"' do
556
+ proc { self.class.let(:test_value) { true } }.must_raise ArgumentError
557
+ end
558
+
559
+ it 'raises an error if the name shadows a normal instance method' do
560
+ proc { self.class.let(:message) { true } }.must_raise ArgumentError
561
+ end
562
+
563
+ it "doesn't raise an error if it is just another let" do
564
+ proc do
565
+ describe :outer do
566
+ let(:bar)
567
+ describe :inner do
568
+ let(:bar)
569
+ end
570
+ end
571
+ :good
572
+ end.call.must_equal :good
573
+ end
574
+
575
+ it 'procs come after dont_flip' do
576
+ p = proc{ }
577
+ assert_respond_to p, :call
578
+ p.must_respond_to :call
579
+ end
580
+ end
581
+
582
+ describe Betatest::Spec, :subject do
583
+ attr_reader :subject_evaluation_count
584
+
585
+ subject do
586
+ @subject_evaluation_count ||= 0
587
+ @subject_evaluation_count += 1
588
+ @subject_evaluation_count
589
+ end
590
+
591
+ it "is evaluated once per example" do
592
+ subject.must_equal 1
593
+ subject.must_equal 1
594
+ subject_evaluation_count.must_equal 1
595
+ end
596
+ end
597
+
598
+ class TestMetaStatic < Betatest::Test
599
+ def test_children
600
+ Betatest::Spec.children.clear # prevents parallel run
601
+
602
+ x = y = z = nil
603
+ x = describe "top-level thingy" do
604
+ y = describe "first thingy" do end
605
+
606
+ it "top-level-it" do end
607
+
608
+ z = describe "second thingy" do end
609
+ end
610
+
611
+ assert_equal [x], Betatest::Spec.children
612
+ assert_equal [y, z], x.children
613
+ assert_equal [], y.children
614
+ assert_equal [], z.children
615
+ end
616
+ end
617
+
618
+ require_relative 'metametameta'
619
+
620
+ class TestMeta < MetaMetaMetaTestCase
621
+ parallelize_me!
622
+
623
+ def util_structure
624
+ x = y = z = nil
625
+ before_list = []
626
+ after_list = []
627
+ x = describe "top-level thingy" do
628
+ before { before_list << 1 }
629
+ after { after_list << 1 }
630
+
631
+ it "top-level-it" do end
632
+
633
+ y = describe "inner thingy" do
634
+ before { before_list << 2 }
635
+ after { after_list << 2 }
636
+ it "inner-it" do end
637
+
638
+ z = describe "very inner thingy" do
639
+ before { before_list << 3 }
640
+ after { after_list << 3 }
641
+ it "inner-it" do end
642
+
643
+ it {} # ignore me
644
+ specify {} # anonymous it
645
+ end
646
+ end
647
+ end
648
+
649
+ return x, y, z, before_list, after_list
650
+ end
651
+
652
+ def test_register_spec_type
653
+ original_types = Betatest::Spec::TYPES.dup
654
+
655
+ assert_includes Betatest::Spec::TYPES, [//, Betatest::Spec]
656
+
657
+ Betatest::Spec.register_spec_type(/woot/, TestMeta)
658
+
659
+ p = lambda do |x| true end
660
+ Betatest::Spec.register_spec_type TestMeta, &p
661
+
662
+ keys = Betatest::Spec::TYPES.map(&:first)
663
+
664
+ assert_includes keys, /woot/
665
+ assert_includes keys, p
666
+ ensure
667
+ Betatest::Spec::TYPES.replace original_types
668
+ end
669
+
670
+ def test_spec_type
671
+ original_types = Betatest::Spec::TYPES.dup
672
+
673
+ Betatest::Spec.register_spec_type(/A$/, MiniSpecA)
674
+ Betatest::Spec.register_spec_type MiniSpecB do |desc|
675
+ desc.superclass == ExampleA
676
+ end
677
+
678
+ assert_equal MiniSpecA, Betatest::Spec.spec_type(ExampleA)
679
+ assert_equal MiniSpecB, Betatest::Spec.spec_type(ExampleB)
680
+ ensure
681
+ Betatest::Spec::TYPES.replace original_types
682
+ end
683
+
684
+ def test_bug_dsl_expectations
685
+ spec_class = Class.new MiniSpecB do
686
+ it "should work" do
687
+ 0.must_equal 0
688
+ end
689
+ end
690
+
691
+ test_name = spec_class.instance_methods.sort.grep(/test/).first
692
+
693
+ spec = spec_class.new test_name
694
+
695
+ result = spec.run
696
+
697
+ assert spec.passed?
698
+ assert result.passed?
699
+ assert_equal 1, result.assertions
700
+ end
701
+
702
+ def test_name
703
+ spec_a = describe ExampleA do; end
704
+ spec_b = describe ExampleB, :random_method do; end
705
+
706
+ assert_equal "ExampleA", spec_a.name
707
+ assert_equal "ExampleB::random_method", spec_b.name
708
+ end
709
+
710
+ def test_name2
711
+ assert_equal "NamedExampleA", NamedExampleA.name
712
+ assert_equal "NamedExampleB", NamedExampleB.name
713
+ assert_equal "NamedExampleC", NamedExampleC.name
714
+
715
+ spec_a = describe ExampleA do; end
716
+ spec_b = describe ExampleB, :random_method do; end
717
+
718
+ assert_equal "ExampleA", spec_a.name
719
+ assert_equal "ExampleB::random_method", spec_b.name
720
+ end
721
+
722
+ def test_structure
723
+ x, y, z, * = util_structure
724
+
725
+ assert_equal "top-level thingy", x.to_s
726
+ assert_equal "top-level thingy::inner thingy", y.to_s
727
+ assert_equal "top-level thingy::inner thingy::very inner thingy", z.to_s
728
+
729
+ assert_equal "top-level thingy", x.desc
730
+ assert_equal "inner thingy", y.desc
731
+ assert_equal "very inner thingy", z.desc
732
+
733
+ top_methods = %w(setup teardown test_0001_top-level-it)
734
+ inner_methods1 = %w(setup teardown test_0001_inner-it)
735
+ inner_methods2 = inner_methods1 +
736
+ %w(test_0002_anonymous test_0003_anonymous)
737
+
738
+ assert_equal top_methods, x.instance_methods(false).sort.map(&:to_s)
739
+ assert_equal inner_methods1, y.instance_methods(false).sort.map(&:to_s)
740
+ assert_equal inner_methods2, z.instance_methods(false).sort.map(&:to_s)
741
+ end
742
+
743
+ def test_setup_teardown_behavior
744
+ _, _, z, before_list, after_list = util_structure
745
+
746
+ @tu = z
747
+
748
+ run_tu_with_fresh_reporter
749
+
750
+ size = z.runnable_methods.size
751
+ assert_equal [1, 2, 3] * size, before_list
752
+ assert_equal [3, 2, 1] * size, after_list
753
+ end
754
+
755
+ def test_describe_first_structure
756
+ x = x1 = x2 = y = z = nil
757
+ x = describe "top-level thingy" do
758
+ y = describe "first thingy" do end
759
+
760
+ x1 = it "top level it" do end
761
+ x2 = it "не латинские буквы-и-спецсимволы&いった α, β, γ, δ, ε hello!!! world" do end
762
+
763
+ z = describe "second thingy" do end
764
+ end
765
+
766
+ test_methods = ["test_0001_top level it", "test_0002_не латинские буквы-и-спецсимволы&いった α, β, γ, δ, ε hello!!! world"].sort
767
+
768
+ assert_equal test_methods, [x1, x2]
769
+ assert_equal test_methods,
770
+ x.instance_methods.grep(/^test/).map {|o| o.to_s}.sort
771
+ assert_equal [], y.instance_methods.grep(/^test/)
772
+ assert_equal [], z.instance_methods.grep(/^test/)
773
+ end
774
+
775
+ def test_structure_subclasses
776
+ z = nil
777
+ x = Class.new Betatest::Spec do
778
+ def xyz; end
779
+ end
780
+ y = Class.new x do
781
+ z = describe("inner") {}
782
+ end
783
+
784
+ assert_respond_to x.new(nil), "xyz"
785
+ assert_respond_to y.new(nil), "xyz"
786
+ assert_respond_to z.new(nil), "xyz"
787
+ end
788
+ end
789
+
790
+ class TestSpecInTestCase < MetaMetaMetaTestCase
791
+ def setup
792
+ super
793
+
794
+ Thread.current[:current_spec] = self
795
+ @tc = self
796
+ @assertion_count = 2
797
+ end
798
+
799
+ def assert_triggered expected, klass = Betatest::Assertion
800
+ @assertion_count += 1
801
+
802
+ e = assert_raises klass do
803
+ yield
804
+ end
805
+
806
+ msg = e.message.sub(/(---Backtrace---).*/m, "\1")
807
+ msg.gsub!(/\(oid=[-0-9]+\)/, "(oid=N)")
808
+
809
+ assert_equal expected, msg
810
+ end
811
+
812
+ def teardown
813
+ msg = "expected #{@assertion_count} assertions, not #{@tc.assertions}"
814
+ assert_equal @assertion_count, @tc.assertions, msg
815
+ end
816
+
817
+ def test_expectation
818
+ @tc.assert_equal true, 1.must_equal(1)
819
+ end
820
+
821
+ def test_expectation_triggered
822
+ assert_triggered "Expected: 2\n Actual: 1" do
823
+ 1.must_equal 2
824
+ end
825
+ end
826
+
827
+ def test_expectation_with_a_message
828
+ assert_triggered "woot.\nExpected: 2\n Actual: 1" do
829
+ 1.must_equal 2, "woot"
830
+ end
831
+ end
832
+ end