test-runner for caas multi-step tests
This commit is contained in:
parent
ac9db5d684
commit
a8e12afc76
9 changed files with 122 additions and 4 deletions
|
|
@ -23,9 +23,10 @@ proc expectIntLit(c: PContext, n: PNode): int =
|
||||||
proc semInstantiationInfo(c: PContext, n: PNode): PNode =
|
proc semInstantiationInfo(c: PContext, n: PNode): PNode =
|
||||||
result = newNodeIT(nkPar, n.info, n.typ)
|
result = newNodeIT(nkPar, n.info, n.typ)
|
||||||
let idx = expectIntLit(c, n.sons[1])
|
let idx = expectIntLit(c, n.sons[1])
|
||||||
|
let useFullPaths = expectIntLit(c, n.sons[2])
|
||||||
let info = getInfoContext(idx)
|
let info = getInfoContext(idx)
|
||||||
var filename = newNodeIT(nkStrLit, n.info, getSysType(tyString))
|
var filename = newNodeIT(nkStrLit, n.info, getSysType(tyString))
|
||||||
filename.strVal = ToFilename(info)
|
filename.strVal = if useFullPaths != 0: info.toFullPath else: info.ToFilename
|
||||||
var line = newNodeIT(nkIntLit, n.info, getSysType(tyInt))
|
var line = newNodeIT(nkIntLit, n.info, getSysType(tyInt))
|
||||||
line.intVal = ToLinenumber(info)
|
line.intVal = ToLinenumber(info)
|
||||||
result.add(filename)
|
result.add(filename)
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,12 @@ proc write*(s: PStream, x: string) =
|
||||||
## terminating zero is written.
|
## terminating zero is written.
|
||||||
writeData(s, cstring(x), x.len)
|
writeData(s, cstring(x), x.len)
|
||||||
|
|
||||||
|
proc writeln*(s: PStream, args: varargs[string, `$`]) =
|
||||||
|
## writes one or more strings to the the stream `s` followed
|
||||||
|
## by a new line. No length field or terminating zero is written.
|
||||||
|
for str in args: write(s, str)
|
||||||
|
write(s, "\n")
|
||||||
|
|
||||||
proc read[T](s: PStream, result: var T) =
|
proc read[T](s: PStream, result: var T) =
|
||||||
## generic read procedure. Reads `result` from the stream `s`.
|
## generic read procedure. Reads `result` from the stream `s`.
|
||||||
if readData(s, addr(result), sizeof(T)) != sizeof(T):
|
if readData(s, addr(result), sizeof(T)) != sizeof(T):
|
||||||
|
|
|
||||||
|
|
@ -2407,8 +2407,8 @@ proc astToStr*[T](x: T): string {.magic: "AstToStr", noSideEffect.}
|
||||||
## converts the AST of `x` into a string representation. This is very useful
|
## converts the AST of `x` into a string representation. This is very useful
|
||||||
## for debugging.
|
## for debugging.
|
||||||
|
|
||||||
proc InstantiationInfo*(index = -1): tuple[filename: string, line: int] {.
|
proc InstantiationInfo*(index = -1, fullPaths = false): tuple[
|
||||||
magic: "InstantiationInfo", noSideEffect.}
|
filename: string, line: int] {. magic: "InstantiationInfo", noSideEffect.}
|
||||||
## provides access to the compiler's instantiation stack line information.
|
## provides access to the compiler's instantiation stack line information.
|
||||||
##
|
##
|
||||||
## This proc is mostly useful for meta programming (eg. ``assert`` template)
|
## This proc is mostly useful for meta programming (eg. ``assert`` template)
|
||||||
|
|
@ -2438,6 +2438,9 @@ proc InstantiationInfo*(index = -1): tuple[filename: string, line: int] {.
|
||||||
## testException(EInvalidIndex, tester(1))
|
## testException(EInvalidIndex, tester(1))
|
||||||
## # --> Test failure at example.nim:20 with 'tester(1)'
|
## # --> Test failure at example.nim:20 with 'tester(1)'
|
||||||
|
|
||||||
|
template CurrentSourcePath*: string = InstantiationInfo(-1, true).filename
|
||||||
|
## returns the full file-system path of the current source
|
||||||
|
|
||||||
proc raiseAssert*(msg: string) {.noinline.} =
|
proc raiseAssert*(msg: string) {.noinline.} =
|
||||||
raise newException(EAssertionFailed, msg)
|
raise newException(EAssertionFailed, msg)
|
||||||
|
|
||||||
|
|
|
||||||
7
tests/caas/basic-recompile.txt
Normal file
7
tests/caas/basic-recompile.txt
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
main.nim
|
||||||
|
> c
|
||||||
|
SuccessX
|
||||||
|
> c
|
||||||
|
! Processing
|
||||||
|
SuccessX
|
||||||
|
|
||||||
3
tests/caas/imported.nim
Normal file
3
tests/caas/imported.nim
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
proc `+++`*(a,b: string): string =
|
||||||
|
return a & " " & b
|
||||||
|
|
||||||
7
tests/caas/main.nim
Normal file
7
tests/caas/main.nim
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import imported, strutils
|
||||||
|
|
||||||
|
proc main =
|
||||||
|
var t1 = "text"
|
||||||
|
var t2 = t1.toUpper
|
||||||
|
echo(t1 +++ t2)
|
||||||
|
|
||||||
83
tests/caasdriver.nim
Normal file
83
tests/caasdriver.nim
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
import osproc, streams, os, strutils, re
|
||||||
|
|
||||||
|
type
|
||||||
|
TNimrodSession* = object
|
||||||
|
nim: PProcess
|
||||||
|
|
||||||
|
proc dirname(path: string): string = path.splitPath()[0]
|
||||||
|
|
||||||
|
const
|
||||||
|
TesterDir = CurrentSourcePath.dirname
|
||||||
|
NimrodBin = TesterDir / "../bin/nimrod"
|
||||||
|
|
||||||
|
proc startNimrodSession*(project: string): TNimrodSession =
|
||||||
|
result.nim = startProcess(NimrodBin,
|
||||||
|
workingDir = project.dirname,
|
||||||
|
args = ["serve", "--server.type:stdin", project])
|
||||||
|
|
||||||
|
proc doCommand*(session: var TNimrodSession, command: string): string =
|
||||||
|
session.nim.inputStream.write(command & "\n")
|
||||||
|
session.nim.inputStream.flush
|
||||||
|
|
||||||
|
result = ""
|
||||||
|
|
||||||
|
while true:
|
||||||
|
var line = TaintedString("")
|
||||||
|
if session.nim.outputStream.readLine(line):
|
||||||
|
if line.string == "": break
|
||||||
|
result.add(line.string & "\n")
|
||||||
|
|
||||||
|
proc close(session: var TNimrodSession) {.destructor.} =
|
||||||
|
session.nim.close
|
||||||
|
|
||||||
|
proc doScenario(script: string, output: PStream): bool =
|
||||||
|
result = true
|
||||||
|
|
||||||
|
var f = open(script)
|
||||||
|
var project = TaintedString("")
|
||||||
|
|
||||||
|
if f.readLine(project):
|
||||||
|
var
|
||||||
|
s = startNimrodSession(script.dirname / project.string)
|
||||||
|
tline = TaintedString("")
|
||||||
|
lastOutput = ""
|
||||||
|
ln = 1
|
||||||
|
|
||||||
|
while f.readLine(tline):
|
||||||
|
var line = tline.string
|
||||||
|
inc ln
|
||||||
|
if line.strip.len == 0: continue
|
||||||
|
|
||||||
|
if line.startsWith(">"):
|
||||||
|
lastOutput = s.doCommand(line.substr(1).strip)
|
||||||
|
output.writeln line, "\n", lastOutput
|
||||||
|
else:
|
||||||
|
var expectMatch = true
|
||||||
|
var pattern = line
|
||||||
|
if line.startsWith("!"):
|
||||||
|
pattern = line.substr(1).strip
|
||||||
|
expectMatch = false
|
||||||
|
|
||||||
|
var actualMatch = lastOutput.find(re(pattern)) != -1
|
||||||
|
|
||||||
|
if expectMatch == actualMatch:
|
||||||
|
output.writeln "SUCCESS ", line
|
||||||
|
else:
|
||||||
|
output.writeln "FAILURE ", line
|
||||||
|
result = false
|
||||||
|
|
||||||
|
iterator caasTestsRunner*(filter = ""): tuple[test, output: string,
|
||||||
|
status: bool] =
|
||||||
|
for scenario in os.walkFiles(TesterDir / "caas/*.txt"):
|
||||||
|
if filter.len > 0 and find(scenario, filter) == -1: continue
|
||||||
|
var outStream = newStringStream()
|
||||||
|
let r = doScenario(scenario, outStream)
|
||||||
|
yield (scenario, outStream.data, r)
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
var filter = ""
|
||||||
|
if paramCount() > 0: filter = paramStr(1)
|
||||||
|
|
||||||
|
for t, o, r in caasTestsRunner(filter):
|
||||||
|
echo t, "\n", o
|
||||||
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
parseutils, strutils, pegs, os, osproc, streams, parsecfg, browsers, json,
|
parseutils, strutils, pegs, os, osproc, streams, parsecfg, browsers, json,
|
||||||
marshal, cgi, parseopt
|
marshal, cgi, parseopt, caasdriver
|
||||||
|
|
||||||
const
|
const
|
||||||
cmdTemplate = r"nimrod cc --hints:on $# $#"
|
cmdTemplate = r"nimrod cc --hints:on $# $#"
|
||||||
|
|
@ -38,6 +38,7 @@ type
|
||||||
reExeNotFound,
|
reExeNotFound,
|
||||||
reIgnored, # test is ignored
|
reIgnored, # test is ignored
|
||||||
reSuccess # test was successful
|
reSuccess # test was successful
|
||||||
|
|
||||||
TTarget = enum
|
TTarget = enum
|
||||||
targetC, targetCpp, targetObjC, targetJS
|
targetC, targetCpp, targetObjC, targetJS
|
||||||
|
|
||||||
|
|
@ -363,6 +364,10 @@ proc outputJSON(reject, compile, run: TResults) =
|
||||||
var s = pretty(doc)
|
var s = pretty(doc)
|
||||||
writeFile(jsonFile, s)
|
writeFile(jsonFile, s)
|
||||||
|
|
||||||
|
proc runCaasTests(r: var TResults) =
|
||||||
|
for test, output, status in caasTestsRunner():
|
||||||
|
r.addResult(test, "", output, if status: reSuccess else: reOutputsDiffer)
|
||||||
|
|
||||||
proc main() =
|
proc main() =
|
||||||
os.putenv "NIMTEST_NO_COLOR", "1"
|
os.putenv "NIMTEST_NO_COLOR", "1"
|
||||||
os.putenv "NIMTEST_OUTPUT_LVL", "PRINT_FAILURES"
|
os.putenv "NIMTEST_OUTPUT_LVL", "PRINT_FAILURES"
|
||||||
|
|
@ -404,6 +409,7 @@ proc main() =
|
||||||
writeResults(runJson, r)
|
writeResults(runJson, r)
|
||||||
of "special":
|
of "special":
|
||||||
runSpecialTests(r, p.cmdLineRest.string)
|
runSpecialTests(r, p.cmdLineRest.string)
|
||||||
|
runCaasTests(r)
|
||||||
writeResults(runJson, r)
|
writeResults(runJson, r)
|
||||||
of "rodfiles":
|
of "rodfiles":
|
||||||
runRodFiles(r, p.cmdLineRest.string)
|
runRodFiles(r, p.cmdLineRest.string)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ Library Additions
|
||||||
- Added ``system.unsafeNew`` to support hacky variable length objects.
|
- Added ``system.unsafeNew`` to support hacky variable length objects.
|
||||||
- ``system.fields`` and ``system.fieldPairs`` support ``object`` too; they
|
- ``system.fields`` and ``system.fieldPairs`` support ``object`` too; they
|
||||||
used to only support tuples.
|
used to only support tuples.
|
||||||
|
- Added ``system.CurrentSourcePath`` returning the full file-system path of
|
||||||
|
the current source file
|
||||||
|
|
||||||
|
|
||||||
Changes affecting backwards compatibility
|
Changes affecting backwards compatibility
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue