stylesheet = sys_get_temp_dir().'/material-scheme-'.Str::random(8).'.css'; $this->data = Str::replaceLast('.css', '.json', $this->stylesheet); }); afterEach(function () { File::delete([$this->stylesheet, $this->data]); }); it('writes the scheme as a stylesheet and as data', function () { $this->artisan('material:scheme', ['seed' => '#4F46E5', '--output' => $this->stylesheet]) ->assertSuccessful(); $scheme = json_decode(File::get($this->data), true); $stylesheet = File::get($this->stylesheet); expect($scheme) ->seed->toBe('#4f46e5') ->variant->toBe('tonal-spot') ->spec->toBe('2025') ->and(array_keys($scheme['dark']))->toEqual(array_keys($scheme['light'])) ->and($scheme['light'])->toHaveKeys(['primary', 'on-primary', 'tertiary-container', 'surface-container-high', 'outline-variant', 'success', 'on-warning-container', 'info-container']) ->and($scheme['light']['surface'])->not->toBe($scheme['dark']['surface']) ->and($scheme['light']['inverse-success'])->toBe($scheme['dark']['success']); foreach (['light' => "[data-theme='light']", 'dark' => "[data-theme='dark']"] as $theme => $selector) { $block = Str::of($stylesheet)->after($selector)->before('}')->toString(); expect($block)->toContain("color-scheme: {$theme};"); foreach ($scheme[$theme] as $role => $hex) { expect($block)->toContain("--md-sys-color-{$role}: {$hex};"); } } expect($stylesheet)->toContain('php artisan material:scheme "#4f46e5" --variant=tonal-spot'); }); it('generates a different scheme per variant', function () { $this->artisan('material:scheme', ['seed' => '#4f46e5', '--variant' => 'vibrant', '--output' => $this->stylesheet]) ->assertSuccessful(); $vibrant = json_decode(File::get($this->data), true); $this->artisan('material:scheme', ['seed' => '#4f46e5', '--output' => $this->stylesheet]) ->assertSuccessful(); $tonalSpot = json_decode(File::get($this->data), true); expect($vibrant['variant'])->toBe('vibrant') ->and($vibrant['light']['primary'])->not->toBe($tonalSpot['light']['primary']); }); it('refuses a seed that is not a colour', function () { $this->artisan('material:scheme', ['seed' => 'indigo', '--output' => $this->stylesheet]) ->expectsOutputToContain('#rrggbb') ->assertFailed(); expect(File::exists($this->stylesheet))->toBeFalse(); }); it('refuses an unknown variant', function () { $this->artisan('material:scheme', ['seed' => '#4f46e5', '--variant' => 'loud', '--output' => $this->stylesheet]) ->expectsOutputToContain('Unknown variant "loud"') ->assertFailed(); }); it('fails without writing anything when node cannot run', function () { config(['livewire-material.node' => '/nonexistent/node']); $this->artisan('material:scheme', ['seed' => '#4f46e5', '--output' => $this->stylesheet]) ->assertFailed(); expect(File::exists($this->stylesheet))->toBeFalse(); });