import logging import os from os.path import abspath, dirname currdir = dirname(abspath(__file__)) + os.sep import pyutilib.th as unittest import pyutilib.misc from pyutilib.workflow import * try: import json json_available = True except: json_available = False class Handler(logging.StreamHandler): def emit(self, record): raise RuntimeError(str(record)) handler = Handler() logger = logging.getLogger('pyutilib.workflow') class TestData(unittest.TestCase): def test1(self): # Print FunctorAPIData string data = FunctorAPIData() data.a = 1 data.b = [1, 2] data.c = FunctorAPIData() data.c.x = 1 data.c.y = 2 data.aa = 'here is more' data.clean() pyutilib.misc.setup_redirect(currdir + 'test1.out') print(data) pyutilib.misc.reset_redirect() self.assertFileEqualsBaseline(currdir + 'test1.out', currdir + 'test1.txt') self.assertEquals(len(data._dirty_), 0) @unittest.skipIf(not json_available, "JSON not available") def test2(self): # Print FunctorAPIData representation data = FunctorAPIData() data.a = 1 data.b = [1, 2] data.c = FunctorAPIData() data.c.x = 1 data.c.y = 2 data['aa'] = 'here is more' data.clean() FILE = open(currdir + 'test2.out', 'w') json.dump(data, FILE) FILE.close() self.assertMatchesJsonBaseline(currdir + 'test2.out', currdir + 'test2.txt') self.assertEquals(len(data._dirty_), 0) @unittest.expectedFailure def test_err1(self): # Unknown attribute data = FunctorAPIData() data._x @unittest.expectedFailure def test_err2(self): # Undeclared attribute data = FunctorAPIData() data.declare('a') data.x @unittest.expectedFailure def test_err3(self): # Undeclared attribute data = FunctorAPIData() data.declare(['a']) data.x class TestAPI(unittest.TestCase): @classmethod def setUpClass(cls): # Disable the pyutilib.workflow logging handler if len(logger.handlers) > 0: cls._handler = logger.handlers[0] logger.removeHandler(cls._handler) else: cls._handler = None logger.addHandler(handler) @classmethod def tearDownClass(cls): # Re-enable the pyutilib.workflow logging handler logger.removeHandler(handler) if not cls._handler is None: logger.addHandler(cls._handler) def test1(self): # Simple test: no keyword arguments or return values @functor_api def test1(data): # Required: # data: input data data.a = 2 data.b[0] = 2 # options = FunctorAPIData() options.a = 1 options.b = [1, 2] retval = test1(options) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test1(data=options) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) # self.assertTrue('test1' in FunctorAPIFactory.services()) def test1a(self): """Simple test: no keyword arguments or return values""" @functor_api def test1a(data): """ Required: data: input data Return: data: output data """ data.a = 2 data.b[0] = 2 # options = FunctorAPIData() options.a = 1 options.b = [1, 2] retval = test1a(options) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test1a(data=options) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) def test1b(self): """Simple test: data keyword argument, no return values""" @functor_api def test1b(data=None): data.a = 2 data.b[0] = 2 # options = FunctorAPIData() options.a = 1 options.b = [1, 2] retval = test1b(options) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test1b(data=options) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) def test2(self): """Simple test: no keyword arguments, returning data""" @functor_api def test2(data): data.a = 2 data.b[0] = 2 return data # options = FunctorAPIData() options.a = 1 options.b = [1, 2] retval = test2(options) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test2(data=options) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) def test2a(self): """Simple test: no keyword arguments, returning data""" @functor_api def test2a(data): """ Required: data: input data Return: data: output data """ data.a = 2 data.b[0] = 2 return data # options = FunctorAPIData() options.a = 1 options.b = [1, 2] retval = test2a(options) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test2a(data=options) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) def test3(self): """Simple test: keyword arguments, no return values""" @functor_api def test3(data, x=1, y=2): """ Required: data: input data x: integer Optional: y: integer """ data.a = y data.b[0] = x # options = FunctorAPIData() options.a = 1 options.b = [1, 2] retval = test3(options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test3(data=options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) def test3a(self): """Simple test: keyword arguments, no return values""" @functor_api def test3a(x=1, y=2, data=None): """ Required: data: input data x: integer Optional: y: integer """ data.a = y data.b[0] = x # options = FunctorAPIData() options.a = 1 options.b = [1, 2] retval = test3a(options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test3a(data=options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) def test4(self): """Simple test: keyword arguments, simple return value""" @functor_api def test4(data, x=1, y=2): """ Required: data: input data x: integer Optional: y: integer Return: data: output data """ data.a = y data.b[0] = x return data # options = FunctorAPIData() options.a = 1 options.b = [1, 2] retval = test4(options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test4(data=options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) def test5(self): """Simple test: keyword arguments, non-data return values""" @functor_api(outputs=('z')) def test5(data, x=1, y=2): """ Required: data: input data x: integer Optional: y: integer Return: data: output data z: integer """ data.a = y data.b[0] = x return FunctorAPIData(z=x) # options = FunctorAPIData() options.a = 1 options.b = [1, 2] retval = test5(options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test5(data=options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) self.assertEquals(retval.z, 2) def test6(self): """Simple test: keyword arguments, non-data return values with data""" @functor_api(outputs=('z')) def test6(data, x=1, y=2): """ Required: data: input data x: integer Optional: y: integer Return: data: output data z: integer """ data.a = y data.b[0] = x return FunctorAPIData(data=data, z=x) # options = FunctorAPIData() options.a = 1 options.b = [1, 2] retval = test6(options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test6(data=options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) self.assertEquals(retval.z, 2) def test5a(self): """Outputs specified in docstring: keyword arguments, non-data return values""" @functor_api def test5a(data, x=1, y=2): """ Required: data: input data x: integer Optional: y: integer Return: data: output data z: integer """ data.a = y data.b[0] = x return FunctorAPIData(z=x) # options = FunctorAPIData() options.a = 1 options.b = [1, 2] retval = test5a(options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test5a(data=options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) self.assertEquals(retval.z, 2) def test6a(self): """Outputs specified in docstring: keyword arguments, non-data return values with data""" @functor_api def test6a(data, x=1, y=2): """ Required: data: input data x: integer Optional: y: integer Return: data: output data z: integer """ data.a = y data.b[0] = x return FunctorAPIData(data=data, z=x) # options = FunctorAPIData() options.a = 1 options.b = [1, 2] retval = test6a(options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test6a(data=options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) self.assertEquals(retval.z, 2) def test7a(self): """Test with dict data""" @functor_api def test7a(data, x=1, y=2): """ Required: data: input data x: integer Optional: y: integer """ data.a = y data.b[0] = x # options = {} options['a'] = 1 options['b'] = [1, 2] retval = test7a(options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test7a(data=options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) def test7b(self): """Test with dict data and return a dictionary""" @functor_api def test7b(data, x=1, y=2): """ Required: data: input data x: integer Optional: y: integer """ data.a = y data.b[0] = x return {'data': data} # options = {} options['a'] = 1 options['b'] = [1, 2] retval = test7b(options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test7b(data=options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) def test7c(self): """Test with dict data and return a dictionary""" @functor_api def test7c(data, x=1, y=2): """ Required: data: input data x: integer Optional: y: integer Return: z: integer """ data.a = y data.b[0] = x return {'data': data, 'z': x} # options = {} options['a'] = 1 options['b'] = [1, 2] retval = test7c(options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test7c(data=options, x=2) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) self.assertEquals(retval.z, 2) def test8(self): """Simple test with required nested data""" @functor_api def test8(data): """ Required: data: input data data.foo.bar: """ data.foo.foo = 3 #data.a = 2 #data.b[0] = 2 # options = FunctorAPIData() options.foo = FunctorAPIData() options.foo.bar = 1 options.a = 1 options.b = [1, 2] retval = test8(options) self.assertEquals(retval.data.a, 1) self.assertEquals(retval.data.b, [1, 2]) self.assertEquals(retval.data.foo.foo, 3) #retval = test8(data=options) #self.assertEquals(retval.data.a, 2) #self.assertEquals(retval.data.b, [2,2]) def test9(self): """Simple test: no keyword arguments or return values""" @functor_api def test9(data): """ This is the short documentation. This is the long documentation. Required: data: multiline description of input data object data.a: More data """ data.a = 2 data.b[0] = 2 # options = FunctorAPIData() options.a = 1 options.b = [1, 2] retval = test9(options) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) retval = test9(data=options) self.assertEquals(retval.data.a, 2) self.assertEquals(retval.data.b, [2, 2]) # self.assertTrue('test1' in FunctorAPIFactory.services()) self.assertEquals(test9.__short_doc__, 'This is the\nshort\ndocumentation.') self.assertEquals(test9.__long_doc__, 'This\n\nis\n\nthe\n\nlong documentation.') @unittest.expectedFailure def test10(self): """Simple test: no keyword arguments or return values""" @functor_api def test10(data=None, x=1): """ Required: x: Optional: data: """ return FunctorAPIData(z=2 * x) # retval = test10(x=3) self.assertEquals(retval.z, 6) @unittest.expectedFailure def test_err1(self): """Expect an error when variable length arguments are supported""" @functor_api def err1(*args): pass @unittest.expectedFailure def test_err2(self): """Expect an error when variable length keyword arguments are supported""" @functor_api def err2(**kwargs): pass @unittest.expectedFailure def test_err3(self): """Expect an error when return value is not None or Options()""" @functor_api def err3(data): return 1 f(FunctorAPIData()) @unittest.expectedFailure def test_err4(self): """Expect an error when no data argument is specified""" @functor_api def err4(data): data.a = 2 data.b[0] = 2 test1() @unittest.expectedFailure def test_err5(self): """Expect an error when an unspecified return value is given""" @functor_api def err5(data): return FunctorAPIData(z=None) f(FunctorAPIData()) @unittest.expectedFailure def test_err6(self): """Expect an error when no data argument is specified""" @functor_api def err6(): pass f(FunctorAPIData()) @unittest.expectedFailure def test_err7a(self): """Argument missing from docstring""" @functor_api def err7a(data, x=1, y=2): """ Optional: y: integer """ pass @unittest.expectedFailure def test_err7b(self): """Argument missing from docstring""" @functor_api def err7b(data, x=1, y=2): """ Required: x: integer """ pass @unittest.expectedFailure def test_err7c(self): """Argument missing from docstring""" @functor_api(outputs=('z')) def err7c(data, x=1, y=2): """ Required: x: integer Optional: y: integer """ return FunctorAPIData(z=1) @unittest.expectedFailure def test_err7A(self): """Unexpected required argument""" @functor_api def err7A(data, x=1, y=2): """ Required: x: integer bad: integer Optional: y: integer """ pass @unittest.expectedFailure def test_err7B(self): """Argument missing from docstring""" @functor_api def err7B(data, x=1, y=2): """ Required: x: integer Optional: y: integer bad: integer """ pass @unittest.expectedFailure def test_err7C(self): """Argument missing from docstring""" @functor_api(outputs=('z')) def err7C(data, x=1, y=2): """ Required: x: integer Optional: y: integer Return: z: integer bad: integer """ return FunctorAPIData(z=1) @unittest.expectedFailure def test_err8a(self): """Missing nested value""" @functor_api def err8a(data): """ Required: data.x: integer """ pass err8a(FunctorAPIData()) @unittest.expectedFailure def test_err8b(self): """Nested value with None value""" @functor_api def err8b(data): """ Required: data.x: integer """ pass err8b(FunctorAPIData(data=FunctorAPIData())) @unittest.expectedFailure def test_err8c(self): """Nested value with None value""" @functor_api def err8c(data): """ Required: data.x.y: integer """ pass err8c(FunctorAPIData(x={})) @unittest.expectedFailure def test_err9(self): """Redefinied test functions""" @functor_api def err9(data): pass @functor_api def err9(data): pass @unittest.expectedFailure def test_err10(self): """Simple test with required nested data""" @functor_api def err10(data): """ Required: data: input data data.foo.bar: """ data.foo.foo = 3 data.a = 2 # options = FunctorAPIData() options.foo = FunctorAPIData() options.foo.bar = 1 options.a = 1 options.b = [1, 2] retval = err10(options) self.assertEquals(retval.data.a, 1) self.assertEquals(retval.data.b, [1, 2]) self.assertEquals(retval.data.foo.foo, 3) @unittest.expectedFailure def test_err10a(self): """Expect an error when the same functor is defined twice""" @functor_api def err10a(data): pass @functor_api def err10a(data): pass @unittest.expectedFailure def test_err10b(self): """Expect an error when the same functor is defined twice""" @functor_api(namespace='foo') def err10b(data): pass @functor_api(namespace='foo') def err10b(data): pass @unittest.expectedFailure def test_err11(self): """Expect an error when 'data' is not defined when it is required""" @functor_api def err11(data=None, x=1): """ Required: data: x: """ err11(x=2) @unittest.expectedFailure def test_err12(self): """Expect an error when multiple data options are provided""" @functor_api def err12(data): pass err12({}, {}) @unittest.expectedFailure def test_err13(self): """Expect an error when returning something other than None, FunctorAPIData or a dict object""" @functor_api def err13(data): return set() err13({}) if __name__ == "__main__": unittest.main()