mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-19 00:28:47 +02:00
init in beforeclass + read defined classes/interfaces by module
This commit is contained in:
@@ -27,13 +27,11 @@ require_once __DIR__ . '/XmlModule.php';
|
||||
use ModuleInstallerAPI;
|
||||
/**
|
||||
* @package Combodo\iTop\Test\UnitTest\Setup
|
||||
* @group beforeSetup
|
||||
*/
|
||||
class iTopModulesDependencyTest extends ItopTestCase {
|
||||
private array $aFilesToRemove = [];
|
||||
private array $aModules=[];
|
||||
private array $aModulesDepsByModuleName=[];
|
||||
private array $aModulesDatamodelSectionByModuleName=[];
|
||||
private static array $aModulesDataByModuleName=[];
|
||||
private string $sCurrentModule;
|
||||
private array $aDefineNodes;
|
||||
private array $aDependencyNodes;
|
||||
@@ -43,9 +41,6 @@ class iTopModulesDependencyTest extends ItopTestCase {
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp(); // TODO: Change the autogenerated stub
|
||||
|
||||
require_once APPROOT."setup/modulediscovery.class.inc.php";
|
||||
require_once(APPROOT.'/setup/moduleinstaller.class.inc.php');
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
@@ -59,13 +54,17 @@ class iTopModulesDependencyTest extends ItopTestCase {
|
||||
{
|
||||
if (count($this->aAllDmFiles)==0){
|
||||
$aGlobPAtterns = [
|
||||
APPROOT.'datamodels/2.x/*/datamodel.*.xml',
|
||||
APPROOT.'datamodels/2.x',
|
||||
APPROOT.'application/*.xml',
|
||||
APPROOT.'core/*.xml',
|
||||
APPROOT.'extensions',
|
||||
APPROOT.'extensions/*',
|
||||
APPROOT.'data/production-modules',
|
||||
APPROOT.'data/production-modules/*',
|
||||
];
|
||||
|
||||
foreach ($aGlobPAtterns as $sPattern) {
|
||||
$this->aAllDmFiles = array_merge($this->aAllDmFiles, glob($sPattern));
|
||||
$this->aAllDmFiles = array_merge($this->aAllDmFiles, glob("$sPattern/datamodel.*.xml"));
|
||||
}
|
||||
}
|
||||
return $this->aAllDmFiles;
|
||||
@@ -123,36 +122,32 @@ class iTopModulesDependencyTest extends ItopTestCase {
|
||||
$this->CompleteModuleDependencies();
|
||||
}
|
||||
|
||||
/*private function ReadModuleFileData2() : void
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
$aDirsToScan = [
|
||||
APPROOT.'datamodels/2.x',
|
||||
APPROOT.'extensions',
|
||||
APPROOT.'data/production-modules',
|
||||
];
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
foreach(\ModuleDiscovery::GetAvailableModules($aDirsToScan) as $sModuleId => $aData) {
|
||||
list($sModuleName, $sVersion) = \ModuleDiscovery::GetModuleName($sModuleId);
|
||||
$aCurrentDeps = $aData['dependencies'] ?? [];
|
||||
$this->aModulesDepsByModuleName[$sModuleName] = $aCurrentDeps;
|
||||
require_once APPROOT."setup/modulediscovery.class.inc.php";
|
||||
require_once(APPROOT.'/setup/moduleinstaller.class.inc.php');
|
||||
|
||||
if (count(self::$aModulesDataByModuleName)>0){
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
private function ReadModuleFileData() : void
|
||||
{
|
||||
$aDirsToScan = [
|
||||
APPROOT.'datamodels/2.x',
|
||||
APPROOT.'extensions',
|
||||
APPROOT.'extensions/*',
|
||||
APPROOT.'data/production-modules',
|
||||
APPROOT.'data/production-modules/*',
|
||||
];
|
||||
$this->aModulesDepsByModuleName=[];
|
||||
$aFilesToRemove=[];
|
||||
foreach ($aDirsToScan as $sDir){
|
||||
foreach (glob("$sDir/*/module.*.php") as $sFile) {
|
||||
$sContent = file_get_contents($sFile);
|
||||
$sContent=str_replace('SetupWebPage::AddModule', '$aModuleData=array', $sContent);
|
||||
|
||||
$sTempFile = tempnam(sys_get_temp_dir(), 'modulefile_');
|
||||
$this->aFilesToRemove[]=$sTempFile;
|
||||
$aFilesToRemove[]=$sTempFile;
|
||||
file_put_contents($sTempFile, $sContent);
|
||||
$bDebug=false;
|
||||
if ($bDebug){
|
||||
@@ -163,37 +158,55 @@ class iTopModulesDependencyTest extends ItopTestCase {
|
||||
if ($bDebug){
|
||||
var_dump($aModuleData);
|
||||
}
|
||||
//replace tmp file by real module path
|
||||
$aModuleData[0]=$sFile;
|
||||
$sModuleId=$aModuleData[1];
|
||||
|
||||
list($sModuleName, $sVersion) = \ModuleDiscovery::GetModuleName($sModuleId);
|
||||
$aData=$aModuleData[2];
|
||||
$this->aModulesDepsByModuleName[$sModuleName] = $aData['dependencies'] ?? [];
|
||||
$this->aModulesDatamodelSectionByModuleName[$sModuleName] = $aData['datamodel'] ?? [];
|
||||
self::$aModulesDataByModuleName[$sModuleName] = $aModuleData;
|
||||
}
|
||||
|
||||
ksort(self::$aModulesDataByModuleName);
|
||||
|
||||
foreach ($aFilesToRemove as $sTmpFile){
|
||||
@unlink($sTmpFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*public function testReadModuleFileData()
|
||||
public function testReadModuleFileData()
|
||||
{
|
||||
$this->ReadModuleFileData2();
|
||||
ksort($this->aModulesDepsByModuleName);
|
||||
$this->assertEquals([], $this->aModulesDepsByModuleName);
|
||||
}*/
|
||||
$aFullnameClassesByModuleName=[];
|
||||
foreach (self::$aModulesDataByModuleName as $sModuleName => $aModuleData){
|
||||
echo "$sModuleName\n";
|
||||
$aFiles = $aModuleData[2]['datamodel'] ?? [];
|
||||
$sDir = dirname($aModuleData[0]);
|
||||
|
||||
foreach ($aFiles as $sFile){
|
||||
if (preg_match("|.*model\.$sModuleName\.php|", $sFile)){
|
||||
continue;
|
||||
}
|
||||
$aFullnameClassesByModuleName=array_merge($aFullnameClassesByModuleName, $this->ReadDependencies($sModuleName, "$sDir/$sFile"));
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertEquals([], $aFullnameClassesByModuleName);
|
||||
}
|
||||
|
||||
public function testModules()
|
||||
{
|
||||
$this->FetchAllDependenciesViaDM();
|
||||
$this->ReadModuleFileData();
|
||||
|
||||
$aErrors=[];
|
||||
/** @var XmlModule $oXmlModule */
|
||||
foreach ($this->aModules as $sModuleName => $oXmlModule) {
|
||||
$aCurrentDeps = $this->aModulesDepsByModuleName[$sModuleName] ?? [];
|
||||
$aCurrentDeps = self::$aModulesDataByModuleName[$sModuleName][2]['dependencies'] ?? [];
|
||||
$aModuleErrors=[];
|
||||
foreach ($oXmlModule->aDependencyModulesNames as $sDepModuleName => $oXmlModule2){
|
||||
$sXmlUIDs = implode('|', $oXmlModule->aXMlMetaInfosByModuleNames[$sDepModuleName]);
|
||||
$bResolved=false;
|
||||
foreach ($aCurrentDeps as $sDepString){
|
||||
$oModuleDependency = new \ModuleDependency($sDepString);
|
||||
$oModuleDependency = new \iTopCoreModuleDependency($sDepString);
|
||||
|
||||
if (in_array($sDepModuleName, $oModuleDependency->GetPotentialPrerequisiteModuleNames())) {
|
||||
$bResolved=true;
|
||||
@@ -352,6 +365,85 @@ class iTopModulesDependencyTest extends ItopTestCase {
|
||||
$oXmlModule->CompleteModuleDependencies($this->aModules);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read declared classes/interfaces in modules.php file (either directly listed files or inside autoload)
|
||||
* @param string $sModuleName: module name
|
||||
* @param string : module file path
|
||||
*
|
||||
* @return array: dict with fullname classes as keys and module name as value
|
||||
*/
|
||||
public function ReadDependencies(string $sModuleName, string $sPath) : array
|
||||
{
|
||||
if (false !== strpos($sPath, 'autoload.php')){
|
||||
return $this->ReadAutoloadDependencies($sModuleName, $sPath);
|
||||
}
|
||||
|
||||
$aRes=[];
|
||||
|
||||
$sContent = file_get_contents($sPath);
|
||||
|
||||
$sNamespace='';
|
||||
if (preg_match('|namespace (.*)[ ]*;|', $sContent, $aMatches)){
|
||||
$sNamespace=trim($aMatches[1]) . '\\';
|
||||
}
|
||||
|
||||
|
||||
if (preg_match_all('|^class ([a-zA-Z]*) |m', $sContent, $aMatches)){
|
||||
foreach($aMatches[1] as $sClass){
|
||||
$aRes[$sNamespace.$sClass]=$sModuleName;
|
||||
}
|
||||
}
|
||||
|
||||
if (preg_match_all('|^interface ([a-zA-Z]*) |m', $sContent, $aMatches)){
|
||||
foreach($aMatches[1] as $sInterface){
|
||||
$aRes[$sNamespace.$sInterface]=$sModuleName;
|
||||
}
|
||||
}
|
||||
|
||||
return $aRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read declared classes/interfaces autoload file
|
||||
* @param string $sModuleName: module name
|
||||
* @param string : module file path
|
||||
*
|
||||
* @return array: dict with fullname classes as keys and module name as value
|
||||
*/
|
||||
private function ReadAutoloadDependencies(string $sModuleName, string $sPath) : array
|
||||
{
|
||||
$sAutoloadClassMap = dirname($sPath) . "/composer/autoload_classmap.php";
|
||||
//echo $sAutoloadClassMap . '\n';
|
||||
if (!is_file($sAutoloadClassMap)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$sTempfile = tempnam(sys_get_temp_dir(), 'autoload_');
|
||||
$this->aFilesToRemove[] = $sTempfile;
|
||||
$sContent = file_get_contents($sAutoloadClassMap);
|
||||
$sReplace=<<<TXT
|
||||
\$aModuleFiles=
|
||||
TXT;
|
||||
$sContent = preg_replace('|return|', $sReplace, $sContent);
|
||||
//echo $sContent;
|
||||
file_put_contents($sTempfile, $sContent);
|
||||
require_once $sTempfile;
|
||||
|
||||
$aRes=[];
|
||||
foreach (array_keys($aModuleFiles) as $sClass){
|
||||
if (strpos($sClass, 'InstalledVersions')){
|
||||
continue;
|
||||
}
|
||||
$aRes[$sClass]=$sModuleName;
|
||||
}
|
||||
return $aRes;
|
||||
}
|
||||
|
||||
public function testReadDependencies()
|
||||
{
|
||||
$this->assertEquals(['CASLoginExtension'], $this->ReadDependencies('authent-cas', APPROOT . 'datamodels/2.x/authent-cas/src/CASLoginExtension.php'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user