1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
# Copyright 2016-2018 Dirk Thomas
# Licensed under the Apache License, Version 2.0
from argparse import ArgumentParser
from unittest.mock import Mock
from unittest.mock import patch
from colcon_core.argument_parser import ArgumentParserDecorator
from colcon_core.argument_parser import ArgumentParserDecoratorExtensionPoint
from colcon_core.argument_parser import decorate_argument_parser
from colcon_core.argument_parser import get_argument_parser_extensions
import pytest
from .extension_point_context import ExtensionPointContext
class Extension1(ArgumentParserDecoratorExtensionPoint):
PRIORITY = 80
class Extension2(ArgumentParserDecoratorExtensionPoint):
pass
def test_get_argument_parser_extensions():
with ExtensionPointContext(extension1=Extension1, extension2=Extension2):
extensions = get_argument_parser_extensions()
assert ['extension2', 'extension1'] == \
list(extensions.keys())
def decorate_argument_parser_mock(*, parser):
class Decorator():
def __init__(self, parser):
self.parser = parser
def add_argument(self, *args, **kwargs):
pass # pragma: no cover
return Decorator(parser)
def test_decorate_argument_parser():
parser = ArgumentParser()
with ExtensionPointContext(extension1=Extension1, extension2=Extension2):
extensions = get_argument_parser_extensions()
# one invalid return value, one not implemented
extensions['extension1'].decorate_argument_parser = Mock(
return_value=None)
with patch('colcon_core.argument_parser.logger.error') as error:
decorated_parser = decorate_argument_parser(parser)
assert decorated_parser == parser
# the raised exceptions are catched and result in error messages
assert error.call_count == 2
assert len(error.call_args_list[0][0]) == 1
assert error.call_args_list[0][0][0].startswith(
"Exception in argument parser decorator extension 'extension2': "
'\n')
assert error.call_args_list[0][0][0].endswith(
'\nNotImplementedError\n')
assert len(error.call_args_list[1][0]) == 1
assert error.call_args_list[1][0][0].startswith(
"Exception in argument parser decorator extension 'extension1': "
'decorate_argument_parser() should return a parser like object\n')
# one exception, one valid decorator
extensions['extension2'].decorate_argument_parser = Mock(
side_effect=RuntimeError('custom exception'))
extensions['extension1'].decorate_argument_parser = Mock(
side_effect=decorate_argument_parser_mock)
with patch('colcon_core.argument_parser.logger.error') as error:
decorated_parser = decorate_argument_parser(parser)
assert decorated_parser.parser == parser
# the raised exception is catched and results in an error message
assert error.call_count == 1
assert len(error.call_args[0]) == 1
assert error.call_args[0][0].startswith(
"Exception in argument parser decorator extension 'extension2': "
'custom exception\n')
class Decorator(ArgumentParserDecorator):
def __init__(self, parser, **kwargs):
self.foo = 'foo'
super().__init__(parser, **kwargs)
def test_argument_parser_decorator():
parser = ArgumentParser()
# __getattr__
decorator = ArgumentParserDecorator(parser)
assert decorator.format_help == parser.format_help
del decorator.__dict__['_decoree']
with pytest.raises(AttributeError):
decorator.format_help
# __setattr__
decorator = Decorator(parser)
decorator.foo = 'bar'
assert 'foo' in decorator.__dict__
assert decorator.__dict__['foo'] == 'bar'
decorator.add_argument = True
assert parser.add_argument is True
assert 'bar' not in decorator.__dict__
del decorator.__dict__['_decoree']
decorator.bar = 'baz'
assert 'bar' in decorator.__dict__
assert decorator.__dict__['bar'] == 'baz'
# nesting
parser = ArgumentParser()
decorator = Decorator(parser)
group = decorator.add_argument_group()
group.add_argument('arg1')
group = decorator.add_mutually_exclusive_group()
group.add_argument('--arg2', action='store_true')
group = decorator.add_subparsers(dest='verb')
group = group.add_parser('do')
group.add_argument('arg3')
args = parser.parse_args(['ARG1', '--arg2', 'do', 'ARG3'])
assert args.arg1 == 'ARG1'
assert args.arg2 is True
assert args.verb == 'do'
assert args.arg3 == 'ARG3'
|