From 04e19f91716b9de6ec26df1478146eaedd47a329 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Thu, 14 Dec 2017 12:24:46 +1300 Subject: Introduce a custom widget for command editing The builtin urwid.Edit widget is not sufficiently flexible for what we want to do. --- test/mitmproxy/tools/console/test_commander.py | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 test/mitmproxy/tools/console/test_commander.py (limited to 'test') diff --git a/test/mitmproxy/tools/console/test_commander.py b/test/mitmproxy/tools/console/test_commander.py new file mode 100644 index 00000000..b1f23df4 --- /dev/null +++ b/test/mitmproxy/tools/console/test_commander.py @@ -0,0 +1,37 @@ + +from mitmproxy.tools.console.commander import commander + + +class TestCommandBuffer: + + def test_backspace(self): + tests = [ + [("", 0), ("", 0)], + [("1", 0), ("1", 0)], + [("1", 1), ("", 0)], + [("123", 3), ("12", 2)], + [("123", 2), ("13", 1)], + [("123", 0), ("123", 0)], + ] + for start, output in tests: + cb = commander.CommandBuffer() + cb.buf, cb.cursor = start[0], start[1] + cb.backspace() + assert cb.buf == output[0] + assert cb.cursor == output[1] + + def test_insert(self): + tests = [ + [("", 0), ("x", 1)], + [("a", 0), ("xa", 1)], + [("xa", 2), ("xax", 3)], + ] + for start, output in tests: + cb = commander.CommandBuffer() + cb.buf, cb.cursor = start[0], start[1] + cb.insert("x") + assert cb.buf == output[0] + assert cb.cursor == output[1] + + + -- cgit v1.2.3 From e64d5c6bb963dedf291ed3c694ef735c8980a019 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Thu, 14 Dec 2017 15:43:15 +1300 Subject: commands: add a Cmd argument type This represents a command passed as an argument. Also split arguments from command values themselves, making the command help for meta-commands much clearer. --- test/mitmproxy/test_command.py | 4 ++++ test/mitmproxy/tools/console/test_commander.py | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/mitmproxy/test_command.py b/test/mitmproxy/test_command.py index e1879ba2..c8007463 100644 --- a/test/mitmproxy/test_command.py +++ b/test/mitmproxy/test_command.py @@ -100,6 +100,7 @@ def test_typename(): assert command.typename(command.Choice("foo"), False) == "choice" assert command.typename(command.Path, False) == "path" + assert command.typename(command.Cmd, False) == "cmd" class DummyConsole: @@ -162,6 +163,9 @@ def test_parsearg(): assert command.parsearg( tctx.master.commands, "foo", command.Path ) == "foo" + assert command.parsearg( + tctx.master.commands, "foo", command.Cmd + ) == "foo" class TDec: diff --git a/test/mitmproxy/tools/console/test_commander.py b/test/mitmproxy/tools/console/test_commander.py index b1f23df4..fdf54897 100644 --- a/test/mitmproxy/tools/console/test_commander.py +++ b/test/mitmproxy/tools/console/test_commander.py @@ -32,6 +32,3 @@ class TestCommandBuffer: cb.insert("x") assert cb.buf == output[0] assert cb.cursor == output[1] - - - -- cgit v1.2.3 From 0cd4a7726892ecda494d94bd12af0094c53a6a85 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Thu, 14 Dec 2017 17:49:53 +1300 Subject: commands: add a parser for partial commands We only return Cmd and str types for the moment. --- test/mitmproxy/test_command.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'test') diff --git a/test/mitmproxy/test_command.py b/test/mitmproxy/test_command.py index c8007463..5218042c 100644 --- a/test/mitmproxy/test_command.py +++ b/test/mitmproxy/test_command.py @@ -64,6 +64,16 @@ class TestCommand: c = command.Command(cm, "cmd.three", a.cmd3) assert c.call(["1"]) == 1 + def test_parse_partial(self): + tests = [ + ["foo bar", [("foo", command.Cmd), ("bar", str)]], + ["foo 'bar", [("foo", command.Cmd), ("'bar", str)]], + ] + with taddons.context() as tctx: + cm = command.CommandManager(tctx.master) + for s, expected in tests: + assert cm.parse_partial(s) == expected + def test_simple(): with taddons.context() as tctx: -- cgit v1.2.3 From 4d358c49fbeafe504cc7b9a8b66ea572c8cbb0ee Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Fri, 15 Dec 2017 07:20:07 +1300 Subject: WIP: autocompletion --- test/mitmproxy/test_command.py | 18 +++++++++++-- test/mitmproxy/tools/console/test_commander.py | 35 ++++++++++++++++---------- 2 files changed, 38 insertions(+), 15 deletions(-) (limited to 'test') diff --git a/test/mitmproxy/test_command.py b/test/mitmproxy/test_command.py index 5218042c..b4711236 100644 --- a/test/mitmproxy/test_command.py +++ b/test/mitmproxy/test_command.py @@ -66,8 +66,22 @@ class TestCommand: def test_parse_partial(self): tests = [ - ["foo bar", [("foo", command.Cmd), ("bar", str)]], - ["foo 'bar", [("foo", command.Cmd), ("'bar", str)]], + [ + "foo bar", + [ + command.ParseResult(value = "foo", type = command.Cmd), + command.ParseResult(value = "bar", type = str) + ], + ], + [ + "foo 'bar", + [ + command.ParseResult(value = "foo", type = command.Cmd), + command.ParseResult(value = "'bar", type = str) + ] + ], + ["a", [command.ParseResult(value = "a", type = command.Cmd)]], + ["", [command.ParseResult(value = "", type = command.Cmd)]], ] with taddons.context() as tctx: cm = command.CommandManager(tctx.master) diff --git a/test/mitmproxy/tools/console/test_commander.py b/test/mitmproxy/tools/console/test_commander.py index fdf54897..9ef4a318 100644 --- a/test/mitmproxy/tools/console/test_commander.py +++ b/test/mitmproxy/tools/console/test_commander.py @@ -1,5 +1,5 @@ - from mitmproxy.tools.console.commander import commander +from mitmproxy.test import taddons class TestCommandBuffer: @@ -13,12 +13,13 @@ class TestCommandBuffer: [("123", 2), ("13", 1)], [("123", 0), ("123", 0)], ] - for start, output in tests: - cb = commander.CommandBuffer() - cb.buf, cb.cursor = start[0], start[1] - cb.backspace() - assert cb.buf == output[0] - assert cb.cursor == output[1] + with taddons.context() as tctx: + for start, output in tests: + cb = commander.CommandBuffer(tctx.master) + cb.buf, cb.cursor = start[0], start[1] + cb.backspace() + assert cb.buf == output[0] + assert cb.cursor == output[1] def test_insert(self): tests = [ @@ -26,9 +27,17 @@ class TestCommandBuffer: [("a", 0), ("xa", 1)], [("xa", 2), ("xax", 3)], ] - for start, output in tests: - cb = commander.CommandBuffer() - cb.buf, cb.cursor = start[0], start[1] - cb.insert("x") - assert cb.buf == output[0] - assert cb.cursor == output[1] + with taddons.context() as tctx: + for start, output in tests: + cb = commander.CommandBuffer(tctx.master) + cb.buf, cb.cursor = start[0], start[1] + cb.insert("x") + assert cb.buf == output[0] + assert cb.cursor == output[1] + + def test_cycle_completion(self): + with taddons.context() as tctx: + cb = commander.CommandBuffer(tctx.master) + cb.buf = "foo bar" + cb.cursor = len(cb.buf) + cb.cycle_completion() -- cgit v1.2.3 From 8c0ba71fd8f2e29e8348c88aa6d653d3161ea20a Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Fri, 15 Dec 2017 09:43:09 +1300 Subject: commander: tab completion for command names --- test/mitmproxy/tools/console/test_commander.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'test') diff --git a/test/mitmproxy/tools/console/test_commander.py b/test/mitmproxy/tools/console/test_commander.py index 9ef4a318..1ac4c5c6 100644 --- a/test/mitmproxy/tools/console/test_commander.py +++ b/test/mitmproxy/tools/console/test_commander.py @@ -2,6 +2,31 @@ from mitmproxy.tools.console.commander import commander from mitmproxy.test import taddons +class TestListCompleter: + def test_cycle(self): + tests = [ + [ + "", + ["a", "b", "c"], + ["a", "b", "c", "a"] + ], + [ + "xxx", + ["a", "b", "c"], + ["xxx", "xxx", "xxx"] + ], + [ + "b", + ["a", "b", "ba", "bb", "c"], + ["b", "ba", "bb", "b"] + ], + ] + for start, options, cycle in tests: + c = commander.ListCompleter(start, options) + for expected in cycle: + assert c.cycle() == expected + + class TestCommandBuffer: def test_backspace(self): -- cgit v1.2.3 From 1c097813c16d530631562727cd9c2db0fae8755d Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Fri, 15 Dec 2017 11:34:53 +1300 Subject: commands: emit types from partial parser, implement choice completion --- test/mitmproxy/test_command.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/mitmproxy/test_command.py b/test/mitmproxy/test_command.py index b4711236..76ce2245 100644 --- a/test/mitmproxy/test_command.py +++ b/test/mitmproxy/test_command.py @@ -11,19 +11,24 @@ from mitmproxy.utils import typecheck class TAddon: + @command.command("cmd1") def cmd1(self, foo: str) -> str: """cmd1 help""" return "ret " + foo + @command.command("cmd2") def cmd2(self, foo: str) -> str: return 99 + @command.command("cmd3") def cmd3(self, foo: int) -> int: return foo + @command.command("empty") def empty(self) -> None: pass + @command.command("varargs") def varargs(self, one: str, *var: str) -> typing.Sequence[str]: return list(var) @@ -34,6 +39,7 @@ class TAddon: def choose(self, arg: str) -> typing.Sequence[str]: return ["one", "two", "three"] + @command.command("path") def path(self, arg: command.Path) -> None: pass @@ -82,11 +88,25 @@ class TestCommand: ], ["a", [command.ParseResult(value = "a", type = command.Cmd)]], ["", [command.ParseResult(value = "", type = command.Cmd)]], + [ + "cmd3 1", + [ + command.ParseResult(value = "cmd3", type = command.Cmd), + command.ParseResult(value = "1", type = int), + ] + ], + [ + "cmd3 ", + [ + command.ParseResult(value = "cmd3", type = command.Cmd), + command.ParseResult(value = "", type = int), + ] + ], ] with taddons.context() as tctx: - cm = command.CommandManager(tctx.master) + tctx.master.addons.add(TAddon()) for s, expected in tests: - assert cm.parse_partial(s) == expected + assert tctx.master.commands.parse_partial(s) == expected def test_simple(): -- cgit v1.2.3