StylesheetsTest.php's new test runs DesignGuard's own family table (check (i)) over resources/views, resources/js, src, tests/Browser and tests/Feature — the guard turned on the package's own source, so the two never drift apart. tests/Feature/DesignGuardTest.php and tests/Fixtures/design-guard/ carry Tailwind on purpose and are left out. The scan found Tailwind-shaped class strings used as caller classes in 21 test files (a component test proving a caller's class lands on the root or a caller's size wins, mostly), left over from before Tailwind cleared the whole stack: replaced with neutral application-style names (`app-hero-icon`) or, where one already carries the right meaning, an `md-*` class (`md-text-end`, `md-ink-warning`). BreakpointsTest.php's own heredoc probe — which needs a genuine Tailwind-shaped breakpoint prefix to prove its detection works — now builds that one string from a placeholder at runtime, so its own source stays clean for this same scan. Plan step 42 (Phase F), Part A. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
68 lines
3.4 KiB
PHP
68 lines
3.4 KiB
PHP
<?php
|
|
|
|
use NoNameWeb\LivewireMaterial\Tests\Support\ComponentStylesheet;
|
|
|
|
it('is a named progressbar, drawn by its stylesheet rather than by classes', function () {
|
|
$html = (string) $this->blade('<x-loading />');
|
|
|
|
expect($html)
|
|
->toContain('data-md-loading')
|
|
->toContain('role="progressbar"')
|
|
->toContain('aria-label="Loading"')
|
|
->toContain('<animateTransform')
|
|
->toMatch('/<svg data-md-loading-animated="data-md-loading-animated" aria-hidden="true" focusable="false"/')
|
|
->toMatch('/<svg data-md-loading-still="data-md-loading-still" aria-hidden="true" focusable="false"/')
|
|
->not->toContain('class=');
|
|
});
|
|
|
|
it('is 48px in the primary colour unless the caller sizes or colours it', function () {
|
|
$css = ComponentStylesheet::read('loading');
|
|
|
|
expect($css->declarations('[data-md-loading]'))
|
|
->toMatchArray(['inline-size' => '48px', 'block-size' => '48px', 'color' => 'var(--md-sys-color-primary)'])
|
|
// A caller's class lands on the root untouched, and outranks the package's layer.
|
|
->and((string) $this->blade('<x-loading class="app-upload-spinner" label="Uploading" />'))
|
|
->toContain('class="app-upload-spinner"')
|
|
->toContain('aria-label="Uploading"');
|
|
});
|
|
|
|
it('sits on a primary-container circle when contained', function () {
|
|
expect((string) $this->blade('<x-loading contained />'))->toContain('data-md-contained')
|
|
->and((string) $this->blade('<x-loading />'))->not->toContain('data-md-contained')
|
|
->and(ComponentStylesheet::read('loading')->declarations('[data-md-loading][data-md-contained]'))->toBe([
|
|
'border-radius' => 'var(--md-sys-shape-corner-full)',
|
|
'background-color' => 'var(--md-sys-color-primary-container)',
|
|
'color' => 'var(--md-sys-color-on-primary-container)',
|
|
]);
|
|
});
|
|
|
|
it('rests the same shape under reduced motion', function () {
|
|
$css = ComponentStylesheet::read('loading');
|
|
|
|
expect($css->declarations('[data-md-loading] > [data-md-loading-still]'))->toBe(['display' => 'none'])
|
|
->and($css->declarations('[data-md-loading] > [data-md-loading-animated]', ['@media (prefers-reduced-motion: reduce)']))->toBe(['display' => 'none'])
|
|
->and($css->declarations('[data-md-loading] > [data-md-loading-still]', ['@media (prefers-reduced-motion: reduce)']))->toBe(['display' => 'block']);
|
|
});
|
|
|
|
it('says nothing where something else already does', function () {
|
|
expect((string) $this->blade('<x-loading :label="false" />'))
|
|
->toContain('aria-hidden="true"')
|
|
->not->toContain('role="progressbar"');
|
|
|
|
expect((string) $this->blade('<x-button label="Save" wire:click="save" spinner />'))
|
|
->toContain('<animateTransform')
|
|
->not->toContain('role="progressbar"');
|
|
});
|
|
|
|
it('animates without script and rests the same shape', function () {
|
|
$animated = file_get_contents(__DIR__.'/../../../resources/svg/loading-indicator/indeterminate.svg');
|
|
$static = file_get_contents(__DIR__.'/../../../resources/svg/loading-indicator/static.svg');
|
|
|
|
expect($animated)->toStartWith('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" fill="currentColor">')
|
|
->toContain('repeatCount="indefinite"')
|
|
->not->toContain('<script')
|
|
->not->toContain('__ID__')
|
|
->and($static)->toStartWith('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" fill="currentColor">')
|
|
->not->toContain('<animate');
|
|
});
|