# Perforce Defect Tracking Integration Project # # # TEST_CHECK_CONFIG.PY -- UNIT TEST FOR CHECK_CONFIG MODULE # # Gareth Rees, Ravenbrook Limited, 2001-03-14 # # # 1. INTRODUCTION # # This module defines a set of unit tests for the check_config module. # # It uses the PyUnit unit test framework [PyUnit]. # # The intended readership is project developers. # # This document is not confidential. import os import sys p4dti_path = os.path.join(os.getcwd(), os.pardir, 'code', 'replicator') if p4dti_path not in sys.path: sys.path.append(p4dti_path) import check_config import p4dti_unittest import types import unittest # 2. TEST CASES # 2.1. Passing and failing simple checks # # This test case has a table of values together with the checks which # each value is supposed to pass. The value is given to each checker # function in turn and the result compared with the expectation in the # table. class fns(p4dti_unittest.TestCase): class test: def method(self): pass def __call__(self): pass # The 'codes' table maps a code letter to a checking function in the # check_config module. codes = { 'b': check_config.check_bool, 'd': check_config.check_date, 'e': check_config.check_email, 'f': check_config.check_function, 'h': check_config.check_host, 'i': check_config.check_int, 's': check_config.check_string, 'S': check_config.check_string_or_none, 'I': check_config.check_identifier, 'c': check_config.check_changelist_url, 'j': check_config.check_job_url, 'l': (lambda x, y: check_config.check_list_of (x, y, types.IntType, 'integers')), 'L': (lambda x, y: check_config.check_list_of (x, y, types.StringType, 'strings')), 'p': check_config.check_list_of_string_pairs, } # The 'data' table is a list of pairs (codes, value), where 'codes' # is a list of code letters indicating the checking functions that # the value will pass (other checking functions will fail). data = [ ( "b i ", 0 ), ( "b i ", 1 ), ( " c h sS", "http://www.fo.bar/?%%3a+%%%d%%+%%3d" ), ( " c h sS", "%d" ), ( " c j S", None ), ( " d h sS", "2001-12-01 23:00:59" ), ( " d h sS", "1971-01-31 00:59:00" ), ( " e h sS", "gdr@ravenbrook.com" ), ( " e h sS", "gdr&rb+foo/bar/baz@xyz.invalid" ), ( " e h sS", "gdr!foo!bar@ravenbrook" ), ( " e h sS", "foo.bar@foo.bar.baz.quux.spong" ), ( " e h sS", "!#$%&'*+-/0123456789=?AZ^_`az{|}@uk" ), ( " f ", test() ), # Object ( " f ", test().method ), # Method ( " f ", sys.stdout.write ), # BuiltinMethod ( " f ", getattr ), # BuiltinFunction ( " f ", (lambda (foo): None) ),# Function ( " h I sS", "abcdefg_0123456" ), ( " h I sS", "abcdefg" ), ( " h I sS", "_abcdefghijklmnopqrstuvwxyz56789" ), ( " h I sS", "_ABCDEFGHIJKLMNOPQRSTUVWXYZ01234" ), ( " h I sS", "_" ), ( " h I sS", "M" ), ( " h I sS", "A0Z" ), ( " h j sS", "http://www.foo.bar/?%%%%2b+%s+%%" ), ( " h j sS", "%s" ), ( " h sS", "www.ravenbrook.com" ), ( " h sS", "public.perforce.com" ), ( " h sS", "http://www.foo.bar/%d/%" ), ( " h sS", "http://%s/%x/%%%" ), ( " h sS", "gdr@foo@com" ), ( " h sS", "gdr@" ), ( " h sS", "gdr.ravenbrook.com" ), ( " h sS", "foo;bar@foo.com" ), ( " h sS", "foo,bar@baz.com>" ), ( " h sS", "abc@.foo.com" ), ( " h sS", "abc.@foo.com" ), ( " h sS", "@foo.com" ), ( " h sS", "@" ), ( " h sS", "" ), ( " h sS", "9_" ), ( " h sS", "9_" ), ( " h sS", "9" ), ( " h sS", "5abc" ), ( " h sS", "2001/03/14 13:59:42" ), ( " h sS", "2001-3-4 3:59:42" ), ( " h sS", "2001-03-14T13:59:42Z" ), ( " h sS", "1971-13-01 00:00:00" ), ( " h sS", "1971-01-32 00:00:00" ), ( " h sS", "1971-01-01 24:00:00" ), ( " h sS", "1971-01-01 00:60:00" ), ( " h sS", "1971-01-01 00:00:60" ), ( " h sS", "1971-01-00 00:00:00" ), ( " h sS", "1971-00-01 00:00:00" ), ( " h sS", "0abc" ), ( " h sS", "01-03-14 13:59:42" ), ( " h sS", "" ), ( " i ", 99 ), ( " i ", -1 ), ( " lLp ", [] ), ( " l ", [1, 4, 7] ), ( " L ", ["list", "of", "strings"] ), ( " p ", [("a", "b")] ), ( " p ", [("list",""),("of",""),("string","pairs")]), ( " ", ["Not", "all", -1, "strings"] ), ( " ", [("some", "not"), "pairs"]), ] def runTest(self): "Checking functions (test_check_config.fns)" for (codes, value) in self.data: for (code, checker) in self.codes.items(): try: self.value = value checker(self, 'value') except check_config.error: if code in codes: self.addFailure("Checker %s on '%s' failed " "(should have passed)." % (checker, value)) else: if code not in codes: self.addFailure("Checker %s on '%s' passed " "(should have failed)." % (checker, value)) # 3. RUNNING THE TESTS def tests(): suite = unittest.TestSuite() suite.addTest(fns()) return suite if __name__ == "__main__": unittest.main(defaultTest="tests") # A. REFERENCES # # [PyUnit] "PyUnit - a unit testing framework for Python"; Steve # Purcell; . # # # B. DOCUMENT HISTORY # # 2001-03-14 GDR Created. # # 2001-03-24 GDR Added tests for check_changelist_url and # check_identfier. # # 2001-04-24 GDR Use p4dti_unittest to collect many failures per test # case. # # 2001-07-09 NB Added check_job_url test. # # 2001-11-21 GDR Use new check_* calling convention. Test # check_function against built-ins and methods. # # 2001-12-05 GDR Test check_list_of. # # 2003-11-25 NB Added tests for check_list_of_string_pairs. # # # C. COPYRIGHT AND LICENSE # # This file is copyright (c) 2001 Perforce Software, Inc. All rights # reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH # DAMAGE. # # # $Id: //info.ravenbrook.com/project/p4dti/version/2.1/test/test_check_config.py#1 $