betatest 0.0.1

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