Fixed debug.nim not showing DEBUG - before a message

Made whitespace significant in the test suite
Fixed tests with DEBUG - on partially
This commit is contained in:
Productive2 2021-02-09 15:00:18 +01:00
parent c267a6c3be
commit ad74c45213
11 changed files with 59 additions and 60 deletions

View File

@ -67,7 +67,7 @@ proc disassembleInstruction*(chunk: Chunk, offset: int): int =
of jumpInstructions: of jumpInstructions:
result = jumpInstruction($opcode, chunk, offset) result = jumpInstruction($opcode, chunk, offset)
else: else:
echo &"Unknown opcode {opcode} at index {offset}" echo &"DEBUG - Unknown opcode {opcode} at index {offset}"
result = offset + 1 result = offset + 1
@ -77,4 +77,4 @@ proc disassembleChunk*(chunk: Chunk, name: string) =
var index = 0 var index = 0
while index < chunk.code.len: while index < chunk.code.len:
index = disassembleInstruction(chunk, index) index = disassembleInstruction(chunk, index)
echo &"==== Debug session ended - Chunk '{name}' ====" echo &"==== Debug session ended - Chunk '{name}' ===="

View File

@ -3,7 +3,7 @@
var a = b; var a = b;
//stderr:An unhandled exception occurred, traceback below: //stderr:An unhandled exception occurred, traceback below:
//stderr: File '''', line 1, in <module>: //stderr: File '''', line 1, in <module>:
//stderr:ReferenceError: undefined name 'b' //stderr:ReferenceError: undefined name 'b'
@ -16,7 +16,7 @@ var a = b;
[end] [end]
[stderr] [stderr]
An unhandled exception occurred, traceback below: An unhandled exception occurred, traceback below:
[] File '''', line 1, in <module>: File '''', line 1, in <module>:
ReferenceError: undefined name 'b' ReferenceError: undefined name 'b'
[end] [end]
[end] [end]

View File

@ -3,7 +3,7 @@
var a = 2 + "hey"; var a = 2 + "hey";
//stderr:An unhandled exception occurred, traceback below: //stderr:An unhandled exception occurred, traceback below:
//stderr: File '''', line 1, in <module>: //stderr: File '''', line 1, in <module>:
//stderr:TypeError: unsupported binary operator '+' for objects of type 'integer' and 'string' //stderr:TypeError: unsupported binary operator '+' for objects of type 'integer' and 'string'
[end] [end]

View File

@ -1,4 +1,5 @@
[Test: problem4] [Test: problem4]
[skip]
[source: mixed] [source: mixed]
// Find the largest palindrome that is a product of two 3 digit numbers // Find the largest palindrome that is a product of two 3 digit numbers

View File

@ -1,4 +1,5 @@
[Test: inputtest] [Test: inputtest]
[skip]
[source: mixed] [source: mixed]
//stdin:Hello world! //stdin:Hello world!
print(readLine()); print(readLine());
@ -7,7 +8,7 @@ print(readLine());
[end] [end]
[Test: inputtesttwo] [Test: inputtesttwo]
[skip]
[source: raw] [source: raw]
print(readLine()); print(readLine());
[end] [end]

View File

@ -1,4 +1,5 @@
[Test: is] [Test: is]
[skip]
[source:mixed] [source:mixed]
var x = 4; var x = 4;
var y = x; var y = x;

View File

@ -17,8 +17,6 @@
# a testrunner process # a testrunner process
import ../src/vm import ../src/vm
import os
import strformat
var btvm = initVM() var btvm = initVM()

View File

