Disabled external gits

This commit is contained in:
2022-04-07 18:43:21 +02:00
parent 182267a8cb
commit 88cb3426ad
1067 changed files with 102374 additions and 6 deletions

View File

@@ -0,0 +1,38 @@
package amyc.test
import java.io.ByteArrayInputStream
import amyc.analyzer.{NameAnalyzer, TypeChecker}
import amyc.codegen._
import amyc.parsing._
import amyc.utils._
import amyc.wasm.Module
import scala.collection.JavaConverters._
import scala.sys.process._
class CodegenTests extends ExecutionTests {
object CodePrinterExecutor extends Pipeline[Module, Unit] {
def run(ctx: Context)(m: Module) = {
CodePrinter.run(ctx)(m)
val fileName = s"${m.name}.js"
// Consume all standard input!
val input = Console.in.lines.iterator().asScala.toList.mkString("\n")
val inputS = new ByteArrayInputStream(input.getBytes("UTF-8"))
val exitCode = s"nodejs wasmout/$fileName" #< inputS ! ProcessLogger(Console.out.println, Console.err.println)
if (exitCode != 0)
throw AmycFatalError("Nonzero code returned from nodejs")
}
}
val pipeline =
Lexer andThen
Parser andThen
NameAnalyzer andThen
TypeChecker andThen
CodeGen andThen
CodePrinterExecutor
}

View File

@@ -0,0 +1,93 @@
package amyc.test
import java.io.File
import java.util.stream.Collectors
import amyc.utils._
import org.junit.Assert.fail
abstract class CompilerTest extends TestUtils {
private def runPipeline(pipeline: Pipeline[List[File], Unit], fileNames: List[String]) = {
val ctx = Context(new Reporter, fileNames)
val files = ctx.files.map(new File(_))
pipeline.run(ctx)(files)
ctx.reporter.terminateIfErrors()
}
private def runPipelineRedirected(
pipeline: Pipeline[List[File], Unit],
compiledFiles: List[String],
input: String
): String = {
testWithRedirectedIO(runPipeline(pipeline, compiledFiles), input)
}
private def assertEqual(output: String, expected: String) = {
val rejectLine = (s: String) =>
s.isEmpty ||
s.startsWith("[ Info ]") ||
s.startsWith("[Warning]") ||
s.startsWith("[ Error ]") ||
s.startsWith("[ Fatal ]")
def filtered(s: String) = s.lines.filter(rejectLine(_)==false).collect(Collectors.joining("\n"));
val filteredOutput = filtered(output)
val filteredExpected = filtered(expected)
if (filteredOutput != filteredExpected) {
val sb = new StringBuffer()
sb.append("\nOutput is different:\n")
sb.append("\nOutput: \n")
sb.append(filteredOutput)
sb.append("\n\nExpected output: \n")
sb.append(filteredExpected)
sb.append("\n")
fail(sb.toString)
}
}
protected def compareOutputs(
pipeline: Pipeline[List[File], Unit],
compiledFiles: List[String],
expectedFile: String,
input: String = ""
) = {
try {
val output = runPipelineRedirected(pipeline, compiledFiles, input)
val expected = scala.io.Source.fromFile(new File(expectedFile)).mkString
assertEqual(output, expected)
} catch {
// We only want to catch AmyFatalError gracefully, the rest can propagate
case AmycFatalError(msg) =>
fail(s"\n $msg\n")
}
}
protected def demandPass(
pipeline: Pipeline[List[File], Unit],
compiledFiles: List[String],
input: String = ""
) = {
try {
runPipelineRedirected(pipeline, compiledFiles, input)
} catch {
case AmycFatalError(msg) =>
fail(s"\n $msg\n")
}
}
protected def demandFailure(
pipeline: Pipeline[List[File], Unit],
compiledFiles: List[String],
input: String = ""
) = {
try {
runPipelineRedirected(pipeline, compiledFiles, input)
fail("Test should fail but it passed!")
} catch {
case AmycFatalError(_) =>
// Ok, this is what we wanted. Other exceptions should propagate though
}
}
}

View File

@@ -0,0 +1,15 @@
package amyc.test
import org.junit.Test
abstract class ExecutionTests extends TestSuite {
val baseDir = "interpreter"
val outputExt = "txt"
@Test def testEmptyObject = shouldOutput("EmptyObject")
@Test def testMinimalError = shouldFail("MinimalError")
}

View File

@@ -0,0 +1,17 @@
package amyc.test
import amyc.parsing._
import org.junit.Test
class LexerTests extends TestSuite {
val pipeline = Lexer andThen DisplayTokens
val baseDir = "lexer"
val outputExt = "txt"
@Test def testKeywords = shouldOutput("Keywords")
@Test def testSingleAmp = shouldFail("SingleAmp")
}

