#!/usr/bin/php getMessage()), true); self::log('Stack trace:', true); self::log($e->getTraceAsString(), true); exit(1); } } public static function testAsserts(): void { // Test assertions $hello = 'Hello'; try { assert_strict_equals(5, 5); assert_equals(5, '5'); assert_not_strict_equals(true, 1); assert_not_equals(5, 6); assert_similar($hello, $hello); assert_true(true); assert_false(false); assert_null(null); assert_not_null(5); assert_not_null(''); assert_empty([]); assert_empty(null); assert_empty(''); assert_not_empty([1, 2, 3]); assert_instanceof(StdClass::class, new stdClass()); assert_string_length($hello, 5); assert_string_contains($hello, 'll'); assert_string_starts_with($hello, 'He'); assert_string_ends_with($hello, 'lo'); assert_positive_int(5); assert_negative_int(-5); assert_count(2, [1, 2]); assert_array_has_key('id', ['id' => 1]); assert_execution_time_less_than(1000, function () { usleep(1000); }); assert_memory_usage_less_than(1000000, function () { $a = 'a'; }); $tempFile = sys_get_temp_dir() . '/unitester_test_file'; file_put_contents($tempFile, 'content'); try { assert_file_exists($tempFile); assert_is_readable($tempFile); assert_is_writable($tempFile); } finally { @unlink($tempFile); } assert_file_not_exists($tempFile); assert_directory_exists(__DIR__); } catch (Throwable $e) { throw new RuntimeException($e->getMessage()); } // Test exceptions $throwMessage = 'Expected exception not thrown. : ' . AssertionFailureException::class; try { assert_strict_equals(true, 1); throw new RuntimeException(sprintf('Line %d: %s', __LINE__, $throwMessage)); } catch (AssertionFailureException $e) { } try { assert_equals(5, 6); throw new RuntimeException(sprintf('Line %d: %s', __LINE__, $throwMessage)); } catch (AssertionFailureException $e) { } try { assert_not_strict_equals(false, false); throw new RuntimeException(sprintf('Line %d: %s', __LINE__, $throwMessage)); } catch (AssertionFailureException $e) { } try { assert_not_equals(5, 5); throw new RuntimeException(sprintf('Line %d: %s', __LINE__, $throwMessage)); } catch (AssertionFailureException $e) { } try { assert_similar($hello, 'hello'); throw new RuntimeException(sprintf('Line %d: %s', __LINE__, $throwMessage)); } catch (AssertionFailureException $e) { } try { assert_true(false); throw new RuntimeException(sprintf('Line %d: %s', __LINE__, $throwMessage)); } catch (AssertionFailureException $e) { } try { assert_false(true); throw new RuntimeException(sprintf('Line %d: %s', __LINE__, $throwMessage)); } catch (AssertionFailureException $e) { } try { assert_null(''); throw new RuntimeException(sprintf('Line %d: %s', __LINE__, $throwMessage)); } catch (AssertionFailureException $e) { } try { assert_not_null(null); throw new RuntimeException(sprintf('Line %d: %s', __LINE__, $throwMessage)); } catch (AssertionFailureException $e) { } try { assert_empty(' '); throw new RuntimeException(sprintf('Line %d: %s', __LINE__, $throwMessage)); } catch (AssertionFailureException $e) { } try { assert_not_empty([]); throw new RuntimeException(sprintf('Line %d: %s', __LINE__, $throwMessage)); } catch (AssertionFailureException $e) { } try { assert_instanceof(self::class, new stdClass()); throw new RuntimeException(sprintf('Line %d: %s', __LINE__, $throwMessage)); } catch (AssertionFailureException $e) { } try { assert_string_length($hello, 6); throw new RuntimeException(sprintf('Line %d: %s', __LINE__, $throwMessage)); } catch (AssertionFailureException $e) { } } public static function testFinder(): void { try { $testFinder = new TestFinder(dirname(__DIR__) . '/tests'); $foundTests = $testFinder->find(); self::expected(count($foundTests) === 4, 'Expected 4 tests, got ' . count($foundTests)); foreach ($testFinder->find() as $test) { self::expected(in_array($test, self::$listOfTestClasses), 'Expected ' . implode(', ', self::$listOfTestClasses) . ', got ' . is_string($test) ? $test : gettype($test)); } } catch (Throwable $e) { throw new RuntimeException($e->getMessage()); } } public static function testTestCase(): void { /** * @var TestCase $test */ foreach (self::$listOfTestClasses as $testClass) { $test = new $testClass(); $test->run(); switch ($testClass) { case ComparisonTest::class: case AssertionTest::class: self::expected($test->getAssertions() === 2, 'Expected 2 assertions, got ' . $test->getAssertions()); break; case ExceptionHandlingTest::class: self::expected($test->getAssertions() === 1, 'Expected 1 assertions, got ' . $test->getAssertions()); break; case PerformanceFileTest::class: self::expected($test->getAssertions() === 7, 'Expected 7 assertions, got ' . $test->getAssertions()); break; default: throw new RuntimeException('Unexpected test class ' . $testClass); } } } private static function testTestExecutor(): void { $output = new Output(function (string $message) { }); $testExecutor = new TestExecutor(self::$listOfTestClasses, $output); $code = $testExecutor->run(); self::expected($code === 0, 'Expected code 0, got ' . $code); $wrongTestClass = new class extends TestCase { protected function setUp(): void { } protected function tearDown(): void { } protected function execute(): void { $this->assertNotNull(null); } }; $testExecutor = new TestExecutor([$wrongTestClass], $output); $code = $testExecutor->run(); self::expected($code === 1, 'Expected code 1, got ' . $code); } private static function testTestRunner(): void { $line = 0; $output = new Output(static function (string $message) use (&$line) { ++$line; if ($line === 1) { self::expected($message === 'Usage PHP UniTester : [options] [folder]', 'Expected "Usage PHP UniTester : [options] [folder]", got "' . $message . '"'); } }); $code = TestRunnerCli::run($output, ['', '--help']); self::expected($code === 0, 'Expected code 0, got ' . $code); $line = 0; $waitingLineMessage = sprintf('PHP UniTester version %s', TestRunnerCli::VERSION); $output = new Output(static function (string $message) use (&$line, $waitingLineMessage) { ++$line; if ($line === 1) { self::expected($message === $waitingLineMessage, sprintf('Expected "%s", got "%s"', $waitingLineMessage, $message)); } }); $code = TestRunnerCli::run($output, ['', '--version']); self::expected($code === 0, 'Expected code 0, got ' . $code); $output = new Output(function (string $message) { }); $code = TestRunnerCli::run($output, ['', '--not-exists-option']); self::expected($code === 1, 'Expected code 1, got ' . $code); $output = new Output(function (string $message) { }); $code = TestRunnerCli::run($output, ['', 'argument1', 'argument2']); self::expected($code === 1, 'Expected code 1, got ' . $code); $output = new Output(function (string $message) { }); $code = TestRunnerCli::run($output, ['', 'folder/not/exists']); self::expected($code === 1, 'Expected code 1, got ' . $code); $output = new Output(function (string $message) { }); $code = TestRunnerCli::run($output, ['', dirname(__DIR__) . '/tests']); self::expected($code === 0, 'Expected code 0, got ' . $code); } private static function expected($condition, string $errorMessage = null): void { if (!$condition) { throw new RuntimeException($errorMessage); } } private static function log(string $message, bool $isError = false): void { fwrite($isError ? STDERR : STDOUT, $message . PHP_EOL); } } SelfTest::run();