move code linting to a stricter pep8-esque auto-formatting tool, black

This commit is contained in:
Ryan Petrello
2021-03-19 12:44:51 -04:00
parent 9b702e46fe
commit c2ef0a6500
671 changed files with 20538 additions and 21924 deletions

View File

@@ -7,7 +7,6 @@ from awxkit.cli import run, CLI
class MockedCLI(CLI):
def fetch_version_root(self):
pass
@@ -17,9 +16,7 @@ class MockedCLI(CLI):
@property
def json(self):
return {
'users': None
}
return {'users': None}
@pytest.mark.parametrize('help_param', ['-h', '--help'])
@@ -29,10 +26,7 @@ def test_help(capfd, help_param):
out, err = capfd.readouterr()
assert "usage:" in out
for snippet in (
'--conf.host https://example.awx.org]',
'-v, --verbose'
):
for snippet in ('--conf.host https://example.awx.org]', '-v, --verbose'):
assert snippet in out
@@ -59,8 +53,5 @@ def test_list_resources(capfd, resource):
_, out = capfd.readouterr()
assert "usage:" in out
for snippet in (
'--conf.host https://example.awx.org]',
'-v, --verbose'
):
for snippet in ('--conf.host https://example.awx.org]', '-v, --verbose'):
assert snippet in out

View File

@@ -4,16 +4,15 @@ from requests.exceptions import ConnectionError
from awxkit.cli import CLI
from awxkit import config
def test_host_from_environment():
cli = CLI()
cli.parse_args(
['awx'],
env={'TOWER_HOST': 'https://xyz.local'}
)
cli.parse_args(['awx'], env={'TOWER_HOST': 'https://xyz.local'})
with pytest.raises(ConnectionError):
cli.connect()
assert config.base_url == 'https://xyz.local'
def test_host_from_argv():
cli = CLI()
cli.parse_args(['awx', '--conf.host', 'https://xyz.local'])
@@ -21,43 +20,30 @@ def test_host_from_argv():
cli.connect()
assert config.base_url == 'https://xyz.local'
def test_username_and_password_from_environment():
cli = CLI()
cli.parse_args(
['awx'],
env={
'TOWER_USERNAME': 'mary',
'TOWER_PASSWORD': 'secret'
}
)
cli.parse_args(['awx'], env={'TOWER_USERNAME': 'mary', 'TOWER_PASSWORD': 'secret'})
with pytest.raises(ConnectionError):
cli.connect()
assert config.credentials.default.username == 'mary'
assert config.credentials.default.password == 'secret'
def test_username_and_password_argv():
cli = CLI()
cli.parse_args([
'awx', '--conf.username', 'mary', '--conf.password', 'secret'
])
cli.parse_args(['awx', '--conf.username', 'mary', '--conf.password', 'secret'])
with pytest.raises(ConnectionError):
cli.connect()
assert config.credentials.default.username == 'mary'
assert config.credentials.default.password == 'secret'
def test_config_precedence():
cli = CLI()
cli.parse_args(
[
'awx', '--conf.username', 'mary', '--conf.password', 'secret'
],
env={
'TOWER_USERNAME': 'IGNORE',
'TOWER_PASSWORD': 'IGNORE'
}
)
cli.parse_args(['awx', '--conf.username', 'mary', '--conf.password', 'secret'], env={'TOWER_USERNAME': 'IGNORE', 'TOWER_PASSWORD': 'IGNORE'})
with pytest.raises(ConnectionError):
cli.connect()

View File

