♻️ iTopDesignFormatTest : get version directly from expected content

This commit is contained in:
Pierre Goiffon
2022-11-09 11:52:17 +01:00
parent 52c984d5e7
commit 8f6065d4f4
3 changed files with 112 additions and 46 deletions

View File

@@ -0,0 +1,10 @@
<?php
/*
* @copyright Copyright (C) 2010-2022 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
class iTopXmlException extends CoreException
{
}

View File

@@ -191,6 +191,7 @@ class iTopDesignFormat
$aErrors[] = $aLogEntry['msg'];
}
}
return $aErrors;
}
@@ -202,15 +203,49 @@ class iTopDesignFormat
return $this->aLog;
}
/**
* @throws \iTopXmlException if root node not found
*/
public function GetITopDesignNode(): DOMNode
{
$oXPath = new DOMXPath($this->oDocument);
// Retrieve the version number
$oNodeList = $oXPath->query('/itop_design');
if ($oNodeList->length === 0) {
throw new iTopXmlException('File format: no root <itop_design> tag found');
}
return $oNodeList->item(0);
}
/**
* @return string
* @throws \iTopXmlException
*/
public function GetVersion()
{
$oITopDesignNode = $this->GetITopDesignNode();
$sVersion = $oITopDesignNode->getAttribute('version');
if (utils::IsNullOrEmptyString($sVersion)) {
// Originally, the information was missing: default to 1.0
$sVersion = '1.0';
}
return $sVersion;
}
/**
* An alternative to getNodePath, that gives the id of nodes instead of the position within the children
*
* @param $oNode
*
* @return string
*/
public static function GetItopNodePath($oNode)
{
if ($oNode instanceof DOMDocument) return '';
$sId = $oNode->getAttribute('id');
$sNodeDesc = ($sId != '') ? $oNode->nodeName.'['.$sId.']' : $oNode->nodeName;
return self::GetItopNodePath($oNode->parentNode).'/'.$sNodeDesc;
@@ -247,30 +282,24 @@ class iTopDesignFormat
$this->aLog = array();
$this->bStatus = true;
$oXPath = new DOMXPath($this->oDocument);
// Retrieve the version number
$oNodeList = $oXPath->query('/itop_design');
if ($oNodeList->length == 0)
{
// Hmm, not an iTop Data Model file...
$this->LogError('File format, no root <itop_design> tag found');
try {
$sVersion = $this->GetVersion();
}
else
{
$sVersion = $oNodeList->item(0)->getAttribute('version');
if ($sVersion == '')
{
// Originaly, the information was missing: default to 1.0
$sVersion = '1.0';
}
$this->LogInfo("Converting from $sVersion to $sTargetVersion");
$this->DoConvert($sVersion, $sTargetVersion, $oFactory);
if ($this->bStatus)
{
// Update the version number
$oNodeList->item(0)->setAttribute('version', $sTargetVersion);
}
catch (iTopXmlException $e) {
$this->LogError($e->getMessage());
return $this->bStatus;
}
$this->LogInfo("Converting from $sVersion to $sTargetVersion");
$this->DoConvert($sVersion, $sTargetVersion, $oFactory);
if ($this->bStatus) {
/** @noinspection PhpUnhandledExceptionInspection already called earlier so should not crash */
$oITopDesignNode = $this->GetITopDesignNode();
// Update the version number
$oITopDesignNode->setAttribute('version', $sTargetVersion);
}
return $this->bStatus;
}
@@ -318,22 +347,39 @@ class iTopDesignFormat
}
// Transform to the intermediate format
$aCallSpec = array($this, $sTransform);
try
{
try {
call_user_func($aCallSpec, $oFactory);
// Recurse
$this->DoConvert($sIntermediate, $sTo, $oFactory);
}
catch (Exception $e)
{
catch (Exception $e) {
$this->LogError($e->getMessage());
}
}
/**
* @param \DOMNode|null $node
* @param bool $bFormatOutput
* @param bool $bPreserveWhiteSpace
*
* @return false|string
*
* @uses \DOMDocument::saveXML()
*/
public function GetXmlAsString($node = null, $bFormatOutput = true, $bPreserveWhiteSpace = false)
{
$this->oDocument->formatOutput = $bFormatOutput;
$this->oDocument->preserveWhiteSpace = $bPreserveWhiteSpace;
return $this->oDocument->saveXML($node = null);
}
/**
* Upgrade the format from version 1.0 to 1.1
*
* @param \ModelFactory $oFactory
*
* @return void (Errors are logged)
*/
protected function From10To11($oFactory)

View File

@@ -28,47 +28,57 @@ class iTopDesignFormatTest extends ItopTestCase
* @covers iTopDesignFormat::Convert
* @dataProvider ConvertProvider
*
* @param string $sTargetVersion
* @param string $sXmlFileName Corresponding files should exist in the `Convert-samples` dir with the `.expected` and `.input` suffixes
* Example "1.7_to_1.6" for `Convert-samples/1.7_to_1.6.expected.xml` and `Convert-samples/1.7_to_1.6.input.xml`
*
* @throws \Exception
*/
public function testConvert($sTargetVersion, $sXmlFileName, $iExpectedErrors = 0, $sFirstErrorMessage = '')
public function testConvert($sXmlFileName, $iExpectedErrors = 0, $sFirstErrorMessage = '')
{
$sSamplesRelDirPath = 'Convert-samples/';
$sInputXml = $this->GetFileContent($sSamplesRelDirPath.$sXmlFileName.'.input');
$oInputDocument = new DOMDocument();
libxml_clear_errors();
$oInputDocument->preserveWhiteSpace = false;
$oInputDocument->loadXML($sInputXml);
$oInputDocument->formatOutput = true;
$oDesignFormat = new iTopDesignFormat($oInputDocument);
$bResult = $oDesignFormat->Convert($sTargetVersion);
$aErrors = $oDesignFormat->GetErrors();
$sExpectedXml = $this->GetFileContent($sSamplesRelDirPath.$sXmlFileName.'.expected');
$oExpectedDesignFormat = static::GetItopFormatFromString($sExpectedXml);
$sTargetVersion = $oExpectedDesignFormat->GetVersion();
$sInputXml = $this->GetFileContent($sSamplesRelDirPath.$sXmlFileName.'.input');
$oInputDesignFormat = static::GetItopFormatFromString($sInputXml);
$bResult = $oInputDesignFormat->Convert($sTargetVersion);
$aErrors = $oInputDesignFormat->GetErrors();
$this->assertCount($iExpectedErrors, $aErrors);
if ($iExpectedErrors > 0) {
$this->assertFalse($bResult);
$this->assertEquals($sFirstErrorMessage, $aErrors[0]);
}
$sConvertedXml = $oInputDocument->saveXML();
/** @noinspection PhpRedundantOptionalArgumentInspection We REALLY want those options so specifying it anyway */
$sConvertedXml = $oInputDesignFormat->GetXmlAsString(null, true, false);
// Erase dynamic values
$sConvertedXml = preg_replace('@<trashed_node id="\w+"@', '<trashed_node id="XXX"', $sConvertedXml);
$sExpectedXml = $this->GetFileContent($sSamplesRelDirPath.$sXmlFileName.'.expected');
$this->assertEquals($sExpectedXml, $sConvertedXml);
}
private static function GetItopFormatFromString(string $sFileContent): iTopDesignFormat
{
$oInputDocument = new DOMDocument();
/** @noinspection PhpComposerExtensionStubsInspection */
libxml_clear_errors();
$oInputDocument->formatOutput = true;
$oInputDocument->preserveWhiteSpace = false;
$oInputDocument->loadXML($sFileContent);
return new iTopDesignFormat($oInputDocument);
}
public function ConvertProvider()
{
return [
'1.6 to 1.7 2' => ['sTargetVersion' => '1.7', 'sXmlFileName' => '1.6_to_1.7_2'],
'1.7 to 1.6' => ['sTargetVersion' => '1.6', 'sXmlFileName' => '1.7_to_1.6'],
'1.7 to 1.6 2' => ['sTargetVersion' => '1.6', 'sXmlFileName' => '1.7_to_1.6_2'],
'1.7 to 3.0' => ['sTargetVersion' => '3.0', 'sXmlFileName' => '1.7_to_3.0'],
'3.0 to 1.7' => ['sTargetVersion' => '1.7', 'sXmlFileName' => '3.0_to_1.7'],
'Bug_4569' => ['sTargetVersion' => '1.7', 'sXmlFileName' => 'Bug_4569'],
'1.6 to 1.7 2' => ['sXmlFileName' => '1.6_to_1.7_2'],
'1.7 to 1.6' => ['sXmlFileName' => '1.7_to_1.6'],
'1.7 to 1.6 2' => ['sXmlFileName' => '1.7_to_1.6_2'],
'1.7 to 3.0' => ['sXmlFileName' => '1.7_to_3.0'],
'3.0 to 1.7' => ['sXmlFileName' => '3.0_to_1.7'],
'Bug_4569' => ['sXmlFileName' => 'Bug_4569'],
];
}