diff options
Diffstat (limited to 'lab2/src/test/scala/jsy')
-rw-r--r-- | lab2/src/test/scala/jsy/lab2/Lab2Spec.scala | 269 | ||||
-rw-r--r-- | lab2/src/test/scala/jsy/tester/JavascriptyTester.scala | 27 |
2 files changed, 296 insertions, 0 deletions
diff --git a/lab2/src/test/scala/jsy/lab2/Lab2Spec.scala b/lab2/src/test/scala/jsy/lab2/Lab2Spec.scala new file mode 100644 index 0000000..b14d015 --- /dev/null +++ b/lab2/src/test/scala/jsy/lab2/Lab2Spec.scala @@ -0,0 +1,269 @@ +package jsy.lab2 + +import org.scalatest.flatspec.AnyFlatSpec +import Parser.parse +import ast._ + +/* Import your Lab 1 code. */ +import Lab2._ + +/** + * This is an empty test class that you may use to write your own tests. + */ +class Lab2StudentSpec extends AnyFlatSpec { + + val e_toNumber_test1 = N(3.0) + "toNumber" should s"${e_toNumber_test1}" in { + assertResult(3.0) { toNumber(e_toNumber_test1) } + } + + val e_toBoolean_test1 = B(true) + "toBoolean" should s"${e_toBoolean_test1}" in { + assertResult(true) { toBoolean(e_toBoolean_test1) } + } + + val e_toStr_test1 = S("hello") + "toStr" should s"${e_toStr_test1}" in { + assertResult("hello") { toStr(e_toStr_test1) } + } + +} + +/* + * This file contains a number of *Spec classes that define a set of + * tests. + */ +class Lab2Spec extends AnyFlatSpec { + + "And" should "return true only if both expressions are true" in { + val t = B(true) + val f = B(false) + assert(eval(Binary(And,t,t)) === t) + assert(eval(Binary(And,t,f)) === f) + assert(eval(Binary(And,f,t)) === f) + assert(eval(Binary(And,f,f)) === f) + } + + it should "return non-intuitive results from differing types" in { + val e1 = N(0) + val e2 = B(true) + val e3 = eval(Binary(And, e1, e2)) + assert(e3 === N(0)) + } + + "Or" should "return true if either or both expressions are true" in { + val t = B(true) + val f = B(false) + assert(eval(Binary(Or,t,t)) === t) + assert(eval(Binary(Or,f,t)) === t) + assert(eval(Binary(Or,t,f)) === t) + assert(eval(Binary(Or,f,f)) === f) + } + + it should "return non-intuitive results from differing types" in { + val e1 = N(5) + val e2 = B(false) + val e3 = eval(Binary(Or, e1, e2)) + assert(e3 === N(5)) + } + + "Plus" should "add two number values and return a number" in { + val e1 = N(1) + val e2 = N(2) + val e3 = eval(Binary(Plus, e1, e2)) + assert(e3 === N(3)) + } + + "Minus" should "subtract two number values and return a number" in { + val e1 = N(3) + val e2 = N(1) + val e3 = eval(Binary(Minus, e1, e2)) + assert(e3 === N(2)) + } + + "Times" should "multiply two number values and return a number" in { + val e1 = N(3) + val e2 = N(2) + val e3 = eval(Binary(Times, e1, e2)) + assert(e3 === N(6)) + } + + "Div" should "divide two number values and return a number" in { + val e1 = N(8) + val e2 = N(5) + val e3 = eval(Binary(Div, e1, e2)) + assert(e3 === N(1.6)) + } + + "Arithmetic Operators" should "produce non-intuitive solutions given differing expression types" in { + val e1 = B(true) + val e2 = N(7) + assert(eval(Binary(Plus,e1,e2)) == N(8)) + } + + "Eq" should "return true if two numerical values are the same" in { + val e1 = N(5) + val e2 = N(5) + val e3 = eval(Binary(Eq, e1, e2)) + assert(e3 === B(true)) + } + + it should "return false if two numerical values are not the same" in { + val e1 = N(5) + val e2 = N(7) + val e3 = eval(Binary(Eq, e1, e2)) + assert(e3 === B(false)) + } + + "Ne" should "return true if two numerical values are different" in { + val e1 = N(5) + val e2 = N(7) + val e3 = eval(Binary(Ne, e1, e2)) + assert(e3 === B(true)) + } + + it should "return false if two numerical values are the same" in { + val e1 = N(5) + val e2 = N(5) + val e3 = eval(Binary(Ne, e1, e2)) + assert(e3 === B(false)) + } + + "Lt" should "return true if the first expression is less than the second" in { + val e1 = N(5) + val e2 = N(7) + val e3 = eval(Binary(Lt, e1, e2)) + assert(e3 === B(true)) + } + + it should "return false if the first expression is not strictly less than the second" in { + val e1 = N(7) + val e2 = N(5) + val e3 = eval(Binary(Lt, e1, e2)) + assert(e3 === B(false)) + } + + it should "return false if two number values are the same" in { + val e1 = N(5) + val e2 = N(5) + val e3 = eval(Binary(Lt, e1, e2)) + assert(e3 === B(false)) + } + + "Le" should "return true if the first expression is less than the second" in { + val e1 = N(5) + val e2 = N(7) + val e3 = eval(Binary(Le, e1, e2)) + assert(e3 === B(true)) + } + + it should "return false if the first expression is greater than the second" in { + val e1 = N(7) + val e2 = N(5) + val e3 = eval(Binary(Le, e1, e2)) + assert(e3 === B(false)) + } + + it should "return true if two number values are the same" in { + val e1 = N(5) + val e2 = N(5) + val e3 = eval(Binary(Le, e1, e2)) + assert(e3 === B(true)) + } + + "Gt" should "return true if the first expression is greater than the second" in { + val e1 = N(8) + val e2 = N(7) + val e3 = eval(Binary(Gt, e1, e2)) + assert(e3 === B(true)) + } + + it should "return false if the first expression is not strictly greater than the second" in { + val e1 = N(4) + val e2 = N(5) + val e3 = eval(Binary(Gt, e1, e2)) + assert(e3 === B(false)) + } + + it should "return false if two number values are the same" in { + val e1 = N(5) + val e2 = N(5) + val e3 = eval(Binary(Gt, e1, e2)) + assert(e3 === B(false)) + } + + "Ge" should "return true if the first expression is greater than the second" in { + val e1 = N(8) + val e2 = N(7) + val e3 = eval(Binary(Ge, e1, e2)) + assert(e3 === B(true)) + } + + it should "return false if the first expression is less than the second" in { + val e1 = N(4) + val e2 = N(5) + val e3 = eval(Binary(Ge, e1, e2)) + assert(e3 === B(false)) + } + + it should "return true if two number values are the same" in { + val e1 = N(5) + val e2 = N(5) + val e3 = eval(Binary(Ge, e1, e2)) + assert(e3 === B(true)) + } + + "Comparisons" should "produce non-intuitive results given the expressions given" in { + val e1 = N(5) + val e2 = Undefined + assert(eval(Binary(Eq,e1,e2)) === B(false)) + } + + "ConstDecl" should "extend the environment with the first expression results bound to the identifier, and then eval the second expression" in { + val e1 = N(3) + val e2 = Binary(Plus, Var("x"), N(1)) + val e3 = eval(ConstDecl("x", e1, e2)) + assert(e3 === N(4)) + } + + "If" should "eval the first expression if the conditional is true" in { + val e1 = Binary(Plus, N(3), N(2)) + val e2 = Binary(Plus, N(1), N(1)) + val e3 = eval(If(B(true), e1, e2)) + assert(e3 === N(5)) + } + + it should "eval the second expression if the conditional is false" in { + val e1 = Binary(Plus, N(3), N(2)) + val e2 = Binary(Plus, N(1), N(1)) + val e3 = eval(If(B(false), e1, e2)) + assert(e3 === N(2)) + } + + "Seq" should "execute the first expression, followed by the second, and should eval to the second expression" in { + val e1 = Binary(Plus, N(3), N(2)) + val e2 = Binary(Plus, N(1), N(1)) + val e3 = eval(Binary(Seq, e1, e2)) + assert(e3 === N(2)) + } + + "Neg" should "return the negation of a number value" in { + val e1 = N(5) + val e2 = eval(Unary(Neg, e1)) + assert(e2 === N(-5)) + } + + "Not" should "return the compliment of a boolean value" in { + val e1 = B(true) + val e2 = B(false) + val e3 = eval(Unary(Not, e1)) + val e4 = eval(Unary(Not, e2)) + assert(e3 === B(false)) + assert(e4 === B(true)) + } + +} + +// The next bit of code runs a test for each .jsy file in src/test/resources/lab2. +// The test expects a corresponding .ans file with the expected result. +class Lab2JsyTests extends jsy.tester.JavascriptyTester(None, "lab2", Lab2) diff --git a/lab2/src/test/scala/jsy/tester/JavascriptyTester.scala b/lab2/src/test/scala/jsy/tester/JavascriptyTester.scala new file mode 100644 index 0000000..ab611b9 --- /dev/null +++ b/lab2/src/test/scala/jsy/tester/JavascriptyTester.scala @@ -0,0 +1,27 @@ +package jsy.tester + +import java.io.File + +import jsy.util.JsyApplication +import org.scalatest._ +import flatspec._ + +/* + * A ScalaTest interface for running system tests. + */ +class JavascriptyTester(rootPrefix: Option[String], testDirectory: String, jsy: JsyApplication) extends AnyFlatSpec { + + val testResources = s"src${File.separator}test${File.separator}resources" + val testPrefix = rootPrefix match { + case None => testResources + case Some(p) => s"${p}${File.separator}${testResources}" + } + val testPath = s"${testPrefix}${File.separator}${testDirectory}" + jsy.test(new File(testPath)) { case (in,ans,assertion) => + s"eval on ${in}" should s"match ${ans}" in { + val (b: Boolean, msg: String) = assertion + assert(b, msg) + } + } + +} |