mirror of https://github.com/status-im/NimYAML.git
Added automatic test for quickstart snippets
* There are errors which indicate real bugs!
This commit is contained in:
parent
5d4ec6c43f
commit
0f2e077b87
|
@ -5,6 +5,7 @@ test/tdom
|
||||||
test/tserialization
|
test/tserialization
|
||||||
test/tjson
|
test/tjson
|
||||||
test/yamlTestSuite
|
test/yamlTestSuite
|
||||||
|
test/tquickstart
|
||||||
test/*.exe
|
test/*.exe
|
||||||
test/*.pdb
|
test/*.pdb
|
||||||
test/*.ilk
|
test/*.ilk
|
||||||
|
@ -19,4 +20,5 @@ bench/json
|
||||||
docout
|
docout
|
||||||
doc/rstPreproc
|
doc/rstPreproc
|
||||||
doc/tmp.rst
|
doc/tmp.rst
|
||||||
|
doc/**/code
|
||||||
yaml-dev-kit
|
yaml-dev-kit
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import yaml
|
import yaml.serialization, streams
|
||||||
type Person = object
|
type Person = object
|
||||||
name : string
|
name : string
|
||||||
age : int32
|
age : int32
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import yaml
|
import yaml.serialization, streams
|
||||||
type Person = object
|
type Person = object
|
||||||
name : string
|
name : string
|
||||||
age : int32
|
age : int32
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import yaml
|
import yaml.serialization, yaml.presenter, streams
|
||||||
type Person = object
|
type Person = object
|
||||||
name: string
|
name: string
|
||||||
age: int32
|
age: int32
|
||||||
|
|
||||||
var personList: seq[Person]
|
var personList = newSeq[Person]()
|
||||||
personList.add(Person(name: "Karl Koch", age: 23))
|
personList.add(Person(name: "Karl Koch", age: 23))
|
||||||
personList.add(Person(name: "Peter Pan", age: 12))
|
personList.add(Person(name: "Peter Pan", age: 12))
|
||||||
|
|
||||||
var s = newFileStream("out.yaml")
|
var s = newFileStream("out.yaml", fmWrite)
|
||||||
dump(personList, s, options = defineOptions(
|
dump(personList, s, options = defineOptions(
|
||||||
style = psCanonical,
|
style = psCanonical,
|
||||||
indentationStep = 3,
|
indentationStep = 3,
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
%YAML 1.1
|
%YAML 1.1
|
||||||
--- !nim:system:seq(nim:custom:Person)
|
---
|
||||||
[
|
!nim:system:seq(nim:custom:Person) [
|
||||||
!nim:custom:Person {
|
!nim:custom:Person {
|
||||||
? !!str "name"
|
? !!str "name"
|
||||||
: !!str "Karl Koch",
|
: !!str "Karl Koch",
|
||||||
? !!str "age"
|
? !!str "age"
|
||||||
: !nim:system:int32 "23"
|
: !nim:system:int32 "23"
|
||||||
},
|
},
|
||||||
!nim:custom:Person {
|
!nim:custom:Person {
|
||||||
? !!str "name"
|
? !!str "name"
|
||||||
: !!str "Peter Pan",
|
: !!str "Peter Pan",
|
||||||
? !!str "age"
|
? !!str "age"
|
||||||
: !nim:system:int32 "12"
|
: !nim:system:int32 "12"
|
||||||
}
|
}
|
||||||
]
|
]
|
|
@ -1,4 +1,4 @@
|
||||||
import yaml
|
import yaml.serialization, streams
|
||||||
type
|
type
|
||||||
Node = ref NodeObj
|
Node = ref NodeObj
|
||||||
NodeObj = object
|
NodeObj = object
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import yaml
|
import yaml.serialization, streams
|
||||||
type
|
type
|
||||||
Node = ref NodeObj
|
Node = ref NodeObj
|
||||||
NodeObj = object
|
NodeObj = object
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import yaml
|
import yaml, streams
|
||||||
type Mob = object
|
type Mob = object
|
||||||
level, experience: int32
|
level, experience: int32
|
||||||
drops: seq[string]
|
drops: seq[string]
|
||||||
|
@ -9,6 +9,5 @@ setTagUri(seq[string], "!Drops")
|
||||||
var mob = Mob(level: 42, experience: 1800, drops:
|
var mob = Mob(level: 42, experience: 1800, drops:
|
||||||
@["Sword of Mob Slaying"])
|
@["Sword of Mob Slaying"])
|
||||||
var s = newFileStream("out.yaml", fmWrite)
|
var s = newFileStream("out.yaml", fmWrite)
|
||||||
dump(mob, s,
|
dump(mob, s, tagStyle = tsAll)
|
||||||
options = defineOptions(tagStyle = tsAll))
|
|
||||||
s.close()
|
s.close()
|
|
@ -1,4 +1,4 @@
|
||||||
import yaml
|
import yaml.serialization, yaml.presenter, streams
|
||||||
type Person = object
|
type Person = object
|
||||||
name : string
|
name : string
|
||||||
age : int32
|
age : int32
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "Karl Koch",
|
"name": "Karl Koch",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import yaml
|
import yaml.serialization, streams
|
||||||
type Person = object
|
type Person = object
|
||||||
name : string
|
name : string
|
||||||
age : int32
|
age : int32
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import yaml
|
import yaml, streams
|
||||||
type
|
type
|
||||||
Person = object
|
Person = object
|
||||||
name: string
|
name: string
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import yaml
|
import yaml, streams
|
||||||
type Person = object
|
type Person = object
|
||||||
name: string
|
name: string
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
import unittest, os, osproc, macros, strutils, streams
|
||||||
|
|
||||||
|
proc inputTest(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
|
||||||
|
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
|
||||||
|
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})
|
||||||
|
setCurrentDir(currentDir) # workaround for https://github.com/nim-lang/Nim/issues/4867
|
||||||
|
if process.waitForExit() != 0:
|
||||||
|
echo "executable output:"
|
||||||
|
echo "==================\n"
|
||||||
|
echo process.outputStream().readAll()
|
||||||
|
result = false
|
||||||
|
else: result = true
|
||||||
|
|
||||||
|
proc outputTest(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
|
||||||
|
copyFile(codeFileOrig, codeFileDest)
|
||||||
|
defer: removeFile(codeFileDest)
|
||||||
|
var process = startProcess("nim c --hints:off -p:" & escape(basePath) &
|
||||||
|
" code.nim", path, [], 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"
|
||||||
|
echo process.outputStream().readAll()
|
||||||
|
result = false
|
||||||
|
else:
|
||||||
|
defer: removeFile(exeFileDest)
|
||||||
|
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"
|
||||||
|
echo process.outputStream().readAll()
|
||||||
|
result = false
|
||||||
|
else:
|
||||||
|
var
|
||||||
|
expected = open(path / "01-out.yaml", fmRead)
|
||||||
|
actual = open(path / "out.yaml", 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(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))))
|
||||||
|
elif fileExists(path / "01-out.yaml"):
|
||||||
|
test.add(newCall("doAssert", newCall("outputTest", 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()
|
|
@ -18,6 +18,9 @@
|
||||||
|
|
||||||
import tables, typetraits, strutils, macros, streams
|
import tables, typetraits, strutils, macros, streams
|
||||||
import parser, taglib, presenter, stream, ../private/internal, hints
|
import parser, taglib, presenter, stream, ../private/internal, hints
|
||||||
|
export stream
|
||||||
|
# *something* in here needs externally visible `==`(x,y: AnchorId),
|
||||||
|
# but I cannot figure out what. binding it would be the better option.
|
||||||
|
|
||||||
type
|
type
|
||||||
SerializationContext* = ref object
|
SerializationContext* = ref object
|
||||||
|
|
Loading…
Reference in New Issue