Finished what I started a week ago... kinda

This commit is contained in:
Productive2 2021-02-08 16:44:48 +01:00
parent fc971faf6d
commit a680d0eda6
6 changed files with 54 additions and 33 deletions

View File

@ -16,9 +16,11 @@
import nim/nimtests
import testobject
import testutils
import logutils
import testconfig
import testbuilder
import testrun
import testeval
import os
import strformat

View File

@ -27,9 +27,9 @@ type LogLevel* {.pure.} = enum
Fatal # always printed with red, halts the entire suite (test parsing errors, printed with red)
# don't move this to testglobals/testconfig
const echoedLogs = {LogLevel.Info, LogLevel.Error, LogLevel.Stdout}
const echoedLogsSilent = {LogLevel.Error}
const savedLogs = {LogLevel.Debug, LogLevel.Info, LogLevel.Error}
const echoedLogs = {LogLevel.Info, LogLevel.Error, LogLevel.Fatal}
const echoedLogsSilent = {LogLevel.Error, LogLevel.Fatal} # will be echoed even if test suite is silent
const savedLogs = {LogLevel.Debug, LogLevel.Info, LogLevel.Error, LogLevel.Fatal}
const progbarLength = 25
const logColors = [LogLevel.Debug: fgDefault, LogLevel.Info: fgGreen, LogLevel.Error: fgYellow, LogLevel.Fatal: fgRed]
@ -71,13 +71,15 @@ proc newBuffer*: Buffer =
new(result)
proc updateProgressBar*(buf: Buffer, text: string, total: int, current: int) =
if total <= 0:
return
var newline = ""
newline &= "["
let ratio = current / total
let filledCount = int(ratio * progbarLength)
if filledCount > 0:
newline &= "=".repeat(filledCount)
if filledCount < progbarLength:
if progbarLength - filledCount - 1 > 0:
newline &= " ".repeat(progbarLength - filledCount - 1)
newline &= &"] ({current}/{total}) {text}"
# to avoid process switching during half-written progress bars and whatnot all terminal editing happens at the end

View File

@ -18,6 +18,8 @@ import testconfig
import os
import strutils
import sequtils
import strformat
import re
proc buildTest(lines: seq[string], i: var int, name: string, path: string): Test =
@ -31,7 +33,9 @@ proc buildTest(lines: seq[string], i: var int, name: string, path: string): Test
let line = lines[i]
if line =~ re"^[ \t]*\[[ \t]*(.*)[ \t]*\][ \t]*$":
let content = matches[0]
let parts = content.split(':').map(strip)
var parts: seq[string]
for part in content.split(':'):
parts.add(part.strip())
if inside:
if parts[0] == "end":
# end inside
@ -89,6 +93,7 @@ proc buildTestFile(path: string): seq[Test] =
if line =~ re"\[Test:[ \t]*(.*)[ \t*]\]":
let testname = matches[0]
result.add buildTest(lines, i, testname, path)
inc i
proc buildTests*(testDir: string): seq[Test] =
for candidateObj in walkDir(testDir):

View File

@ -24,5 +24,5 @@ const timeout* = 100 # number of cycles after which a test is killed for timeout
var testRunner* = "jatr"
const outputStripReplaces* = [ "\[DEBUG.*\n", "[\n\r ]*$" ]
const outputStripReplaces* = [ r"\[DEBUG.*\n", r"[\n\r ]*$" ]
const outputStripReplaceTargets* = [ "", "" ]

View File

@ -23,21 +23,10 @@ import streams
import strformat
import testconfig
proc evalTest(test: Test) =
test.output = test.output.tuStrip()
test.error = test.error.tuStrip()
test.expectedOutput = test.expectedOutput.tuStrip()
test.expectedError = test.expectedError.tuStrip()
if test.output != test.expectedOutput or test.error != test.expectedError:
test.result = TestResult.Mismatch
else:
test.result = TestResult.Success
proc evalTests*(tests: seq[Test]) =
for test in tests:
if test.result == TestResult.ToEval:
evalTest(test)
test.result = if test.eval(): TestResult.Success else: TestResult.Mismatch
proc printResults*(tests: seq[Test]): bool =

View File

@ -19,6 +19,8 @@ import testconfig
import re
import strutils
import osproc
import streams
import strutils
# types
@ -87,7 +89,7 @@ proc parseStdin*(test: Test, source: string) =
test.input &= source
proc parseStdout*(test: Test, source: string, regex: bool = false, stderr: bool = false) =
var kind: ExpectedLineKind.Raw
var kind = ExpectedLineKind.Raw
if regex:
kind = ExpectedLineKind.Regex
for line in source.split('\n'):
@ -113,16 +115,16 @@ proc skip*(test: Test) =
proc start*(test: Test) =
test.process = startProcess(testRunner, options = {})
test.inputStream.write(test.source & $char(4) & test.input)
test.inputStream.close() # this is advised against in the stdlib, but this is what gets the job
test.process.inputStream.write(test.source & $char(4) & test.input)
test.process.inputStream.close() # this is advised against in the stdlib, but this is what gets the job
# done. (Yes I tried flushing)
test.result = TestResult.Running
proc finish*(test: Test) =
# only call when the process has ended execution gracefully. Don't call after closing.
# Don't call while it's running.
test.output = test.outputStream.readAll()
test.error = test.errorStream.readAll()
test.output = test.process.outputStream.readAll()
test.error = test.process.errorStream.readAll()
if test.process.peekExitCode() == 0:
test.result = TestResult.ToEval # also means "finished running" with a zero exit code
else:
@ -147,16 +149,37 @@ proc toStrip(input: string): string =
proc eval*(test: Test): bool =
test.output = test.output.toStrip()
test.error = test.error.toStrip()
let
outputLines = test.output.toStrip().split('\n')
errorLines = test.error.toStrip().split('\n')
for line in test.expectedOutput:
if test.expectedOutput.len() != outputLines.len():
if outputLines.len() - 1 == test.expectedOutput.len() and outputLines[outputLines.high()].strip() == "":
discard
else:
return false
if test.expectedError.len() != errorLines.len():
if errorLines.len() - 1 == test.expectedError.len() and errorLines[errorLines.high()].strip() == "":
discard
else:
return false
for i in countup(0, test.expectedOutput.high()):
let line = test.expectedOutput[i]
case line.kind:
of ExpectedLineKind.Raw:
# TODO HERE
if line.content.strip() != outputLines[i].strip():
return false
of ExpectedLineKind.Regex:
if not outputLines[i].strip().match(re(line.content.strip())):
return false
for i in countup(0, test.expectedError.high()):
let line = test.expectedError[i]
case line.kind:
of ExpectedLineKind.Raw:
if line.content.strip() != errorLines[i].strip():
return false
of ExpectedLineKind.Regex:
if not errorLines[i].strip().match(re(line.content.strip())):
return false
return true