Add ModelReflection Service as dependency injection + tests

This commit is contained in:
Eric Espie
2025-11-19 14:42:32 +01:00
parent 6678689b77
commit 65bd6d9fd0
18 changed files with 285 additions and 44 deletions

View File

@@ -435,6 +435,8 @@ return array(
'Combodo\\iTop\\Dependencies\\AbstractFolderAnalyzer' => $baseDir . '/sources/Dependencies/AbstractFolderAnalyzer.php',
'Combodo\\iTop\\Dependencies\\Composer\\iTopComposer' => $baseDir . '/sources/Dependencies/Composer/iTopComposer.php',
'Combodo\\iTop\\Dependencies\\NPM\\iTopNPM' => $baseDir . '/sources/Dependencies/NPM/iTopNPM.php',
'Combodo\\iTop\\DependencyInjection\\DIException' => $baseDir . '/sources/DependencyInjection/DIException.php',
'Combodo\\iTop\\DependencyInjection\\DIService' => $baseDir . '/sources/DependencyInjection/DIService.php',
'Combodo\\iTop\\DesignDocument' => $baseDir . '/core/designdocument.class.inc.php',
'Combodo\\iTop\\DesignElement' => $baseDir . '/core/designdocument.class.inc.php',
'Combodo\\iTop\\Form\\Field\\AbstractSimpleField' => $baseDir . '/sources/Form/Field/AbstractSimpleField.php',
@@ -491,12 +493,9 @@ return array(
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => $baseDir . '/sources/Forms/Block/Base/TextFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeValueChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\DataModel\\IDataModelBlock' => $baseDir . '/sources/Forms/Block/DataModel/IDataModelBlock.php',
'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/OqlFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Expression\\ExpressionFormBlock' => $baseDir . '/sources/Forms/Block/Expression/ExpressionFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\FormBlockDescription' => $baseDir . '/sources/Forms/Block/FormBlockDescription.php',
'Combodo\\iTop\\Forms\\Block\\FormBlockException' => $baseDir . '/sources/Forms/Block/FormBlockException.php',
'Combodo\\iTop\\Forms\\Block\\FormBlockFactory' => $baseDir . '/sources/Forms/Block/FormBlockFactory.php',
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyHandler' => $baseDir . '/sources/Forms/FormBuilder/DependencyHandler.php',
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyMap' => $baseDir . '/sources/Forms/FormBuilder/DependencyMap.php',
'Combodo\\iTop\\Forms\\FormBuilder\\FormBuilder' => $baseDir . '/sources/Forms/FormBuilder/FormBuilder.php',
@@ -523,6 +522,7 @@ return array(
'Combodo\\iTop\\Forms\\IO\\FormBlockIOException' => $baseDir . '/sources/Forms/IO/FormBlockIOException.php',
'Combodo\\iTop\\Forms\\IO\\FormInput' => $baseDir . '/sources/Forms/IO/FormInput.php',
'Combodo\\iTop\\Forms\\IO\\FormOutput' => $baseDir . '/sources/Forms/IO/FormOutput.php',
'Combodo\\iTop\\Forms\\IO\\Format\\AbstractIOFormat' => $baseDir . '/sources/Forms/IO/Format/AbstractIOFormat.php',
'Combodo\\iTop\\Forms\\IO\\Format\\AttributeIOFormat' => $baseDir . '/sources/Forms/IO/Format/AttributeIOFormat.php',
'Combodo\\iTop\\Forms\\IO\\Format\\BooleanIOFormat' => $baseDir . '/sources/Forms/IO/Format/BooleanIOFormat.php',
'Combodo\\iTop\\Forms\\IO\\Format\\ClassIOFormat' => $baseDir . '/sources/Forms/IO/Format/ClassIOFormat.php',

View File

@@ -816,6 +816,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Dependencies\\AbstractFolderAnalyzer' => __DIR__ . '/../..' . '/sources/Dependencies/AbstractFolderAnalyzer.php',
'Combodo\\iTop\\Dependencies\\Composer\\iTopComposer' => __DIR__ . '/../..' . '/sources/Dependencies/Composer/iTopComposer.php',
'Combodo\\iTop\\Dependencies\\NPM\\iTopNPM' => __DIR__ . '/../..' . '/sources/Dependencies/NPM/iTopNPM.php',
'Combodo\\iTop\\DependencyInjection\\DIException' => __DIR__ . '/../..' . '/sources/DependencyInjection/DIException.php',
'Combodo\\iTop\\DependencyInjection\\DIService' => __DIR__ . '/../..' . '/sources/DependencyInjection/DIService.php',
'Combodo\\iTop\\DesignDocument' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
'Combodo\\iTop\\DesignElement' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
'Combodo\\iTop\\Form\\Field\\AbstractSimpleField' => __DIR__ . '/../..' . '/sources/Form/Field/AbstractSimpleField.php',
@@ -872,12 +874,9 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/TextFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeValueChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\DataModel\\IDataModelBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/IDataModelBlock.php',
'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/OqlFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Expression\\ExpressionFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Expression/ExpressionFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\FormBlockDescription' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockDescription.php',
'Combodo\\iTop\\Forms\\Block\\FormBlockException' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockException.php',
'Combodo\\iTop\\Forms\\Block\\FormBlockFactory' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockFactory.php',
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyHandler' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/DependencyHandler.php',
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyMap' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/DependencyMap.php',
'Combodo\\iTop\\Forms\\FormBuilder\\FormBuilder' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/FormBuilder.php',
@@ -904,6 +903,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Forms\\IO\\FormBlockIOException' => __DIR__ . '/../..' . '/sources/Forms/IO/FormBlockIOException.php',
'Combodo\\iTop\\Forms\\IO\\FormInput' => __DIR__ . '/../..' . '/sources/Forms/IO/FormInput.php',
'Combodo\\iTop\\Forms\\IO\\FormOutput' => __DIR__ . '/../..' . '/sources/Forms/IO/FormOutput.php',
'Combodo\\iTop\\Forms\\IO\\Format\\AbstractIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/AbstractIOFormat.php',
'Combodo\\iTop\\Forms\\IO\\Format\\AttributeIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/AttributeIOFormat.php',
'Combodo\\iTop\\Forms\\IO\\Format\\BooleanIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/BooleanIOFormat.php',
'Combodo\\iTop\\Forms\\IO\\Format\\ClassIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/ClassIOFormat.php',

View File

@@ -169,10 +169,7 @@ abstract class Controller extends AbstractController
$this->SetViewPath($sViewPath, $aAdditionalPaths);
if ($sModuleName != 'core') {
try {
$this->aDefaultParams = [
'sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php'),
'sAPPROOTURL' => utils::GetAbsoluteUrlAppRoot(),
];
$this->aDefaultParams = ['sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php')];
} catch (Exception $e) {
IssueLog::Error($e->getMessage());
}
@@ -200,10 +197,7 @@ abstract class Controller extends AbstractController
$this->SetModuleName(basename($sModulePath));
$this->SetViewPath($sModulePath.'/view');
try {
$this->aDefaultParams = [
'sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php'),
'sAPPROOTURL' => utils::GetAbsoluteUrlAppRoot(),
];
$this->aDefaultParams = ['sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php')];
} catch (Exception $e) {
IssueLog::Error($e->getMessage());
}

