mirror of
https://github.com/pestphp/pest.git
synced 2026-07-21 17:10:03 +02:00
81eacd79fd
- keep table/Inertia/database link-tracking alive in piggyback-coverage recording, and merge link-only edges into the piggybacked edge set - route migration changes through the watch-pattern fallback when the graph has no recorded table usage - re-run cached failures whose test file cannot be located, downgrading filtered runs to full replay instead of silently skipping them - align non-filtered replay with the failOn*/displayDetailsOn* rerun policy - resolve anonymous index Blade components (<x-card> from card/index.blade.php) and stop swallowing components whose static usage walk selected no tests - parse CTE/REPLACE queries and schema-qualified identifiers in TableExtractor - scope-filter the xdebug recording path like pcov - ignore in-flight .tmp files in FileState::keysWithPrefix and delete unreadable worker partials - vite deps helper: resolve rolldown through rolldown-vite installs and degrade gracefully, honour vite.config resolve.alias (incl. the laravel-vite-plugin '@' default), resolve .vue/.svelte/.mts/.cts extensions, and stop memoizing cycle-tainted transitive sets Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
97 lines
4.3 KiB
PHP
97 lines
4.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use Pest\Plugins\Tia\TableExtractor;
|
|
|
|
describe('fromSql()', function (): void {
|
|
it('extracts tables from plain DML', function (): void {
|
|
expect(TableExtractor::fromSql('select * from users'))->toBe(['users'])
|
|
->and(TableExtractor::fromSql('INSERT INTO orders (id) VALUES (1)'))->toBe(['orders'])
|
|
->and(TableExtractor::fromSql('UPDATE posts SET title = ?'))->toBe(['posts'])
|
|
->and(TableExtractor::fromSql('DELETE FROM sessions WHERE id = ?'))->toBe(['sessions']);
|
|
});
|
|
|
|
it('extracts tables from joins', function (): void {
|
|
expect(TableExtractor::fromSql('select * from orders join users on users.id = orders.user_id'))
|
|
->toBe(['orders', 'users']);
|
|
});
|
|
|
|
it('extracts tables from CTE queries', function (): void {
|
|
$sql = 'WITH recent AS (SELECT * FROM orders WHERE created_at > ?) SELECT * FROM recent JOIN users ON users.id = recent.user_id';
|
|
|
|
expect(TableExtractor::fromSql($sql))->toBe(['orders', 'recent', 'users']);
|
|
});
|
|
|
|
it('extracts tables from REPLACE INTO', function (): void {
|
|
expect(TableExtractor::fromSql('REPLACE INTO settings (key, value) VALUES (?, ?)'))
|
|
->toBe(['settings']);
|
|
});
|
|
|
|
it('records the table, not the schema, for qualified identifiers', function (): void {
|
|
expect(TableExtractor::fromSql('select * from public.users'))->toBe(['users'])
|
|
->and(TableExtractor::fromSql('select * from "public"."users"'))->toBe(['users'])
|
|
->and(TableExtractor::fromSql('select * from `analytics`.`events`'))->toBe(['events'])
|
|
->and(TableExtractor::fromSql('UPDATE public.posts SET title = ?'))->toBe(['posts']);
|
|
});
|
|
|
|
it('handles quoted identifiers', function (): void {
|
|
expect(TableExtractor::fromSql('select * from "users"'))->toBe(['users'])
|
|
->and(TableExtractor::fromSql('select * from `users`'))->toBe(['users'])
|
|
->and(TableExtractor::fromSql('select * from [users]'))->toBe(['users']);
|
|
});
|
|
|
|
it('ignores schema metadata tables', function (): void {
|
|
expect(TableExtractor::fromSql("select * from sqlite_master where type = 'table'"))->toBeEmpty()
|
|
->and(TableExtractor::fromSql('select * from pg_catalog.pg_tables'))->toBeEmpty()
|
|
->and(TableExtractor::fromSql('select * from information_schema.tables'))->toBeEmpty();
|
|
});
|
|
|
|
it('returns nothing for non-DML statements', function (): void {
|
|
expect(TableExtractor::fromSql('PRAGMA foreign_keys = ON'))->toBeEmpty()
|
|
->and(TableExtractor::fromSql(''))->toBeEmpty()
|
|
->and(TableExtractor::fromSql(' '))->toBeEmpty();
|
|
});
|
|
});
|
|
|
|
describe('fromMigrationSource()', function (): void {
|
|
it('extracts tables from Schema builder calls', function (): void {
|
|
$php = <<<'PHP'
|
|
Schema::create('users', function (Blueprint $table) {});
|
|
Schema::table('orders', function (Blueprint $table) {});
|
|
Schema::rename('old_posts', 'posts');
|
|
Schema::dropIfExists('sessions');
|
|
PHP;
|
|
|
|
expect(TableExtractor::fromMigrationSource($php))
|
|
->toBe(['old_posts', 'orders', 'posts', 'sessions', 'users']);
|
|
});
|
|
|
|
it('extracts tables from raw DDL statements', function (): void {
|
|
$php = <<<'PHP'
|
|
DB::statement('ALTER TABLE users ADD COLUMN age INT');
|
|
DB::statement('CREATE TABLE IF NOT EXISTS invoices (id INT)');
|
|
PHP;
|
|
|
|
expect(TableExtractor::fromMigrationSource($php))->toBe(['invoices', 'users']);
|
|
});
|
|
|
|
it('records the table, not the schema, in qualified DDL and DML', function (): void {
|
|
$php = <<<'PHP'
|
|
DB::statement('ALTER TABLE public.users ADD COLUMN age INT');
|
|
DB::statement('CREATE TABLE "analytics"."events" (id INT)');
|
|
DB::statement('INSERT INTO public.settings (key) VALUES (1)');
|
|
DB::statement('DELETE FROM `public`.`sessions`');
|
|
DB::table('public.audits')->delete();
|
|
PHP;
|
|
|
|
expect(TableExtractor::fromMigrationSource($php))
|
|
->toBe(['audits', 'events', 'sessions', 'settings', 'users']);
|
|
});
|
|
|
|
it('extracts tables from DB::table calls', function (): void {
|
|
expect(TableExtractor::fromMigrationSource("DB::table('permissions')->insert([]);"))
|
|
->toBe(['permissions']);
|
|
});
|
|
});
|