Merge pull request #702 from Icinga/add-perfdata-unittests

Add perfdata unittests
This commit is contained in:
Johannes Meyer 2023-01-19 11:30:30 +01:00 committed by GitHub
commit d14c732a9f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 877 additions and 7 deletions

View file

@ -115,7 +115,7 @@ class PerfDataSet implements IteratorAggregate
$this->skipSpaces();
if (in_array($this->perfdataStr[$this->parserPos], array('"', "'"))) {
$quoteChar = $this->perfdataStr[$this->parserPos++];
$label = $this->readUntil($quoteChar);
$label = $this->readUntil($quoteChar, '=');
$this->parserPos++;
if ($this->perfdataStr[$this->parserPos] === '=') {
@ -133,17 +133,30 @@ class PerfDataSet implements IteratorAggregate
/**
* Return all characters between the current parser position and the given character
*
* @param string $stopChar The character on which to stop
* @param string $stopChar The character on which to stop
* @param string $backtrackOn The character on which to backtrack
*
* @return string
* @return string
*/
protected function readUntil(string $stopChar): string
protected function readUntil(string $stopChar, string $backtrackOn = null): string
{
$start = $this->parserPos;
while ($this->parserPos < strlen($this->perfdataStr) && $this->perfdataStr[$this->parserPos] !== $stopChar) {
$breakCharEncounteredAt = null;
$stringExhaustedAt = strlen($this->perfdataStr);
while ($this->parserPos < $stringExhaustedAt) {
if ($this->perfdataStr[$this->parserPos] === $stopChar) {
break;
} elseif ($breakCharEncounteredAt === null && $this->perfdataStr[$this->parserPos] === $backtrackOn) {
$breakCharEncounteredAt = $this->parserPos;
}
$this->parserPos++;
}
if ($breakCharEncounteredAt !== null && $this->parserPos === $stringExhaustedAt) {
$this->parserPos = $breakCharEncounteredAt;
}
return substr($this->perfdataStr, $start, $this->parserPos - $start);
}

View file

@ -92,7 +92,7 @@ class ThresholdRange
*
* @return $this
*/
public function setMin(float $min): self
public function setMin(?float $min): self
{
$this->min = $min;
return $this;
@ -115,7 +115,7 @@ class ThresholdRange
*
* @return $this
*/
public function setMax(float $max): self
public function setMax(?float $max): self
{
$this->max = $max;
return $this;

View file

@ -0,0 +1,12 @@
<?php
/* Icinga DB Web | (c) 2023 Icinga GmbH | GPLv2 */
namespace Tests\Icinga\Module\Icingadb\Lib;
use Icinga\Module\Icingadb\Util\PerfDataSet;
class PerfdataSetWithPublicData extends PerfdataSet
{
public $perfdata = [];
}

View file

@ -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',
$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');
}
}

View file

@ -0,0 +1,402 @@
<?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',
$p->getValue(),
'Perfdata::fromString does not properly parse performance data values'
);
}
/**
* @depends testWhetherFromStringParsesAGivenStringCorrectly
*/
public function testWhetherGetValueReturnsValidValues()
{
$this->assertSame(
'1337',
Perfdata::fromString('test=1337')->getValue(),
'Perfdata::getValue does not return correct values'
);
$this->assertSame(
'1337',
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',
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',
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',
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'
);
}
}

View file

@ -0,0 +1,323 @@
<?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')
);
}
}