Integrated parser and quickstart tests

* Now executed when calling `nim tests`
 * Refactored parser tests to use unittest
 * Fixed some pwd issues in tests
This commit is contained in:
Felix Krause 2016-10-09 15:05:18 +02:00
parent 4bde3a7986
commit 846b836e92
6 changed files with 150 additions and 118 deletions

View File

@ -25,15 +25,16 @@ available as tags in this repository and can be fetched via nimble:
## Developers
```bash
nim tests # runs unit tests (serialization, dom, json)
# for parser tests, see yamlTestSuite
nim tests # runs all tests
nim lexerTests # run lexer tests
nim parserTests # run parser tests (git-clones yaml-dev-kit)
nim serializationTests # runs serialization tests
nim quickstartTests # run tests for quickstart snippets from documentation
nim documentation # builds documentation to folder docout
nim server # builds the REST server used for the testing ground
nim bench # runs benchmarks, requires libyaml
nim clean # guess
nim build # build a library
nim yamlTestSuite # execute YAML test suite (git-clones yaml-dev-kit)
```
NimYAML needs at least Nim 0.15.0 in order to compile.

View File

@ -8,15 +8,25 @@ task tests, "Run all tests":
--verbosity:0
setCommand "c", "test/tests"
task yamlTestSuite, "Run YAML 1.2 test suite":
task lexerTests, "Run lexer tests":
--r
--verbosity:0
setCommand "c", "test/yamlTestSuite"
setCommand "c", "test/tlex"
task parserTests, "Run parser tests":
--r
--verbosity:0
setCommand "c", "test/tparser"
task serializationTests, "Run serialization tests":
--r
--verbosity:0
setCommand "c", "test/serializing"
setCommand "c", "test/tserialization"
task quickstartTests, "Run quickstart tests":
--r
--verbosity:0
setCommand "c", "test/tquickstart"
task documentation, "Generate documentation":
exec "mkdir -p docout"

View File

@ -4,4 +4,4 @@
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
import tlex, tjson, tserialization, tdom
import tlex, tjson, tserialization, tdom, tparser, tquickstart

106
test/tparser.nim Normal file
View File

@ -0,0 +1,106 @@
# NimYAML - YAML implementation in Nim
# (c) Copyright 2016 Felix Krause
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
import os, osproc, terminal, strutils, streams, macros, unittest
import testEventParser, commonTestUtils
import "../yaml"
const devKitFolder = "yaml-dev-kit"
proc echoError(msg: string) =
styledWriteLine(stdout, fgRed, "[error] ", fgWhite, msg, resetStyle)
proc ensureDevKitCloneCorrect() {.compileTime.} =
if dirExists(devKitFolder):
var isCorrectClone = true
if dirExists(devKitFolder / ".git"):
let remoteUrl =
staticExec("cd " & devKitFolder & " && git remote get-url origin")
if remoteUrl != "https://github.com/ingydotnet/yaml-dev-kit.git":
isCorrectClone = false
let branches = staticExec("cd " & devKitFolder & " && git branch")
if "* data" notin branches.splitLines():
isCorrectClone = false
if isCorrectClone:
let updateOutput = staticExec("git pull")
#if uError != 0:
# echo "could not update yaml-dev-kit! please fix this problem and compile again."
# echo "output:\n"
# echo "$ git pull"
# echo updateOutput
# quit 1
else:
echo devKitFolder, " exists, but is not in expected state. Make sure it is a git repo,"
echo "cloned from https://github.com/ingydotnet/yaml-dev-kit.git, and the data branch"
echo "is active. Alternatively, delete the folder " & devKitFolder & '.'
quit 1
else:
let cloneOutput = staticExec("git clone https://github.com/ingydotnet/yaml-dev-kit.git -b data")
#if cError != 0:
# echo "could not clone https://github.com/ingydotnet/yaml-dev-kit.git. Make sure"
# echo "you are connected to the internet and your proxy settings are correct. output:\n"
# echo "$ git clone https://github.com/ingydotnet/yaml-dev-kit.git"
# echo cloneOutput
# quit 1
proc parserTest(path: string): bool =
var
tagLib = initExtendedTagLibrary()
parser = newYamlParser(tagLib)
actualIn = newFileStream(path / "in.yaml")
actual = parser.parse(actualIn)
expectedIn = newFileStream(path / "test.event")
expected = parseEventStream(expectedIn, tagLib)
defer:
actualIn.close()
expectedIn.close()
var i = 1
try:
while not actual.finished():
let actualEvent = actual.next()
if expected.finished():
echoError("At token #" & $i & ": Expected stream end, got " &
$actualEvent.kind)
return false
let expectedEvent = expected.next()
if expectedEvent != actualEvent:
printDifference(expectedEvent, actualEvent)
echoError("At token #" & $i &
": Actual tokens do not match expected tokens")
return false
i.inc()
if not expected.finished():
echoError("Got fewer tokens than expected, first missing " &
"token: " & $expected.next().kind)
return false
except:
let e = getCurrentException()
if e.parent of YamlParserError:
let pe = (ref YamlParserError)(e.parent)
echo "line ", pe.line, ", column ", pe.column, ": ", pe.msg
echo pe.lineContent
else: echo e.msg
echoError("Catched an exception at token #" & $i &
" test was not successful")
return false
result = true
macro genTests(): untyped =
ensureDevKitCloneCorrect()
result = newStmtList()
let pwd = staticExec("pwd")
for kind, dirName in walkDir(devKitFolder, true):
if kind == pcDir:
if dirName in [".git", "name", "tags", "meta"]: continue
# see https://github.com/nim-lang/Nim/issues/4871
let title = slurp(pwd / devKitFolder / dirName / "===")
result.add(newCall("test",
newLit(strip(title) & " [" &
dirName & ']'), newCall("doAssert", newCall("parserTest",
newLit(devKitFolder / dirName)))))
result = newCall("suite", newLit("Parser Tests (from yaml-dev-kit)"), result)
genTests()

