#!/usr/bin/env python # # testcase.py: Control of test case execution. # # Subversion is a tool for revision control. # See http://subversion.tigris.org for more information. # # ==================================================================== # Copyright (c) 2001 Collabnet. All rights reserved. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms # are also available at http://subversion.tigris.org/license-1.html. # If newer versions of this license are posted there, you may use a # newer version instead, at your option. # ###################################################################### import os, sys import traceback # for print_exc() __all__ = ['TestCase', 'XFail', 'Skip'] class _Predicate: """A general-purpose predicate that encapsulates a test case (function), a condition for its execution and a set of display properties for test lists and test log output.""" def __init__(self, func): if isinstance(func, _Predicate): # Whee, this is better than blessing objects in Perl! # For the unenlightened: What we're doing here is adopting the # identity *and class* of 'func' self.__dict__ = func.__dict__ self.__class__ = func.__class__ else: self.func = func self.cond = 0 self.text = ['PASS: ', 'FAIL: ', 'SKIP: ', ''] assert type(self.func) is type(lambda x: 0) def list_mode(self): return self.text[3] def skip_text(self): return self.text[2] def run_text(self, error): if error: return self.text[1] else: return self.text[0] def convert_error(self, error): return error class TestCase: """Encapsulate a single test case (predicate), including logic for runing the test and test list output.""" def __init__(self, func, index): self.pred = _Predicate(func) self.index = index def func_code(self): return self.pred.func.func_code def list(self): print " %2d %-5s %s" % (self.index, self.pred.list_mode(), self.pred.func.__doc__) def run(self, args): if self.pred.cond: error = 0 print self.pred.skip_text(), else: error = 1 try: error = apply(self.pred.func, args) except KeyboardInterrupt: print "Interrupted" sys.exit(0) except: print "caught unexpected exception" traceback.print_exc(file=sys.stdout) print self.pred.run_text(error), error = self.pred.convert_error(error) print os.path.basename(sys.argv[0]), \ str(self.index) + ":", self.pred.func.__doc__ return error class XFail(_Predicate): "A test that is expected to fail." def __init__(self, func): _Predicate.__init__(self, func) self.text[0] = 'XPASS:' self.text[1] = 'XFAIL:' if self.text[3] == '': self.text[3] = 'XFAIL' def convert_error(self, error): # Conditions are reversed here: a failure expected, therefore it # isn't an error; a pass is an error. return not error class Skip(_Predicate): "A test that will be skipped when a condition is true." def __init__(self, func, cond): _Predicate.__init__(self, func) self.cond = cond if self.cond: self.text[3] = 'SKIP' ### End of file.