From d2752cde56e7cf67abc2e7f0a0fc91612016585f Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Wed, 27 Jan 2010 08:22:22 -0500 Subject: Encourage a run of `make` to build auto-generated files. Fixes Ben's "unintuitive test procedure" bug: Date: Wed, 27 Jan 2010 14:09:14 +1100 From: Ben Finney Subject: [Be-devel] Re: Test suite on Trevor's development branch ... > $ python ./test.py > Traceback (most recent call last): [...] > ImportError: No module named _version So it's not possible to simply get a copy of the branch and try running the test suite. ... --- Makefile | 3 +++ README | 26 +++++++++++++++++++++++++- doc/README.dev | 3 +++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ad78ccb..568e42c 100644 --- a/Makefile +++ b/Makefile @@ -66,6 +66,9 @@ install: doc build clean: $(RM) -rf ${GENERATED_FILES} +test : build + python test.py + .PHONY: libbe/_version.py libbe/_version.py: bzr version-info --format python > $@ diff --git a/README b/README index fe0fd08..b39fca1 100644 --- a/README +++ b/README @@ -1,6 +1,7 @@ Bugs Everywhere =============== -This is Bugs Everywhere, a bugtracker built on distributed revision + +This is Bugs Everywhere (BE), a bugtracker built on distributed revision control. It works with Arch, Bazaar, Darcs, Git, and Mercurial at the moment, but is easily extensible. It can also function with no RCS at all. @@ -9,9 +10,32 @@ The idea is to package the bug information with the source code, so that bugs can be marked "fixed" in the branches that fix them. So, instead of numbers, bugs have globally unique ids. +Getting BE +========== + +BE is available as a bzr repository:: + + $ bzr branch http://bzr.bugseverywhere.org/be + +See the homepage_ for details. If you do branch the bzr repo, you'll +need to run:: + + $ make + +to build some auto-generated files (e.g. ``libbe/_version.py``), and:: + + $ make install + +to install BE. By default BE will install into your home directory, +but you can tweak the ``PREFIX`` variable in ``Makefile`` to install +to another location. + +.. _homepage: http://bugseverywhere.org/ + Getting started =============== + To get started, you must set the bugtracker root. Typically, you will want to set the bug root to your project root, so that Bugs Everywhere works in any part of your project tree. diff --git a/doc/README.dev b/doc/README.dev index cfb1896..67be177 100644 --- a/doc/README.dev +++ b/doc/README.dev @@ -52,6 +52,9 @@ for example: For a definition of "any tests", see ``test.py``'s ``add_module_tests()`` function. +Note that you will need to run ``make`` before testing a clean BE +branch to auto-generate required files like ``libbe/_version.py``. + Profiling ========= -- cgit From 8a07fe257946104c80f656617c168a340f4dae77 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Wed, 27 Jan 2010 08:39:00 -0500 Subject: Add --help, --quiet options to test.py. Fixes Ben's "unintuitive test.py interface" bug: Date: Wed, 27 Jan 2010 14:09:14 +1100 From: Ben Finney Subject: [Be-devel] Re: Test suite on Trevor's development branch ... > $ python ./test.py -q > > ---------------------------------------------------------------------- > Ran 0 tests in 0.000s > > OK Running a Python unittest-capable test suite with "-q" should run it in "quiet" mode, where progress is indicated by single characters along a lone, and only failures and errors are reported. ... --- test.py | 76 +++++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 33 deletions(-) diff --git a/test.py b/test.py index fc7e5d3..5f00ac1 100644 --- a/test.py +++ b/test.py @@ -16,17 +16,6 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -"""Usage: python test.py [module(s) ...] - -When called without optional module names, run the test suites for -*all* modules. This may raise lots of errors if you haven't installed -one of the versioning control systems. - -When called with module name arguments, only run the test suites from -those modules and their submodules. For example: - python test.py libbe.bugdir libbe.storage -""" - import doctest import os import os.path @@ -84,27 +73,48 @@ def add_module_tests(suite, modname): pass suite.addTest(s) -suite = unittest.TestSuite() -tree = python_tree() -if len(sys.argv) <= 1: - for node in tree.traverse(): - add_module_tests(suite, node.modname) -else: - added = [] - for modname in sys.argv[1:]: - for node in tree.traverse(): - if node.modname == modname: - for n in node.traverse(): - if n.modname not in added: - add_module_tests(suite, n.modname) - added.append(n.modname) - break +if __name__ == '__main__': + import optparse + parser = optparse.OptionParser(usage='%prog [options] [modules ...]', + description= +"""When called without optional module names, run the test suites for +*all* modules. This may raise lots of errors if you haven't installed +one of the versioning control systems. + +When called with module name arguments, only run the test suites from +those modules and their submodules. For example:: -result = unittest.TextTestRunner(verbosity=2).run(suite) + $ python test.py libbe.bugdir libbe.storage +""") + parser.add_option('-q', '--quiet', action='store_true', default=False, + help='Run unittests in quiet mode (verbosity 1).') + options,args = parser.parse_args() -numErrors = len(result.errors) -numFailures = len(result.failures) -numBad = numErrors + numFailures -if numBad > 126: - numBad = 1 -sys.exit(numBad) + verbosity = 2 + if options.quiet == True: + verbosity = 1 + + suite = unittest.TestSuite() + tree = python_tree() + if len(args) == 0: + for node in tree.traverse(): + add_module_tests(suite, node.modname) + else: + added = [] + for modname in args: + for node in tree.traverse(): + if node.modname == modname: + for n in node.traverse(): + if n.modname not in added: + add_module_tests(suite, n.modname) + added.append(n.modname) + break + + result = unittest.TextTestRunner(verbosity=verbosity).run(suite) + + numErrors = len(result.errors) + numFailures = len(result.failures) + numBad = numErrors + numFailures + if numBad > 126: + numBad = 1 + sys.exit(numBad) -- cgit From 4203368d2a1f9cc794646754a5027e307074fbf6 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Wed, 27 Jan 2010 10:27:27 -0500 Subject: Make VCS error messages and Storage test failures more descriptive --- libbe/storage/base.py | 15 ++++++++++++--- libbe/storage/vcs/arch.py | 9 ++++++--- libbe/storage/vcs/base.py | 2 +- libbe/storage/vcs/darcs.py | 6 +++--- libbe/storage/vcs/git.py | 2 +- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/libbe/storage/base.py b/libbe/storage/base.py index 64ae3e7..423f141 100644 --- a/libbe/storage/base.py +++ b/libbe/storage/base.py @@ -552,20 +552,29 @@ if TESTING == True: # this class will be the basis of tests for several classes, # so make sure we print the name of the class we're dealing with. + def _classname(self): + version = '?' + try: + if hasattr(self, 's'): + version = self.s.version() + except: + pass + return '%s:%s' % (self.Class.__name__, version) + def fail(self, msg=None): """Fail immediately, with the given message.""" raise self.failureException, \ - '(%s) %s' % (self.Class.__name__, msg) + '(%s) %s' % (self._classname(), msg) def failIf(self, expr, msg=None): "Fail the test if the expression is true." if expr: raise self.failureException, \ - '(%s) %s' % (self.Class.__name__, msg) + '(%s) %s' % (self.classname(), msg) def failUnless(self, expr, msg=None): """Fail the test unless the expression is true.""" if not expr: raise self.failureException, \ - '(%s) %s' % (self.Class.__name__, msg) + '(%s) %s' % (self.classname(), msg) def setUp(self): """Set up test fixtures for Storage test case.""" diff --git a/libbe/storage/vcs/arch.py b/libbe/storage/vcs/arch.py index 74ba371..bfccf59 100644 --- a/libbe/storage/vcs/arch.py +++ b/libbe/storage/vcs/arch.py @@ -72,7 +72,8 @@ class Arch(base.VCS): def _vcs_version(self): status,output,error = self._u_invoke_client('--version') - return output + version = '\n'.join(output.splitlines()[:2]) + return version def _vcs_detect(self, path): """Detect whether a directory is revision-controlled using Arch""" @@ -307,7 +308,8 @@ class Arch(base.VCS): return base.VCS._vcs_get_file_contents(self, relpath) def _vcs_path(self, id, revision): - raise NotImplementedError + raise NotImplementedError( + 'Too little Arch understanding at the moment...') def _vcs_commit(self, commitfile, allow_empty=False): if allow_empty == False: @@ -356,7 +358,8 @@ class Arch(base.VCS): return '%s--%s' % (self._archive_project_name(), log) def _vcs_changed(self, revision): - raise NotImplementedError + raise NotImplementedError( + 'Too little Arch understanding at the moment...') if libbe.TESTING == True: diff --git a/libbe/storage/vcs/base.py b/libbe/storage/vcs/base.py index 8335cfa..337576e 100644 --- a/libbe/storage/vcs/base.py +++ b/libbe/storage/vcs/base.py @@ -515,7 +515,7 @@ os.listdir(self.get_path("bugs")): """ Does the path exist in a given revision? (True/False) """ - raise NotImplementedError + raise NotImplementedError('Lazy BE developers') def _vcs_remove(self, path): """ diff --git a/libbe/storage/vcs/darcs.py b/libbe/storage/vcs/darcs.py index c6892b4..7c6f069 100644 --- a/libbe/storage/vcs/darcs.py +++ b/libbe/storage/vcs/darcs.py @@ -53,7 +53,7 @@ class Darcs(base.VCS): def _vcs_version(self): status,output,error = self._u_invoke_client('--version') - return output.rstrip('\n') + return output.strip() def version_cmp(self, *args): """ @@ -191,8 +191,8 @@ class Darcs(base.VCS): if path in children: return True return False - # Darcs versions <= 2.3.1 lack the --patch option for 'show files' - raise NotImplementedError + raise NotImplementedError( + 'Darcs versions <= 2.3.1 lack the --patch option for "show files"') def _vcs_listdir(self, path, revision): if self.version_cmp(2, 3, 1) == 1: diff --git a/libbe/storage/vcs/git.py b/libbe/storage/vcs/git.py index 6d3aa87..e2c1b83 100644 --- a/libbe/storage/vcs/git.py +++ b/libbe/storage/vcs/git.py @@ -49,7 +49,7 @@ class Git(base.VCS): def _vcs_version(self): status,output,error = self._u_invoke_client('--version') - return output + return output.strip() def _vcs_get_user_id(self): status,output,error = \ -- cgit