aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Rudolph <johannes.rudolph@gmail.com>2014-07-08 14:57:01 +0200
committerJohannes Rudolph <johannes.rudolph@gmail.com>2014-07-08 14:57:01 +0200
commita575405afdc8943cd537f54515b833e0e3a04338 (patch)
tree4b61657e95dd40186ab3dd480bd3e1d3e5e092f8
parent5f2a8a060191f839a7e632d23344a4337e80e877 (diff)
downloadsbt-boilerplate-a575405afdc8943cd537f54515b833e0e3a04338.tar.gz
sbt-boilerplate-a575405afdc8943cd537f54515b833e0e3a04338.tar.bz2
sbt-boilerplate-a575405afdc8943cd537f54515b833e0e3a04338.zip
refactoring and sprinkle some syntactic sugar for better test writing
-rw-r--r--src/main/scala/spray/boilerplate/Generator.scala2
-rw-r--r--src/main/scala/spray/boilerplate/TemplateParser.scala53
-rw-r--r--src/test/scala/spray/boilerplate/TemplateParserSpecs.scala6
3 files changed, 22 insertions, 39 deletions
diff --git a/src/main/scala/spray/boilerplate/Generator.scala b/src/main/scala/spray/boilerplate/Generator.scala
index ca0e104..37b91eb 100644
--- a/src/main/scala/spray/boilerplate/Generator.scala
+++ b/src/main/scala/spray/boilerplate/Generator.scala
@@ -14,7 +14,7 @@ object Generator {
def generate(format: TemplateElement)(idx: Int): String = format match {
- case Sequence(els) => els.map(e => generate(e)(idx)).mkString
+ case Sequence(els@_*) => els.map(e => generate(e)(idx)).mkString
case Expand(inner, sep) => (1 to idx).map(generate(inner)).mkString(sep)
case Offset(i) => (idx + i - 1).toString
case LiteralString(lit) => lit
diff --git a/src/main/scala/spray/boilerplate/TemplateParser.scala b/src/main/scala/spray/boilerplate/TemplateParser.scala
index f97a352..d718e1a 100644
--- a/src/main/scala/spray/boilerplate/TemplateParser.scala
+++ b/src/main/scala/spray/boilerplate/TemplateParser.scala
@@ -9,8 +9,12 @@ package spray.boilerplate
import util.parsing.combinator.RegexParsers
import java.lang.RuntimeException
-sealed trait TemplateElement
-case class Sequence(elements: Seq[TemplateElement]) extends TemplateElement
+sealed trait TemplateElement {
+ def ~(next: TemplateElement): TemplateElement = Sequence(this, next)
+}
+case class Sequence(elements: TemplateElement*) extends TemplateElement {
+ override def ~(next: TemplateElement): TemplateElement = Sequence(elements :+ next: _*)
+}
/** A literal string that shouldn't be changed */
case class LiteralString(literal: String) extends TemplateElement
/* An offset to be replaced by the current index */
@@ -23,19 +27,17 @@ object TemplateParser extends RegexParsers {
type Tokens = TemplateElement
override val skipWhitespace = false
- def elements: Parser[TemplateElement] = rep1(element) ^^ {
- case one :: Nil => one
- case several => Sequence(several)
- }
-
+ def elements: Parser[TemplateElement] = rep1(element) ^^ maybeSequence
def element: Parser[TemplateElement] = offset| literalString | expand
- def offset: Parser[Offset] = "[012]".r ^^ (s => Offset(s.toInt))
+ def offset: Parser[Offset] = offsetChars ^^ (s => Offset(s.toInt))
def literalString: Parser[LiteralString] = rep1(escapedLiteralNumber | literalChar) ^^ (chs => LiteralString(chs.mkString))
def literalChar: Parser[Char] =
- not("[#" | """#[^\]]*\]""".r | "[012]".r) ~> elem("Any character", _ => true)
+ not("[#" | """#[^\]]*\]""".r | offsetChars) ~> elem("Any character", _ => true)
+
+ def offsetChars = "[012]".r
- def escapedLiteralNumber: Parser[Char] = "##" ~> """[012]""".r ^^ (_.head)
+ def escapedLiteralNumber: Parser[Char] = "##" ~> offsetChars ^^ (_.head)
def outsideTemplate: Parser[LiteralString]= """(?s).+?(?=(\[#)|(\z))""".r ^^ (LiteralString(_))
@@ -43,37 +45,18 @@ object TemplateParser extends RegexParsers {
case els ~ x ~ sep => Expand(els, sep.getOrElse(", "))
}
def outsideElements: Parser[TemplateElement] =
- rep1(expand | outsideTemplate) ^^ {
- case one :: Nil => one
- case several => Sequence(several)
- }
+ rep1(expand | outsideTemplate) ^^ maybeSequence
def separatorChars: Parser[Option[String]] = rep("""[^\]]""".r) ^^ (_.reduceLeftOption(_ + _))
+ def maybeSequence(els: Seq[TemplateElement]): TemplateElement = els match {
+ case one :: Nil => one
+ case several => Sequence(several: _*)
+ }
+
def parse(input:String): TemplateElement =
phrase(outsideElements)(new scala.util.parsing.input.CharArrayReader(input.toCharArray)) match {
case Success(res,_) => res
case x:NoSuccess => throw new RuntimeException(x.msg)
}
}
-
-object TestParser extends App {
- def check(format: String) {
- println(TemplateParser.parse(format))
- println("Template:\n"+format+"\n")
- println("Generated Code:\n"+Generator.generateFromTemplate(format,5))
- println("-----End-----\n")
- }
-
- check("""This text
- |should not be parsed
- |Tuple1
- |
- [#Tuple1#]
- |
- |Product 1""".stripMargin)
-
- check("[#abc ##1 # ++ ]")
- check("[#abc Tuple##22 #]")
- check("[#abc Tuple1 #]")
-} \ No newline at end of file
diff --git a/src/test/scala/spray/boilerplate/TemplateParserSpecs.scala b/src/test/scala/spray/boilerplate/TemplateParserSpecs.scala
index a0b8603..1e5e844 100644
--- a/src/test/scala/spray/boilerplate/TemplateParserSpecs.scala
+++ b/src/test/scala/spray/boilerplate/TemplateParserSpecs.scala
@@ -14,13 +14,13 @@ class TemplateParserSpecs extends Specification {
}
"multiple expansions" in {
parse("[#a#]abc[#b#]") ===
- Sequence(List(Expand(LiteralString("a"), ", "), LiteralString("abc"), Expand(LiteralString("b"), ", ")))
+ Expand(LiteralString("a"), ", ") ~ LiteralString("abc") ~ Expand(LiteralString("b"), ", ")
}
"one surrounded expansion" in {
- parse("abc[#a#]def") === Sequence(List(LiteralString("abc"), Expand(LiteralString("a"), ", "), LiteralString("def")))
+ parse("abc[#a#]def") === LiteralString("abc") ~ Expand(LiteralString("a"), ", ") ~ LiteralString("def")
}
"an expanded number" in {
- parse("[#T1#]") === Expand(Sequence(List(LiteralString("T"), Offset(1))), ", ")
+ parse("[#T1#]") === Expand(LiteralString("T") ~ Offset(1), ", ")
}
"a quoted number" in {
parse("[#T##1#]") === Expand(LiteralString("T1"), ", ")