Add initial documentation to test suite
This commit is contained in:
parent
b2efb1c9b5
commit
41abf59395
|
@ -25,33 +25,47 @@ import util/symbols
|
|||
|
||||
type
|
||||
TestStatus* = enum
|
||||
## Test status enumeration
|
||||
Init, Running, Success,
|
||||
Failed, Crashed,
|
||||
TimedOut, Skipped
|
||||
|
||||
TestKind* = enum
|
||||
## Test type enumeration
|
||||
Tokenizer, Parser, TypeChecker,
|
||||
Runtime
|
||||
|
||||
TestRunner = proc (suite: TestSuite, test: Test)
|
||||
|
||||
# Represents a test outcome. The exc field contains
|
||||
# the exception raised during the test, if any. The
|
||||
# error field indicates whether the test errored out
|
||||
# or not. If exc is non-null and error is false, this
|
||||
# means the error was expected behavior
|
||||
TestOutcome = tuple[error: bool, exc: ref Exception]
|
||||
|
||||
Test* {.inheritable.} = ref object
|
||||
skip*: bool
|
||||
name*: string
|
||||
kind*: TestKind
|
||||
source*: string
|
||||
status*: TestStatus
|
||||
expected*: TestStatus
|
||||
outcome*: TestOutcome
|
||||
runnerFunc: TestRunner
|
||||
## A generic test object
|
||||
|
||||
skip*: bool # Skip running this test if true
|
||||
name*: string # Test name. Only useful for displaying purposes
|
||||
kind*: TestKind # Test kind (tokenizer, parser, compiler, etc.)
|
||||
source*: string # The source input of the test. Usually peon code
|
||||
status*: TestStatus # The test's current state
|
||||
expected*: TestStatus # The test's expected final state after run()
|
||||
outcome*: TestOutcome # The test's outcome
|
||||
runnerFunc: TestRunner # The test's internal runner function
|
||||
|
||||
|
||||
TokenizerTest* = ref object of Test
|
||||
## A tokenization test. Allows to specify
|
||||
## a desired error message and error location
|
||||
## upon tokenization failure
|
||||
message: string
|
||||
location: tuple[start, stop: int]
|
||||
|
||||
TestSuite* = ref object
|
||||
## A suite of tests
|
||||
tests*: seq[Test]
|
||||
|
||||
|
||||
|
@ -80,21 +94,15 @@ proc `$`*(self: Test): string =
|
|||
return ""
|
||||
|
||||
|
||||
proc getTestDetails(self: Test): string =
|
||||
doAssert self.status != Init
|
||||
case self.kind:
|
||||
of Tokenizer:
|
||||
var self = TokenizerTest(self)
|
||||
result = &"expecting "
|
||||
else:
|
||||
# TODO
|
||||
discard
|
||||
proc createLexer: Lexer =
|
||||
result = newLexer()
|
||||
result.fillSymbolTable()
|
||||
|
||||
|
||||
proc tokenizeSucceedsRunner(suite: TestSuite, test: Test) =
|
||||
## Runs a tokenitazion test that is expected to succeed
|
||||
try:
|
||||
var tokenizer = newLexer()
|
||||
tokenizer.fillSymbolTable()
|
||||
var tokenizer = createLexer()
|
||||
discard tokenizer.lex(test.source, "<string>")
|
||||
except LexingError:
|
||||
test.status = Failed
|
||||
|
@ -110,10 +118,11 @@ proc tokenizeSucceedsRunner(suite: TestSuite, test: Test) =
|
|||
|
||||
|
||||
proc tokenizeFailsRunner(suite: TestSuite, test: Test) =
|
||||
## Runs a tokenitazion test that is expected to fail
|
||||
## and checks that it fails in the way we expect
|
||||
var test = TokenizerTest(test)
|
||||
try:
|
||||
var tokenizer = newLexer()
|
||||
tokenizer.fillSymbolTable()
|
||||
var tokenizer = createLexer()
|
||||
discard tokenizer.lex(test.source, "<string>")
|
||||
except LexingError:
|
||||
var exc = LexingError(getCurrentException())
|
||||
|
@ -132,54 +141,64 @@ proc tokenizeFailsRunner(suite: TestSuite, test: Test) =
|
|||
test.status = Failed
|
||||
|
||||
|
||||
proc newTestSuite*: TestSuite = new(result)
|
||||
proc newTestSuite*: TestSuite =
|
||||
## Creates a new test suite
|
||||
new(result)
|
||||
|
||||
|
||||
proc addTest*(self: TestSuite, test: Test) =
|
||||
## Adds a test to the test suite
|
||||
self.tests.add(test)
|
||||
|
||||
|
||||
proc addTests*(self: TestSuite, tests: openarray[Test]) =
|
||||
## Adds the given tests to the test suite
|
||||
for test in tests:
|
||||
self.addTest(test)
|
||||
|
||||
|
||||
proc removeTest*(self: TestSuite, test: Test) =
|
||||
## Removes the given test from the test suite
|
||||
self.tests.delete(self.tests.find(test))
|
||||
|
||||
|
||||
proc removeTests*(self: TestSuite, tests: openarray[Test]) =
|
||||
## Removes the given tests from the test suite
|
||||
for test in tests:
|
||||
self.removeTest(test)
|
||||
|
||||
|
||||
proc newTokenizeTest(name, source: string): TokenizerTest =
|
||||
proc newTokenizeTest(name, source: string, skip = false): TokenizerTest =
|
||||
new(result)
|
||||
result.name = name
|
||||
result.kind = Tokenizer
|
||||
result.status = Init
|
||||
result.source = source
|
||||
result.skip = skip
|
||||
|
||||
|
||||
proc testTokenizeSucceeds*(name, source: string, skip = false): Test =
|
||||
var test = newTokenizeTest(name, source)
|
||||
## Creates a new tokenizer test that is expected to succeed
|
||||
var test = newTokenizeTest(name, source, skip)
|
||||
test.runnerFunc = tokenizeSucceedsRunner
|
||||
test.message = ""
|
||||
test.location = (-1 , -1)
|
||||
result = Test(test)
|
||||
result.skip = skip
|
||||
|
||||
|
||||
proc testTokenizeFails*(name, source: string, message: string, location: tuple[start, stop: int], skip = false): Test =
|
||||
var test = newTokenizeTest(name, source)
|
||||
## Creates a new tokenizer test that is expected to fail with the
|
||||
## given error message and at the given location
|
||||
var test = newTokenizeTest(name, source, skip)
|
||||
test.runnerFunc = tokenizeFailsRunner
|
||||
test.message = message
|
||||
test.location = location
|
||||
result = Test(test)
|
||||
result.skip = skip
|
||||
|
||||
|
||||
proc run*(self: TestSuite) =
|
||||
## Runs the test suite to completion,
|
||||
## sequentially
|
||||
for test in self.tests:
|
||||
if test.skip:
|
||||
test.status = Skipped
|
||||
|
@ -188,6 +207,10 @@ proc run*(self: TestSuite) =
|
|||
|
||||
|
||||
proc successful*(self: TestSuite): bool =
|
||||
## Returns whether the test suite completed
|
||||
## successfully or not. If called before run(),
|
||||
## this function returns false. Skipped tests
|
||||
## do not affect the outcome of this function
|
||||
result = true
|
||||
for test in self.tests:
|
||||
if test.status in [Skipped, Success]:
|
||||
|
|
Loading…
Reference in New Issue