diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:44:46 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:44:46 +0000 |
commit | b18bc644404e02b57635bfcc8258e85abb141146 (patch) | |
tree | 686512eacb2dba0055277ef7ec2f28695b3418ea /test/php/library/Icingadb/Util | |
parent | Initial commit. (diff) | |
download | icingadb-web-b18bc644404e02b57635bfcc8258e85abb141146.tar.xz icingadb-web-b18bc644404e02b57635bfcc8258e85abb141146.zip |
Adding upstream version 1.1.1.upstream/1.1.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | test/php/library/Icingadb/Util/PerfdataSetTest.php | 120 | ||||
-rw-r--r-- | test/php/library/Icingadb/Util/PerfdataTest.php | 591 | ||||
-rw-r--r-- | test/php/library/Icingadb/Util/ThresholdRangeTest.php | 343 |
3 files changed, 1054 insertions, 0 deletions
diff --git a/test/php/library/Icingadb/Util/PerfdataSetTest.php b/test/php/library/Icingadb/Util/PerfdataSetTest.php new file mode 100644 index 0000000..618c29a --- /dev/null +++ b/test/php/library/Icingadb/Util/PerfdataSetTest.php @@ -0,0 +1,120 @@ +<?php + +/* Icinga DB Web | (c) 2023 Icinga GmbH | GPLv2 */ + +namespace Tests\Icinga\Module\Icingadb\Util; + +use Icinga\Module\Icingadb\Util\PerfDataSet; +use PHPUnit\Framework\TestCase; +use Tests\Icinga\Module\Icingadb\Lib\PerfdataSetWithPublicData; + +class PerfdataSetTest extends TestCase +{ + public function testWhetherValidSimplePerfdataLabelsAreProperlyParsed() + { + $pset = PerfdataSetWithPublicData::fromString('key1=val1 key2=val2 key3 =val3'); + $this->assertSame( + 'key1', + $pset->perfdata[0]->getLabel(), + 'PerfdataSet does not correctly parse valid simple labels' + ); + $this->assertSame( + 'key2', + $pset->perfdata[1]->getLabel(), + 'PerfdataSet does not correctly parse valid simple labels' + ); + $this->assertSame( + 'key3', + $pset->perfdata[2]->getLabel(), + 'PerfdataSet does not correctly parse valid simple labels' + ); + } + + public function testWhetherNonQuotedPerfdataLablesWithSpacesAreProperlyParsed() + { + $pset = PerfdataSetWithPublicData::fromString('key 1=val1 key 1 + 1=val2'); + $this->assertSame( + 'key 1', + $pset->perfdata[0]->getLabel(), + 'PerfdataSet does not correctly parse non quoted labels with spaces' + ); + $this->assertSame( + 'key 1 + 1', + $pset->perfdata[1]->getLabel(), + 'PerfdataSet does not correctly parse non quoted labels with spaces' + ); + } + + public function testWhetherValidQuotedPerfdataLabelsAreProperlyParsed() + { + $pset = PerfdataSetWithPublicData::fromString('\'key 1\'=val1 "key 2"=val2 \'a=b\'=0%;;2'); + $this->assertSame( + 'key 1', + $pset->perfdata[0]->getLabel(), + 'PerfdataSet does not correctly parse valid quoted labels' + ); + $this->assertSame( + 'key 2', + $pset->perfdata[1]->getLabel(), + 'PerfdataSet does not correctly parse valid quoted labels' + ); + $this->assertSame( + 'a=b', + $pset->perfdata[2]->getLabel(), + 'PerfdataSet does not correctly parse labels with equal signs' + ); + } + + public function testWhetherInvalidQuotedPerfdataLabelsAreProperlyParsed() + { + $pset = PerfdataSetWithPublicData::fromString('\'key 1=1 key 2"=2'); + $this->assertSame( + 'key 1', + $pset->perfdata[0]->getLabel(), + 'PerfdataSet does not correctly parse invalid quoted labels' + ); + $this->assertSame( + 'key 2"', + $pset->perfdata[1]->getLabel(), + 'PerfdataSet does not correctly parse invalid quoted labels' + ); + $pset = PerfdataSetWithPublicData::fromString('"key 1=1 "key 2"=2'); + $this->assertSame( + 'key 1=1', + $pset->perfdata[0]->getLabel(), + 'PerfdataSet does not correctly parse invalid quoted labels' + ); + $this->assertNull( + $pset->perfdata[0]->getValue() + ); + $this->assertSame( + '2"', + $pset->perfdata[1]->getLabel(), + 'PerfdataSet does not correctly parse invalid quoted labels' + ); + $this->assertSame( + 2.0, + $pset->perfdata[1]->getValue() + ); + } + + /** + * @depends testWhetherValidSimplePerfdataLabelsAreProperlyParsed + */ + public function testWhetherAPerfdataSetIsIterable() + { + $pset = PerfdataSet::fromString('key=value'); + foreach ($pset as $p) { + $this->assertSame('key', $p->getLabel()); + return; + } + + $this->fail('PerfdataSet objects cannot be iterated'); + } + + public function testWhetherPerfdataSetsCanBeInitializedWithEmptyStrings() + { + $pset = PerfdataSetWithPublicData::fromString(''); + $this->assertEmpty($pset->perfdata, 'PerfdataSet::fromString does not accept emtpy strings'); + } +} diff --git a/test/php/library/Icingadb/Util/PerfdataTest.php b/test/php/library/Icingadb/Util/PerfdataTest.php new file mode 100644 index 0000000..5a63825 --- /dev/null +++ b/test/php/library/Icingadb/Util/PerfdataTest.php @@ -0,0 +1,591 @@ +<?php + +/* Icinga DB Web | (c) 2023 Icinga GmbH | GPLv2 */ + +namespace Tests\Icinga\Module\Icingadb\Util; + +use Icinga\Module\Icingadb\Util\PerfData; +use PHPUnit\Framework\TestCase; + +class PerfdataTest extends TestCase +{ + public function testWhetherFromStringThrowsExceptionWhenGivenAnEmptyString() + { + $this->expectException(\InvalidArgumentException::class); + + Perfdata::fromString(''); + } + + public function testWhetherFromStringThrowsExceptionWhenGivenAnInvalidString() + { + $this->expectException(\InvalidArgumentException::class); + + Perfdata::fromString('test'); + } + + public function testWhetherFromStringParsesAGivenStringCorrectly() + { + $p = Perfdata::fromString('key=1234'); + $this->assertSame( + 'key', + $p->getLabel(), + 'Perfdata::fromString does not properly parse performance data labels' + ); + $this->assertSame( + 1234.0, + $p->getValue(), + 'Perfdata::fromString does not properly parse performance data values' + ); + } + + /** + * @depends testWhetherFromStringParsesAGivenStringCorrectly + */ + public function testWhetherGetValueReturnsValidValues() + { + $this->assertSame( + 1337.0, + Perfdata::fromString('test=1337')->getValue(), + 'Perfdata::getValue does not return correct values' + ); + $this->assertSame( + 1337.0, + Perfdata::fromString('test=1337;;;;')->getValue(), + 'Perfdata::getValue does not return correct values' + ); + } + + /** + * @depends testWhetherFromStringParsesAGivenStringCorrectly + */ + public function testWhetherDecimalValuesAreCorrectlyParsed() + { + $this->assertSame( + 1337.5, + Perfdata::fromString('test=1337.5')->getValue(), + 'Perfdata objects do not parse decimal values correctly' + ); + $this->assertSame( + 1337.5, + Perfdata::fromString('test=1337.5B')->getValue(), + 'Perfdata objects do not parse decimal values correctly' + ); + } + + /** + * @depends testWhetherFromStringParsesAGivenStringCorrectly + */ + public function testWhetherGetValueReturnsNullForInvalidOrUnknownValues() + { + $this->assertNull( + Perfdata::fromString('test=U')->getValue(), + 'Perfdata::getValue does not return null for unknown values' + ); + $this->assertNull( + Perfdata::fromString('test=i am not a value')->getValue(), + 'Perfdata::getValue does not return null for invalid values' + ); + $this->assertNull( + PerfData::fromString('test=')->getValue(), + 'Perfdata::getValue does not return null for invalid values' + ); + $this->assertNull( + PerfData::fromString('test=-kW')->getValue(), + 'Perfdata::getValue does not return null for invalid values' + ); + $this->assertNull( + PerfData::fromString('test=kW')->getValue(), + 'Perfdata::getValue does not return null for invalid values' + ); + $this->assertNull( + PerfData::fromString('test=-')->getValue(), + 'Perfdata::getValue does not return null for invalid values' + ); + } + + /** + * @depends testWhetherFromStringParsesAGivenStringCorrectly + */ + public function testWhetherUnitOfUnkownValuesIsCorrectlyIdentified() + { + $this->assertNull( + Perfdata::fromString('test=U')->getUnit(), + 'Perfdata::getUnit does not return null for unknown values' + ); + $this->assertNull( + Perfdata::fromString('test=i am not a value')->getUnit(), + 'Perfdata::getUnit does not return null for unknown values' + ); + $this->assertNull( + PerfData::fromString('test=')->getUnit(), + 'Perfdata::getUnit does not return null for unknown values' + ); + $this->assertSame( + 'kW', + PerfData::fromString('test=-kW')->getUnit(), + 'Perfdata::getUnit does not return correct unit for invalid values' + ); + $this->assertSame( + 'kW', + PerfData::fromString('test=kW')->getUnit(), + 'Perfdata::getUnit does not return correct unit for invalid values' + ); + $this->assertNull( + PerfData::fromString('test=-')->getUnit(), + 'Perfdata::getUnit does not return null for unknown values' + ); + } + + /** + * @depends testWhetherFromStringParsesAGivenStringCorrectly + */ + public function testWhethergetWarningThresholdReturnsCorrectValues() + { + $zeroToTen = Perfdata::fromString('test=1;10')->getWarningThreshold(); + $this->assertSame( + 0.0, + $zeroToTen->getMin(), + 'Perfdata::getWarningThreshold does not return correct values' + ); + $this->assertSame( + 10.0, + $zeroToTen->getMax(), + 'Perfdata::getWarningThreshold does not return correct values' + ); + $tenToInfinity = Perfdata::fromString('test=1;10:')->getWarningThreshold(); + $this->assertSame( + 10.0, + $tenToInfinity->getMin(), + 'Perfdata::getWarningThreshold does not return correct values' + ); + $this->assertNull( + $tenToInfinity->getMax(), + 'Perfdata::getWarningThreshold does not return correct values' + ); + $infinityToTen = Perfdata::fromString('test=1;~:10')->getWarningThreshold(); + $this->assertNull( + $infinityToTen->getMin(), + 'Perfdata::getWarningThreshold does not return correct values' + ); + $this->assertSame( + 10.0, + $infinityToTen->getMax(), + 'Perfdata::getWarningThreshold does not return correct values' + ); + $tenToTwenty = Perfdata::fromString('test=1;10:20')->getWarningThreshold(); + $this->assertSame( + 10.0, + $tenToTwenty->getMin(), + 'Perfdata::getWarningThreshold does not return correct values' + ); + $this->assertSame( + 20.0, + $tenToTwenty->getMax(), + 'Perfdata::getWarningThreshold does not return correct values' + ); + $tenToTwentyInverted = Perfdata::fromString('test=1;@10:20')->getWarningThreshold(); + $this->assertTrue( + $tenToTwentyInverted->isInverted(), + 'Perfdata::getWarningThreshold does not return correct values' + ); + } + + /** + * @depends testWhetherFromStringParsesAGivenStringCorrectly + */ + public function testWhetherGetCriticalThresholdReturnsCorrectValues() + { + $zeroToTen = Perfdata::fromString('test=1;;10')->getCriticalThreshold(); + $this->assertSame( + 0.0, + $zeroToTen->getMin(), + 'Perfdata::getCriticalThreshold does not return correct values' + ); + $this->assertSame( + 10.0, + $zeroToTen->getMax(), + 'Perfdata::getCriticalThreshold does not return correct values' + ); + $tenToInfinity = Perfdata::fromString('test=1;;10:')->getCriticalThreshold(); + $this->assertSame( + 10.0, + $tenToInfinity->getMin(), + 'Perfdata::getCriticalThreshold does not return correct values' + ); + $this->assertNull( + $tenToInfinity->getMax(), + 'Perfdata::getCriticalThreshold does not return correct values' + ); + $infinityToTen = Perfdata::fromString('test=1;;~:10')->getCriticalThreshold(); + $this->assertNull( + $infinityToTen->getMin(), + 'Perfdata::getCriticalThreshold does not return correct values' + ); + $this->assertSame( + 10.0, + $infinityToTen->getMax(), + 'Perfdata::getCriticalThreshold does not return correct values' + ); + $tenToTwenty = Perfdata::fromString('test=1;;10:20')->getCriticalThreshold(); + $this->assertSame( + 10.0, + $tenToTwenty->getMin(), + 'Perfdata::getCriticalThreshold does not return correct values' + ); + $this->assertSame( + 20.0, + $tenToTwenty->getMax(), + 'Perfdata::getCriticalThreshold does not return correct values' + ); + $tenToTwentyInverted = Perfdata::fromString('test=1;;@10:20')->getCriticalThreshold(); + $this->assertTrue( + $tenToTwentyInverted->isInverted(), + 'Perfdata::getCriticalThreshold does not return correct values' + ); + } + + /** + * @depends testWhetherFromStringParsesAGivenStringCorrectly + */ + public function testWhetherGetMinimumValueReturnsCorrectValues() + { + $this->assertSame( + 1337.0, + Perfdata::fromString('test=1;;;1337')->getMinimumValue(), + 'Perfdata::getMinimumValue does not return correct values' + ); + $this->assertSame( + 1337.5, + Perfdata::fromString('test=1;;;1337.5')->getMinimumValue(), + 'Perfdata::getMinimumValue does not return correct values' + ); + } + + /** + * @depends testWhetherFromStringParsesAGivenStringCorrectly + */ + public function testWhetherGetMaximumValueReturnsCorrectValues() + { + $this->assertSame( + 1337.0, + Perfdata::fromString('test=1;;;;1337')->getMaximumValue(), + 'Perfdata::getMaximumValue does not return correct values' + ); + $this->assertSame( + 1337.5, + Perfdata::fromString('test=1;;;;1337.5')->getMaximumValue(), + 'Perfdata::getMaximumValue does not return correct values' + ); + } + + /** + * @depends testWhetherFromStringParsesAGivenStringCorrectly + */ + public function testWhetherMissingValuesAreProperlyHandled() + { + $perfdata = Perfdata::fromString('test=1;;3;5'); + $this->assertEmpty( + (string) $perfdata->getWarningThreshold(), + 'Perfdata objects do not correctly identify omitted warning tresholds' + ); + $this->assertNull( + $perfdata->getMaximumValue(), + 'Perfdata objects do not return null for missing maximum values' + ); + } + + /** + * @depends testWhetherGetValueReturnsValidValues + */ + public function testWhetherValuesAreIdentifiedAsNumber() + { + $this->assertTrue( + Perfdata::fromString('test=666')->isNumber(), + 'Perfdata objects do not identify ordinary digits as number' + ); + } + + /** + * @depends testWhetherGetValueReturnsValidValues + */ + public function testWhetherValuesAreIdentifiedAsSeconds() + { + $this->assertTrue( + Perfdata::fromString('test=666s')->isSeconds(), + 'Perfdata objects do not identify seconds as seconds' + ); + } + + /** + * @depends testWhetherGetValueReturnsValidValues + */ + public function testWhetherValuesAreIdentifiedAsPercentage() + { + $this->assertTrue( + Perfdata::fromString('test=66%')->isPercentage(), + 'Perfdata objects do not identify percentages as percentages' + ); + } + + /** + * @depends testWhetherValuesAreIdentifiedAsPercentage + */ + public function testWhetherMinAndMaxAreNotRequiredIfUnitIsInPercent() + { + $perfdata = Perfdata::fromString('test=1%'); + $this->assertSame( + 0.0, + $perfdata->getMinimumValue(), + 'Perfdata objects do not set minimum value to 0 if UOM is %' + ); + $this->assertSame( + 100.0, + $perfdata->getMaximumValue(), + 'Perfdata objects do not set maximum value to 100 if UOM is %' + ); + } + + /** + * @depends testWhetherGetValueReturnsValidValues + */ + public function testWhetherValuesAreIdentifiedAsBytes() + { + $this->assertTrue( + Perfdata::fromString('test=66666B')->isBytes(), + 'Perfdata objects do not identify bytes as bytes' + ); + } + + /** + * @depends testWhetherGetValueReturnsValidValues + */ + public function testWhetherValuesAreIdentifiedAsCounter() + { + $this->assertTrue( + Perfdata::fromString('test=123c')->isCounter(), + 'Perfdata objects do not identify counters as counters' + ); + } + + /** + * @depends testWhetherValuesAreIdentifiedAsPercentage + */ + public function testWhetherPercentagesAreHandledCorrectly() + { + $this->assertSame( + 66.0, + Perfdata::fromString('test=66%')->getPercentage(), + 'Perfdata objects do not correctly handle native percentages' + ); + $this->assertSame( + 50.0, + Perfdata::fromString('test=0;;;-250;250')->getPercentage(), + 'Perfdata objects do not correctly convert suitable values to percentages' + ); + $this->assertNull( + Perfdata::fromString('test=50')->getPercentage(), + 'Perfdata objects do return a percentage though their unit is not % and no maximum is given' + ); + $this->assertNull( + Perfdata::fromString('test=25;;;50;100')->getPercentage(), + 'Perfdata objects do return a percentage though their value is lower than it\'s allowed minimum' + ); + $this->assertNull( + Perfdata::fromString('test=25;;;0;')->getPercentage(), + 'Perfdata objects do not ignore empty max values when returning percentages' + ); + $this->assertNull( + Perfdata::fromString('test=25;;;0;0')->getPercentage(), + 'Perfdata objects do not ignore impossible min/max combinations when returning percentages' + ); + } + + public function testWhetherInvalidValueInPerfDataHandledCorrectly() + { + $p1 = Perfdata::fromString('test=2,0'); + $this->assertFalse($p1->isValid()); + $this->assertNull( + $p1->getValue(), + 'Perfdata::getValue does not return null for invalid values' + ); + $this->assertSame( + '2,0', + $p1->toArray()['value'] + ); + + $p2 = Perfdata::fromString('test=i am not a value'); + $this->assertFalse($p2->isValid()); + $this->assertNull( + $p2->getValue(), + 'Perfdata::getValue does not return null for invalid values' + ); + $this->assertSame( + 'i am not a value', + $p2->toArray()['value'] + ); + + $p3 = Perfdata::fromString('test='); + $this->assertFalse($p3->isValid()); + $this->assertNull( + $p3->getValue(), + 'Perfdata::getValue does not return null for invalid values' + ); + $this->assertSame( + '', + $p3->toArray()['value'] + ); + + $p4 = Perfdata::fromString('test=-kW'); + $this->assertFalse($p4->isValid()); + $this->assertNull( + $p4->getValue(), + 'Perfdata::getValue does not return null for invalid values' + ); + $this->assertSame( + '-kW', + $p4->toArray()['value'] + ); + + $p5 = Perfdata::fromString('test=kW'); + $this->assertFalse($p5->isValid()); + $this->assertNull( + $p5->getValue(), + 'Perfdata::getValue does not return null for invalid values' + ); + $this->assertSame( + 'kW', + $p5->toArray()['value'] + ); + + $p6 = Perfdata::fromString('test=-'); + $this->assertFalse($p6->isValid()); + $this->assertNull( + $p6->getValue(), + 'Perfdata::getValue does not return null for invalid values' + ); + $this->assertSame( + '-', + $p6->toArray()['value'] + ); + } + + public function testWhetherInvalidMinInPerfDataHandledCorrectly() + { + $p1 = Perfdata::fromString('test=1;;;2,0'); + $this->assertFalse($p1->isValid()); + $this->assertNull( + $p1->getMinimumValue(), + 'Perfdata::getMinimumValue does not return null for invalid min values' + ); + $this->assertSame( + '2,0', + $p1->toArray()['min'] + ); + + $p2 = Perfdata::fromString('test=1;;;foo'); + $this->assertFalse($p2->isValid()); + $this->assertNull( + $p2->getMinimumValue(), + 'Perfdata::getMinimumValue does not return null for invalid min values' + ); + $this->assertSame( + 'foo', + $p2->toArray()['min'] + ); + } + + public function testWhetherInvalidMaxInPerfDataHandledCorrectly() + { + $p1 = Perfdata::fromString('test=1;;;;2,0'); + $this->assertFalse($p1->isValid()); + $this->assertNull( + $p1->getMaximumValue(), + 'Perfdata::getMaximumValue does not return null for invalid max values' + ); + $this->assertSame( + '2,0', + $p1->toArray()['max'] + ); + + $p2 = Perfdata::fromString('test=1;;;;foo'); + $this->assertFalse($p2->isValid()); + $this->assertNull( + $p2->getMaximumValue(), + 'Perfdata::getMaximumValue does not return null for invalid max values' + ); + $this->assertSame( + 'foo', + $p2->toArray()['max'] + ); + } + + public function testWhetherInvalidWarningThresholdInPerfDataHandledCorrectly() + { + $p1 = Perfdata::fromString('test=1;2,0:'); + $this->assertFalse($p1->getWarningThreshold()->isValid()); + $this->assertFalse($p1->isValid()); + $this->assertSame( + '2,0:', + (string) $p1->getWarningThreshold() + ); + + $p2 = Perfdata::fromString('test=1;0:4,0'); + $this->assertFalse($p2->getWarningThreshold()->isValid()); + $this->assertFalse($p2->isValid()); + $this->assertSame( + '0:4,0', + (string) $p2->getWarningThreshold() + ); + + $p3 = Perfdata::fromString('test=1;foo'); + $this->assertFalse($p2->getWarningThreshold()->isValid()); + $this->assertFalse($p3->isValid()); + $this->assertSame( + 'foo', + (string) $p3->getWarningThreshold() + ); + + $p4 = Perfdata::fromString('test=1;10@'); + $this->assertFalse($p2->getWarningThreshold()->isValid()); + $this->assertFalse($p4->isValid()); + $this->assertSame( + '10@', + (string) $p4->getWarningThreshold() + ); + } + + public function testWhetherInvalidCriticalThresholdInPerfDataHandledCorrectly() + { + $p1 = Perfdata::fromString('test=1;;2,0:'); + $this->assertFalse($p1->getCriticalThreshold()->isValid()); + $this->assertFalse($p1->isValid()); + $this->assertSame( + '2,0:', + (string) $p1->getCriticalThreshold() + ); + + $p2 = Perfdata::fromString('test=1;;0:4,0'); + $this->assertFalse($p2->getCriticalThreshold()->isValid()); + $this->assertFalse($p2->isValid()); + $this->assertSame( + '0:4,0', + (string) $p2->getCriticalThreshold() + ); + + $p3 = Perfdata::fromString('test=1;;foo'); + $this->assertFalse($p2->getCriticalThreshold()->isValid()); + $this->assertFalse($p3->isValid()); + $this->assertSame( + 'foo', + (string) $p3->getCriticalThreshold() + ); + + $p4 = Perfdata::fromString('test=1;;10@'); + $this->assertFalse($p2->getCriticalThreshold()->isValid()); + $this->assertFalse($p4->isValid()); + $this->assertSame( + '10@', + (string) $p4->getCriticalThreshold() + ); + } +} diff --git a/test/php/library/Icingadb/Util/ThresholdRangeTest.php b/test/php/library/Icingadb/Util/ThresholdRangeTest.php new file mode 100644 index 0000000..b191e88 --- /dev/null +++ b/test/php/library/Icingadb/Util/ThresholdRangeTest.php @@ -0,0 +1,343 @@ +<?php + +/* Icinga DB Web | (c) 2023 Icinga GmbH | GPLv2 */ + +namespace Tests\Icinga\Module\Icingadb\Util; + +use Icinga\Module\Icingadb\Util\ThresholdRange; +use PHPUnit\Framework\TestCase; + +class ThresholdRangeTest extends TestCase +{ + public function testFromStringProperlyParsesDoubleExclusiveRanges() + { + $outside0And10 = ThresholdRange::fromString('10'); + $this->assertSame( + 0.0, + $outside0And10->getMin(), + 'ThresholdRange::fromString() does not identify zero as default minimum for double exclusive ranges' + ); + $this->assertSame( + 10.0, + $outside0And10->getMax(), + 'ThresholdRange::fromString() does not identify ten as explicit maximum for double exclusive ranges' + ); + $this->assertFalse( + $outside0And10->isInverted(), + 'ThresholdRange::fromString() identifies double exclusive ranges as inclusive' + ); + + $outside10And20 = ThresholdRange::fromString('10:20'); + $this->assertSame( + 10.0, + $outside10And20->getMin(), + 'ThresholdRange::fromString() does not identify ten as explicit minimum for double exclusive ranges' + ); + $this->assertSame( + 20.0, + $outside10And20->getMax(), + 'ThresholdRange::fromString() does not identify twenty as explicit maximum for double exclusive ranges' + ); + $this->assertFalse( + $outside10And20->isInverted(), + 'ThresholdRange::fromString() identifies double exclusive ranges as inclusive' + ); + } + + /** + * @depends testFromStringProperlyParsesDoubleExclusiveRanges + */ + public function testContainsCorrectlyEvaluatesDoubleExclusiveRanges() + { + $outside0And10 = ThresholdRange::fromString('10'); + $this->assertFalse( + $outside0And10->contains(-1), + 'ThresholdRange::contains() identifies negative values as greater than or equal to zero' + ); + $this->assertFalse( + $outside0And10->contains(11), + 'ThresholdRange::contains() identifies eleven as smaller than or equal to ten' + ); + $this->assertTrue( + $outside0And10->contains(10), + 'ThresholdRange::contains() identifies 10 as outside the range 0..10' + ); + + $outside10And20 = ThresholdRange::fromString('10:20'); + $this->assertFalse( + $outside10And20->contains(9), + 'ThresholdRange::contains() identifies nine as greater than or equal to 10' + ); + $this->assertFalse( + $outside10And20->contains(21), + 'ThresholdRange::contains() identifies twenty-one as smaller than or equal to twenty' + ); + $this->assertTrue( + $outside10And20->contains(20), + 'ThresholdRange::contains() identifies 20 as outside the range 10..20' + ); + } + + public function testFromStringProperlyParsesSingleExclusiveRanges() + { + $smallerThan10 = ThresholdRange::fromString('10:'); + $this->assertSame( + 10.0, + $smallerThan10->getMin(), + 'ThresholdRange::fromString() does not identify ten as explicit minimum for single exclusive ranges' + ); + $this->assertNull( + $smallerThan10->getMax(), + 'ThresholdRange::fromString() does not identify infinity as default maximum for single exclusive ranges' + ); + $this->assertFalse( + $smallerThan10->isInverted(), + 'ThresholdRange::fromString() identifies single exclusive ranges as inclusive' + ); + + $greaterThan10 = ThresholdRange::fromString('~:10'); + $this->assertNull( + $greaterThan10->getMin(), + 'ThresholdRange::fromString() does not identify infinity as explicit minimum for single exclusive ranges' + ); + $this->assertSame( + 10.0, + $greaterThan10->getMax(), + 'ThresholdRange::fromString() does not identify ten as explicit maximum for single exclusive ranges' + ); + $this->assertFalse( + $greaterThan10->isInverted(), + 'ThresholdRange::fromString() identifies single exclusive ranges as inclusive' + ); + } + + /** + * @depends testFromStringProperlyParsesSingleExclusiveRanges + */ + public function testContainsCorrectlyEvaluatesSingleExclusiveRanges() + { + $smallerThan10 = ThresholdRange::fromString('10:'); + $this->assertFalse( + $smallerThan10->contains(9), + 'ThresholdRange::contains() identifies nine as greater than or equal to ten' + ); + $this->assertTrue( + $smallerThan10->contains(PHP_INT_MAX), + 'ThresholdRange::contains() identifies infinity as outside the range 10..~' + ); + + $greaterThan10 = ThresholdRange::fromString('~:10'); + $this->assertFalse( + $greaterThan10->contains(11), + 'ThresholdRange::contains() identifies eleven as smaller than or equal to ten' + ); + $this->assertTrue( + $greaterThan10->contains(~PHP_INT_MAX), + 'ThresholdRange::contains() identifies negative infinity as outside the range ~..10' + ); + } + + public function testFromStringProperlyParsesInclusiveRanges() + { + $inside0And10 = ThresholdRange::fromString('@10'); + $this->assertSame( + 0.0, + $inside0And10->getMin(), + 'ThresholdRange::fromString() does not identify zero as default minimum for inclusive ranges' + ); + $this->assertSame( + 10.0, + $inside0And10->getMax(), + 'ThresholdRange::fromString() does not identify ten as explicit maximum for inclusive ranges' + ); + $this->assertTrue( + $inside0And10->isInverted(), + 'ThresholdRange::fromString() identifies inclusive ranges as double exclusive' + ); + + $inside10And20 = ThresholdRange::fromString('@10:20'); + $this->assertSame( + 10.0, + $inside10And20->getMin(), + 'ThresholdRange::fromString() does not identify ten as explicit minimum for inclusive ranges' + ); + $this->assertSame( + 20.0, + $inside10And20->getMax(), + 'ThresholdRange::fromString() does not identify twenty as explicit maximum for inclusive ranges' + ); + $this->assertTrue( + $inside10And20->isInverted(), + 'ThresholdRange::fromString() identifies inclusive ranges as double exclusive' + ); + + $greaterThan10 = ThresholdRange::fromString('@10:'); + $this->assertSame( + 10.0, + $greaterThan10->getMin(), + 'ThresholdRange::fromString() does not identify ten as explicit minimum for inclusive ranges' + ); + $this->assertNull( + $greaterThan10->getMax(), + 'ThresholdRange::fromString() does not identify infinity as default maximum for inclusive ranges' + ); + $this->assertTrue( + $greaterThan10->isInverted(), + 'ThresholdRange::fromString() identifies inclusive ranges as single exclusive' + ); + + $smallerThan10 = ThresholdRange::fromString('@~:10'); + $this->assertNull( + $smallerThan10->getMin(), + 'ThresholdRange::fromString() does not identify infinity as explicit minimum for inclusive ranges' + ); + $this->assertSame( + 10.0, + $smallerThan10->getMax(), + 'ThresholdRange::fromString() does not identify ten as explicit maximum for inclusive ranges' + ); + $this->assertTrue( + $smallerThan10->isInverted(), + 'ThresholdRange::fromString() identifies inclusive ranges as single exclusive' + ); + } + + /** + * @depends testFromStringProperlyParsesInclusiveRanges + */ + public function testContainsCorrectlyEvaluatesInclusiveRanges() + { + $inside0And10 = ThresholdRange::fromString('@10'); + $this->assertFalse( + $inside0And10->contains(10), + 'ThresholdRange::contains() identifies ten as greater than ten' + ); + $this->assertTrue( + $inside0And10->contains(11), + 'ThresholdRange::contains() identifies eleven as smaller than or equal to ten' + ); + $this->assertTrue( + $inside0And10->contains(-1), + 'ThresholdRange::contains() identifies negative values as greater than or equal to zero' + ); + + $inside10And20 = ThresholdRange::fromString('@10:20'); + $this->assertFalse( + $inside10And20->contains(20), + 'ThresholdRange::contains() identifies twenty as greater than twenty' + ); + $this->assertTrue( + $inside10And20->contains(21), + 'ThresholdRange::contains() identifies twenty-one as smaller than or equal to twenty' + ); + $this->assertTrue( + $inside10And20->contains(9), + 'ThresholdRange::contains() identifies nine as greater than or equal to ten' + ); + + $greaterThan10 = ThresholdRange::fromString('@10:'); + $this->assertFalse( + $greaterThan10->contains(PHP_INT_MAX), + 'ThresholdRange::contains() identifies infinity as smaller than ten' + ); + $this->assertTrue( + $greaterThan10->contains(9), + 'ThresholdRange::contains() identifies nine as greater than or equal to ten' + ); + + $smallerThan10 = ThresholdRange::fromString('@~:10'); + $this->assertFalse( + $smallerThan10->contains(~PHP_INT_MAX), + 'ThresholdRange::contains() identifies negative infinity as greater than ten' + ); + $this->assertTrue( + $smallerThan10->contains(11), + 'ThresholdRange::contains() identifies eleven as smaller than or equal to ten' + ); + } + + public function testFromStringProperlyParsesEmptyThresholds() + { + $emptyThreshold = ThresholdRange::fromString(''); + $this->assertNull( + $emptyThreshold->getMin(), + 'ThresholdRange::fromString() does not identify negative infinity as implicit minimum for empty strings' + ); + $this->assertNull( + $emptyThreshold->getMax(), + 'ThresholdRange::fromString() does not identify infinity as implicit maximum for empty strings' + ); + $this->assertFalse( + $emptyThreshold->isInverted(), + 'ThresholdRange::fromString() identifies empty strings as inclusive ranges rather than exclusive' + ); + } + + /** + * @depends testFromStringProperlyParsesEmptyThresholds + */ + public function testContainsEvaluatesEverythingToTrueForEmptyThresholds() + { + $emptyThreshold = ThresholdRange::fromString(''); + $this->assertTrue( + $emptyThreshold->contains(0), + 'ThresholdRange::contains() does not identify zero as valid without any threshold' + ); + $this->assertTrue( + $emptyThreshold->contains(10), + 'ThresholdRange::contains() does not identify ten as valid without any threshold' + ); + $this->assertTrue( + $emptyThreshold->contains(PHP_INT_MAX), + 'ThresholdRange::contains() does not identify infinity as valid without any threshold' + ); + $this->assertTrue( + $emptyThreshold->contains(~PHP_INT_MAX), + 'ThresholdRange::contains() does not identify negative infinity as valid without any threshold' + ); + } + + public function testInvalidThresholdNotationsAreRenderedAsIs() + { + $this->assertSame( + ':', + (string) ThresholdRange::fromString(':') + ); + $this->assertSame( + '~:', + (string) ThresholdRange::fromString('~:') + ); + $this->assertSame( + '20:10', + (string) ThresholdRange::fromString('20:10') + ); + $this->assertSame( + '10@', + (string) ThresholdRange::fromString('10@') + ); + $this->assertSame( + 'foo', + (string) ThresholdRange::fromString('foo') + ); + $this->assertSame( + '4,4:2,2', + (string) ThresholdRange::fromString('4,4:2,2') + ); + } + + public function testInvalidThresholdNotationsConsideredInValid() + { + $this->assertFalse( + ThresholdRange::fromString('10@')->isValid(), + 'Invalid threshold notation 10@ considered as valid' + ); + $this->assertFalse( + ThresholdRange::fromString('foo')->isValid(), + 'Invalid threshold notation foo considered as valid' + ); + $this->assertFalse( + ThresholdRange::fromString('4,4:2,2')->isValid(), + 'Invalid threshold notation 4,4:2,2 considered as valid' + ); + } +} |