passed++; echo COLOR_GREEN . "✓ " . COLOR_RESET . $message . "\n"; } else { $this->failed++; $this->errors[] = $message; echo COLOR_RED . "✗ " . COLOR_RESET . $message . "\n"; } } public function assertEquals($expected, $actual, string $message): void { $this->assert($expected === $actual, $message . " (expected: " . var_export($expected, true) . ", got: " . var_export($actual, true) . ")"); } public function assertNotNull($value, string $message): void { $this->assert($value !== null, $message); } public function assertNull($value, string $message): void { $this->assert($value === null, $message); } public function assertContains(string $needle, string $haystack, string $message): void { $this->assert(str_contains($haystack, $needle), $message); } public function summary(): void { echo "\n" . str_repeat("=", 50) . "\n"; echo COLOR_GREEN . "Пройдено: {$this->passed}" . COLOR_RESET . "\n"; echo COLOR_RED . "Провалено: {$this->failed}" . COLOR_RESET . "\n"; if (!empty($this->errors)) { echo COLOR_YELLOW . "\nОшибки:\n" . COLOR_RESET; foreach ($this->errors as $error) { echo " - {$error}\n"; } } echo str_repeat("=", 50) . "\n"; exit($this->failed > 0 ? 1 : 0); } } require_once __DIR__ . '/../config/database.php'; $test = new TestRunner(); echo "\n" . COLOR_YELLOW . "=== ТЕСТЫ ПРОЕКТА AETERNA ===" . COLOR_RESET . "\n\n"; $testFiles = glob(__DIR__ . '/*Test.php'); foreach ($testFiles as $testFile) { echo COLOR_YELLOW . "\n--- " . basename($testFile) . " ---" . COLOR_RESET . "\n"; require_once $testFile; } $test->summary();