packages/requirements/tests/Unit/Config/CoverageThresholdsTest.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\CoverageThresholds;
13use Requirements\Input\Fields;
14use Requirements\Input\InvalidInputException;
15use Requirements\Model\Source;
16
17#[CoversClass(CoverageThresholds::class)]
18#[UsesClass(Fields::class)]
19#[UsesClass(Source::class)]
20#[Small]
21final class CoverageThresholdsTest extends TestCase
22{
23 public function testReadReturnsThresholdsAsFloats(): void
24 {
25 $sources = ['manual' => new Source('manual', 'source.html', 'html', 'main p'), 'rfc' => new Source('rfc', 'rfc.xml', 'xml', 't')];
26 self::assertSame(['manual' => 80.0, 'rfc' => 12.5], (new CoverageThresholds())->read(['manual' => 80, 'rfc' => 12.5], $sources));
27 }
28
29 public function testReadAcceptsNoThresholds(): void
30 {
31 self::assertSame([], (new CoverageThresholds())->read([], ['manual' => new Source('manual', 'source.html', 'html', 'main p')]));
32 }
33
34 public function testReadAcceptsBounds(): void
35 {
36 $sources = ['low' => new Source('low', 'source.html', 'html', 'p'), 'high' => new Source('high', 'source.html', 'html', 'p')];
37 self::assertSame(['low' => 0.0, 'high' => 100.0], (new CoverageThresholds())->read(['low' => 0, 'high' => 100], $sources));
38 }
39
40 #[DataProvider('providerInvalid')]
41 public function testReadRejectsInvalidThresholds(mixed $value, string $message): void
42 {
43 $this->expectException(InvalidInputException::class);
44 $this->expectExceptionMessage($message);
45 (new CoverageThresholds())->read($value, ['manual' => new Source('manual', 'source.html', 'html', 'main p')]);
46 }
47
48 /**
49 * @return array<string, array{mixed, string}>
50 */
51 public static function providerInvalid(): array
52 {
53 return [
54 'unknown source' => [['manual' => 50, 'other' => 50], 'Unknown source threshold: other'],
55 'above one hundred' => [['manual' => 100.5], 'coverage.sources.manual must be a number from 0 to 100.'],
56 'negative' => [['manual' => -1], 'coverage.sources.manual must be a number from 0 to 100.'],
57 'not a number' => [['manual' => '50'], 'coverage.sources.manual must be a number from 0 to 100.'],
58 'not a mapping' => ['manual', 'coverage.sources must be a mapping.'],
59 'list' => [[50], 'coverage.sources must have string keys.'],
60 ];
61 }
62}
63