View File

@@ -0,0 +1,19 @@
<?php
/*
* @copyright Copyright (C) 2010-2025 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\DependencyInjection;
use IssueLog;
use Throwable;
class DIException extends \Exception
{
public function __construct(string $sMessage = '', int $iCode = 0, ?Throwable $oPrevious = null, array $aContext = [])
{
parent::__construct($sMessage, $iCode, $oPrevious);
IssueLog::Exception(get_class($this).' occurs: '.$sMessage, $this, null, $aContext);
}
}

View File

@@ -0,0 +1,60 @@
<?php
/*
* @copyright Copyright (C) 2010-2025 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\DependencyInjection;
class DIService
{
private static DIService $oInstance;
private array $aServices = [];
protected function __construct()
{
}
final public static function GetInstance(): DIService
{
if (!isset(static::$oInstance)) {
static::$oInstance = new DIService();
}
return static::$oInstance;
}
/**
* Register a service by name
*
* @api
*
* @param string $sName Name of the service to register
* @param mixed $oService Service to register
*
* @return void
*/
final public function RegisterService(string $sName, mixed $oService): void
{
$aServices[$sName] = $oService;
}
/**
* Get a previously registered service
*
* @api
*
* @param string $sName name of the service to get
*
* @return mixed
* @throws \Combodo\iTop\DependencyInjection\DIException
*/
final public function GetService(string $sName): mixed
{
if (!isset($this->aServices[$sName])) {
throw new DIException("Service ".json_encode($sName)." not found");
}
return $this->aServices[$sName];
}
}

