From: W. Trevor King Date: Sun, 21 Jun 2009 11:28:48 +0000 (-0400) Subject: Merge from Ben Finney's RCS unittest patch X-Git-Tag: 1.0.0~80 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=47901fbf10ba498a91a4701129a2f1959d00df67;p=be.git Merge from Ben Finney's RCS unittest patch This involved an `upgrade' of BE's bzr repo Previous version (via `bzr info path/to/repo`): pack-0.92 Current version: rich-root-pack The whole rich-root thing is a bzr features-vs-backwards-compatability thing they've been wrestling with [1,2,3,4,...]. It seems that BE was in some sort of unstable equilibrium [5], so I'll follow Ben's lead and make the official switch. Note that you'll need to use bzr>=1.5 to make the shift [6]. For the sake of completeness, the whole rich-root thing was introduced here [7], but I don't understand enough of bzr to make sense of the diff. It just versions the repo's root directory the same way it versions other directories [3]. The bzr people seem to be planning to phase out non-rich-root formats in favor of brisbane-core, aka 2.0beta [8], by bzr 2.0 [8], which is apparently on the horizon [9,10,11]. What a headache. Citations are all titles/X-List-Received-Date from https://lists.ubuntu.com/archives/bazaar/ with the exception of the URL [11]. [1] [RFC] rich root pack as default in 1.8 ? Sat, 06 Sep 2008 03:33:46 -0000 (conclusion: none) [2] Re: 1.9rc1 countdown Thu, 30 Oct 2008 08:44:53 -0000 (conclusion: "primary" format should be rich-root next time we make a new format) [3] So many repo formats Fri, 14 Nov 2008 08:41:33 -0000 Mon, 17 Nov 2008 07:37:47 -0000 (explains rich-root format) Mon, 17 Nov 2008 22:37:39 -0000 (explains no-return policy) Mon, 17 Nov 2008 20:57:08 -0000 (explicitly lists non-svn reasons for rich-root) [4] Branch fails from 'pack-0.92' repo to 'rich-root-pack' repo. Wed, 27 Aug 2008 11:31:11 -0000 (we're not sure again) [5] Branch fails from 'pack-0.92' repo to 'rich-root-pack' repo. Sun, 20 Apr 2008 12:58:09 -0000 [6] Branch fails from 'pack-0.92' repo to 'rich-root-pack' repo. Fri, 29 Aug 2008 13:23:52 -0000 [7] [RFC] Knit format 2 Fri, 25 Aug 2006 22:55:36 -0000 [8] bazaar 2.0beta format for launchpad release Fri, 29 May 2009 06:00:03 -0000 [9] Upgrading loggerhead to 1.9-rich-root Mon, 11 May 2009 22:35:28 -0000 (mentions eventual switch to rich-root in 2.0) [10] bzr 1.16rc1 released! Fri, 12 Jun 2009 08:00:08 -0000 (confirms eventual switch to rich-root in 2.0) [11] https://launchpad.net/bzr/+announcement/2733 (current outstanding releases: 1.17, 2.0) --- 47901fbf10ba498a91a4701129a2f1959d00df67 diff --cc libbe/arch.py index a2d6bde,73bef35..cd0f3b2 --- a/libbe/arch.py +++ b/libbe/arch.py @@@ -14,21 -14,24 +14,24 @@@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + -import sys +import codecs import os +import re import shutil ++import sys import time -import re import unittest import doctest import config from beuuid import uuid_gen - from rcs import RCS, RCStestCase, CommandError + import rcs + from rcs import RCS -client = config.get_val("arch_client") -if client is None: - client = "tla" - config.set_val("arch_client", client) +DEFAULT_CLIENT = "tla" + +client = config.get_val("arch_client", default=DEFAULT_CLIENT) def new(): return Arch() diff --cc libbe/bzr.py index 38af6bb,4a01d8a..98ca571 --- a/libbe/bzr.py +++ b/libbe/bzr.py @@@ -14,8 -14,10 +14,10 @@@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + -import sys import os import re ++import sys import unittest import doctest diff --cc libbe/git.py index e57014f,4a1ddee..401b5e5 --- a/libbe/git.py +++ b/libbe/git.py @@@ -13,8 -13,10 +13,10 @@@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + -import sys import os import re ++import sys import unittest import doctest diff --cc libbe/hg.py index c00d7e2,52f8a96..a7413af --- a/libbe/hg.py +++ b/libbe/hg.py @@@ -13,8 -13,10 +13,10 @@@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + -import sys import os import re ++import sys import unittest import doctest diff --cc libbe/rcs.py index 786f9dd,a5a1769..c0b92e7 --- a/libbe/rcs.py +++ b/libbe/rcs.py @@@ -14,15 -14,14 +14,16 @@@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ from subprocess import Popen, PIPE +import codecs import os import os.path -from socket import gethostname import re +from socket import gethostname +import shutil import sys import tempfile -import shutil import unittest import doctest @@@ -550,97 -543,274 +551,274 @@@ class RCS(object) body.lstrip('\n') if len(body) == 0: body = None - f.close + f.close() return (summary, body) + + def setup_rcs_test_fixtures(testcase): + """Set up test fixtures for RCS test case.""" + testcase.rcs = testcase.Class() + testcase.dir = Dir() + testcase.dirname = testcase.dir.path + + testcase.rcs_supports_uninitialized_user_id = ( + testcase.rcs.name not in ["git"]) + testcase.rcs_supports_set_user_id = ( + testcase.rcs.name not in ["None", "hg"]) + + if not testcase.rcs.installed(): + testcase.fail( + "%(name)s RCS not found" % vars(testcase.Class)) + + if testcase.Class.name != "None": + testcase.failIf( + testcase.rcs.detect(testcase.dirname), + "Detected %(name)s RCS before initialising" + % vars(testcase.Class)) + + testcase.rcs.init(testcase.dirname) + + + class RCSTestCase(unittest.TestCase): + """Test cases for base RCS class.""" - class RCStestCase(unittest.TestCase): Class = RCS + def __init__(self, *args, **kwargs): - unittest.TestCase.__init__(self, *args, **kwargs) + super(RCSTestCase, self).__init__(*args, **kwargs) self.dirname = None - def instantiateRCS(self): - return self.Class() + def setUp(self): - self.dir = Dir() - self.dirname = self.dir.path - self.rcs = self.instantiateRCS() + super(RCSTestCase, self).setUp() + setup_rcs_test_fixtures(self) + def tearDown(self): del(self.rcs) - del(self.dirname) - def fullPath(self, path): - return os.path.join(self.dirname, path) - def assertPathExists(self, path): - fullpath = self.fullPath(path) - self.failUnless(os.path.exists(fullpath)==True, - "path %s does not exist" % fullpath) - def uidTest(self): + super(RCSTestCase, self).tearDown() + + def full_path(self, rel_path): + return os.path.join(self.dirname, rel_path) + + + class RCS_init_TestCase(RCSTestCase): + """Test cases for RCS.init method.""" + + def test_detect_should_succeed_after_init(self): + """Should detect RCS in directory after initialization.""" + self.failUnless( + self.rcs.detect(self.dirname), + "Did not detect %(name)s RCS after initialising" + % vars(self.Class)) + + def test_rcs_rootdir_in_specified_root_path(self): + """RCS root directory should be in specified root path.""" + rp = os.path.realpath(self.rcs.rootdir) + dp = os.path.realpath(self.dirname) + rcs_name = self.Class.name + self.failUnless( + dp == rp or rp == None, + "%(rcs_name)s RCS root in wrong dir (%(dp)s %(rp)s)" % vars()) + + + class RCS_get_user_id_TestCase(RCSTestCase): + """Test cases for RCS.get_user_id method.""" + + def test_gets_existing_user_id(self): + """Should get the existing user ID.""" + if not self.rcs_supports_uninitialized_user_id: + return + user_id = self.rcs.get_user_id() - self.failUnless(user_id != None, - "unable to get a user id") - user_idB = "John Doe " - if self.rcs.name in ["None", "hg"]: - self.assertRaises(SettingIDnotSupported, self.rcs.set_user_id, - user_idB) + self.failUnless( + user_id is not None, + "unable to get a user id") + + + class RCS_set_user_id_TestCase(RCSTestCase): + """Test cases for RCS.set_user_id method.""" + + def setUp(self): + super(RCS_set_user_id_TestCase, self).setUp() + + if self.rcs_supports_uninitialized_user_id: + self.prev_user_id = self.rcs.get_user_id() else: - self.rcs.set_user_id(user_idB) - self.failUnless(self.rcs.get_user_id() == user_idB, - "user id not set correctly (was %s, is %s)" \ - % (user_id, self.rcs.get_user_id())) - self.failUnless(self.rcs.set_user_id(user_id) == None, - "unable to restore user id %s" % user_id) - self.failUnless(self.rcs.get_user_id() == user_id, - "unable to restore user id %s" % user_id) - def versionTest(self, path): - origpath = path - path = self.fullPath(path) - contentsA = "Lorem ipsum" - contentsB = "dolor sit amet" - self.rcs.set_file_contents(path,contentsA) - self.failUnless(self.rcs.get_file_contents(path)==contentsA, - "File contents not set or read correctly") - revision = self.rcs.commit("Commit current status") - self.failUnless(self.rcs.get_file_contents(path)==contentsA, - "Committing File contents not set or read correctly") - if self.rcs.versioned == True: - self.rcs.set_file_contents(path,contentsB) - self.failUnless(self.rcs.get_file_contents(path)==contentsB, - "File contents not set correctly after commit") - contentsArev = self.rcs.get_file_contents(path, revision) - self.failUnless(contentsArev==contentsA, \ - "Original file contents not saved in revision %s\n%s\n%s\n" \ - % (revision, contentsA, contentsArev)) - dup = self.rcs.duplicate_repo(revision) - duppath = os.path.join(dup, origpath) - dupcont = file(duppath, "rb").read() - self.failUnless(dupcont == contentsA) + self.prev_user_id = "Uninitialized identity " + + if self.rcs_supports_set_user_id: + self.test_new_user_id = "John Doe " + self.rcs.set_user_id(self.test_new_user_id) + + def tearDown(self): + if self.rcs_supports_set_user_id: + self.rcs.set_user_id(self.prev_user_id) + super(RCS_set_user_id_TestCase, self).tearDown() + + def test_raises_error_in_unsupported_vcs(self): + """Should raise an error in a VCS that doesn't support it.""" + if self.rcs_supports_set_user_id: + return + self.assertRaises( + SettingIDnotSupported, + self.rcs.set_user_id, "foo") + + def test_updates_user_id_in_supporting_rcs(self): + """Should update the user ID in an RCS that supports it.""" + if not self.rcs_supports_set_user_id: + return + user_id = self.rcs.get_user_id() + self.failUnlessEqual( + self.test_new_user_id, user_id, + "user id not set correctly (expected %s, got %s)" + % (self.test_new_user_id, user_id)) + + + def setup_rcs_revision_test_fixtures(testcase): + """Set up revision test fixtures for RCS test case.""" + testcase.test_dirs = ['a', 'a/b', 'c'] + for path in testcase.test_dirs: + testcase.rcs.mkdir(testcase.full_path(path)) + + testcase.test_files = ['a/text', 'a/b/text'] + + testcase.test_contents = { + 'rev_1': "Lorem ipsum", + 'uncommitted': "dolor sit amet", + } + + + class RCS_mkdir_TestCase(RCSTestCase): + """Test cases for RCS.mkdir method.""" + + def setUp(self): + super(RCS_mkdir_TestCase, self).setUp() + setup_rcs_revision_test_fixtures(self) + + def tearDown(self): + for path in reversed(sorted(self.test_dirs)): + self.rcs.recursive_remove(self.full_path(path)) + super(RCS_mkdir_TestCase, self).tearDown() + + def test_mkdir_creates_directory(self): + """Should create specified directory in filesystem.""" + for path in self.test_dirs: + full_path = self.full_path(path) + self.failUnless( + os.path.exists(full_path), + "path %(full_path)s does not exist" % vars()) + + + class RCS_commit_TestCase(RCSTestCase): + """Test cases for RCS.commit method.""" + + def setUp(self): + super(RCS_commit_TestCase, self).setUp() + setup_rcs_revision_test_fixtures(self) + + def tearDown(self): + for path in reversed(sorted(self.test_dirs)): + self.rcs.recursive_remove(self.full_path(path)) + super(RCS_commit_TestCase, self).tearDown() + + def test_file_contents_as_specified(self): + """Should set file contents as specified.""" + test_contents = self.test_contents['rev_1'] + for path in self.test_files: + full_path = self.full_path(path) + self.rcs.set_file_contents(full_path, test_contents) + current_contents = self.rcs.get_file_contents(full_path) + self.failUnlessEqual(test_contents, current_contents) + + def test_file_contents_as_committed(self): + """Should have file contents as specified after commit.""" + test_contents = self.test_contents['rev_1'] + for path in self.test_files: + full_path = self.full_path(path) + self.rcs.set_file_contents(full_path, test_contents) + revision = self.rcs.commit("Initial file contents.") + current_contents = self.rcs.get_file_contents(full_path) + self.failUnlessEqual(test_contents, current_contents) + + def test_file_contents_as_set_when_uncommitted(self): + """Should set file contents as specified after commit.""" + if not self.rcs.versioned: + return + for path in self.test_files: + full_path = self.full_path(path) + self.rcs.set_file_contents( + full_path, self.test_contents['rev_1']) + revision = self.rcs.commit("Initial file contents.") + self.rcs.set_file_contents( + full_path, self.test_contents['uncommitted']) + current_contents = self.rcs.get_file_contents(full_path) + self.failUnlessEqual( + self.test_contents['uncommitted'], current_contents) + + def test_revision_file_contents_as_committed(self): + """Should get file contents as committed to specified revision.""" + if not self.rcs.versioned: + return + for path in self.test_files: + full_path = self.full_path(path) + self.rcs.set_file_contents( + full_path, self.test_contents['rev_1']) + revision = self.rcs.commit("Initial file contents.") + self.rcs.set_file_contents( + full_path, self.test_contents['uncommitted']) + committed_contents = self.rcs.get_file_contents( + full_path, revision) + self.failUnlessEqual( + self.test_contents['rev_1'], committed_contents) + + + class RCS_duplicate_repo_TestCase(RCSTestCase): + """Test cases for RCS.duplicate_repo method.""" + + def setUp(self): + super(RCS_duplicate_repo_TestCase, self).setUp() + setup_rcs_revision_test_fixtures(self) + + def tearDown(self): + self.rcs.remove_duplicate_repo() + for path in reversed(sorted(self.test_dirs)): + self.rcs.recursive_remove(self.full_path(path)) + super(RCS_duplicate_repo_TestCase, self).tearDown() + + def test_revision_file_contents_as_committed(self): + """Should match file contents as committed to specified revision.""" + if not self.rcs.versioned: + return + for path in self.test_files: + full_path = self.full_path(path) + self.rcs.set_file_contents( + full_path, self.test_contents['rev_1']) + revision = self.rcs.commit("Commit current status") + self.rcs.set_file_contents( + full_path, self.test_contents['uncommitted']) + dup_repo_path = self.rcs.duplicate_repo(revision) + dup_file_path = os.path.join(dup_repo_path, path) + dup_file_contents = file(dup_file_path, 'rb').read() + self.failUnlessEqual( + self.test_contents['rev_1'], dup_file_contents) self.rcs.remove_duplicate_repo() - def testRun(self): - self.failUnless(self.rcs.installed() == True, - "%s RCS not found" % self.Class.name) - if self.Class.name != "None": - self.failUnless(self.rcs.detect(self.dirname)==False, - "Detected %s RCS before initializing" \ - % self.Class.name) - self.rcs.init(self.dirname) - self.failUnless(self.rcs.detect(self.dirname)==True, - "Did not detect %s RCS after initializing" \ - % self.Class.name) - rp = os.path.realpath(self.rcs.rootdir) - dp = os.path.realpath(self.dirname) - self.failUnless(dp == rp or rp == None, - "%s RCS root in wrong dir (%s %s)" \ - % (self.Class.name, dp, rp)) - self.uidTest() - self.rcs.mkdir(self.fullPath('a')) - self.rcs.mkdir(self.fullPath('a/b')) - self.rcs.mkdir(self.fullPath('c')) - self.assertPathExists('a') - self.assertPathExists('a/b') - self.assertPathExists('c') - self.versionTest('a/text') - self.versionTest('a/b/text') - self.rcs.recursive_remove(self.fullPath('a')) - - unitsuite = unittest.TestLoader().loadTestsFromTestCase(RCStestCase) + + + def make_rcs_testcase_subclasses(rcs_class, namespace): + """Make RCSTestCase subclasses for rcs_class in the namespace.""" + rcs_testcase_classes = [ + c for c in ( + ob for ob in globals().values() if isinstance(ob, type)) + if issubclass(c, RCSTestCase)] + + for base_class in rcs_testcase_classes: + testcase_class_name = rcs_class.__name__ + base_class.__name__ + testcase_class_bases = (base_class,) + testcase_class_dict = dict(base_class.__dict__) + testcase_class_dict['Class'] = rcs_class + testcase_class = type( + testcase_class_name, testcase_class_bases, testcase_class_dict) + setattr(namespace, testcase_class_name, testcase_class) + + + unitsuite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) suite = unittest.TestSuite([unitsuite, doctest.DocTestSuite()])