Source code for geometry.manifolds.tests.checks_generation
"""
These are very "meta" utils for creating nose tests on the fly.
Here is an example use: ::
thinghies = {'banana': 'yellow', 'apple': 'red', 'sky': 'blue'}
def thinghies_list():
return thinghies.keys()
def thinghies_args(x):
return (x, thinghies[x])
def thinghies_attrs(x):
return dict(thinghy_name='%s' % x, flavor=thinghies[x])
for_all_thinghies = fancy_test_decorator(lister=thinghies_list,
arguments=thinghies_args,
attributes=thinghies_attrs)
And this is the proper test: ::
@for_all_thinghies
def check_good_flavor(id_thinghy, flavor):
print('test for %s %s' % (id_thinghy, flavor))
"""
import sys
from nose.tools import istest, nottest
from geometry import logger
__all__ = ['fancy_test_decorator']
def add_to_module(function, module_name):
module = sys.modules[module_name]
name = function.__name__
if not 'test' in name:
raise Exception('No "test" in function name %r' % name)
if not 'test' in module_name:
raise Exception('While adding %r in %r: module does not have "test"'
' in it, so nose will not find the test.' %
(name, module_name))
if name in module.__dict__:
raise Exception('Already created test %r.' % name)
module.__dict__[name] = function
# logger.debug('Added test %s:%s' % (module.__name__, name))
def add_checker_f(f, x, arguments, attributes, naming):
name = 'test_%s_%s' % (f.__name__, naming(x))
@istest
def caller():
try:
args = None
args = arguments(x)
f(*args)
except (Exception, AssertionError):
msg = 'Error while executing test %r.\n' % name
msg += ' f = %s\n' % f
msg += ' f.__module__ = %s\n' % f.__module__
msg += ' x = %s\n' % str(x)
msg += ' arguments() = %s\n' % str(arguments)
msg += ' arguments(x) = %s\n' % str(args)
msg += ' attributes = %s\n' % str(attributes)
logger.error(msg)
raise
caller.__name__ = name
for k, v in attributes(x).items():
caller.__dict__[k] = v
caller.__dict__['test'] = f.__name__
add_to_module(caller, f.__module__)
# TODO: add debug info function
[docs]@nottest
def fancy_test_decorator(lister,
arguments=lambda x: x,
attributes=lambda x: {'id': str(x)},
naming=lambda x: str(x),
debug=False):
'''
Creates a fancy decorator for adding checks.
:param lister: a function that should give a list of objects
:param arguments: from object to arguments
:param attributes: (optional) set of attributes for the test
Returns a function that can be used as a decorator.
'''
def for_all_stuff(check):
for x in lister():
if debug:
logger.info('add test %s / %s ' % (check, x))
add_checker_f(check, x, arguments, attributes, naming)
return check
return for_all_stuff