assertCount(1, $plugins); $this->assertTrue($plugins->has('TestPlugin')); } public function testAdd(): void { $plugins = new PluginCollection(); $this->assertCount(0, $plugins); $plugins->add(new TestPlugin()); $this->assertCount(1, $plugins); } public function testAddDuplicate(): void { $this->expectException(CakeException::class); $this->expectExceptionMessage('Plugin named `TestPlugin` is already loaded'); $plugins = new PluginCollection(); $plugins->add(new TestPlugin()); $plugins->add(new TestPlugin()); } public function testAddFromConfig(): void { Configure::write('debug', false); $config = [ 'Company/TestPluginThree', 'TestPlugin' => ['onlyDebug' => true], 'Nope' => ['optional' => true], 'Named' => ['routes' => false], ]; $plugins = new PluginCollection(); $plugins->addFromConfig($config); $this->assertCount(2, $plugins); $this->assertTrue($plugins->has('Company/TestPluginThree')); $this->assertFalse($plugins->has('TestPlugin')); $this->assertFalse($plugins->get('Named')->isEnabled('routes')); } public function testAddOperations(): void { $plugins = new PluginCollection(); $plugins->add(new TestPlugin()); $this->assertFalse($plugins->has('Nope')); $this->assertSame($plugins, $plugins->remove('Nope')); $this->assertTrue($plugins->has('TestPlugin')); $this->assertSame($plugins, $plugins->remove('TestPlugin')); $this->assertCount(0, $plugins); $this->assertFalse($plugins->has('TestPlugin')); } public function testAddVendoredPlugin(): void { $plugins = new PluginCollection(); $plugins->add(new TestPluginThreePlugin()); $this->assertTrue($plugins->has('Company/TestPluginThree')); $this->assertFalse($plugins->has('TestPluginThree')); $this->assertFalse($plugins->has('Company')); $this->assertFalse($plugins->has('TestPlugin')); } public function testHas(): void { $plugins = new PluginCollection(); $this->assertFalse($plugins->has('TestPlugin')); $plugins->add(new TestPlugin()); $this->assertTrue($plugins->has('TestPlugin')); $this->assertFalse($plugins->has('Plugin')); } public function testGet(): void { $plugins = new PluginCollection(); $plugin = new TestPlugin(); $plugins->add($plugin); $this->assertSame($plugin, $plugins->get('TestPlugin')); } public function testGetAutoload(): void { $plugins = new PluginCollection(); $plugin = $plugins->get('Named'); $this->assertInstanceOf(NamedPlugin::class, $plugin); } public function testGetInvalid(): void { $this->expectException(MissingPluginException::class); $plugins = new PluginCollection(); $plugins->get('Invalid'); } public function testCreate(): void { $plugins = new PluginCollection(); $plugin = $plugins->create('Named'); $this->assertInstanceOf(NamedPlugin::class, $plugin); $plugin = $plugins->create('Named', ['name' => 'Granpa']); $this->assertInstanceOf(NamedPlugin::class, $plugin); $this->assertSame('Granpa', $plugin->getName()); $plugin = $plugins->create(NamedPlugin::class); $this->assertInstanceOf(NamedPlugin::class, $plugin); $plugin = $plugins->create('Company/TestPluginThree'); $this->assertInstanceOf(TestPluginThreePlugin::class, $plugin); $plugin = $plugins->create('TestTheme'); $this->assertInstanceOf(BasePlugin::class, $plugin); $this->assertSame('TestTheme', $plugin->getName()); } public function testCreateException(): void { $this->expectException(CakeException::class); $this->expectExceptionMessage('Cannot create a plugin with empty name'); $plugins = new PluginCollection(); $plugins->create(''); } public function testIterator(): void { $data = [ new TestPlugin(), new TestPluginThreePlugin(), ]; $plugins = new PluginCollection($data); $out = []; foreach ($plugins as $plugin) { $this->assertInstanceOf(PluginInterface::class, $plugin); $out[] = $plugin; } $this->assertSame($data, $out); } public function testWith(): void { $plugins = new PluginCollection(); $plugin = new TestPlugin(); $plugin->disable('routes'); $pluginThree = new TestPluginThreePlugin(); $plugins->add($plugin); $plugins->add($pluginThree); $out = []; foreach ($plugins->with('routes') as $p) { $out[] = $p; } $this->assertCount(1, $out); $this->assertSame($pluginThree, $out[0]); } /** * Test that looping over the plugin collection during * a with loop doesn't lose iteration state. * * This situation can happen when a plugin like bake * needs to discover things inside other plugins. */ public function testWithInnerIteration(): void { $plugins = new PluginCollection(); $plugin = new TestPlugin(); $pluginThree = new TestPluginThreePlugin(); $plugins->add($plugin); $plugins->add($pluginThree); $out = []; foreach ($plugins->with('routes') as $p) { // phpcs:ignore SlevomatCodingStandard.Variables.UnusedVariable.UnusedVariable foreach ($plugins as $i) { // Do nothing, we just need to enumerate the collection } $out[] = $p; } $this->assertCount(2, $out); $this->assertSame($plugin, $out[0]); $this->assertSame($pluginThree, $out[1]); } public function testWithInvalidHook(): void { $this->expectException(InvalidArgumentException::class); $plugins = new PluginCollection(); // phpcs:ignore SlevomatCodingStandard.Variables.UnusedVariable.UnusedVariable foreach ($plugins->with('bad') as $p) { } } public function testFindPathNoConfigureData(): void { Configure::write('plugins', []); $plugins = new PluginCollection(); $path = $plugins->findPath('TestPlugin'); $this->assertSame(TEST_APP . 'Plugin' . DS . 'TestPlugin' . DS, $path); } public function testFindPathLoadsConfigureData(): void { $configPath = ROOT . DS . 'cakephp-plugins.php'; $this->skipIf(file_exists($configPath), 'cakephp-plugins.php exists, skipping overwrite'); $file = << [ 'TestPlugin' => '/config/path' ] ]; PHP; file_put_contents($configPath, $file); $plugins = new PluginCollection(); Configure::delete('plugins'); $path = $plugins->findPath('TestPlugin'); unlink($configPath); $this->assertSame('/config/path', $path); } public function testFindPathConfigureData(): void { Configure::write('plugins', ['TestPlugin' => '/some/path']); $plugins = new PluginCollection(); $path = $plugins->findPath('TestPlugin'); $this->assertSame('/some/path', $path); } public function testFindPathMissingPlugin(): void { Configure::write('plugins', []); $plugins = new PluginCollection(); $this->expectException(MissingPluginException::class); $plugins->findPath('InvalidPlugin'); } }