packages/requirements/tests/Unit/Config/ExtensionClassesTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Config;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\Attributes\Small;
10use PHPUnit\Framework\Attributes\UsesClass;
11use PHPUnit\Framework\TestCase;
12use Requirements\Config\ExtensionClasses;
13use Requirements\Input\Fields;
14use Requirements\Input\InvalidInputException;
15use Tests\Fake\CountingRunner;
16use Tests\Fake\MemorySource;
17
18#[CoversClass(ExtensionClasses::class)]
19#[UsesClass(Fields::class)]
20#[Small]
21final class ExtensionClassesTest extends TestCase
22{
23    public function testReadReturnsClassNamesByName(): void
24    {
25        self::assertSame(['memory' => MemorySource::class, 'counting' => CountingRunner::class], ExtensionClasses::read(['memory' => MemorySource::class, 'counting' => CountingRunner::class]));
26    }
27
28    public function testReadAcceptsEmptyMapping(): void
29    {
30        self::assertSame([], ExtensionClasses::read([]));
31    }
32
33    public function testReadKeepsNamesThatAreNotClasses(): void
34    {
35        self::assertSame(['memory' => 'Missing\\Extension'], ExtensionClasses::read(['memory' => 'Missing\\Extension']));
36    }
37
38    #[DataProvider('providerInvalid')]
39    public function testReadRejectsInvalidMapping(mixed $value, string $message): void
40    {
41        $this->expectException(InvalidInputException::class);
42        $this->expectExceptionMessage($message);
43        ExtensionClasses::read($value);
44    }
45
46    /**
47     * @return array<string, array{mixed, string}>
48     */
49    public static function providerInvalid(): array
50    {
51        return [
52            'not a mapping' => [MemorySource::class, 'extensions must be a mapping.'],
53            'list' => [[MemorySource::class], 'extensions must have string keys.'],
54            'empty class name' => [['memory' => ''], 'memory must be a nonempty string.'],
55            'blank class name' => [['memory' => MemorySource::class, 'counting' => ' '], 'counting must be a nonempty string.'],
56            'class name not a string' => [['memory' => 1], 'memory must be a nonempty string.'],
57        ];
58    }
59}
60