View File

@@ -0,0 +1,44 @@
package amyc.test
import amyc.analyzer.{NameAnalyzer, SymbolTable}
import amyc.ast.SymbolicTreeModule.Program
import amyc.ast.{Identifier, SymbolicPrinter}
import amyc.parsing._
import amyc.utils._
import org.junit.Test
import scala.language.implicitConversions
class NameAnalyzerTests extends TestSuite {
// A little hackery to overcome that Identifier names do not refresh over pipeline runs...
private class TestUniquePrinter extends SymbolicPrinter {
private val counter = new UniqueCounter[String]
private val map = scala.collection.mutable.Map[Identifier, Int]()
override implicit def printName(name: Identifier)(implicit printUniqueIds: Boolean): Document = {
if (printUniqueIds) {
val id = map.getOrElseUpdate(name, counter.next(name.name))
s"${name.name}_$id"
} else {
name.name
}
}
}
private val treePrinterS: Pipeline[(Program, SymbolTable), Unit] = {
new Pipeline[(Program, SymbolTable), Unit] {
def run(ctx: Context)(v: (Program, SymbolTable)) = {
println((new TestUniquePrinter)(v._1)(true))
}
}
}
val pipeline = Lexer andThen Parser andThen NameAnalyzer andThen treePrinterS
val baseDir = "nameAnalyzer"
val outputExt = "scala"
@Test def testParamAndLocal = shouldOutput("ParamAndLocal")
@Test def testArgumentNumberFunction = shouldFail("ArgumentNumberFunction")
}

View File

@@ -0,0 +1,18 @@
package amyc.test
import amyc.parsing._
import org.junit.Test
class ParserTests extends TestSuite with amyc.MainHelpers {
val pipeline = Lexer andThen Parser andThen treePrinterN("")
val baseDir = "parser"
val outputExt = "scala"
@Test def testEmpty = shouldOutput("Empty")
@Test def testLiterals = shouldOutput("Literals")
@Test def testEmptyFile = shouldFail("EmptyFile")
}

View File

@@ -0,0 +1,54 @@
package amyc.test
import java.io.File
import amyc.utils.Pipeline
abstract class TestSuite extends CompilerTest {
val pipeline: Pipeline[List[File], Unit]
val baseDir: String
lazy val effectiveBaseDir: String =
// getClass.getResource(s"/$baseDir").getPath
s"test/resources/$baseDir"
val passing = "passing"
val failing = "failing"
val outputs = "outputs"
val outputExt: String
def shouldOutput(inputFiles: List[String], outputFile: String, input: String = ""): Unit = {
compareOutputs(
pipeline,
inputFiles map (f => s"$effectiveBaseDir/$passing/$f.scala"),
s"$effectiveBaseDir/$outputs/$outputFile.$outputExt",
input
)
}
def shouldOutput(inputFile: String): Unit = {
shouldOutput(List(inputFile), inputFile)
}
def shouldFail(inputFiles: List[String], input: String = ""): Unit = {
demandFailure(
pipeline,
inputFiles map (f => s"$effectiveBaseDir/$failing/$f.scala"),
input
)
}
def shouldFail(inputFile: String): Unit = {
shouldFail(List(inputFile))
}
def shouldPass(inputFiles: List[String], input: String = ""): Unit = {
demandPass(pipeline, inputFiles map (f => s"$effectiveBaseDir/$passing/$f.scala"), input)
}
def shouldPass(inputFile: String): Unit = {
shouldPass(List(inputFile))
}
}

View File

@@ -0,0 +1,24 @@
package amyc.test
import java.io._
/** Some utilities for running tests */
trait TestUtils {
/** Run test,
* with input also redirected from a String,
* and output is redirected to a local StringBuilder.
*/
def testWithRedirectedIO[T](test: => T, input: String): String = {
import scala.Console._
val inputS = new StringReader(input)
val outputS = new ByteArrayOutputStream()
withOut(outputS) {
withErr(outputS) {
withIn(inputS) {
test
}
}
}
outputS.toString()
}
}

View File

@@ -0,0 +1,25 @@
package amyc.test
import amyc.analyzer.{NameAnalyzer, TypeChecker}
import amyc.parsing._
import amyc.utils._
import org.junit.Test
class TyperTests extends TestSuite {
// We need a unit pipeline
private def unit[A]: Pipeline[A, Unit] = {
new Pipeline[A, Unit] {
def run(ctx: Context)(v: A) = ()
}
}
val pipeline = Lexer andThen Parser andThen NameAnalyzer andThen TypeChecker andThen unit
val baseDir = "typer"
val outputExt = "" // No output files for typechecking
@Test def testArithError1 = shouldFail("ArithError1")
@Test def testArithmetic = shouldPass("Arithmetic")
}