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