testament: error instead of silently overwrite a spec (#16166)

This commit is contained in:
Timothee Cour 2020-11-29 10:42:50 -08:00 • committed by GitHub
commit 6114df3c24
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 27 deletions

View file

@ -8,7 +8,7 @@
# #
import sequtils, parseutils, strutils, os, streams, parsecfg, import sequtils, parseutils, strutils, os, streams, parsecfg,
tables, hashes tables, hashes, sets
type TestamentData* = ref object type TestamentData* = ref object
# better to group globals under 1 object; could group the other ones here too # better to group globals under 1 object; could group the other ones here too
@ -82,7 +82,7 @@ type
tline*, tcolumn*: int tline*, tcolumn*: int
exitCode*: int exitCode*: int
msg*: string msg*: string
ccodeCheck*: string ccodeCheck*: seq[string]
maxCodeSize*: int maxCodeSize*: int
err*: TResultEnum err*: TResultEnum
inCurrentBatch*: bool inCurrentBatch*: bool
@ -244,11 +244,19 @@ proc parseSpec*(filename: string): TSpec =
var ss = newStringStream(specStr) var ss = newStringStream(specStr)
var p: CfgParser var p: CfgParser
open(p, ss, filename, 1) open(p, ss, filename, 1)
var flags: HashSet[string]
while true: while true:
var e = next(p) var e = next(p)
case e.kind case e.kind
of cfgKeyValuePair: of cfgKeyValuePair:
case normalize(e.key) let key = e.key.normalize
const whiteListMulti = ["disabled", "ccodecheck"]
## list of flags that are correctly handled when passed multiple times
## (instead of being overwritten)
if key notin whiteListMulti:
doAssert key notin flags, $(key, filename)
flags.incl key
case key
of "action": of "action":
case e.value.normalize case e.value.normalize
of "compile": of "compile":
@ -298,7 +306,7 @@ proc parseSpec*(filename: string): TSpec =
result.msg = e.value result.msg = e.value
if result.action != actionRun: if result.action != actionRun:
result.action = actionCompile result.action = actionCompile
of "errormsg", "errmsg": of "errormsg", "errmsg": # xxx just use errormsg, no need for such aliases
result.msg = e.value result.msg = e.value
result.action = actionReject result.action = actionReject
of "nimout": of "nimout":
@ -361,7 +369,7 @@ proc parseSpec*(filename: string): TSpec =
else: else:
result.cmd = e.value result.cmd = e.value
of "ccodecheck": of "ccodecheck":
result.ccodeCheck = e.value result.ccodeCheck.add e.value
of "maxcodesize": of "maxcodesize":
discard parseInt(e.value, result.maxCodeSize) discard parseInt(e.value, result.maxCodeSize)
of "timeout": of "timeout":

View file

@ -402,9 +402,8 @@ proc codegenCheck(test: TTest, target: TTarget, spec: TSpec, expectedMsg: var st
try: try:
let genFile = generatedFile(test, target) let genFile = generatedFile(test, target)
let contents = readFile(genFile).string let contents = readFile(genFile).string
let check = spec.ccodeCheck for check in spec.ccodeCheck:
if check.len > 0: if check.len > 0 and check[0] == '\\':
if check[0] == '\\':
# little hack to get 'match' support: # little hack to get 'match' support:
if not contents.match(check.peg): if not contents.match(check.peg):
given.err = reCodegenFailure given.err = reCodegenFailure

View file

@ -1,17 +1,23 @@
discard """ discard """
errormsg: "type mismatch: got <string> but expected 'int'" cmd: "nim check $options $file"
line: 33 action: "reject"
file: "tcaseexpr1.nim" nimout: '''
tcaseexpr1.nim(33, 10) Error: not all cases are covered; missing: {C}
errormsg: "not all cases are covered; missing: {C}" '''
line: 27
file: "tcaseexpr1.nim"
""" """
# NOTE: This spec is wrong. Spec doesn't support multiple error #[
# messages. The first one is simply overridden by the second one. # xxx make nimout comparison use nimoutCheck instead of:
# This just has never been noticed. elif expected.nimout.len > 0 and expected.nimout.normalizeMsg notin given.nimout.normalizeMsg:
and then use nimout: '''
tcaseexpr1.nim(33, 10) Error: not all cases are covered2; missing: {C}
tcaseexpr1.nim(39, 12) Error: type mismatch: got <string> but expected 'int literal(10)'
'''
]#
# line 20
type type
E = enum A, B, C E = enum A, B, C

View file

@ -2,12 +2,11 @@ discard """
exitcode: 1 exitcode: 1
targets: "c" targets: "c"
matrix: "-d:debug; -d:release" matrix: "-d:debug; -d:release"
outputsub: '''t13115.nim(13) t13115
Error: unhandled exception: This char is'''
outputsub: ''' and works fine! [Exception]''' outputsub: ''' and works fine! [Exception]'''
""" """
const b_null: char = 0.char # bug #13115
var msg = "This char is `" & $b_null & "` and works fine!" # xxx bug: doesn't yet work for cpp
var msg = "This char is `" & '\0' & "` and works fine!"
raise newException(Exception, msg) raise newException(Exception, msg)

View file

@ -1,10 +1,23 @@
discard """ discard """
cmd: "nim check $options $file" cmd: "nim check $options $file"
errormsg: "'proc' is not a concrete type" action: "reject"
errormsg: "'Foo' is not a concrete type." nimout: '''
errormsg: "invalid type: 'proc' in this context: 'TBaseMed'" tmetafield.nim(26, 5) Error: 'proc' is not a concrete type; for a callback without parameters use 'proc()'
tmetafield.nim(27, 5) Error: 'Foo' is not a concrete type
tmetafield.nim(29, 5) Error: invalid type: 'proc' in this context: 'TBaseMed' for var
'''
""" """
# bug #188
# line 20
type type
Foo[T] = object Foo[T] = object
x: T x: T
@ -15,4 +28,3 @@ type
var a: TBaseMed var a: TBaseMed
# issue 188