From 55913961a8ffad8e3c23e032a213d4ede9b74c4d Mon Sep 17 00:00:00 2001 From: Dennis Haupt Date: Thu, 13 Aug 2026 08:48:16 +0200 Subject: [PATCH 1/2] fix(interop): round yield before casting to int Float multiplication is inexact: 8.04 * 1000000 yields 8039999.999999999, which SafeCast::toInt rejects as not a whole number. --- src/InterOp/LaneResult.php | 3 ++- tests/InterOp/LaneResultTest.php | 39 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 tests/InterOp/LaneResultTest.php diff --git a/src/InterOp/LaneResult.php b/src/InterOp/LaneResult.php index e37f16e..7f5fdb7 100644 --- a/src/InterOp/LaneResult.php +++ b/src/InterOp/LaneResult.php @@ -88,7 +88,8 @@ public static function fromInterOpRow(array $row): self $clusterStatistic, $sequencingQualityControl, SafeCast::toInt($intensityCycle->value), - SafeCast::toInt(SafeCast::toFloat($row['Yield']) * 1000000) + // Rounding because float multiplication is inexact, e.g. 8.04 * 1000000 = 8039999.999999999 + SafeCast::toInt(round(SafeCast::toFloat($row['Yield']) * 1000000)) ); } diff --git a/tests/InterOp/LaneResultTest.php b/tests/InterOp/LaneResultTest.php new file mode 100644 index 0000000..9bd5247 --- /dev/null +++ b/tests/InterOp/LaneResultTest.php @@ -0,0 +1,39 @@ + '1234 +/- 56', + 'Cluster PF' => '92.34 +/- 1.23', + 'Aligned' => '28.66 +/- 0.12', + 'Error' => '0.27 +/- 0.01', + 'Intensity C1' => '4321 +/- 0', + 'Legacy Phasing/Prephasing Rate' => '0.123 / 0.045', + 'Reads' => '1.23', + 'Reads PF' => '1.13', + '%>=Q30' => '93.21', + 'Yield' => $gigabases, + ]); + + self::assertSame($expectedKilobases, $laneResult->yield); + } + + /** @return iterable */ + public static function yieldsProvider(): iterable + { + yield ['8.04', 8040000]; + yield ['1.49', 1490000]; + yield ['0.02', 20000]; + yield ['0', 0]; + } +} From cbe0eb95631598231623e7b3cbb75190044567de Mon Sep 17 00:00:00 2001 From: dhaupt88 <133017448+dhaupt88@users.noreply.github.com> Date: Thu, 13 Aug 2026 06:53:56 +0000 Subject: [PATCH 2/2] Apply php-cs-fixer changes --- tests/Microplate/CoordinateSystemTest.php | 4 ++-- tests/SafeCastTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Microplate/CoordinateSystemTest.php b/tests/Microplate/CoordinateSystemTest.php index 6af7acf..a88361a 100644 --- a/tests/Microplate/CoordinateSystemTest.php +++ b/tests/Microplate/CoordinateSystemTest.php @@ -63,11 +63,11 @@ public function testEquals(): void self::assertTrue($coordinateSystem6x8->equals($coordinateSystem6x8AnotherInstance)); self::assertTrue($coordinateSystem6x8AnotherInstance->equals($coordinateSystem6x8)); - $coordinateSystem6x8Child = new class() extends CoordinateSystem6x8 {}; + $coordinateSystem6x8Child = new class extends CoordinateSystem6x8 {}; self::assertTrue($coordinateSystem6x8->equals($coordinateSystem6x8Child)); self::assertTrue($coordinateSystem6x8Child->equals($coordinateSystem6x8)); - $coordinateSystem8x8ModifiedChild = new class() extends CoordinateSystem6x8 { + $coordinateSystem8x8ModifiedChild = new class extends CoordinateSystem6x8 { public function columns(): array { return range(1, 8); diff --git a/tests/SafeCastTest.php b/tests/SafeCastTest.php index f511b06..f837923 100644 --- a/tests/SafeCastTest.php +++ b/tests/SafeCastTest.php @@ -149,13 +149,13 @@ public static function validStringProvider(): iterable yield ['0', 0]; yield ['3.14', 3.14]; yield ['-2.5', -2.5]; - yield ['object-string-with-stringable-interface', new class() implements \Stringable { + yield ['object-string-with-stringable-interface', new class implements \Stringable { public function __toString(): string { return 'object-string-with-stringable-interface'; } }]; - yield ['object-string-without-stringable-interface', new class() { + yield ['object-string-without-stringable-interface', new class { public function __toString(): string { return 'object-string-without-stringable-interface';