@@ -11,19 +11,17 @@ from awxkit.cli.resource import Import
def test_json_empty_list():
page = Page.from_json({
'results': []
})
page = Page.from_json({'results': []})
formatted = format_response(page)
assert json.loads(formatted) == {'results': []}
def test_yaml_empty_list():
page = Page.from_json({
'results': []
})
page = Page.from_json({'results': []})
formatted = format_response(page, fmt='yaml')
assert yaml.safe_load(formatted) == {'results': []}
def test_json_list():
users = {
'results': [
@@ -36,6 +34,7 @@ def test_json_list():
formatted = format_response(page)
assert json.loads(formatted) == users
def test_yaml_list():
users = {
'results': [

View File

@@ -11,13 +11,11 @@ from awxkit.cli.options import ResourceOptionsParser
class ResourceOptionsParser(ResourceOptionsParser):
def get_allowed_options(self):
self.allowed_options = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']
class OptionsPage(Page):
def options(self):
return self
@@ -33,30 +31,31 @@ class OptionsPage(Page):
class TestOptions(unittest.TestCase):
def setUp(self):
_parser = argparse.ArgumentParser()
self.parser = _parser.add_subparsers(help='action')
def test_list(self):
page = OptionsPage.from_json({
'actions': {
'GET': {},
'POST': {},
page = OptionsPage.from_json(
{
'actions': {
'GET': {},
'POST': {},
}
}
})
)
ResourceOptionsParser(None, page, 'users', self.parser)
assert 'list' in self.parser.choices
def test_list_filtering(self):
page = OptionsPage.from_json({
'actions': {
'GET': {},
'POST': {
'first_name': {'type': 'string'}
},
page = OptionsPage.from_json(
{
'actions': {
'GET': {},
'POST': {'first_name': {'type': 'string'}},
}
}
})
)
options = ResourceOptionsParser(None, page, 'users', self.parser)
options.build_query_arguments('list', 'POST')
assert 'list' in self.parser.choices
@@ -66,14 +65,14 @@ class TestOptions(unittest.TestCase):
assert '--first_name TEXT' in out.getvalue()
def test_list_not_filterable(self):
page = OptionsPage.from_json({
'actions': {
'GET': {},
'POST': {
'middle_name': {'type': 'string', 'filterable': False}
},
page = OptionsPage.from_json(
{
'actions': {
'GET': {},
'POST': {'middle_name': {'type': 'string', 'filterable': False}},
}
}
})
)
options = ResourceOptionsParser(None, page, 'users', self.parser)
options.build_query_arguments('list', 'POST')
assert 'list' in self.parser.choices
@@ -83,16 +82,18 @@ class TestOptions(unittest.TestCase):
assert '--middle_name' not in out.getvalue()
def test_creation_optional_argument(self):
page = OptionsPage.from_json({
'actions': {
'POST': {
'first_name': {
'type': 'string',
'help_text': 'Please specify your first name',
}
},
page = OptionsPage.from_json(
{
'actions': {
'POST': {
'first_name': {
'type': 'string',
'help_text': 'Please specify your first name',
}
},
}
}
})
)
options = ResourceOptionsParser(None, page, 'users', self.parser)
options.build_query_arguments('create', 'POST')
assert 'create' in self.parser.choices
@@ -102,17 +103,13 @@ class TestOptions(unittest.TestCase):
assert '--first_name TEXT Please specify your first name' in out.getvalue()
def test_creation_required_argument(self):
page = OptionsPage.from_json({
'actions': {
'POST': {
'username': {
'type': 'string',
'help_text': 'Please specify a username',
'required': True
}
},
page = OptionsPage.from_json(
{
'actions': {
'POST': {'username': {'type': 'string', 'help_text': 'Please specify a username', 'required': True}},
}
}
})
)
options = ResourceOptionsParser(None, page, 'users', self.parser)
options.build_query_arguments('create', 'POST')
assert 'create' in self.parser.choices
@@ -122,13 +119,13 @@ class TestOptions(unittest.TestCase):
assert '--username TEXT Please specify a username'
def test_integer_argument(self):
page = OptionsPage.from_json({
'actions': {
'POST': {
'max_hosts': {'type': 'integer'}
},
page = OptionsPage.from_json(
{
'actions': {
'POST': {'max_hosts': {'type': 'integer'}},
}
}
})
)
options = ResourceOptionsParser(None, page, 'organizations', self.parser)
options.build_query_arguments('create', 'POST')
assert 'create' in self.parser.choices
@@ -138,13 +135,13 @@ class TestOptions(unittest.TestCase):
assert '--max_hosts INTEGER' in out.getvalue()
def test_boolean_argument(self):
page = OptionsPage.from_json({
'actions': {
'POST': {
'diff_mode': {'type': 'boolean'}
},
page = OptionsPage.from_json(
{
'actions': {
'POST': {'diff_mode': {'type': 'boolean'}},
}
}
})
)
options = ResourceOptionsParser(None, page, 'users', self.parser)
options.build_query_arguments('create', 'POST')
assert 'create' in self.parser.choices
@@ -154,23 +151,25 @@ class TestOptions(unittest.TestCase):
assert '--diff_mode BOOLEAN' in out.getvalue()
def test_choices(self):
page = OptionsPage.from_json({
'actions': {
'POST': {
'verbosity': {
'type': 'integer',
'choices': [
(0, '0 (Normal)'),
(1, '1 (Verbose)'),
(2, '2 (More Verbose)'),
(3, '3 (Debug)'),
(4, '4 (Connection Debug)'),
(5, '5 (WinRM Debug)'),
]
}
},
page = OptionsPage.from_json(
{
'actions': {
'POST': {
'verbosity': {
'type': 'integer',
'choices': [
(0, '0 (Normal)'),
(1, '1 (Verbose)'),
(2, '2 (More Verbose)'),
(3, '3 (Debug)'),
(4, '4 (Connection Debug)'),
(5, '5 (WinRM Debug)'),
],
}
},
}
}
})
)
options = ResourceOptionsParser(None, page, 'users', self.parser)
options.build_query_arguments('create', 'POST')
assert 'create' in self.parser.choices
@@ -181,9 +180,7 @@ class TestOptions(unittest.TestCase):
def test_actions_with_primary_key(self):
for method in ('get', 'modify', 'delete'):
page = OptionsPage.from_json({
'actions': {'GET': {}, 'POST': {}}
})
page = OptionsPage.from_json({'actions': {'GET': {}, 'POST': {}}})
ResourceOptionsParser(None, page, 'jobs', self.parser)
assert method in self.parser.choices
@@ -193,19 +190,20 @@ class TestOptions(unittest.TestCase):
class TestSettingsOptions(unittest.TestCase):
def setUp(self):
_parser = argparse.ArgumentParser()
self.parser = _parser.add_subparsers(help='action')
def test_list(self):
page = OptionsPage.from_json({
'actions': {
'GET': {},
'POST': {},
'PUT': {},
page = OptionsPage.from_json(
{
'actions': {
'GET': {},
'POST': {},
'PUT': {},
}
}
})
)
page.endpoint = '/settings/all/'
ResourceOptionsParser(None, page, 'settings', self.parser)
assert 'list' in self.parser.choices

View File

@@ -14,32 +14,39 @@ def set_config_cred_to_desired(config, location):
config_ref = config_ref[_location]
setattr(config_ref, split[-1], 'desired')
class MockCredentialType(object):
class MockCredentialType(object):
def __init__(self, name, kind, managed_by_tower=True):
self.name = name
self.kind = kind
self.managed_by_tower = managed_by_tower
@pytest.mark.parametrize('field, kind, config_cred, desired_field, desired_value',
[('field', 'ssh', PseudoNamespace(field=123), 'field', 123),
('subscription', 'azure', PseudoNamespace(subscription_id=123), 'subscription', 123),
('project_id', 'gce', PseudoNamespace(project=123), 'project', 123),
('authorize_password', 'net', PseudoNamespace(authorize=123), 'authorize_password', 123)])
@pytest.mark.parametrize(
'field, kind, config_cred, desired_field, desired_value',
[
('field', 'ssh', PseudoNamespace(field=123), 'field', 123),
('subscription', 'azure', PseudoNamespace(subscription_id=123), 'subscription', 123),
('project_id', 'gce', PseudoNamespace(project=123), 'project', 123),
('authorize_password', 'net', PseudoNamespace(authorize=123), 'authorize_password', 123),
],
)
def test_get_payload_field_and_value_from_config_cred(field, kind, config_cred, desired_field, desired_value):
ret_field, ret_val = credentials.get_payload_field_and_value_from_kwargs_or_config_cred(field, kind, {},
config_cred)
ret_field, ret_val = credentials.get_payload_field_and_value_from_kwargs_or_config_cred(field, kind, {}, config_cred)
assert ret_field == desired_field
assert ret_val == desired_value
@pytest.mark.parametrize('field, kind, kwargs, desired_field, desired_value',
[('field', 'ssh', dict(field=123), 'field', 123),
('subscription', 'azure', dict(subscription=123), 'subscription', 123),
('project_id', 'gce', dict(project_id=123), 'project', 123),
('authorize_password', 'net', dict(authorize_password=123), 'authorize_password', 123)])
@pytest.mark.parametrize(
'field, kind, kwargs, desired_field, desired_value',
[
('field', 'ssh', dict(field=123), 'field', 123),
('subscription', 'azure', dict(subscription=123), 'subscription', 123),
('project_id', 'gce', dict(project_id=123), 'project', 123),
('authorize_password', 'net', dict(authorize_password=123), 'authorize_password', 123),
],
)
def test_get_payload_field_and_value_from_kwarg(field, kind, kwargs, desired_field, desired_value):
ret_field, ret_val = credentials.get_payload_field_and_value_from_kwargs_or_config_cred(field, kind, kwargs,
PseudoNamespace())
ret_field, ret_val = credentials.get_payload_field_and_value_from_kwargs_or_config_cred(field, kind, kwargs, PseudoNamespace())
assert ret_field == desired_field
assert ret_val == desired_value

View File

@@ -21,7 +21,6 @@ class MockHasCreate(has_create.HasCreate):
class A(MockHasCreate):
def create(self, **kw):
return self
@@ -87,13 +86,12 @@ class H(MockHasCreate):
optional_dependencies = [E, A]
def create(self, a=None, e=None, **kw):
def create(self, a=None, e=None, **kw):
self.create_and_update_dependencies(*filter_by_class((a, A), (e, E)))
return self
class MultipleWordClassName(MockHasCreate):
def create(self, **kw):
return self
@@ -102,7 +100,7 @@ class AnotherMultipleWordClassName(MockHasCreate):
optional_dependencies = [MultipleWordClassName]
def create(self, multiple_word_class_name=None, **kw):
def create(self, multiple_word_class_name=None, **kw):
self.create_and_update_dependencies(*filter_by_class((multiple_word_class_name, MultipleWordClassName)))
return self
@@ -183,19 +181,17 @@ def test_optional_dependency_graph_with_additional():
def test_creation_order():
"""confirms that `has_create.creation_order()` returns a valid creation order in the desired list of sets format"""
dependency_graph = dict(eight=set(['seven', 'six']),
seven=set(['five']),
six=set(),
five=set(['two', 'one']),
four=set(['one']),
three=set(['two']),
two=set(['one']),
one=set())
desired = [set(['one', 'six']),
set(['two', 'four']),
set(['three', 'five']),
set(['seven']),
set(['eight'])]
dependency_graph = dict(
eight=set(['seven', 'six']),
seven=set(['five']),
six=set(),
five=set(['two', 'one']),
four=set(['one']),
three=set(['two']),
two=set(['one']),
one=set(),
)
desired = [set(['one', 'six']), set(['two', 'four']), set(['three', 'five']), set(['seven']), set(['eight'])]
assert has_create.creation_order(dependency_graph) == desired
@@ -203,14 +199,16 @@ def test_creation_order_with_loop():
"""confirms that `has_create.creation_order()` raises toposort.CircularDependencyError when evaluating
a cyclic dependency graph
"""
dependency_graph = dict(eight=set(['seven', 'six']),
seven=set(['five']),
six=set(),
five=set(['two', 'one']),
four=set(['one']),
three=set(['two']),
two=set(['one']),
one=set(['eight']))
dependency_graph = dict(
eight=set(['seven', 'six']),
seven=set(['five']),
six=set(),
five=set(['two', 'one']),
four=set(['one']),
three=set(['two']),
two=set(['one']),
one=set(['eight']),
)
with pytest.raises(CircularDependencyError):
assert has_create.creation_order(dependency_graph)
@@ -239,9 +237,11 @@ class Five(MockHasCreate):
class IsntAHasCreate(object):
pass
class Six(MockHasCreate, IsntAHasCreate):
dependencies = [Two]
class Seven(MockHasCreate):
dependencies = [IsntAHasCreate]
@@ -265,8 +265,7 @@ def test_separate_async_optionals_three_exist():
the class that has shared item as a dependency occurs first in a separate creation group
"""
order = has_create.creation_order(has_create.optional_dependency_graph(Five, Four, Three))
assert has_create.separate_async_optionals(order) == [set([One]), set([Two]), set([Three]),
set([Five]), set([Four])]
assert has_create.separate_async_optionals(order) == [set([One]), set([Two]), set([Three]), set([Five]), set([Four])]
def test_separate_async_optionals_not_has_create():
@@ -345,8 +344,7 @@ def test_dependency_resolution_complete():
for item in (h, a, e, d, c, b):
if item._dependency_store:
assert all(item._dependency_store.values()
), "{0} missing dependency: {0._dependency_store}".format(item)
assert all(item._dependency_store.values()), "{0} missing dependency: {0._dependency_store}".format(item)
assert a == b._dependency_store[A], "Duplicate dependency detected"
assert a == c._dependency_store[A], "Duplicate dependency detected"
@@ -468,7 +466,6 @@ def test_teardown_ds_cleared():
class OneWithArgs(MockHasCreate):
def create(self, **kw):
self.kw = kw
return self
@@ -492,18 +489,17 @@ class ThreeWithArgs(MockHasCreate):
optional_dependencies = [TwoWithArgs]
def create(self, one_with_args=OneWithArgs, two_with_args=None, **kw):
self.create_and_update_dependencies(*filter_by_class((one_with_args, OneWithArgs),
(two_with_args, TwoWithArgs)))
self.create_and_update_dependencies(*filter_by_class((one_with_args, OneWithArgs), (two_with_args, TwoWithArgs)))
self.kw = kw
return self
class FourWithArgs(MockHasCreate):
dependencies = [TwoWithArgs, ThreeWithArgs]
def create(self, two_with_args=TwoWithArgs, three_with_args=ThreeWithArgs, **kw):
self.create_and_update_dependencies(*filter_by_class((two_with_args, TwoWithArgs),
(three_with_args, ThreeWithArgs)))
self.create_and_update_dependencies(*filter_by_class((two_with_args, TwoWithArgs), (three_with_args, ThreeWithArgs)))
self.kw = kw
return self
@@ -536,10 +532,9 @@ def test_no_tuple_for_class_arg_causes_shared_dependencies_nested_staggering():
def test_tuple_for_class_arg_causes_unshared_dependencies_when_downstream():
"""Confirms that provided arg-tuple for dependency type is applied instead of chained dependency"""
three_wa = ThreeWithArgs().create(two_with_args=(TwoWithArgs, dict(one_with_args=False,
make_one_with_args=True,
two_with_args_kw_arg=234)),
three_with_args_kw_arg=345)
three_wa = ThreeWithArgs().create(
two_with_args=(TwoWithArgs, dict(one_with_args=False, make_one_with_args=True, two_with_args_kw_arg=234)), three_with_args_kw_arg=345
)
assert isinstance(three_wa.ds.one_with_args, OneWithArgs)
assert isinstance(three_wa.ds.two_with_args, TwoWithArgs)
assert isinstance(three_wa.ds.two_with_args.ds.one_with_args, OneWithArgs)
@@ -552,13 +547,12 @@ def test_tuple_for_class_arg_causes_unshared_dependencies_when_downstream():
def test_tuples_for_class_arg_cause_unshared_dependencies_when_downstream():
"""Confirms that provided arg-tuple for dependency type is applied instead of chained dependency"""
four_wa = FourWithArgs().create(two_with_args=(TwoWithArgs, dict(one_with_args=False,
make_one_with_args=True,
two_with_args_kw_arg=456)),
# No shared dependencies with four_wa.ds.two_with_args
three_with_args=(ThreeWithArgs, dict(one_with_args=(OneWithArgs, {}),
two_with_args=False)),
four_with_args_kw=567)
four_wa = FourWithArgs().create(
two_with_args=(TwoWithArgs, dict(one_with_args=False, make_one_with_args=True, two_with_args_kw_arg=456)),
# No shared dependencies with four_wa.ds.two_with_args
three_with_args=(ThreeWithArgs, dict(one_with_args=(OneWithArgs, {}), two_with_args=False)),
four_with_args_kw=567,
)
assert isinstance(four_wa.ds.two_with_args, TwoWithArgs)
assert isinstance(four_wa.ds.three_with_args, ThreeWithArgs)
assert isinstance(four_wa.ds.two_with_args.ds.one_with_args, OneWithArgs)
@@ -575,25 +569,21 @@ class NotHasCreate(object):
class MixinUserA(MockHasCreate, NotHasCreate):
def create(self, **kw):
return self
class MixinUserB(MockHasCreate, NotHasCreate):
def create(self, **kw):
return self
class MixinUserC(MixinUserB):
def create(self, **kw):
return self
class MixinUserD(MixinUserC):
def create(self, **kw):
return self
@@ -646,17 +636,12 @@ class DynamicallyDeclaresNotHasCreateDependency(MockHasCreate):
dependencies = [NotHasCreate]
def create(self, not_has_create=MixinUserA):
dynamic_dependency = dict(mixinusera=MixinUserA,
mixinuserb=MixinUserB,
mixinuserc=MixinUserC)
dynamic_dependency = dict(mixinusera=MixinUserA, mixinuserb=MixinUserB, mixinuserc=MixinUserC)
self.create_and_update_dependencies(dynamic_dependency[not_has_create])
return self
@pytest.mark.parametrize('dependency,dependency_class',
[('mixinusera', MixinUserA),
('mixinuserb', MixinUserB),
('mixinuserc', MixinUserC)])
@pytest.mark.parametrize('dependency,dependency_class', [('mixinusera', MixinUserA), ('mixinuserb', MixinUserB), ('mixinuserc', MixinUserC)])
def test_subclass_or_parent_dynamic_not_has_create_dependency_declaration(dependency, dependency_class):
"""Confirms that dependencies that dynamically declare dependencies subclassed from not HasCreate
are properly linked
@@ -670,17 +655,12 @@ class DynamicallyDeclaresHasCreateDependency(MockHasCreate):
dependencies = [MixinUserB]
def create(self, mixin_user_b=MixinUserB):
dynamic_dependency = dict(mixinuserb=MixinUserB,
mixinuserc=MixinUserC,
mixinuserd=MixinUserD)
dynamic_dependency = dict(mixinuserb=MixinUserB, mixinuserc=MixinUserC, mixinuserd=MixinUserD)
self.create_and_update_dependencies(dynamic_dependency[mixin_user_b])
return self
@pytest.mark.parametrize('dependency,dependency_class',
[('mixinuserb', MixinUserB),
('mixinuserc', MixinUserC),
('mixinuserd', MixinUserD)])
@pytest.mark.parametrize('dependency,dependency_class', [('mixinuserb', MixinUserB), ('mixinuserc', MixinUserC), ('mixinuserd', MixinUserD)])
def test_subclass_or_parent_dynamic_has_create_dependency_declaration(dependency, dependency_class):
"""Confirms that dependencies that dynamically declare dependencies subclassed from not HasCreate
are properly linked

View File

@@ -169,8 +169,7 @@ def test_wildcard_and_specific_method_registration_acts_as_default(reg):
def test_multiple_method_registrations_disallowed_for_single_path_single_registration(reg, method):
with pytest.raises(TypeError) as e:
reg.register((('some_path', method), ('some_path', method)), One)
assert str(e.value) == ('"{0.pattern}" already has registered method "{1}"'
.format(reg.url_pattern('some_path'), method))
assert str(e.value) == ('"{0.pattern}" already has registered method "{1}"'.format(reg.url_pattern('some_path'), method))
@pytest.mark.parametrize('method', ('method', '.*'))
@@ -178,8 +177,7 @@ def test_multiple_method_registrations_disallowed_for_single_path_multiple_regis
reg.register('some_path', method, One)
with pytest.raises(TypeError) as e:
reg.register('some_path', method, One)
assert str(e.value) == ('"{0.pattern}" already has registered method "{1}"'
.format(reg.url_pattern('some_path'), method))
assert str(e.value) == ('"{0.pattern}" already has registered method "{1}"'.format(reg.url_pattern('some_path'), method))
def test_paths_can_be_patterns(reg):
@@ -188,10 +186,9 @@ def test_paths_can_be_patterns(reg):
def test_mixed_form_single_registration(reg):
reg.register([('some_path_one', 'method_one'),
'some_path_two',
('some_path_three', ('method_two', 'method_three')),
'some_path_four', 'some_path_five'], One)
reg.register(
[('some_path_one', 'method_one'), 'some_path_two', ('some_path_three', ('method_two', 'method_three')), 'some_path_four', 'some_path_five'], One
)
assert reg.get('some_path_one', 'method_one') is One
assert reg.get('some_path_one') is None
assert reg.get('some_path_one', 'nonexistent') is None
@@ -209,10 +206,9 @@ def test_mixed_form_single_registration(reg):
def test_mixed_form_single_registration_with_methodless_default(reg):
reg.setdefault(One)
reg.register([('some_path_one', 'method_one'),
'some_path_two',
('some_path_three', ('method_two', 'method_three')),
'some_path_four', 'some_path_five'], Two)
reg.register(
[('some_path_one', 'method_one'), 'some_path_two', ('some_path_three', ('method_two', 'method_three')), 'some_path_four', 'some_path_five'], Two
)
assert reg.get('some_path_one', 'method_one') is Two
assert reg.get('some_path_one') is One
assert reg.get('some_path_one', 'nonexistent') is One
@@ -230,10 +226,9 @@ def test_mixed_form_single_registration_with_methodless_default(reg):
def test_mixed_form_single_registration_with_method_default(reg):
reg.setdefault('existent', One)
reg.register([('some_path_one', 'method_one'),
'some_path_two',
('some_path_three', ('method_two', 'method_three')),
'some_path_four', 'some_path_five'], Two)
reg.register(
[('some_path_one', 'method_one'), 'some_path_two', ('some_path_three', ('method_two', 'method_three')), 'some_path_four', 'some_path_five'], Two
)
assert reg.get('some_path_one', 'method_one') is Two
assert reg.get('some_path_one') is None
assert reg.get('some_path_one', 'existent') is One

View File

@@ -9,60 +9,68 @@ from awxkit import utils
from awxkit import exceptions as exc
@pytest.mark.parametrize('inp, out',
[[True, True],
[False, False],
[1, True],
[0, False],
[1.0, True],
[0.0, False],
['TrUe', True],
['FalSe', False],
['yEs', True],
['No', False],
['oN', True],
['oFf', False],
['asdf', True],
['0', False],
['', False],
[{1: 1}, True],
[{}, False],
[(0,), True],
[(), False],
[[1], True],
[[], False]])
@pytest.mark.parametrize(
'inp, out',
[
[True, True],
[False, False],
[1, True],
[0, False],
[1.0, True],
[0.0, False],
['TrUe', True],
['FalSe', False],
['yEs', True],
['No', False],
['oN', True],
['oFf', False],
['asdf', True],
['0', False],
['', False],
[{1: 1}, True],
[{}, False],
[(0,), True],
[(), False],
[[1], True],
[[], False],
],
)
def test_to_bool(inp, out):
assert utils.to_bool(inp) == out
@pytest.mark.parametrize('inp, out',
[["{}", {}],
["{'null': null}", {"null": None}],
["{'bool': true}", {"bool": True}],
["{'bool': false}", {"bool": False}],
["{'int': 0}", {"int": 0}],
["{'float': 1.0}", {"float": 1.0}],
["{'str': 'abc'}", {"str": "abc"}],
["{'obj': {}}", {"obj": {}}],
["{'list': []}", {"list": []}],
["---", None],
["---\n'null': null", {'null': None}],
["---\n'bool': true", {'bool': True}],
["---\n'bool': false", {'bool': False}],
["---\n'int': 0", {'int': 0}],
["---\n'float': 1.0", {'float': 1.0}],
["---\n'string': 'abc'", {'string': 'abc'}],
["---\n'obj': {}", {'obj': {}}],
["---\n'list': []", {'list': []}],
["", None],
["'null': null", {'null': None}],
["'bool': true", {'bool': True}],
["'bool': false", {'bool': False}],
["'int': 0", {'int': 0}],
["'float': 1.0", {'float': 1.0}],
["'string': 'abc'", {'string': 'abc'}],
["'obj': {}", {'obj': {}}],
["'list': []", {'list': []}]])
@pytest.mark.parametrize(
'inp, out',
[
["{}", {}],
["{'null': null}", {"null": None}],
["{'bool': true}", {"bool": True}],
["{'bool': false}", {"bool": False}],
["{'int': 0}", {"int": 0}],
["{'float': 1.0}", {"float": 1.0}],
["{'str': 'abc'}", {"str": "abc"}],
["{'obj': {}}", {"obj": {}}],
["{'list': []}", {"list": []}],
["---", None],
["---\n'null': null", {'null': None}],
["---\n'bool': true", {'bool': True}],
["---\n'bool': false", {'bool': False}],
["---\n'int': 0", {'int': 0}],
["---\n'float': 1.0", {'float': 1.0}],
["---\n'string': 'abc'", {'string': 'abc'}],
["---\n'obj': {}", {'obj': {}}],
["---\n'list': []", {'list': []}],
["", None],
["'null': null", {'null': None}],
["'bool': true", {'bool': True}],
["'bool': false", {'bool': False}],
["'int': 0", {'int': 0}],
["'float': 1.0", {'float': 1.0}],
["'string': 'abc'", {'string': 'abc'}],
["'obj': {}", {'obj': {}}],
["'list': []", {'list': []}],
],
)
def test_load_valid_json_or_yaml(inp, out):
assert utils.load_json_or_yaml(inp) == out
@@ -74,19 +82,13 @@ def test_load_invalid_json_or_yaml(inp):
@pytest.mark.parametrize('non_ascii', [True, False])
@pytest.mark.skipif(
sys.version_info < (3, 6),
reason='this is only intended to be used in py3, not the CLI'
)
@pytest.mark.skipif(sys.version_info < (3, 6), reason='this is only intended to be used in py3, not the CLI')
def test_random_titles_are_unicode(non_ascii):
assert isinstance(utils.random_title(non_ascii=non_ascii), str)
@pytest.mark.parametrize('non_ascii', [True, False])
@pytest.mark.skipif(
sys.version_info < (3, 6),
reason='this is only intended to be used in py3, not the CLI'
)
@pytest.mark.skipif(sys.version_info < (3, 6), reason='this is only intended to be used in py3, not the CLI')
def test_random_titles_generates_correct_characters(non_ascii):
title = utils.random_title(non_ascii=non_ascii)
if non_ascii:
@@ -98,34 +100,39 @@ def test_random_titles_generates_correct_characters(non_ascii):
title.encode('utf-8')
@pytest.mark.parametrize('inp, out',
[['ClassNameShouldChange', 'class_name_should_change'],
['classnameshouldntchange', 'classnameshouldntchange'],
['Classspacingshouldntchange', 'classspacingshouldntchange'],
['Class1Name2Should3Change', 'class_1_name_2_should_3_change'],
['Class123name234should345change456', 'class_123_name_234_should_345_change_456']])
@pytest.mark.parametrize(
'inp, out',
[
['ClassNameShouldChange', 'class_name_should_change'],
['classnameshouldntchange', 'classnameshouldntchange'],
['Classspacingshouldntchange', 'classspacingshouldntchange'],
['Class1Name2Should3Change', 'class_1_name_2_should_3_change'],
['Class123name234should345change456', 'class_123_name_234_should_345_change_456'],
],
)
def test_class_name_to_kw_arg(inp, out):
assert utils.class_name_to_kw_arg(inp) == out
@pytest.mark.parametrize('first, second, expected',
[['/api/v2/resources/', '/api/v2/resources/', True],
['/api/v2/resources/', '/api/v2/resources/?test=ignored', True],
['/api/v2/resources/?one=ignored', '/api/v2/resources/?two=ignored', True],
['http://one.com', 'http://one.com', True],
['http://one.com', 'http://www.one.com', True],
['http://one.com', 'http://one.com?test=ignored', True],
['http://one.com', 'http://www.one.com?test=ignored', True],
['http://one.com', 'https://one.com', False],
['http://one.com', 'https://one.com?test=ignored', False]])
@pytest.mark.parametrize(
'first, second, expected',
[
['/api/v2/resources/', '/api/v2/resources/', True],
['/api/v2/resources/', '/api/v2/resources/?test=ignored', True],
['/api/v2/resources/?one=ignored', '/api/v2/resources/?two=ignored', True],
['http://one.com', 'http://one.com', True],
['http://one.com', 'http://www.one.com', True],
['http://one.com', 'http://one.com?test=ignored', True],
['http://one.com', 'http://www.one.com?test=ignored', True],
['http://one.com', 'https://one.com', False],
['http://one.com', 'https://one.com?test=ignored', False],
],
)
def test_are_same_endpoint(first, second, expected):
assert utils.are_same_endpoint(first, second) == expected
@pytest.mark.parametrize('endpoint, expected',
[['/api/v2/resources/', 'v2'],
['/api/v2000/resources/', 'v2000'],
['/api/', 'common']])
@pytest.mark.parametrize('endpoint, expected', [['/api/v2/resources/', 'v2'], ['/api/v2000/resources/', 'v2000'], ['/api/', 'common']])
def test_version_from_endpoint(endpoint, expected):
assert utils.version_from_endpoint(endpoint) == expected
@@ -133,42 +140,51 @@ def test_version_from_endpoint(endpoint, expected):
class OneClass:
pass
class TwoClass:
pass
class ThreeClass:
pass
class FourClass(ThreeClass):
pass
def test_filter_by_class_with_subclass_class():
filtered = utils.filter_by_class((OneClass, OneClass), (FourClass, ThreeClass))
assert filtered == [OneClass, FourClass]
def test_filter_by_class_with_subclass_instance():
one = OneClass()
four = FourClass()
filtered = utils.filter_by_class((one, OneClass), (four, ThreeClass))
assert filtered == [one, four]
def test_filter_by_class_no_arg_tuples():
three = ThreeClass()
filtered = utils.filter_by_class((True, OneClass), (False, TwoClass), (three, ThreeClass))
assert filtered == [OneClass, None, three]
def test_filter_by_class_with_arg_tuples_containing_class():
one = OneClass()
three = (ThreeClass, dict(one=1, two=2))
filtered = utils.filter_by_class((one, OneClass), (False, TwoClass), (three, ThreeClass))
assert filtered == [one, None, three]
def test_filter_by_class_with_arg_tuples_containing_subclass():
one = OneClass()
three = (FourClass, dict(one=1, two=2))
filtered = utils.filter_by_class((one, OneClass), (False, TwoClass), (three, ThreeClass))
assert filtered == [one, None, three]
@pytest.mark.parametrize('truthy', (True, 123, 'yes'))
def test_filter_by_class_with_arg_tuples_containing_truthy(truthy):
one = OneClass()
@@ -177,18 +193,20 @@ def test_filter_by_class_with_arg_tuples_containing_truthy(truthy):
assert filtered == [one, None, (ThreeClass, dict(one=1, two=2))]
@pytest.mark.parametrize('date_string,now,expected', [
('2017-12-20T00:00:01.5Z', datetime(2017, 12, 20, 0, 0, 2, 750000), 1.25),
('2017-12-20T00:00:01.5Z', datetime(2017, 12, 20, 0, 0, 1, 500000), 0.00),
('2017-12-20T00:00:01.5Z', datetime(2017, 12, 20, 0, 0, 0, 500000), -1.00),
])
@pytest.mark.parametrize(
'date_string,now,expected',
[
('2017-12-20T00:00:01.5Z', datetime(2017, 12, 20, 0, 0, 2, 750000), 1.25),
('2017-12-20T00:00:01.5Z', datetime(2017, 12, 20, 0, 0, 1, 500000), 0.00),
('2017-12-20T00:00:01.5Z', datetime(2017, 12, 20, 0, 0, 0, 500000), -1.00),
],
)
def test_seconds_since_date_string(date_string, now, expected):
with mock.patch('awxkit.utils.utcnow', return_value=now):
assert utils.seconds_since_date_string(date_string) == expected
class RecordingCallback(object):
def __init__(self, value=True):
self.call_count = 0
self.value = value
@@ -225,7 +243,6 @@ def test_suppress():
class TestPollUntil(object):
@pytest.mark.parametrize('timeout', [0, 0.0, -0.5, -1, -9999999])
def test_callback_called_once_for_non_positive_timeout(self, timeout):
with mock.patch('awxkit.utils.logged_sleep') as sleep:
@@ -246,7 +263,6 @@ class TestPollUntil(object):
class TestPseudoNamespace(object):
def test_set_item_check_item(self):
pn = utils.PseudoNamespace()
pn['key'] = 'value'
@@ -319,10 +335,7 @@ class TestPseudoNamespace(object):
assert pn == dict(one=[dict(two=2), dict(three=3)])
def test_instantiation_via_nested_dict_with_lists(self):
pn = utils.PseudoNamespace(dict(one=[dict(two=2),
dict(three=dict(four=4,
five=[dict(six=6),
dict(seven=7)]))]))
pn = utils.PseudoNamespace(dict(one=[dict(two=2), dict(three=dict(four=4, five=[dict(six=6), dict(seven=7)]))]))
assert pn.one[1].three.five[1].seven == 7
def test_instantiation_via_nested_dict_with_tuple(self):
@@ -332,10 +345,7 @@ class TestPseudoNamespace(object):
assert pn == dict(one=(dict(two=2), dict(three=3)))
def test_instantiation_via_nested_dict_with_tuples(self):
pn = utils.PseudoNamespace(dict(one=(dict(two=2),
dict(three=dict(four=4,
five=(dict(six=6),
dict(seven=7)))))))
pn = utils.PseudoNamespace(dict(one=(dict(two=2), dict(three=dict(four=4, five=(dict(six=6), dict(seven=7)))))))
assert pn.one[1].three.five[1].seven == 7
def test_update_with_nested_dict(self):
@@ -348,23 +358,16 @@ class TestPseudoNamespace(object):
def test_update_with_nested_dict_with_lists(self):
pn = utils.PseudoNamespace()
pn.update(dict(one=[dict(two=2),
dict(three=dict(four=4,
five=[dict(six=6),
dict(seven=7)]))]))
pn.update(dict(one=[dict(two=2), dict(three=dict(four=4, five=[dict(six=6), dict(seven=7)]))]))
assert pn.one[1].three.five[1].seven == 7
def test_update_with_nested_dict_with_tuples(self):
pn = utils.PseudoNamespace()
pn.update(dict(one=(dict(two=2),
dict(three=dict(four=4,
five=(dict(six=6),
dict(seven=7)))))))
pn.update(dict(one=(dict(two=2), dict(three=dict(four=4, five=(dict(six=6), dict(seven=7)))))))
assert pn.one[1].three.five[1].seven == 7
class TestUpdatePayload(object):
def test_empty_payload(self):
fields = ('one', 'two', 'three', 'four')
kwargs = dict(two=2, four=4)

View File

@@ -8,6 +8,7 @@ from awxkit.ws import WSClient
ParseResult = namedtuple("ParseResult", ["port", "hostname", "secure"])
def test_explicit_hostname():
client = WSClient("token", "some-hostname", 556, False)
assert client.port == 556
@@ -16,12 +17,15 @@ def test_explicit_hostname():
assert client.token == "token"
@pytest.mark.parametrize('url, result',
[['https://somename:123', ParseResult(123, "somename", True)],
['http://othername:456', ParseResult(456, "othername", False)],
['http://othername', ParseResult(80, "othername", False)],
['https://othername', ParseResult(443, "othername", True)],
])
@pytest.mark.parametrize(
'url, result',
[
['https://somename:123', ParseResult(123, "somename", True)],
['http://othername:456', ParseResult(456, "othername", False)],
['http://othername', ParseResult(80, "othername", False)],
['https://othername', ParseResult(443, "othername", True)],
],
)
def test_urlparsing(url, result):
with patch("awxkit.ws.config") as mock_config:
mock_config.base_url = url