Browse Source

Implement CommandCollection::add/has/get

Mark Story 8 years ago
parent
commit
4c007589b6
2 changed files with 181 additions and 0 deletions
  1. 67 0
      src/Console/CommandCollection.php
  2. 114 0
      tests/TestCase/Console/CommandCollectionTest.php

+ 67 - 0
src/Console/CommandCollection.php

@@ -0,0 +1,67 @@
+<?php
+namespace Cake\Console;
+
+use ArrayIterator;
+use InvalidArgumentException;
+use IteratorAggregate;
+
+class CommandCollection implements IteratorAggregate
+{
+    protected $commands = [];
+
+    public function __construct(array $commands = [])
+    {
+        foreach ($commands as $name => $command) {
+            $this->add($name, $command);
+        }
+    }
+
+    public function add($name, $command)
+    {
+        // Once we have a new Command class this should check
+        // against that interface.
+        if (!is_subclass_of($command, 'Cake\Console\Shell')) {
+            throw new InvalidArgumentException(
+                "'$name' is not a subclass of Cake\Console\Shell or a valid command."
+            );
+        }
+        $this->commands[$name] = $command;
+
+        return $this;
+    }
+
+    public function remove($name)
+    {
+    }
+
+    /**
+     * Check whether the named shell exists in the collection.
+     *
+     * @param string $name The named shell.
+     * @return bool
+     */
+    public function has($name)
+    {
+        return isset($this->commands[$name]);
+    }
+
+    /**
+     * Get the target for a command.
+     *
+     * @param string $name The named shell.
+     * @return string|Cake\Console\Shell Either the shell class or an instance.
+     * @throws \InvalidArgumentException when unknown commands are fetched.
+     */
+    public function get($name)
+    {
+        if (!$this->has($name)) {
+            throw new InvalidArgumentException("The $name is not a known command name.");
+        }
+        return $this->commands[$name];
+    }
+
+    public function getIterator()
+    {
+        return new ArrayIterator($this->commands);
+    }
+}

+ 114 - 0
tests/TestCase/Console/CommandCollectionTest.php

@@ -0,0 +1,114 @@
+<?php
+namespace Cake\Test\Console;
+
+use Cake\Console\CommandCollection;
+use Cake\Shell\I18nShell;
+use Cake\Shell\RoutesShell;
+use Cake\TestSuite\TestCase;
+use stdClass;
+
+/**
+ * Test case for the CommandCollection
+ */
+class CommandCollectionTest extends TestCase
+{
+    public function testConstructor()
+    {
+        $this->markTestIncomplete();
+    }
+
+    public function testConstructorInvalidClass()
+    {
+        $this->markTestIncomplete();
+    }
+
+    public function testConstructorInvalidFactory()
+    {
+        $this->markTestIncomplete();
+    }
+
+    /**
+     * Test basic add/get
+     *
+     * @return void
+     */
+    public function testAdd()
+    {
+        $collection = new CommandCollection();
+        $this->assertSame($collection, $collection->add('routes', RoutesShell::class));
+        $this->assertTrue($collection->has('routes'));
+        $this->assertSame(RoutesShell::class, $collection->get('routes'));
+    }
+
+    /**
+     * Test that add() replaces.
+     *
+     * @return void
+     */
+    public function testAddReplace()
+    {
+        $collection = new CommandCollection();
+        $this->assertSame($collection, $collection->add('routes', RoutesShell::class));
+        $this->assertSame($collection, $collection->add('routes', I18nShell::class));
+        $this->assertTrue($collection->has('routes'));
+        $this->assertSame(I18nShell::class, $collection->get('routes'));
+    }
+
+    /**
+     * Test adding with instances
+     *
+     * @return void
+     */
+    public function testAddInstance()
+    {
+        $collection = new CommandCollection();
+        $io = $this->getMockBuilder('Cake\Console\ConsoleIo')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $shell = new RoutesShell($io);
+        $collection->add('routes', $shell);
+
+        $this->assertTrue($collection->has('routes'));
+        $this->assertSame($shell, $collection->get('routes'));
+    }
+
+    /**
+     * Instances that are not shells should fail.
+     *
+     * @expectedException InvalidArgumentException
+     * @expectedExceptionMessage 'routes' is not a subclass of Cake\Console\Shell
+     */
+    public function testAddInvalidInstance()
+    {
+        $collection = new CommandCollection();
+        $shell = new stdClass();
+        $collection->add('routes', $shell);
+    }
+
+    /**
+     * Class names that are not shells should fail
+     *
+     * @expectedException InvalidArgumentException
+     * @expectedExceptionMessage 'routes' is not a subclass of Cake\Console\Shell
+     */
+    public function testInvalidShellClassName()
+    {
+        $collection = new CommandCollection();
+        $collection->add('routes', stdClass::class);
+    }
+
+    public function testRemove()
+    {
+        $this->markTestIncomplete();
+    }
+
+    public function testRemoveUnknown()
+    {
+        $this->markTestIncomplete();
+    }
+
+    public function testGetIterator()
+    {
+        $this->markTestIncomplete();
+    }
+}