failed()) { $this->markTestSkipped("Node ({$node}) could not run; `npm run check:font` reads the woff2's axes."); } $result = Process::run([$node, __DIR__.'/../../bin/check-font.mjs']); expect($result->successful())->toBeTrue($result->errorOutput()); $font = json_decode($result->output(), true, flags: JSON_THROW_ON_ERROR); expect($font['axes'])->toHaveKeys(['wght', 'ROND']) // font.css declares `font-weight: 400 700`; every typescale weight is inside it. ->and($font['axes']['wght'])->toMatchArray(['min' => 400, 'max' => 700]) // The axis every `type-emphasized-*` utility sets to 100; a re-subset must keep it. ->and($font['axes']['ROND'])->toMatchArray(['min' => 0, 'max' => 100]); }); it('fails loudly when the font has no variable axes at all', function () { $node = config('livewire-material.node', 'node'); if (Process::run([$node, '--version'])->failed()) { $this->markTestSkipped("Node ({$node}) could not run; `npm run check:font` reads the woff2's axes."); } $result = Process::run([$node, __DIR__.'/../../bin/check-font.mjs', __DIR__.'/../Fixtures/no-such-font.woff2']); expect($result->failed())->toBeTrue() ->and($result->errorOutput())->toContain('no-such-font.woff2'); });