diff options
Diffstat (limited to 'scalatexApi/src/test/scala')
-rw-r--r-- | scalatexApi/src/test/scala/scalatex/AdvancedTests.scala | 120 | ||||
-rw-r--r-- | scalatexApi/src/test/scala/scalatex/BasicTests.scala | 418 | ||||
-rw-r--r-- | scalatexApi/src/test/scala/scalatex/ErrorTests.scala | 321 | ||||
-rw-r--r-- | scalatexApi/src/test/scala/scalatex/ParserTests.scala | 50 | ||||
-rw-r--r-- | scalatexApi/src/test/scala/scalatex/TestUtil.scala | 16 |
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]", "") + } +} |