packages/requirements/tests/Unit/Source/UnitTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Source;
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\Model\Source;
13use Requirements\Source\Unit;
14
15#[CoversClass(Unit::class)]
16#[UsesClass(Source::class)]
17#[Small]
18final class UnitTest extends TestCase
19{
20 public function testKeyHashesTheUriFormatAndLocation(): void
21 {
22 $unit = new Unit('line:1', 'Names start with a letter.');
23
24 self::assertSame(hash('sha256', "notes.txt\0text\0line:1"), $unit->key(new Source('notes', 'notes.txt', 'text', 'lines:1')));
25 }
26
27 public function testKeyIgnoresTheIdSelectorAndText(): void
28 {
29 $key = (new Unit('line:1', 'First.'))->key(new Source('notes', 'notes.txt', 'text', 'lines:1'));
30
31 self::assertSame($key, (new Unit('line:1', 'Second.'))->key(new Source('other', 'notes.txt', 'text', 'lines:1-9')));
32 }
33
34 #[DataProvider('providerKeyDistinguishes')]
35 public function testKeyDistinguishesUnits(string $uri, string $format, string $location): void
36 {
37 $key = (new Unit('line:1', 'Text.'))->key(new Source('notes', 'notes.txt', 'text', 'lines:1'));
38
39 self::assertNotSame($key, (new Unit($location, 'Text.'))->key(new Source('notes', $uri, $format, 'lines:1')));
40 }
41
42 /**
43 * @return array<string, array{string, string, string}>
44 */
45 public static function providerKeyDistinguishes(): array
46 {
47 return [
48 'uri' => ['other.txt', 'text', 'line:1'],
49 'format' => ['notes.txt', 'markdown', 'line:1'],
50 'location' => ['notes.txt', 'text', 'line:2'],
51 'boundary' => ['notes.txtte', 'xt', 'line:1'],
52 ];
53 }
54
55 #[DataProvider('providerNormalize')]
56 public function testNormalize(string $text, string $expected): void
57 {
58 self::assertSame($expected, Unit::normalize($text));
59 }
60
61 /**
62 * @return array<string, array{string, string}>
63 */
64 public static function providerNormalize(): array
65 {
66 return [
67 'collapsed whitespace' => [" Names\n\tstart with a letter. ", 'Names start with a letter.'],
68 'no-break space' => ["Names\u{00a0}\u{00a0}start.", 'Names start.'],
69 'carriage return' => ["Names\r\nstart.", 'Names start.'],
70 'blank' => [" \n\t ", ''],
71 'unicode kept' => ['日本語 text', '日本語 text'],
72 'invalid UTF-8 only trimmed' => [" \xFF text ", "\xFF text"],
73 ];
74 }
75}
76