1<?php 2 3namespace Drupal\Tests\Component\Discovery; 4 5use Drupal\Component\Discovery\DiscoveryException; 6use Drupal\Component\Discovery\YamlDirectoryDiscovery; 7use Drupal\Component\FileCache\FileCacheFactory; 8use org\bovigo\vfs\vfsStream; 9use PHPUnit\Framework\TestCase; 10 11/** 12 * YamlDirectoryDiscoveryTest component unit tests. 13 * 14 * @coversDefaultClass \Drupal\Component\Discovery\YamlDirectoryDiscovery 15 * 16 * @group Discovery 17 */ 18class YamlDirectoryDiscoveryTest extends TestCase { 19 20 /** 21 * {@inheritdoc} 22 */ 23 protected function setUp(): void { 24 // Ensure that FileCacheFactory has a prefix. 25 FileCacheFactory::setPrefix('prefix'); 26 } 27 28 /** 29 * Tests YAML directory discovery. 30 * 31 * @covers ::findAll 32 */ 33 public function testDiscovery() { 34 vfsStream::setup('modules', NULL, [ 35 'test_1' => [ 36 'subdir1' => [ 37 'item_1.test.yml' => "id: item1\nname: 'test1 item 1'", 38 ], 39 'subdir2' => [ 40 'item_2.test.yml' => "id: item2\nname: 'test1 item 2'", 41 ], 42 ], 43 'test_2' => [ 44 'subdir1' => [ 45 'item_3.test.yml' => "id: item3\nname: 'test2 item 3'", 46 ], 47 'subdir2' => [], 48 ], 49 'test_3' => [], 50 'test_4' => [ 51 'subdir1' => [ 52 'item_4.test.yml' => "id: item4\nname: 'test4 item 4'", 53 'item_5.test.yml' => "id: item5\nname: 'test4 item 5'", 54 'item_6.test.yml' => "id: item6\nname: 'test4 item 6'", 55 ], 56 ], 57 ]); 58 59 // Set up the directories to search. 60 $directories = [ 61 // Multiple directories both with valid items. 62 'test_1' => [ 63 vfsStream::url('modules/test_1/subdir1'), 64 vfsStream::url('modules/test_1/subdir2'), 65 ], 66 // The subdir2 directory is empty. 67 'test_2' => [ 68 vfsStream::url('modules/test_2/subdir1'), 69 vfsStream::url('modules/test_2/subdir2'), 70 ], 71 // Directories that do not exist. 72 'test_3' => [ 73 vfsStream::url('modules/test_3/subdir1'), 74 vfsStream::url('modules/test_3/subdir2'), 75 ], 76 // A single directory. 77 'test_4' => vfsStream::url('modules/test_4/subdir1'), 78 ]; 79 80 $discovery = new YamlDirectoryDiscovery($directories, 'test'); 81 $data = $discovery->findAll(); 82 83 $this->assertSame(['id' => 'item1', 'name' => 'test1 item 1', YamlDirectoryDiscovery::FILE_KEY => 'vfs://modules/test_1/subdir1/item_1.test.yml'], $data['test_1']['item1']); 84 $this->assertSame(['id' => 'item2', 'name' => 'test1 item 2', YamlDirectoryDiscovery::FILE_KEY => 'vfs://modules/test_1/subdir2/item_2.test.yml'], $data['test_1']['item2']); 85 $this->assertCount(2, $data['test_1']); 86 87 $this->assertSame(['id' => 'item3', 'name' => 'test2 item 3', YamlDirectoryDiscovery::FILE_KEY => 'vfs://modules/test_2/subdir1/item_3.test.yml'], $data['test_2']['item3']); 88 $this->assertCount(1, $data['test_2']); 89 90 $this->assertTrue(empty($data['test_3']), 'test_3 provides 0 items'); 91 92 $this->assertSame(['id' => 'item4', 'name' => 'test4 item 4', YamlDirectoryDiscovery::FILE_KEY => 'vfs://modules/test_4/subdir1/item_4.test.yml'], $data['test_4']['item4']); 93 $this->assertSame(['id' => 'item5', 'name' => 'test4 item 5', YamlDirectoryDiscovery::FILE_KEY => 'vfs://modules/test_4/subdir1/item_5.test.yml'], $data['test_4']['item5']); 94 $this->assertSame(['id' => 'item6', 'name' => 'test4 item 6', YamlDirectoryDiscovery::FILE_KEY => 'vfs://modules/test_4/subdir1/item_6.test.yml'], $data['test_4']['item6']); 95 $this->assertCount(3, $data['test_4']); 96 } 97 98 /** 99 * Tests YAML directory discovery with an alternate ID key. 100 * 101 * @covers ::findAll 102 */ 103 public function testDiscoveryAlternateId() { 104 vfsStream::setup('modules', NULL, [ 105 'test_1' => [ 106 'item_1.test.yml' => "alt_id: item1\nid: ignored", 107 ], 108 ]); 109 110 // Set up the directories to search. 111 $directories = ['test_1' => vfsStream::url('modules/test_1')]; 112 113 $discovery = new YamlDirectoryDiscovery($directories, 'test', 'alt_id'); 114 $data = $discovery->findAll(); 115 116 $this->assertSame(['alt_id' => 'item1', 'id' => 'ignored', YamlDirectoryDiscovery::FILE_KEY => 'vfs://modules/test_1/item_1.test.yml'], $data['test_1']['item1']); 117 $this->assertCount(1, $data['test_1']); 118 } 119 120 /** 121 * Tests YAML directory discovery with a missing ID key. 122 * 123 * @covers ::findAll 124 * @covers ::getIdentifier 125 */ 126 public function testDiscoveryNoIdException() { 127 $this->expectException(DiscoveryException::class); 128 $this->expectExceptionMessage('The vfs://modules/test_1/item_1.test.yml contains no data in the identifier key \'id\''); 129 vfsStream::setup('modules', NULL, [ 130 'test_1' => [ 131 'item_1.test.yml' => "", 132 ], 133 ]); 134 135 // Set up the directories to search. 136 $directories = ['test_1' => vfsStream::url('modules/test_1')]; 137 138 $discovery = new YamlDirectoryDiscovery($directories, 'test'); 139 $discovery->findAll(); 140 } 141 142 /** 143 * Tests YAML directory discovery with invalid YAML. 144 * 145 * @covers ::findAll 146 */ 147 public function testDiscoveryInvalidYamlException() { 148 $this->expectException(DiscoveryException::class); 149 $this->expectExceptionMessage('The vfs://modules/test_1/item_1.test.yml contains invalid YAML'); 150 vfsStream::setup('modules', NULL, [ 151 'test_1' => [ 152 'item_1.test.yml' => "id: invalid\nfoo : [bar}", 153 ], 154 ]); 155 156 // Set up the directories to search. 157 $directories = ['test_1' => vfsStream::url('modules/test_1')]; 158 159 $discovery = new YamlDirectoryDiscovery($directories, 'test'); 160 $discovery->findAll(); 161 } 162 163} 164