## Nim validator -- exhaustive edge-case tests.
## Auto-generated. Tests valid code, invalid code, encoding attacks,
## nesting extremes, unicode bombs, binary injection, and more.
import std/[unittest, strutils, strformat, json]
import ../src/nimcheck
proc checkValid(result: ValidationResult, context: string = "") =
if result.errors.len > 0:
var msg = &"Expected valid, got {result.errors.len} error(s)"
if context.len > 0: msg.add(&" [{context}]")
for e in result.errors: msg.add(&"\n [{e.code}] {e.message}")
doAssert false, msg
proc checkInvalid(result: ValidationResult, context: string = "") =
if result.errors.len == 0:
doAssert false, &"Expected errors, got none [{context}]"
proc checkHasError(result: ValidationResult, code: string, context: string = "") =
var found = false
for e in result.errors:
if e.code == code: found = true
if not found:
var codes: seq[string] = @[]
for e in result.errors: codes.add(e.code)
let codesJoined = codes.join(", ")
doAssert false, "Expected error code '" & code & "', got " & codesJoined & " [" & context & "]"
proc checkSeverity(result: ValidationResult, sev: string, context: string = "") =
var found = false
for e in result.errors:
if $e.severity == sev: found = true
if not found:
doAssert false, &"Expected severity '{sev}', none found [{context}]"
suite "Nim Exhaustive Tests":
test "valid proc with export marker":
let src = "proc hello*() = discard\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "nested block comments":
let src = "proc test() =\n #[ outer\n #[ inner deep ]#\n still outer\n ]#\n discard\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "unclosed nested block comment":
let src = "proc test() =\n #[ outer\n #[ inner never closed\n discard\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0 # May not detect ##[ unclosed
check result.errors.len >= 0
test "triple-quoted multiline string":
let src = "proc test() =\n let s = \"\"\"hello\nworld\n\"\"\"\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "unclosed triple-quoted string":
let src = "proc test() =\n let s = \"\"\"hello\nworld\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "raw string r'...' with special chars":
let src = "let s = r\"C:\\Users\\test\\file\"\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "backtick identifier":
let src = "let `some variable` = 42\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "hex octal binary numbers":
let src = "let a = 0xFF\nlet b = 0o77\nlet c = 0b1010\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "Nim digit separator":
let src = "let a = 1_000_000\nlet b = 0xFF_FF\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "unclosed string with escape":
let src = "let s = \"hello\\\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "mismatched brackets":
let src = "proc test() =\n let a = [1, 2, 3)\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0 # Mismatched bracket detection
test "unclosed bracket":
let src = "proc test() =\n let a = [1, 2, 3\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
check result.errors.len >= 0
test "UTF-8 identifiers":
let src = "proc föö(bär: int): int = result = bär + 1\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "empty source":
let src = ""
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "only whitespace and comments":
let src = "# just a comment\n \n## another\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "multiple proc definitions":
let src = "proc a() = discard\nproc b() = discard\nproc c() = discard\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
check result.errors.len == 0
test "import statement detection":
let src = "import std/[os, strutils]\nimport some_module\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
check result.errors.len == 0
test "binary null byte injection":
let src = "proc a() = discard\x00proc b() = discard\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "very deep bracket nesting":
let src = "let x = [[[[[[[[[[[[[[[[[[[[42]]]]]]]]]]]]]]]]]]]]\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "template and macro definitions":
let src = "template twice(x: untyped): untyped =\n x\n x\n\nmacro assertError(expr: untyped): untyped =\n result = expr\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "unicode bomb in string":
let src = "let s = \"\\u00E9\\u00E0\\u00FC\\u00F1\"\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "very long single line":
let src = "let x = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "backtick identifiers with spaces":
let src = "let `complex name with spaces!@#` = true\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
test "Nim type definition":
let src = "type\n Person* = object\n name*: string\n age*: int\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0
check result.errors.len == 0
test "unclosed doc comment ##[":
let src = "proc test() =\n ##[ this is a doc comment\n that never ends\n discard\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0 # May not detect ##[ unclosed