Skip to content

Commit

Permalink
Unpacking multiple levels can be specified by an optional argument of @…
Browse files Browse the repository at this point in the history
…unpack and @unpackall

This is just proof of concept. Documentation has not been updated.
  • Loading branch information
Jan Holeček committed May 14, 2015
1 parent 25bf37c commit 9828a50
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 8 deletions.
30 changes: 22 additions & 8 deletions ddt.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
# Public interface - Decorators


def unpack(func):
def unpack(arg):
"""
Method decorator to unpack parameters from the next (syntactically)
parameters set (``@data`` or ``@file_data`` decorator) by one level.
Expand All @@ -46,19 +46,33 @@ def unpack(func):
and/or applied multiple times.
"""
getattr(func, PARAMS_SETS_ATTR)[0].unpack()
if isinstance(arg, int):
return lambda func: _unpack(arg, func)
else:
return _unpack(1, arg)


def _unpack(count, func):
getattr(func, PARAMS_SETS_ATTR)[0].unpack(count)
return func


def unpackall(func):
def unpackall(arg):
"""
Method decorator to unpack parameters in all parameter sets by one level.
Multiple levels are unpacked if ``@unpack`` and ``@unpackall`` are combined
and/or applied multiple times.
"""
setattr(func, UNPACKALL_ATTR, getattr(func, UNPACKALL_ATTR, 0) + 1)
if isinstance(arg, int):
return lambda func: _unpackall(arg, func)
else:
return _unpackall(1, arg)


def _unpackall(count, func):
setattr(func, UNPACKALL_ATTR, getattr(func, UNPACKALL_ATTR, 0) + count)
return func


Expand Down Expand Up @@ -309,15 +323,15 @@ def __init__(self, *unnamed_values, **named_values):
self.unnamed_values = unnamed_values
self.named_values = named_values

def unpack(self):
def unpack(self, count=1):
"""
Increases by one the number of times values should be unpacked before
passing them to the test function.
This method is called directly by the ``unpack`` decorator.
"""
self.unpack_count = self.unpack_count + 1
self.unpack_count = self.unpack_count + count

def use_class(self, cls): # pylint: disable=unused-argument
"""
Expand Down Expand Up @@ -381,15 +395,15 @@ def use_class(self, cls):
self.pathbase = os.path.dirname(cls_path)
return self

def unpack(self):
def unpack(self, count=1):
"""
Increase by one the number of times values should be unpacked before
passing them to the test function.
This method is called directly by the @unpack decorator.
"""
self.unpack_count = self.unpack_count + 1
self.unpack_count = self.unpack_count + count

def load_values(self): # pylint: disable=unused-argument
try:
Expand Down
34 changes: 34 additions & 0 deletions test/test_ddt2_specification.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,3 +512,37 @@ def test(self, *args, **kwargs):

method_name = 'test__0_u0158' if six.PY2 else 'test__0_\u0158'
self.assertTrue(hasattr(tc, method_name))

def test__multi_level_unpack_by_decorator_argument(self):

@ddt.ddt
class SampleTestCase(object):
@ddt.data(A=['a', 'b'])
@ddt.unpack(2)
@ddt.data(B=[('c', 'd')])
@ddt.data(C=dict(x='e', y='f'))
def test(self, *args, **kwargs):
return args, kwargs

tc = SampleTestCase()

args, kwargs = tc.test__0_A__0_B__0_C()
self.assertEqual(args, (['a', 'b'], 'c', 'd', dict(x='e', y='f')))
self.assertEqual(kwargs, {})

def test__multi_level_unpackall_by_decorator_argument(self):

@ddt.ddt
class SampleTestCase(object):
@ddt.unpackall(2)
@ddt.data(A=['a', 'b'])
@ddt.data(B=[('c', 'd')])
@ddt.data(C=dict(x='e', y='f'))
def test(self, *args, **kwargs):
return args, kwargs

tc = SampleTestCase()

args, kwargs = tc.test__0_A__0_B__0_C()
self.assertEqual(args, ('a', 'b', 'c', 'd'))
self.assertEqual(kwargs, dict(x='e', y='f'))

0 comments on commit 9828a50

Please sign in to comment.