Repository: pddg/uroboros

Issue:
Support multiple argument for `add_command()`
## What is this?

`uroboros.Command.add_command()` supports only one `Command` now.
This feature will support multiple `Command`.

Before

```python
root = RootCommand()
root.add_command(ACommand())
root.add_command(BCommand())
root.add_command(CCommand())
```

After

```python
root = RootCommand()
root.add_command(
    ACommand(),
    BCommand(),
    CCommand(),
)
```

## How to implement?

Just use `for` loop

Discussion:

Patch:
diff --git a/uroboros/command.py b/uroboros/command.py
index 8167aba..963cba2 100644
--- a/uroboros/command.py
+++ b/uroboros/command.py
@@ -134,25 +134,26 @@ class Command(metaclass=abc.ABCMeta):
         parser.set_defaults(func=self.run)
         return parser
 
-    def add_command(self, command: 'Command') -> 'Command':
+    def add_command(self, *commands: 'Command') -> 'Command':
         """
         Add sub command to this command.
-        :param command: An instance of `uroboros.command.Command`
+        :param commands: An instance of `uroboros.command.Command`
         :return: None
         """
-        assert isinstance(command, Command), \
-            "Given command is not an instance of `uroboros.Command` or" \
-            "an instance of its subclass."
-        assert getattr(command, "name", None) is not None, \
-            "{} does not have `name` attribute.".format(
-                command.__class__.__name__)
-        command_id = id(command)
-        if command_id in self._parent_ids or \
-                command_id in self._sub_command_ids:
-            raise errors.CommandDuplicateError(command, self)
-        command.register_parent(self._parent_ids)
-        command.increment_nest(self._layer)
-        self.sub_commands.append(command)
+        for command in commands:
+            assert isinstance(command, Command), \
+                "Given command is not an instance of `uroboros.Command` or" \
+                "an instance of its subclass."
+            assert getattr(command, "name", None) is not None, \
+                "{} does not have `name` attribute.".format(
+                    command.__class__.__name__)
+            command_id = id(command)
+            if command_id in self._parent_ids or \
+                    command_id in self._sub_command_ids:
+                raise errors.CommandDuplicateError(command, self)
+            command.register_parent(self._parent_ids)
+            command.increment_nest(self._layer)
+            self.sub_commands.append(command)
         return self
 
     @property


Test patch:
diff --git a/tests/test_command.py b/tests/test_command.py
index cfa85f1..b80b64f 100644
--- a/tests/test_command.py
+++ b/tests/test_command.py
@@ -134,6 +134,18 @@ class TestCommand(object):
             actual = command._sub_command_ids
             assert actual == expected
 
+    @pytest.mark.parametrize(
+        'root_cmd,add_commands', [
+            (RootCommand(), [SecondCommand()]),
+            (RootCommand(), [SecondCommand(), ThirdCommand()]),
+        ]
+    )
+    def test_multiple_add_command(self, root_cmd, add_commands):
+        root_cmd.add_command(*add_commands)
+        actual = root_cmd._sub_command_ids
+        expected = set([id(c) for c in add_commands])
+        assert actual == expected
+
     def test_add_others(self):
         root = RootCommand()
         with pytest.raises(AssertionError):