diff --git a/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php b/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php index 442ef7200..61aa11ecf 100644 --- a/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php +++ b/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php @@ -59,6 +59,13 @@ */ final class TestLocationBucketSorterTest extends TestCase { + /** + * Used for floating point comparisons. + * + * @var float + */ + private const EPSILON = 0.001; + public function test_it_sorts(): void { $testLocation = new TestLocation('', '', 0.0); @@ -189,7 +196,7 @@ public function test_it_sorts_faster_than_quicksort(ArrayIterator $uniqueTestLoc $totalQuickSort += microtime(true) - $start; } - $this->assertGreaterThanOrEqual(0.01, abs($totalQuickSort - $totalBucketSort)); + $this->assertGreaterThanOrEqual(self::EPSILON, self::getRelativeError($totalQuickSort, $totalBucketSort)); } public static function locationsArrayProvider(): iterable @@ -206,6 +213,22 @@ static function (float $executionTime): TestLocation { yield 'All locations' => [new ArrayIterator($locations)]; } + /** + * Finds relative error. + * + * @see https://floating-point-gui.de/errors/comparison/ + * @see https://stackoverflow.com/questions/4915462/how-should-i-do-floating-point-comparison + */ + private static function getRelativeError(float $a, float $b): float + { + // We do not expect A or B to be extremely small or large: these are edge cases, + // and they will need special handling which we avoid simplicity sake. + self::assertGreaterThan(self::EPSILON, abs($a)); + self::assertGreaterThan(self::EPSILON, abs($b)); + + return abs($a - $b) / (abs($a) + abs($b)); + } + private static function quicksort(&$uniqueTestLocations): void { usort(