Skip to content

Instantly share code, notes, and snippets.

@kaja47
Created October 12, 2012 20:20
Show Gist options
  • Save kaja47/3881286 to your computer and use it in GitHub Desktop.
Save kaja47/3881286 to your computer and use it in GitHub Desktop.
String Calculator TDD kata
import java.util.regex.Pattern
def add(numbers: String, delimiters: Seq[String] = Seq(",")): Int = {
val delimRegex = "^//(.+?)\n(.*)$".r
val multiDelim = "^//(\\[.+?\\])\n(.*)$".r
numbers match {
case "" => 0
case multiDelim(dels, ns) => add(ns, dels.init.tail split "\\]\\[")
case delimRegex(del, ns) => add(ns, Seq(del))
case ns =>
val mkDelim = (delimiters :+ "\n") map Pattern.quote mkString ("(", "|", ")")
val ints = ns split mkDelim map (_.toInt)
val negs = ints filter (_ < 0)
if (negs nonEmpty) throw new Exception(negs mkString ",")
else ints filter (_ <= 1000) sum
}
}
def tests = Seq[(String, Boolean)](
"zero" -> (add("") == 0),
"1 num" -> (add("1") == 1),
"1 num" -> (add("0") == 0),
"1 num" -> (add("9") == 9),
"2 nums" -> (add("1,2") == 3),
"2 nums" -> (add("0,0") == 0),
"2 nums" -> (add("9,1") == 10),
"3 nums" -> (add("1,2,3") == 6),
"3 nums" -> (add("0,0,0") == 0),
"3 nums" -> (add("9,1,10") == 20),
"many nums" -> (add("1,1,1,1,1,1,1,1,1,1") == 10),
"newlines" -> (add("1\n2") == 3),
"newlines" -> (add("1\n2,3") == 6),
"newlines" -> (add("1,2\n3") == 6),
"newlines" -> (add("1\n2\n3") == 6),
"delims" -> (add("//;\n1") == 1),
"delims" -> (add("//;\n1;2;3") == 6),
"delims" -> (add("//*\n1*2*3") == 6),
"delims" -> (add("//.\n1.2.3") == 6),
"negs" -> excMsg(add("-1"), "-1"),
"negs" -> excMsg(add("-1,1"), "-1"),
"negs" -> excMsg(add("-1,-1"), "-1,-1"),
"bigs" -> (add("2,1001") == 2),
"bigs" -> (add("1001,1001") == 0),
"longdel" -> (add("//***\n1***2***3") == 6),
"longdel" -> (add("//***\n1") == 1),
"longdel" -> (add("//***\n") == 0),
"muldel" -> (add("//[*]\n1*2") == 3),
"muldel" -> (add("//[*][%]\n1*2%3") == 6),
"muldel" -> (add("//[*][%]\n") == 0),
"lmuldel" -> (add("//[***][%]\n1***2%3***4") == 10),
"" -> true
)
def tee[T](a: T) = {println(a); a }
def excMsg(comp: => Any, msg: String): Boolean =
try {
comp; false
} catch {
case e => e.getMessage == msg
}
tests foreach {
case (name, false) => println("failed! "+name)
case (name, true) => println("ok "+name)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment