mirror of
https://github.com/status-im/NimYAML.git
synced 2025-01-26 19:19:24 +00:00
Added automatic test for quickstart snippets
* There are errors which indicate real bugs!
This commit is contained in:
parent
5d4ec6c43f
commit
0f2e077b87
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,6 +5,7 @@ test/tdom
|
||||
test/tserialization
|
||||
test/tjson
|
||||
test/yamlTestSuite
|
||||
test/tquickstart
|
||||
test/*.exe
|
||||
test/*.pdb
|
||||
test/*.ilk
|
||||
@ -19,4 +20,5 @@ bench/json
|
||||
docout
|
||||
doc/rstPreproc
|
||||
doc/tmp.rst
|
||||
doc/**/code
|
||||
yaml-dev-kit
|
||||
|
@ -1,4 +1,4 @@
|
||||
import yaml
|
||||
import yaml.serialization, streams
|
||||
type Person = object
|
||||
name : string
|
||||
age : int32
|
||||
|
@ -1,8 +1,8 @@
|
||||
%YAML 1.2
|
||||
--- !nim:system:seq(nim:custom:Person)
|
||||
-
|
||||
--- !nim:system:seq(nim:custom:Person)
|
||||
-
|
||||
name: Karl Koch
|
||||
age: 23
|
||||
-
|
||||
-
|
||||
name: Peter Pan
|
||||
age: 12
|
||||
age: 12
|
||||
|
@ -1,4 +1,4 @@
|
||||
import yaml
|
||||
import yaml.serialization, streams
|
||||
type Person = object
|
||||
name : string
|
||||
age : int32
|
||||
|
@ -1,13 +1,13 @@
|
||||
import yaml
|
||||
import yaml.serialization, yaml.presenter, streams
|
||||
type Person = object
|
||||
name: string
|
||||
age: int32
|
||||
|
||||
var personList: seq[Person]
|
||||
var personList = newSeq[Person]()
|
||||
personList.add(Person(name: "Karl Koch", age: 23))
|
||||
personList.add(Person(name: "Peter Pan", age: 12))
|
||||
|
||||
var s = newFileStream("out.yaml")
|
||||
var s = newFileStream("out.yaml", fmWrite)
|
||||
dump(personList, s, options = defineOptions(
|
||||
style = psCanonical,
|
||||
indentationStep = 3,
|
||||
|
@ -1,16 +1,16 @@
|
||||
%YAML 1.1
|
||||
--- !nim:system:seq(nim:custom:Person)
|
||||
[
|
||||
!nim:custom:Person {
|
||||
---
|
||||
!nim:system:seq(nim:custom:Person) [
|
||||
!nim:custom:Person {
|
||||
? !!str "name"
|
||||
: !!str "Karl Koch",
|
||||
? !!str "age"
|
||||
: !nim:system:int32 "23"
|
||||
},
|
||||
!nim:custom:Person {
|
||||
},
|
||||
!nim:custom:Person {
|
||||
? !!str "name"
|
||||
: !!str "Peter Pan",
|
||||
? !!str "age"
|
||||
: !nim:system:int32 "12"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -1,4 +1,4 @@
|
||||
import yaml
|
||||
import yaml.serialization, streams
|
||||
type
|
||||
Node = ref NodeObj
|
||||
NodeObj = object
|
||||
|
@ -1,11 +1,11 @@
|
||||
%YAML 1.2
|
||||
--- !nim:custom:NodeObj &a
|
||||
--- !nim:custom:NodeObj &a
|
||||
name: Node 1
|
||||
left:
|
||||
left:
|
||||
name: Node 2
|
||||
left: !!null ~
|
||||
right: &b
|
||||
right: &b
|
||||
name: Node 3
|
||||
left: *a
|
||||
right: !!null ~
|
||||
right: *b
|
||||
right: *b
|
||||
|
@ -1,4 +1,4 @@
|
||||
import yaml
|
||||
import yaml.serialization, streams
|
||||
type
|
||||
Node = ref NodeObj
|
||||
NodeObj = object
|
||||
|
@ -1,4 +1,4 @@
|
||||
import yaml
|
||||
import yaml, streams
|
||||
type Mob = object
|
||||
level, experience: int32
|
||||
drops: seq[string]
|
||||
@ -9,6 +9,5 @@ setTagUri(seq[string], "!Drops")
|
||||
var mob = Mob(level: 42, experience: 1800, drops:
|
||||
@["Sword of Mob Slaying"])
|
||||
var s = newFileStream("out.yaml", fmWrite)
|
||||
dump(mob, s,
|
||||
options = defineOptions(tagStyle = tsAll))
|
||||
dump(mob, s, tagStyle = tsAll)
|
||||
s.close()
|
@ -1,5 +1,5 @@
|
||||
%YAML 1.2
|
||||
--- !Mob
|
||||
--- !Mob
|
||||
!nim:field level: !nim:system:int32 42
|
||||
!nim:field experience: !nim:system:int32 1800
|
||||
!nim:field drops: !Drops [!!str Sword of Mob Slaying]
|
||||
!nim:field drops: !Drops [!!str Sword of Mob Slaying]
|
||||
|
@ -1,4 +1,4 @@
|
||||
import yaml
|
||||
import yaml.serialization, yaml.presenter, streams
|
||||
type Person = object
|
||||
name : string
|
||||
age : int32
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
[
|
||||
{
|
||||
"name": "Karl Koch",
|
||||
@ -7,4 +8,4 @@
|
||||
"name": "Peter Pan",
|
||||
"age": 12
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -1,4 +1,4 @@
|
||||
import yaml
|
||||
import yaml.serialization, streams
|
||||
type Person = object
|
||||
name : string
|
||||
age : int32
|
||||
|
@ -1,4 +1,4 @@
|
||||
import yaml
|
||||
import yaml, streams
|
||||
type
|
||||
Person = object
|
||||
name: string
|
||||
|
@ -1,4 +1,4 @@
|
||||
import yaml
|
||||
import yaml, streams
|
||||
type Person = object
|
||||
name: string
|
||||
|
||||
|
128
test/tquickstart.nim
Normal file
128
test/tquickstart.nim
Normal file
@ -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 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
|
||||
SerializationContext* = ref object
|
||||
|
Loading…
x
Reference in New Issue
Block a user