tests / lint (push) Successful in 1m6s
tests / feature (8.4) (push) Successful in 1m12s
tests / feature (8.5) (push) Successful in 1m16s
tests / browser (chrome, chromium) (push) Successful in 3m17s
tests / browser (firefox, firefox) (push) Successful in 4m43s
tests / browser (safari, webkit) (push) Successful in 5m22s
The check sat beside the name and truncated it at four columns; it now sits in the tile's corner under the swatch dots. Attributes other than the binding (data-test, class) reach the fieldset, and the dots' ring follows the selected tile's colour. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
69 lines
3.3 KiB
PHP
69 lines
3.3 KiB
PHP
<?php
|
|
|
|
use Illuminate\Support\Facades\File;
|
|
|
|
beforeEach(function () {
|
|
$this->path = sys_get_temp_dir().'/scheme-picker-'.uniqid().'.json';
|
|
File::put($this->path, json_encode([
|
|
'default' => 'indigo',
|
|
'profiles' => [
|
|
'indigo' => ['label' => 'Indigo', 'light' => ['primary' => '#4f46e5', 'secondary' => '#5b5d72', 'tertiary' => '#77536d'], 'dark' => ['primary' => '#c0c1ff', 'secondary' => '#c4c5dd', 'tertiary' => '#e6bad7']],
|
|
'teal' => ['label' => 'Teal', 'light' => ['primary' => '#00897b', 'secondary' => '#4a635f', 'tertiary' => '#456179'], 'dark' => ['primary' => '#80cbc4', 'secondary' => '#b1ccc6', 'tertiary' => '#adcae5']],
|
|
],
|
|
]));
|
|
config(['livewire-material.scheme' => $this->path]);
|
|
});
|
|
|
|
afterEach(function () {
|
|
File::delete($this->path);
|
|
});
|
|
|
|
it('draws a radio per generated profile, bound, named and previewing on change', function () {
|
|
$html = (string) $this->blade('<x-scheme-picker label="Colour profile" hint="Applies after saving" wire:model="colorProfile" />');
|
|
|
|
expect($html)
|
|
->toContain('<legend class="mb-2 type-label-lg text-on-surface-variant">Colour profile</legend>')
|
|
->toContain('Applies after saving')
|
|
->toContain('data-scheme-option="indigo"')
|
|
->toContain('data-scheme-option="teal"')
|
|
->toMatch('/<input\s+wire:model="colorProfile"\s+type="radio"\s+name="colorProfile"\s+value="teal"/')
|
|
->toContain('x-on:change="$store.theme.previewScheme($event.target.value)"')
|
|
->toContain('>Teal</span>')
|
|
->toContain('style="--swatch-light: #00897b; --swatch-dark: #80cbc4"');
|
|
});
|
|
|
|
it('puts its other attributes on the group and the binding on the radios', function () {
|
|
$html = (string) $this->blade('<x-scheme-picker wire:model="colorProfile" data-test="color-profile" class="mt-4" />');
|
|
|
|
expect($html)->toMatch('/<fieldset x-data data-scheme-picker class="min-w-0 mt-4" data-test="color-profile">/')
|
|
->and(substr_count($html, 'wire:model="colorProfile"'))->toBe(2)
|
|
->and(substr_count($html, 'data-test="color-profile"'))->toBe(1);
|
|
});
|
|
|
|
it('keeps its inline styles to the scheme file\'s checked colours', function () {
|
|
File::put($this->path, json_encode([
|
|
'default' => 'indigo',
|
|
'profiles' => ['indigo' => ['label' => 'Indigo', 'light' => ['primary' => 'red; background: url(x)'], 'dark' => []]],
|
|
]));
|
|
|
|
$html = (string) $this->blade('<x-scheme-picker wire:model="colorProfile" />');
|
|
|
|
preg_match_all('/style="([^"]*)"/', $html, $styles);
|
|
|
|
expect($styles[1])->not->toBeEmpty()
|
|
->each->toMatch('/^--swatch-light: #[0-9a-fA-F]{6}; --swatch-dark: #[0-9a-fA-F]{6}$/');
|
|
});
|
|
|
|
it('shows a validation message for the bound property instead of the hint', function () {
|
|
$this->withViewErrors(['colorProfile' => ['Choose one of the colour profiles.']])
|
|
->blade('<x-scheme-picker wire:model="colorProfile" hint="Applies after saving" />')
|
|
->assertSee('Choose one of the colour profiles.')
|
|
->assertDontSee('Applies after saving');
|
|
});
|
|
|
|
it('renders nothing for a single scheme', function () {
|
|
File::put($this->path, json_encode(['light' => ['primary' => '#123456'], 'dark' => []]));
|
|
|
|
expect(trim((string) $this->blade('<x-scheme-picker wire:model="colorProfile" />')))->toBe('');
|
|
});
|