View File

@ -1,23 +1,21 @@
import unittest, os, osproc, macros, strutils, streams
proc inputTest(path: string): bool =
proc inputTest(basePath, path: string): bool =
let
inFileOrig = path / "01-in.yaml"
inFileDest = path / "in.yaml"
codeFileOrig = path / "00-code.nim"
codeFileDest = path / "code.nim"
exeFileDest = when defined(windows): path / "code.exe" else: path / "code"
currentDir = getCurrentDir()
basePath = currentDir / ".."
absolutePath = currentDir / path
absolutePath = basePath / path
inFileOrig = absolutePath / "01-in.yaml"
inFileDest = absolutePath / "in.yaml"
codeFileOrig = absolutePath / "00-code.nim"
codeFileDest = absolutePath / "code.nim"
exeFileDest = when defined(windows): absolutePath / "code.exe" else:
absolutePath / "code"
copyFile(inFileOrig, inFileDest)
copyFile(codeFileOrig, codeFileDest)
defer:
removeFile(inFileDest)
removeFile(codeFileDest)
var process = startProcess("nim c --hints:off -p:" & escape(basePath) &
" code.nim", path, [], nil, {poStdErrToStdOut, poEvalCommand})
setCurrentDir(currentDir) # workaround for https://github.com/nim-lang/Nim/issues/4867
" code.nim", absolutePath, [], nil, {poStdErrToStdOut, poEvalCommand})
defer:
process.close()
if process.waitForExit() != 0:
@ -30,7 +28,6 @@ proc inputTest(path: string): bool =
process.close()
process = startProcess(absolutePath / "code", absolutePath, [], nil,
{poStdErrToStdOut, poEvalCommand})
setCurrentDir(currentDir) # workaround for https://github.com/nim-lang/Nim/issues/4867
if process.waitForExit() != 0:
echo "executable output:"
echo "==================\n"
@ -38,22 +35,20 @@ proc inputTest(path: string): bool =
result = false
else: result = true
proc outputTest(path: string): bool =
proc outputTest(basePath, path: string): bool =
let
codeFileOrig = path / "00-code.nim"
codeFileDest = path / "code.nim"
exeFileDest = when defined(windows): path / "code.exe" else: path / "code"
currentDir = getCurrentDir()
basePath = currentDir / ".."
absolutePath = currentDir / path
outFileExpected = path / "01-out.yaml"
outFileActual = path / "out.yaml"
absolutePath = basePath / path
codeFileOrig = absolutePath / "00-code.nim"
codeFileDest = absolutePath / "code.nim"
exeFileDest = when defined(windows): absolutePath / "code.exe" else:
absolutePath / "code"
outFileExpected = absolutePath / "01-out.yaml"
outFileActual = absolutePath / "out.yaml"
copyFile(codeFileOrig, codeFileDest)
defer: removeFile(codeFileDest)
var process = startProcess("nim c --hints:off -p:" & escape(basePath) &
" code.nim", path, [], nil, {poStdErrToStdOut, poEvalCommand})
" code.nim", absolutePath, [], nil, {poStdErrToStdOut, poEvalCommand})
defer: process.close()
setCurrentDir(currentDir) # workaround for https://github.com/nim-lang/Nim/issues/4867
if process.waitForExit() != 0:
echo "compiler output:"
echo "================\n"
@ -64,7 +59,6 @@ proc outputTest(path: string): bool =
process.close()
process = startProcess(absolutePath / "code", absolutePath, [], nil,
{poStdErrToStdOut, poEvalCommand})
setCurrentDir(currentDir) # workaround for https://github.com/nim-lang/Nim/issues/4867
if process.waitForExit() != 0:
echo "executable output:"
echo "==================\n"
@ -108,13 +102,17 @@ proc outputTest(path: string): bool =
proc testsFor(path: string, root: bool = true, titlePrefix: string = ""):
NimNode {.compileTime.} =
result = newStmtList()
let title = titlePrefix & slurp(path / "title").splitLines()[0]
let
baseDir = staticExec("pwd")
title = titlePrefix & slurp(baseDir / path / "title").splitLines()[0]
if fileExists(path / "00-code.nim"):
var test = newCall("test", newLit(title))
if fileExists(path / "01-in.yaml"):
test.add(newCall("doAssert", newCall("inputTest", newLit(path))))
test.add(newCall("doAssert", newCall("inputTest", newLit(baseDir),
newLit(path))))
elif fileExists(path / "01-out.yaml"):
test.add(newCall("doAssert", newCall("outputTest", newLit(path))))
test.add(newCall("doAssert", newCall("outputTest", newLit(baseDir),
newLit(path))))
else:
echo "Error: neither 01-in.yaml nor 01-out.yaml exists in " & path & '!'
quit 1
@ -126,6 +124,6 @@ proc testsFor(path: string, root: bool = true, titlePrefix: string = ""):
if root:
result = newCall("suite", newLit(title), result)
macro genTests(): untyped = testsFor("../doc/snippets/quickstart")
macro genTests(): untyped = testsFor("doc/snippets/quickstart")
genTests()

