In which we start to get serious about the test suite
In the course of writing the blog about loops, I discovered the Forth 2012 Test Suite. I thought it would be pretty cool to include something similar. If I reimplement the entire suite and my interpreter passes it, then it is compliant with the standard.
Tests in the test suite are of the form:
T{
code ->
expected-stack }T
Tests in my version of the test suite are of the form
t("
code", expected: "
expected-stack")
where code is a string containing Forth words to test and expected-stack is a string containing the expected stack after the test. Tests are performed by running code on a test Forth machine and running result on an “expected result” Forth machine. Here is its definition
func t(_ script: String, expected: String, file: String = #file, line: Int = #line, function: String = #function)
{
let fileURL = URL(fileURLWithPath: file)
let location = "\(fileURL.lastPathComponent)(\(line)) \(function)"
do
{
var output = ""
try testMachine.interpret(input: "clearstack", output: &output)
try expectMachine.interpret(input: "clearstack", output: &output)
try testMachine.interpret(input: script, output: &output)
try expectMachine.interpret(input: expected, output: &output)
var actualOutput = ""
var expectedOutput = ""
try testMachine.interpret(input: ".s", output: &actualOutput)
try expectMachine.interpret(input: ".s", output: &expectedOutput)
XCTAssert(actualOutput == expectedOutput, "\(location): Expected '\(expectedOutput)', got '\(actualOutput)'")
}
catch
{
XCTFail("\(location): Error thrown: \(error)")
}
}
The form of the function makes it very easy to convert the Forth Test Suite by doing three global replaces.
The code is tagged blog-1108 and so far replicates about 423 out 639 of the tests in core.