Skip to content

Commit 169242a

Browse files
committed
Test
1 parent 20e8b3a commit 169242a

4 files changed

Lines changed: 99 additions & 5 deletions

File tree

bin/check-fixtures

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,32 @@
1515
$fixturesDir = __DIR__ . '/../tests/Fixtures';
1616
$errors = [];
1717
$checked = 0;
18+
$dimensionErrors = [];
19+
$dimensionsChecked = 0;
20+
21+
// Required fixture dimensions (must match CI environment)
22+
const REQUIRED_WIDTH = 180;
23+
const REQUIRED_HEIGHT = 32;
24+
25+
echo "Checking fixture dimensions (" . REQUIRED_WIDTH . "x" . REQUIRED_HEIGHT . ")...\n\n";
26+
27+
// Check dimensions for all terminal fixtures
28+
$dimensionsChecked += checkFixtureDimensions($fixturesDir . '/iterm', $dimensionErrors);
29+
$dimensionsChecked += checkFixtureDimensions($fixturesDir . '/ghostty', $dimensionErrors);
30+
31+
if (count($dimensionErrors) > 0) {
32+
echo "DIMENSION ERRORS FOUND:\n\n";
33+
foreach ($dimensionErrors as $error) {
34+
echo "{$error}\n";
35+
}
36+
echo "\n";
37+
echo "Found " . count($dimensionErrors) . " fixture dimension error(s).\n";
38+
echo "All fixtures must be generated at " . REQUIRED_WIDTH . "x" . REQUIRED_HEIGHT . ".\n";
39+
echo "Resize your terminal and run: composer test:screenshots\n";
40+
exit(1);
41+
}
42+
43+
echo "✓ All {$dimensionsChecked} fixture(s) have correct dimensions.\n\n";
1844

1945
echo "Checking terminal fixture synchronization...\n\n";
2046

@@ -134,3 +160,35 @@ function filesMatch(string $file1, string $file2): bool
134160
{
135161
return file_get_contents($file1) === file_get_contents($file2);
136162
}
163+
164+
/**
165+
* Check that all fixtures in a directory have the required dimensions.
166+
*
167+
* @return int Number of fixtures checked
168+
*/
169+
function checkFixtureDimensions(string $dir, array &$errors): int
170+
{
171+
$checked = 0;
172+
173+
if (!is_dir($dir)) {
174+
return $checked;
175+
}
176+
177+
$files = findJsonFiles($dir);
178+
foreach ($files as $file) {
179+
$data = json_decode(file_get_contents($file), true);
180+
181+
if (!isset($data['width']) || !isset($data['height'])) {
182+
continue;
183+
}
184+
185+
$checked++;
186+
187+
if ($data['width'] !== REQUIRED_WIDTH || $data['height'] !== REQUIRED_HEIGHT) {
188+
$relPath = basename(dirname($dir)) . '/' . basename($dir) . '/' . substr($file, strlen($dir) + 1);
189+
$errors[] = "{$relPath}: {$data['width']}x{$data['height']} (expected " . REQUIRED_WIDTH . "x" . REQUIRED_HEIGHT . ")";
190+
}
191+
}
192+
193+
return $checked;
194+
}

tests/Support/ComparesVisually.php

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,44 @@ public function assertTerminalMatch(array|string $content, bool $iterate = false
5959
}
6060

6161
$this->uniqueTestIdentifier = $this->uniqueTestIdentifier();
62-
[$path, $function] = $this->uniqueTestIdentifier;
6362

64-
$fixturePath = $this->terminalFixturePath();
65-
$fixtureExists = $this->fixtureStore()->loadTerminalFixture($fixturePath, $content) !== null;
66-
$fixturesInSync = $this->fixtureStore()->fixturesAreInSync($path, $function);
63+
// First, try fixture comparison (fast path)
64+
if ($this->tryFixtureMatch($content)) {
65+
$this->assertTrue(true);
66+
return;
67+
}
6768

68-
if ($this->visualConfig()->shouldRunVisualTest($fixtureExists, $fixturesInSync)) {
69+
// Fixture didn't match or doesn't exist - fall back to visual comparison if enabled
70+
if ($this->visualConfig()->canRunVisualTest()) {
6971
$this->terminalEnv()->withOutput(fn() => $this->assertVisualMatch($content));
7072
} else {
73+
// No visual testing available - run fixture match which will skip or fail appropriately
7174
$this->assertFixtureMatch($content);
7275
}
7376
}
7477

78+
/**
79+
* Try to match against a fixture. Returns true if fixture exists and matches.
80+
* Returns false if fixture doesn't exist or doesn't match (caller should fall back to visual).
81+
*/
82+
protected function tryFixtureMatch(array $content): bool
83+
{
84+
$fixturePath = $this->terminalFixturePath();
85+
$fixture = $this->fixtureStore()->loadTerminalFixture($fixturePath, $content);
86+
87+
if (!$fixture) {
88+
return false;
89+
}
90+
91+
$screen = new Screen($fixture->width, $fixture->height);
92+
93+
foreach ($content as $c) {
94+
$screen->write($c);
95+
}
96+
97+
return $fixture->output === $screen->output();
98+
}
99+
75100
protected function assertFixtureMatch(array $content): void
76101
{
77102
$fixturePath = $this->terminalFixturePath();

tests/Support/VisualFixtureStore.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ public function terminalFixturePath(string $relativePath, string $function): str
3939
}
4040
}
4141

42+
// In CI (no terminal), prefer iTerm fixtures since we assert iTerm and Ghostty are identical
43+
$itermPath = "{$this->config->fixturesRoot}/iterm/{$relativePath}/{$function}.json";
44+
if (file_exists($itermPath)) {
45+
return $itermPath;
46+
}
47+
4248
return "{$this->config->fixturesRoot}/{$relativePath}/{$function}.json";
4349
}
4450

tests/Support/VisualTestConfig.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ public function shouldRunVisualTest(bool $fixtureExists, bool $fixturesInSync =
113113
return false;
114114
}
115115

116+
public function canRunVisualTest(): bool
117+
{
118+
return $this->mode !== self::MODE_DISABLED && $this->hasValidTerminal();
119+
}
120+
116121
public function titleBarHeight(): int
117122
{
118123
return match ($this->terminal) {

0 commit comments

Comments
 (0)