aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2013-02-28 02:47:37 -0600
committerJesse Luehrs <doy@tozt.net>2013-02-28 02:48:25 -0600
commit6f4f0015aa32de0e2eda11bfa11144961fd70480 (patch)
tree814c4f937b6ccb7e66e1c6fe7ce6c5c61e3949f4 /src
parente071cf04ba20fd1608f138abe6e03878c7fe70bf (diff)
downloadscala-test-more-6f4f0015aa32de0e2eda11bfa11144961fd70480.tar.gz
scala-test-more-6f4f0015aa32de0e2eda11bfa11144961fd70480.zip
eliminate Message
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/org/perl8/test/TestMore.scala217
-rw-r--r--src/main/scala/org/perl8/test/package.scala24
-rw-r--r--src/main/scala/org/perl8/test/tap/Producer.scala63
-rw-r--r--src/main/scala/org/perl8/test/tap/TestBuilder.scala75
-rw-r--r--src/test/scala/org/perl8/test/TestMoreTest.scala6
-rw-r--r--src/test/scala/org/perl8/test/tap/TestBuilderTest.scala14
6 files changed, 223 insertions, 176 deletions
diff --git a/src/main/scala/org/perl8/test/TestMore.scala b/src/main/scala/org/perl8/test/TestMore.scala
index 98962b0..21ef449 100644
--- a/src/main/scala/org/perl8/test/TestMore.scala
+++ b/src/main/scala/org/perl8/test/TestMore.scala
@@ -7,7 +7,7 @@ import org.perl8.test.tap.TestBuilder
class TestMore (plan: Plan = NoPlan) extends Test with DelayedInit {
def delayedInit (body: => Unit) {
testBody = { terminalInUse =>
- todo = NoMessage
+ todo = None
builder = new TestBuilder(plan, terminalInUse)
body
}
@@ -23,80 +23,64 @@ class TestMore (plan: Plan = NoPlan) extends Test with DelayedInit {
builder.exitCode
}
- def ok (cond: Boolean, desc: Message = NoMessage): Boolean = {
- builderOk(cond, desc)
- if (!cond) {
- failed(desc)
- }
- cond
- }
+ def ok (cond: Boolean): Boolean =
+ test(cond)
- def is[T] (got: T, expected: T, desc: Message = NoMessage): Boolean = {
- val cond = got == expected
- builderOk(cond, desc)
- if (!cond) {
- val reason =
- " got: '" + got + "'\n" +
- " expected: '" + expected + "'\n"
- failed(desc, reason)
- }
- cond
- }
+ def ok (cond: Boolean, desc: String): Boolean =
+ testWithDesc(cond, desc)
- def isnt[T] (got: T, expected: T, desc: Message = NoMessage): Boolean = {
- val cond = got != expected
- builderOk(cond, desc)
- if (!cond) {
- val reason =
- " got: '" + got + "'\n" +
- " expected: anything else\n"
- failed(desc, reason)
- }
- cond
- }
+ def is[T] (got: T, expected: T): Boolean =
+ test(got == expected, isMessage(got, expected))
- def like (got: String, rx: Regex, desc: Message = NoMessage): Boolean = {
- val cond = rx.findFirstIn(got).nonEmpty
- builderOk(cond, desc)
- if (!cond) {
- val reason =
- " '" + got + "'\n" +
- " doesn't match '" + rx + "'\n"
- failed(desc, reason)
- }
- cond
- }
+ def is[T] (got: T, expected: T, desc: String): Boolean =
+ testWithDesc(got == expected, desc, isMessage(got, expected))
- def unlike (got: String, rx: Regex, desc: Message = NoMessage): Boolean = {
- val cond = rx.findFirstIn(got).isEmpty
- builderOk(cond, desc)
- if (!cond) {
- val reason =
- " '" + got + "'\n" +
- " matches '" + rx + "'\n"
- failed(desc, reason)
- }
- cond
- }
+ def isnt[T] (got: T, expected: T): Boolean =
+ test(got != expected, isntMessage(got))
+
+ def isnt[T] (got: T, expected: T, desc: String): Boolean =
+ testWithDesc(got != expected, desc, isntMessage(got))
+
+ def like (got: String, rx: Regex): Boolean =
+ test(rx.findFirstIn(got).nonEmpty, likeMessage(got, rx))
- def pass (desc: Message = NoMessage): Boolean =
+ def like (got: String, rx: Regex, desc: String): Boolean =
+ testWithDesc(rx.findFirstIn(got).nonEmpty, desc, likeMessage(got, rx))
+
+ def unlike (got: String, rx: Regex): Boolean =
+ test(rx.findFirstIn(got).isEmpty, unlikeMessage(got, rx))
+
+ def unlike (got: String, rx: Regex, desc: String): Boolean =
+ testWithDesc(rx.findFirstIn(got).isEmpty, desc, unlikeMessage(got, rx))
+
+ def pass: Boolean =
+ ok(true)
+
+ def pass (desc: String): Boolean =
ok(true, desc)
- def fail (desc: Message = NoMessage): Boolean =
+ def fail: Boolean =
+ ok(false)
+
+ def fail (desc: String): Boolean =
ok(false, desc)
def diag (message: String) {
builder.diag(message)
}
- def BAIL_OUT (desc: Message = NoMessage) {
+ def BAIL_OUT {
+ builder.bailOut
+ }
+
+ def BAIL_OUT (desc: String) {
builder.bailOut(desc)
}
- def todo (reason: Message = NoMessage)(body: => Unit) {
+ def todo (reason: String)(body: => Unit) {
val oldTodo = todo
try {
- todo = reason
+ todo = Some(reason)
body
}
finally {
@@ -104,14 +88,20 @@ class TestMore (plan: Plan = NoPlan) extends Test with DelayedInit {
}
}
- def skip (count: Int, reason: Message = NoMessage)(body: => Unit) {
+ def skip (count: Int)(body: => Unit) {
+ for (i <- 1 to count) {
+ builder.skip
+ }
+ }
+
+ def skip (count: Int, reason: String)(body: => Unit) {
for (i <- 1 to count) {
builder.skip(reason)
}
}
def subtest (
- name: Message,
+ name: String,
plan: Plan = NoPlan
)(body: => Unit): Boolean = {
val oldBuilder = builder
@@ -126,32 +116,74 @@ class TestMore (plan: Plan = NoPlan) extends Test with DelayedInit {
ok(success, name)
}
- protected def ignoreFrame (frame: StackTraceElement): Boolean = {
- val className = frame.getClassName
- val methodName = frame.getMethodName
+ private def isMessage[T] (got: T, expected: T): String =
+ " got: '" + got + "'\n" +
+ " expected: '" + expected + "'\n"
- // ignore everything in this class, except the hideTestMethod call which we
- // use as a stack trace marker
- (className == "org.perl8.test.TestMore" &&
- methodName != "hideTestMethod") ||
- // when you call a method in a class when the method is defined in a
- // trait, it calls a stub which calls the real definition in the trait.
- // the trait is represented under the hood as a class with the same name
- // as the trait, except with $class appended. this is a gross reliance on
- // implementation details that could change at any moment, but i don't
- // really see any better options.
- """\$class$""".r.findFirstIn(className).nonEmpty
+ private def isntMessage[T] (got: T): String =
+ " got: '" + got + "'\n" +
+ " expected: anything else\n"
+
+ private def likeMessage (got: String, rx: Regex): String =
+ " '" + got + "'\n" +
+ " doesn't match '" + rx + "'\n"
+
+ private def unlikeMessage (got: String, rx: Regex): String =
+ " '" + got + "'\n" +
+ " matches '" + rx + "'\n"
+
+ private def testWithDesc (
+ cond: Boolean,
+ desc: String
+ ): Boolean = {
+ todo match {
+ case Some(t) => builder.okTodo(cond, "- " + desc, t)
+ case None => builder.ok(cond, "- " + desc)
+ }
+ if (!cond) {
+ failed(Some(desc), None)
+ }
+ cond
}
- private def builderOk (cond: Boolean, desc: Message) {
- builder.ok(cond, desc.map(d => "- " + d), todo)
+ private def testWithDesc (
+ cond: Boolean,
+ desc: String,
+ reason: => String
+ ): Boolean = {
+ todo match {
+ case Some(t) => builder.okTodo(cond, "- " + desc, t)
+ case None => builder.ok(cond, "- " + desc)
+ }
+ if (!cond) {
+ failed(Some(desc), Some(reason))
+ }
+ cond
+ }
+
+ private def test (cond: Boolean): Boolean = {
+ todo match {
+ case Some(t) => builder.okTodo(cond, t)
+ case None => builder.ok(cond)
+ }
+ if (!cond) {
+ failed(None, None)
+ }
+ cond
}
- private def failed (desc: Message, reason: String) {
- failed(desc, Some(reason))
+ private def test (cond: Boolean, reason: => String): Boolean = {
+ todo match {
+ case Some(t) => builder.okTodo(cond, t)
+ case None => builder.ok(cond)
+ }
+ if (!cond) {
+ failed(None, Some(reason))
+ }
+ cond
}
- private def failed (desc: Message, reason: Option[String] = None) {
+ private def failed (desc: Option[String], reason: Option[String]) {
val stack = Thread.currentThread.getStackTrace.drop(1).filter { frame =>
!ignoreFrame(frame)
}
@@ -171,11 +203,11 @@ class TestMore (plan: Plan = NoPlan) extends Test with DelayedInit {
case None => ("<unknown file>", "<unknown line>")
}
val message = " " + (todo match {
- case HasMessage(_) => "Failed (TODO) test"
- case NoMessage => "Failed test"
+ case Some(_) => "Failed (TODO) test"
+ case None => "Failed test"
}) + (desc match {
- case HasMessage(m) => " '" + m + "'\n "
- case NoMessage => " "
+ case Some(m) => " '" + m + "'\n "
+ case None => " "
})
val trace = "at " + file + " line " + line + "."
builder.diag(message + trace + reason.map("\n" + _).getOrElse(""))
@@ -187,7 +219,24 @@ class TestMore (plan: Plan = NoPlan) extends Test with DelayedInit {
body
}
- private var todo: Message = _
- private var builder: TestBuilder = _
+ protected def ignoreFrame (frame: StackTraceElement): Boolean = {
+ val className = frame.getClassName
+ val methodName = frame.getMethodName
+
+ // ignore everything in this class, except the hideTestMethod call which we
+ // use as a stack trace marker
+ (className == "org.perl8.test.TestMore" &&
+ methodName != "hideTestMethod") ||
+ // when you call a method in a class when the method is defined in a
+ // trait, it calls a stub which calls the real definition in the trait.
+ // the trait is represented under the hood as a class with the same name
+ // as the trait, except with $class appended. this is a gross reliance on
+ // implementation details that could change at any moment, but i don't
+ // really see any better options.
+ """\$class$""".r.findFirstIn(className).nonEmpty
+ }
+
+ private var todo: Option[String] = _
+ private var builder: TestBuilder = _
private var testBody: Boolean => Unit = _
}
diff --git a/src/main/scala/org/perl8/test/package.scala b/src/main/scala/org/perl8/test/package.scala
index 5d7ba32..b18dc2f 100644
--- a/src/main/scala/org/perl8/test/package.scala
+++ b/src/main/scala/org/perl8/test/package.scala
@@ -6,9 +6,6 @@ package object test {
implicit def intToPlan (p: Int): Plan =
NumericPlan(p)
- implicit def stringToMessage (s: String): Message =
- new HasMessage(s)
-
sealed trait Plan {
val plan: Int
val skipAll: Boolean
@@ -42,22 +39,7 @@ package object test {
def apply () = SkipAllNoMessage
}
- sealed trait Message
- case class HasMessage (contents: String) extends Message
- case object NoMessage extends Message
-
- implicit def messageToOption (message: Message): Option[String] =
- message match {
- case HasMessage(x) => Some(x)
- case NoMessage => None
- }
-
- implicit def optionToMessage (option: Option[String]): Message =
- option match {
- case Some(x) => HasMessage(x)
- case None => NoMessage
- }
-
- case class BailOutException (message: String)
- extends RuntimeException(message)
+ case class BailOutException (
+ message: String
+ ) extends RuntimeException(message)
}
diff --git a/src/main/scala/org/perl8/test/tap/Producer.scala b/src/main/scala/org/perl8/test/tap/Producer.scala
index 4b45970..52c72c9 100644
--- a/src/main/scala/org/perl8/test/tap/Producer.scala
+++ b/src/main/scala/org/perl8/test/tap/Producer.scala
@@ -3,42 +3,39 @@ package org.perl8.test.tap
object Producer {
import org.perl8.test._
- def result (
- cond: Boolean,
- num: Int,
- desc: Message = NoMessage,
- todo: Message = NoMessage
- ): String =
- join(
- (if (!cond) Some("not") else None),
- Some("ok"),
- Some(num),
- desc,
- todo.map(t => "# TODO " + t)
- )
-
- def skip (num: Int, reason: Message = NoMessage): String =
- join(
- Some("ok"),
- Some(num),
- Some("# skip"),
- reason
- )
+ def result (cond: Boolean, num: Int): String =
+ (if (cond) "ok " else "not ok ") + num
+
+ def result (cond: Boolean, num: Int, desc: String): String =
+ result(cond, num) + " " + desc
+
+ def todoResult (cond: Boolean, num: Int, todo: String): String =
+ result(cond, num) + " # TODO " + todo
+
+ def todoResult (cond: Boolean, num: Int, desc: String, todo: String): String =
+ result(cond, num, desc) + " # TODO " + todo
+
+ def skip (num: Int): String =
+ "ok " + num + " # skip"
+
+ def skip (num: Int, reason: String): String =
+ skip(num) + " " + reason
def comment (message: String): String =
message.split("\n").map(m => "# " + m).mkString("\n")
def plan (plan: Plan): String =
- join(
- Some("1.." + plan.plan),
- (if (plan.skipAll || plan.message.isDefined) Some("#") else None),
- (if (plan.skipAll) Some("SKIP") else None),
- plan.message
- )
-
- def bailOut (message: Message = NoMessage) =
- join(Some("Bail out!"), message)
-
- private def join (strings: Option[Any]*): String =
- strings.flatMap(x => x).mkString(" ")
+ if (plan.skipAll) {
+ val skip = "1..0 # SKIP"
+ plan.message.map(m => skip + " " + m).getOrElse(skip)
+ }
+ else {
+ "1.." + plan.plan
+ }
+
+ def bailOut: String =
+ "Bail out!"
+
+ def bailOut (message: String): String =
+ "Bail out! " + message
}
diff --git a/src/main/scala/org/perl8/test/tap/TestBuilder.scala b/src/main/scala/org/perl8/test/tap/TestBuilder.scala
index 432f902..99465fd 100644
--- a/src/main/scala/org/perl8/test/tap/TestBuilder.scala
+++ b/src/main/scala/org/perl8/test/tap/TestBuilder.scala
@@ -18,55 +18,74 @@ class TestBuilder private (
def cloneForSubtest (newPlan: Plan): TestBuilder =
new TestBuilder(newPlan, indent + " ", terminalInUse)
- def ok (
- test: Boolean,
- description: Message = NoMessage,
- todo: Message = NoMessage
- ) {
- val line = Producer.result(test, state.currentTest, description, todo)
- state.ok(test || todo.isDefined)
- outLine(line)
+ def ok (test: Boolean) {
+ state.ok(test)
+ outLine(Producer.result(test, state.currentTest))
}
- def skip (reason: Message = NoMessage) {
- val line = Producer.skip(state.currentTest, reason)
+ def ok (test: Boolean, description: String) {
+ state.ok(test)
+ outLine(Producer.result(test, state.currentTest, description))
+ }
+
+ def okTodo (test: Boolean, todo: String) {
state.ok(true)
- outLine(line)
+ outLine(Producer.todoResult(test, state.currentTest, todo))
}
- def diag (message: Message) {
- message.foreach { m =>
- errLine(Producer.comment(m))
- }
+ def okTodo (test: Boolean, description: String, todo: String) {
+ state.ok(true)
+ outLine(Producer.todoResult(test, state.currentTest, description, todo))
+ }
+
+ def skip {
+ state.ok(true)
+ outLine(Producer.skip(state.currentTest))
+ }
+
+ def skip (reason: String) {
+ state.ok(true)
+ outLine(Producer.skip(state.currentTest, reason))
+ }
+
+ def diag (message: String) {
+ errLine(Producer.comment(message))
+ }
+
+ def note (message: String) {
+ outLine(Producer.comment(message))
}
- def note (message: Message) {
- message.foreach(m => outLine(Producer.comment(m)))
+ def bailOut {
+ val bailOutMessage = Producer.bailOut
+ outLine(bailOutMessage)
+ throw new BailOutException(bailOutMessage)
}
- def bailOut (message: Message = NoMessage) {
- outLine(Producer.bailOut(message))
- throw new BailOutException(message.getOrElse(""))
+ def bailOut (message: String) {
+ val bailOutMessage = Producer.bailOut(message)
+ outLine(bailOutMessage)
+ throw new BailOutException(bailOutMessage)
}
def doneTesting: Boolean = {
plan match {
- case NoPlan => outLine(Producer.plan(state.currentTest - 1))
+ case NoPlan => outLine(Producer.plan(state.currentTest))
case _ => ()
}
if (!state.isPassing) {
if (!state.matchesPlan) {
val planCount = (plan match {
- case NoPlan => state.currentTest - 1
+ case NoPlan => state.currentTest
case p => p.plan
})
val planned = planCount + " test" + (if (planCount > 1) "s" else "")
- val ran = state.currentTest - 1
+ val ran = state.currentTest
diag("Looks like you planned " + planned + " but ran " + ran + ".")
}
- if (state.currentTest == 1) {
+ if (state.currentTest == 0) {
diag("No tests run!")
}
@@ -74,7 +93,7 @@ class TestBuilder private (
val count = state.failCount
val fails = count + " test" + (if (count > 1) "s" else "")
val total =
- state.currentTest - 1 + (if (state.matchesPlan) "" else " run")
+ state.currentTest + (if (state.matchesPlan) "" else " run")
diag("Looks like you failed " + fails + " of " + total + ".")
}
}
@@ -126,14 +145,14 @@ class TestBuilder private (
}
def currentTest: Int =
- failCount + passCount + 1
+ failCount + passCount
def matchesPlan: Boolean = plan match {
- case NumericPlan(p) => p.plan == failCount + passCount
+ case NumericPlan(p) => p.plan == currentTest
case _ => true
}
def isPassing: Boolean =
- currentTest > 1 && failCount == 0 && matchesPlan
+ currentTest > 0 && failCount == 0 && matchesPlan
}
}
diff --git a/src/test/scala/org/perl8/test/TestMoreTest.scala b/src/test/scala/org/perl8/test/TestMoreTest.scala
index 8555a71..317aaaf 100644
--- a/src/test/scala/org/perl8/test/TestMoreTest.scala
+++ b/src/test/scala/org/perl8/test/TestMoreTest.scala
@@ -43,17 +43,17 @@ class TestMoreTest extends TestMore {
diag("pass")
pass("it works!")
- pass()
+ pass
skip(2, "don't do this yet") {
pass("skipped")
- pass()
+ pass
}
todo("not working yet") {
diag("fail")
fail("it doesn't work")
- fail()
+ fail
}
}
diff --git a/src/test/scala/org/perl8/test/tap/TestBuilderTest.scala b/src/test/scala/org/perl8/test/tap/TestBuilderTest.scala
index 6aff4a1..d59541a 100644
--- a/src/test/scala/org/perl8/test/tap/TestBuilderTest.scala
+++ b/src/test/scala/org/perl8/test/tap/TestBuilderTest.scala
@@ -160,19 +160,19 @@ class TestBuilderTest extends TestMore {
builder.bailOut("oh no!")
Console.withOut(oldOut) {
Console.withErr(oldErr) {
- fail()
+ fail
}
}
}
catch {
case e: BailOutException => Console.withOut(oldOut) {
Console.withErr(oldErr) {
- is(e.message, "oh no!")
+ is(e.message, "Bail out! oh no!")
}
}
case _: Throwable => Console.withOut(oldOut) {
Console.withErr(oldErr) {
- fail()
+ fail
}
}
}
@@ -181,7 +181,7 @@ class TestBuilderTest extends TestMore {
val expected =
"ok 1\n" +
- "Bail out! oh no!\n"
+ "Bail out! oh no!\n"
is(output.toString, expected)
}
@@ -221,7 +221,7 @@ class TestBuilderTest extends TestMore {
val builder = new TestBuilder
builder.ok(false)
builder.skip("not now")
- builder.skip()
+ builder.skip
builder.doneTesting
}
}
@@ -241,8 +241,8 @@ class TestBuilderTest extends TestMore {
Console.withOut(output) {
Console.withErr(output) {
val builder = new TestBuilder
- builder.ok(false, "do a thing", todo = "not working yet")
- builder.ok(true, todo = "is it?")
+ builder.okTodo(false, "do a thing", todo = "not working yet")
+ builder.okTodo(true, todo = "is it?")
builder.doneTesting
}
}