aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mitmproxy/command.py18
-rw-r--r--mitmproxy/tools/console/commander/commander.py2
-rw-r--r--mitmproxy/types.py2
-rw-r--r--test/mitmproxy/test_command.py90
-rw-r--r--test/mitmproxy/test_types.py4
5 files changed, 55 insertions, 61 deletions
diff --git a/mitmproxy/command.py b/mitmproxy/command.py
index b645798d..d813568f 100644
--- a/mitmproxy/command.py
+++ b/mitmproxy/command.py
@@ -133,9 +133,12 @@ class CommandManager(mitmproxy.types._CommandBase):
def add(self, path: str, func: typing.Callable):
self.commands[path] = Command(self, path, func)
- def parse_partial(self, cmdstr: str) -> typing.Sequence[ParseResult]:
+ def parse_partial(
+ self,
+ cmdstr: str
+ ) -> typing.Tuple[typing.Sequence[ParseResult], typing.Sequence[str]]:
"""
- Parse a possibly partial command. Return a sequence of (part, type) tuples.
+ Parse a possibly partial command. Return a sequence of ParseResults and a sequence of remainder type help items.
"""
buf = io.StringIO(cmdstr)
parts = [] # type: typing.List[str]
@@ -188,7 +191,16 @@ class CommandManager(mitmproxy.types._CommandBase):
valid=valid,
)
)
- return parse
+
+ remhelp = []
+ for x in params:
+ remt = mitmproxy.types.CommandTypes.get(x, None)
+ if not x:
+ remhelp = []
+ break
+ remhelp.append(remt.display)
+
+ return parse, remhelp
def call_args(self, path: str, args: typing.Sequence[str]) -> typing.Any:
"""
diff --git a/mitmproxy/tools/console/commander/commander.py b/mitmproxy/tools/console/commander/commander.py
index 13c80092..fd13f870 100644
--- a/mitmproxy/tools/console/commander/commander.py
+++ b/mitmproxy/tools/console/commander/commander.py
@@ -79,7 +79,7 @@ class CommandBuffer():
def cycle_completion(self) -> None:
if not self.completion:
- parts = self.master.commands.parse_partial(self.buf[:self.cursor])
+ parts, remainhelp = self.master.commands.parse_partial(self.buf[:self.cursor])
last = parts[-1]
ct = mitmproxy.types.CommandTypes.get(last.type, None)
if ct:
diff --git a/mitmproxy/types.py b/mitmproxy/types.py
index 35d4ed7e..36f33943 100644
--- a/mitmproxy/types.py
+++ b/mitmproxy/types.py
@@ -174,6 +174,8 @@ class _CmdType(_BaseType):
return list(manager.commands.keys())
def parse(self, manager: _CommandBase, t: type, s: str) -> str:
+ if s not in manager.commands:
+ raise exceptions.TypeError("Unknown command: %s" % s)
return s
def is_valid(self, manager: _CommandBase, typ: typing.Any, val: typing.Any) -> bool:
diff --git a/test/mitmproxy/test_command.py b/test/mitmproxy/test_command.py
index 75b10098..25df2e61 100644
--- a/test/mitmproxy/test_command.py
+++ b/test/mitmproxy/test_command.py
@@ -78,39 +78,54 @@ class TestCommand:
[
"foo bar",
[
- command.ParseResult(value = "foo", type = mitmproxy.types.Cmd, valid = True),
+ command.ParseResult(value = "foo", type = mitmproxy.types.Cmd, valid = False),
command.ParseResult(value = "bar", type = str, valid = True)
],
+ [],
],
[
- "foo 'bar",
+ "cmd1 'bar",
[
- command.ParseResult(value = "foo", type = mitmproxy.types.Cmd, valid = True),
+ command.ParseResult(value = "cmd1", type = mitmproxy.types.Cmd, valid = True),
command.ParseResult(value = "'bar", type = str, valid = True)
- ]
+ ],
+ [],
+ ],
+ [
+ "a",
+ [command.ParseResult(value = "a", type = mitmproxy.types.Cmd, valid = False)],
+ [],
+ ],
+ [
+ "",
+ [command.ParseResult(value = "", type = mitmproxy.types.Cmd, valid = False)],
+ []
],
- ["a", [command.ParseResult(value = "a", type = mitmproxy.types.Cmd, valid = True)]],
- ["", [command.ParseResult(value = "", type = mitmproxy.types.Cmd, valid = True)]],
[
"cmd3 1",
[
command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd, valid = True),
command.ParseResult(value = "1", type = int, valid = True),
- ]
+ ],
+ []
],
[
"cmd3 ",
[
command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd, valid = True),
command.ParseResult(value = "", type = int, valid = False),
- ]
+ ],
+ []
],
[
"subcommand ",
[
- command.ParseResult(value = "subcommand", type = mitmproxy.types.Cmd, valid = True),
- command.ParseResult(value = "", type = mitmproxy.types.Cmd, valid = True),
- ]
+ command.ParseResult(
+ value = "subcommand", type = mitmproxy.types.Cmd, valid = True,
+ ),
+ command.ParseResult(value = "", type = mitmproxy.types.Cmd, valid = False),
+ ],
+ ["arg"],
],
[
"subcommand cmd3 ",
@@ -118,13 +133,16 @@ class TestCommand:
command.ParseResult(value = "subcommand", type = mitmproxy.types.Cmd, valid = True),
command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd, valid = True),
command.ParseResult(value = "", type = int, valid = False),
- ]
+ ],
+ []
],
]
with taddons.context() as tctx:
tctx.master.addons.add(TAddon())
- for s, expected in tests:
- assert tctx.master.commands.parse_partial(s) == expected
+ for s, expected, expectedremain in tests:
+ current, remain = tctx.master.commands.parse_partial(s)
+ assert current == expected
+ assert expectedremain == remain
def test_simple():
@@ -179,51 +197,11 @@ def test_parsearg():
with taddons.context() as tctx:
tctx.master.addons.add(DummyConsole())
assert command.parsearg(tctx.master.commands, "foo", str) == "foo"
-
- assert command.parsearg(tctx.master.commands, "1", int) == 1
+ with pytest.raises(exceptions.CommandError, match="Unsupported"):
+ command.parsearg(tctx.master.commands, "foo", type)
with pytest.raises(exceptions.CommandError):
command.parsearg(tctx.master.commands, "foo", int)
- assert command.parsearg(tctx.master.commands, "true", bool) is True
- assert command.parsearg(tctx.master.commands, "false", bool) is False
- with pytest.raises(exceptions.CommandError):
- command.parsearg(tctx.master.commands, "flobble", bool)
-
- assert len(command.parsearg(
- tctx.master.commands, "2", typing.Sequence[flow.Flow]
- )) == 2
- assert command.parsearg(tctx.master.commands, "1", flow.Flow)
- with pytest.raises(exceptions.CommandError):
- command.parsearg(tctx.master.commands, "2", flow.Flow)
- with pytest.raises(exceptions.CommandError):
- command.parsearg(tctx.master.commands, "0", flow.Flow)
- with pytest.raises(exceptions.CommandError):
- command.parsearg(tctx.master.commands, "foo", Exception)
-
- assert command.parsearg(
- tctx.master.commands, "foo", typing.Sequence[str]
- ) == ["foo"]
- assert command.parsearg(
- tctx.master.commands, "foo, bar", typing.Sequence[str]
- ) == ["foo", "bar"]
-
- a = TAddon()
- tctx.master.commands.add("choices", a.choices)
- assert command.parsearg(
- tctx.master.commands, "one", mitmproxy.types.Choice("choices"),
- ) == "one"
- with pytest.raises(exceptions.CommandError):
- assert command.parsearg(
- tctx.master.commands, "invalid", mitmproxy.types.Choice("choices"),
- )
-
- assert command.parsearg(
- tctx.master.commands, "foo", mitmproxy.types.Path
- ) == "foo"
- assert command.parsearg(
- tctx.master.commands, "foo", mitmproxy.types.Cmd
- ) == "foo"
-
class TDec:
@command.command("cmd1")
diff --git a/test/mitmproxy/test_types.py b/test/mitmproxy/test_types.py
index 5b1dd3a2..46e23ff3 100644
--- a/test/mitmproxy/test_types.py
+++ b/test/mitmproxy/test_types.py
@@ -88,7 +88,9 @@ def test_cmd():
b = mitmproxy.types._CmdType()
assert b.is_valid(tctx.master.commands, mitmproxy.types.Cmd, "foo") is False
assert b.is_valid(tctx.master.commands, mitmproxy.types.Cmd, "cmd1") is True
- assert b.parse(tctx.master.commands, mitmproxy.types.Cmd, "foo") == "foo"
+ assert b.parse(tctx.master.commands, mitmproxy.types.Cmd, "cmd1") == "cmd1"
+ with pytest.raises(mitmproxy.exceptions.TypeError):
+ assert b.parse(tctx.master.commands, mitmproxy.types.Cmd, "foo")
assert len(
b.completion(tctx.master.commands, mitmproxy.types.Cmd, "")
) == len(tctx.master.commands.commands.keys())