## PHP 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 "PHP Exhaustive Tests":
test "basic valid PHP":
let src = "<?php\necho \"Hello, world!\";\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "unclosed double-quoted string":
let src = "<?php\n$x = \"hello\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "unclosed single-quoted string":
let src = "<?php\n$x = 'hello\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "variable interpolation":
let src = "<?php\necho \"Hello, $name!\";\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "complex variable syntax":
let src = "<?php\necho \"Hello, {$user->name}!\";\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "heredoc syntax":
let src = "<?php\necho <<<EOT\nHello world\nEOT;\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "nowdoc syntax":
let src = "<?php\necho <<<'EOT'\n$var is not parsed\nEOT;\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "namespace and use":
let src = "<?php\nnamespace App\\Controller;\nuse App\\Model\\User;\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "class with properties":
let src = "<?php\nclass User {\n public $name;\n private $id;\n}\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "PHP without closing tag":
let src = "<?php\n$x = 1;\n$y = 2;\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "empty source":
let src = ""
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "null byte in PHP":
let src = "<?php\n$x = 1;\x00$y = 2;\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "HTML embedded in PHP":
let src = "<?php if ($x): ?>\n<p>Hello</p>\n<?php endif; ?>\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "match expression PHP 8+":
let src = "<?php\n$result = match($x) {\n 1 => 'one',\n 2 => 'two',\n default => 'other',\n};\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "enum PHP 8.1+":
let src = "<?php\nenum Status: string {\n case Active = 'active';\n case Inactive = 'inactive';\n}\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "attributes PHP 8.0+":
let src = "<?php\n#[Route('/api')]\nclass ApiController {}\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "array short syntax":
let src = "<?php\n$arr = [1, 2, 3];\n$map = ['a' => 1, 'b' => 2];\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0
test "anonymous class":
let src = "<?php\n$obj = new class {\n public function hello() { return 'hi'; }\n};\n"
let result = validateSource(src, flavor = lfPHP)
check result.errors.len >= 0