diff options
author | Maximilian Hils <git@maximilianhils.com> | 2019-11-21 14:13:08 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-21 14:13:08 +0100 |
commit | 3550bdfe006ba321c706b16f58a6b0d5b4e744b7 (patch) | |
tree | 46a1eb299a89866668a85fb2045f616377e538dc /test | |
parent | 3a7ca3e1e7cc4e0d1d8a6702cbf443f7cddaf00f (diff) | |
parent | f7a3e903ac69950ef862757886ed83506b7d1bd9 (diff) | |
download | mitmproxy-3550bdfe006ba321c706b16f58a6b0d5b4e744b7.tar.gz mitmproxy-3550bdfe006ba321c706b16f58a6b0d5b4e744b7.tar.bz2 mitmproxy-3550bdfe006ba321c706b16f58a6b0d5b4e744b7.zip |
Merge pull request #3693 from typoon/fix-command-bar-issue-3259
Improve Command Bar UX
Diffstat (limited to 'test')
-rw-r--r-- | test/mitmproxy/addons/test_core.py | 2 | ||||
-rw-r--r-- | test/mitmproxy/addons/test_save.py | 2 | ||||
-rw-r--r-- | test/mitmproxy/test_command.py | 321 | ||||
-rw-r--r-- | test/mitmproxy/test_command_lexer.py | 38 | ||||
-rw-r--r-- | test/mitmproxy/test_types.py | 15 | ||||
-rw-r--r-- | test/mitmproxy/tools/console/test_commander.py | 143 | ||||
-rw-r--r-- | test/mitmproxy/tools/console/test_defaultkeys.py | 19 |
7 files changed, 440 insertions, 100 deletions
diff --git a/test/mitmproxy/addons/test_core.py b/test/mitmproxy/addons/test_core.py index 59875c2b..e6924ead 100644 --- a/test/mitmproxy/addons/test_core.py +++ b/test/mitmproxy/addons/test_core.py @@ -11,7 +11,7 @@ def test_set(): sa = core.Core() with taddons.context(loadcore=False) as tctx: assert tctx.master.options.server - tctx.command(sa.set, "server=false") + tctx.command(sa.set, "server", "false") assert not tctx.master.options.server with pytest.raises(exceptions.CommandError): diff --git a/test/mitmproxy/addons/test_save.py b/test/mitmproxy/addons/test_save.py index 4aa1f648..6727a96f 100644 --- a/test/mitmproxy/addons/test_save.py +++ b/test/mitmproxy/addons/test_save.py @@ -73,7 +73,7 @@ def test_save_command(tmpdir): v = view.View() tctx.master.addons.add(v) tctx.master.addons.add(sa) - tctx.master.commands.call_strings("save.file", ["@shown", p]) + tctx.master.commands.execute("save.file @shown %s" % p) def test_simple(tmpdir): diff --git a/test/mitmproxy/test_command.py b/test/mitmproxy/test_command.py index d9dcf5f9..a432f9e3 100644 --- a/test/mitmproxy/test_command.py +++ b/test/mitmproxy/test_command.py @@ -1,13 +1,15 @@ -import typing import inspect +import io +import typing + +import pytest + +import mitmproxy.types from mitmproxy import command -from mitmproxy import flow from mitmproxy import exceptions -from mitmproxy.test import tflow +from mitmproxy import flow from mitmproxy.test import taddons -import mitmproxy.types -import io -import pytest +from mitmproxy.test import tflow class TAddon: @@ -29,7 +31,7 @@ class TAddon: return "ok" @command.command("subcommand") - def subcommand(self, cmd: mitmproxy.types.Cmd, *args: mitmproxy.types.Arg) -> str: + def subcommand(self, cmd: mitmproxy.types.Cmd, *args: mitmproxy.types.CmdArgs) -> str: return "ok" @command.command("empty") @@ -83,17 +85,15 @@ class TestCommand: with pytest.raises(exceptions.CommandError): command.Command(cm, "invalidret", a.invalidret) with pytest.raises(exceptions.CommandError): - command.Command(cm, "invalidarg", a.invalidarg) + assert command.Command(cm, "invalidarg", a.invalidarg) def test_varargs(self): with taddons.context() as tctx: cm = command.CommandManager(tctx.master) a = TAddon() c = command.Command(cm, "varargs", a.varargs) - assert c.signature_help() == "varargs str *str -> [str]" + assert c.signature_help() == "varargs one *var -> str[]" assert c.call(["one", "two", "three"]) == ["two", "three"] - with pytest.raises(exceptions.CommandError): - c.call(["one", "two", 3]) def test_call(self): with taddons.context() as tctx: @@ -101,7 +101,7 @@ class TestCommand: a = TAddon() c = command.Command(cm, "cmd.path", a.cmd1) assert c.call(["foo"]) == "ret foo" - assert c.signature_help() == "cmd.path str -> str" + assert c.signature_help() == "cmd.path foo -> str" c = command.Command(cm, "cmd.two", a.cmd2) with pytest.raises(exceptions.CommandError): @@ -115,154 +115,305 @@ class TestCommand: [ "foo bar", [ - command.ParseResult( - value = "foo", type = mitmproxy.types.Cmd, valid = False - ), - command.ParseResult( - value = "bar", type = mitmproxy.types.Unknown, valid = False - ) + command.ParseResult(value="foo", type=mitmproxy.types.Cmd, valid=False), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="bar", type=mitmproxy.types.Unknown, valid=False) ], [], ], [ "cmd1 'bar", [ - command.ParseResult(value = "cmd1", type = mitmproxy.types.Cmd, valid = True), - command.ParseResult(value = "'bar", type = str, valid = True) + command.ParseResult(value="cmd1", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="'bar", type=str, valid=True) ], [], ], [ "a", - [command.ParseResult(value = "a", type = mitmproxy.types.Cmd, valid = False)], + [command.ParseResult(value="a", type=mitmproxy.types.Cmd, valid=False)], [], ], [ "", - [command.ParseResult(value = "", type = mitmproxy.types.Cmd, valid = False)], - [] + [], + [ + command.CommandParameter("", mitmproxy.types.Cmd), + command.CommandParameter("", mitmproxy.types.CmdArgs) + ] ], [ "cmd3 1", [ - command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd, valid = True), - command.ParseResult(value = "1", type = int, valid = True), + command.ParseResult(value="cmd3", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, 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), + command.ParseResult(value="cmd3", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), ], - [] + [command.CommandParameter('foo', int)] ], [ "subcommand ", [ - command.ParseResult( - value = "subcommand", type = mitmproxy.types.Cmd, valid = True, - ), - command.ParseResult(value = "", type = mitmproxy.types.Cmd, valid = False), + command.ParseResult(value="subcommand", type=mitmproxy.types.Cmd, valid=True, ), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + ], + [ + command.CommandParameter('cmd', mitmproxy.types.Cmd), + command.CommandParameter('args', mitmproxy.types.CmdArgs, kind=inspect.Parameter.VAR_POSITIONAL), ], - ["arg"], ], [ - "subcommand cmd3 ", + "varargs one", [ - 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), + command.ParseResult(value="varargs", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="one", type=str, valid=True), ], - [] + [command.CommandParameter('var', str, kind=inspect.Parameter.VAR_POSITIONAL)] ], [ - "cmd4", + "varargs one two three", [ - command.ParseResult(value = "cmd4", type = mitmproxy.types.Cmd, valid = True), + command.ParseResult(value="varargs", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="one", type=str, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="two", type=str, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="three", type=str, valid=True), ], - ["int", "str", "path"] + [], ], [ - "cmd4 ", + "subcommand cmd3 ", [ - command.ParseResult(value = "cmd4", type = mitmproxy.types.Cmd, valid = True), - command.ParseResult(value = "", type = int, valid = False), + command.ParseResult(value="subcommand", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="cmd3", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), ], - ["str", "path"] + [command.CommandParameter('foo', int)] ], [ - "cmd4 1", + "cmd4", [ - command.ParseResult(value = "cmd4", type = mitmproxy.types.Cmd, valid = True), - command.ParseResult(value = "1", type = int, valid = True), + command.ParseResult(value="cmd4", type=mitmproxy.types.Cmd, valid=True), ], - ["str", "path"] + [ + command.CommandParameter('a', int), + command.CommandParameter('b', str), + command.CommandParameter('c', mitmproxy.types.Path), + ] + ], + [ + "cmd4 ", + [ + command.ParseResult(value="cmd4", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + ], + [ + command.CommandParameter('a', int), + command.CommandParameter('b', str), + command.CommandParameter('c', mitmproxy.types.Path), + ] ], [ "cmd4 1", [ - command.ParseResult(value = "cmd4", type = mitmproxy.types.Cmd, valid = True), - command.ParseResult(value = "1", type = int, valid = True), + command.ParseResult(value="cmd4", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="1", type=int, valid=True), ], - ["str", "path"] + [ + command.CommandParameter('b', str), + command.CommandParameter('c', mitmproxy.types.Path), + ] ], [ "flow", [ - command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True), + command.ParseResult(value="flow", type=mitmproxy.types.Cmd, valid=True), ], - ["flow", "str"] + [ + command.CommandParameter('f', flow.Flow), + command.CommandParameter('s', str), + ] ], [ "flow ", [ - command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True), - command.ParseResult(value = "", type = flow.Flow, valid = False), + command.ParseResult(value="flow", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), ], - ["str"] + [ + command.CommandParameter('f', flow.Flow), + command.CommandParameter('s', str), + ] ], [ "flow x", [ - command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True), - command.ParseResult(value = "x", type = flow.Flow, valid = False), + command.ParseResult(value="flow", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="x", type=flow.Flow, valid=False), ], - ["str"] + [ + command.CommandParameter('s', str), + ] ], [ "flow x ", [ - command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True), - command.ParseResult(value = "x", type = flow.Flow, valid = False), - command.ParseResult(value = "", type = str, valid = True), + command.ParseResult(value="flow", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="x", type=flow.Flow, valid=False), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), ], - [] + [ + command.CommandParameter('s', str), + ] ], [ "flow \"one two", [ - command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True), - command.ParseResult(value = "\"one two", type = flow.Flow, valid = False), + command.ParseResult(value="flow", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="\"one two", type=flow.Flow, valid=False), ], - ["str"] + [ + command.CommandParameter('s', str), + ] ], [ - "flow \"one two\"", + "flow \"three four\"", [ - command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True), - command.ParseResult(value = "one two", type = flow.Flow, valid = False), + command.ParseResult(value="flow", type=mitmproxy.types.Cmd, valid=True), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value='"three four"', type=flow.Flow, valid=False), ], - ["str"] + [ + command.CommandParameter('s', str), + ] ], + [ + "spaces ' '", + [ + command.ParseResult(value="spaces", type=mitmproxy.types.Cmd, valid=False), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="' '", type=mitmproxy.types.Unknown, valid=False) + ], + [], + ], + [ + 'spaces2 " "', + [ + command.ParseResult(value="spaces2", type=mitmproxy.types.Cmd, valid=False), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value='" "', type=mitmproxy.types.Unknown, valid=False) + ], + [], + ], + [ + '"abc"', + [ + command.ParseResult(value='"abc"', type=mitmproxy.types.Cmd, valid=False), + ], + [], + ], + [ + "'def'", + [ + command.ParseResult(value="'def'", type=mitmproxy.types.Cmd, valid=False), + ], + [], + ], + [ + "cmd10 'a' \"b\" c", + [ + command.ParseResult(value="cmd10", type=mitmproxy.types.Cmd, valid=False), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="'a'", type=mitmproxy.types.Unknown, valid=False), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value='"b"', type=mitmproxy.types.Unknown, valid=False), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="c", type=mitmproxy.types.Unknown, valid=False), + ], + [], + ], + [ + "cmd11 'a \"b\" c'", + [ + command.ParseResult(value="cmd11", type=mitmproxy.types.Cmd, valid=False), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="'a \"b\" c'", type=mitmproxy.types.Unknown, valid=False), + ], + [], + ], + [ + 'cmd12 "a \'b\' c"', + [ + command.ParseResult(value="cmd12", type=mitmproxy.types.Cmd, valid=False), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value='"a \'b\' c"', type=mitmproxy.types.Unknown, valid=False), + ], + [], + ], + [ + r'cmd13 "a \"b\" c"', + [ + command.ParseResult(value="cmd13", type=mitmproxy.types.Cmd, valid=False), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value=r'"a \"b\" c"', type=mitmproxy.types.Unknown, valid=False), + ], + [], + ], + [ + r"cmd14 'a \'b\' c'", + [ + command.ParseResult(value="cmd14", type=mitmproxy.types.Cmd, valid=False), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value=r"'a \'b\' c'", type=mitmproxy.types.Unknown, valid=False), + ], + [], + ], + [ + " spaces_at_the_begining_are_not_stripped", + [ + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="spaces_at_the_begining_are_not_stripped", type=mitmproxy.types.Cmd, + valid=False), + ], + [], + ], + [ + " spaces_at_the_begining_are_not_stripped neither_at_the_end ", + [ + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="spaces_at_the_begining_are_not_stripped", type=mitmproxy.types.Cmd, + valid=False), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + command.ParseResult(value="neither_at_the_end", type=mitmproxy.types.Unknown, valid=False), + command.ParseResult(value=" ", type=mitmproxy.types.Space, valid=True), + ], + [], + ], + ] + with taddons.context() as tctx: tctx.master.addons.add(TAddon()) for s, expected, expectedremain in tests: current, remain = tctx.master.commands.parse_partial(s) - assert current == expected - assert expectedremain == remain + assert (s, current, expectedremain) == (s, expected, remain) def test_simple(): @@ -270,9 +421,11 @@ def test_simple(): c = command.CommandManager(tctx.master) a = TAddon() c.add("one.two", a.cmd1) - assert c.commands["one.two"].help == "cmd1 help" - assert(c.execute("one.two foo") == "ret foo") - assert(c.call("one.two", "foo") == "ret foo") + assert (c.commands["one.two"].help == "cmd1 help") + assert (c.execute("one.two foo") == "ret foo") + assert (c.execute("one.two \"foo\"") == "ret foo") + assert (c.execute("one.two 'foo bar'") == "ret foo bar") + assert (c.call("one.two", "foo") == "ret foo") with pytest.raises(exceptions.CommandError, match="Unknown"): c.execute("nonexistent") with pytest.raises(exceptions.CommandError, match="Invalid"): @@ -281,8 +434,14 @@ def test_simple(): c.execute("one.two too many args") with pytest.raises(exceptions.CommandError, match="Unknown"): c.call("nonexistent") - with pytest.raises(exceptions.CommandError, match="No escaped"): + with pytest.raises(exceptions.CommandError, match="Unknown"): c.execute("\\") + with pytest.raises(exceptions.CommandError, match="Unknown"): + c.execute(r"\'") + with pytest.raises(exceptions.CommandError, match="Unknown"): + c.execute(r"\"") + with pytest.raises(exceptions.CommandError, match="Unknown"): + c.execute(r"\"") c.add("empty", a.empty) c.execute("empty") @@ -294,13 +453,13 @@ def test_simple(): def test_typename(): assert command.typename(str) == "str" - assert command.typename(typing.Sequence[flow.Flow]) == "[flow]" + assert command.typename(typing.Sequence[flow.Flow]) == "flow[]" - assert command.typename(mitmproxy.types.Data) == "[data]" - assert command.typename(mitmproxy.types.CutSpec) == "[cut]" + assert command.typename(mitmproxy.types.Data) == "data[][]" + assert command.typename(mitmproxy.types.CutSpec) == "cut[]" assert command.typename(flow.Flow) == "flow" - assert command.typename(typing.Sequence[str]) == "[str]" + assert command.typename(typing.Sequence[str]) == "str[]" assert command.typename(mitmproxy.types.Choice("foo")) == "choice" assert command.typename(mitmproxy.types.Path) == "path" diff --git a/test/mitmproxy/test_command_lexer.py b/test/mitmproxy/test_command_lexer.py new file mode 100644 index 00000000..3f009f88 --- /dev/null +++ b/test/mitmproxy/test_command_lexer.py @@ -0,0 +1,38 @@ +import pyparsing +import pytest + +from mitmproxy import command_lexer + + +@pytest.mark.parametrize( + "test_input,valid", [ + ("'foo'", True), + ('"foo"', True), + ("'foo' bar'", False), + ("'foo\\' bar'", True), + ("'foo' 'bar'", False), + ("'foo'x", False), + ('''"foo ''', True), + ('''"foo 'bar' ''', True), + ] +) +def test_partial_quoted_string(test_input, valid): + if valid: + assert command_lexer.PartialQuotedString.parseString(test_input, parseAll=True)[0] == test_input + else: + with pytest.raises(pyparsing.ParseException): + command_lexer.PartialQuotedString.parseString(test_input, parseAll=True) + + +@pytest.mark.parametrize( + "test_input,expected", [ + ("'foo'", ["'foo'"]), + ('"foo"', ['"foo"']), + ("'foo' 'bar'", ["'foo'", ' ', "'bar'"]), + ("'foo'x", ["'foo'", 'x']), + ('''"foo''', ['"foo']), + ('''"foo 'bar' ''', ['''"foo 'bar' ''']), + ] +) +def test_expr(test_input, expected): + assert list(command_lexer.expr.parseString(test_input, parseAll=True)) == expected diff --git a/test/mitmproxy/test_types.py b/test/mitmproxy/test_types.py index 571985fb..2cd17d87 100644 --- a/test/mitmproxy/test_types.py +++ b/test/mitmproxy/test_types.py @@ -2,7 +2,6 @@ import pytest import os import typing import contextlib -from unittest import mock import mitmproxy.exceptions import mitmproxy.types @@ -64,13 +63,14 @@ def test_int(): b.parse(tctx.master.commands, int, "foo") -def test_path(tdata): +def test_path(tdata, monkeypatch): with taddons.context() as tctx: b = mitmproxy.types._PathType() assert b.parse(tctx.master.commands, mitmproxy.types.Path, "/foo") == "/foo" assert b.parse(tctx.master.commands, mitmproxy.types.Path, "/bar") == "/bar" - with mock.patch.dict("os.environ", {"HOME": "/home/test"}): - assert b.parse(tctx.master.commands, mitmproxy.types.Path, "~/mitm") == "/home/test/mitm" + monkeypatch.setenv("HOME", "/home/test") + monkeypatch.setenv("USERPROFILE", "/home/test") + assert b.parse(tctx.master.commands, mitmproxy.types.Path, "~/mitm") == "/home/test/mitm" assert b.is_valid(tctx.master.commands, mitmproxy.types.Path, "foo") is True assert b.is_valid(tctx.master.commands, mitmproxy.types.Path, "~/mitm") is True assert b.is_valid(tctx.master.commands, mitmproxy.types.Path, 3) is False @@ -127,10 +127,9 @@ def test_cutspec(): def test_arg(): with taddons.context() as tctx: b = mitmproxy.types._ArgType() - assert b.completion(tctx.master.commands, mitmproxy.types.Arg, "") == [] - assert b.parse(tctx.master.commands, mitmproxy.types.Arg, "foo") == "foo" - assert b.is_valid(tctx.master.commands, mitmproxy.types.Arg, "foo") is True - assert b.is_valid(tctx.master.commands, mitmproxy.types.Arg, 1) is False + assert b.completion(tctx.master.commands, mitmproxy.types.CmdArgs, "") == [] + assert b.parse(tctx.master.commands, mitmproxy.types.CmdArgs, "foo") == "foo" + assert b.is_valid(tctx.master.commands, mitmproxy.types.CmdArgs, 1) is False def test_strseq(): diff --git a/test/mitmproxy/tools/console/test_commander.py b/test/mitmproxy/tools/console/test_commander.py index b5e226fe..a77be043 100644 --- a/test/mitmproxy/tools/console/test_commander.py +++ b/test/mitmproxy/tools/console/test_commander.py @@ -1,6 +1,7 @@ +import pytest -from mitmproxy.tools.console.commander import commander from mitmproxy.test import taddons +from mitmproxy.tools.console.commander import commander class TestListCompleter: @@ -28,6 +29,112 @@ class TestListCompleter: assert c.cycle() == expected +class TestCommandEdit: + def test_open_command_bar(self): + with taddons.context() as tctx: + history = commander.CommandHistory(tctx.master, size=3) + edit = commander.CommandEdit(tctx.master, '', history) + + try: + edit.update() + except IndexError: + pytest.faied("Unexpected IndexError") + + def test_insert(self): + with taddons.context() as tctx: + history = commander.CommandHistory(tctx.master, size=3) + edit = commander.CommandEdit(tctx.master, '', history) + edit.keypress(1, 'a') + assert edit.get_edit_text() == 'a' + + # Don't let users type a space before starting a command + # as a usability feature + history = commander.CommandHistory(tctx.master, size=3) + edit = commander.CommandEdit(tctx.master, '', history) + edit.keypress(1, ' ') + assert edit.get_edit_text() == '' + + def test_backspace(self): + with taddons.context() as tctx: + history = commander.CommandHistory(tctx.master, size=3) + edit = commander.CommandEdit(tctx.master, '', history) + edit.keypress(1, 'a') + edit.keypress(1, 'b') + assert edit.get_edit_text() == 'ab' + edit.keypress(1, 'backspace') + assert edit.get_edit_text() == 'a' + + def test_left(self): + with taddons.context() as tctx: + history = commander.CommandHistory(tctx.master, size=3) + edit = commander.CommandEdit(tctx.master, '', history) + edit.keypress(1, 'a') + assert edit.cbuf.cursor == 1 + edit.keypress(1, 'left') + assert edit.cbuf.cursor == 0 + + # Do it again to make sure it won't go negative + edit.keypress(1, 'left') + assert edit.cbuf.cursor == 0 + + def test_right(self): + with taddons.context() as tctx: + history = commander.CommandHistory(tctx.master, size=3) + edit = commander.CommandEdit(tctx.master, '', history) + edit.keypress(1, 'a') + assert edit.cbuf.cursor == 1 + + # Make sure cursor won't go past the text + edit.keypress(1, 'right') + assert edit.cbuf.cursor == 1 + + # Make sure cursor goes left and then back right + edit.keypress(1, 'left') + assert edit.cbuf.cursor == 0 + edit.keypress(1, 'right') + assert edit.cbuf.cursor == 1 + + def test_up_and_down(self): + with taddons.context() as tctx: + history = commander.CommandHistory(tctx.master, size=3) + edit = commander.CommandEdit(tctx.master, '', history) + + buf = commander.CommandBuffer(tctx.master, 'cmd1') + history.add_command(buf) + buf = commander.CommandBuffer(tctx.master, 'cmd2') + history.add_command(buf) + + edit.keypress(1, 'up') + assert edit.get_edit_text() == 'cmd2' + edit.keypress(1, 'up') + assert edit.get_edit_text() == 'cmd1' + edit.keypress(1, 'up') + assert edit.get_edit_text() == 'cmd1' + + history = commander.CommandHistory(tctx.master, size=5) + edit = commander.CommandEdit(tctx.master, '', history) + edit.keypress(1, 'a') + edit.keypress(1, 'b') + edit.keypress(1, 'c') + assert edit.get_edit_text() == 'abc' + edit.keypress(1, 'up') + assert edit.get_edit_text() == '' + edit.keypress(1, 'down') + assert edit.get_edit_text() == 'abc' + edit.keypress(1, 'down') + assert edit.get_edit_text() == 'abc' + + history = commander.CommandHistory(tctx.master, size=5) + edit = commander.CommandEdit(tctx.master, '', history) + buf = commander.CommandBuffer(tctx.master, 'cmd3') + history.add_command(buf) + edit.keypress(1, 'z') + edit.keypress(1, 'up') + assert edit.get_edit_text() == 'cmd3' + edit.keypress(1, 'down') + assert edit.get_edit_text() == 'z' + + class TestCommandHistory: def fill_history(self, commands): with taddons.context() as tctx: @@ -148,13 +255,39 @@ class TestCommandBuffer: cb.cursor = len(cb.text) cb.cycle_completion() + ch = commander.CommandHistory(tctx.master, 30) + ce = commander.CommandEdit(tctx.master, "se", ch) + ce.keypress(1, 'tab') + ce.update() + ret = ce.cbuf.render() + assert ret == [ + ('commander_command', 'set'), + ('text', ' '), + ('commander_hint', 'option '), + ('commander_hint', 'value '), + ] + def test_render(self): with taddons.context() as tctx: cb = commander.CommandBuffer(tctx.master) cb.text = "foo" assert cb.render() - def test_flatten(self): - with taddons.context() as tctx: - cb = commander.CommandBuffer(tctx.master) - assert cb.flatten("foo bar") == "foo bar" + cb.text = "set view_filter '~bq test'" + ret = cb.render() + assert ret == [ + ('commander_command', 'set'), + ('text', ' '), + ('text', 'view_filter'), + ('text', ' '), + ('text', "'~bq test'"), + ] + + cb.text = "set" + ret = cb.render() + assert ret == [ + ('commander_command', 'set'), + ('text', ' '), + ('commander_hint', 'option '), + ('commander_hint', 'value '), + ] diff --git a/test/mitmproxy/tools/console/test_defaultkeys.py b/test/mitmproxy/tools/console/test_defaultkeys.py index 52075c84..58a0a585 100644 --- a/test/mitmproxy/tools/console/test_defaultkeys.py +++ b/test/mitmproxy/tools/console/test_defaultkeys.py @@ -1,14 +1,18 @@ +import pytest + +import mitmproxy.types +from mitmproxy import command +from mitmproxy import ctx from mitmproxy.test.tflow import tflow from mitmproxy.tools.console import defaultkeys from mitmproxy.tools.console import keymap from mitmproxy.tools.console import master -from mitmproxy import command - -import pytest @pytest.mark.asyncio async def test_commands_exist(): + command_manager = command.CommandManager(ctx) + km = keymap.Keymap(None) defaultkeys.map(km) assert km.bindings @@ -16,7 +20,14 @@ async def test_commands_exist(): await m.load_flow(tflow()) for binding in km.bindings: - cmd, *args = command.lexer(binding.command) + parsed, _ = command_manager.parse_partial(binding.command.strip()) + + cmd = parsed[0].value + args = [ + a.value for a in parsed[1:] + if a.type != mitmproxy.types.Space + ] + assert cmd in m.commands.commands cmd_obj = m.commands.commands[cmd] |