summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2014-11-05 22:25:58 -0800
committerLi Haoyi <haoyi@dropbox.com>2014-11-05 22:25:58 -0800
commit784f3da4192a0e30ddd94cfb10f91d0bc8dc4f7f (patch)
tree83bc659db8b89e904b6b3377d91ef3016be98d18
parent62871430033658a36e04772a4417526ac399b0dc (diff)
downloadhands-on-scala-js-784f3da4192a0e30ddd94cfb10f91d0bc8dc4f7f.tar.gz
hands-on-scala-js-784f3da4192a0e30ddd94cfb10f91d0bc8dc4f7f.tar.bz2
hands-on-scala-js-784f3da4192a0e30ddd94cfb10f91d0bc8dc4f7f.zip
Fixed the Scala grammar, property/call/type-param chaining now works and more tests pass
-rw-r--r--scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala33
-rw-r--r--scalatexApi/src/test/scala/scalatex/BasicTests.scala868
-rw-r--r--scalatexApi/src/test/scala/scalatex/ErrorTests.scala650
-rw-r--r--scalatexApi/src/test/scala/scalatex/ParserTests.scala732
4 files changed, 1148 insertions, 1135 deletions
diff --git a/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala b/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala
index 3e0c408..caaac87 100644
--- a/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala
+++ b/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala
@@ -98,7 +98,7 @@ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identif
ForCFlow |
"throw" ~ Expr |
"return" ~ optional(Expr) |
- SimpleExpr1 ~ ArgumentExprs ~ '=' ~ Expr |
+ SimpleExpr ~ ArgumentExprs ~ '=' ~ Expr |
optional(SimpleExpr ~ '.') ~ IdS ~ '=' ~ Expr |
PostfixExpr ~ optional("match" ~ '{' ~ CaseClauses ~ '}' | Ascription)
}
@@ -111,19 +111,32 @@ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identif
def PostfixExpr: Rule0 = rule { InfixExpr ~ optional(IdS ~ optional(NewlineS)) }
def InfixExpr: Rule0 = rule { PrefixExpr ~ zeroOrMore(IdS ~ optional(NewlineS) ~ PrefixExpr) }
def PrefixExpr = rule { optional(anyOf("-+~!")) ~ SimpleExpr }
- def SimpleExpr: Rule0 = rule { SimpleExpr1 ~ optional(ArgumentExprs) ~ optional('_') | SimpleExprNoLiteral}
- def SimpleExprNoLiteral: Rule0 = rule {
- "new" ~ (ClassTemplate | TemplateBody) | BlockExpr | '(' ~ optional(Exprs) ~ ')'
+"""
+ SimpleExpr ::= ‘new’ (ClassTemplate | TemplateBody)
+ | BlockExpr
+ | SimpleExpr1 [‘_’]
+ SimpleExpr1 ::= Literal
+ | Path
+ | ‘_’
+ | ‘(’ [Exprs] ‘)’
+ | SimpleExpr ‘.’ id s
+ | SimpleExpr TypeArgs
+ | SimpleExpr1 ArgmentExprs
+"""
+ def SimpleExpr: Rule0 = rule {
+ SimpleExpr1 ~ zeroOrMore('.' ~ IdS | TypeArgs | ArgumentExprs) ~ optional('_')
}
- def SimpleExpr1: Rule0 = rule {
- // run(println("SimpleExpr1 matching on " + pos)) ~
- LiteralS ~ drop[String] | //literal currently captures, so it can be used outside. but since all our rules lack AST, we drop its value in order to be able to compose them
+
+ def SimpleExpr1 = rule{
+ "new" ~ (ClassTemplate | TemplateBody) |
+ BlockExpr |
+ LiteralS ~ drop[String] |
Path |
'_' |
- SimpleExprNoLiteral ~ '.' ~ IdS |
- SimpleExprNoLiteral ~ TypeArgs /*|
- XmlExpr*/
+ '(' ~ optional(Exprs) ~ ')'
}
+
+
def Exprs: Rule0 = rule { oneOrMore(Expr).separatedBy(',') }
def ArgumentExprs: Rule0 = rule {
'(' ~ (optional(Exprs ~ ',') ~ PostfixExpr ~ ':' ~ '_' ~ '*' | optional(Exprs)) ~ ')' |
diff --git a/scalatexApi/src/test/scala/scalatex/BasicTests.scala b/scalatexApi/src/test/scala/scalatex/BasicTests.scala
index fc4bff8..4bc362c 100644
--- a/scalatexApi/src/test/scala/scalatex/BasicTests.scala
+++ b/scalatexApi/src/test/scala/scalatex/BasicTests.scala
@@ -1,468 +1,468 @@
-//package scalatex
-//import utest._
-//import scala.collection.mutable.ArrayBuffer
-//import scalatex.stages._
-//import scalatags.Text.all._
+package scalatex
+import utest._
+import scala.collection.mutable.ArrayBuffer
+import scalatex.stages._
+import scalatags.Text.all._
+
+
+/**
+* Created by haoyi on 7/14/14.
+*/
+object BasicTests extends TestSuite{
+ import TestUtil._
+
+ val tests = TestSuite{
+
+ 'helloWorld{
+ object omg {
+ def wtf(s: Frag*): Frag = Seq[Frag]("|", s, "|")
+ }
+ def str = "hear me moo"
+ check(
+ tw("""
+ @omg.wtf
+ i @b{am} cow @str
+ """),
+ "|i<b>am</b>cowhearmemoo|"
+ )
+ }
+ 'interpolation{
+ 'chained-check(
+ tw("omg @scala.math.pow(0.5, 3) wtf"),
+ "omg 0.125 wtf"
+ )
+ 'parens-check(
+ tw("omg @(1 + 2 + 3 + 4) wtf"),
+ "omg 10 wtf"
+ )
+ 'block-check(
+ tw("""
+ @{"lol" * 3}
+ @{
+ val omg = "omg"
+ omg * 2
+ }
+ """),
+ """
+ lollollol
+ omgomg
+ """
+ )
+ }
+ 'definitions{
+ 'imports{
+ object Whee{
+ def func(x: Int) = x * 2
+ }
+ check(
+ tw("""
+ @import math._
+ @import Whee.func
+ @abs(-10)
+ @p
+ @max(1, 2)
+ @func(2)
+ """),
+ """
+ 10
+ <p>
+ 2
+ 4
+ </p>
+ """
+ )
+ }
+ 'valDefVar{
+ check(
+ tw("""
+ Hello
+ @val x = 1
+ World @x
+ @def y = "omg"
+ mooo
+ @y
+ """),
+ """
+ Hello
+ World 1
+ mooo
+ omg
+ """
+ )
+ }
+ 'classObjectTrait{
+ check(
+ tw("""
+ @trait Trait{
+ def tt = 2
+ }
+ Hello
+ @case object moo extends Trait{
+ val omg = "wtf"
+ }
+
+ @moo.toString
+ @moo.omg
+ @case class Foo(i: Int, s: String, b: Boolean)
+ TT is @moo.tt
+ @Foo(10, "10", true).toString
+ """),
+ """
+ Hello
+ moo
+ wtf
+ TT is 2
+ Foo(10, 10, true)
+ """
+ )
+ }
+ }
+ 'parenArgumentLists{
+ 'attributes{
+ check(
+ tw("""
+ @div(id:="my-id"){ omg }
+ @div(id:="my-id")
+ omg
+ """),
+ """
+ <divid="my-id">omg</div>
+ <divid="my-id">omg</div>
+ """
+ )
+ }
+// 'multiline{
//
-//
-///**
-//* Created by haoyi on 7/14/14.
-//*/
-//object BasicTests extends TestSuite{
-// import TestUtil._
-//
-// val tests = TestSuite{
-//
-// 'helloWorld{
-// object omg {
-// def wtf(s: Frag*): Frag = Seq[Frag]("|", s, "|")
-// }
-// def str = "hear me moo"
-// check(
-// tw("""
-// @omg.wtf
-// i @b{am} cow @str
-// """),
-// "|i<b>am</b>cowhearmemoo|"
-// )
-// }
-// 'interpolation{
-// 'chained-check(
-// tw("omg @scala.math.pow(0.5, 3) wtf"),
-// "omg 0.125 wtf"
-// )
-// 'parens-check(
-// tw("omg @(1 + 2 + 3 + 4) wtf"),
-// "omg 10 wtf"
-// )
-// 'block-check(
-// tw("""
-// @{"lol" * 3}
-// @{
-// val omg = "omg"
-// omg * 2
-// }
-// """),
-// """
-// lollollol
-// omgomg
-// """
-// )
-// }
-// 'definitions{
-// 'imports{
-// object Whee{
-// def func(x: Int) = x * 2
-// }
-// check(
-// tw("""
-// @import math._
-// @import Whee.func
-// @abs(-10)
-// @p
-// @max(1, 2)
-// @func(2)
-// """),
-// """
-// 10
-// <p>
-// 2
-// 4
-// </p>
-// """
-// )
-// }
-// 'valDefVar{
// check(
// tw("""
-// Hello
-// @val x = 1
-// World @x
-// @def y = "omg"
-// mooo
-// @y
+// @div(
+// h1("Hello World"),
+// p("I am a ", b{"cow"})
+// )
// """),
// """
-// Hello
-// World 1
-// mooo
-// omg
+// <div>
+// <h1>Hello World</h1>
+// <p>I am a <b>cow</b></p>
+// </div>
// """
// )
// }
-// 'classObjectTrait{
-// check(
-// tw("""
-// @trait Trait{
-// def tt = 2
-// }
-// Hello
-// @case object moo extends Trait{
-// val omg = "wtf"
-// }
+ }
+ 'grouping{
+ 'negative{
+ // The indentation for "normal" text is ignored; we only
+ // create blocks from the indentation following a scala
+ // @xxx expression
+ check(
+ tw("""
+ I am cow hear me moo
+ I weigh twice as much as you
+ And I look good on the barbecue
+ Yoghurt curds cream cheese and butter
+ Comes from liquids from my udder
+ I am cow I am cow hear me moooooo
+ """),
+ """
+ I am cow hear me moo
+ I weigh twice as much as you
+ And I look good on the barbecue
+ Yoghurt curds cream cheese and butter
+ Comes from liquids from my udder
+ I am cow I am cow hear me moooooo
+ """
+ )
+ }
+ 'indentation{
+ 'simple{
+ val world = "World2"
+
+ check(
+ tw("""
+ @h1
+ Hello World
+ @h2
+ hello @world
+ @h3
+ Cow
+ """),
+ """
+ <h1>HelloWorld</h1>
+ <h2>helloWorld2</h2>
+ <h3>Cow</h3>
+ """
+ )
+ }
+ 'linearNested{
+ check(
+ tw("""
+ @h1 @span @a Hello World
+ @h2 @span @a hello
+ @b world
+ @h3 @i
+ @div Cow
+ """),
+ """
+ <h1></h1><span></span><a></a>HelloWorld
+ <h2></h2><span></span><a></a>hello<b></b>world
+ <h3></h3><i></i><div></div>Cow
+ """
+ )
+ }
+ 'crasher{
+ tw("""
+@html
+ @head
+ @meta
+ @div
+ @a
+ @span
+ """)
+ }
+ }
+ 'curlies{
+ 'simple{
+ val world = "World2"
+
+ check(
+ tw("""@div{Hello World}"""),
+ """<div>HelloWorld</div>"""
+ )
+ }
+ 'multiline{
+ check(
+ tw("""
+ @div{
+ Hello
+ }
+ """),
+ """
+ <div>Hello</div>
+ """
+ )
+ }
+ }
+ 'mixed{
+ check(
+ tw("""
+ @div{
+ Hello
+ @div
+ @h1
+ WORLD @b{!!!}
+ lol
+ @p{
+ @h2{Header 2}
+ }
+ }
+ """),
+ """
+ <div>
+ Hello
+ <div>
+ <h1>WORLD<b>!!!</b>lol</h1>
+ <p><h2>Header2</h2></p>
+ </div>
+ </div>
+ """
+ )
+ }
//
-// @moo.toString
-// @moo.omg
-// @case class Foo(i: Int, s: String, b: Boolean)
-// TT is @moo.tt
-// @Foo(10, "10", true).toString
-// """),
-// """
-// Hello
-// moo
-// wtf
-// TT is 2
-// Foo(10, 10, true)
-// """
-// )
-// }
-// }
-// 'parenArgumentLists{
-// 'attributes{
+// 'args{
+// val things = Seq(1, 2, 3)
// check(
// tw("""
-// @div(id:="my-id"){ omg }
-// @div(id:="my-id")
-// omg
-// """),
-// """
-// <divid="my-id">omg</div>
-// <divid="my-id">omg</div>
-// """
-// )
-// }
-//// 'multiline{
-////
-//// check(
-//// tw("""
-//// @div(
-//// h1("Hello World"),
-//// p("I am a ", b{"cow"})
-//// )
-//// """),
-//// """
-//// <div>
-//// <h1>Hello World</h1>
-//// <p>I am a <b>cow</b></p>
-//// </div>
-//// """
-//// )
-//// }
-// }
-// 'grouping{
-// 'negative{
-// // The indentation for "normal" text is ignored; we only
-// // create blocks from the indentation following a scala
-// // @xxx expression
-// check(
-// tw("""
-// I am cow hear me moo
-// I weigh twice as much as you
-// And I look good on the barbecue
-// Yoghurt curds cream cheese and butter
-// Comes from liquids from my udder
-// I am cow I am cow hear me moooooo
+// @ul
+// @things.map { x =>
+// @li
+// @x
+// }
// """),
-// """
-// I am cow hear me moo
-// I weigh twice as much as you
-// And I look good on the barbecue
-// Yoghurt curds cream cheese and butter
-// Comes from liquids from my udder
-// I am cow I am cow hear me moooooo
-// """
-// )
-// }
-// 'indentation{
-// 'simple{
-// val world = "World2"
-//
-// check(
-// tw("""
-// @h1
-// Hello World
-// @h2
-// hello @world
-// @h3
-// Cow
-// """),
-// """
-// <h1>HelloWorld</h1>
-// <h2>helloWorld2</h2>
-// <h3>Cow</h3>
-// """
-// )
-// }
-// 'linearNested{
-// check(
-// tw("""
-// @h1 @span @a Hello World
-// @h2 @span @a hello
-// @b world
-// @h3 @i
-// @div Cow
-// """),
-// """
-// <h1></h1><span></span><a></a>HelloWorld
-// <h2></h2><span></span><a></a>hello<b></b>world
-// <h3></h3><i></i><div></div>Cow
-// """
-// )
-// }
-// 'crasher{
// tw("""
-//@html
-// @head
-// @meta
-// @div
-// @a
-// @span
-// """)
-// }
-// }
-// 'curlies{
-// 'simple{
-// val world = "World2"
+// @ul
+// @things.map x =>
+// @li
+// @x
//
-// check(
-// tw("""@div{Hello World}"""),
-// """<div>HelloWorld</div>"""
-// )
-// }
-// 'multiline{
-// check(
-// tw("""
-// @div{
-// Hello
-// }
-// """),
-// """
-// <div>Hello</div>
-// """
-// )
-// }
-// }
-// 'mixed{
-// check(
-// tw("""
-// @div{
-// Hello
-// @div
-// @h1
-// WORLD @b{!!!}
-// lol
-// @p{
-// @h2{Header 2}
-// }
-// }
// """),
// """
-// <div>
-// Hello
-// <div>
-// <h1>WORLD<b>!!!</b>lol</h1>
-// <p><h2>Header2</h2></p>
-// </div>
-// </div>
+// <ul>
+// <li>1</li>
+// <li>2</li>
+// <li>3</li>
+// </ul>
// """
// )
// }
-////
-//// 'args{
-//// val things = Seq(1, 2, 3)
-//// check(
-//// tw("""
-//// @ul
-//// @things.map { x =>
-//// @li
-//// @x
-//// }
-//// """),
-//// tw("""
-//// @ul
-//// @things.map x =>
-//// @li
-//// @x
-////
-//// """),
-//// """
-//// <ul>
-//// <li>1</li>
-//// <li>2</li>
-//// <li>3</li>
-//// </ul>
-//// """
-//// )
-//// }
-// }
-////
-// 'loops {
-////
-// * - check(
-// tw("""
-// @for(x <- 0 until 3)
-// lol
-// """),
-// tw("""
-// @for(x <- 0 until 3){
-// lol
-// }
-// """),
-// "lollollol"
-// )
+ }
//
+ 'loops {
//
-// * - check(
-// tw("""
-// @p
-// @for(x <- 0 until 2)
-// @for(y <- 0 until 2)
-// lol@x@y
-// """),
-// tw( """
-// @p
-// @for(x <- 0 until 2){
-// @for(y <- 0 until 2)
-// lol@x@y
-// }
-// """),
-// tw("""
-// @p
-// @for(x <- 0 until 2)
-// @for(y <- 0 until 2){
-// lol@x@y
-// }
-// """),
-// "<p>lol00lol01lol10lol11</p>"
-// )
-// check(
-// tw("""
-// @p
-// @for(x <- 0 until 2)
-// @for(y <- 0 until 2)
-// lol@x@y
-// """),
-// "<p>lol00lol01lol10lol11</p>"
-// )
-//
-// * - check(
-// tw(
-// """
-// @for(x <- 0 until 2; y <- 0 until 2)
-// @div{@x@y}
-//
-// """),
-// """<div>00</div><div>01</div><div>10</div><div>11</div>"""
-// )
-// }
-//
-// 'ifElse{
-// 'basicExamples{
+ * - check(
+ tw("""
+ @for(x <- 0 until 3)
+ lol
+ """),
+ tw("""
+ @for(x <- 0 until 3){
+ lol
+ }
+ """),
+ "lollollol"
+ )
+
+
+ * - check(
+ tw("""
+ @p
+ @for(x <- 0 until 2)
+ @for(y <- 0 until 2)
+ lol@x@y
+ """),
+ tw( """
+ @p
+ @for(x <- 0 until 2){
+ @for(y <- 0 until 2)
+ lol@x@y
+ }
+ """),
+ tw("""
+ @p
+ @for(x <- 0 until 2)
+ @for(y <- 0 until 2){
+ lol@x@y
+ }
+ """),
+ "<p>lol00lol01lol10lol11</p>"
+ )
+ check(
+ tw("""
+ @p
+ @for(x <- 0 until 2)
+ @for(y <- 0 until 2)
+ lol@x@y
+ """),
+ "<p>lol00lol01lol10lol11</p>"
+ )
+
+ * - check(
+ tw(
+ """
+ @for(x <- 0 until 2; y <- 0 until 2)
+ @div{@x@y}
+
+ """),
+ """<div>00</div><div>01</div><div>10</div><div>11</div>"""
+ )
+ }
+
+ 'ifElse{
+ 'basicExamples{
+ * - check(
+ tw("""
+ @if(false)
+ Hello
+ @else
+ lols
+ @p
+ """),
+ "lols<p></p>"
+ )
+
+ * - check(
+ tw("""
+ @div
+ @if(true)
+ Hello
+ @else
+ lols
+ """),
+ "<div>Hello</div>"
+ )
+
+ * - check(
+ tw("""
+ @div
+ @if(true)
+ Hello
+ @else
+ lols
+ """),
+ "<div>Hello</div>"
+ )
+ * - check(
+ tw("""
+ @if(false)
+ Hello
+ @else
+ lols
+ """),
+ "lols"
+ )
+ * - check(
+ tw("""
+ @if(false)
+ Hello
+ @else
+ lols
+ @img
+ """),
+ "lols<img/>"
+ )
+ * - check(
+ tw("""
+ @p
+ @if(true)
+ Hello
+ @else
+ lols
+ """),
+ tw("""
+ @p
+ @if(true){
+ Hello
+ }else{
+ lols
+ }
+ """),
+ "<p>Hello</p>"
+ )
+ }
+// 'funkyExpressions{
// * - check(
// tw("""
-// @if(false)
-// Hello
-// @else
-// lols
// @p
-// """),
-// "lols<p></p>"
-// )
-//
-// * - check(
-// tw("""
-// @div
-// @if(true)
-// Hello
+// @if(true == false == (true.==(false)))
+// @if(true == false == (true.==(false)))
+// Hello1
+// @else
+// lols1
// @else
-// lols
+// @if(true == false == (true.==(false)))
+// Hello2
+// @else
+// lols2
// """),
-// "<div>Hello</div>"
-// )
-//
-// * - check(
-// tw("""
-// @div
-// @if(true)
-// Hello
-// @else
-// lols
-// """),
-// "<div>Hello</div>"
-// )
-// * - check(
-// tw("""
-// @if(false)
-// Hello
-// @else
-// lols
-// """),
-// "lols"
-// )
-// * - check(
-// tw("""
-// @if(false)
-// Hello
-// @else
-// lols
-// @img
-// """),
-// "lols<img/>"
+// "<p>Hello1</p>"
// )
// * - check(
// tw("""
// @p
-// @if(true)
-// Hello
+// @if(true == false != (true.==(false)))
+// @if(true == false != (true.==(false)))
+// Hello1
+// @else
+// lols1
// @else
-// lols
+// @if(true == false != (true.==(false)))
+// Hello2
+// @else
+// lols2
// """),
-// tw("""
-// @p
-// @if(true){
-// Hello
-// }else{
-// lols
-// }
-// """),
-// "<p>Hello</p>"
+// "<p>lols2</p>"
// )
// }
-//// 'funkyExpressions{
-//// * - check(
-//// tw("""
-//// @p
-//// @if(true == false == (true.==(false)))
-//// @if(true == false == (true.==(false)))
-//// Hello1
-//// @else
-//// lols1
-//// @else
-//// @if(true == false == (true.==(false)))
-//// Hello2
-//// @else
-//// lols2
-//// """),
-//// "<p>Hello1</p>"
-//// )
-//// * - check(
-//// tw("""
-//// @p
-//// @if(true == false != (true.==(false)))
-//// @if(true == false != (true.==(false)))
-//// Hello1
-//// @else
-//// lols1
-//// @else
-//// @if(true == false != (true.==(false)))
-//// Hello2
-//// @else
-//// lols2
-//// """),
-//// "<p>lols2</p>"
-//// )
-//// }
-// }
-// }
-//
-//}
+ }
+ }
+
+}
diff --git a/scalatexApi/src/test/scala/scalatex/ErrorTests.scala b/scalatexApi/src/test/scala/scalatex/ErrorTests.scala
index 77afd8c..8535b72 100644
--- a/scalatexApi/src/test/scala/scalatex/ErrorTests.scala
+++ b/scalatexApi/src/test/scala/scalatex/ErrorTests.scala
@@ -1,373 +1,373 @@
-//package scalatex
-//
-//import utest._
-//import scalatex.stages._
-//import scalatags.Text.all._
-//import scalatex.Internals.{DebugFailure, twRuntimeErrors}
-//
-///**
-//* Created by haoyi on 7/14/14.
-//*/
-//object ErrorTests extends TestSuite{
-// def check(x: => Unit, expectedMsg: String, expectedError: String) = {
-// val DebugFailure(msg, pos) = intercept[DebugFailure](x)
-// def format(str: String) = {
-// val whitespace = " \t\n".toSet
-// "\n" + str.dropWhile(_ == '\n')
-// .reverse
-// .dropWhile(whitespace.contains)
-// .reverse
-// }
-// // Format these guys nicely to normalize them and make them
-// // display nicely in the assert error message if it blows up
-// val formattedPos = format(pos)
-// val formattedExpectedPos = format(expectedError)
-//
-// assert(msg.contains(expectedMsg))
-// assert(formattedPos == formattedExpectedPos)
-//
-// }
-// val tests = TestSuite{
-//
-//
-// 'simple - check(
-// twRuntimeErrors("omg @notInScope lol"),
-// """not found: value notInScope""",
-// """
-// twRuntimeErrors("omg @notInScope lol"),
-// ^
-// """
-// )
-//
-//// 'chained{
-// 'properties {
-// * - check(
-// twRuntimeErrors("omg @math.lol lol"),
-// """object lol is not a member of package math""",
-// """
-// twRuntimeErrors("omg @math.lol lol"),
-// ^
-// """
-// )
-//
-// * - check(
-// twRuntimeErrors("omg @math.E.lol lol"),
-// """value lol is not a member of Double""",
-// """
-// twRuntimeErrors("omg @math.E.lol lol"),
-// ^
-// """
-// )
-// * - check(
-// twRuntimeErrors("omg @_root_.scala.math.lol lol"),
-// """object lol is not a member of package math""",
-// """
-// twRuntimeErrors("omg @_root_.scala.math.lol lol"),
-// ^
-// """
-// )
+package scalatex
+
+import utest._
+import scalatex.stages._
+import scalatags.Text.all._
+import scalatex.Internals.{DebugFailure, twRuntimeErrors}
+
+/**
+* Created by haoyi on 7/14/14.
+*/
+object ErrorTests extends TestSuite{
+ def check(x: => Unit, expectedMsg: String, expectedError: String) = {
+ val DebugFailure(msg, pos) = intercept[DebugFailure](x)
+ def format(str: String) = {
+ val whitespace = " \t\n".toSet
+ "\n" + str.dropWhile(_ == '\n')
+ .reverse
+ .dropWhile(whitespace.contains)
+ .reverse
+ }
+ // Format these guys nicely to normalize them and make them
+ // display nicely in the assert error message if it blows up
+ val formattedPos = format(pos)
+ val formattedExpectedPos = format(expectedError)
+
+ assert(msg.contains(expectedMsg))
+ assert(formattedPos == formattedExpectedPos)
+
+ }
+ val tests = TestSuite{
+
+
+ 'simple - check(
+ twRuntimeErrors("omg @notInScope lol"),
+ """not found: value notInScope""",
+ """
+ twRuntimeErrors("omg @notInScope lol"),
+ ^
+ """
+ )
+
+// 'chained{
+ 'properties {
+ * - check(
+ twRuntimeErrors("omg @math.lol lol"),
+ """object lol is not a member of package math""",
+ """
+ twRuntimeErrors("omg @math.lol lol"),
+ ^
+ """
+ )
+
+ * - check(
+ twRuntimeErrors("omg @math.E.lol lol"),
+ """value lol is not a member of Double""",
+ """
+ twRuntimeErrors("omg @math.E.lol lol"),
+ ^
+ """
+ )
+ * - check(
+ twRuntimeErrors("omg @_root_.scala.math.lol lol"),
+ """object lol is not a member of package math""",
+ """
+ twRuntimeErrors("omg @_root_.scala.math.lol lol"),
+ ^
+ """
+ )
+ * - check(
+ twRuntimeErrors("omg @_root_.scala.gg.lol lol"),
+ """object gg is not a member of package scala""",
+ """
+ twRuntimeErrors("omg @_root_.scala.gg.lol lol"),
+ ^
+ """
+ )
+ * - check(
+ twRuntimeErrors("omg @_root_.ggnore.math.lol lol"),
+ """object ggnore is not a member of package <root>""",
+ """
+ twRuntimeErrors("omg @_root_.ggnore.math.lol lol"),
+ ^
+ """
+ )
+ }
+ 'calls{
+ * - check(
+ twRuntimeErrors("@scala.QQ.abs(-10).tdo(10).sum.z"),
+ """object QQ is not a member of package scala""",
+ """
+ twRuntimeErrors("@scala.QQ.abs(-10).tdo(10).sum.z"),
+ ^
+ """
+ )
+ * - check(
+ twRuntimeErrors("@scala.math.abs(-10).tdo(10).sum.z"),
+ "value tdo is not a member of Int",
+ """
+ twRuntimeErrors("@scala.math.abs(-10).tdo(10).sum.z"),
+ ^
+ """
+ )
+ * - check(
+ twRuntimeErrors("@scala.math.abs(-10).to(10).sum.z"),
+ "value z is not a member of Int",
+ """
+ twRuntimeErrors("@scala.math.abs(-10).to(10).sum.z"),
+ ^
+ """
+ )
+ * - check(
+ twRuntimeErrors("@scala.math.abs(-10).to(10).sum.z()"),
+ "value z is not a member of Int",
+ """
+ twRuntimeErrors("@scala.math.abs(-10).to(10).sum.z()"),
+ ^
+ """
+ )
+ * - check(
+ twRuntimeErrors("@scala.math.abs(-10).cow.sum.z"),
+ "value cow is not a member of Int",
+ """
+ twRuntimeErrors("@scala.math.abs(-10).cow.sum.z"),
+ ^
+ """
+ )
+ * - check(
+ twRuntimeErrors("@scala.smath.abs.cow.sum.z"),
+ "object smath is not a member of package scala",
+ """
+ twRuntimeErrors("@scala.smath.abs.cow.sum.z"),
+ ^
+ """
+ )
+ * - check(
+ twRuntimeErrors("@scala.math.cos('omg)"),
+ "type mismatch",
+ """
+ twRuntimeErrors("@scala.math.cos('omg)"),
+ ^
+ """
+ )
+ * - check(
+ twRuntimeErrors("@scala.math.cos[omg]('omg)"),
+ "not found: type omg",
+ """
+ twRuntimeErrors("@scala.math.cos[omg]('omg)"),
+ ^
+ """
+ )
+ * - check(
+ twRuntimeErrors("""
+ I am cow hear me moo
+ @scala.math.abs(-10).tdo(10).sum.z
+ I weigh twice as much as you
+ """),
+ "value tdo is not a member of Int",
+ """
+ @scala.math.abs(-10).tdo(10).sum.z
+ ^
+ """
+ )
+ }
+ 'curlies{
+ * - check(
+ twRuntimeErrors("@p{@Seq(1, 2, 3).foldLeft(0)}"),
+ "missing arguments for method foldLeft",
+ """
+ twRuntimeErrors("@p{@Seq(1, 2, 3).foldLeft(0)}"),
+ ^
+ """
+ )
+
+ * - check(
+ twRuntimeErrors("@Nil.foldLeft{XY}"),
+ "missing arguments for method foldLeft",
+ """
+ twRuntimeErrors("@Nil.foldLeft{XY}"),
+ ^
+ """
+ )
+
// * - check(
-// twRuntimeErrors("omg @_root_.scala.gg.lol lol"),
-// """object gg is not a member of package scala""",
-// """
-// twRuntimeErrors("omg @_root_.scala.gg.lol lol"),
-// ^
+// twRuntimeErrors("@Seq(1).map{(y: String) => omg}"),
+// "type mismatch",
+// """
+// twRuntimeErrors("@Seq(1).map{(y: String) => omg}"),
+// ^
// """
// )
// * - check(
-// twRuntimeErrors("omg @_root_.ggnore.math.lol lol"),
-// """object ggnore is not a member of package <root>""",
+// twRuntimeErrors("@Nil.map{ omg}"),
+// "too many arguments for method map",
// """
-// twRuntimeErrors("omg @_root_.ggnore.math.lol lol"),
-// ^
+// twRuntimeErrors("@Nil.map{ omg}"),
+// ^
// """
// )
// }
-// 'calls{
-// * - check(
-// twRuntimeErrors("@scala.QQ.abs(-10).tdo(10).sum.z"),
-// """object QQ is not a member of package scala""",
-// """
-// twRuntimeErrors("@scala.QQ.abs(-10).tdo(10).sum.z"),
-// ^
-// """
-// )
-// * - check(
-// twRuntimeErrors("@scala.math.abs(-10).tdo(10).sum.z"),
-// "value tdo is not a member of Int",
-// """
-// twRuntimeErrors("@scala.math.abs(-10).tdo(10).sum.z"),
-// ^
-// """
-// )
-// * - check(
-// twRuntimeErrors("@scala.math.abs(-10).to(10).sum.z"),
-// "value z is not a member of Int",
-// """
-// twRuntimeErrors("@scala.math.abs(-10).to(10).sum.z"),
-// ^
-// """
-// )
+ 'callContents{
+ * - check(
+ twRuntimeErrors("@scala.math.abs((1, 2).wtf)"),
+ "value wtf is not a member of (Int, Int)",
+ """
+ twRuntimeErrors("@scala.math.abs((1, 2).wtf)"),
+ ^
+ """
+ )
+
+ * - check(
+ twRuntimeErrors("@scala.math.abs((1, 2).swap._1.toString().map(_.toString.wtf))"),
+ "value wtf is not a member of String",
+ """
+ twRuntimeErrors("@scala.math.abs((1, 2).swap._1.toString().map(_.toString.wtf))"),
+ ^
+ """
+ )
+ }
+// }
+// 'ifElse{
+// 'oneLine {
// * - check(
-// twRuntimeErrors("@scala.math.abs(-10).to(10).sum.z()"),
-// "value z is not a member of Int",
+// twRuntimeErrors("@if(math > 10){ 1 }else{ 2 }"),
+// "object > is not a member of package math",
// """
-// twRuntimeErrors("@scala.math.abs(-10).to(10).sum.z()"),
-// ^
+// twRuntimeErrors("@if(math > 10){ 1 }else{ 2 }"),
+// ^
// """
// )
// * - check(
-// twRuntimeErrors("@scala.math.abs(-10).cow.sum.z"),
-// "value cow is not a member of Int",
+// twRuntimeErrors("@if(true){ (@math.pow(10)) * 10 }else{ 2 }"),
+// "Unspecified value parameter y",
// """
-// twRuntimeErrors("@scala.math.abs(-10).cow.sum.z"),
+// twRuntimeErrors("@if(true){ (@math.pow(10)) * 10 }else{ 2 }"),
// ^
// """
// )
// * - check(
-// twRuntimeErrors("@scala.smath.abs.cow.sum.z"),
-// "object smath is not a member of package scala",
+// twRuntimeErrors("@if(true){ * 10 }else{ @math.sin(3, 4, 5) }"),
+// "too many arguments for method sin: (x: Double)Double",
// """
-// twRuntimeErrors("@scala.smath.abs.cow.sum.z"),
-// ^
+// twRuntimeErrors("@if(true){ * 10 }else{ @math.sin(3, 4, 5) }"),
+// ^
// """
// )
+// }
+// 'multiLine{
// * - check(
-// twRuntimeErrors("@scala.math.cos('omg)"),
-// "type mismatch",
+// twRuntimeErrors("""
+// Ho Ho Ho
+//
+// @if(math != 10)
+// I am a cow
+// @else
+// You are a cow
+// GG
+// """),
+// "object != is not a member of package math",
// """
-// twRuntimeErrors("@scala.math.cos('omg)"),
-// ^
+// @if(math != 10)
+// ^
// """
// )
// * - check(
-// twRuntimeErrors("@scala.math.cos[omg]('omg)"),
-// "not found: type omg",
+// twRuntimeErrors("""
+// Ho Ho Ho
+//
+// @if(4 != 10)
+// I am a cow @math.lols
+// @else
+// You are a cow
+// GG
+// """),
+// "object lols is not a member of package math",
// """
-// twRuntimeErrors("@scala.math.cos[omg]('omg)"),
-// ^
+// I am a cow @math.lols
+// ^
// """
// )
// * - check(
// twRuntimeErrors("""
-// I am cow hear me moo
-// @scala.math.abs(-10).tdo(10).sum.z
-// I weigh twice as much as you
+// Ho Ho Ho
+//
+// @if(12 != 10)
+// I am a cow
+// @else
+// @math.E.toString.gog(1)
+// GG
// """),
-// "value tdo is not a member of Int",
+// "value gog is not a member of String",
// """
-// @scala.math.abs(-10).tdo(10).sum.z
-// ^
+// @math.E.toString.gog(1)
+// ^
// """
// )
// }
-// 'curlies{
-// * - check(
-// twRuntimeErrors("@p{@Seq(1, 2, 3).foldLeft(0)}"),
-// "missing arguments for method foldLeft",
-// """
-// twRuntimeErrors("@p{@Seq(1, 2, 3).foldLeft(0)}"),
-// ^
-// """
-// )
-//
-// * - check(
-// twRuntimeErrors("@Nil.foldLeft{XY}"),
-// "missing arguments for method foldLeft",
+// }
+// 'forLoop{
+// 'oneLine{
+// 'header - check(
+// twRuntimeErrors("omg @for(x <- (0 + 1 + 2) omglolol (10 + 11 + 2)){ hello }"),
+// """value omglolol is not a member of Int""",
// """
-// twRuntimeErrors("@Nil.foldLeft{XY}"),
-// ^
+// twRuntimeErrors("omg @for(x <- (0 + 1 + 2) omglolol (10 + 11 + 2)){ hello }"),
+// ^
// """
// )
//
-//// * - check(
-//// twRuntimeErrors("@Seq(1).map{(y: String) => omg}"),
-//// "type mismatch",
-//// """
-//// twRuntimeErrors("@Seq(1).map{(y: String) => omg}"),
-//// ^
-//// """
-//// )
-//// * - check(
-//// twRuntimeErrors("@Nil.map{ omg}"),
-//// "too many arguments for method map",
-//// """
-//// twRuntimeErrors("@Nil.map{ omg}"),
-//// ^
-//// """
-//// )
-//// }
-// 'callContents{
-// * - check(
-// twRuntimeErrors("@scala.math.abs((1, 2).wtf)"),
-// "value wtf is not a member of (Int, Int)",
+// 'body - check(
+// twRuntimeErrors("omg @for(x <- 0 until 10){ @((x, 2) + (1, 2)) }"),
+// """too many arguments for method +""",
// """
-// twRuntimeErrors("@scala.math.abs((1, 2).wtf)"),
-// ^
+// twRuntimeErrors("omg @for(x <- 0 until 10){ @((x, 2) + (1, 2)) }"),
+// ^
// """
// )
-//
-// * - check(
-// twRuntimeErrors("@scala.math.abs((1, 2).swap._1.toString().map(_.toString.wtf))"),
-// "value wtf is not a member of String",
+// }
+// 'multiLine{
+// 'body - check(
+// twRuntimeErrors("""
+// omg
+// @for(x <- 0 until 10)
+// I am cow hear me moo
+// I weigh twice as much as @x.kkk
+// """),
+// """value kkk is not a member of Int""",
// """
-// twRuntimeErrors("@scala.math.abs((1, 2).swap._1.toString().map(_.toString.wtf))"),
-// ^
+// I weigh twice as much as @x.kkk
+// ^
// """
// )
// }
-//// }
-//// 'ifElse{
-//// 'oneLine {
-//// * - check(
-//// twRuntimeErrors("@if(math > 10){ 1 }else{ 2 }"),
-//// "object > is not a member of package math",
-//// """
-//// twRuntimeErrors("@if(math > 10){ 1 }else{ 2 }"),
-//// ^
-//// """
-//// )
-//// * - check(
-//// twRuntimeErrors("@if(true){ (@math.pow(10)) * 10 }else{ 2 }"),
-//// "Unspecified value parameter y",
-//// """
-//// twRuntimeErrors("@if(true){ (@math.pow(10)) * 10 }else{ 2 }"),
-//// ^
-//// """
-//// )
-//// * - check(
-//// twRuntimeErrors("@if(true){ * 10 }else{ @math.sin(3, 4, 5) }"),
-//// "too many arguments for method sin: (x: Double)Double",
-//// """
-//// twRuntimeErrors("@if(true){ * 10 }else{ @math.sin(3, 4, 5) }"),
-//// ^
-//// """
-//// )
-//// }
-//// 'multiLine{
-//// * - check(
-//// twRuntimeErrors("""
-//// Ho Ho Ho
-////
-//// @if(math != 10)
-//// I am a cow
-//// @else
-//// You are a cow
-//// GG
-//// """),
-//// "object != is not a member of package math",
-//// """
-//// @if(math != 10)
-//// ^
-//// """
-//// )
-//// * - check(
-//// twRuntimeErrors("""
-//// Ho Ho Ho
-////
-//// @if(4 != 10)
-//// I am a cow @math.lols
-//// @else
-//// You are a cow
-//// GG
-//// """),
-//// "object lols is not a member of package math",
-//// """
-//// I am a cow @math.lols
-//// ^
-//// """
-//// )
-//// * - check(
-//// twRuntimeErrors("""
-//// Ho Ho Ho
-////
-//// @if(12 != 10)
-//// I am a cow
-//// @else
-//// @math.E.toString.gog(1)
-//// GG
-//// """),
-//// "value gog is not a member of String",
-//// """
-//// @math.E.toString.gog(1)
-//// ^
-//// """
-//// )
-//// }
-//// }
-//// 'forLoop{
-//// 'oneLine{
-//// 'header - check(
-//// twRuntimeErrors("omg @for(x <- (0 + 1 + 2) omglolol (10 + 11 + 2)){ hello }"),
-//// """value omglolol is not a member of Int""",
-//// """
-//// twRuntimeErrors("omg @for(x <- (0 + 1 + 2) omglolol (10 + 11 + 2)){ hello }"),
-//// ^
-//// """
-//// )
-////
-//// 'body - check(
-//// twRuntimeErrors("omg @for(x <- 0 until 10){ @((x, 2) + (1, 2)) }"),
-//// """too many arguments for method +""",
-//// """
-//// twRuntimeErrors("omg @for(x <- 0 until 10){ @((x, 2) + (1, 2)) }"),
-//// ^
-//// """
-//// )
-//// }
-//// 'multiLine{
-//// 'body - check(
-//// twRuntimeErrors("""
-//// omg
-//// @for(x <- 0 until 10)
-//// I am cow hear me moo
-//// I weigh twice as much as @x.kkk
-//// """),
-//// """value kkk is not a member of Int""",
-//// """
-//// I weigh twice as much as @x.kkk
-//// ^
-//// """
-//// )
-//// }
-//// }
-//// 'multiLine{
-//// 'missingVar - check(
-//// twRuntimeErrors("""
-//// omg @notInScope lol
-//// """),
-//// """not found: value notInScope""",
-//// """
-//// omg @notInScope lol
-//// ^
-//// """
-//// )
-//// 'wrongType - check(
-//// twRuntimeErrors("""
-//// omg @{() => ()} lol
-//// """),
-//// """type mismatch""",
-//// """
-//// omg @{() => ()} lol
-//// ^
-//// """
-//// )
-////
-//// 'bigExpression - check(
-//// twRuntimeErrors("""
-//// @{
-//// val x = 1 + 2
-//// val y = new Object()
-//// val z = y * x
-//// x
-//// }
-//// """),
-//// "value * is not a member of Object",
-//// """
-//// val z = y * x
-//// ^
-//// """
-//// )
// }
-// }
-//}
+// 'multiLine{
+// 'missingVar - check(
+// twRuntimeErrors("""
+// omg @notInScope lol
+// """),
+// """not found: value notInScope""",
+// """
+// omg @notInScope lol
+// ^
+// """
+// )
+// 'wrongType - check(
+// twRuntimeErrors("""
+// omg @{() => ()} lol
+// """),
+// """type mismatch""",
+// """
+// omg @{() => ()} lol
+// ^
+// """
+// )
+//
+// 'bigExpression - check(
+// twRuntimeErrors("""
+// @{
+// val x = 1 + 2
+// val y = new Object()
+// val z = y * x
+// x
+// }
+// """),
+// "value * is not a member of Object",
+// """
+// val z = y * x
+// ^
+// """
+// )
+ }
+ }
+}
diff --git a/scalatexApi/src/test/scala/scalatex/ParserTests.scala b/scalatexApi/src/test/scala/scalatex/ParserTests.scala
index a09f8e4..68f05cc 100644
--- a/scalatexApi/src/test/scala/scalatex/ParserTests.scala
+++ b/scalatexApi/src/test/scala/scalatex/ParserTests.scala
@@ -16,384 +16,384 @@ object ParserTests extends utest.TestSuite{
assert(parsed == expected)
}
def tests = TestSuite{
-// 'Trim{
-// def wrap(s: String) = "|" + s + "|"
-// * - {
-// val trimmed = wrap(stages.Trim.old("""
-// i am cow
-// hear me moo
-// i weigh twice as much as you
-// """))
-// val expected = wrap("""
-// |i am cow
-// | hear me moo
-// | i weigh twice as much as you
-// |""".stripMargin)
-// assert(trimmed == expected)
-//
-// }
-// * - {
-// val trimmed = wrap(stages.Trim.old(
-// """
-// @{"lol" * 3}
-// @{
-// val omg = "omg"
-// omg * 2
-// }
-// """
-// ))
-// val expected = wrap(
-// """
-// |@{"lol" * 3}
-// |@{
-// | val omg = "omg"
-// | omg * 2
-// |}
-// |""".stripMargin
-// )
-// assert(trimmed == expected)
-// }
-// 'dropTrailingWhitespace - {
-//
-// val trimmed = wrap(stages.Trim.old(
-// Seq(
-// " i am a cow ",
-// " hear me moo ",
-// " i weigh twice as much as you"
-// ).mkString("\n")
-// ))
-// val expected = wrap(
-// Seq(
-// "i am a cow",
-// " hear me moo",
-// " i weigh twice as much as you"
-// ).mkString("\n")
-// )
-// assert(trimmed == expected)
-// }
-// }
-// 'Text {
-// * - check("i am a cow", _.Text.run(), Block.Text("i am a cow"))
-// * - check("i am a @cow", _.Text.run(), Block.Text("i am a "))
-// * - check("i am a @@cow", _.Text.run(), Block.Text("i am a @cow"))
-// * - check("i am a @@@cow", _.Text.run(), Block.Text("i am a @"))
-// * - check("i am a @@@@cow", _.Text.run(), Block.Text("i am a @@cow"))
-//
-// }
-// 'Code{
-// 'identifier - check("@gggg ", _.Code.run(), "gggg")
-// 'parens - check("@(1 + 1)lolsss\n", _.Code.run(), "(1 + 1)")
-// 'curlies - check("@{{1} + (1)} ", _.Code.run(), "{{1} + (1)}")
-// 'blocks - check("@{val x = 1; 1} ", _.Code.run(), "{val x = 1; 1}")
-// 'weirdBackticks - check("@{`{}}{()@`}\n", _.Code.run(), "{`{}}{()@`}")
-// }
-// 'MiscCode{
-// 'imports{
-// * - check("@import math.abs", _.Header.run(), "import math.abs")
-// * - check("@import math.{abs, sin}", _.Header.run(), "import math.{abs, sin}")
-// }
-// 'headerblocks{
-// check(
-// """@import math.abs
-// |@import math.sin
-// |
-// |hello world
-// |""".stripMargin,
-// _.HeaderBlock.run(),
-// Ast.Header(
-// "import math.abs\nimport math.sin",
-// Ast.Block(
-// Seq(Text("\n", 33), Text("\n", 34), Text("hello world", 35), Text("\n", 46)),
-// 33
-// )
-// )
-// )
-// }
-// 'caseclass{
-// check(
-// """@case class Foo(i: Int, s: String)
-// """.stripMargin,
-// _.Header.run(),
-// "case class Foo(i: Int, s: String)"
-// )
-// }
-//
-// }
-// 'Block{
-// * - check("{i am a cow}", _.BraceBlock.run(), Block(Seq(Block.Text("i am a cow", 1)), 1))
-// * - check("{i @am a @cow}", _.BraceBlock.run(),
-// Block(Seq(
-// Block.Text("i ", 1),
-// Chain("am",Seq(), 3),
-// Block.Text(" a ", 6),
-// Chain("cow",Seq(), 9)
-// ), 1)
-// )
-// }
-// 'Chain{
-// * - check("@omg.bbq[omg].fff[fff](123) ", _.ScalaChain.run(),
-// Chain("omg",Seq(
-// Chain.Prop("bbq", 4),
-// Chain.TypeArgs("[omg]", 8),
-// Chain.Prop("fff", 13),
-// Chain.TypeArgs("[fff]", 17),
-// Chain.Args("(123)", 22)
-// ))
-// )
-// * - check("@omg{bbq}.cow(moo){a @b}\n", _.ScalaChain.run(),
-// Chain("omg",Seq(
-// Block(Seq(Text("bbq", 5)), 5),
-// Chain.Prop("cow", 9),
-// Chain.Args("(moo)", 13),
-// Block(Seq(Text("a ", 19), Chain("b", Nil, 21)), 19)
-// ))
-// )
-// }
-// 'ControlFlow{
-// 'for {
-// 'for - check(
-// "@for(x <- 0 until 3){lol}",
-// _.ForLoop.run(),
-// For("for(x <- 0 until 3)", Block(Seq(Text("lol", 21)), 21))
-// )
-// 'forBlock - check(
-// """
-// |@for(x <- 0 until 3)
-// | lol""".stripMargin,
-// _.Body.run(),
-// Block(Seq(
-// Text("\n"),
-// For("for(x <- 0 until 3)", Block(Seq(Text("\n ", 21), Text("lol", 24)), 21))
-// ))
-// )
-// 'forBlockBraces - check(
-// """
-// |@for(x <- 0 until 3){
-// | lol
-// |}""".stripMargin,
-// _.Body.run(),
-// Block(Seq(
-// Text("\n"),
-// For("for(x <- 0 until 3)", Block(Seq(Text("\n ", 22), Text("lol", 25), Text("\n", 28)), 22))
-// ))
-// )
-// }
-// 'ifElse {
-// 'if - check(
-// "@if(true){lol}",
-// _.IfElse.run(),
-// IfElse("if(true)", Block(Seq(Text("lol", 10)), 10), None)
-// )
-// 'ifElse - check(
-// "@if(true){lol}else{ omg }",
-// _.IfElse.run(),
-// IfElse("if(true)", Block(Seq(Text("lol", 10)), 10), Some(Block(Seq(Text(" omg ", 19)), 19)))
-// )
-// 'ifBlock - check(
-// """
-// |@if(true)
-// | omg""".stripMargin,
-// _.IfElse.run(),
-// IfElse("if(true)", Block(Seq(Text("\n ", 10), Text("omg", 13)), 10), None)
-// )
-// 'ifBlockElseBlock - check(
-// """
-// |@if(true)
-// | omg
-// |@else
-// | wtf""".stripMargin,
-// _.IfElse.run(),
-// IfElse(
-// "if(true)",
-// Block(Seq(Text("\n ", 10), Text("omg", 13)), 10),
-// Some(Block(Seq(Text("\n ", 22), Text("wtf", 25)), 22))
-// )
-// )
-// 'ifBlockElseBraceBlock - check(
-// """@if(true){
-// | omg
-// |}else{
-// | wtf
-// |}""".stripMargin,
-// _.IfElse.run(),
-// IfElse(
-// "if(true)",
-// Block(Seq(Text("\n ", 10), Text("omg", 13), Text("\n", 16)), 10),
-// Some(Block(Seq(Text("\n ", 23), Text("wtf", 26), Text("\n", 29)), 23))
-// )
-// )
-// 'ifBlockElseBraceBlockNested - {
-// val res = Parser(Trim.old(
-// """
-// @p
-// @if(true){
-// Hello
-// }else{
-// lols
-// }
-// """))
-// val expected =
-// Block(Vector(
-// Text("\n"),
-// Chain("p",Vector(Block(Vector(
-// Text("\n ", 3),
-// IfElse("if(true)",
-// Block(Vector(
-// Text("\n ", 16), Text("Hello", 21), Text("\n ", 26)
-// ), 16),
-// Some(Block(Vector(
-// Text("\n ", 35), Text("lols", 40), Text("\n ", 44)
-// ), 35))
-// )), 3)), 1),
-// Text("\n", 48)
-// ))
-// assert(res == expected)
-// }
-// 'ifElseBlock - check(
-// """@if(true){
-// | omg
-// |}else
-// | wtf""".stripMargin,
-// _.IfElse.run(),
-// IfElse(
-// "if(true)",
-// Block(Seq(Text("\n ", 10), Text("omg", 13), Text("\n", 16)), 10),
-// Some(Block(Seq(Text("\n ", 22), Text("wtf", 25)), 22))
-// )
-// )
-// }
-//
-// }
-// 'Body{
-// 'indents - check(
-// """
-// |@omg
-// | @wtf
-// | @bbq
-// | @lol""".stripMargin,
-// _.Body.run(),
-// Block(Seq(
-// Text("\n"),
-// Chain("omg",Seq(Block(Seq(
-// Text("\n ", 5),
-// Chain("wtf",Seq(Block(Seq(
-// Text("\n ", 7),
-// Chain("bbq",Seq(Block(Seq(
-// Text("\n ", 9),
-// Chain("lol",Seq(), 16)
-// ), 9)), 12)
-// ), 7)), 8)
-// ), 5)), 1)
-// ))
-// )
-// 'dedents - check(
-// """
-// |@omg
-// | @wtf
-// |@bbq""".stripMargin,
-// _.Body.run(),
-// Block(Seq(
-// Text("\n"),
-// Chain("omg",Seq(Block(
-// Seq(
-// Text("\n ", 5),
-// Chain("wtf",Seq(), 8)
-// ),
-// 5
-// )), 1),
-// Text("\n", 12),
-// Chain("bbq", Seq(), 13)
-// ))
-// )
-// 'braces - check(
-// """
-// |@omg{
-// | @wtf
-// |}
-// |@bbq""".stripMargin,
-// _.Body.run(),
-// Block(Seq(
-// Text("\n"),
-// Chain("omg",Seq(Block(
-// Seq(
-// Text("\n ", 6),
-// Chain("wtf",Seq(), 9),
-// Text("\n", 13)
-// ),
-// 6
-// )), 1),
-// Text("\n", 15),
-// Chain("bbq", Seq(), 16)
-// ))
-// )
-// 'dedentText - check(
+ 'Trim{
+ def wrap(s: String) = "|" + s + "|"
+ * - {
+ val trimmed = wrap(stages.Trim.old("""
+ i am cow
+ hear me moo
+ i weigh twice as much as you
+ """))
+ val expected = wrap("""
+ |i am cow
+ | hear me moo
+ | i weigh twice as much as you
+ |""".stripMargin)
+ assert(trimmed == expected)
+
+ }
+ * - {
+ val trimmed = wrap(stages.Trim.old(
+ """
+ @{"lol" * 3}
+ @{
+ val omg = "omg"
+ omg * 2
+ }
+ """
+ ))
+ val expected = wrap(
+ """
+ |@{"lol" * 3}
+ |@{
+ | val omg = "omg"
+ | omg * 2
+ |}
+ |""".stripMargin
+ )
+ assert(trimmed == expected)
+ }
+ 'dropTrailingWhitespace - {
+
+ val trimmed = wrap(stages.Trim.old(
+ Seq(
+ " i am a cow ",
+ " hear me moo ",
+ " i weigh twice as much as you"
+ ).mkString("\n")
+ ))
+ val expected = wrap(
+ Seq(
+ "i am a cow",
+ " hear me moo",
+ " i weigh twice as much as you"
+ ).mkString("\n")
+ )
+ assert(trimmed == expected)
+ }
+ }
+ 'Text {
+ * - check("i am a cow", _.Text.run(), Block.Text("i am a cow"))
+ * - check("i am a @cow", _.Text.run(), Block.Text("i am a "))
+ * - check("i am a @@cow", _.Text.run(), Block.Text("i am a @cow"))
+ * - check("i am a @@@cow", _.Text.run(), Block.Text("i am a @"))
+ * - check("i am a @@@@cow", _.Text.run(), Block.Text("i am a @@cow"))
+
+ }
+ 'Code{
+ 'identifier - check("@gggg ", _.Code.run(), "gggg")
+ 'parens - check("@(1 + 1)lolsss\n", _.Code.run(), "(1 + 1)")
+ 'curlies - check("@{{1} + (1)} ", _.Code.run(), "{{1} + (1)}")
+ 'blocks - check("@{val x = 1; 1} ", _.Code.run(), "{val x = 1; 1}")
+ 'weirdBackticks - check("@{`{}}{()@`}\n", _.Code.run(), "{`{}}{()@`}")
+ }
+ 'MiscCode{
+ 'imports{
+ * - check("@import math.abs", _.Header.run(), "import math.abs")
+ * - check("@import math.{abs, sin}", _.Header.run(), "import math.{abs, sin}")
+ }
+ 'headerblocks{
+ check(
+ """@import math.abs
+ |@import math.sin
+ |
+ |hello world
+ |""".stripMargin,
+ _.HeaderBlock.run(),
+ Ast.Header(
+ "import math.abs\nimport math.sin",
+ Ast.Block(
+ Seq(Text("\n", 33), Text("\n", 34), Text("hello world", 35), Text("\n", 46)),
+ 33
+ )
+ )
+ )
+ }
+ 'caseclass{
+ check(
+ """@case class Foo(i: Int, s: String)
+ """.stripMargin,
+ _.Header.run(),
+ "case class Foo(i: Int, s: String)"
+ )
+ }
+
+ }
+ 'Block{
+ * - check("{i am a cow}", _.BraceBlock.run(), Block(Seq(Block.Text("i am a cow", 1)), 1))
+ * - check("{i @am a @cow}", _.BraceBlock.run(),
+ Block(Seq(
+ Block.Text("i ", 1),
+ Chain("am",Seq(), 3),
+ Block.Text(" a ", 6),
+ Chain("cow",Seq(), 9)
+ ), 1)
+ )
+ }
+ 'Chain{
+ * - check("@omg.bbq[omg].fff[fff](123) ", _.ScalaChain.run(),
+ Chain("omg",Seq(
+ Chain.Prop("bbq", 4),
+ Chain.TypeArgs("[omg]", 8),
+ Chain.Prop("fff", 13),
+ Chain.TypeArgs("[fff]", 17),
+ Chain.Args("(123)", 22)
+ ))
+ )
+ * - check("@omg{bbq}.cow(moo){a @b}\n", _.ScalaChain.run(),
+ Chain("omg",Seq(
+ Block(Seq(Text("bbq", 5)), 5),
+ Chain.Prop("cow", 9),
+ Chain.Args("(moo)", 13),
+ Block(Seq(Text("a ", 19), Chain("b", Nil, 21)), 19)
+ ))
+ )
+ }
+ 'ControlFlow{
+ 'for {
+ 'for - check(
+ "@for(x <- 0 until 3){lol}",
+ _.ForLoop.run(),
+ For("for(x <- 0 until 3)", Block(Seq(Text("lol", 21)), 21))
+ )
+ 'forBlock - check(
+ """
+ |@for(x <- 0 until 3)
+ | lol""".stripMargin,
+ _.Body.run(),
+ Block(Seq(
+ Text("\n"),
+ For("for(x <- 0 until 3)", Block(Seq(Text("\n ", 21), Text("lol", 24)), 21))
+ ))
+ )
+ 'forBlockBraces - check(
+ """
+ |@for(x <- 0 until 3){
+ | lol
+ |}""".stripMargin,
+ _.Body.run(),
+ Block(Seq(
+ Text("\n"),
+ For("for(x <- 0 until 3)", Block(Seq(Text("\n ", 22), Text("lol", 25), Text("\n", 28)), 22))
+ ))
+ )
+ }
+ 'ifElse {
+ 'if - check(
+ "@if(true){lol}",
+ _.IfElse.run(),
+ IfElse("if(true)", Block(Seq(Text("lol", 10)), 10), None)
+ )
+ 'ifElse - check(
+ "@if(true){lol}else{ omg }",
+ _.IfElse.run(),
+ IfElse("if(true)", Block(Seq(Text("lol", 10)), 10), Some(Block(Seq(Text(" omg ", 19)), 19)))
+ )
+ 'ifBlock - check(
+ """
+ |@if(true)
+ | omg""".stripMargin,
+ _.IfElse.run(),
+ IfElse("if(true)", Block(Seq(Text("\n ", 10), Text("omg", 13)), 10), None)
+ )
+ 'ifBlockElseBlock - check(
+ """
+ |@if(true)
+ | omg
+ |@else
+ | wtf""".stripMargin,
+ _.IfElse.run(),
+ IfElse(
+ "if(true)",
+ Block(Seq(Text("\n ", 10), Text("omg", 13)), 10),
+ Some(Block(Seq(Text("\n ", 22), Text("wtf", 25)), 22))
+ )
+ )
+ 'ifBlockElseBraceBlock - check(
+ """@if(true){
+ | omg
+ |}else{
+ | wtf
+ |}""".stripMargin,
+ _.IfElse.run(),
+ IfElse(
+ "if(true)",
+ Block(Seq(Text("\n ", 10), Text("omg", 13), Text("\n", 16)), 10),
+ Some(Block(Seq(Text("\n ", 23), Text("wtf", 26), Text("\n", 29)), 23))
+ )
+ )
+ 'ifBlockElseBraceBlockNested - {
+ val res = Parser(Trim.old(
+ """
+ @p
+ @if(true){
+ Hello
+ }else{
+ lols
+ }
+ """))
+ val expected =
+ Block(Vector(
+ Text("\n"),
+ Chain("p",Vector(Block(Vector(
+ Text("\n ", 3),
+ IfElse("if(true)",
+ Block(Vector(
+ Text("\n ", 16), Text("Hello", 21), Text("\n ", 26)
+ ), 16),
+ Some(Block(Vector(
+ Text("\n ", 35), Text("lols", 40), Text("\n ", 44)
+ ), 35))
+ )), 3)), 1),
+ Text("\n", 48)
+ ))
+ assert(res == expected)
+ }
+ 'ifElseBlock - check(
+ """@if(true){
+ | omg
+ |}else
+ | wtf""".stripMargin,
+ _.IfElse.run(),
+ IfElse(
+ "if(true)",
+ Block(Seq(Text("\n ", 10), Text("omg", 13), Text("\n", 16)), 10),
+ Some(Block(Seq(Text("\n ", 22), Text("wtf", 25)), 22))
+ )
+ )
+ }
+
+ }
+ 'Body{
+ 'indents - check(
+ """
+ |@omg
+ | @wtf
+ | @bbq
+ | @lol""".stripMargin,
+ _.Body.run(),
+ Block(Seq(
+ Text("\n"),
+ Chain("omg",Seq(Block(Seq(
+ Text("\n ", 5),
+ Chain("wtf",Seq(Block(Seq(
+ Text("\n ", 7),
+ Chain("bbq",Seq(Block(Seq(
+ Text("\n ", 9),
+ Chain("lol",Seq(), 16)
+ ), 9)), 12)
+ ), 7)), 8)
+ ), 5)), 1)
+ ))
+ )
+ 'dedents - check(
+ """
+ |@omg
+ | @wtf
+ |@bbq""".stripMargin,
+ _.Body.run(),
+ Block(Seq(
+ Text("\n"),
+ Chain("omg",Seq(Block(
+ Seq(
+ Text("\n ", 5),
+ Chain("wtf",Seq(), 8)
+ ),
+ 5
+ )), 1),
+ Text("\n", 12),
+ Chain("bbq", Seq(), 13)
+ ))
+ )
+ 'braces - check(
+ """
+ |@omg{
+ | @wtf
+ |}
+ |@bbq""".stripMargin,
+ _.Body.run(),
+ Block(Seq(
+ Text("\n"),
+ Chain("omg",Seq(Block(
+ Seq(
+ Text("\n ", 6),
+ Chain("wtf",Seq(), 9),
+ Text("\n", 13)
+ ),
+ 6
+ )), 1),
+ Text("\n", 15),
+ Chain("bbq", Seq(), 16)
+ ))
+ )
+ 'dedentText - check(
+ """
+ |@omg("lol", 1, 2)
+ | @wtf
+ |bbq""".stripMargin,
+ _.Body.run(),
+ Block(Seq(
+ Text("\n"),
+ Chain("omg",Seq(
+ Args("""("lol", 1, 2)""", 5),
+ Block(Seq(
+ Text("\n ", 18),
+ Chain("wtf",Seq(), 21)
+ ), 18)
+ ), 1),
+ Text("\n", 25),
+ Text("bbq", 26)
+ ))
+ )
+// * - check(
// """
-// |@omg("lol", 1, 2)
-// | @wtf
+// |@omg("lol",
+// |1,
+// | 2
+// | )
+// | wtf
// |bbq""".stripMargin,
// _.Body.run(),
// Block(Seq(
-// Text("\n"),
// Chain("omg",Seq(
-// Args("""("lol", 1, 2)""", 5),
+// Args("(\"lol\",\n1,\n 2\n )"),
// Block(Seq(
-// Text("\n ", 18),
-// Chain("wtf",Seq(), 21)
-// ), 18)
-// ), 1),
-// Text("\n", 25),
-// Text("bbq", 26)
-// ))
-// )
-//// * - check(
-//// """
-//// |@omg("lol",
-//// |1,
-//// | 2
-//// | )
-//// | wtf
-//// |bbq""".stripMargin,
-//// _.Body.run(),
-//// Block(Seq(
-//// Chain("omg",Seq(
-//// Args("(\"lol\",\n1,\n 2\n )"),
-//// Block(Seq(
-//// Text("\n "), Text("wtf")
-//// ))
-//// )),
-//// Text("\n"),
-//// Text("bbq")
-//// ))
-//// )
-// 'codeBlocks - check(
-// """
-// |@{"lol" * 3}
-// |@{
-// | val omg = "omg"
-// | omg * 2
-// |}""".stripMargin,
-// _.Body.run(),
-// Block(Seq(
+// Text("\n "), Text("wtf")
+// ))
+// )),
// Text("\n"),
-// Chain("{\"lol\" * 3}", Seq(), 1),
-// Text("\n", 13),
-// Chain("""{
-// | val omg = "omg"
-// | omg * 2
-// |}""".stripMargin,
-// Seq(),
-// 14
-// )
+// Text("bbq")
// ))
// )
-// }
- 'Test{
- check(
- "@scala.math.abs((1, 2).swap._1)",
+ 'codeBlocks - check(
+ """
+ |@{"lol" * 3}
+ |@{
+ | val omg = "omg"
+ | omg * 2
+ |}""".stripMargin,
_.Body.run(),
- ""
+ Block(Seq(
+ Text("\n"),
+ Chain("{\"lol\" * 3}", Seq(), 1),
+ Text("\n", 13),
+ Chain("""{
+ | val omg = "omg"
+ | omg * 2
+ |}""".stripMargin,
+ Seq(),
+ 14
+ )
+ ))
)
}
+ 'Test{
+// check(
+// "@scala.math.abs((1, 2).swap._1.toString())",
+// _.Body.run(),
+// ""
+// )
+ }
}
}