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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
package com.iinteractive.test.harness
/** This is the entry point to running tests written with this library from
* the command line. Note that this library also implements the
* [[https://github.com/harrah/test-interface common testing interface]] for
* test libraries, so tests should also just work with `sbt test`.
*
* If this application is run and given just a single test class name, it
* will run that test and write its TAP stream to the console.
*
* {{{
* $ scala com.iinteractive.test.harness.TestHarness MyTest
* ok 1
* ok 2
* 1..2
* }}}
*
* If this application is run and given multiple test class names, it will
* run each of those tests, and present a summary report, similar to the one
* produces by
* [[https://metacpan.org/module/Test::Harness Perl's Test::Harness]].
*
* {{{
* $ scala com.iinteractive.test.harness.TestHarness MyTest1 MyTest2
* MyTest1 .. ok
* MyTest2 .. ok
* All tests successful.
* Files=2, Tests=4
* Result: PASS
* }}}
*
* This application also accepts a few command line options to customize its
* behavior:
*
* - `-r`: Alternative [[com.iinteractive.test.harness.Reporter Reporter]]
* class to use for running a single test.
* - `-R`: Alternative
* [[com.iinteractive.test.harness.MultiTestReporter MultiTestReporter]]
* class to use for running a group of tests. Also enables using the
* MultiTestReporter for a single test.
* - `--help`: Prints usage information.
*/
object TestHarness {
import com.iinteractive.test.Test
/** Entry point for the harness application. */
def main (args: Array[String]) {
val opts = parseOpts(args.toList)
val single = opts("prefer-single").asInstanceOf[Boolean]
val exitCode = if (single) {
val reporterName = opts("single-reporter").asInstanceOf[String]
val testName = opts("test-classes").asInstanceOf[List[String]].apply(0)
val reporter = newInstance[Reporter](reporterName)
reporter.run(testName)
}
else {
val reporterName = opts("multi-reporter").asInstanceOf[String]
val testNames = opts("test-classes").asInstanceOf[List[String]]
val reporter = newInstance[MultiTestReporter](reporterName)
reporter.run(testNames)
}
sys.exit(exitCode)
}
protected def parseOpts (args: List[String]): Map[String, Any] = args match {
case Nil => Map(
"single-reporter" -> "com.iinteractive.test.harness.TAPReporter",
"multi-reporter" -> "com.iinteractive.test.harness.SummaryReporter",
"prefer-single" -> true,
"test-classes" -> Nil
)
case "-r" :: singleReporter :: rest =>
parseOpts(rest) + ("single-reporter" -> singleReporter)
case "-R" :: multiReporter :: rest =>
parseOpts(rest) ++ Map(
"multi-reporter" -> multiReporter,
"prefer-single" -> false
)
case "--help" :: rest =>
usage(0)
case `unknownOption` :: rest =>
usage(1)
case testClass :: rest => {
val opts = parseOpts(rest)
val tests = opts("test-classes").asInstanceOf[List[String]]
opts ++ Map(
"test-classes" -> (testClass :: tests),
"prefer-single" -> tests.isEmpty
)
}
}
protected def usage (exitCode: Int) = {
val out = if (exitCode == 0) Console.out else Console.err
out.println("harness [-r <single-reporter-class>]\n" +
" [-R <multi-reporter-class>]\n" +
" [--help]\n" +
" <test-class> [<test-class>...]\n")
sys.exit(exitCode)
}
private val unknownOption = """^-.*""".r
}
|