-
-
Notifications
You must be signed in to change notification settings - Fork 609
/
SimpleParentRunner.scala
73 lines (61 loc) · 2.39 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
package com.typesafe.slick.testkit.util
import java.lang.reflect.InvocationTargetException
import scala.jdk.CollectionConverters.*
import org.junit.runner.{Description, Runner}
import org.junit.runner.manipulation.{Ordering as _, *}
import org.junit.runner.notification.{Failure, RunNotifier, StoppedByUserException}
import org.junit.runners.model.*
/**
* 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] = _
protected final def children: Seq[T] = {
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 runChildren(notifier: RunNotifier): Unit
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 annotations = testClass.getAnnotations
val desc = Description.createSuiteDescription(testClass.getName, annotations *)
for(ch <- children) desc.addChild(describeChild(ch))
desc
}
def run(notifier: RunNotifier): Unit = {
val description = getDescription
notifier.fireTestSuiteStarted(description)
try runChildren(notifier)
catch {
case e: StoppedByUserException => throw e
case e: Throwable => addFailure(e, notifier, description)
}
finally notifier.fireTestSuiteFinished(description)
}
final def filter(filter: Filter): Unit = {
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): Unit = {
children.foreach(sorter.apply)
children =
children.sorted(
Ordering.comparatorToOrdering(sorter)
.on(describeChild)
)
}
}