@ -26,7 +26,7 @@ proc parseModalLine(line: string): tuple[modal: bool, mode: string, detail: stri
# when non modal, mode becomes the line # when non modal, mode becomes the line
# when comment is true, it must not do anything to whenever it is exported # when comment is true, it must not do anything to whenever it is exported
let line = line.strip() let line = line
result.modal = false result.modal = false
result.mode = "" result.mode = ""
result.detail = "" result.detail = ""
@ -41,9 +41,6 @@ proc parseModalLine(line: string): tuple[modal: bool, mode: string, detail: stri
result.comment = true result.comment = true
result.modal = true result.modal = true
return result return result
elif line[1] == ']':
result.mode = line[2..line.high()]
return result
result.modal = true result.modal = true
else: else:
result.mode = line result.mode = line
@ -84,8 +81,9 @@ proc buildTest(lines: seq[string], i: var int, name: string, path: string): Test
var detail: string var detail: string
var inside: bool = false var inside: bool = false
var body: string var body: string
var modeline: int = -1
while i < lines.len(): while i < lines.len():
let parsed = parseModalLine(lines[i].strip()) let parsed = parseModalLine(lines[i])
let line = parsed.mode let line = parsed.mode
if parsed.modal and not parsed.comment: if parsed.modal and not parsed.comment:
if inside: if inside:
@ -95,31 +93,34 @@ proc buildTest(lines: seq[string], i: var int, name: string, path: string): Test
result.parseMixed(body) result.parseMixed(body)
elif mode == "source" and detail == "raw": elif mode == "source" and detail == "raw":
result.parseSource(body) result.parseSource(body)
elif mode == "stdout" and (detail == ""): elif mode == "stdout" or mode == "stderr":
result.parseStdout(body) let err = (mode == "stderr")
elif mode == "stdoutre" or (mode == "stdout" and detail == "re"): if detail == "":
result.parseStdout(body, true) result.parseStdout(body, err = err)
elif mode == "stderr" and (detail == ""): elif detail == "re":
result.parseStderr(body) result.parseStdout(body, re = true, err = err)
elif mode == "stderrre" or (mode == "stderr" and detail == "re"): elif detail == "nw":
result.parseStderr(body, true) result.parseStdout(body, nw = true, err = err)
elif detail == "nwre":
result.parseStdout(body, nw = true, re = true, err = err)
else:
fatal &"Invalid mode detail {detail} for mode {mode} in test {name} at line {modeline} in {path}. Valid are re, nw and nwre."
elif detail != "": elif detail != "":
fatal &"Invalid mode detail {detail} for mode {mode} in test {name} at {path}." fatal &"Invalid mode detail {detail} for mode {mode} in test {name} at line {modeline} in {path}."
# non-modedetail modes below: # non-modedetail modes below:
elif mode == "stdin": elif mode == "stdin":
result.parseStdin(body) result.parseStdin(body)
elif mode == "python": elif mode == "python":
result.parsePython(body) result.parsePython(body)
elif mode == "comment":
discard # just a comment
else: else:
fatal &"Invalid mode {mode} for test {name} at {path}." fatal &"Invalid mode {mode} for test {name} at line {modeline} in {path}."
inside = false inside = false
mode = "" mode = ""
detail = "" detail = ""
body = "" body = ""
modeline = -1
else: else:
fatal &"Invalid mode {parsed.mode} when inside a block (currently in mode {mode})." fatal &"Invalid mode {parsed.mode} when inside a block (currently in mode {mode}) at line {i} in {path}."
else: # still if modal, but not inside else: # still if modal, but not inside
if parsed.mode == "skip": if parsed.mode == "skip":
result.skip() result.skip()
@ -131,15 +132,11 @@ proc buildTest(lines: seq[string], i: var int, name: string, path: string): Test
inside = true inside = true
mode = parsed.mode mode = parsed.mode
detail = parsed.detail detail = parsed.detail
modeline = i
elif parsed.comment: elif parsed.comment:
discard discard
elif inside: # when not modal elif inside: # when not modal
body &= line & "\n" body &= line & "\n"
elif line.strip().len() == 0:
discard # whitespace
else:
# invalid
fatal &"Invalid code inside a test: {line} in test {name} at {path}"
inc i inc i
proc buildTestFile(path: string): seq[Test] = proc buildTestFile(path: string): seq[Test] =
@ -147,7 +144,7 @@ proc buildTestFile(path: string): seq[Test] =
let lines = path.readFile().split('\n') let lines = path.readFile().split('\n')
var i = 0 var i = 0
while i < lines.len(): while i < lines.len():
let parsed = lines[i].strip().parseModalLine() let parsed = lines[i].parseModalLine()
let line = parsed.mode let line = parsed.mode
if parsed.modal and not parsed.comment: if parsed.modal and not parsed.comment:
if parsed.mode == "test": if parsed.mode == "test":

View File

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

View File

@ -54,7 +54,7 @@ proc printResults*(tests: seq[Test]): bool =
inc killed inc killed
else: else:
log(LogLevel.Error, &"Probably a testing suite bug: test {test.path} has result {test.result}. Refer to testeval.nim/printResults.") log(LogLevel.Error, &"Probably a testing suite bug: test {test.path} has result {test.result}. Refer to testeval.nim/printResults.")
let finalLevel = if fail == 0 and crash == 0: LogLevel.Info else: LogLevel.Error let finalLevel = if fail == 0 and crash == 0 and killed == 0: LogLevel.Info else: LogLevel.Error
log(finalLevel, &"{tests.len()} tests: {success} succeeded, {skipped} skipped, {fail} failed, {killed} killed, {crash} crashed.") log(finalLevel, &"{tests.len()} tests: {success} succeeded, {skipped} skipped, {fail} failed, {killed} killed, {crash} crashed.")
result = fail == 0 and crash == 0 result = fail == 0 and crash == 0

View File

@ -61,9 +61,9 @@ proc genEL(content: string, kind: ExpectedLineKind): ExpectedLine =
proc compileExpectedOutput(source: string, rawkw: string, rekw: string): seq[ExpectedLine] = proc compileExpectedOutput(source: string, rawkw: string, rekw: string): seq[ExpectedLine] =
for line in source.split('\n'): for line in source.split('\n'):
if line =~ re("^.*//" & rawkw & ":[ ]?(.*)$"): if line =~ re("^.*//" & rawkw & ":(.*)$"):
result &= genEL(matches[0], ExpectedLineKind.Raw) result &= genEL(matches[0], ExpectedLineKind.Raw)
elif line =~ re("^.*//" & rekw & ":[ ]?(.*)$"): elif line =~ re("^.*//" & rekw & ":(.*)$"):
result &= genEL(matches[0], ExpectedLineKind.Regex) result &= genEL(matches[0], ExpectedLineKind.Regex)
proc compileExpectedOutput(source: string): seq[ExpectedLine] = proc compileExpectedOutput(source: string): seq[ExpectedLine] =
@ -74,7 +74,7 @@ proc compileExpectedError(source: string): seq[ExpectedLine] =
proc compileInput(source: string): string = proc compileInput(source: string): string =
for line in source.split('\n'): for line in source.split('\n'):
if line =~ re"^.*//stdin:[ ]?(.*)$": if line =~ re"^.*//stdin:(.*)$":
result &= matches[0] & "\n" result &= matches[0] & "\n"
proc parseMixed*(test: Test, source: string) = proc parseMixed*(test: Test, source: string) =
@ -89,17 +89,20 @@ proc parseSource*(test: Test, source: string) =
proc parseStdin*(test: Test, source: string) = proc parseStdin*(test: Test, source: string) =
test.input &= source test.input &= source
proc parseStdout*(test: Test, source: string, regex: bool = false, stderr: bool = false) = proc parseStdout*(test: Test, source: string, re: bool = false, nw: bool = false, err: bool = false) =
var kind = ExpectedLineKind.Raw var kind = ExpectedLineKind.Raw
if regex: if re:
kind = ExpectedLineKind.Regex kind = ExpectedLineKind.Regex
for line in source.split('\n'): for line in source.split('\n'):
if stderr: var toAdd = line
test.expectedError.add(genEL(line, kind)) if nw:
toAdd = toAdd.strip()
if err:
test.expectedError.add(genEL(toAdd, kind))
else: else:
test.expectedOutput.add(genEL(line, kind)) test.expectedOutput.add(genEL(toAdd, kind))
if stderr: if err:
while test.expectedError.len() > 0 and test.expectedError[test.expectedError.high()].content == "": while test.expectedError.len() > 0 and test.expectedError[test.expectedError.high()].content == "":
discard test.expectedError.pop() discard test.expectedError.pop()
else: else:
@ -168,19 +171,15 @@ proc running*(test: Test): bool =
# Helpers for evaluating tests # Helpers for evaluating tests
proc stdStrip(input: string): seq[string] = proc stdStrip(input: string): seq[string] =
var lines = input.split('\n') var lines: seq[string]
var toRemove: seq[int] for line in input.split('\n'):
for i in countup(0, lines.high()): var included = true
template line: string = lines[i] for pattern in outputIgnore:
let hadContent = line.len() > 0 if line.match(re(pattern)):
for op in countup(0, outputStripReplaces.high()): included = false
line = line.replace(re(outputStripReplaces[op]), outputStripReplaceTargets[op]) if included:
if hadContent and line.len() == 0: lines.add(line)
toRemove.add(i)
for i in toRemove:
lines.delete(i)
while lines.len() > 0 and lines[lines.high()] == "": while lines.len() > 0 and lines[lines.high()] == "":
discard lines.pop() discard lines.pop()
lines lines
@ -189,6 +188,9 @@ proc eval*(test: Test): bool =
let let
outputLines = test.output.stdStrip() outputLines = test.output.stdStrip()
errorLines = test.error.stdStrip() errorLines = test.error.stdStrip()
# just for updated debug output
test.output = outputLines.join("\n")
test.error = errorLines.join("\n")
if test.expectedOutput.len() != outputLines.len(): if test.expectedOutput.len() != outputLines.len():
test.mismatchPos = outputLines.len() test.mismatchPos = outputLines.len()
@ -201,22 +203,22 @@ proc eval*(test: Test): bool =
let line = test.expectedOutput[i] let line = test.expectedOutput[i]
case line.kind: case line.kind:
of ExpectedLineKind.Raw: of ExpectedLineKind.Raw:
if line.content.strip() != outputLines[i].strip(): if line.content != outputLines[i]:
test.mismatchPos = i test.mismatchPos = i
return false return false
of ExpectedLineKind.Regex: of ExpectedLineKind.Regex:
if not outputLines[i].strip().match(re(line.content.strip())): if not outputLines[i].match(re(line.content)):
test.mismatchPos = i test.mismatchPos = i
return false return false
for i in countup(0, test.expectedError.high()): for i in countup(0, test.expectedError.high()):
let line = test.expectedError[i] let line = test.expectedError[i]
case line.kind: case line.kind:
of ExpectedLineKind.Raw: of ExpectedLineKind.Raw:
if line.content.strip() != errorLines[i].strip(): if line.content != errorLines[i]:
test.errorMismatchPos = i test.errorMismatchPos = i
return false return false
of ExpectedLineKind.Regex: of ExpectedLineKind.Regex:
if not errorLines[i].strip().match(re(line.content.strip())): if not errorLines[i].match(re(line.content)):
test.errorMismatchPos = i test.errorMismatchPos = i
return false return false