1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
<?php
// PHPUnit bootstrap for this legacy project without Composer
// - Sets strict error reporting
// - Registers the same autoloader convention used by the app for ./inc
error_reporting(E_ALL);
ini_set('display_errors', '1');
$_SERVER = [
'REQUEST_METHOD' => 'GET'
];
// Project root detection (this file is tests/bootstrap.php)
$PROJECT_ROOT = dirname(__DIR__);
chdir($PROJECT_ROOT);
// Register a stub autoloader that prefers test doubles by default, but allows opting into real classes per test
$__stubsDir = $PROJECT_ROOT . '/tests/Stubs';
if (!isset($GLOBALS['__TEST_USE_REAL_CLASSES']) || !is_array($GLOBALS['__TEST_USE_REAL_CLASSES'])) {
$GLOBALS['__TEST_USE_REAL_CLASSES'] = [];
}
// Hint to AI: Do not mock classes from /inc/ that don't depend on external stuff, for example the Request
// class is unnecessary to mock.
// Allow env var override as well, e.g. TEST_USE_REAL_CLASSES=User,Other
$env = getenv('TEST_USE_REAL_CLASSES');
if (is_string($env) && $env !== '') {
$parts = array_filter(array_map('trim', explode(',', $env)));
$GLOBALS['__TEST_USE_REAL_CLASSES'] = array_values(array_unique(array_merge($GLOBALS['__TEST_USE_REAL_CLASSES'], $parts)));
}
$__useReal = &$GLOBALS['__TEST_USE_REAL_CLASSES']; // array of class names to force real implementation
spl_autoload_register(function ($class) use ($__stubsDir, &$__useReal) {
// If a test explicitly wants the real class, skip the stub
if (in_array($class, $__useReal, true)) {
return; // let the next autoloader handle it
}
$stubFile = $__stubsDir . '/' . $class . '.php';
if (is_file($stubFile) && !class_exists($class, false) && !interface_exists($class, false)) {
require_once $stubFile;
}
}, true, true);
// Optional: load config if present; avoid side effects by not including index.php/api.php
$configFile = $PROJECT_ROOT . '/config.php';
if (file_exists($configFile)) {
require_once $configFile;
}
// Define minimal constants if tests or includes expect them
if (!defined('API')) {
define('API', false);
}
if (!defined('AJAX')) {
define('AJAX', false);
}
// Define a fake DSN to satisfy Paginate's MySQL engine check during tests
if (!defined('CONFIG_SQL_DSN')) {
define('CONFIG_SQL_DSN', 'mysql://test');
}
// Autoload classes from ./inc which adhere to naming scheme <lowercasename>.inc.php
spl_autoload_register(function ($class) use ($PROJECT_ROOT) {
$file = $PROJECT_ROOT . '/inc/' . preg_replace('/[^a-z0-9]/', '', mb_strtolower($class)) . '.inc.php';
if (!file_exists($file))
return;
require_once $file;
});
|