Below is the file 'tests.py' from this revision. You can also download the file.
#!/usr/bin/env python2.4 # Copyright (C) 2005 Grahame Bowland <grahame@angrygoats.net> # # This program is made available under the GNU GPL version 2.0 or # greater. See the accompanying file COPYING for details. # # This program is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. # # Unit tests for ViewMTN # # Aiming for reasonably full coverage, but the tests are being # written after the application so it's slow and tedious work :-) # import unittest import stat import os # modules we're testing.. import viewmtn import mtn class ConfigTest(unittest.TestCase): "Test that the configuration file is correct" def can_access(self, fname): self.failIf (not os.access(fname, os.R_OK), "Cannot access file: " + fname) def is_uri(self, uri): self.failIf (not isinstance(uri, str), "URIs must be instances of <str>") self.failIf (not uri[-1] == '/', "All URIs in config file must end in '/'") def is_file(self, fname): self.failIf (not stat.S_ISREG(os.stat(fname).st_mode), "Files in config file must be regular files: " + fname) def is_command(self, fname): self.failIf (not os.access(fname, os.X_OK), "Must be able to execute: " + fname) def is_directory(self, fname): self.failIf (not stat.S_ISDIR(os.stat(fname).st_mode), "Must be a directory: " + fname) # # describe the config file with lists of functions that should # succeed on the value found in the config file. for now, any # option listed below is required (ViewMTN doesn't really have # optional configuration directives, anyway..) # check_keys = [(lambda self : self.config, lambda obj, key : hasattr(obj, key), lambda obj, key : getattr(obj, key), { 'dynamic_uri_path' : (is_uri,), 'static_uri_path' : (is_uri,), 'running_under_apache2' : None, 'monotone' : (can_access, is_file, is_command), 'dbfile' : (can_access, is_file,), 'highlight_command' : (can_access, is_file, is_command), 'graphopts' : None, 'icon_theme' : None, 'icon_size' : None, }), (lambda self: self.config.graphopts, lambda obj, key : obj.has_key(key), lambda obj, key : obj[key], { 'directory' : (can_access, is_directory), 'uri' : (is_uri,), 'dot' : (can_access, is_file, is_command), 'nodeopts' : None }), (lambda self: self.config.graphopts['nodeopts'], lambda obj, key : obj.has_key(key), lambda obj, key : obj[key], { 'fontname' : None, 'fontsize' : None, 'shape' : None, 'height' : None, 'spline' : None, 'style' : None, 'fillcolor' : None }) ] def setUp(self): self.config = __import__('config') def testRequiredKeys(self): "all required configuration options present" for val_func, has_func, get_func, keys in self.check_keys: to_check = val_func(self) for key in keys: self.failIf(not has_func(to_check, key), "Required configuration option '%s' not found." % key) funcs = keys[key] if funcs == None: continue val = get_func(to_check, key) map(lambda func : func(self, val), funcs) class MTNRegexpTests(unittest.TestCase): entirely_non_hex = 'NOTX' starts_with_hex = 'A9NOTX' ends_with_hex = 'NOTXA9' valid_revision = 'abcdEf0123456789abcdEf0123456789abcdef12' too_long_revision = valid_revision + '9' too_short_revision = valid_revision[:-1] non_hex_revision = valid_revision.replace('a', 'Q') non_hex_start_revision = 'QQ' + valid_revision non_hex_end_revision = valid_revision + 'QQ' def testHex(self): "Test that mtn.py regular expressions do what we think they do" self.assertEqual(mtn.hex_re_c.match('').groups(), ('',), 'hex_re must match empty string') self.assertEqual(mtn.hex_re_c.match(self.entirely_non_hex).groups(), ('',), 'hex_re must match entirely non-hex and group empty string') self.assertEqual(mtn.hex_re_c.match(self.starts_with_hex).groups(), ('A9',), 'hex_re must match hex followed by non-hex and group beginning hex') self.assertEqual(mtn.hex_re_c.match(self.ends_with_hex).groups(), ('',), 'hex_re must match non-hex followed by hex and group empty string') self.assertEqual(mtn.revision_re_c.match(''), None, 'revision_re must not match empty string') self.assertEqual(mtn.revision_re_c.match(self.valid_revision).groups(), (self.valid_revision,), 'revision_re must match valid revision') self.failIf(mtn.revision_re_c.match(self.too_short_revision), 'revision_re must not match too-short revision') self.failIf(mtn.revision_re_c.match(self.non_hex_revision), 'revision_re must not match non-hex revision') self.failIf(mtn.revision_re_c.match(self.non_hex_start_revision), 'revision_re must not match non-hex followed by valid revision') self.failIf(mtn.revision_re_c.match(self.non_hex_end_revision), 'revision_re must not match valid revision followed by non-hex') class MtnTypeTests(unittest.TestCase): def testRevision(self): "Test the mtn.Revision class" self.assertEqual (mtn.Revision(''), '', 'Revision must work for empty revision, and subclass str()') self.assertRaises (mtn.MonotoneException, lambda : mtn.Revision(MTNRegexpTests.too_long_revision)) self.assertRaises (mtn.MonotoneException, lambda : mtn.Revision(MTNRegexpTests.too_short_revision)) self.assertRaises (mtn.MonotoneException, lambda : mtn.Revision(MTNRegexpTests.non_hex_revision)) self.assertRaises (mtn.MonotoneException, lambda : mtn.Revision(MTNRegexpTests.non_hex_start_revision)) self.assertRaises (mtn.MonotoneException, lambda : mtn.Revision(MTNRegexpTests.non_hex_end_revision)) self.assertEqual (mtn.Revision(MTNRegexpTests.valid_revision), MTNRegexpTests.valid_revision, 'Revision must work for valid revision, and subclass str()') def testAuthor(self): "Test the mtn.Author class" self.assertEqual (mtn.Author(''), '', 'Author must work for empty string, and subclass str()') self.assertEqual (mtn.Author('Gumby'), 'Gumby', 'Author must work for non-empty string, and subclass str()') class MtnAutomateTests(unittest.TestCase): def testPacketHeader(self): pass if __name__ == '__main__': unittest.main() ### ### vi:expandtab:sw=4:ts=4 ###