Skip to content

Commit

Permalink
Relaxes type restriction on parameters decorator argument
Browse files Browse the repository at this point in the history
  • Loading branch information
hazmat345 committed Feb 27, 2019
1 parent c45d98e commit f1a5510
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 12 deletions.
11 changes: 6 additions & 5 deletions brewtils/decorators.py
Expand Up @@ -298,25 +298,26 @@ def cmd1(self, **kwargs):
pass
Args:
*args (list): Positional arguments
*args (iterable): Positional arguments
The first (and only) positional argument must be a list containing
dictionaries that describe parameters.
Returns:
func: The decorated function
"""
if len(args) == 1:
if not isinstance(args[0], list):
raise PluginParamError("@parameters argument must be a list")
return functools.partial(parameters, args[0])
elif len(args) != 2:
raise PluginParamError("@parameters takes a single argument")

if not isinstance(args[1], types.FunctionType):
raise PluginParamError("@parameters must be applied to a function")

for param in args[0]:
parameter(args[1], **param)
try:
for param in args[0]:
parameter(args[1], **param)
except TypeError:
raise PluginParamError("@parameters arg must be an iterable of dictionaries")

@wrapt.decorator(enabled=_wrap_functions)
def wrapper(_double_wrapped, _, _args, _kwargs):
Expand Down
43 changes: 36 additions & 7 deletions test/decorators_test.py
Expand Up @@ -2,7 +2,6 @@

import pytest
from mock import Mock, call, patch
from pytest_lazyfixture import lazy_fixture

import brewtils.decorators
from brewtils.decorators import (
Expand Down Expand Up @@ -368,14 +367,44 @@ def func2(_, foo):
func1._command.parameters[0], func2._command.parameters[0]
)

@pytest.mark.parametrize("args", [[], [1], [1, 2], [1, 2, 3], lazy_fixture("cmd")])
def test_bad_arguments(self, args):
# Can't put lazy fixture in a list inside of parametrize...
if not isinstance(args, list):
args = [args]
@pytest.mark.parametrize("args", [[], [1, 2, 3]])
def test_bad_arity(self, args):
# Must be called with either just one arg, or one arg + the function
with pytest.raises(PluginParamError) as ex:
parameters(*args)
assert "single argument" in str(ex)

@pytest.mark.parametrize(
"arg1,arg2",
[
(1, cmd), # arg1 needs to be iterable
([1], cmd), # arg1 item needs to be **able
([], 1), # arg2 must be a FunctionType
],
)
def test_bad_args(self, arg1, arg2):
with pytest.raises(PluginParamError):
parameters(*args)
parameters(arg1, arg2)

def test_dict_values(self, cmd, param_definition, wrap_functions):
test_mock = Mock()
wrapped = parameters({"foo": param_definition}.values(), cmd)

assert len(cmd._command.parameters) == 1
assert cmd._command.parameters[0].key == "foo"
assert wrapped(self, test_mock) == test_mock

def test_dict_values_decorator(self, param_definition, wrap_functions):
test_mock = Mock()
param_spec = {"foo": param_definition}

@parameters(param_spec.values())
def func(_, foo):
return foo

assert len(func._command.parameters) == 1
assert func._command.parameters[0].key == "foo"
assert func(self, test_mock) == test_mock


class TestCommand(object):
Expand Down

0 comments on commit f1a5510

Please sign in to comment.