diff --git a/src/Panel/Dump/DumpCardRenderer.php b/src/Panel/Dump/DumpCardRenderer.php index b8a12a8..25bf026 100644 --- a/src/Panel/Dump/DumpCardRenderer.php +++ b/src/Panel/Dump/DumpCardRenderer.php @@ -80,7 +80,9 @@ private static function firstFrame(array $trace): array } /** - * Formats a Unix timestamp in seconds as `H:i:s.mmm`, falling back to `''` when no timestamp is set. + * Formats the row timestamp as `H:i:s.mmm`, falling back to `''` when no timestamp is set. + * + * {@see DumpRow::$time} already holds epoch milliseconds, so the fraction is truncated, not scaled again. */ private static function formatTime(float $time): string { @@ -88,7 +90,7 @@ private static function formatTime(float $time): string return ''; } - return Format::timeOfDay(intval($time * 1000)); + return Format::timeOfDay(intval($time)); } /** diff --git a/tests/Panel/Dump/DumpCardRendererTest.php b/tests/Panel/Dump/DumpCardRendererTest.php index 43b473e..8ba7634 100644 --- a/tests/Panel/Dump/DumpCardRendererTest.php +++ b/tests/Panel/Dump/DumpCardRendererTest.php @@ -146,7 +146,7 @@ public function testRenderMessageCellEscapesMalformedAndMismatchedDumpTags(): vo public function testRenderMessageCellFormatsMillisecondsAtTheUpperBoundary(): void { $html = DumpCardRenderer::renderMessageCell( - self::makeRow(time: 1_700_000_000.1239), + self::makeRow(time: 1_700_000_000_123.9), self::traceLine(), 0, ); @@ -162,7 +162,7 @@ public function testRenderMessageCellFormatsMillisecondsAtTheUpperBoundary(): vo HTML, $html, - 'Millisecond conversion must use exactly one thousand units per second.', + 'Fractional milliseconds must be truncated, not scaled.', ); } @@ -211,7 +211,7 @@ public function testRenderMessageCellKeepsPollutedClosingTokensEscaped(): void public function testRenderMessageCellKeepsTimeAndTraceMetadataTogether(): void { $html = DumpCardRenderer::renderMessageCell( - self::makeRow(time: 1_700_000_000.5, trace: [['file' => '/app/User.php', 'line' => 42]]), + self::makeRow(time: 1_700_000_000_500.0, trace: [['file' => '/app/User.php', 'line' => 42]]), self::traceLine(), 0, ); @@ -418,7 +418,7 @@ public function testRenderMessageCellOmitsTypeBadgeWhenPayloadStartsWithSymbol() public function testRenderMessageCellRendersFormattedTimeWhenTimeIsPositive(): void { $html = DumpCardRenderer::renderMessageCell( - self::makeRow(time: 1_700_000_000.789), + self::makeRow(time: 1_700_000_000_789.0), self::traceLine(), 0, ); diff --git a/tests/Storage/SnapshotStoreTest.php b/tests/Storage/SnapshotStoreTest.php index 25b171c..4d5de94 100644 --- a/tests/Storage/SnapshotStoreTest.php +++ b/tests/Storage/SnapshotStoreTest.php @@ -5,7 +5,7 @@ namespace PHPForge\Debug\Tests\Storage; use PHPForge\Debug\Storage\{DebugSnapshot, RequestSummary, SnapshotStore, StorageException}; -use PHPUnit\Framework\Attributes\{Group, TestWith}; +use PHPUnit\Framework\Attributes\{Group, RequiresOperatingSystemFamily, TestWith}; use PHPUnit\Framework\TestCase; use Xepozz\InternalMocker\MockerState; @@ -485,12 +485,9 @@ public function testManifestReadResultDistinguishesEmptyStoreFromCorruptManifest ); } + #[RequiresOperatingSystemFamily('Linux')] public function testManifestReadResultReportsEmptyAndUnreadableManifestFiles(): void { - if (PHP_OS_FAMILY === 'Windows') { - self::markTestSkipped('POSIX read permissions are not portable to Windows.'); - } - mkdir($this->path, recursive: true); file_put_contents("{$this->path}/index.json", ''); @@ -902,12 +899,9 @@ public function testSnapshotReadResultDistinguishesMissingInvalidAndCorruptSnaps ); } + #[RequiresOperatingSystemFamily('Linux')] public function testSnapshotReadResultReportsEmptyMismatchAndUnreadableFiles(): void { - if (PHP_OS_FAMILY === 'Windows') { - self::markTestSkipped('POSIX read permissions are not portable to Windows.'); - } - mkdir($this->path, recursive: true); file_put_contents("{$this->path}/empty.json", ''); @@ -1513,12 +1507,9 @@ static function (string $directory, string $prefix) use (&$temporaryFileCalls): ); } + #[RequiresOperatingSystemFamily('Linux')] public function testWriteRejectsUnreadableExistingTransactionTarget(): void { - if (PHP_OS_FAMILY === 'Windows') { - self::markTestSkipped('POSIX read permissions are not portable to Windows.'); - } - $store = $this->store(); $store->writeSnapshot( @@ -1539,14 +1530,9 @@ public function testWriteRejectsUnreadableExistingTransactionTarget(): void ); } + #[RequiresOperatingSystemFamily('Linux')] public function testWriteRejectsUnreadableManifest(): void { - if (PHP_OS_FAMILY === 'Windows') { - self::markTestSkipped( - 'POSIX read permissions are not portable to Windows.', - ); - } - $store = $this->store(); $store->writeSnapshot(