NimYAML/test/tquickstart.nim

135 lines
4.8 KiB
Nim

import unittest, os, osproc, macros, strutils, streams
const baseDir = parentDir(staticExec("pwd"))
let (nimPathRaw, nimPathRet) =
execCmdEx("which nim", {poStdErrToStdOut, poUsePath})
if nimPathRet != 0: quit "could not locate nim executable:\n" & nimPathRaw
let nimPath =
if nimPathRaw[0] == '/': nimPathRaw.strip else: baseDir / nimPathRaw.strip
proc inputTest(basePath, path: string): bool =
let
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(nimPath & " c --hints:off -p:" & escape(basePath) &
" code.nim", absolutePath, [], nil, {poStdErrToStdOut, poEvalCommand})
defer:
process.close()
if process.waitForExit() != 0:
echo "compiler output:"
echo "================\n"
echo process.outputStream().readAll()
result = false
else:
defer: removeFile(exeFileDest)
process.close()
process = startProcess(absolutePath / "code", absolutePath, [], nil,
{poStdErrToStdOut, poEvalCommand})
if process.waitForExit() != 0:
echo "executable output:"
echo "==================\n"
echo process.outputStream().readAll()
result = false
else: result = true
proc outputTest(basePath, path: string): bool =
let
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(nimPath & " c --hints:off -p:" & escape(basePath) &
" code.nim", absolutePath, [], nil, {poStdErrToStdOut, poEvalCommand})
defer: process.close()
if process.waitForExit() != 0:
echo "compiler output:"
echo "================\n"
echo process.outputStream().readAll()
result = false
else:
defer: removeFile(exeFileDest)
process.close()
process = startProcess(absolutePath / "code", absolutePath, [], nil,
{poStdErrToStdOut, poEvalCommand})
if process.waitForExit() != 0:
echo "executable output:"
echo "==================\n"
echo process.outputStream().readAll()
result = false
else:
defer: removeFile(outFileActual)
var
expected = open(outFileExpected, fmRead)
actual = open(outFileActual, fmRead)
lineNumber = 1
defer:
expected.close()
actual.close()
var
expectedLine = ""
actualLine = ""
while true:
if expected.readLine(expectedLine):
if actual.readLine(actualLine):
if expectedLine != actualLine:
echo "difference at line #", lineNumber, ':'
echo "expected: ", escape(expectedLine)
echo " actual: ", escape(actualLine)
return false
else:
echo "actual output has fewer lines than expected; ",
"first missing line: #", lineNumber
echo "expected: ", escape(expectedLine)
return false
else:
if actual.readLine(actualLine):
echo "actual output has more lines than expected; ",
"first unexpected line: #", lineNumber
echo "content: ", escape(actualLine)
return false
else: break
lineNumber.inc()
result = true
proc testsFor(path: string, root: bool = true, titlePrefix: string = ""):
NimNode {.compileTime.} =
result = newStmtList()
let
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(baseDir),
newLit(path))))
elif fileExists(path / "01-out.yaml"):
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
result.add(test)
for kind, childPath in walkDir(path):
if kind == pcDir:
if childPath != path / "nimcache":
result.add(testsFor(childPath, false, if root: "" else: title & ' '))
if root:
result = newCall("suite", newLit(title), result)
macro genTests(): untyped = testsFor("doc/snippets/quickstart")
genTests()