1/*
2 * Copyright 2001-2008 Artima, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.scalatest
17
18import org.scalatest.events._
19
20class SpecSpec extends Spec with SharedHelpers with GivenWhenThen {
21
22  describe("A Spec") {
23
24    it("should return the test names in registration order from testNames") {
25
26      val a = new Spec {
27        it("should test this") {}
28        it("should test that") {}
29      }
30
31      expect(List("should test this", "should test that")) {
32        a.testNames.iterator.toList
33      }
34
35      val b = new Spec {}
36
37      expect(List[String]()) {
38        b.testNames.iterator.toList
39      }
40
41      val c = new Spec {
42        it("should test that") {}
43        it("should test this") {}
44      }
45
46      expect(List("should test that", "should test this")) {
47        c.testNames.iterator.toList
48      }
49
50      val d = new Spec {
51        describe("A Tester") {
52          it("should test that") {}
53          it("should test this") {}
54        }
55      }
56
57      expect(List("A Tester should test that", "A Tester should test this")) {
58        d.testNames.iterator.toList
59      }
60
61      val e = new Spec {
62        describe("A Tester") {
63          it("should test this") {}
64          it("should test that") {}
65        }
66      }
67
68      expect(List("A Tester should test this", "A Tester should test that")) {
69        e.testNames.iterator.toList
70      }
71    }
72
73    it("should throw DuplicateTestNameException if a duplicate test name registration is attempted") {
74
75      intercept[DuplicateTestNameException] {
76        new Spec {
77          it("should test this") {}
78          it("should test this") {}
79        }
80      }
81      intercept[DuplicateTestNameException] {
82        new Spec {
83          it("should test this") {}
84          ignore("should test this") {}
85        }
86      }
87      intercept[DuplicateTestNameException] {
88        new Spec {
89          ignore("should test this") {}
90          ignore("should test this") {}
91        }
92      }
93      intercept[DuplicateTestNameException] {
94        new Spec {
95          ignore("should test this") {}
96          it("should test this") {}
97        }
98      }
99    }
100
101    it("should invoke withFixture from runTest") {
102      val a = new Spec {
103        var withFixtureWasInvoked = false
104        var testWasInvoked = false
105        override def withFixture(test: NoArgTest) {
106          withFixtureWasInvoked = true
107          super.withFixture(test)
108        }
109        it("should do something") {
110          testWasInvoked = true
111        }
112      }
113      a.run(None, SilentReporter, new Stopper {}, Filter(), Map(), None, new Tracker())
114      assert(a.withFixtureWasInvoked)
115      assert(a.testWasInvoked)
116    }
117    it("should pass the correct test name in the NoArgTest passed to withFixture") {
118      val a = new Spec {
119        var correctTestNameWasPassed = false
120        override def withFixture(test: NoArgTest) {
121          correctTestNameWasPassed = test.name == "should do something"
122          super.withFixture(test)
123        }
124        it("should do something") {}
125      }
126      a.run(None, SilentReporter, new Stopper {}, Filter(), Map(), None, new Tracker())
127      assert(a.correctTestNameWasPassed)
128    }
129    it("should pass the correct config map in the NoArgTest passed to withFixture") {
130      val a = new Spec {
131        var correctConfigMapWasPassed = false
132        override def withFixture(test: NoArgTest) {
133          correctConfigMapWasPassed = (test.configMap == Map("hi" -> 7))
134          super.withFixture(test)
135        }
136        it("should do something") {}
137      }
138      a.run(None, SilentReporter, new Stopper {}, Filter(), Map("hi" -> 7), None, new Tracker())
139      assert(a.correctConfigMapWasPassed)
140    }
141    describe("(with info calls)") {
142      class InfoInsideTestSpec extends Spec {
143        val msg = "hi there, dude"
144        val testName = "test name"
145        it(testName) {
146          info(msg)
147        }
148      }
149      // In a Spec, any InfoProvided's fired during the test should be cached and sent out after the test has
150      // suceeded or failed. This makes the report look nicer, because the info is tucked under the "specifier'
151      // text for that test.
152      it("should, when the info appears in the code of a successful test, report the info after the TestSucceeded") {
153        val spec = new InfoInsideTestSpec
154        val (infoProvidedIndex, testStartingIndex, testSucceededIndex) =
155          getIndexesForInformerEventOrderTests(spec, spec.testName, spec.msg)
156        assert(testSucceededIndex < infoProvidedIndex)
157      }
158      class InfoBeforeTestSpec extends Spec {
159        val msg = "hi there, dude"
160        val testName = "test name"
161        info(msg)
162        it(testName) {}
163      }
164      it("should, when the info appears in the body before a test, report the info before the test") {
165        val spec = new InfoBeforeTestSpec
166        val (infoProvidedIndex, testStartingIndex, testSucceededIndex) =
167          getIndexesForInformerEventOrderTests(spec, spec.testName, spec.msg)
168        assert(infoProvidedIndex < testStartingIndex)
169        assert(testStartingIndex < testSucceededIndex)
170      }
171      it("should, when the info appears in the body after a test, report the info after the test runs") {
172        val msg = "hi there, dude"
173        val testName = "test name"
174        class MySpec extends Spec {
175          it(testName) {}
176          info(msg)
177        }
178        val (infoProvidedIndex, testStartingIndex, testSucceededIndex) =
179          getIndexesForInformerEventOrderTests(new MySpec, testName, msg)
180        assert(testStartingIndex < testSucceededIndex)
181        assert(testSucceededIndex < infoProvidedIndex)
182      }
183      it("should throw an IllegalStateException when info is called by a method invoked after the suite has been executed") {
184        class MySpec extends Spec {
185          callInfo() // This should work fine
186          def callInfo() {
187            info("howdy")
188          }
189          it("howdy also") {
190            callInfo() // This should work fine
191          }
192        }
193        val spec = new MySpec
194        val myRep = new EventRecordingReporter
195        spec.run(None, myRep, new Stopper {}, Filter(), Map(), None, new Tracker)
196        intercept[IllegalStateException] {
197          spec.callInfo()
198        }
199      }
200      it("should send an InfoProvided with an IndentedText formatter with level 1 when called outside a test") {
201        val spec = new InfoBeforeTestSpec
202        val indentedText = getIndentedTextFromInfoProvided(spec)
203        assert(indentedText === IndentedText("+ " + spec.msg, spec.msg, 0))
204      }
205      it("should send an InfoProvided with an IndentedText formatter with level 2 when called within a test") {
206        val spec = new InfoInsideTestSpec
207        val indentedText = getIndentedTextFromInfoProvided(spec)
208        assert(indentedText === IndentedText("  + " + spec.msg, spec.msg, 1))
209      }
210    }
211    it("should return registered tags, including ignore tags, from the tags method") {
212
213      val a = new Spec {
214        ignore("should test this") {}
215        it("should test that") {}
216      }
217      expect(Map("should test this" -> Set("org.scalatest.Ignore"))) {
218        a.tags
219      }
220
221      val b = new Spec {
222        it("should test this") {}
223        ignore("should test that") {}
224      }
225      expect(Map("should test that" -> Set("org.scalatest.Ignore"))) {
226        b.tags
227      }
228
229      val c = new Spec {
230        ignore("should test this") {}
231        ignore("should test that") {}
232      }
233      expect(Map("should test this" -> Set("org.scalatest.Ignore"), "should test that" -> Set("org.scalatest.Ignore"))) {
234        c.tags
235      }
236
237      val d = new Spec {
238        it("should test this") {}
239        it("should test that") {}
240      }
241      expect(Map()) {
242        d.tags
243      }
244
245      val e = new Spec {
246        it("should test this", mytags.SlowAsMolasses) {}
247        ignore("should test that", mytags.SlowAsMolasses) {}
248      }
249      expect(Map("should test this" -> Set("org.scalatest.SlowAsMolasses"), "should test that" -> Set("org.scalatest.Ignore", "org.scalatest.SlowAsMolasses"))) {
250        e.tags
251      }
252
253      val f = new Spec {}
254      expect(Map()) {
255        f.tags
256      }
257
258      val g = new Spec {
259        it("should test this", mytags.SlowAsMolasses, mytags.WeakAsAKitten) {}
260        it("should test that", mytags.SlowAsMolasses) {}
261      }
262      expect(Map("should test this" -> Set("org.scalatest.SlowAsMolasses", "org.scalatest.WeakAsAKitten"), "should test that" -> Set("org.scalatest.SlowAsMolasses"))) {
263        g.tags
264      }
265    }
266
267    describe("(when a nesting rule has been violated)") {
268
269      it("should, if they call a describe from within an it clause, result in a TestFailedException when running the test") {
270
271        class MySpec extends Spec {
272          it("should blow up") {
273            describe("in the wrong place, at the wrong time") {
274            }
275          }
276        }
277
278        val spec = new MySpec
279        ensureTestFailedEventReceived(spec, "should blow up")
280      }
281      it("should, if they call a describe with a nested it from within an it clause, result in a TestFailedException when running the test") {
282
283        class MySpec extends Spec {
284          it("should blow up") {
285            describe("in the wrong place, at the wrong time") {
286              it("should never run") {
287                assert(1 === 1)
288              }
289            }
290          }
291        }
292
293        val spec = new MySpec
294        ensureTestFailedEventReceived(spec, "should blow up")
295      }
296      it("should, if they call a nested it from within an it clause, result in a TestFailedException when running the test") {
297
298        class MySpec extends Spec {
299          it("should blow up") {
300            it("should never run") {
301              assert(1 === 1)
302            }
303          }
304        }
305
306        val spec = new MySpec
307        ensureTestFailedEventReceived(spec, "should blow up")
308      }
309      it("should, if they call a nested it with tags from within an it clause, result in a TestFailedException when running the test") {
310
311        class MySpec extends Spec {
312          it("should blow up") {
313            it("should never run", mytags.SlowAsMolasses) {
314              assert(1 === 1)
315            }
316          }
317        }
318
319        val spec = new MySpec
320        ensureTestFailedEventReceived(spec, "should blow up")
321      }
322      it("should, if they call a describe with a nested ignore from within an it clause, result in a TestFailedException when running the test") {
323
324        class MySpec extends Spec {
325          it("should blow up") {
326            describe("in the wrong place, at the wrong time") {
327              ignore("should never run") {
328                assert(1 === 1)
329              }
330            }
331          }
332        }
333
334        val spec = new MySpec
335        ensureTestFailedEventReceived(spec, "should blow up")
336      }
337      it("should, if they call a nested ignore from within an it clause, result in a TestFailedException when running the test") {
338
339        class MySpec extends Spec {
340          it("should blow up") {
341            ignore("should never run") {
342              assert(1 === 1)
343            }
344          }
345        }
346
347        val spec = new MySpec
348        ensureTestFailedEventReceived(spec, "should blow up")
349      }
350      it("should, if they call a nested ignore with tags from within an it clause, result in a TestFailedException when running the test") {
351
352        class MySpec extends Spec {
353          it("should blow up") {
354            ignore("should never run", mytags.SlowAsMolasses) {
355              assert(1 === 1)
356            }
357          }
358        }
359
360        val spec = new MySpec
361        ensureTestFailedEventReceived(spec, "should blow up")
362      }
363    }
364    it("should run tests registered via the 'it should behave like' syntax") {
365      trait SharedSpecTests { this: Spec =>
366        def nonEmptyStack(s: String)(i: Int) {
367          it("should be that I am shared") {}
368        }
369      }
370      class MySpec extends Spec with SharedSpecTests {
371        it should behave like nonEmptyStack("hi")(1)
372      }
373      val suite = new MySpec
374      val reporter = new EventRecordingReporter
375      suite.run(None, reporter, new Stopper {}, Filter(), Map(), None, new Tracker)
376
377      val indexedList = reporter.eventsReceived
378
379      val testStartingOption = indexedList.find(_.isInstanceOf[TestStarting])
380      assert(testStartingOption.isDefined)
381      assert(testStartingOption.get.asInstanceOf[TestStarting].testName === "should be that I am shared")
382    }
383
384    it("should throw NullPointerException if a null test tag is provided") {
385      // it
386      intercept[NullPointerException] {
387        new Spec {
388          it("hi", null) {}
389        }
390      }
391      val caught = intercept[NullPointerException] {
392        new Spec {
393          it("hi", mytags.SlowAsMolasses, null) {}
394        }
395      }
396      assert(caught.getMessage === "a test tag was null")
397      intercept[NullPointerException] {
398        new Spec {
399          it("hi", mytags.SlowAsMolasses, null, mytags.WeakAsAKitten) {}
400        }
401      }
402      // ignore
403      intercept[NullPointerException] {
404        new Spec {
405          ignore("hi", null) {}
406        }
407      }
408      val caught2 = intercept[NullPointerException] {
409        new Spec {
410          ignore("hi", mytags.SlowAsMolasses, null) {}
411        }
412      }
413      assert(caught2.getMessage === "a test tag was null")
414      intercept[NullPointerException] {
415        new Spec {
416          ignore("hi", mytags.SlowAsMolasses, null, mytags.WeakAsAKitten) {}
417        }
418      }
419    }
420    it("should return a correct tags map from the tags method") {
421
422      val a = new Spec {
423        ignore("test this") {}
424        it("test that") {}
425      }
426      expect(Map("test this" -> Set("org.scalatest.Ignore"))) {
427        a.tags
428      }
429
430      val b = new Spec {
431        it("test this") {}
432        ignore("test that") {}
433      }
434      expect(Map("test that" -> Set("org.scalatest.Ignore"))) {
435        b.tags
436      }
437
438      val c = new Spec {
439        ignore("test this") {}
440        ignore("test that") {}
441      }
442      expect(Map("test this" -> Set("org.scalatest.Ignore"), "test that" -> Set("org.scalatest.Ignore"))) {
443        c.tags
444      }
445
446      val d = new Spec {
447        it("test this", mytags.SlowAsMolasses) {}
448        ignore("test that", mytags.SlowAsMolasses) {}
449      }
450      expect(Map("test this" -> Set("org.scalatest.SlowAsMolasses"), "test that" -> Set("org.scalatest.Ignore", "org.scalatest.SlowAsMolasses"))) {
451        d.tags
452      }
453
454      val e = new Spec {}
455      expect(Map()) {
456        e.tags
457      }
458
459      val f = new Spec {
460        it("test this", mytags.SlowAsMolasses, mytags.WeakAsAKitten) {}
461        it("test that", mytags.SlowAsMolasses) {}
462      }
463      expect(Map("test this" -> Set("org.scalatest.SlowAsMolasses", "org.scalatest.WeakAsAKitten"), "test that" -> Set("org.scalatest.SlowAsMolasses"))) {
464        f.tags
465      }
466    }
467
468    class TestWasCalledSuite extends Spec {
469      var theTestThisCalled = false
470      var theTestThatCalled = false
471      it("should run this") { theTestThisCalled = true }
472      it("should run that, maybe") { theTestThatCalled = true }
473    }
474
475    it("should execute all tests when run is called with testName None") {
476
477      val b = new TestWasCalledSuite
478      b.run(None, SilentReporter, new Stopper {}, Filter(), Map(), None, new Tracker)
479      assert(b.theTestThisCalled)
480      assert(b.theTestThatCalled)
481    }
482
483    it("should execute one test when run is called with a defined testName") {
484
485      val a = new TestWasCalledSuite
486      a.run(Some("should run this"), SilentReporter, new Stopper {}, Filter(), Map(), None, new Tracker)
487      assert(a.theTestThisCalled)
488      assert(!a.theTestThatCalled)
489    }
490
491    it("should report as ignored, and not run, tests marked ignored") {
492
493      val a = new Spec {
494        var theTestThisCalled = false
495        var theTestThatCalled = false
496        it("test this") { theTestThisCalled = true }
497        it("test that") { theTestThatCalled = true }
498      }
499
500      val repA = new TestIgnoredTrackingReporter
501      a.run(None, repA, new Stopper {}, Filter(), Map(), None, new Tracker)
502      assert(!repA.testIgnoredReceived)
503      assert(a.theTestThisCalled)
504      assert(a.theTestThatCalled)
505
506      val b = new Spec {
507        var theTestThisCalled = false
508        var theTestThatCalled = false
509        ignore("test this") { theTestThisCalled = true }
510        it("test that") { theTestThatCalled = true }
511      }
512
513      val repB = new TestIgnoredTrackingReporter
514      b.run(None, repB, new Stopper {}, Filter(), Map(), None, new Tracker)
515      assert(repB.testIgnoredReceived)
516      assert(repB.lastEvent.isDefined)
517      assert(repB.lastEvent.get.testName endsWith "test this")
518      assert(!b.theTestThisCalled)
519      assert(b.theTestThatCalled)
520
521      val c = new Spec {
522        var theTestThisCalled = false
523        var theTestThatCalled = false
524        it("test this") { theTestThisCalled = true }
525        ignore("test that") { theTestThatCalled = true }
526      }
527
528      val repC = new TestIgnoredTrackingReporter
529      c.run(None, repC, new Stopper {}, Filter(), Map(), None, new Tracker)
530      assert(repC.testIgnoredReceived)
531      assert(repC.lastEvent.isDefined)
532      assert(repC.lastEvent.get.testName endsWith "test that", repC.lastEvent.get.testName)
533      assert(c.theTestThisCalled)
534      assert(!c.theTestThatCalled)
535
536      // The order I want is order of appearance in the file.
537      // Will try and implement that tomorrow. Subtypes will be able to change the order.
538      val d = new Spec {
539        var theTestThisCalled = false
540        var theTestThatCalled = false
541        ignore("test this") { theTestThisCalled = true }
542        ignore("test that") { theTestThatCalled = true }
543      }
544
545      val repD = new TestIgnoredTrackingReporter
546      d.run(None, repD, new Stopper {}, Filter(), Map(), None, new Tracker)
547      assert(repD.testIgnoredReceived)
548      assert(repD.lastEvent.isDefined)
549      assert(repD.lastEvent.get.testName endsWith "test that") // last because should be in order of appearance
550      assert(!d.theTestThisCalled)
551      assert(!d.theTestThatCalled)
552    }
553
554    it("should run a test marked as ignored if run is invoked with that testName") {
555      // If I provide a specific testName to run, then it should ignore an Ignore on that test
556      // method and actually invoke it.
557      val e = new Spec {
558        var theTestThisCalled = false
559        var theTestThatCalled = false
560        ignore("test this") { theTestThisCalled = true }
561        it("test that") { theTestThatCalled = true }
562      }
563
564      val repE = new TestIgnoredTrackingReporter
565      e.run(Some("test this"), repE, new Stopper {}, Filter(), Map(), None, new Tracker)
566      assert(!repE.testIgnoredReceived)
567      assert(e.theTestThisCalled)
568    }
569
570    it("should run only those tests selected by the tags to include and exclude sets") {
571
572      // Nothing is excluded
573      val a = new Spec {
574        var theTestThisCalled = false
575        var theTestThatCalled = false
576        it("test this", mytags.SlowAsMolasses) { theTestThisCalled = true }
577        it("test that") { theTestThatCalled = true }
578      }
579      val repA = new TestIgnoredTrackingReporter
580      a.run(None, repA, new Stopper {}, Filter(), Map(), None, new Tracker)
581      assert(!repA.testIgnoredReceived)
582      assert(a.theTestThisCalled)
583      assert(a.theTestThatCalled)
584
585      // SlowAsMolasses is included, one test should be excluded
586      val b = new Spec {
587        var theTestThisCalled = false
588        var theTestThatCalled = false
589        it("test this", mytags.SlowAsMolasses) { theTestThisCalled = true }
590        it("test that") { theTestThatCalled = true }
591      }
592      val repB = new TestIgnoredTrackingReporter
593      b.run(None, repB, new Stopper {}, Filter(Some(Set("org.scalatest.SlowAsMolasses")), Set()), Map(), None, new Tracker)
594      assert(!repB.testIgnoredReceived)
595      assert(b.theTestThisCalled)
596      assert(!b.theTestThatCalled)
597
598      // SlowAsMolasses is included, and both tests should be included
599      val c = new Spec {
600        var theTestThisCalled = false
601        var theTestThatCalled = false
602        it("test this", mytags.SlowAsMolasses) { theTestThisCalled = true }
603        it("test that", mytags.SlowAsMolasses) { theTestThatCalled = true }
604      }
605      val repC = new TestIgnoredTrackingReporter
606      c.run(None, repB, new Stopper {}, Filter(Some(Set("org.scalatest.SlowAsMolasses")), Set()), Map(), None, new Tracker)
607      assert(!repC.testIgnoredReceived)
608      assert(c.theTestThisCalled)
609      assert(c.theTestThatCalled)
610
611      // SlowAsMolasses is included. both tests should be included but one ignored
612      val d = new Spec {
613        var theTestThisCalled = false
614        var theTestThatCalled = false
615        ignore("test this", mytags.SlowAsMolasses) { theTestThisCalled = true }
616        it("test that", mytags.SlowAsMolasses) { theTestThatCalled = true }
617      }
618      val repD = new TestIgnoredTrackingReporter
619      d.run(None, repD, new Stopper {}, Filter(Some(Set("org.scalatest.SlowAsMolasses")), Set("org.scalatest.Ignore")), Map(), None, new Tracker)
620      assert(repD.testIgnoredReceived)
621      assert(!d.theTestThisCalled)
622      assert(d.theTestThatCalled)
623
624      // SlowAsMolasses included, FastAsLight excluded
625      val e = new Spec {
626        var theTestThisCalled = false
627        var theTestThatCalled = false
628        var theTestTheOtherCalled = false
629        it("test this", mytags.SlowAsMolasses, mytags.FastAsLight) { theTestThisCalled = true }
630        it("test that", mytags.SlowAsMolasses) { theTestThatCalled = true }
631        it("test the other") { theTestTheOtherCalled = true }
632      }
633      val repE = new TestIgnoredTrackingReporter
634      e.run(None, repE, new Stopper {}, Filter(Some(Set("org.scalatest.SlowAsMolasses")), Set("org.scalatest.FastAsLight")),
635                Map(), None, new Tracker)
636      assert(!repE.testIgnoredReceived)
637      assert(!e.theTestThisCalled)
638      assert(e.theTestThatCalled)
639      assert(!e.theTestTheOtherCalled)
640
641      // An Ignored test that was both included and excluded should not generate a TestIgnored event
642      val f = new Spec {
643        var theTestThisCalled = false
644        var theTestThatCalled = false
645        var theTestTheOtherCalled = false
646        ignore("test this", mytags.SlowAsMolasses, mytags.FastAsLight) { theTestThisCalled = true }
647        it("test that", mytags.SlowAsMolasses) { theTestThatCalled = true }
648        it("test the other") { theTestTheOtherCalled = true }
649      }
650      val repF = new TestIgnoredTrackingReporter
651      f.run(None, repF, new Stopper {}, Filter(Some(Set("org.scalatest.SlowAsMolasses")), Set("org.scalatest.FastAsLight")),
652                Map(), None, new Tracker)
653      assert(!repF.testIgnoredReceived)
654      assert(!f.theTestThisCalled)
655      assert(f.theTestThatCalled)
656      assert(!f.theTestTheOtherCalled)
657
658      // An Ignored test that was not included should not generate a TestIgnored event
659      val g = new Spec {
660        var theTestThisCalled = false
661        var theTestThatCalled = false
662        var theTestTheOtherCalled = false
663        it("test this", mytags.SlowAsMolasses, mytags.FastAsLight) { theTestThisCalled = true }
664        it("test that", mytags.SlowAsMolasses) { theTestThatCalled = true }
665        ignore("test the other") { theTestTheOtherCalled = true }
666      }
667      val repG = new TestIgnoredTrackingReporter
668      g.run(None, repG, new Stopper {}, Filter(Some(Set("org.scalatest.SlowAsMolasses")), Set("org.scalatest.FastAsLight")),
669                Map(), None, new Tracker)
670      assert(!repG.testIgnoredReceived)
671      assert(!g.theTestThisCalled)
672      assert(g.theTestThatCalled)
673      assert(!g.theTestTheOtherCalled)
674
675      // No tagsToInclude set, FastAsLight excluded
676      val h = new Spec {
677        var theTestThisCalled = false
678        var theTestThatCalled = false
679        var theTestTheOtherCalled = false
680        it("test this", mytags.SlowAsMolasses, mytags.FastAsLight) { theTestThisCalled = true }
681        it("test that", mytags.SlowAsMolasses) { theTestThatCalled = true }
682        it("test the other") { theTestTheOtherCalled = true }
683      }
684      val repH = new TestIgnoredTrackingReporter
685      h.run(None, repH, new Stopper {}, Filter(None, Set("org.scalatest.FastAsLight")), Map(), None, new Tracker)
686      assert(!repH.testIgnoredReceived)
687      assert(!h.theTestThisCalled)
688      assert(h.theTestThatCalled)
689      assert(h.theTestTheOtherCalled)
690
691      // No tagsToInclude set, mytags.SlowAsMolasses excluded
692      val i = new Spec {
693        var theTestThisCalled = false
694        var theTestThatCalled = false
695        var theTestTheOtherCalled = false
696        it("test this", mytags.SlowAsMolasses, mytags.FastAsLight) { theTestThisCalled = true }
697        it("test that", mytags.SlowAsMolasses) { theTestThatCalled = true }
698        it("test the other") { theTestTheOtherCalled = true }
699      }
700      val repI = new TestIgnoredTrackingReporter
701      i.run(None, repI, new Stopper {}, Filter(None, Set("org.scalatest.SlowAsMolasses")), Map(), None, new Tracker)
702      assert(!repI.testIgnoredReceived)
703      assert(!i.theTestThisCalled)
704      assert(!i.theTestThatCalled)
705      assert(i.theTestTheOtherCalled)
706
707      // No tagsToInclude set, mytags.SlowAsMolasses excluded, TestIgnored should not be received on excluded ones
708      val j = new Spec {
709        var theTestThisCalled = false
710        var theTestThatCalled = false
711        var theTestTheOtherCalled = false
712        ignore("test this", mytags.SlowAsMolasses, mytags.FastAsLight) { theTestThisCalled = true }
713        ignore("test that", mytags.SlowAsMolasses) { theTestThatCalled = true }
714        it("test the other") { theTestTheOtherCalled = true }
715      }
716      val repJ = new TestIgnoredTrackingReporter
717      j.run(None, repJ, new Stopper {}, Filter(None, Set("org.scalatest.SlowAsMolasses")), Map(), None, new Tracker)
718      assert(!repI.testIgnoredReceived)
719      assert(!j.theTestThisCalled)
720      assert(!j.theTestThatCalled)
721      assert(j.theTestTheOtherCalled)
722
723      // Same as previous, except Ignore specifically mentioned in excludes set
724      val k = new Spec {
725        var theTestThisCalled = false
726        var theTestThatCalled = false
727        var theTestTheOtherCalled = false
728        ignore("test this", mytags.SlowAsMolasses, mytags.FastAsLight) { theTestThisCalled = true }
729        ignore("test that", mytags.SlowAsMolasses) { theTestThatCalled = true }
730        ignore("test the other") { theTestTheOtherCalled = true }
731      }
732      val repK = new TestIgnoredTrackingReporter
733      k.run(None, repK, new Stopper {}, Filter(None, Set("org.scalatest.SlowAsMolasses", "org.scalatest.Ignore")), Map(), None, new Tracker)
734      assert(repK.testIgnoredReceived)
735      assert(!k.theTestThisCalled)
736      assert(!k.theTestThatCalled)
737      assert(!k.theTestTheOtherCalled)
738    }
739
740    it("should return the correct test count from its expectedTestCount method") {
741
742      val a = new Spec {
743        it("test this") {}
744        it("test that") {}
745      }
746      assert(a.expectedTestCount(Filter()) === 2)
747
748      val b = new Spec {
749        ignore("test this") {}
750        it("test that") {}
751      }
752      assert(b.expectedTestCount(Filter()) === 1)
753
754      val c = new Spec {
755        it("test this", mytags.FastAsLight) {}
756        it("test that") {}
757      }
758      assert(c.expectedTestCount(Filter(Some(Set("org.scalatest.FastAsLight")), Set())) === 1)
759      assert(c.expectedTestCount(Filter(None, Set("org.scalatest.FastAsLight"))) === 1)
760
761      val d = new Spec {
762        it("test this", mytags.FastAsLight, mytags.SlowAsMolasses) {}
763        it("test that", mytags.SlowAsMolasses) {}
764        it("test the other thing") {}
765      }
766      assert(d.expectedTestCount(Filter(Some(Set("org.scalatest.FastAsLight")), Set())) === 1)
767      assert(d.expectedTestCount(Filter(Some(Set("org.scalatest.SlowAsMolasses")), Set("org.scalatest.FastAsLight"))) === 1)
768      assert(d.expectedTestCount(Filter(None, Set("org.scalatest.SlowAsMolasses"))) === 1)
769      assert(d.expectedTestCount(Filter()) === 3)
770
771      val e = new Spec {
772        it("test this", mytags.FastAsLight, mytags.SlowAsMolasses) {}
773        it("test that", mytags.SlowAsMolasses) {}
774        ignore("test the other thing") {}
775      }
776      assert(e.expectedTestCount(Filter(Some(Set("org.scalatest.FastAsLight")), Set())) === 1)
777      assert(e.expectedTestCount(Filter(Some(Set("org.scalatest.SlowAsMolasses")), Set("org.scalatest.FastAsLight"))) === 1)
778      assert(e.expectedTestCount(Filter(None, Set("org.scalatest.SlowAsMolasses"))) === 0)
779      assert(e.expectedTestCount(Filter()) === 2)
780
781      val f = new Suites(a, b, c, d, e)
782      assert(f.expectedTestCount(Filter()) === 10)
783    }
784
785    it("should generate a TestPending message when the test body is (pending)") {
786
787      val a = new Spec {
788
789        it("should do this") (pending)
790
791        it("should do that") {
792          assert(2 + 2 === 4)
793        }
794
795        it("should do something else") {
796          assert(2 + 2 === 4)
797          pending
798        }
799      }
800
801      val rep = new EventRecordingReporter
802      a.run(None, rep, new Stopper {}, Filter(), Map(), None, new Tracker())
803      val tp = rep.testPendingEventsReceived
804      assert(tp.size === 2)
805    }
806    it("should generate a test failure if a Throwable, or an Error other than direct Error subtypes " +
807            "known in JDK 1.5, excluding AssertionError") {
808      val a = new Spec {
809        it("throws AssertionError") { throw new AssertionError }
810        it("throws plain old Error") { throw new Error }
811        it("throws Throwable") { throw new Throwable }
812      }
813      val rep = new EventRecordingReporter
814      a.run(None, rep, new Stopper {}, Filter(), Map(), None, new Tracker())
815      val tf = rep.testFailedEventsReceived
816      assert(tf.size === 3)
817    }
818    it("should propagate out Errors that are direct subtypes of Error in JDK 1.5, other than " +
819            "AssertionError, causing Suites and Runs to abort.") {
820      val a = new Spec {
821        it("throws AssertionError") { throw new OutOfMemoryError }
822      }
823      intercept[OutOfMemoryError] {
824        a.run(None, SilentReporter, new Stopper {}, Filter(), Map(), None, new Tracker())
825      }
826    }
827    it("should send InfoProvided events with aboutAPendingTest set to true for info " +
828            "calls made from a test that is pending") {
829      val a = new Spec with GivenWhenThen {
830        it("should do something else") {
831          given("two integers")
832          when("one is subracted from the other")
833          then("the result is the difference between the two numbers")
834          pending
835        }
836      }
837      val rep = new EventRecordingReporter
838      a.run(None, rep, new Stopper {}, Filter(), Map(), None, new Tracker())
839      val ip = rep.infoProvidedEventsReceived
840      assert(ip.size === 3)
841      for (event <- ip) {
842        assert(event.aboutAPendingTest.isDefined && event.aboutAPendingTest.get)
843      }
844    }
845    it("should send InfoProvided events with aboutAPendingTest set to false for info " +
846            "calls made from a test that is not pending") {
847      val a = new Spec with GivenWhenThen {
848        it("should do something else") {
849          given("two integers")
850          when("one is subracted from the other")
851          then("the result is the difference between the two numbers")
852          assert(1 + 1 === 2)
853        }
854      }
855      val rep = new EventRecordingReporter
856      a.run(None, rep, new Stopper {}, Filter(), Map(), None, new Tracker())
857      val ip = rep.infoProvidedEventsReceived
858      assert(ip.size === 3)
859      for (event <- ip) {
860        assert(event.aboutAPendingTest.isDefined && !event.aboutAPendingTest.get)
861      }
862    }
863  }
864}
865
866