blade('')) ->toContain('size-1.5 rounded-corner-full') ->toContain('bg-error text-on-error') ->toContain('aria-hidden="true"'); }); it('is M3\'s large badge with a count, capped by max', function () { expect((string) $this->blade(''))->toContain('h-4 min-w-4')->toContain('>4') ->and((string) $this->blade(''))->toContain('>999+') ->and((string) $this->blade(''))->toContain('>12')->toContain('bg-primary text-on-primary'); }); it('pins itself to the corner of an icon when floating', function () { expect((string) $this->blade(''))->toContain('absolute top-0.5 end-0.5') ->and((string) $this->blade('')) ->toContain('absolute -top-1') ->toContain('aria-label="3 new messages"') ->not->toContain('aria-hidden'); }); it('draws a status label in a container or an outline', function () { expect((string) $this->blade('')) ->toContain('h-6 gap-1 rounded-corner-sm px-2 type-label-md') ->toContain('bg-success-container text-on-success-container') ->not->toContain('aria-hidden') ->and((string) $this->blade('')) ->toContain('border border-outline-variant text-on-surface-variant') ->not->toContain('bg-error'); }); it('renders its slot as HTML, and is a dot while the slot holds nothing but comments', function () { $html = (string) $this->blade(' Pro'); expect($html) ->toContain('h-6 gap-1 rounded-corner-sm') ->toContain('toContain(' Pro') ->not->toContain('<svg') ->and((string) $this->blade(''))->toContain('<b>4</b>') ->and((string) $this->blade("\n \n"))->toContain('size-1.5 rounded-corner-full') ->and((string) $this->blade('120'))->toContain('>99+'); }); it('draws neutral ink on every variant', function () { expect((string) $this->blade(''))->toContain('size-1.5 rounded-corner-full bg-on-surface-variant text-surface') ->and((string) $this->blade(''))->toContain('tabular-nums bg-on-surface-variant text-surface') ->and((string) $this->blade(''))->toContain('type-label-md bg-surface-container-high text-on-surface-variant') ->and((string) $this->blade(''))->toContain('type-label-md border border-outline-variant text-on-surface-variant'); }); it('leaves a plain badge to the caller\'s colour classes', function (string $badge, string $shape) { $html = (string) $this->blade($badge); preg_match('/class="([^"]*)"/', $html, $class); expect($class[1]) ->toContain($shape) ->toEndWith('bg-tertiary-container text-on-tertiary-container') ->and(preg_replace('/bg-tertiary-container text-on-tertiary-container$/', '', $class[1]))->not->toMatch('/(^|\s)(bg|text|border)-/'); })->with([ 'dot' => ['', 'size-1.5 rounded-corner-full'], 'count' => ['', 'h-4 min-w-4 rounded-corner-full px-1 type-label-sm tabular-nums'], 'tonal' => ['', 'h-6 gap-1 rounded-corner-sm px-2 type-label-md'], 'outline' => ['', 'h-6 gap-1 rounded-corner-sm px-2 type-label-md border'], ]); it('keeps its default colours, and falls back to error on a colour it does not know', function () { expect((string) $this->blade('')) ->toContain('class="inline-flex shrink-0 items-center justify-center whitespace-nowrap h-4 min-w-4 rounded-corner-full px-1 type-label-sm tabular-nums bg-error text-on-error"') ->and((string) $this->blade('')) ->toContain('class="inline-flex shrink-0 items-center justify-center whitespace-nowrap h-6 gap-1 rounded-corner-sm px-2 type-label-md bg-error-container text-on-error-container"') ->and((string) $this->blade('')) ->toContain('class="inline-flex shrink-0 items-center justify-center whitespace-nowrap h-6 gap-1 rounded-corner-sm px-2 type-label-md border border-outline-variant text-on-surface-variant"') ->and((string) $this->blade(''))->toContain('bg-error text-on-error'); }); it('draws a solid status label in the colour itself, spoken like any label', function () { $html = (string) $this->blade(''); expect($html) ->toContain('bg-primary text-on-primary') ->toContain('h-6 gap-1 rounded-corner-sm px-2 type-label-md') ->not->toContain('aria-hidden') ->toContain('>Built in<') ->and((string) $this->blade('')) ->toContain('bg-on-surface-variant text-surface') ->and((string) $this->blade('')) ->toContain('size-1.5'); });