View File

@ -1,83 +0,0 @@
# NimYAML - YAML implementation in Nim
# (c) Copyright 2016 Felix Krause
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
import os, terminal, strutils, streams
import testEventParser, commonTestUtils
import "../yaml"
const gitCmd =
"git clone https://github.com/ingydotnet/yaml-dev-kit.git -b data"
proc echoError(msg: string) =
styledWriteLine(stdout, fgRed, "[error] ", fgWhite, msg, resetStyle)
proc echoInfo(msg: string) =
styledWriteLine(stdout, fgGreen, "[info] ", fgWhite, msg, resetStyle)
removeDir("yaml-dev-kit")
if execShellCmd(gitCmd) != 0:
echoError("Could not check out yaml-dev-kit (no internet connection?)")
quit(1)
var gotErrors = false
for kind, dirPath in walkDir("yaml-dev-kit"):
block curTest:
if kind == pcDir:
if dirPath[^4..^1] in [".git", "name", "tags", "meta"]: continue
var
tagLib = initExtendedTagLibrary()
parser = newYamlParser(tagLib)
actualIn = newFileStream(dirPath / "in.yaml")
actual = parser.parse(actualIn)
expectedIn = newFileStream(dirPath / "test.event")
expected = parseEventStream(expectedIn, tagLib)
styledWriteLine(stdout, fgBlue, "[test] ", fgWhite, dirPath[^4..^1],
": ", strip(readFile(dirPath / "===")), resetStyle)
var i = 1
try:
while not actual.finished():
let actualEvent = actual.next()
if expected.finished():
echoError("At token #" & $i & ": Expected stream end, got " &
$actualEvent.kind)
gotErrors = true
actualIn.close()
expectedIn.close()
break curTest
let expectedEvent = expected.next()
if expectedEvent != actualEvent:
printDifference(expectedEvent, actualEvent)
echoError("At token #" & $i &
": Actual tokens do not match expected tokens")
gotErrors = true
actualIn.close()
expectedIn.close()
break curTest
i.inc()
if not expected.finished():
echoError("Got fewer tokens than expected, first missing " &
"token: " & $expected.next().kind)
gotErrors = true
except:
gotErrors = true
let e = getCurrentException()
if e.parent of YamlParserError:
let pe = (ref YamlParserError)(e.parent)
echo "line ", pe.line, ", column ", pe.column, ": ", pe.msg
echo pe.lineContent
else: echo e.msg
echoError("Catched an exception at token #" & $i &
" test was not successful")
actualIn.close()
expectedIn.close()
if gotErrors:
echoError("There were errors while running the tests")
quit(1)
else:
echoInfo("All tests were successful")
quit(0)