# Perforce Defect Tracking Integration Project # # # TEST_MESSAGE.PY -- UNIT TESTS FOR MESSAGE MODULE # # Gareth Rees, Ravenbrook Limited, 2001-03-13 # # # 1. INTRODUCTION # # This module defines a set of unit tests for the message 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 message import p4dti_unittest import string import unittest import whrandom # 2. TEST CASES # 2.1. Message creation and conversion # # Test that messages can be created and converted to a string. success_cases = [ ( 1, "Test 1", message.DEBUG, "Foo", "(Foo-11) Test 1" ), ( 22, "Test 2", message.INFO, "XYZ", "(XYZ-226) Test 2" ), ( 333, "Test 3", message.NOTICE, "", "(3337) Test 3" ), ( 4444, "Test 4", message.WARNING, "P4DTI", "(P4DTI-44447) Test 4" ), ( 12345, "Test 5", message.ERR, "%%%%", "(%%%%-123452) Test 5" ), ( 9999, "Test 6", message.CRIT, "%s%d", "(%s%d-99992) Test 6" ), ( 999, "Test 7", message.ALERT, "abcdefg", "(abcdefg-999X) Test 7" ), ( 0, "Test 8", message.EMERG, "", "(00) Test 8" ), ] class create(p4dti_unittest.TestCase): def runTest(self): "Message creation and conversion (test_message.create)" for case in success_cases: (id, text, priority, product, expected) = case msg = message.message(id, text, priority, product) found = str(msg) if expected != found: self.addFailure("Case %s: expected '%s' but found '%s'." % (case, expected, found)) # 2.2. Failure on message creation # # Test that attempts to create messages with bogus data fail. failure_cases = [ ( None, "Failure 1", message.EMERG, "Foo", AssertionError ), ( -1, "Failure 2", message.INFO, "XYZ", AssertionError ), ( 0, None, message.EMERG, "", AssertionError ), ( 999, "Failure 4", "message.CRIT", "Foo", AssertionError ), ( 56, "Failure 5", -1, "P4DTI", AssertionError ), ( 12345, "Failure 6", 100, "abcd", AssertionError ), ( 1234, "Failure 7", message.EMERG, 999, AssertionError ), ] class fail(p4dti_unittest.TestCase): def runTest(self): "Creating messages with bogus data fails (test_message.fail)" for case in failure_cases: (id, text, priority, product, expected) = case try: msg = message.message(id, text, priority, product) except expected: pass else: self.addFailure("Case %s: expected %s." % (case, expected)) # 2.3. Message wrapping # # Test that wrapping to a number of columns works as expected. class wrap(p4dti_unittest.TestCase): def runTest(self): "Message wrapping (test_message.wrap)" # On trial 0, try cases where no word is longer than the number of # columns. On trial 1, try cases where some words are longer than the # number of columns. for trial in range(2): columns = 1 while columns < 1000: nwords = 10 + whrandom.randint(0, columns) def word(_, c=columns, t=trial): return (string.letters[whrandom.randint(0,25)] * whrandom.randint(1, c * (t + 1))) text = string.join(map(word, range(nwords)), ' ') msg = message.message(0, text, message.DEBUG, "") expected = str(msg) wrapped = msg.wrap(columns) lines = string.split(wrapped, '\n') if lines[0] == '(00)': found = lines[0] + ' ' + string.join(lines[1:], ' ') else: found = string.join(lines, ' ') for l in range(0,len(lines)): # On trial 0 each line must fit in the columns, since no # word was longer than columns. if (trial == 0 and (l > 0 or columns > 4) and len(lines[l]) > columns): self.addFailure("Wrapping to %d columns, line %d has " "length %d (%s)." % (columns, l, len(lines[l]), lines)) # Lines longer than the columns consist of a single word. if (len(lines[l]) > columns and string.find(lines[l], ' ') != -1): self.addFailure("Wrapping to %d columns, line %d has " "a space (%s)." % (columns, l, lines)) # No line can be extended by adjoining the first word from # the following line without making it go over the number # of columns. if (l + 1 < len(lines) and (len(lines[l]) + 1 + (l == 0) + len(string.split(lines[l+1],' ')[0])) <= columns): self.addFailure("Wrapping to %d columns, line %d " "could have an extra word in it (%s)." % (columns, l, lines)) if expected != found: self.addFailure("Wrapping to %d columns:\nExpected: %s\n" "Found: %s\nWrapped: %s." % (columns, expected, found, `wrapped`)) columns = columns * 2 + whrandom.randint(0,1) # 3. RUNNING THE TESTS def tests(): suite = unittest.TestSuite() for t in [create, fail, wrap]: 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. # # # C. COPYRIGHT AND LICENCE # # 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/branch/2001-11-05/nt-service/test/test_message.py#1 $