/
SimpleParentRunner.scala
76 lines (63 loc) · 2.59 KB
/
SimpleParentRunner.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.typesafe.slick.testkit.util
import org.junit.runner.{Runner, Description}
import org.junit.runner.notification.{StoppedByUserException, Failure, RunNotifier}
import org.junit.runner.manipulation._
import org.junit.runners.model._
import scala.collection.JavaConverters._
import java.lang.reflect.InvocationTargetException
/**
* A JUnit Runner similar to JUnit's own ParentRunner but simpler, more
* extensible (in the way we need it), and more Scala-like.
*/
abstract class SimpleParentRunner[T](testClass: Class[_]) extends Runner with Filterable with Sortable {
private var _children: Seq[T] = null
protected final def children = {
if(_children == null) _children = getChildren
_children
}
protected final def children_= (s: Seq[T]) = _children = s
protected def getChildren: Seq[T]
protected def describeChild(child: T): Description
protected def runChildInner(child: T, notifier: RunNotifier) = ???
protected def runChild(child: T, notifier: RunNotifier): Unit = {
val desc = describeChild(child)
notifier.fireTestStarted(desc)
try runChildInner(child, notifier) catch {
case t: Throwable => addFailure(t, notifier, desc)
} finally notifier.fireTestFinished(desc)
}
protected def runChildren(notifier: RunNotifier) =
children.foreach(ch => runChild(ch, notifier))
protected final def addFailure(t: Throwable, notifier: RunNotifier, desc: Description): Unit = t match {
case t: MultipleFailureException =>
t.getFailures.asScala.foreach(t2 => addFailure(t2, notifier, desc))
case i: InvocationTargetException =>
addFailure(i.getTargetException, notifier, desc)
case t: Throwable =>
notifier.fireTestFailure(new Failure(desc, t))
}
def getDescription = {
val desc = Description.createSuiteDescription(testClass.getName, testClass.getAnnotations: _*)
for(ch <- children) desc.addChild(describeChild(ch))
desc
}
def run(notifier: RunNotifier) {
try runChildren(notifier) catch {
case e: StoppedByUserException => throw e
case e: Throwable => addFailure(e, notifier, getDescription)
}
}
final def filter(filter: Filter) {
children = children.filter { ch =>
if(!filter.shouldRun(describeChild(ch))) false
else try { filter.apply(ch); true } catch { case _: NoTestsRemainException => false }
}
if(children.isEmpty) throw new NoTestsRemainException
}
final def sort(sorter: Sorter) {
children.foreach(sorter.apply _)
children = children.sorted(new Ordering[T] {
def compare(o1: T, o2: T): Int = sorter.compare(describeChild(o1), describeChild(o2))
})
}
}