summaryrefslogtreecommitdiff
path: root/scalatexApi/src/test/scala
diff options
context:
space:
mode:
Diffstat (limited to 'scalatexApi/src/test/scala')
-rw-r--r--scalatexApi/src/test/scala/scalatex/AdvancedTests.scala120
-rw-r--r--scalatexApi/src/test/scala/scalatex/BasicTests.scala418
-rw-r--r--scalatexApi/src/test/scala/scalatex/ErrorTests.scala321
-rw-r--r--scalatexApi/src/test/scala/scalatex/ParserTests.scala50
-rw-r--r--scalatexApi/src/test/scala/scalatex/TestUtil.scala16
5 files changed, 925 insertions, 0 deletions
diff --git a/scalatexApi/src/test/scala/scalatex/AdvancedTests.scala b/scalatexApi/src/test/scala/scalatex/AdvancedTests.scala
new file mode 100644
index 0000000..4315735
--- /dev/null
+++ b/scalatexApi/src/test/scala/scalatex/AdvancedTests.scala
@@ -0,0 +1,120 @@
+package scalatex
+
+import utest._
+import scalatex.stages._
+import scalatags.Text.all._
+
+
+/**
+* Created by haoyi on 7/14/14.
+*/
+object AdvancedTests extends TestSuite{
+ import TestUtil._
+
+ val tests = TestSuite{
+ 'localDef{
+ check(
+ tw("""
+ @lol(n: Int) = @{
+ "omg" * n
+ }
+
+ @lol(2)
+ """),
+ "omgomg"
+ )
+ }
+ 'innerTemplate{
+ check(
+ tw("""
+ @lol(f: Int) =
+ omg @f
+
+ @lol(1)
+ @lol(2: Int)
+ @lol(3 + 1)
+ """),
+ tw("""
+ @lol(f: Int) ={
+ omg @f
+ }
+ @lol(1)
+ @lol(2: Int)
+ @lol(3 + 1)
+ """),
+ tw("""
+ @lol(f: Int) = {
+ omg @f
+ }
+ @lol(1)
+ @lol(2: Int)
+ @lol(3 + 1)
+ """),
+ """
+ omg1omg2omg4
+ """
+ )
+ }
+ 'innerInnerTemplate{
+ check(
+ tw("""
+ @lol(f: Int) =
+ @wtf(g: Int) =
+ wtf @g
+
+ @wtf(1 + 2 + 3)
+ @wtf(f)
+
+ @lol(1)
+ @lol(2: Int)
+ @lol(3 + 1)
+ """),
+ tw("""
+ @lol(f: Int) = {
+ @wtf(g: Int) = {
+ wtf @g
+ }
+ @wtf(1 + 2 + 3)
+ @wtf(f)
+ }
+ @lol(1)
+ @lol(2: Int)
+ @lol(3 + 1)
+ """),
+ tw("""
+ @lol(f: Int) = {
+ @wtf(g: Int) =
+ wtf @g
+
+ @wtf(1 + 2 + 3)
+ @wtf(f)
+ }
+ @lol(1)
+ @lol(2: Int)
+ @lol(3 + 1)
+ """),
+ tw("""
+ @lol(f: Int) =
+ @wtf(g: Int) = {
+ wtf @g
+ }
+ @wtf(1 + 2 + 3)
+ @wtf(f)
+
+ @lol(1)
+ @lol(2: Int)
+ @lol(3 + 1)
+ """),
+ """
+ wtf6
+ wtf1
+ wtf6
+ wtf2
+ wtf6
+ wtf4
+ """
+ )
+ }
+
+ }
+}
diff --git a/scalatexApi/src/test/scala/scalatex/BasicTests.scala b/scalatexApi/src/test/scala/scalatex/BasicTests.scala
new file mode 100644
index 0000000..0488ef6
--- /dev/null
+++ b/scalatexApi/src/test/scala/scalatex/BasicTests.scala
@@ -0,0 +1,418 @@
+package scalatex
+import utest._
+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
+ """
+ )
+ }
+ '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>
+ """
+ )
+ }
+ 'parenArgumentLists{
+ 'attributes{
+ check(
+ tw("""
+ @div(id:="my-id") omg
+ @div(id:="my-id"){ omg }
+ @div(id:="my-id")
+ omg
+ """),
+ """
+ <divid="my-id">omg</div>
+ <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
+ """),
+ """
+ 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><span></span><a></a>HelloWorld</h1>
+ <h2><span></span><a></a>hello<b>world</b></h2>
+ <h3><i></i><div>Cow</div></h3>
+ """
+ )
+ }
+ '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>
+ """
+ )
+ }
+
+ '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
+ }
+ """),
+ 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("""
+ @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
new file mode 100644
index 0000000..a122dd2
--- /dev/null
+++ b/scalatexApi/src/test/scala/scalatex/ErrorTests.scala
@@ -0,0 +1,321 @@
+package scalatex
+
+import utest._
+import scalatex.stages._
+import scalatags.Text.all._
+import scalatex.Internals.{DebugFailure, twDebug}
+
+/**
+* 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(
+ twDebug("omg @notInScope lol"),
+ """not found: value notInScope""",
+ """
+ twDebug("omg @notInScope lol"),
+ ^
+ """
+ )
+
+ 'chained{
+ 'properties {
+ * - check(
+ twDebug("omg @math.lol lol"),
+ """object lol is not a member of package math""",
+ """
+ twDebug("omg @math.lol lol"),
+ ^
+ """
+ )
+
+ * - check(
+ twDebug("omg @math.E.lol lol"),
+ """value lol is not a member of Double""",
+ """
+ twDebug("omg @math.E.lol lol"),
+ ^
+ """
+ )
+ * - check(
+ twDebug("omg @_root_.scala.math.lol lol"),
+ """object lol is not a member of package math""",
+ """
+ twDebug("omg @_root_.scala.math.lol lol"),
+ ^
+ """
+ )
+ * - check(
+ twDebug("omg @_root_.scala.gg.lol lol"),
+ """object gg is not a member of package scala""",
+ """
+ twDebug("omg @_root_.scala.gg.lol lol"),
+ ^
+ """
+ )
+ * - check(
+ twDebug("omg @_root_.ggnore.math.lol lol"),
+ """object ggnore is not a member of package <root>""",
+ """
+ twDebug("omg @_root_.ggnore.math.lol lol"),
+ ^
+ """
+ )
+ }
+ 'calls{
+ * - check(
+ twDebug("@scala.QQ.abs(-10).tdo(10).sum.z"),
+ """object QQ is not a member of package scala""",
+ """
+ twDebug("@scala.QQ.abs(-10).tdo(10).sum.z"),
+ ^
+ """
+ )
+ * - check(
+ twDebug("@scala.math.abs(-10).tdo(10).sum.z"),
+ "value tdo is not a member of Int",
+ """
+ twDebug("@scala.math.abs(-10).tdo(10).sum.z"),
+ ^
+ """
+ )
+ * - check(
+ twDebug("@scala.math.abs(-10).to(10).sum.z"),
+ "value z is not a member of Int",
+ """
+ twDebug("@scala.math.abs(-10).to(10).sum.z"),
+ ^
+ """
+ )
+ * - check(
+ twDebug("@scala.math.abs(-10).to(10).sum.z()"),
+ "value z is not a member of Int",
+ """
+ twDebug("@scala.math.abs(-10).to(10).sum.z()"),
+ ^
+ """
+ )
+ * - check(
+ twDebug("@scala.math.abs(-10).cow.sum.z"),
+ "value cow is not a member of Int",
+ """
+ twDebug("@scala.math.abs(-10).cow.sum.z"),
+ ^
+ """
+ )
+ * - check(
+ twDebug("@scala.smath.abs.cow.sum.z"),
+ "object smath is not a member of package scala",
+ """
+ twDebug("@scala.smath.abs.cow.sum.z"),
+ ^
+ """
+ )
+ * - check(
+ twDebug("""
+ 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
+ ^
+ """
+ )
+ }
+ 'callContents{
+ * - check(
+ twDebug("@scala.math.abs((1, 2).wtf)"),
+ "value wtf is not a member of (Int, Int)",
+ """
+ twDebug("@scala.math.abs((1, 2).wtf)"),
+ ^
+ """
+ )
+
+ * - check(
+ twDebug("@scala.math.abs((1, 2).swap._1.toString().map(_.toString.wtf))"),
+ "value wtf is not a member of String",
+ """
+ twDebug("@scala.math.abs((1, 2).swap._1.toString().map(_.toString.wtf))"),
+ ^
+ """
+ )
+ }
+ }
+ 'ifElse{
+ 'oneLine {
+ * - check(
+ twDebug("@if(math > 10){ 1 }else{ 2 }"),
+ "object > is not a member of package math",
+ """
+ twDebug("@if(math > 10){ 1 }else{ 2 }"),
+ ^
+ """
+ )
+ * - check(
+ twDebug("@if(true){ (@math.pow(10)) * 10 }else{ 2 }"),
+ "Unspecified value parameter y",
+ """
+ twDebug("@if(true){ (@math.pow(10)) * 10 }else{ 2 }"),
+ ^
+ """
+ )
+ * - check(
+ twDebug("@if(true){ * 10 }else{ @math.sin(3, 4, 5) }"),
+ "too many arguments for method sin: (x: Double)Double",
+ """
+ twDebug("@if(true){ * 10 }else{ @math.sin(3, 4, 5) }"),
+ ^
+ """
+ )
+ }
+ 'multiLine{
+ * - check(
+ twDebug("""
+ 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(
+ twDebug("""
+ 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(
+ twDebug("""
+ 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(
+ twDebug("omg @for(x <- (0 + 1 + 2) omglolol (10 + 11 + 2)){ hello }"),
+ """value omglolol is not a member of Int""",
+ """
+ twDebug("omg @for(x <- (0 + 1 + 2) omglolol (10 + 11 + 2)){ hello }"),
+ ^
+ """
+ )
+
+ 'body - check(
+ twDebug("omg @for(x <- 0 until 10){ @((x, 2) + (1, 2)) }"),
+ """too many arguments for method +""",
+ """
+ twDebug("omg @for(x <- 0 until 10){ @((x, 2) + (1, 2)) }"),
+ ^
+ """
+ )
+ }
+ 'multiLine{
+ 'body - check(
+ twDebug("""
+ 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(
+ twDebug("""
+ omg @notInScope lol
+ """),
+ """not found: value notInScope""",
+ """
+ omg @notInScope lol
+ ^
+ """
+ )
+ 'wrongType - check(
+ twDebug("""
+ omg @{() => ()} lol
+ """),
+ """type mismatch""",
+ """
+ omg @{() => ()} lol
+ ^
+ """
+ )
+
+ 'bigExpression - check(
+ twDebug("""
+ @{
+ 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
new file mode 100644
index 0000000..619bb3a
--- /dev/null
+++ b/scalatexApi/src/test/scala/scalatex/ParserTests.scala
@@ -0,0 +1,50 @@
+package scalatex
+import utest._
+import scalatex.stages.{TwistNodes, Parser}
+
+/**
+ * Created by haoyi on 8/2/14.
+ */
+object ParserTests extends TestSuite{
+ val WN = TwistNodes
+ val WP = Parser
+ def check[T](s: String, f: Parser => T, expected: Option[T]){
+ val parsed = WP.parse(s, f).toOption
+ assert(parsed == expected)
+ }
+ val tests = TestSuite{
+// 'chainedExpressions {
+// check("", _.expression(), None)
+// check("asd", _.expression(), None)
+// check("@asd", _.expression(), Some(
+// WN.Display(WN.ScalaExp(Seq(WN.Simple("asd"))))
+// ))
+//
+// check("@asd{", _.expression(), None)
+// check("@asd(", _.expression(), None)
+// check("@asd()", _.expression(), Some(
+// WN.Display(WN.ScalaExp(Seq(WN.Simple("asd()"))))
+// ))
+// check("@asd(ggnore)", _.expression(), Some(
+// WN.Display(WN.ScalaExp(Seq(WN.Simple("asd(ggnore)"))))
+// ))
+// check("@asd.wtf(ggnore).bbq.lol", _.expression(), Some(
+// WN.Display(WN.ScalaExp(Seq(WN.Simple("asd"), WN.Simple(".wtf(ggnore).bbq.lol"))))
+// ))
+// check("@asd{}", _.expression(), Some(
+// WN.Display(WN.ScalaExp(Seq(WN.Simple("asd"), WN.Block("", None, Seq()))))
+// ))
+// check("@asd{lol}", _.expression(), Some(
+// WN.Display(WN.ScalaExp(Seq(WN.Simple("asd"), WN.Block("", None, Seq(WN.Plain("lol"))))))
+// ))
+// check("@asd{lol}.wtf('l'){gg}", _.expression(), Some(
+// WN.Display(WN.ScalaExp(Seq(
+// WN.Simple("asd"),
+// WN.Block("", None, Seq(WN.Plain("lol"))),
+// WN.Simple(".wtf('l')"),
+// WN.Block("", None, Seq(WN.Plain("gg")))
+// )))
+// ))
+// }
+ }
+}
diff --git a/scalatexApi/src/test/scala/scalatex/TestUtil.scala b/scalatexApi/src/test/scala/scalatex/TestUtil.scala
new file mode 100644
index 0000000..5a72677
--- /dev/null
+++ b/scalatexApi/src/test/scala/scalatex/TestUtil.scala
@@ -0,0 +1,16 @@
+package scalatex
+
+import utest._
+
+
+object TestUtil {
+ implicit def stringify(f: scalatags.Text.all.Frag) = f.render
+ def check(rendered: String*) = {
+ val collapsed = rendered.map(collapse)
+ val first = collapsed(0)
+ assert(collapsed.forall(_ == first))
+ }
+ def collapse(s: String): String = {
+ s.replaceAll("[ \n]", "")
+ }
+}