fix: livewire

This commit is contained in:
nuno maduro
2026-08-07 14:27:26 +01:00
parent 7b6415ccd0
commit eb88513baf
6 changed files with 446 additions and 8 deletions
+115
View File
@@ -147,6 +147,121 @@ describe('applyBladeStaticChanges()', function (): void {
});
});
describe('Livewire component views', function (): void {
beforeEach(function (): void {
$this->projectRoot = sys_get_temp_dir().'/pest-tia-livewire-sfc-'.bin2hex(random_bytes(4));
mkdir($this->projectRoot, 0755, true);
$this->watchPatterns = new WatchPatterns;
$this->watchPatterns->add(['resources/views/**' => 'tests/Feature']);
Container::getInstance()->add(WatchPatterns::class, $this->watchPatterns);
});
afterEach(function (): void {
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($this->projectRoot, FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST,
);
foreach ($files as $file) {
assert($file instanceof SplFileInfo);
if ($file->isDir()) {
@rmdir($file->getPathname());
} else {
@unlink($file->getPathname());
}
}
@rmdir($this->projectRoot);
Container::getInstance()->add(WatchPatterns::class, new WatchPatterns);
});
it('maps a changed component to generated views from different workers', function (): void {
$ordersPath = 'resources/views/components/orders.blade.php';
$usersPath = 'resources/views/components/admin/⚡users.blade.php';
$ordersHash = substr(md5(DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $ordersPath)), 0, 8);
$usersHash = substr(md5(DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $usersPath)), 0, 8);
mkdir(dirname($this->projectRoot.'/'.$ordersPath), 0755, true);
mkdir(dirname($this->projectRoot.'/'.$usersPath), 0755, true);
file_put_contents($this->projectRoot.'/'.$ordersPath, '<div>Orders</div>');
file_put_contents($this->projectRoot.'/'.$usersPath, '<div>Users</div>');
$graph = new Graph($this->projectRoot);
$graph->link('tests/Feature/OrdersTest.php', 'storage/framework/views/test_1/livewire/views/'.$ordersHash.'.blade.php');
$graph->link('tests/Feature/UsersTest.php', 'storage/framework/views/test_2/livewire/views/'.$usersHash.'.blade.php');
expect($graph->affected([$ordersPath]))->toBe(['tests/Feature/OrdersTest.php']);
});
it('maps documented SFC locations', function (string $sourcePath): void {
$hash = substr(md5(DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $sourcePath)), 0, 8);
mkdir(dirname($this->projectRoot.'/'.$sourcePath), 0755, true);
file_put_contents($this->projectRoot.'/'.$sourcePath, '<div>Component</div>');
$graph = new Graph($this->projectRoot);
$graph->link('tests/Feature/ComponentTest.php', 'storage/framework/views/test_3/livewire/views/'.$hash.'.blade.php');
$graph->link('tests/Feature/UnrelatedTest.php', 'storage/framework/views/test_4/livewire/views/deadbeef.blade.php');
expect($graph->affected([$sourcePath]))->toBe(['tests/Feature/ComponentTest.php']);
})->with([
'default pages namespace' => ['resources/views/pages/post/⚡create.blade.php'],
'default layouts namespace without emoji' => ['resources/views/layouts/app.blade.php'],
'additional component location' => ['resources/views/widgets/orders.blade.php'],
]);
it('maps documented MFC locations using the component directory hash', function (string $componentDirectory, string $viewPath): void {
$hash = substr(md5(DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $componentDirectory)), 0, 8);
$classPath = $componentDirectory.'/'.basename($viewPath, '.blade.php').'.php';
mkdir($this->projectRoot.'/'.$componentDirectory, 0755, true);
file_put_contents($this->projectRoot.'/'.$viewPath, '<div>Component</div>');
file_put_contents($this->projectRoot.'/'.$classPath, '<?php');
$graph = new Graph($this->projectRoot);
$graph->link('tests/Feature/ComponentTest.php', 'storage/framework/views/test_5/livewire/views/'.$hash.'.blade.php');
$graph->link('tests/Feature/UnrelatedTest.php', 'storage/framework/views/test_6/livewire/views/deadbeef.blade.php');
expect($graph->affected([$viewPath]))->toBe(['tests/Feature/ComponentTest.php']);
})->with([
'default component location' => ['resources/views/components/post/⚡create', 'resources/views/components/post/⚡create/create.blade.php'],
'default component location without emoji' => ['resources/views/components/post/create', 'resources/views/components/post/create/create.blade.php'],
'index convention' => ['resources/views/components/post/⚡index', 'resources/views/components/post/⚡index/index.blade.php'],
]);
it('preserves direct view edges for class-based components', function (): void {
$viewPath = 'resources/views/livewire/create-post.blade.php';
mkdir(dirname($this->projectRoot.'/'.$viewPath), 0755, true);
file_put_contents($this->projectRoot.'/'.$viewPath, '<div>Create post</div>');
$graph = new Graph($this->projectRoot);
$graph->link('tests/Feature/CreatePostTest.php', $viewPath);
expect($graph->affected([$viewPath]))->toBe(['tests/Feature/CreatePostTest.php']);
});
it('falls back to watch patterns when no generated view matches', function (): void {
$ordersPath = 'resources/views/components/orders.blade.php';
$ordersHash = substr(md5(DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $ordersPath)), 0, 8);
$unmatchedPath = 'resources/views/components/unmatched.blade.php';
mkdir(dirname($this->projectRoot.'/'.$ordersPath), 0755, true);
file_put_contents($this->projectRoot.'/'.$ordersPath, '<div>Orders</div>');
file_put_contents($this->projectRoot.'/'.$unmatchedPath, '<div>Unmatched</div>');
$graph = new Graph($this->projectRoot);
$graph->link('tests/Feature/OrdersTest.php', 'storage/framework/views/test_1/livewire/views/'.$ordersHash.'.blade.php');
$graph->link('tests/Feature/UsersTest.php', 'storage/framework/views/test_2/livewire/views/deadbeef.blade.php');
expect($graph->affected([$unmatchedPath]))
->toBe(['tests/Feature/OrdersTest.php', 'tests/Feature/UsersTest.php']);
});
});
describe('markKnownTestFiles()', function (): void {
it('makes a test file with no edges known', function (): void {
$graph = new Graph(sys_get_temp_dir());