aboutsummaryrefslogtreecommitdiff
path: root/src/test/scala
diff options
context:
space:
mode:
authorjackkoenig2016-03-14 22:35:06 -0700
committerjackkoenig2016-03-15 13:43:57 -0700
commit373d3cfcb5566c448dcad6b679dee43bf66f878a (patch)
tree6a80e496588f56f5c52be40bcc0155ba8987811a /src/test/scala
parent5737a8ccbf54a6d22095023205867e851e204c3f (diff)
Revamp string literal handling
Diffstat (limited to 'src/test/scala')
-rw-r--r--src/test/scala/firrtlTests/FirrtlSpec.scala6
-rw-r--r--src/test/scala/firrtlTests/StringSpec.scala113
2 files changed, 116 insertions, 3 deletions
diff --git a/src/test/scala/firrtlTests/FirrtlSpec.scala b/src/test/scala/firrtlTests/FirrtlSpec.scala
index 438a5282..a8ccb0a9 100644
--- a/src/test/scala/firrtlTests/FirrtlSpec.scala
+++ b/src/test/scala/firrtlTests/FirrtlSpec.scala
@@ -90,7 +90,7 @@ trait BackendCompilationUtilities {
val e = Process(s"./V${prefix}", dir) !
ProcessLogger(line => {
triggered = triggered || line.contains(assertionMsg)
- System.out.println(line)
+ //System.out.println(line)
})
triggered
}
@@ -101,7 +101,7 @@ trait BackendCompilationUtilities {
}
trait FirrtlRunners extends BackendCompilationUtilities {
- lazy val cpp = new File(s"/integration/top.cpp")
+ lazy val cppHarness = new File(s"/top.cpp")
def compileFirrtlTest(prefix: String, srcDir: String): File = {
val testDir = createTempDirectory(prefix)
copyResourceToFile(s"${srcDir}/${prefix}.fir", new File(testDir, s"${prefix}.fir"))
@@ -112,7 +112,7 @@ trait FirrtlRunners extends BackendCompilationUtilities {
def runFirrtlTest(prefix: String, srcDir: String) {
val testDir = compileFirrtlTest(prefix, srcDir)
val harness = new File(testDir, s"top.cpp")
- copyResourceToFile(cpp.toString, harness)
+ copyResourceToFile(cppHarness.toString, harness)
verilogToCpp(prefix, testDir, Seq(), harness).!
cppToExe(prefix, testDir).!
diff --git a/src/test/scala/firrtlTests/StringSpec.scala b/src/test/scala/firrtlTests/StringSpec.scala
new file mode 100644
index 00000000..2278a147
--- /dev/null
+++ b/src/test/scala/firrtlTests/StringSpec.scala
@@ -0,0 +1,113 @@
+
+package firrtlTests
+
+import firrtl._
+
+import java.io._
+
+import scala.sys.process._
+import org.scalatest._
+import org.scalatest.prop._
+import org.scalatest.Assertions._
+import org.scalacheck._
+
+class PrintfSpec extends FirrtlPropSpec {
+
+ property("Printf should correctly print values in each format %x, %d, %b") {
+ val prefix = "Printf"
+ val testDir = compileFirrtlTest(prefix, "/features")
+ val harness = new File(testDir, s"top.cpp")
+ copyResourceToFile(cppHarness.toString, harness)
+
+ verilogToCpp(prefix, testDir, Seq(), harness).!
+ cppToExe(prefix, testDir).!
+
+ // Check for correct Printf:
+ // Count up from 0, match decimal, hex, and binary
+ // see /features/Print.fir to see what we're matching
+ val regex = """\tcount\s+=\s+(\d+)\s+0x(\w+)\s+b([01]+).*""".r
+ var done = false
+ var expected = 0
+ var error = false
+ val ret = Process(s"./V${prefix}", testDir) !
+ ProcessLogger( line => {
+ line match {
+ case regex(dec, hex, bin) => {
+ if (!done) {
+ // Must mark error before assertion or sbt test will pass
+ if (Integer.parseInt(dec, 10) != expected) error = true
+ assert(Integer.parseInt(dec, 10) == expected)
+ if (Integer.parseInt(hex, 16) != expected) error = true
+ assert(Integer.parseInt(hex, 16) == expected)
+ if (Integer.parseInt(bin, 2) != expected) error = true
+ assert(Integer.parseInt(bin, 2) == expected)
+ expected += 1
+ }
+ }
+ case _ => // Do Nothing
+ }
+ })
+ if (error) fail()
+ }
+}
+
+class StringSpec extends FirrtlPropSpec {
+
+ // Whitelist is [0x20 - 0x7e]
+ val whitelist =
+ """ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ""" +
+ """[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"""
+ val whitelistBA: Array[Byte] = Array.range(0x20, 0x7e) map (_.toByte)
+
+ property(s"Character whitelist should be supported: [$whitelist] ") {
+ val lit = firrtl.FIRRTLStringLitHandler.unescape(whitelist)
+ // Check internal
+ lit.array zip whitelistBA foreach { case (b, e) =>
+ assert(b == e, s"(${b.toChar} did not equal expected ${e.toChar})")
+ }
+ // Check result
+ assert(lit.serialize == whitelist)
+ }
+
+ // Valid escapes = \n, \t, \\, \", \'
+ val esc = """\\\'\"\t\n"""
+ val validEsc = Seq('n', 't', '\\', '"', '\'')
+ property(s"Escape characters [$esc] should parse") {
+ val lit = firrtl.FIRRTLStringLitHandler.unescape(esc)
+ assert(lit.array(0) == 0x5c)
+ assert(lit.array(1) == 0x27)
+ assert(lit.array(2) == 0x22)
+ assert(lit.array(3) == 0x09)
+ assert(lit.array(4) == 0x0a)
+ assert(lit.array.length == 5)
+ }
+
+ // Generators for random testing
+ val validChar = for (c <- Gen.choose(0x20.toChar, 0x7e.toChar) if c != '\\') yield c
+ val validCharSeq = Gen.containerOf[Seq, Char](validChar)
+ val invalidChar = Gen.oneOf(Gen.choose(0x00.toChar, 0x1f.toChar),
+ Gen.choose(0x7f.toChar, 0xff.toChar))
+ val invalidEsc = for (
+ c <- Gen.choose(0x00.toChar, 0xff.toChar
+ ) if (!validEsc.contains(c))) yield c
+
+ property("Random invalid strings should fail") {
+ forAll(validCharSeq, invalidChar, validCharSeq) {
+ (head: Seq[Char], bad: Char, tail: Seq[Char]) =>
+ val str = ((head :+ bad) ++ tail).mkString
+ intercept[InvalidStringLitException] {
+ firrtl.FIRRTLStringLitHandler.unescape(str)
+ }
+ }
+ }
+
+ property(s"Invalid escape characters should fail") {
+ forAll(validCharSeq, invalidEsc, validCharSeq) {
+ (head: Seq[Char], badEsc: Char, tail: Seq[Char]) =>
+ val str = (head ++ Seq('\\', badEsc) ++ tail).mkString
+ intercept[InvalidEscapeCharException] {
+ firrtl.FIRRTLStringLitHandler.unescape(str)
+ }
+ }
+ }
+}