diff options
author | kotfu <kotfu@kotfu.net> | 2018-05-02 19:11:28 -0700 |
---|---|---|
committer | kotfu <kotfu@kotfu.net> | 2018-05-02 19:11:28 -0700 |
commit | 9ade8ac377b90f36445aeec1de01b650bbad2283 (patch) | |
tree | 78dede898fec07147302ce188a67f7ce09485a8c /tests | |
parent | ad634b2e7f68392727246f796647b92d67172011 (diff) | |
parent | e8d952574743c00e2116d24044220cbaa95cfb38 (diff) | |
download | cmd2-git-9ade8ac377b90f36445aeec1de01b650bbad2283.tar.gz |
Merge branch 'ply' of https://github.com/python-cmd2/cmd2 into ply
Diffstat (limited to 'tests')
26 files changed, 263 insertions, 26 deletions
diff --git a/tests/conftest.py b/tests/conftest.py index ed76cba9..562ca4fa 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,7 +10,7 @@ import sys from pytest import fixture from unittest import mock -import cmd2 +from cmd2 import cmd2 # Prefer statically linked gnureadline if available (for macOS compatibility due to issues with libedit) try: @@ -89,7 +89,7 @@ debug: False echo: False editor: vim feedback_to_output: False -locals_in_py: True +locals_in_py: False prompt: (Cmd) quiet: False timing: False @@ -106,7 +106,7 @@ debug: False # Show full error stack on error echo: False # Echo command issued into output editor: vim # Program used by ``edit`` feedback_to_output: False # Include nonessentials in `|`, `>` results -locals_in_py: True # Allow access to your application in py via self +locals_in_py: False # Allow access to your application in py via self prompt: (Cmd) # The prompt issued to solicit input quiet: False # Don't print nonessential feedback timing: False # Report execution times diff --git a/tests/pyscript/bar1.py b/tests/pyscript/bar1.py new file mode 100644 index 00000000..c6276a87 --- /dev/null +++ b/tests/pyscript/bar1.py @@ -0,0 +1 @@ +app.bar('11', '22') diff --git a/tests/pyscript/foo1.py b/tests/pyscript/foo1.py new file mode 100644 index 00000000..6e345d95 --- /dev/null +++ b/tests/pyscript/foo1.py @@ -0,0 +1 @@ +app.foo('aaa', 'bbb', counter=3, trueval=True, constval=True) diff --git a/tests/pyscript/foo2.py b/tests/pyscript/foo2.py new file mode 100644 index 00000000..d4df7616 --- /dev/null +++ b/tests/pyscript/foo2.py @@ -0,0 +1 @@ +app.foo('11', '22', '33', '44', counter=3, trueval=True, constval=True) diff --git a/tests/pyscript/foo3.py b/tests/pyscript/foo3.py new file mode 100644 index 00000000..db69edaf --- /dev/null +++ b/tests/pyscript/foo3.py @@ -0,0 +1 @@ +app.foo('11', '22', '33', '44', '55', '66', counter=3, trueval=False, constval=False) diff --git a/tests/pyscript/foo4.py b/tests/pyscript/foo4.py new file mode 100644 index 00000000..88fd3ce8 --- /dev/null +++ b/tests/pyscript/foo4.py @@ -0,0 +1,8 @@ +result = app.foo('aaa', 'bbb', counter=3) +out_text = 'Fail' +if result: + data = result.data + if 'aaa' in data.variable and 'bbb' in data.variable and data.counter == 3: + out_text = 'Success' + +print(out_text) diff --git a/tests/pyscript/help.py b/tests/pyscript/help.py new file mode 100644 index 00000000..3f67793c --- /dev/null +++ b/tests/pyscript/help.py @@ -0,0 +1 @@ +app.help()
\ No newline at end of file diff --git a/tests/pyscript/help_media.py b/tests/pyscript/help_media.py new file mode 100644 index 00000000..78025bdd --- /dev/null +++ b/tests/pyscript/help_media.py @@ -0,0 +1 @@ +app.help('media') diff --git a/tests/pyscript/media_movies_add1.py b/tests/pyscript/media_movies_add1.py new file mode 100644 index 00000000..a9139cb1 --- /dev/null +++ b/tests/pyscript/media_movies_add1.py @@ -0,0 +1 @@ +app.media.movies.add('My Movie', 'PG-13', director=('George Lucas', 'J. J. Abrams')) diff --git a/tests/pyscript/media_movies_add2.py b/tests/pyscript/media_movies_add2.py new file mode 100644 index 00000000..5c4617ae --- /dev/null +++ b/tests/pyscript/media_movies_add2.py @@ -0,0 +1 @@ +app.media.movies.add('My Movie', 'PG-13', actor=('Mark Hamill'), director=('George Lucas', 'J. J. Abrams')) diff --git a/tests/pyscript/media_movies_list1.py b/tests/pyscript/media_movies_list1.py new file mode 100644 index 00000000..0124bbcb --- /dev/null +++ b/tests/pyscript/media_movies_list1.py @@ -0,0 +1 @@ +app.media.movies.list()
\ No newline at end of file diff --git a/tests/pyscript/media_movies_list2.py b/tests/pyscript/media_movies_list2.py new file mode 100644 index 00000000..83f6c8ff --- /dev/null +++ b/tests/pyscript/media_movies_list2.py @@ -0,0 +1 @@ +app.media().movies().list()
\ No newline at end of file diff --git a/tests/pyscript/media_movies_list3.py b/tests/pyscript/media_movies_list3.py new file mode 100644 index 00000000..4fcf1288 --- /dev/null +++ b/tests/pyscript/media_movies_list3.py @@ -0,0 +1 @@ +app('media movies list')
\ No newline at end of file diff --git a/tests/pyscript/media_movies_list4.py b/tests/pyscript/media_movies_list4.py new file mode 100644 index 00000000..1165b0c5 --- /dev/null +++ b/tests/pyscript/media_movies_list4.py @@ -0,0 +1 @@ +app.media.movies.list(actor='Mark Hamill') diff --git a/tests/pyscript/media_movies_list5.py b/tests/pyscript/media_movies_list5.py new file mode 100644 index 00000000..962b1516 --- /dev/null +++ b/tests/pyscript/media_movies_list5.py @@ -0,0 +1 @@ +app.media.movies.list(actor=('Mark Hamill', 'Carrie Fisher')) diff --git a/tests/pyscript/media_movies_list6.py b/tests/pyscript/media_movies_list6.py new file mode 100644 index 00000000..5f8d3654 --- /dev/null +++ b/tests/pyscript/media_movies_list6.py @@ -0,0 +1 @@ +app.media.movies.list(rating='PG') diff --git a/tests/pyscript/media_movies_list7.py b/tests/pyscript/media_movies_list7.py new file mode 100644 index 00000000..bb0e28bb --- /dev/null +++ b/tests/pyscript/media_movies_list7.py @@ -0,0 +1 @@ +app.media.movies.list(rating=('PG', 'PG-13')) diff --git a/tests/scripts/recursive.py b/tests/scripts/recursive.py index 84f445bb..32c981b6 100644 --- a/tests/scripts/recursive.py +++ b/tests/scripts/recursive.py @@ -3,4 +3,4 @@ """ Example demonstrating that running a Python script recursively inside another Python script isn't allowed """ -cmd('pyscript ../script.py') +app('pyscript ../script.py') diff --git a/tests/test_argparse.py b/tests/test_argparse.py index f7c6eaba..94a7b5ed 100644 --- a/tests/test_argparse.py +++ b/tests/test_argparse.py @@ -5,7 +5,7 @@ Cmd2 testing for argument parsing import argparse import pytest -import cmd2 +from cmd2 import cmd2 from unittest import mock from .conftest import run_cmd, StdOut diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py index 17760d4d..b570ad3c 100644 --- a/tests/test_cmd2.py +++ b/tests/test_cmd2.py @@ -21,7 +21,7 @@ try: except ImportError: from unittest import mock -import cmd2 +from cmd2 import cmd2 from .conftest import run_cmd, normalize, BASE_HELP, BASE_HELP_VERBOSE, \ HELP_HISTORY, SHORTCUTS_TXT, SHOW_TXT, SHOW_LONG, StdOut @@ -109,7 +109,7 @@ def test_base_show_readonly(base_app): def test_cast(): - cast = cmd2.cmd2.cast + cast = cmd2.cast # Boolean assert cast(True, True) == True @@ -132,7 +132,7 @@ def test_cast(): assert cast([1,2], [3,4]) == [3,4] def test_cast_problems(capsys): - cast = cmd2.cmd2.cast + cast = cmd2.cast expected = 'Problem setting parameter (now {}) to {}; incorrect type?\n' @@ -256,8 +256,8 @@ def test_base_error(base_app): @pytest.fixture def hist(): - from cmd2.cmd2 import HistoryItem - h = cmd2.cmd2.History([HistoryItem('first'), HistoryItem('second'), HistoryItem('third'), HistoryItem('fourth')]) + from cmd2.cmd2 import History, HistoryItem + h = History([HistoryItem('first'), HistoryItem('second'), HistoryItem('third'), HistoryItem('fourth')]) return h def test_history_span(hist): @@ -700,18 +700,18 @@ def test_pipe_to_shell_error(base_app, capsys): assert err.startswith("EXCEPTION of type '{}' occurred with message:".format(expected_error)) -@pytest.mark.skipif(not cmd2.cmd2.can_clip, +@pytest.mark.skipif(not cmd2.can_clip, reason="Pyperclip could not find a copy/paste mechanism for your system") def test_send_to_paste_buffer(base_app): # Test writing to the PasteBuffer/Clipboard run_cmd(base_app, 'help >') expected = normalize(BASE_HELP) - assert normalize(cmd2.cmd2.get_paste_buffer()) == expected + assert normalize(cmd2.get_paste_buffer()) == expected # Test appending to the PasteBuffer/Clipboard run_cmd(base_app, 'help history >>') expected = normalize(BASE_HELP + '\n' + HELP_HISTORY) - assert normalize(cmd2.cmd2.get_paste_buffer()) == expected + assert normalize(cmd2.get_paste_buffer()) == expected def test_base_timing(base_app, capsys): @@ -1368,7 +1368,7 @@ optional arguments: reason="cmd2._which function only used on Mac and Linux") def test_which_editor_good(): editor = 'vi' - path = cmd2.cmd2._which(editor) + path = cmd2._which(editor) # Assert that the vi editor was found because it should exist on all Mac and Linux systems assert path @@ -1376,7 +1376,7 @@ def test_which_editor_good(): reason="cmd2._which function only used on Mac and Linux") def test_which_editor_bad(): editor = 'notepad.exe' - path = cmd2.cmd2._which(editor) + path = cmd2._which(editor) # Assert that the editor wasn't found because no notepad.exe on non-Windows systems ;-) assert path is None @@ -1403,7 +1403,7 @@ def multiline_app(): return app def test_multiline_complete_empty_statement_raises_exception(multiline_app): - with pytest.raises(cmd2.cmd2.EmptyStatement): + with pytest.raises(cmd2.EmptyStatement): multiline_app._complete_statement('') def test_multiline_complete_statement_without_terminator(multiline_app): @@ -1421,7 +1421,7 @@ def test_multiline_complete_statement_without_terminator(multiline_app): def test_clipboard_failure(capsys): # Force cmd2 clipboard to be disabled - cmd2.cmd2.disable_clip() + cmd2.disable_clip() app = cmd2.Cmd() # Redirect command output to the clipboard when a clipboard isn't present diff --git a/tests/test_completion.py b/tests/test_completion.py index 46e68764..a027d780 100644 --- a/tests/test_completion.py +++ b/tests/test_completion.py @@ -12,7 +12,7 @@ import argparse import os import sys -import cmd2 +from cmd2 import cmd2 import pytest from .conftest import complete_tester, StdOut from examples.subcommands import SubcommandsExample diff --git a/tests/test_parsing.py b/tests/test_parsing.py index 3f8fc07c..7940bbd8 100644 --- a/tests/test_parsing.py +++ b/tests/test_parsing.py @@ -7,7 +7,7 @@ Released under MIT license, see LICENSE file """ import pytest -import cmd2 +from cmd2 import cmd2 from cmd2.parsing import StatementParser from cmd2 import utils @@ -292,10 +292,10 @@ def test_parse_redirect_to_unicode_filename(parser): def test_empty_statement_raises_exception(): app = cmd2.Cmd() - with pytest.raises(cmd2.cmd2.EmptyStatement): + with pytest.raises(cmd2.EmptyStatement): app._complete_statement('') - with pytest.raises(cmd2.cmd2.EmptyStatement): + with pytest.raises(cmd2.EmptyStatement): app._complete_statement(' ') @pytest.mark.parametrize('line,command,args', [ diff --git a/tests/test_pyscript.py b/tests/test_pyscript.py new file mode 100644 index 00000000..8d0cefd8 --- /dev/null +++ b/tests/test_pyscript.py @@ -0,0 +1,214 @@ +""" +Unit/functional testing for argparse completer in cmd2 + +Copyright 2018 Eric Lin <anselor@gmail.com> +Released under MIT license, see LICENSE file +""" +import os +import pytest +from cmd2.cmd2 import Cmd, with_argparser +from cmd2 import argparse_completer +from .conftest import run_cmd, StdOut +from cmd2.utils import namedtuple_with_defaults + +class PyscriptExample(Cmd): + ratings_types = ['G', 'PG', 'PG-13', 'R', 'NC-17'] + + def _do_media_movies(self, args) -> None: + if not args.command: + self.do_help('media movies') + else: + print('media movies ' + str(args.__dict__)) + + def _do_media_shows(self, args) -> None: + if not args.command: + self.do_help('media shows') + + if not args.command: + self.do_help('media shows') + else: + print('media shows ' + str(args.__dict__)) + + media_parser = argparse_completer.ACArgumentParser(prog='media') + + media_types_subparsers = media_parser.add_subparsers(title='Media Types', dest='type') + + movies_parser = media_types_subparsers.add_parser('movies') + movies_parser.set_defaults(func=_do_media_movies) + + movies_commands_subparsers = movies_parser.add_subparsers(title='Commands', dest='command') + + movies_list_parser = movies_commands_subparsers.add_parser('list') + + movies_list_parser.add_argument('-t', '--title', help='Title Filter') + movies_list_parser.add_argument('-r', '--rating', help='Rating Filter', nargs='+', + choices=ratings_types) + movies_list_parser.add_argument('-d', '--director', help='Director Filter') + movies_list_parser.add_argument('-a', '--actor', help='Actor Filter', action='append') + + movies_add_parser = movies_commands_subparsers.add_parser('add') + movies_add_parser.add_argument('title', help='Movie Title') + movies_add_parser.add_argument('rating', help='Movie Rating', choices=ratings_types) + movies_add_parser.add_argument('-d', '--director', help='Director', nargs=(1, 2), required=True) + movies_add_parser.add_argument('actor', help='Actors', nargs='*') + + movies_delete_parser = movies_commands_subparsers.add_parser('delete') + + shows_parser = media_types_subparsers.add_parser('shows') + shows_parser.set_defaults(func=_do_media_shows) + + shows_commands_subparsers = shows_parser.add_subparsers(title='Commands', dest='command') + + shows_list_parser = shows_commands_subparsers.add_parser('list') + + @with_argparser(media_parser) + def do_media(self, args): + """Media management command demonstrates multiple layers of subcommands being handled by AutoCompleter""" + func = getattr(args, 'func', None) + if func is not None: + # Call whatever subcommand function was selected + func(self, args) + else: + # No subcommand was provided, so call help + self.do_help('media') + + foo_parser = argparse_completer.ACArgumentParser(prog='foo') + foo_parser.add_argument('-c', dest='counter', action='count') + foo_parser.add_argument('-t', dest='trueval', action='store_true') + foo_parser.add_argument('-n', dest='constval', action='store_const', const=42) + foo_parser.add_argument('variable', nargs=(2, 3)) + foo_parser.add_argument('optional', nargs='?') + foo_parser.add_argument('zeroormore', nargs='*') + + @with_argparser(foo_parser) + def do_foo(self, args): + print('foo ' + str(args.__dict__)) + if self._in_py: + FooResult = namedtuple_with_defaults('FooResult', + ['counter', 'trueval', 'constval', + 'variable', 'optional', 'zeroormore']) + self._last_result = FooResult(**{'counter': args.counter, + 'trueval': args.trueval, + 'constval': args.constval, + 'variable': args.variable, + 'optional': args.optional, + 'zeroormore': args.zeroormore}) + + bar_parser = argparse_completer.ACArgumentParser(prog='bar') + bar_parser.add_argument('first') + bar_parser.add_argument('oneormore', nargs='+') + bar_parser.add_argument('-a', dest='aaa') + + @with_argparser(bar_parser) + def do_bar(self, args): + print('bar ' + str(args.__dict__)) + + +@pytest.fixture +def ps_app(): + c = PyscriptExample() + c.stdout = StdOut() + + return c + + +class PyscriptCustomNameExample(Cmd): + def __init__(self): + super().__init__() + self.pyscript_name = 'custom' + + def do_echo(self, out): + print(out) + + +@pytest.fixture +def ps_echo(): + c = PyscriptCustomNameExample() + c.stdout = StdOut() + + return c + + +@pytest.mark.parametrize('command, pyscript_file', [ + ('help', 'help.py'), + ('help media', 'help_media.py'), +]) +def test_pyscript_help(ps_app, capsys, request, command, pyscript_file): + test_dir = os.path.dirname(request.module.__file__) + python_script = os.path.join(test_dir, 'pyscript', pyscript_file) + expected = run_cmd(ps_app, command) + + assert len(expected) > 0 + assert len(expected[0]) > 0 + out = run_cmd(ps_app, 'pyscript {}'.format(python_script)) + assert len(out) > 0 + assert out == expected + + +@pytest.mark.parametrize('command, pyscript_file', [ + ('media movies list', 'media_movies_list1.py'), + ('media movies list', 'media_movies_list2.py'), + ('media movies list', 'media_movies_list3.py'), + ('media movies list -a "Mark Hamill"', 'media_movies_list4.py'), + ('media movies list -a "Mark Hamill" -a "Carrie Fisher"', 'media_movies_list5.py'), + ('media movies list -r PG', 'media_movies_list6.py'), + ('media movies list -r PG PG-13', 'media_movies_list7.py'), + ('media movies add "My Movie" PG-13 --director "George Lucas" "J. J. Abrams"', + 'media_movies_add1.py'), + ('media movies add "My Movie" PG-13 --director "George Lucas" "J. J. Abrams" "Mark Hamill"', + 'media_movies_add2.py'), + ('foo aaa bbb -ccc -t -n', 'foo1.py'), + ('foo 11 22 33 44 -ccc -t -n', 'foo2.py'), + ('foo 11 22 33 44 55 66 -ccc', 'foo3.py'), + ('bar 11 22', 'bar1.py') +]) +def test_pyscript_out(ps_app, capsys, request, command, pyscript_file): + test_dir = os.path.dirname(request.module.__file__) + python_script = os.path.join(test_dir, 'pyscript', pyscript_file) + run_cmd(ps_app, command) + expected, _ = capsys.readouterr() + + assert len(expected) > 0 + run_cmd(ps_app, 'pyscript {}'.format(python_script)) + out, _ = capsys.readouterr() + assert len(out) > 0 + assert out == expected + + +@pytest.mark.parametrize('command, error', [ + ('app.noncommand', 'AttributeError'), + ('app.media.noncommand', 'AttributeError'), + ('app.media.movies.list(artist="Invalid Keyword")', 'TypeError'), + ('app.foo(counter="a")', 'TypeError'), + ('app.foo("aaa")', 'ValueError'), +]) +def test_pyscript_errors(ps_app, capsys, command, error): + run_cmd(ps_app, 'py {}'.format(command)) + _, err = capsys.readouterr() + + assert len(err) > 0 + assert 'Traceback' in err + assert error in err + + +@pytest.mark.parametrize('pyscript_file, exp_out', [ + ('foo4.py', 'Success'), +]) +def test_pyscript_results(ps_app, capsys, request, pyscript_file, exp_out): + test_dir = os.path.dirname(request.module.__file__) + python_script = os.path.join(test_dir, 'pyscript', pyscript_file) + + run_cmd(ps_app, 'pyscript {}'.format(python_script)) + expected, _ = capsys.readouterr() + assert len(expected) > 0 + assert exp_out in expected + + +def test_pyscript_custom_name(ps_echo, capsys): + message = 'blah!' + run_cmd(ps_echo, 'py custom.echo("{}")'.format(message)) + expected, _ = capsys.readouterr() + assert len(expected) > 0 + expected = expected.splitlines() + assert message == expected[0] + diff --git a/tests/test_submenu.py b/tests/test_submenu.py index fbb9857b..db334daa 100644 --- a/tests/test_submenu.py +++ b/tests/test_submenu.py @@ -4,7 +4,7 @@ Cmd2 testing for argument parsing """ import pytest -import cmd2 +from cmd2 import cmd2 from .conftest import run_cmd, StdOut, normalize diff --git a/tests/test_transcript.py b/tests/test_transcript.py index 6330ab09..c0fb49c1 100644 --- a/tests/test_transcript.py +++ b/tests/test_transcript.py @@ -14,7 +14,7 @@ import random from unittest import mock import pytest -import cmd2 +from cmd2 import cmd2 from .conftest import run_cmd, StdOut, normalize class CmdLineApp(cmd2.Cmd): @@ -184,7 +184,7 @@ now: ---> assert out == expected -class TestMyAppCase(cmd2.cmd2.Cmd2TestCase): +class TestMyAppCase(cmd2.Cmd2TestCase): CmdApp = CmdLineApp CmdApp.testfiles = ['tests/transcript.txt'] @@ -288,7 +288,7 @@ def test_transcript(request, capsys, filename, feedback_to_output): def test_parse_transcript_expected(expected, transformed): app = CmdLineApp() - class TestMyAppCase(cmd2.cmd2.Cmd2TestCase): + class TestMyAppCase(cmd2.Cmd2TestCase): cmdapp = app testcase = TestMyAppCase() diff --git a/tests/transcripts/regex_set.txt b/tests/transcripts/regex_set.txt index bf88c294..b818c464 100644 --- a/tests/transcripts/regex_set.txt +++ b/tests/transcripts/regex_set.txt @@ -10,7 +10,7 @@ debug: False echo: False editor: /.*/ feedback_to_output: False -locals_in_py: True +locals_in_py: False maxrepeats: 3 prompt: (Cmd)/ / quiet: False |