Skip to content

Instantly share code, notes, and snippets.

@squarepegsys
Created September 10, 2012 14:29
Show Gist options
  • Save squarepegsys/3691177 to your computer and use it in GitHub Desktop.
Save squarepegsys/3691177 to your computer and use it in GitHub Desktop.
My attempt of the String Kata in Scala
import org.scalatest.FunSuite
import org.scalatest.matchers.ShouldMatchers
import org.scalatest.BeforeAndAfter
import com.squarepegsystems.StringCalculator
// Tests for the String Kata
// see http://osherove.com/tdd-kata-1/
class StringCalcTest extends FunSuite
with BeforeAndAfter
with ShouldMatchers
{
var calc: StringCalculator=_
before {
calc = new StringCalculator()
}
test("empty string") {
calc.add("") should be(0)
}
test("one string") {
calc.add("5") should be(5)
}
test("two numbers") {
calc.add("2,3") should be(5)
}
test("many numbers") {
calc.add("2,3,5,6,4") should be (20)
}
test("new line delimiter") {
calc.add("2,3\n5") should be (10)
}
test("declare delimiter") {
calc.add("//;\n2;3;5") should be (10)
}
test("reserved character") {
calc.add("//*\n2*3*5") should be (10)
}
test("no negatives") {
val exception = intercept[RuntimeException] {
calc.add("1,-10,2,-5")
}
exception.getMessage should be("No negatives allowed! (-10,-5)")
}
test("Ignore big numbers") {
calc.add("1000,2") should be (1002)
calc.add("1001,2") should be (2)
}
test("any length delimiter") {
calc.add("//[***]\n2***3***5") should be (10)
}
}
package com.squarepegsystems
// Working through the String Kata
// see http://osherove.com/tdd-kata-1/
class StringCalculator {
val AnyLengthDelimiterRegExp = "^//\\[(.+)\\]\n(.+)".r
val DeclaredDelimiterRegExp = "^//(.+)\n(.+)$".r
def add(input :String): Int= {
def findNumbers() : Array[Int]= input match {
case ""=> Array[Int](0)
case (AnyLengthDelimiterRegExp(delimiter,numberStr))=> parseNumberList(delimiter,numberStr)
case (DeclaredDelimiterRegExp(delimiter,numberStr)) => parseNumberList(delimiter,numberStr)
case _ => parseNumberList("\n",input)
}
val negatives = findNumbers.filter(_<0)
if(negatives.length>0){
val negativeList = negatives.map(_.toString)
val negativeString = negativeList.reduceLeft("%s,%s".format(_,_))
throw new RuntimeException("No negatives allowed! (%s)".format(negativeString))
}
findNumbers.filter(_<=1000).reduceLeft(_+_)
}
def parseNumberList(delimiter:String,numberStr:String): Array[Int] = {
val normalizeNumberStr = numberStr.replace(delimiter,",")
normalizeNumberStr.split(",").map(_.toInt)
}
}
@mattdsteele
Copy link

Nice. Think you could commit it test by test (or better yet screencast the entire thing)? I'd love to see how Scala code evolves; especially the pattern matching part of findNumbers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment