# 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 $