Mercurial > hgsubversion
comparison tests/test_util.py @ 1049:608e7c8740af
tests: add a metaclass for testing obsolete mode
We use a metaclass to both make the test code more concise, and more
likely to cover all cases. Typically, someone adding a new fixes will
also add a test, and put it in a class containing similar tests. Going
forward, having that entire class automatically then duplicate its
methods for relevant modes is a plus; a similar approach for stupid
mode already found a few omissions.
| author | Dan Villiom Podlaski Christiansen <danchr@gmail.com> |
|---|---|
| date | Thu, 08 Aug 2013 09:25:24 +0200 |
| parents | 903c9c9dfe6a |
| children | 0932bb4d8870 |
comparison
equal
deleted
inserted
replaced
| 1048:903c9c9dfe6a | 1049:608e7c8740af |
|---|---|
| 24 from mercurial import node | 24 from mercurial import node |
| 25 from mercurial import scmutil | 25 from mercurial import scmutil |
| 26 from mercurial import ui | 26 from mercurial import ui |
| 27 from mercurial import util | 27 from mercurial import util |
| 28 from mercurial import extensions | 28 from mercurial import extensions |
| 29 | |
| 30 try: | |
| 31 from mercurial import obsolete | |
| 32 except ImportError: | |
| 33 obsolete = None | |
| 29 | 34 |
| 30 try: | 35 try: |
| 31 SkipTest = unittest.SkipTest | 36 SkipTest = unittest.SkipTest |
| 32 except AttributeError: | 37 except AttributeError: |
| 33 try: | 38 try: |
| 249 stdout, stderr = p.communicate() | 254 stdout, stderr = p.communicate() |
| 250 if p.returncode: | 255 if p.returncode: |
| 251 raise Exception('svn ls failed on %s: %r' % (path, stderr)) | 256 raise Exception('svn ls failed on %s: %r' % (path, stderr)) |
| 252 return stdout.strip() | 257 return stdout.strip() |
| 253 | 258 |
| 259 | |
| 260 def _obsolete_wrap(cls, name): | |
| 261 origfunc = getattr(cls, name) | |
| 262 | |
| 263 if not name.startswith('test_') or not origfunc: | |
| 264 return | |
| 265 | |
| 266 if not obsolete: | |
| 267 wrapper = _makeskip(name, 'obsolete not available') | |
| 268 else: | |
| 269 def wrapper(self, *args, **opts): | |
| 270 self.assertFalse(obsolete._enabled, 'obsolete was already active') | |
| 271 | |
| 272 obsolete._enabled = True | |
| 273 | |
| 274 try: | |
| 275 origfunc(self, *args, **opts) | |
| 276 self.assertTrue(obsolete._enabled, 'obsolete remains active') | |
| 277 finally: | |
| 278 obsolete._enabled = False | |
| 279 | |
| 280 if not wrapper: | |
| 281 return | |
| 282 | |
| 283 wrapper.__name__ = name + ' obsolete' | |
| 284 wrapper.__module__ = origfunc.__module__ | |
| 285 | |
| 286 if origfunc.__doc__: | |
| 287 firstline = origfunc.__doc__.strip().splitlines()[0] | |
| 288 wrapper.__doc__ = firstline + ' (obsolete)' | |
| 289 | |
| 290 assert getattr(cls, wrapper.__name__, None) is None | |
| 291 | |
| 292 setattr(cls, wrapper.__name__, wrapper) | |
| 293 | |
| 294 class TestMeta(type): | |
| 295 def __init__(cls, *args, **opts): | |
| 296 if cls.obsolete_mode_tests: | |
| 297 for origname in dir(cls): | |
| 298 _obsolete_wrap(cls, origname) | |
| 299 | |
| 300 return super(TestMeta, cls).__init__(*args, **opts) | |
| 301 | |
| 254 class TestBase(unittest.TestCase): | 302 class TestBase(unittest.TestCase): |
| 303 __metaclass__ = TestMeta | |
| 304 | |
| 305 obsolete_mode_tests = False | |
| 306 | |
| 255 def setUp(self): | 307 def setUp(self): |
| 256 _verify_our_modules() | 308 _verify_our_modules() |
| 257 | 309 |
| 258 # the Python 2.7 default of 640 is obnoxiously low | 310 # the Python 2.7 default of 640 is obnoxiously low |
| 259 self.maxDiff = 4096 | 311 self.maxDiff = 4096 |