View File

@@ -7,13 +7,14 @@
namespace Combodo\iTop\Forms\Block\DataModel;
use Combodo\iTop\DependencyInjection\DIService;
use Combodo\iTop\Forms\Block\Base\ChoiceFormBlock;
use Combodo\iTop\Forms\IO\Converter\StringToAttributeConverter;
use Combodo\iTop\Forms\IO\Format\AttributeIOFormat;
use Combodo\iTop\Forms\IO\Format\ClassIOFormat;
use Combodo\iTop\Forms\Register\IORegister;
use Combodo\iTop\Forms\Register\OptionsRegister;
use MetaModel;
use utils;
/**
* Form block for choice of class attributes.
@@ -43,24 +44,32 @@ class AttributeChoiceFormBlock extends ChoiceFormBlock
$oIORegister->AddOutput(self::OUTPUT_ATTRIBUTE, AttributeIOFormat::class, new StringToAttributeConverter());
}
/** @inheritdoc */
/**
* @param \Combodo\iTop\Forms\Register\OptionsRegister $oOptionsRegister
*
* @throws \Combodo\iTop\DependencyInjection\DIException
* @throws \Combodo\iTop\Forms\Block\FormBlockException
* @throws \Combodo\iTop\Forms\Register\RegisterException
*/
public function UpdateOptions(OptionsRegister $oOptionsRegister): void
{
parent::UpdateOptions($oOptionsRegister);
$oClass = $this->GetInputValue(self::INPUT_CLASS_NAME);
$sClass = strval($this->GetInputValue(self::INPUT_CLASS_NAME));
if ($oClass === null) {
if (utils::IsNullOrEmptyString($sClass)) {
$oOptionsRegister->SetOption('choices', []);
return;
}
$aAttributeCodes = MetaModel::GetAttributesList($oClass);
/** @var \ModelReflection $oModelReflection */
$oModelReflection = DIService::GetInstance()->GetService('ModelReflection');
$aAttributeCodes = array_keys($oModelReflection->ListAttributes($sClass));
$aAttributes = [];
foreach ($aAttributeCodes as $sAttributeCode) {
$oAttribute = MetaModel::GetAttributeDef(strval($oClass), $sAttributeCode);
$aAttributes[$oAttribute->GetLabel()] = $sAttributeCode;
foreach ($aAttributeCodes as $sAttCode) {
$oAttribute =$oModelReflection->GetLabel($sClass, $sAttCode);
$aAttributes[$oAttribute->GetLabel()] = $sAttCode;
}
$oOptionsRegister->SetOption('choices', $aAttributes);

View File

@@ -7,6 +7,7 @@
namespace Combodo\iTop\Forms\Block\DataModel;
use Combodo\iTop\DependencyInjection\DIService;
use Combodo\iTop\Forms\Block\Base\ChoiceFormBlock;
use Combodo\iTop\Forms\Block\FormBlockException;
use Combodo\iTop\Forms\IO\Format\AttributeIOFormat;
@@ -15,7 +16,6 @@ use Combodo\iTop\Forms\IO\Format\RawFormat;
use Combodo\iTop\Forms\Register\IORegister;
use Combodo\iTop\Forms\Register\OptionsRegister;
use Exception;
use MetaModel;
/**
* Form block for choice of class attribute values.
@@ -56,12 +56,13 @@ class AttributeValueChoiceFormBlock extends ChoiceFormBlock
{
parent::UpdateOptions($oOptionsRegister);
$oClassName = $this->GetInputValue(self::INPUT_CLASS_NAME);
$oAttribute = $this->GetInputValue(self::INPUT_ATTRIBUTE);
$sClass = strval($this->GetInputValue(self::INPUT_CLASS_NAME));
$sAttCode = strval($this->GetInputValue(self::INPUT_ATTRIBUTE));
try {
$oAttDef = MetaModel::GetAttributeDef(strval($oClassName), strval($oAttribute));
$aValues = $oAttDef->GetAllowedValues();
/** @var \ModelReflection $oModelReflection */
$oModelReflection = DIService::GetInstance()->GetService('ModelReflection');
$aValues = $oModelReflection->GetAllowedValues_att($sClass, $sAttCode);
$oOptionsRegister->SetOption('choices', array_flip($aValues ?? []));
} catch (Exception $e) {

View File

@@ -8,6 +8,7 @@
namespace Combodo\iTop\Forms\IO;
use Combodo\iTop\Forms\Block\AbstractFormBlock;
use Combodo\iTop\Forms\IO\Format\AbstractIOFormat;
use Symfony\Component\Form\FormEvents;
/**
@@ -43,6 +44,9 @@ class AbstractFormIO
*/
public function __construct(string $sName, string $sType, AbstractFormBlock $oOwnerBlock)
{
if (!is_a($sType, AbstractIOFormat::class, true)) {
throw new FormBlockIOException('invalid form format type '.json_encode($sType).' given');
}
$this->sType = $sType;
$this->oOwnerBlock = $oOwnerBlock;
$this->SetName($sName);

View File

@@ -7,9 +7,9 @@
namespace Combodo\iTop\Forms\IO\Converter;
use Combodo\iTop\DependencyInjection\DIService;
use Combodo\iTop\Forms\IO\Format\ClassIOFormat;
use Combodo\iTop\Forms\IO\FormBlockIOException;
use MetaModel;
/**
* OQL expression to class converter.
@@ -18,6 +18,7 @@ class OqlToClassConverter extends AbstractConverter
{
/** @inheritdoc
* @throws \Combodo\iTop\Forms\IO\FormBlockIOException
* @throws \Combodo\iTop\DependencyInjection\DIException
*/
public function Convert(mixed $oData): ?ClassIOFormat
{
@@ -31,7 +32,9 @@ class OqlToClassConverter extends AbstractConverter
// Selected class
if (isset($aMatches[1])) {
$sSelectedClass = $aMatches[1];
if (!MetaModel::IsValidClass($sSelectedClass)) {
/** @var \ModelReflection $oModelReflection */
$oModelReflection = DIService::GetInstance()->GetService('ModelReflection');
if (!$oModelReflection->IsValidClass($sSelectedClass)) {
throw new FormBlockIOException('Class '.json_encode($sSelectedClass).' not found');
}

View File

@@ -23,6 +23,12 @@ class FormBinding
*/
public function __construct(AbstractFormIO $oSourceIO, AbstractFormIO $oDestinationIO)
{
// Check IOFormat validity
$sSourceDataType = $oSourceIO->GetDataType();
$sDestinationDataType = $oDestinationIO->GetDataType();
if (!$sSourceDataType::IsCompatible($sDestinationDataType)) {
throw new FormBlockIOException('binding '.json_encode($sSourceDataType).' to '.json_encode($sDestinationDataType).' is not supported');
}
$this->oDestinationIO = $oDestinationIO;
$this->oSourceIO = $oSourceIO;
$oDestinationIO->Attach($this);

View File

@@ -0,0 +1,16 @@
<?php
/*
* @copyright Copyright (C) 2010-2025 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Forms\IO\Format;
use JsonSerializable;
abstract class AbstractIOFormat implements JsonSerializable
{
abstract public function jsonSerialize(): mixed;
abstract public static function IsCompatible(string $sOtherFormatClass): bool;
}

View File

@@ -2,9 +2,8 @@
namespace Combodo\iTop\Forms\IO\Format;
use JsonSerializable;
class AttributeIOFormat implements JsonSerializable
class AttributeIOFormat extends AbstractIOFormat
{
public string $sAttributeName;
@@ -23,4 +22,9 @@ class AttributeIOFormat implements JsonSerializable
{
return $this->sAttributeName;
}
public static function IsCompatible(string $sOtherFormatClass): bool
{
return is_a($sOtherFormatClass, AttributeIOFormat::class, true) || is_a($sOtherFormatClass, RawFormat::class, true);
}
}

View File

@@ -7,9 +7,7 @@
namespace Combodo\iTop\Forms\IO\Format;
use JsonSerializable;
class BooleanIOFormat implements JsonSerializable
class BooleanIOFormat extends AbstractIOFormat
{
public bool $bValue;
@@ -32,4 +30,9 @@ class BooleanIOFormat implements JsonSerializable
{
return $this->bValue;
}
public static function IsCompatible(string $sOtherFormatClass): bool
{
return is_a($sOtherFormatClass, BooleanIOFormat::class, true) || is_a($sOtherFormatClass, RawFormat::class, true);
}
}

View File

@@ -2,16 +2,26 @@
namespace Combodo\iTop\Forms\IO\Format;
use JsonSerializable;
use Combodo\iTop\DependencyInjection\DIService;
use Combodo\iTop\Forms\IO\FormBlockIOException;
class ClassIOFormat implements JsonSerializable
class ClassIOFormat extends AbstractIOFormat
{
public string $sClassName;
/**
* @throws \Combodo\iTop\DependencyInjection\DIException
* @throws \Combodo\iTop\Forms\IO\FormBlockIOException
*/
public function __construct(string $sClassName)
{
// Check class validity
/** @var \ModelReflection $oModelReflection */
$oModelReflection = DIService::GetInstance()->GetService('ModelReflection');
if (!$oModelReflection->IsValidClass($sClassName)) {
throw new FormBlockIOException("Class ".json_encode($sClassName)." is not valid");
}
$this->sClassName = $sClassName;
// validation du format sinon exception
}
public function __toString(): string
@@ -23,4 +33,9 @@ class ClassIOFormat implements JsonSerializable
{
return $this->sClassName;
}
public static function IsCompatible(string $sOtherFormatClass): bool
{
return is_a($sOtherFormatClass, ClassIOFormat::class, true) || is_a($sOtherFormatClass, RawFormat::class, true);
}
}

View File

@@ -2,18 +2,27 @@
namespace Combodo\iTop\Forms\IO\Format;
class NumberIOFormat
class NumberIOFormat extends AbstractIOFormat
{
public mixed $oValue;
public function __construct(string $oValue)
{
$this->oValue = $oValue;
// validation du format sinon exception
}
public function __toString(): string
{
return $this->oValue;
return strval($this->oValue);
}
public function jsonSerialize(): mixed
{
return strval($this->oValue);
}
public static function IsCompatible(string $sOtherFormatClass): bool
{
return is_a($sOtherFormatClass, NumberIOFormat::class, true) || is_a($sOtherFormatClass, RawFormat::class, true);
}
}

View File

@@ -2,18 +2,27 @@
namespace Combodo\iTop\Forms\IO\Format;
class RawFormat
class RawFormat extends AbstractIOFormat
{
public string $sValue;
public function __construct(string $sValue)
{
$this->sValue = $sValue;
// validation du format sinon exception
}
public function __toString(): string
{
return strval($this->sValue);
return $this->sValue;
}
public function jsonSerialize(): mixed
{
return $this->sValue;
}
public static function IsCompatible(string $sOtherFormatClass): bool
{
return true;
}
}

View File

@@ -82,6 +82,7 @@ class AbstractFormIOTest extends AbstractFormsTest
public function NameFormatSupportsOnlyLettersUnderscoreAndNumbersProvider()
{
return [
// Incorrects
'Spaces not supported' => ['The test name'],
'Minus not supported' => ['The-test-name'],
'Percent not supported' => ['name%'],
@@ -94,4 +95,9 @@ class AbstractFormIOTest extends AbstractFormsTest
];
}
public function testCreatingIOWithUnknownFormatThrowsException()
{
$this->expectException(FormBlockIOException::class);
$oInput = $this->GivenInput('test', 'test_toto');
}
}

View File

@@ -7,6 +7,11 @@
namespace Combodo\iTop\Test\UnitTest\Forms\IO;
use Combodo\iTop\Forms\IO\Format\AttributeIOFormat;
use Combodo\iTop\Forms\IO\Format\BooleanIOFormat;
use Combodo\iTop\Forms\IO\Format\ClassIOFormat;
use Combodo\iTop\Forms\IO\Format\NumberIOFormat;
use Combodo\iTop\Forms\IO\Format\RawFormat;
use Combodo\iTop\Forms\IO\FormBinding;
use Combodo\iTop\Forms\IO\FormBlockIOException;
use Combodo\iTop\Test\UnitTest\sources\Forms\AbstractFormsTest;
@@ -148,6 +153,84 @@ class FormBindingTest extends AbstractFormsTest
// Then
$this->assertEquals('The Value', $oOutputIO1->GetValue(FormEvents::PRE_SET_DATA));
}
/**
* @dataProvider BindingIncompatibleFormatsProvider
*
* @param string $sSourceFormat
* @param string $sDestinationFormat
*
* @return void
*/
public function testBindingIncompatibleFormatsThrowsException(string $sSourceFormat, string $sDestinationFormat)
{
$oOutputIO = $this->GivenOutput('test', $sSourceFormat);
$oInputIO = $this->GivenInput('test', $sDestinationFormat);
$this->expectException(FormBlockIOException::class);
$oOutputIO->BindToInput($oInputIO);
}
public function BindingIncompatibleFormatsProvider(): array
{
return [
'Attribute -> Boolean' => [AttributeIOFormat::class, BooleanIOFormat::class],
'Attribute -> Class' => [AttributeIOFormat::class, ClassIOFormat::class],
'Attribute -> Number' => [AttributeIOFormat::class, NumberIOFormat::class],
'Boolean => Attribute' => [BooleanIOFormat::class, AttributeIOFormat::class],
'Boolean => Class' => [BooleanIOFormat::class, ClassIOFormat::class],
'Boolean => Number' => [BooleanIOFormat::class, NumberIOFormat::class],
'Class => Attribute' => [ClassIOFormat::class, AttributeIOFormat::class],
'Class => Boolean' => [ClassIOFormat::class, BooleanIOFormat::class],
'Class => Number' => [ClassIOFormat::class, NumberIOFormat::class],
'Number => Attribute' => [NumberIOFormat::class, AttributeIOFormat::class],
'Number => Class' => [NumberIOFormat::class, ClassIOFormat::class],
'Number => Boolean' => [NumberIOFormat::class, BooleanIOFormat::class],
];
}
/**
* @dataProvider BindingCompatibleFormatsProvider
*
* @param string $sSourceFormat
* @param string $sDestinationFormat
*
* @return void
*/
public function testBindingCompatibleFormatsWorks(string $sSourceFormat, string $sDestinationFormat)
{
$oOutputIO = $this->GivenOutput('test', $sSourceFormat);
$oInputIO = $this->GivenInput('test', $sDestinationFormat);
$oBinding = $oOutputIO->BindToInput($oInputIO);
$this->assertTrue(is_a($oBinding, FormBinding::class));
}
public function BindingCompatibleFormatsProvider(): array
{
return [
'Attribute -> Attribute' => [AttributeIOFormat::class, AttributeIOFormat::class],
'Attribute -> Raw' => [AttributeIOFormat::class, RawFormat::class],
'Boolean => Boolean' => [BooleanIOFormat::class, BooleanIOFormat::class],
'Boolean => Raw' => [BooleanIOFormat::class, RawFormat::class],
'Class => Class' => [ClassIOFormat::class, ClassIOFormat::class],
'Class => Raw' => [ClassIOFormat::class, RawFormat::class],
'Number => Number' => [NumberIOFormat::class, NumberIOFormat::class],
'Number => Raw' => [NumberIOFormat::class, RawFormat::class],
'Raw => Raw' => [RawFormat::class, RawFormat::class],
'Raw => Attribute' => [RawFormat::class, AttributeIOFormat::class],
'Raw => Boolean' => [RawFormat::class, BooleanIOFormat::class],
'Raw => Class' => [RawFormat::class, ClassIOFormat::class],
'Raw => Number' => [RawFormat::class, NumberIOFormat::class],
];
}
}