mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-07-24 22:34:25 +02:00
ExtensibleSet: basic implementation & tests
This commit is contained in:
parent
40d2e9f120
commit
23dd4721ec
199
library/Director/IcingaConfig/ExtensibleSet.php
Normal file
199
library/Director/IcingaConfig/ExtensibleSet.php
Normal file
@ -0,0 +1,199 @@
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\IcingaConfig;
|
||||
|
||||
use Icinga\Exception\InvalidPropertyException;
|
||||
|
||||
class ExtensibleSet
|
||||
{
|
||||
protected $ownValues;
|
||||
|
||||
protected $plusValues = array();
|
||||
|
||||
protected $minusValues = array();
|
||||
|
||||
protected $resolvedValues;
|
||||
|
||||
protected $allowedValues;
|
||||
|
||||
protected $inheritedValues = array();
|
||||
|
||||
public function __construct($values = null)
|
||||
{
|
||||
if (null !== $values) {
|
||||
$this->override($values);
|
||||
}
|
||||
}
|
||||
|
||||
public function override($values)
|
||||
{
|
||||
$this->ownValues = array();
|
||||
$this->inheritedValues = array();
|
||||
|
||||
$this->addValuesTo($this->ownValues, $values);
|
||||
|
||||
return $this->addResolvedValues($values);
|
||||
}
|
||||
|
||||
public function extend($values)
|
||||
{
|
||||
$this->addValuesTo($this->plusValues, $values);
|
||||
return $this->addResolvedValues($values);
|
||||
}
|
||||
|
||||
public function blacklist($values)
|
||||
{
|
||||
$this->addValuesTo($this->minusValues, $values);
|
||||
|
||||
if ($this->hasBeenResolved()) {
|
||||
$this->removeValuesFrom($this->resolvedValues, $values);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getResolvedValues()
|
||||
{
|
||||
if (! $this->hasBeenResolved()) {
|
||||
$this->recalculate();
|
||||
}
|
||||
|
||||
sort($this->resolvedValues);
|
||||
|
||||
return $this->resolvedValues;
|
||||
}
|
||||
|
||||
protected function hasBeenResolved()
|
||||
{
|
||||
return $this->resolvedValues !== null;
|
||||
}
|
||||
|
||||
public function inheritFrom(ExtensibleSet $parent)
|
||||
{
|
||||
if ($this->ownValues !== null) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->hasBeenResolved()) {
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
$this->inheritedValues = array();
|
||||
|
||||
$this->addValuesTo(
|
||||
$this->inheritedValues,
|
||||
$this->stripBlacklistedValues($parent->getResolvedValues())
|
||||
);
|
||||
|
||||
return $this->recalculate();
|
||||
}
|
||||
|
||||
protected function stripBlacklistedValues($array)
|
||||
{
|
||||
$this->removeValuesFrom($array, $this->minusValues);
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
public function forgetInheritedValues()
|
||||
{
|
||||
$this->inheritedValues = array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function assertValidValue($value)
|
||||
{
|
||||
if (null === $this->allowedValues) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (in_array($value, $this->allowedValues)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new InvalidPropertyException(
|
||||
'Got invalid property "%s", allowed are: (%s)',
|
||||
$value,
|
||||
implode(', ', $this->allowedValues)
|
||||
);
|
||||
}
|
||||
|
||||
protected function addValuesTo(&$array, $values)
|
||||
{
|
||||
foreach ($this->wantArray($values) as $value) {
|
||||
$this->addTo($array, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function addResolvedValues($values)
|
||||
{
|
||||
if (! $this->hasBeenResolved()) {
|
||||
$this->resolvedValues = array();
|
||||
}
|
||||
|
||||
return $this->addValuesTo(
|
||||
$this->resolvedValues,
|
||||
$this->stripBlacklistedValues($this->wantArray($values))
|
||||
);
|
||||
}
|
||||
|
||||
protected function removeValuesFrom(&$array, $values)
|
||||
{
|
||||
foreach ($this->wantArray($values) as $value) {
|
||||
$this->removeFrom($array, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function addTo(&$array, $value)
|
||||
{
|
||||
if (! in_array($value, $array)) {
|
||||
$this->assertValidValue($value);
|
||||
$array[] = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function removeFrom(&$array, $value)
|
||||
{
|
||||
if (false !== ($pos = array_search($value, $array))) {
|
||||
unset($array[$pos]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function recalculate()
|
||||
{
|
||||
$this->resolvedValues = array();
|
||||
if ($this->ownValues === null) {
|
||||
$this->addValuesTo($this->resolvedValues, $this->inheritedValues);
|
||||
} else {
|
||||
$this->addValuesTo($this->resolvedValues, $this->ownValues);
|
||||
}
|
||||
$this->addValuesTo($this->resolvedValues, $this->plusValues);
|
||||
$this->removeFrom($this->resolvedValues, $this->minusValues);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function reset()
|
||||
{
|
||||
$this->resolvedValues = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function wantArray($values)
|
||||
{
|
||||
if (is_array($values)) {
|
||||
return $values;
|
||||
}
|
||||
|
||||
return array($values);
|
||||
}
|
||||
}
|
135
test/php/library/Director/IcingaConfig/ExtensibleSetTest.php
Normal file
135
test/php/library/Director/IcingaConfig/ExtensibleSetTest.php
Normal file
@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Icinga\Module\Director\IcingaConfig;
|
||||
|
||||
use Icinga\Module\Director\IcingaConfig\ExtensibleSet;
|
||||
use Icinga\Module\Director\Test\BaseTestCase;
|
||||
|
||||
class ExtensibleSetTest extends BaseTestCase
|
||||
{
|
||||
public function testNoValuesResultInEmptySet()
|
||||
{
|
||||
$set = new ExtensibleSet();
|
||||
|
||||
$this->assertEquals(
|
||||
array(),
|
||||
$set->getResolvedValues()
|
||||
);
|
||||
}
|
||||
|
||||
public function testValuesPassedToConstructorAreAccepted()
|
||||
{
|
||||
$values = array('Val1', 'Val2', 'Val4');
|
||||
$set = new ExtensibleSet($values);
|
||||
|
||||
$this->assertEquals(
|
||||
$values,
|
||||
$set->getResolvedValues()
|
||||
);
|
||||
}
|
||||
|
||||
public function testSingleValuesCanBeBlacklisted()
|
||||
{
|
||||
$values = array('Val1', 'Val2', 'Val4');
|
||||
$set = new ExtensibleSet($values);
|
||||
$set->blacklist('Val2');
|
||||
|
||||
$this->assertEquals(
|
||||
array('Val1', 'Val4'),
|
||||
$set->getResolvedValues()
|
||||
);
|
||||
}
|
||||
|
||||
public function testMultipleValuesCanBeBlacklisted()
|
||||
{
|
||||
$values = array('Val1', 'Val2', 'Val4');
|
||||
$set = new ExtensibleSet($values);
|
||||
$set->blacklist(array('Val4', 'Val1'));
|
||||
|
||||
$this->assertEquals(
|
||||
array('Val2'),
|
||||
$set->getResolvedValues()
|
||||
);
|
||||
}
|
||||
|
||||
public function testSimpleInheritanceWorksFine()
|
||||
{
|
||||
$values = array('Val1', 'Val2', 'Val4');
|
||||
$parent = new ExtensibleSet($values);
|
||||
$child = new ExtensibleSet();
|
||||
$child->inheritFrom($parent);
|
||||
|
||||
$this->assertEquals(
|
||||
$values,
|
||||
$child->getResolvedValues()
|
||||
);
|
||||
}
|
||||
|
||||
public function testWeCanInheritFromMultipleParents()
|
||||
{
|
||||
$p1set = array('p1a', 'p1c');
|
||||
$p2set = array('p2a', 'p2d');
|
||||
$parent1 = new ExtensibleSet($p1set);
|
||||
$parent2 = new ExtensibleSet($p2set);
|
||||
$child = new ExtensibleSet();
|
||||
$child->inheritFrom($parent1)->inheritFrom($parent2);
|
||||
|
||||
$this->assertEquals(
|
||||
$p2set,
|
||||
$child->getResolvedValues()
|
||||
);
|
||||
}
|
||||
|
||||
public function testOwnValuesOverrideParents()
|
||||
{
|
||||
$cset = array('p1a', 'p1c');
|
||||
$pset = array('p2a', 'p2d');
|
||||
$child = new ExtensibleSet($cset);
|
||||
$parent = new ExtensibleSet($pset);
|
||||
$child->inheritFrom($parent);
|
||||
|
||||
$this->assertEquals(
|
||||
$cset,
|
||||
$child->getResolvedValues()
|
||||
);
|
||||
}
|
||||
|
||||
public function testInheritedValuesCanBeBlacklisted()
|
||||
{
|
||||
$pset = array('p1', 'p2', 'p3');
|
||||
|
||||
$child = new ExtensibleSet();
|
||||
$child->blacklist('p2');
|
||||
|
||||
$parent = new ExtensibleSet($pset);
|
||||
$child->inheritFrom($parent);
|
||||
$child->blacklist(array('not', 'yet', 'p1'));
|
||||
|
||||
$this->assertEquals(
|
||||
array('p3'),
|
||||
$child->getResolvedValues()
|
||||
);
|
||||
|
||||
$child->blacklist(array('p3'));
|
||||
$this->assertEquals(
|
||||
array(),
|
||||
$child->getResolvedValues()
|
||||
);
|
||||
}
|
||||
|
||||
public function testInheritedValuesCanBeExtended()
|
||||
{
|
||||
$pset = array('p1', 'p2', 'p3');
|
||||
|
||||
$child = new ExtensibleSet();
|
||||
$child->extend('p5');
|
||||
|
||||
$parent = new ExtensibleSet($pset);
|
||||
$child->inheritFrom($parent);
|
||||
|
||||
$this->assertEquals(
|
||||
array('p1', 'p2', 'p3', 'p5'),
|
||||
$child->getResolvedValues()
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user