packages/requirements/tests/Unit/Config/Markdown/StaticBadgeTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Config\Markdown;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\Attributes\Small;
10use PHPUnit\Framework\TestCase;
11use Requirements\Config\Markdown\StaticBadge;
12use Requirements\Input\InvalidInputException;
13
14#[CoversClass(StaticBadge::class)]
15#[Small]
16final class StaticBadgeTest extends TestCase
17{
18    #[DataProvider('providerAgreeingBadges')]
19    public function testValidateAcceptsAgreeingOrUncheckedImages(string $url, string $field, string $value): void
20    {
21        StaticBadge::validate($url, $field, $value);
22        $this->addToAssertionCount(1);
23    }
24
25    /**
26     * @return array<string, array{string, string, string}>
27     */
28    public static function providerAgreeingBadges(): array
29    {
30        return [
31            'other host' => ['https://example.org/badge/status-supported-blue', 'status', 'unsupported'],
32            'relative image' => ['assets/grammar.svg', 'label', 'grammar'],
33            'other shields path' => ['https://img.shields.io/static/v1?label=status&message=supported', 'status', 'unsupported'],
34            'other shields role' => ['https://img.shields.io/badge/color-red-blue', 'label', 'anything'],
35            'status' => ['https://img.shields.io/badge/status-unsupported-orange', 'status', 'unsupported'],
36            'kind' => ['https://img.shields.io/badge/kind-requirement-blue', 'kind', 'requirement'],
37            'origin' => ['https://img.shields.io/badge/origin-original-blue', 'origin', 'original'],
38            'category' => ['https://img.shields.io/badge/category-lexical-blue', 'category', 'lexical'],
39            'escaped leading dash' => ['https://img.shields.io/badge/category---names-blue', 'category', '-names'],
40            'escaped trailing dash' => ['https://img.shields.io/badge/label-end---blue', 'label', 'end-'],
41            'escaped underscore' => ['https://img.shields.io/badge/label-under__score-blue', 'label', 'under_score'],
42            'underscore as space' => ['https://img.shields.io/badge/label-with_spaces-blue', 'label', 'with spaces'],
43            'percent-encoded space' => ['https://img.shields.io/badge/label-with%20spaces-blue', 'label', 'with spaces'],
44            'unicode' => ['https://img.shields.io/badge/label-%E6%97%A5%E6%9C%AC%E8%AA%9E-blue', 'label', '日本語'],
45        ];
46    }
47
48    #[DataProvider('providerMisleadingBadges')]
49    public function testValidateRejectsMisleadingStaticImages(string $url, string $field, string $value): void
50    {
51        $this->expectException(InvalidInputException::class);
52        $this->expectExceptionMessage('Static badge image text and role must agree with its alt text and title.');
53        StaticBadge::validate($url, $field, $value);
54    }
55
56    /**
57     * @return array<string, array{string, string, string}>
58     */
59    public static function providerMisleadingBadges(): array
60    {
61        return [
62            'other value' => ['https://img.shields.io/badge/status-supported-blue', 'status', 'unsupported'],
63            'other role' => ['https://img.shields.io/badge/status-supported-blue', 'label', 'supported'],
64            'unescaped dash' => ['https://img.shields.io/badge/label-a-b-blue', 'label', 'a-b'],
65            'no color' => ['https://img.shields.io/badge/label-grammar', 'label', 'grammar'],
66            'underscore is not kept' => ['https://img.shields.io/badge/label-under_score-blue', 'label', 'under_score'],
67        ];
68    }
69}
70