Add fixtures and tests for DesignGuard::missingStylesheets()
Plan step 41(ii): exercises the tag-to-stylesheet mapping (plain, prefixed and namespaced spellings), a package stylesheet's own imports counting toward its dependents (split-button.css satisfies button.css and menu.css too), ->links() needing pagination.css, the always-required foundation.css, and a package tag shadowed by the application's own anonymous or class component. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
08f2ae9d76
commit
b998683762
@@ -1,9 +1,14 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use NoNameWeb\LivewireMaterial\Support\Stylesheets;
|
||||
use NoNameWeb\LivewireMaterial\Testing\DesignGuard;
|
||||
|
||||
const GUARD_FIXTURES = __DIR__.'/../Fixtures/design-guard';
|
||||
|
||||
beforeEach(fn () => Stylesheets::resetCache());
|
||||
|
||||
/**
|
||||
* @param list<string> $violations
|
||||
* @return list<string>
|
||||
@@ -305,6 +310,107 @@ it('bans any further pattern', function () {
|
||||
expect($violations)->toContain('views/page.blade.php:7 a retired utility');
|
||||
});
|
||||
|
||||
it('names the missing package stylesheet and the exact @import line to add', function () {
|
||||
$violations = fixtureRelative(DesignGuard::scan(realpath(GUARD_FIXTURES.'/stylesheets/views/split-button.blade.php'))
|
||||
->missingStylesheets(realpath(GUARD_FIXTURES.'/stylesheets/foundation-only.css'))
|
||||
->violations());
|
||||
|
||||
expect($violations)->toBe([
|
||||
"stylesheets/views/split-button.blade.php:1 `<x-split-button>` needs `components/split-button.css`, missing from stylesheets/foundation-only.css — add `@import '../../../../resources/css/components/split-button.css';`",
|
||||
]);
|
||||
});
|
||||
|
||||
it('counts what an imported package stylesheet already brings in, through its own imports', function () {
|
||||
$violations = DesignGuard::scan(realpath(GUARD_FIXTURES.'/stylesheets/views/dependencies.blade.php'))
|
||||
->missingStylesheets(realpath(GUARD_FIXTURES.'/stylesheets/split-button.css'))
|
||||
->violations();
|
||||
|
||||
expect($violations)->toBe([]);
|
||||
});
|
||||
|
||||
it('needs nothing more once the entry imports all.css', function () {
|
||||
$violations = DesignGuard::scan(realpath(GUARD_FIXTURES.'/stylesheets/views'))
|
||||
->missingStylesheets(realpath(GUARD_FIXTURES.'/stylesheets/all.css'))
|
||||
->violations();
|
||||
|
||||
expect($violations)->toBe([]);
|
||||
});
|
||||
|
||||
it('requires foundation.css whatever the views hold', function () {
|
||||
$violations = fixtureRelative(DesignGuard::scan(realpath(GUARD_FIXTURES.'/stylesheets/views/plain.blade.php'))
|
||||
->missingStylesheets(realpath(GUARD_FIXTURES.'/stylesheets/missing-foundation.css'))
|
||||
->violations());
|
||||
|
||||
expect($violations)->toBe([
|
||||
"stylesheets/missing-foundation.css:1 the CSS entry never imports `foundation.css`, required by every package stylesheet — add `@import '../../../../resources/css/foundation.css';`",
|
||||
]);
|
||||
});
|
||||
|
||||
it('recognises a package tag written under the configured prefix', function () {
|
||||
config(['livewire-material.prefix' => 'm']);
|
||||
|
||||
$violations = fixtureRelative(DesignGuard::scan(realpath(GUARD_FIXTURES.'/stylesheets/views/prefixed.blade.php'))
|
||||
->missingStylesheets(realpath(GUARD_FIXTURES.'/stylesheets/foundation-only.css'))
|
||||
->violations());
|
||||
|
||||
expect($violations)->toBe([
|
||||
"stylesheets/views/prefixed.blade.php:1 `<x-button>` needs `components/button.css`, missing from stylesheets/foundation-only.css — add `@import '../../../../resources/css/components/button.css';`",
|
||||
]);
|
||||
});
|
||||
|
||||
it('recognises a package tag written fully qualified', function () {
|
||||
$violations = fixtureRelative(DesignGuard::scan(realpath(GUARD_FIXTURES.'/stylesheets/views/namespaced.blade.php'))
|
||||
->missingStylesheets(realpath(GUARD_FIXTURES.'/stylesheets/foundation-only.css'))
|
||||
->violations());
|
||||
|
||||
expect($violations)->toBe([
|
||||
"stylesheets/views/namespaced.blade.php:1 `<x-button>` needs `components/button.css`, missing from stylesheets/foundation-only.css — add `@import '../../../../resources/css/components/button.css';`",
|
||||
]);
|
||||
});
|
||||
|
||||
it('needs pagination.css when a view calls ->links()', function () {
|
||||
$violations = fixtureRelative(DesignGuard::scan(realpath(GUARD_FIXTURES.'/stylesheets/views/pagination.blade.php'))
|
||||
->missingStylesheets(realpath(GUARD_FIXTURES.'/stylesheets/foundation-only.css'))
|
||||
->violations());
|
||||
|
||||
expect($violations)->toBe([
|
||||
"stylesheets/views/pagination.blade.php:1 `->links()` needs `components/pagination.css`, missing from stylesheets/foundation-only.css — add `@import '../../../../resources/css/components/pagination.css';`",
|
||||
]);
|
||||
});
|
||||
|
||||
it('reports a package tag the application shadows with its own anonymous component', function () {
|
||||
$views = sys_get_temp_dir().'/livewire-material-guard-shadow-'.uniqid();
|
||||
File::ensureDirectoryExists($views.'/components');
|
||||
File::put($views.'/components/button.blade.php', '<span>the application\'s button</span>');
|
||||
View::getFinder()->prependLocation($views);
|
||||
|
||||
try {
|
||||
$violations = fixtureRelative(DesignGuard::scan(realpath(GUARD_FIXTURES.'/stylesheets/views/shadow.blade.php'))
|
||||
->missingStylesheets(realpath(GUARD_FIXTURES.'/stylesheets/all.css'))
|
||||
->violations());
|
||||
} finally {
|
||||
File::deleteDirectory($views);
|
||||
}
|
||||
|
||||
expect($violations)->toBe([
|
||||
"stylesheets/views/shadow.blade.php:1 `<x-button>` is shadowed by the application's own component of the same name — the package's `<x-button>` never renders here",
|
||||
]);
|
||||
});
|
||||
|
||||
it('reports a package tag the application shadows with its own component class', function () {
|
||||
if (! class_exists('App\View\Components\Card', false)) {
|
||||
eval('namespace App\View\Components; class Card {}');
|
||||
}
|
||||
|
||||
$violations = fixtureRelative(DesignGuard::scan(realpath(GUARD_FIXTURES.'/stylesheets/views/shadow-class.blade.php'))
|
||||
->missingStylesheets(realpath(GUARD_FIXTURES.'/stylesheets/all.css'))
|
||||
->violations());
|
||||
|
||||
expect($violations)->toBe([
|
||||
"stylesheets/views/shadow-class.blade.php:1 `<x-card>` is shadowed by the application's own component of the same name — the package's `<x-card>` never renders here",
|
||||
]);
|
||||
});
|
||||
|
||||
it('passes the package\'s own views', function () {
|
||||
$violations = DesignGuard::scan([__DIR__.'/../../resources/views', __DIR__.'/../../resources/js', __DIR__.'/../../src'])->violations();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user