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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
package org.perl8.test
import scala.util.matching.Regex
import org.perl8.test.tap.TestBuilder
class TestMore (plan: Option[Plan] = None) extends Test with DelayedInit {
def this (plan: Plan) =
this(Some(plan))
def delayedInit (body: => Unit) {
level = 0
todo = NoMessage
builder = new TestBuilder(plan, "", NoMessage)
testBody = () => body
}
def run (): Int = {
if (testBody == null) {
delayedInit { }
}
testBody()
builder.doneTesting
builder.exitCode
}
def ok (cond: Boolean, desc: Message = NoMessage): Boolean = {
builder.ok(cond, desc.map(d => "- " + d), todo)
if (!cond) {
failed(desc)
}
cond
}
def is[T] (got: T, expected: T, desc: Message = NoMessage): Boolean = {
val cond = ok(got == expected, desc)
if (!cond) {
builder.diag(" got: '" + got + "'")
builder.diag(" expected: '" + expected + "'")
}
cond
}
def isnt[T] (got: T, expected: T, desc: Message = NoMessage): Boolean = {
val cond = ok(got != expected, desc)
if (!cond) {
builder.diag(" got: '" + got + "'")
builder.diag(" expected: anything else")
}
cond
}
def like (got: String, rx: Regex, desc: Message = NoMessage): Boolean = {
val cond = ok(rx.findFirstIn(got).nonEmpty, desc)
if (!cond) {
builder.diag(" '" + got + "'")
builder.diag(" doesn't match '" + rx + "'")
}
cond
}
def unlike (got: String, rx: Regex, desc: Message = NoMessage): Boolean = {
val cond = ok(rx.findFirstIn(got).isEmpty, desc)
if (!cond) {
builder.diag(" '" + got + "'")
builder.diag(" matches '" + rx + "'")
}
cond
}
def pass (desc: Message = NoMessage): Boolean =
ok(true, desc)
def fail (desc: Message = NoMessage): Boolean =
ok(false, desc)
def diag (message: String) {
builder.diag(message)
}
def BAIL_OUT (desc: Message = NoMessage) {
builder.bailOut(desc)
}
def todo (reason: Message = NoMessage)(body: => Unit) {
val oldTodo = todo
try {
todo = reason
body
}
finally {
todo = oldTodo
}
}
def skip (count: Int, reason: Message = NoMessage)(body: => Unit) {
for (i <- 1 to count) {
builder.skip(reason)
}
}
def subtest (name: Message, plan: Plan)(body: => Unit): Boolean =
subtest(name, Some(plan))(body)
def subtest (
name: Message,
plan: Option[Plan] = None
)(body: => Unit): Boolean = {
val oldBuilder = builder
val success = try {
builder = new TestBuilder(
plan,
oldBuilder.indent + " ",
name.map(n => "- " + n)
)
body
builder.doneTesting
}
finally {
builder = oldBuilder
}
ok(success, name)
}
private def failed (desc: Message) {
val stack = Thread.currentThread.getStackTrace.drop(1)
def findIdx (level: Int, start: Int): Int = {
val idx = stack.indexWhere({ frame =>
frame.getFileName != "TestMore.scala"
}, start)
if (level == 0) { idx } else { findIdx(level - 1, idx + 1) }
}
val idx = findIdx(level, 0)
val caller = stack.drop(idx).headOption
val (file, line) = caller match {
case Some(frame) => (frame.getFileName, frame.getLineNumber)
case None => ("<unknown file>", "<unknown line>")
}
val message = " " + (todo match {
case HasMessage(_) => "Failed (TODO) test"
case NoMessage => "Failed test"
}) + (desc match {
case HasMessage(m) => " '" + m + "'\n "
case NoMessage => " "
})
val trace = "at " + file + " line " + line + "."
builder.diag(message + trace)
}
def withLevel[T] (newLevel: Int)(body: => T): T = {
val oldLevel = level
try {
// XXX "+4" is something of a hack, not sure how stable it will be
level += newLevel + 4
body
}
finally {
level = oldLevel
}
}
private var level: Int = _
private var todo: Message = _
private var builder: TestBuilder = _
private var testBody: () => Unit = _
}
|