diff --git a/README.md b/README.md index af0dd5d..8a421ae 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/config.nims b/config.nims index efa86f8..5340dbe 100644 --- a/config.nims +++ b/config.nims @@ -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" diff --git a/test/tests.nim b/test/tests.nim index 26231ad..4be6a76 100644 --- a/test/tests.nim +++ b/test/tests.nim @@ -4,4 +4,4 @@ # See the file "copying.txt", included in this # distribution, for details about the copyright. -import tlex, tjson, tserialization, tdom \ No newline at end of file +import tlex, tjson, tserialization, tdom, tparser, tquickstart \ No newline at end of file diff --git a/test/tparser.nim b/test/tparser.nim new file mode 100644 index 0000000..9da5fa2 --- /dev/null +++ b/test/tparser.nim @@ -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() \ No newline at end of file diff --git a/test/tquickstart.nim b/test/tquickstart.nim index d33c1ba..018fc71 100644 --- a/test/tquickstart.nim +++ b/test/tquickstart.nim @@ -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() \ No newline at end of file diff --git a/test/yamlTestSuite.nim b/test/yamlTestSuite.nim deleted file mode 100644 index 2423af4..0000000 --- a/test/yamlTestSuite.nim +++ /dev/null @@ -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) \ No newline at end of file