diff --git a/tests/jats.nim b/tests/jats.nim index 1151d3b..a36b1de 100644 --- a/tests/jats.nim +++ b/tests/jats.nim @@ -16,10 +16,9 @@ import nim/nimtests -import ../src/vm import testutils -import os, osproc, strformat, streams +import os, osproc, strformat, streams, parseopt, strutils # Tests that represent not-yet implemented behaviour const exceptions = ["all.jpl", "for_with_function.jpl", "runtime_interning.jpl", "problem4.jpl"] @@ -99,10 +98,10 @@ proc runTests(tests: seq[Test], runner: string) = buffer.render() proc evalTest(test: Test) = - test.output = test.output.strip() - test.error = test.error.strip() - test.expectedOutput = test.expectedOutput.strip() - test.expectedError = test.expectedError.strip() + 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: @@ -113,7 +112,7 @@ proc evalTests(tests: seq[Test]) = if test.result == TestResult.ToEval: evalTest(test) -proc printResults(tests: seq[Test]) = +proc printResults(tests: seq[Test]): bool = var skipped = 0 success = 0 @@ -138,16 +137,101 @@ proc printResults(tests: seq[Test]) = let finalLevel = if fail == 0 and crash == 0: LogLevel.Info else: LogLevel.Error log(finalLevel, &"{tests.len()} tests: {success} succeeded, {skipped} skipped, {fail} failed, {crash} crashed.") + fail == 0 and crash == 0 + when isMainModule: const jatsVersion = "(dev)" - if paramCount() > 0: - if paramStr(1) == "-h": - echo "Usage: jats [-h | -v | -i | -o filename.txt]" - quit(0) - elif paramStr(1) == "-v": - echo "JATS v" & $jatsVersion - quit(0) + var optparser = initOptParser(commandLineParams()) + type Action {.pure.} = enum + Run, Help, Version + var action: Action = Action.Run + type DebugAction {.pure.} = enum + Interactive, Stdout + var debugActions: seq[DebugAction] + var targetFiles: seq[string] + var verbose = true + + type QuitValue {.pure.} = enum + Success, Failure, ArgParseErr, InternalErr + var quitVal = QuitValue.Success + + proc evalKey(key: string) = + let key = key.toLower() + if key == "h" or key == "help": + action = Action.Help + elif key == "v" or key == "version": + action = Action.Version + elif key == "i" or key == "interactive": + debugActions.add(DebugAction.Interactive) + elif key == "s" or key == "silent": + verbose = false + elif key == "stdout": + debugActions.add(DebugAction.Stdout) + else: + echo &"Unknown flag: {key}" + action = Action.Help + quitVal = QuitValue.ArgParseErr + + proc evalKeyVal(key: string, val: string) = + let key = key.toLower() + if key == "o" or key == "output": + targetFiles.add(val) + else: + echo &"Unknown option: {key}" + action = Action.Help + quitVal = QuitValue.ArgParseErr + + proc evalArg(key: string) = + echo &"Unexpected argument" + action = Action.Help + quitVal = QuitValue.ArgParseErr + + while true: + optparser.next() + case optparser.kind: + of cmdEnd: break + of cmdShortOption, cmdLongOption: + if optparser.val == "": + evalKey(optparser.key) + else: + evalKeyVal(optparser.key, optparser.val) + of cmdArgument: + evalArg(optparser.key) + + proc printUsage = + echo """ +JATS - Just Another Test Suite + +Usage: +jats +Runs the tests +Flags: +-i (or --interactive) displays all debug info +-o: (or --output:) saves debug info to a file +-s (or --silent) will disable all output (except --stdout) +--stdout will put all debug info to stdout +-h (or --help) displays this help message +-v (or --version) displays the version number of JATS +""" + proc printVersion = + echo &"JATS - Just Another Test Suite version {jatsVersion}" + + if action == Action.Help: + printUsage() + quit int(quitVal) + elif action == Action.Version: + printVersion() + quit int(quitVal) + elif action == Action.Run: + discard + else: + echo &"Unknown action {action}, please contact the devs to fix this." + quit int(QuitValue.InternalErr) + + setVerbosity(verbose) + + # start of JATS log(LogLevel.Debug, &"Welcome to JATS") @@ -169,17 +253,29 @@ when isMainModule: log(LogLevel.Debug, &"Evaluating tests...") tests.evalTests() log(LogLevel.Debug, &"Tests evaluated.") - tests.printResults() + if not tests.printResults(): + quitVal = QuitValue.Failure + log(LogLevel.Debug, &"Quitting JATS.") # special options to view the entire debug log + let logs = getTotalLog() + for action in debugActions: + case action: + of DebugAction.Interactive: + let lessExe = findExe("less", extensions = @[""]) + let moreExe = findExe("more", extensions = @[""]) + var viewer = if lessExe == "": moreExe else: lessExe + if viewer != "": + writeFile("testresults.txt", logs) # yes, testresults.txt is reserved + discard execShellCmd(viewer & " testresults.txt") # this way because of pipe buffer sizes + removeFile("testresults.txt") + else: + write stderr, "Interactive mode not supported on your platform, try --stdout and piping, or install/alias 'more' or 'less' to a terminal pager.\n" + of DebugAction.Stdout: + echo logs + for file in targetFiles: + writeFile(file, logs) - if paramCount() > 0: - if paramStr(1) == "-i": - when defined(posix): - discard execCmdEx(&"echo {getTotalLog()} | less") - else: - discard execCmdEx("echo {getTotalLog()} | more") - if paramStr(1) == "-o": - writeFile(paramStr(2), getTotalLog()) + quit int(quitVal) diff --git a/tests/testutils.nim b/tests/testutils.nim index 8499d69..8ec4599 100644 --- a/tests/testutils.nim +++ b/tests/testutils.nim @@ -15,7 +15,7 @@ # Common code from between the JAPL testing suites # (during transition from runtests -> Just Another Test Runner -import re, strutils, terminal, osproc, strformat, times, os +import re, strutils, terminal, osproc, strformat, times # types @@ -43,17 +43,21 @@ type LogLevel* {.pure.} = enum const echoedLogs = {LogLevel.Info, LogLevel.Error, LogLevel.Stdout} +const echoedLogsSilent = {LogLevel.Error} const savedLogs = {LogLevel.Debug, LogLevel.Info, LogLevel.Error} const logColors = [LogLevel.Debug: fgDefault, LogLevel.Info: fgGreen, LogLevel.Error: fgRed, LogLevel.Stdout: fgYellow] var totalLog = "" +var verbose = true +proc setVerbosity*(verb: bool) = + verbose = verb proc log*(level: LogLevel, msg: string) = let msg = &"[{$level} - {$getTime()}] {msg}" if level in savedLogs: totalLog &= msg & "\n" - if level in echoedLogs: + if (verbose and (level in echoedLogs)) or ((not verbose) and (level in echoedLogsSilent)): setForegroundColor(logColors[level]) echo msg setForegroundColor(fgDefault) @@ -83,7 +87,7 @@ proc updateProgressBar*(buf: Buffer, text: string, total: int, current: int) = buf.contents = newline proc render*(buf: Buffer) = - if buf.previous != buf.contents: + if verbose and buf.previous != buf.contents: echo buf.contents buf.previous = buf.contents @@ -101,6 +105,6 @@ proc compileExpectedError*(source: string): string = # stuff for cleaning test output -proc strip*(input: string): string = +proc tuStrip*(input: string): string = return input.replace(re"[\n\r]*$", "")