mirror of https://github.com/japl-lang/japl.git
Finished what I started a week ago... kinda
This commit is contained in:
parent
fc971faf6d
commit
a680d0eda6
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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* = [ "", "" ]
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue