diff options
author | Todd Leonhardt <todd.leonhardt@gmail.com> | 2017-07-02 18:39:14 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-02 18:39:14 -0400 |
commit | 29578bee1857f9c672ab2bc60f47a1d02d889577 (patch) | |
tree | 7324bef4db334308b257388f758e259b85d09da7 | |
parent | 482e9ce1f21677667eca52326d966a594ef6cc1a (diff) | |
parent | b0c3fa4dd7d762fb812a9cf74e6879dbfba04a50 (diff) | |
download | cmd2-git-29578bee1857f9c672ab2bc60f47a1d02d889577.tar.gz |
Merge pull request #165 from python-cmd2/history_tests
Fixed bugs, removed dead code, and added unit tests
-rwxr-xr-x | cmd2.py | 22 | ||||
-rw-r--r-- | tests/test_cmd2.py | 41 | ||||
-rw-r--r-- | tests/test_parsing.py | 62 | ||||
-rw-r--r-- | tests/test_transcript.py | 3 |
4 files changed, 104 insertions, 24 deletions
@@ -1967,24 +1967,6 @@ class History(list): result = None return result - def search(self, target): - """ Search the history for a particular term. - - :param target: str - term to search for - :return: List[str] - list of matches - """ - # If there is no history yet, don't try to search through a non-existent list, just return an empty list - if len(self) < 1: - return [] - - target = target.strip() - if target[0] == target[-1] == '/' and len(target) > 1: - target = target[1:-1] - else: - target = re.escape(target) - pattern = re.compile(target, re.IGNORECASE) - return [s for s in self if pattern.search(s)] - spanpattern = re.compile(r'^\s*(?P<start>-?\d+)?\s*(?P<separator>:|(\.{2,}))?\s*(?P<end>-?\d+)?\s*$') def span(self, raw): @@ -2287,6 +2269,10 @@ class CmdResult(namedtuple_with_two_defaults('CmdResult', ['out', 'err', 'war']) """If err is an empty string, treat the result as a success; otherwise treat it as a failure.""" return not self.err + def __nonzero__(self): + """Python 2 uses this method for determining Truthiness""" + return self.__bool__() + if __name__ == '__main__': # If run as the main application, simply start a bare-bones cmd2 application with only built-in functionality. diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py index 544b758e..02a26af9 100644 --- a/tests/test_cmd2.py +++ b/tests/test_cmd2.py @@ -1154,3 +1154,44 @@ def test_clipboard_failure(capsys): out, err = capsys.readouterr() assert out == '' assert 'Cannot redirect to paste buffer; install ``xclip`` and re-run to enable' in err + + +def test_run_command_with_empty_arg(base_app): + command = 'help' + run_cmd(base_app, command) + out = run_cmd(base_app, 'run') + expected = normalize('{}\n\n'.format(command) + BASE_HELP) + assert out == expected + +def test_run_command_with_empty_history(base_app): + out = run_cmd(base_app, 'run') + assert out == [] + + +class CmdResultApp(cmd2.Cmd): + def __init__(self, *args, **kwargs): + # Need to use this older form of invoking super class constructor to support Python 2.x and Python 3.x + cmd2.Cmd.__init__(self, *args, **kwargs) + + def do_affirmative(self, arg): + self._last_result = cmd2.CmdResult(arg) + + def do_negative(self, arg): + self._last_result = cmd2.CmdResult('', arg) + +@pytest.fixture +def cmdresult_app(): + app = CmdResultApp() + app.stdout = StdOut() + return app + +def test_cmdresult(cmdresult_app): + arg = 'foo' + run_cmd(cmdresult_app, 'affirmative {}'.format(arg)) + assert cmdresult_app._last_result + assert cmdresult_app._last_result == cmd2.CmdResult(arg) + + arg = 'bar' + run_cmd(cmdresult_app, 'negative {}'.format(arg)) + assert not cmdresult_app._last_result + assert cmdresult_app._last_result == cmd2.CmdResult('', arg) diff --git a/tests/test_parsing.py b/tests/test_parsing.py index 1a32a734..254aef15 100644 --- a/tests/test_parsing.py +++ b/tests/test_parsing.py @@ -49,17 +49,69 @@ def test_remaining_args(): def test_history_span(hist): h = hist + assert h == ['first', 'second', 'third', 'fourth'] assert h.span('-2..') == ['third', 'fourth'] - assert h.span('2..3') == ['second', 'third'] + assert h.span('2..3') == ['second', 'third'] # Inclusive of end assert h.span('3') == ['third'] - assert h.span(':') == ['first', 'second', 'third', 'fourth'] + assert h.span(':') == h assert h.span('2..') == ['second', 'third', 'fourth'] assert h.span('-1') == ['fourth'] assert h.span('-2..-3') == ['third', 'second'] + assert h.span('*') == h -def test_history_search(hist): - assert hist.search('o') == ['second', 'fourth'] - assert hist.search('/IR/') == ['first', 'third'] +def test_history_get(hist): + h = hist + assert h == ['first', 'second', 'third', 'fourth'] + assert h.get('') == h + assert h.get('-2') == h[:-2] + assert h.get('5') == [] + assert h.get('2-3') == ['second'] # Exclusive of end + assert h.get('ir') == ['first', 'third'] # Normal string search for all elements containing "ir" + assert h.get('/i.*d/') == ['third'] # Regex string search "i", then anything, then "d" + + +def test_cast(): + cast = cmd2.cast + + # Boolean + assert cast(True, True) == True + assert cast(True, False) == False + assert cast(True, 0) == False + assert cast(True, 1) == True + assert cast(True, 'on') == True + assert cast(True, 'off') == False + assert cast(True, 'ON') == True + assert cast(True, 'OFF') == False + assert cast(True, 'y') == True + assert cast(True, 'n') == False + assert cast(True, 't') == True + assert cast(True, 'f') == False + + # Non-boolean same type + assert cast(1, 5) == 5 + assert cast(3.4, 2.7) == 2.7 + assert cast('foo', 'bar') == 'bar' + assert cast([1,2], [3,4]) == [3,4] + + +def test_cast_problems(capsys): + cast = cmd2.cast + + expected = 'Problem setting parameter (now {}) to {}; incorrect type?\n' + + # Boolean current, with new value not convertible to bool + current = True + new = [True, True] + assert cast(current, new) == current + out, err = capsys.readouterr() + assert out == expected.format(current, new) + + # Non-boolean current, with new value not convertible to current type + current = 1 + new = 'octopus' + assert cast(current, new) == current + out, err = capsys.readouterr() + assert out == expected.format(current, new) def test_parse_empty_string(parser): diff --git a/tests/test_transcript.py b/tests/test_transcript.py index d1363f8e..87640b5e 100644 --- a/tests/test_transcript.py +++ b/tests/test_transcript.py @@ -30,6 +30,7 @@ class CmdLineApp(Cmd): # Need to use this older form of invoking super class constructor to support Python 2.x and Python 3.x Cmd.__init__(self, *args, **kwargs) + self.intro = 'This is an intro banner ...' # Configure how arguments are parsed for @options commands set_posix_shlex(False) @@ -224,7 +225,7 @@ def test_optarser_options_with_spaces_in_quotes(_demo_app): def test_commands_at_invocation(): testargs = ["prog", "say hello", "say Gracie", "quit"] - expected = "hello\nGracie\n" + expected = "This is an intro banner ...\nhello\nGracie\n" with mock.patch.object(sys, 'argv', testargs): app = CmdLineApp() app.stdout = StdOut() |