mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-01 06:28:46 +02:00
N°8772 - Form dependencies manager implementation
- Form SDK implementation - Basic Forms - Dynamics Forms - Basic Blocks + Data Model Block - Form Compilation - Turbo integration
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\sources\Forms\IO;
|
||||
|
||||
use Combodo\iTop\Forms\IO\FormBlockIOException;
|
||||
use Combodo\iTop\Test\UnitTest\sources\Forms\AbstractFormsTest;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
|
||||
class AbstractFormIOTest extends AbstractFormsTest
|
||||
{
|
||||
public function testFormIoHasNoDataAtCreation()
|
||||
{
|
||||
|
||||
$oInput = $this->GivenInput('test');
|
||||
|
||||
$this->assertFalse($oInput->IsDataReady(), 'Created Input must no have data ready at creation');
|
||||
$this->assertFalse($oInput->HasValue(), 'Created Input must no have value at creation');
|
||||
$this->assertFalse($oInput->HasBindingOut());
|
||||
|
||||
$oOutput = $this->GivenOutput('test');
|
||||
|
||||
$this->assertFalse($oOutput->IsDataReady(), 'Created output must no have data ready at creation');
|
||||
$this->assertFalse($oOutput->HasValue(), 'Created output must no have value at creation');
|
||||
$this->assertFalse($oOutput->HasBindingOut());
|
||||
}
|
||||
|
||||
public function testFormIoHasDataAfterSetValue()
|
||||
{
|
||||
|
||||
$oInput = $this->GivenInput('test');
|
||||
$oInput->SetValue(FormEvents::POST_SET_DATA, 'test');
|
||||
|
||||
$this->assertTrue($oInput->IsDataReady(), 'Input must have data ready when set');
|
||||
$this->assertTrue($oInput->HasValue(), 'Input must have value when set');
|
||||
|
||||
$oOutput = $this->GivenOutput('test');
|
||||
$oOutput->SetValue(FormEvents::POST_SET_DATA, 'test');
|
||||
|
||||
$this->assertTrue($oOutput->IsDataReady(), 'Output must have data ready when set');
|
||||
$this->assertTrue($oOutput->HasValue(), 'Output must have value when set');
|
||||
}
|
||||
|
||||
public function testIOValueReflectsTheValuePostedOrTheValueSet()
|
||||
{
|
||||
$oInput = $this->GivenInput('test');
|
||||
|
||||
// When
|
||||
$oInput->SetValue(FormEvents::POST_SET_DATA, 'The value set');
|
||||
|
||||
// Then
|
||||
$this->assertEquals('The value set', $oInput->GetValue());
|
||||
|
||||
// When
|
||||
$oInput->SetValue(FormEvents::POST_SUBMIT, 'The value posted');
|
||||
|
||||
// Then
|
||||
$this->assertEquals('The value posted', $oInput->GetValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider NameFormatSupportsOnlyLettersUnderscoreAndNumbersProvider
|
||||
* @return void
|
||||
* @throws \Combodo\iTop\Forms\IO\FormBlockIOException
|
||||
*/
|
||||
public function testNameFormatSupportsOnlyLettersUnderscoreAndNumbersAndDot(string $sName, bool $bGenerateException = true)
|
||||
{
|
||||
|
||||
if ($bGenerateException) {
|
||||
$this->expectException(FormBlockIOException::class);
|
||||
}
|
||||
$oInput = $this->GivenInput($sName);
|
||||
if (!$bGenerateException) {
|
||||
$this->assertEquals($sName, $oInput->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
public function NameFormatSupportsOnlyLettersUnderscoreAndNumbersProvider()
|
||||
{
|
||||
return [
|
||||
// Incorrects
|
||||
'Spaces not supported' => ['The test name'],
|
||||
'Minus not supported' => ['The-test-name'],
|
||||
'Percent not supported' => ['name%'],
|
||||
'Accent not supported' => ['namé'],
|
||||
'emoji not supported' => ['🎄🎄🎄🎄🎄'],
|
||||
'.name not supported' => ['.name'],
|
||||
'name. not supported' => ['name.'],
|
||||
|
||||
// Corrects
|
||||
'Numbers OK' => ['name123', false],
|
||||
'Starting with number OK' => ['123name123', false],
|
||||
'Underscore OK' => ['The_test_name', false],
|
||||
'Camel OK' => ['TheTestName', false],
|
||||
'name.subname OK' => ['name.subname', false],
|
||||
];
|
||||
}
|
||||
|
||||
public function testCreatingIOWithUnknownFormatThrowsException()
|
||||
{
|
||||
$this->expectException(FormBlockIOException::class);
|
||||
$oInput = $this->GivenInput('test', 'test_toto');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Sources\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\StringIOFormat;
|
||||
use Combodo\iTop\Forms\IO\FormBinding;
|
||||
use Combodo\iTop\Forms\IO\FormBlockIOException;
|
||||
use Combodo\iTop\Test\UnitTest\sources\Forms\AbstractFormsTest;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class FormBindingTest extends AbstractFormsTest
|
||||
{
|
||||
public function testCreatingABinding()
|
||||
{
|
||||
$oInputIO = $this->GivenInput('test');
|
||||
$oOutputIO = $this->GivenOutput('test');
|
||||
|
||||
// When Linking output to input
|
||||
new FormBinding($oOutputIO, $oInputIO);
|
||||
|
||||
// Then
|
||||
$this->assertTrue($oInputIO->IsBound(), 'DestinationIO must be Bound when creating a new binding');
|
||||
}
|
||||
|
||||
public function testBindingTwiceToTheSameInputIsNotPossible()
|
||||
{
|
||||
$oInputIO = $this->GivenInput('test');
|
||||
$oOutputIO1 = $this->GivenOutput('test1');
|
||||
$oOutputIO2 = $this->GivenOutput('test2');
|
||||
|
||||
// When
|
||||
new FormBinding($oOutputIO1, $oInputIO);
|
||||
|
||||
// Then
|
||||
$this->expectException(FormBlockIOException::class);
|
||||
new FormBinding($oOutputIO2, $oInputIO);
|
||||
}
|
||||
|
||||
public function testBindingTwiceToTheSameOutputIsNotPossible()
|
||||
{
|
||||
$oOutputIO1 = $this->GivenOutput('test1');
|
||||
$oOutputIO2 = $this->GivenOutput('test2');
|
||||
$oOutputIO3 = $this->GivenOutput('test3');
|
||||
|
||||
// When
|
||||
new FormBinding($oOutputIO1, $oOutputIO3);
|
||||
|
||||
// Then
|
||||
$this->expectException(FormBlockIOException::class);
|
||||
new FormBinding($oOutputIO2, $oOutputIO3);
|
||||
|
||||
}
|
||||
|
||||
public function testOutputCanBeBoundToInputAndInputIsBoundAfterThat()
|
||||
{
|
||||
$oInputIO = $this->GivenInput('test');
|
||||
$oOutputIO = $this->GivenOutput('test1');
|
||||
|
||||
$this->assertFalse($oInputIO->IsBound(), 'Input must not be Bound by default');
|
||||
|
||||
// When
|
||||
$oOutputIO->BindToInput($oInputIO);
|
||||
|
||||
// Then
|
||||
$this->assertTrue($oInputIO->IsBound(), 'Input must be Bound when binding from an output');
|
||||
}
|
||||
|
||||
public function testInputCanBeBoundToAnotherInputAndItIsBoundAfterThat()
|
||||
{
|
||||
$oInputIO1 = $this->GivenInput('test1');
|
||||
$oInputIO2 = $this->GivenInput('test2');
|
||||
|
||||
// When
|
||||
$oInputIO1->BindToInput($oInputIO2);
|
||||
|
||||
// Then
|
||||
$this->assertTrue($oInputIO2->IsBound(), 'Input must be Bound when binding from an input');
|
||||
}
|
||||
|
||||
public function testOutputCanBeBoundToAnotherOutputAndItIsBoundAfterThat()
|
||||
{
|
||||
$oOutputIO1 = $this->GivenOutput('test1');
|
||||
$oOutputIO2 = $this->GivenOutput('test2');
|
||||
|
||||
$this->assertFalse($oOutputIO2->IsBound(), 'Output must not be bound by default');
|
||||
|
||||
// When
|
||||
$oOutputIO1->BindToOutput($oOutputIO2);
|
||||
|
||||
// Then
|
||||
$this->assertTrue($oOutputIO2->IsBound(), 'Output must be Bound when binding from an output');
|
||||
}
|
||||
|
||||
public function testOutBindingsAreStoredWhenBindToInput()
|
||||
{
|
||||
$oInputIO1 = $this->GivenInput('test1');
|
||||
$oInputIO2 = $this->GivenInput('test2');
|
||||
$oOutputIO1 = $this->GivenOutput('test1');
|
||||
|
||||
// When
|
||||
$oBindingO2ToI1 = $oOutputIO1->BindToInput($oInputIO1);
|
||||
|
||||
// Then
|
||||
$this->assertTrue($oOutputIO1->HasBindingOut(), 'Must have bindings after BindToInput');
|
||||
$this->assertEquals([$oBindingO2ToI1], $oOutputIO1->GetBindingsToInputs(), 'Must have bindings after BindToInput');
|
||||
|
||||
// When
|
||||
$oBindingO1ToI2 = $oOutputIO1->BindToInput($oInputIO2);
|
||||
|
||||
// Then
|
||||
$this->assertEquals([$oBindingO2ToI1, $oBindingO1ToI2], $oOutputIO1->GetBindingsToInputs(), 'Must have bindings after BindToInput');
|
||||
}
|
||||
|
||||
public function testOutBindingsAreStoredWhenBindToOutput()
|
||||
{
|
||||
$oOutputIO1 = $this->GivenOutput('test1');
|
||||
$oOutputIO2 = $this->GivenOutput('test2');
|
||||
$oOutputIO3 = $this->GivenOutput('test3');
|
||||
|
||||
// When
|
||||
$oBindingO1ToO2 = $oOutputIO1->BindToOutput($oOutputIO2);
|
||||
|
||||
// Then
|
||||
$this->assertTrue($oOutputIO1->HasBindingOut(), 'Must have bindings after BindToInput');
|
||||
$this->assertEquals([$oBindingO1ToO2], $oOutputIO1->GetBindingsToOutputs(), 'Must have bindings after BindToOutput');
|
||||
|
||||
// When
|
||||
$oBindingO1ToO3 = $oOutputIO1->BindToOutput($oOutputIO3);
|
||||
|
||||
// Then
|
||||
$this->assertEquals([$oBindingO1ToO2, $oBindingO1ToO3], $oOutputIO1->GetBindingsToOutputs(), 'Must have bindings after BindToOutput');
|
||||
}
|
||||
|
||||
public function testSourceValueIsPropagatedToDestIO()
|
||||
{
|
||||
$oOutputIO1 = $this->GivenOutput('test1');
|
||||
$oInputIO1 = $this->GivenInput('test1');
|
||||
$oBinding = $oOutputIO1->BindToInput($oInputIO1);
|
||||
$oOutputIO1->SetValue(FormEvents::PRE_SET_DATA, 'The Value');
|
||||
|
||||
// When
|
||||
$oBinding->PropagateValues();
|
||||
|
||||
// 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],
|
||||
'Attribute -> String' => [AttributeIOFormat::class, StringIOFormat::class],
|
||||
|
||||
'Boolean => Attribute' => [BooleanIOFormat::class, AttributeIOFormat::class],
|
||||
'Boolean => Class' => [BooleanIOFormat::class, ClassIOFormat::class],
|
||||
'Boolean => Number' => [BooleanIOFormat::class, NumberIOFormat::class],
|
||||
'Boolean -> String' => [BooleanIOFormat::class, StringIOFormat::class],
|
||||
|
||||
'Class => Attribute' => [ClassIOFormat::class, AttributeIOFormat::class],
|
||||
'Class => Boolean' => [ClassIOFormat::class, BooleanIOFormat::class],
|
||||
'Class => Number' => [ClassIOFormat::class, NumberIOFormat::class],
|
||||
'Class -> String' => [ClassIOFormat::class, StringIOFormat::class],
|
||||
|
||||
'Number => Attribute' => [NumberIOFormat::class, AttributeIOFormat::class],
|
||||
'Number => Class' => [NumberIOFormat::class, ClassIOFormat::class],
|
||||
'Number => Boolean' => [NumberIOFormat::class, BooleanIOFormat::class],
|
||||
'Number -> String' => [NumberIOFormat::class, StringIOFormat::class],
|
||||
|
||||
'String => Attribute' => [StringIOFormat::class, AttributeIOFormat::class],
|
||||
'String => Class' => [StringIOFormat::class, ClassIOFormat::class],
|
||||
'String => Boolean' => [StringIOFormat::class, BooleanIOFormat::class],
|
||||
'String -> Number' => [StringIOFormat::class, NumberIOFormat::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],
|
||||
'Boolean => Boolean' => [BooleanIOFormat::class, BooleanIOFormat::class],
|
||||
'Class => Class' => [ClassIOFormat::class, ClassIOFormat::class],
|
||||
'Number => Number' => [NumberIOFormat::class, NumberIOFormat::class],
|
||||
'String => String' => [StringIOFormat::class, StringIOFormat::class],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\sources\Forms\IO\Format;
|
||||
|
||||
use Combodo\iTop\Forms\IO\Format\AttributeIOFormat;
|
||||
use Combodo\iTop\Test\UnitTest\sources\Forms\AbstractFormsTest;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
|
||||
class TestAttributeIOFormat extends AbstractFormsTest
|
||||
{
|
||||
public function testAttributeIOIsAString()
|
||||
{
|
||||
$oInputIO = $this->GivenInput('test', AttributeIOFormat::class);
|
||||
$oInputIO->SetValue(FormEvents::POST_SUBMIT, 'name');
|
||||
|
||||
$this->assertEquals('name', $oInputIO->GetValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\sources\Forms\IO\Format;
|
||||
|
||||
use Combodo\iTop\Forms\IO\Format\BooleanIOFormat;
|
||||
use Combodo\iTop\Test\UnitTest\sources\Forms\AbstractFormsTest;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
|
||||
class TestBooleanIOFormat extends AbstractFormsTest
|
||||
{
|
||||
public function testBooleanIOFormatIsABoolean()
|
||||
{
|
||||
$oInputIO = $this->GivenInput('test', BooleanIOFormat::class);
|
||||
|
||||
$oInputIO->SetValue(FormEvents::POST_SUBMIT, 'true');
|
||||
|
||||
$this->assertEquals(true, $oInputIO->GetValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\sources\Forms\IO\Format;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\sources\Forms\AbstractFormsTest;
|
||||
|
||||
class TestClassIOFormat extends AbstractFormsTest
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\sources\Forms\IO\Format;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\sources\Forms\AbstractFormsTest;
|
||||
|
||||
class TestNumberIOFormat extends AbstractFormsTest
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user