diff --git a/tests/lib/__init__.py b/tests/lib/__init__.py index a28c4588..c6ac15d3 100644 --- a/tests/lib/__init__.py +++ b/tests/lib/__init__.py @@ -76,23 +76,29 @@ def new_module(name, **kwargs): class AttrReplace(object): - def __init__(self, obj, attr, new): + def __init__(self, obj, *args): self.obj = obj - self.attr = attr - self.new = new + self.attrs = args[::2] + self.new = args[1::2] def __enter__(self): - try: - self.old = getattr(self.obj, self.attr) - except AttributeError: - pass - setattr(self.obj, self.attr, self.new) + self.old = {} + for i, attr in enumerate(self.attrs): + try: + self.old[i] = getattr(self.obj, attr) + except AttributeError: + pass + for attr, new in zip(self.attrs, self.new): + setattr(self.obj, attr, new) def __exit__(self, *args): - try: - setattr(self.obj, self.attr, self.old) - except AttributeError: - delattr(self.obj, self.attr) + for i, attr in enumerate(self.attrs): + try: + old = self.old[i] + except KeyError: + delattr(self.obj, attr) + else: + setattr(self.obj, attr, old) replace_attr = AttrReplace diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py new file mode 100644 index 00000000..05db6ab2 --- /dev/null +++ b/tests/test_cmdline.py @@ -0,0 +1,123 @@ +# vim:fileencoding=utf-8:noet + +'''Tests for shell.py parser''' + + +from powerline.shell import get_argparser, finish_args +from tests import TestCase +from tests.lib import replace_attr +import sys +if sys.version_info < (3,): + from io import BytesIO as StrIO +else: + from io import StringIO as StrIO # NOQA + + +class TestParser(TestCase): + def test_main_err(self): + parser = get_argparser() + out = StrIO() + err = StrIO() + def flush(): + out.truncate(0) + err.truncate(0) + with replace_attr(sys, 'stdout', out, 'stderr', err): + for raising_args, raising_reg in [ + ([], 'too few arguments|the following arguments are required: ext'), + (['-r'], 'expected one argument'), + (['shell', '-r'], 'expected one argument'), + (['shell', '-w'], 'expected one argument'), + (['shell', '-c'], 'expected one argument'), + (['shell', '-t'], 'expected one argument'), + (['shell', '-p'], 'expected one argument'), + (['shell', '-R'], 'expected one argument'), + (['shell', '--renderer_module'], 'expected one argument'), + (['shell', '--width'], 'expected one argument'), + (['shell', '--last_exit_code'], 'expected one argument'), + (['shell', '--last_pipe_status'], 'expected one argument'), + (['shell', '--config'], 'expected one argument'), + (['shell', '--theme_option'], 'expected one argument'), + (['shell', '--config_path'], 'expected one argument'), + (['shell', '--renderer_arg'], 'expected one argument'), + (['shell', '--jobnum'], 'expected one argument'), + (['-r', 'zsh_prompt'], 'too few arguments|the following arguments are required: ext'), + (['shell', '--last_exit_code', 'i'], 'invalid int value'), + (['shell', '--last_pipe_status', '1 i'], 'invalid value'), + (['shell', '-R', 'abc'], 'invalid value'), + ]: + self.assertRaises(SystemExit, parser.parse_args, raising_args) + self.assertFalse(out.getvalue()) + self.assertRegexpMatches(err.getvalue(), raising_reg) + flush() + + def test_main_normal(self): + parser = get_argparser() + out = StrIO() + err = StrIO() + with replace_attr(sys, 'stdout', out, 'stderr', err): + for argv, expargs in [ + (['shell'], {'ext': ['shell']}), + (['shell', '-r', 'zsh_prompt'], {'ext': ['shell'], 'renderer_module': 'zsh_prompt'}), + ([ + 'shell', + 'left', + '-r', 'zsh_prompt', + '--last_exit_code', '10', + '--last_pipe_status', '10 20 30', + '--jobnum=10', + '-w', '100', + '-c', 'common.term_truecolor=true', + '-c', 'common.spaces=4', + '-t', 'default.segment_data.hostname.before=H:', + '-p', '.', + '-R', 'smth={"abc":"def"}' + ], { + 'ext': ['shell'], + 'side': 'left', + 'renderer_module': 'zsh_prompt', + 'last_exit_code': 10, + 'last_pipe_status': [10, 20, 30], + 'jobnum': 10, + 'width': 100, + 'config': {'common': {'term_truecolor': True, 'spaces': 4}}, + 'theme_option': { + 'default': { + 'segment_data': { + 'hostname': { + 'before': 'H:' + } + } + } + }, + 'config_path': '.', + 'renderer_arg': {'smth': {'abc': 'def'}}, + }), + (['shell', '-R', 'arg=true'], {'ext': ['shell'], 'renderer_arg': {'arg': True}}), + (['shell', '-t', 'default.segment_info={"hostname": {}}'], { + 'ext': ['shell'], + 'theme_option': { + 'default': { + 'segment_info': { + 'hostname': {} + } + } + }, + }), + (['shell', '-c', 'common={ }'], {'ext': ['shell'], 'config': {'common': {}}}), + ]: + args = parser.parse_args(argv) + finish_args(args) + for key, val in expargs.items(): + self.assertEqual(getattr(args, key), val) + for key, val in args.__dict__.items(): + if key not in expargs: + self.assertFalse(val, msg='key {0} is {1} while it should be something false'.format(key, val)) + self.assertFalse(err.getvalue() + out.getvalue(), msg='unexpected output: {0!r} {1!r}'.format( + err.getvalue(), + out.getvalue(), + )) + + +if __name__ == '__main__': + from tests import main + main()