mirror of
https://github.com/e107inc/e107.git
synced 2025-08-08 15:46:44 +02:00
269 lines
7.3 KiB
PHP
269 lines
7.3 KiB
PHP
<?php
|
|
|
|
|
|
class scriptsTest extends \Codeception\Test\Unit
|
|
{
|
|
|
|
|
|
protected function _before()
|
|
{
|
|
if(!defined('SEP'))
|
|
{
|
|
define("SEP", " <span class='fa fa-angle-double-right e-breadcrumb'></span> ");
|
|
}
|
|
|
|
e107::loadAdminIcons();
|
|
}
|
|
|
|
public function testAdminScripts()
|
|
{
|
|
$exclude = array(
|
|
'index.php',
|
|
'menus.php', // FIXME menus defines e_ADMIN_AREA which messes up other tests.
|
|
'header.php',
|
|
'footer.php'
|
|
);
|
|
|
|
$this->loadScripts(e_ADMIN, $exclude);
|
|
|
|
}
|
|
|
|
public function testAdminIncludes()
|
|
{
|
|
ob_start();
|
|
require_once(e_ADMIN."admin.php");
|
|
ob_end_clean();
|
|
$this->loadScripts(e_ADMIN."includes/");
|
|
|
|
}
|
|
|
|
public function testAdminLayouts()
|
|
{
|
|
$this->loadScripts(e_ADMIN.'includes/layouts/');
|
|
}
|
|
|
|
|
|
public function testFrontend()
|
|
{
|
|
e107::getConfig()->setPref('plug_installed/gsitemap', '1.0');
|
|
|
|
$include = array (
|
|
0 => 'banner.php',
|
|
// 1 => 'class2.php',
|
|
// 2 => 'comment.php',
|
|
3 => 'contact.php',
|
|
|
|
// 5 => 'cron.php',
|
|
// 6 => 'download.php',
|
|
// 7 => 'e107_config.php',
|
|
|
|
// 12 => 'email.php',
|
|
13 => 'error.php',
|
|
|
|
15 => 'fpw.php',
|
|
16 => 'gsitemap.php',
|
|
// 17 => 'index.php', // redirects
|
|
// 18 => 'install.php', // not compatible with core.
|
|
|
|
20 => 'login.php',
|
|
21 => 'membersonly.php',
|
|
// 22 => 'metaweblog.php',
|
|
23 => 'news.php',
|
|
24 => 'online.php',
|
|
25 => 'page.php',
|
|
// 26 => 'print.php',
|
|
// 27 => 'rate.php', // has a redirect.
|
|
// 28 => 'request.php', // redirects
|
|
29 => 'search.php',
|
|
// 30 => 'signup.php', too many 'exit';
|
|
31 => 'sitedown.php',
|
|
32 => 'submitnews.php',
|
|
|
|
// 34 => 'thumb.php', // separate test.
|
|
35 => 'top.php',
|
|
36 => 'unsubscribe.php',
|
|
// 37 => 'upload.php', // FIXME LAN conflict.
|
|
38 => 'user.php',
|
|
// 39 => 'userposts.php', // FIXME needs a rework
|
|
40 => 'usersettings.php',
|
|
);
|
|
|
|
$this->loadScripts(e_BASE, array(), $include);
|
|
}
|
|
|
|
|
|
|
|
private function loadScripts($folder, $exclude = array(), $include = array())
|
|
{
|
|
$list = scandir($folder);
|
|
|
|
$config = e107::getConfig();
|
|
|
|
// Pre-register certain plugins if needed
|
|
$preInstall = array('banner', 'page');
|
|
foreach ($preInstall as $plug) {
|
|
$config->setPref('plug_installed/' . $plug, '1.0');
|
|
}
|
|
|
|
global $pref, $ns, $tp, $frm;
|
|
$pref = e107::getPref();
|
|
$ns = e107::getRender();
|
|
$tp = e107::getParser();
|
|
$frm = e107::getForm();
|
|
|
|
global $_E107;
|
|
$_E107['cli'] = true;
|
|
|
|
$e107Root = realpath(__DIR__ . '/../../../');
|
|
$class2Path = $e107Root . '/class2.php';
|
|
$lanAdminPath = $e107Root . '/e107_languages/English/admin/lan_admin.php';
|
|
|
|
if (!file_exists($class2Path)) {
|
|
$this->fail("Could not locate class2.php at $class2Path");
|
|
return;
|
|
}
|
|
if (!file_exists($lanAdminPath)) {
|
|
$this->fail("Could not locate lan_admin.php at $lanAdminPath");
|
|
return;
|
|
}
|
|
|
|
fwrite(STDOUT, "Loading scripts from: $folder\n");
|
|
|
|
$filesToTest = [];
|
|
$alreadyProcessed = []; // To avoid duplicate processing
|
|
|
|
foreach ($list as $file) {
|
|
// Skip directories "." and ".." or any unintended duplicates
|
|
if ($file === '.' || $file === '..') {
|
|
continue;
|
|
}
|
|
|
|
$ext = pathinfo($folder . $file, PATHINFO_EXTENSION);
|
|
$filePath = realpath($folder . $file); // Get canonicalized absolute path
|
|
|
|
// Skip directories, duplicates, excluded files, or files not in the include list
|
|
if (
|
|
is_dir($filePath) ||
|
|
in_array($filePath, $alreadyProcessed) || // Skip files already processed
|
|
$ext !== 'php' ||
|
|
in_array($file, $exclude) ||
|
|
(!empty($include) && !in_array($file, $include))
|
|
) {
|
|
continue;
|
|
}
|
|
|
|
fwrite(STDOUT, " - $file\n");
|
|
$filesToTest[$file] = $filePath;
|
|
|
|
// Mark this file as processed
|
|
$alreadyProcessed[] = $filePath;
|
|
}
|
|
|
|
if (empty($filesToTest)) {
|
|
fwrite(STDOUT, "No scripts to test in $folder\n");
|
|
return;
|
|
}
|
|
|
|
// Prepare dynamic error-catching and script-loading logic
|
|
$phpCode = "<?php\n";
|
|
$phpCode .= "require_once '" . addslashes($class2Path) . "';\n";
|
|
$phpCode .= "restore_error_handler();\n";
|
|
$phpCode .= "error_reporting(E_ALL | E_STRICT);\n";
|
|
$phpCode .= "ini_set('display_errors', 1);\n";
|
|
$phpCode .= "ini_set('log_errors', 0);\n";
|
|
foreach ($filesToTest as $file => $filePath) {
|
|
$phpCode .= "echo 'START: " . addslashes($file) . "\\n';\n";
|
|
$phpCode .= "try {\n";
|
|
$phpCode .= " require_once '" . addslashes($filePath) . "';\n";
|
|
$phpCode .= "} catch (Throwable \$e) {\n";
|
|
$phpCode .= " echo 'Error in $file: ' . \$e->getMessage() . ' on Line ' . \$e->getLine() . '\\n';\n";
|
|
$phpCode .= "}\n";
|
|
$phpCode .= "echo 'END: " . addslashes($file) . "\\n';\n";
|
|
}
|
|
|
|
// Write the generated code to a temporary PHP file
|
|
$tmpFile = tempnam(sys_get_temp_dir(), 'loadScripts_') . '.php';
|
|
file_put_contents($tmpFile, $phpCode);
|
|
|
|
try {
|
|
$errors = [];
|
|
foreach ($filesToTest as $file => $filePath) {
|
|
// Check for syntax errors using `php -l`
|
|
$lintCommand = sprintf('php -l "%s"', addslashes($filePath));
|
|
exec($lintCommand, $lintOutput, $lintExitCode);
|
|
|
|
if ($lintExitCode !== 0) {
|
|
// Log syntax errors explicitly
|
|
$errors[] = "Syntax error in $file: " . implode("\n", $lintOutput);
|
|
fwrite(STDOUT, "Syntax error in $file: " . implode("\n", $lintOutput) . "\n");
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Run the temporary PHP script
|
|
$command = sprintf('php "%s"', $tmpFile);
|
|
$descriptors = [
|
|
0 => ['pipe', 'r'], // stdin
|
|
1 => ['pipe', 'w'], // stdout
|
|
2 => ['pipe', 'w'], // stderr
|
|
];
|
|
$process = proc_open($command, $descriptors, $pipes);
|
|
|
|
if (!is_resource($process)) {
|
|
$this->fail("Failed to start process for $folder");
|
|
return;
|
|
}
|
|
|
|
fclose($pipes[0]); // No input needed
|
|
$stdout = stream_get_contents($pipes[1]);
|
|
$stderr = stream_get_contents($pipes[2]);
|
|
fclose($pipes[1]);
|
|
fclose($pipes[2]);
|
|
|
|
$exitCode = proc_close($process);
|
|
|
|
// Parse regular runtime errors and warnings
|
|
if ($exitCode !== 0 || !empty($stderr)) {
|
|
if (!empty($stdout)) {
|
|
// Parse START-END blocks or error output
|
|
if (preg_match_all('/START: (.*?)\n(.*?)(\nEND: \1|$)/is', $stdout, $matches, PREG_SET_ORDER)) {
|
|
foreach ($matches as $match) {
|
|
$file = $match[1];
|
|
$blockOutput = trim($match[2]);
|
|
|
|
if (preg_match('/(Parse error|Fatal error|Warning|Notice|Error):.*in\s+([^\s]+)\s+on\s+line\s+(\d+)/i', $blockOutput, $errorMatch)) {
|
|
$errorMessage = $errorMatch[0];
|
|
$error = "Error in $file: $errorMessage";
|
|
fwrite(STDOUT, "$error\n");
|
|
$errors[] = $error;
|
|
} elseif ($blockOutput) {
|
|
$error = "Unexpected output in $file: $blockOutput";
|
|
fwrite(STDOUT, "$error\n");
|
|
$errors[] = $error;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!empty($stderr)) {
|
|
$error = "Error in $folder: " . trim($stderr);
|
|
fwrite(STDOUT, "$error\n");
|
|
$errors[] = $error;
|
|
}
|
|
}
|
|
|
|
// Report the errors or confirm success
|
|
if (!empty($errors)) {
|
|
$this->fail("Errors found in scripts:\n" . implode("\n", $errors));
|
|
} else {
|
|
$this->assertTrue(true, "All scripts in $folder loaded successfully");
|
|
}
|
|
} finally {
|
|
// Cleanup: remove the temporary file
|
|
unlink($tmpFile);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|