# -*- coding: iso-8859-1 # Perforce Defect Tracking Integration Project # # # TEST_TRANSLATOR.PY -- UNIT TEST FOR THE TRANSLATOR MODULE # # Gareth Rees, Ravenbrook Limited, 2001-03-13 # # # 1. INTRODUCTION # # This module defines a unit test for the keyword_translator class. # # 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 dt_interface import dt_tracker import p4dti_unittest import string import translator import time import unittest kt = translator.keyword_translator() date_trans = dt_tracker.date_translator() # 2. KEYWORD TRANSLATOR TEST CASES # 2.1. Single characters in the defect tracker # # Test that all single characters are unchanged when translated from the # defect tracker to Perforce and back again. class dtchar(p4dti_unittest.TestCase): def runTest(self): "Single chars in the defect tracker (test_translator.dtchar)" for i in range(256): a = chr(i) b = kt.translate_dt_to_p4(a) c = kt.translate_p4_to_dt(b) if c != a: self.addFailure("Character %d failure: %s -> %s -> %s" % (i,a,b,c)) # 2.2. Characters in Perforce # # Test that legal keyword characters (except backslash) in Perforce are # unchanged when translated to the defect tracker and back again. # # Perforce job field names can't contain whitespace, hashes, or double # quotes. Values in "select" fields in Perforce jobspecs also can't # contain semicolons or slashes. class p4char(p4dti_unittest.TestCase): def runTest(self): "Characters in Perforce (test_translator.p4char)" for i in range(256): a = chr(i) if (a not in string.whitespace and a not in '#";/\\'): b = kt.translate_p4_to_dt(a) c = kt.translate_dt_to_p4(b) if c != a: self.addFailure("Character %d failure: " "%s -> %s -> %s" % (i,a,b,c)) # 2.3. Strings in the defect tracker # # Test that a collection of miscellaneous strings are unchanged when # translated from the defect tracker to Perforce and back again. class dtstring(p4dti_unittest.TestCase): strings = [ 'the quick brown fox jumps over the lazy dog', '4_1_1_RELEASE', '\\TeX', '(a;b;c)', '"quote"', 'à la recherche du temps perdu', "Æsop's fables", "Ernesto Cesàro, Pál Erdös, Øystein Ore, " "Muhammad ibn Mûsâ al-Khwârizmî", 'Windows 3.1', 'HP-UX', 'OSF/1', '###urgent###', ] def runTest(self): "Strings in the defect tracker (test_translator.dtstring)" for a in self.strings: b = kt.translate_dt_to_p4(a) c = kt.translate_p4_to_dt(b) if c != a: self.addFailure("String failure: %s -> %s -> %s" % (a,b,c)) # 3. NULL TRANSLATOR TEST CASES # # Test that the null translator (translator.translator) does nothing. class null(unittest.TestCase): values = [ 'string', -1, 0.17, 'string\nwith\nnewlines\n', ] def runTest(self): "Null translator (test_translator.null)" dt0 = dt_interface.defect_tracker() dt1 = dt_interface.defect_tracker() issue0 = dt_interface.defect_tracker_issue() issue1 = dt_interface.defect_tracker_issue() t = translator.translator() for v in self.values: assert v == t.translate_dt_to_p4(v, dt0, dt1, issue0, issue1) assert v == t.translate_p4_to_dt(v, dt0, dt1, issue0, issue1) class dummy_config: def __init__(self): pass class dates(p4dti_unittest.TestCase): keys = {} keys["sShortDate"] = "dd/MM/YYYY" # Date format, e.g. dd/MM/yyyy keys["sTimeFormat"] = "HH:MM:SS" # Date format, e.g. dd/MM/yyyy keys["iTime"] = '1' # 0 = 12 hour, 1 = 24 hour format keys["sTime"] = ':' # time seperator (usually ":") keys["sDate"] = '/' # Date seperator (usually "/") keys["s1159"] = 'AM' # AM indicator (if required) keys["s2359"] = 'PM' # PM indicator (if required) def setUp(self): config = dummy_config() config.rid = "" config.sid = "" config.trk = None self.dt = dt_tracker.dt_tracker(config) self.p4 = dt_interface.defect_tracker() def runTest(self): "Null translator (test_translator.null)" trans = dt_tracker.date_translator(self.keys) # US date format self.keys["sShortDate"] = "M/d/yyyy" self.keys["sTimeFormat"] = "h:m:ss tt" self.keys["iTime"] = '0' trans = dt_tracker.date_translator(self.keys) # Let's start with some actual translating test_dates = [("2005/01/31 12:10:23", "1/31/2005 12:10:23 PM"), ("2005/01/31 10:10:23", "1/31/2005 10:10:23 AM"), ("2000/12/31 10:10:23", "12/31/2000 10:10:23 AM"), ("1999/04/07 10:00:00", "4/7/1999 10:0:00 AM"), ("1999/04/07 09:05:00", "4/7/1999 9:5:00 AM"), ("1999/04/07 09:05:00", "4/7/1999 9:5:00 AM"), ] for d, expected in test_dates: result = trans.translate_p4_to_dt(d, self.dt, self.p4) print result if result != expected: self.addFailure("Dates not equal: expected %s got %s" % (expected, result)) # Translate in the other direction for expected, d in test_dates: result = trans.translate_dt_to_p4(d, self.dt, self.p4) print result if result != expected: self.addFailure("Dates not equal: expected %s got %s" % (expected, result)) # UK date format self.keys["sShortDate"] = "dd/MM/yyyy" self.keys["sTimeFormat"] = "HH:mm:ss" self.keys["iTime"] = '1' trans = dt_tracker.date_translator(self.keys) test_dates = [("2005/01/31 12:10:23", "31/01/2005 12:10:23"), ("2005/01/31 10:10:23", "31/01/2005 10:10:23"), ("2000/12/31 09:10:23", "31/12/2000 09:10:23"), ("1999/04/28 09:00:00", "28/04/1999 09:00:00"), ("1999/04/28 14:05:00", "28/04/1999 14:05:00"), ] for d, expected in test_dates: result = trans.translate_p4_to_dt(d, self.dt, self.p4) print result if result != expected: self.addFailure("Dates not equal: expected %s got %s" % (expected, result)) # Translate in the other direction for expected, d in test_dates: result = trans.translate_dt_to_p4(d, self.dt, self.p4) print result if result != expected: self.addFailure("Dates not equal: expected %s got %s" % (expected, result)) now = time.gmtime() expected = time.strftime(r"%d/%m/%Y %H:%M:%S", now) time_int = int(time.mktime(now)) result = trans.translate_p4_to_dt(str(time_int), self.dt, self.p4) if result != expected: self.addFailure("Now Dates not equal: expected %s got %s" % (expected, result)) # Reuse above to check self.assertEquals(now, trans.translate_dt_to_secs(expected)) # 4. RUNNING THE TESTS def tests(): suite = unittest.TestSuite() tests = [dtchar, dtstring, p4char, null] tests = [dates] for t in tests: suite.addTest(t()) 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-13 GDR Created. # # 2001-04-24 GDR Use p4dti_unittest to collect many failures per test # case. # # 2001-12-05 GDR Test the null translator. # # # 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_translator.py#2 $