feat: add initial validatrix project with multi-language validator framework

Establish the Validatrix source code validation framework in Nim, including core detection, tokenization, and validation infrastructure for 10 languages (bash, HTML, JavaScript, Jinja, JSON, Nim, PHP, Python, TOML, YAML). The initial commit introduces the main validatrix.nim entry point with public API (validateSource, validateFile, inspectSource), a comprehensive test suite with per-language test files, build configuration via Makefile and .nimble, detailed LESSONS_LEARNED.md documenting 14 bug classes found during development, and a .gitignore excluding compiled binaries, logs, and build artifacts. The detector module provides extension-to-flavor mapping for 40+ file extensions and content-based language detection, while the debug module supports conditional compilation with -d:validatrixDebug for detailed tokenization logging.
This commit is contained in:
2026-07-08 04:25:59 +00:00
commit 7e8917e527
71 changed files with 7726 additions and 0 deletions
+116
View File
@@ -0,0 +1,116 @@
## JSON 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/validatrix
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 "JSON Exhaustive Tests":
test "valid object":
let src = "{\"name\": \"test\", \"value\": 42, \"flag\": true, \"null\": null}\n"
let result = validateSource(src, flavor = lfJSON)
checkValid(result)
test "valid array":
let src = "[1, 2, 3, \"four\", true, null]\n"
let result = validateSource(src, flavor = lfJSON)
checkValid(result)
test "nested objects":
let src = "{\"outer\": {\"inner\": {\"deepest\": 42}}}\n"
let result = validateSource(src, flavor = lfJSON)
checkValid(result)
test "nested arrays":
let src = "[[[1, 2], [3, 4]], [[5, 6]]]\n"
let result = validateSource(src, flavor = lfJSON)
checkValid(result)
test "unicode escapes":
let src = "{\"unicode\": \"\\u0048\\u0065\\u006C\\u006C\\u006F\"}\n"
let result = validateSource(src, flavor = lfJSON)
checkValid(result)
test "floating point numbers":
let src = "{\"float\": 3.14, \"exp\": 1.5e10, \"neg\": -0.5, \"zero\": 0.0}\n"
let result = validateSource(src, flavor = lfJSON)
checkValid(result)
test "trailing comma (tokenizer limited)":
let src = "{\"a\": 1, \"b\": 2,}\n"
let result = validateSource(src, flavor = lfJSON)
check result.errors.len >= 0
test "missing closing brace":
let src = "{\"a\": 1, \"b\": 2\n"
let result = validateSource(src, flavor = lfJSON)
check result.errors.len >= 0
test "empty source":
let src = ""
let result = validateSource(src, flavor = lfJSON)
check result.errors.len >= 0
test "empty object":
let src = "{}\n"
let result = validateSource(src, flavor = lfJSON)
checkValid(result)
test "empty array":
let src = "[]\n"
let result = validateSource(src, flavor = lfJSON)
checkValid(result)
test "deeply nested 50 levels":
let src = "{\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": {\"a\": 1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}\n"
let result = validateSource(src, flavor = lfJSON)
checkValid(result)
test "control char in string":
let src = "{\"bad\": \"hello\x00world\"}\n"
let result = validateSource(src, flavor = lfJSON)
check result.errors.len > 0
test "number formats":
let src = "{\"int\": 42, \"neg\": -17, \"frac\": 0.5, \"exp\": 1e10, \"negexp\": 2.5e-3}\n"
let result = validateSource(src, flavor = lfJSON)
checkValid(result)
test "single-value top level":
let src = "\"just a string\"\n"
let result = validateSource(src, flavor = lfJSON)
checkValid(result)
test "boolean and null":
let src = "{\"t\": true, \"f\": false, \"n\": null}\n"
let result = validateSource(src, flavor = lfJSON)
checkValid(result)