Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Side by Side Diff: third_party/logilab/common/testlib.py

Issue 719313003: Revert "pylint: upgrade to 1.3.1" (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/logilab/common/tasksqueue.py ('k') | third_party/logilab/common/textutils.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 # copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 2 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
3 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr 3 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
4 # 4 #
5 # This file is part of logilab-common. 5 # This file is part of logilab-common.
6 # 6 #
7 # logilab-common is free software: you can redistribute it and/or modify it unde r 7 # logilab-common is free software: you can redistribute it and/or modify it unde r
8 # the terms of the GNU Lesser General Public License as published by the Free 8 # the terms of the GNU Lesser General Public License as published by the Free
9 # Software Foundation, either version 2.1 of the License, or (at your option) an y 9 # Software Foundation, either version 2.1 of the License, or (at your option) an y
10 # later version. 10 # later version.
11 # 11 #
12 # logilab-common is distributed in the hope that it will be useful, but WITHOUT 12 # logilab-common is distributed in the hope that it will be useful, but WITHOUT
(...skipping 16 matching lines...) Expand all
29 -t testdir -- directory where the tests will be found 29 -t testdir -- directory where the tests will be found
30 -x exclude -- add a test to exclude 30 -x exclude -- add a test to exclude
31 -p profile -- profiled execution 31 -p profile -- profiled execution
32 -d dbc -- enable design-by-contract 32 -d dbc -- enable design-by-contract
33 -m match -- only run test matching the tag pattern which follow 33 -m match -- only run test matching the tag pattern which follow
34 34
35 If no non-option arguments are present, prefixes used are 'test', 35 If no non-option arguments are present, prefixes used are 'test',
36 'regrtest', 'smoketest' and 'unittest'. 36 'regrtest', 'smoketest' and 'unittest'.
37 37
38 """ 38 """
39
40 from __future__ import print_function
41
42 __docformat__ = "restructuredtext en" 39 __docformat__ = "restructuredtext en"
43 # modified copy of some functions from test/regrtest.py from PyXml 40 # modified copy of some functions from test/regrtest.py from PyXml
44 # disable camel case warning 41 # disable camel case warning
45 # pylint: disable=C0103 42 # pylint: disable=C0103
46 43
47 import sys 44 import sys
48 import os, os.path as osp 45 import os, os.path as osp
49 import re 46 import re
50 import traceback 47 import traceback
51 import inspect 48 import inspect
52 import difflib 49 import difflib
53 import tempfile 50 import tempfile
54 import math 51 import math
55 import warnings 52 import warnings
56 from shutil import rmtree 53 from shutil import rmtree
57 from operator import itemgetter 54 from operator import itemgetter
55 from ConfigParser import ConfigParser
56 from logilab.common.deprecation import deprecated
58 from itertools import dropwhile 57 from itertools import dropwhile
59 from inspect import isgeneratorfunction
60
61 from six import string_types
62 from six.moves import builtins, range, configparser, input
63
64 from logilab.common.deprecation import deprecated
65 58
66 import unittest as unittest_legacy 59 import unittest as unittest_legacy
67 if not getattr(unittest_legacy, "__package__", None): 60 if not getattr(unittest_legacy, "__package__", None):
68 try: 61 try:
69 import unittest2 as unittest 62 import unittest2 as unittest
70 from unittest2 import SkipTest 63 from unittest2 import SkipTest
71 except ImportError: 64 except ImportError:
72 raise ImportError("You have to install python-unittest2 to use %s" % __n ame__) 65 sys.exit("You have to install python-unittest2 to use this module")
73 else: 66 else:
74 import unittest 67 import unittest
75 from unittest import SkipTest 68 from unittest import SkipTest
76 69
77 from functools import wraps 70 try:
71 from functools import wraps
72 except ImportError:
73 def wraps(wrapped):
74 def proxy(callable):
75 callable.__name__ = wrapped.__name__
76 return callable
77 return proxy
78 try:
79 from test import test_support
80 except ImportError:
81 # not always available
82 class TestSupport:
83 def unload(self, test):
84 pass
85 test_support = TestSupport()
78 86
87 # pylint: disable=W0622
88 from logilab.common.compat import any, InheritableSet, callable
89 # pylint: enable=W0622
79 from logilab.common.debugger import Debugger, colorize_source 90 from logilab.common.debugger import Debugger, colorize_source
80 from logilab.common.decorators import cached, classproperty 91 from logilab.common.decorators import cached, classproperty
81 from logilab.common import textutils 92 from logilab.common import textutils
82 93
83 94
84 __all__ = ['main', 'unittest_main', 'find_tests', 'run_test', 'spawn'] 95 __all__ = ['main', 'unittest_main', 'find_tests', 'run_test', 'spawn']
85 96
86 DEFAULT_PREFIXES = ('test', 'regrtest', 'smoketest', 'unittest', 97 DEFAULT_PREFIXES = ('test', 'regrtest', 'smoketest', 'unittest',
87 'func', 'validation') 98 'func', 'validation')
88 99
89 is_generator = deprecated('[lgc 0.63] use inspect.isgeneratorfunction')(isgenera torfunction) 100
101 if sys.version_info >= (2, 6):
102 # FIXME : this does not work as expected / breaks tests on testlib
103 # however testlib does not work on py3k for many reasons ...
104 from inspect import CO_GENERATOR
105 else:
106 from compiler.consts import CO_GENERATOR
107
108 if sys.version_info >= (3, 0):
109 def is_generator(function):
110 flags = function.__code__.co_flags
111 return flags & CO_GENERATOR
112
113 else:
114 def is_generator(function):
115 flags = function.func_code.co_flags
116 return flags & CO_GENERATOR
90 117
91 # used by unittest to count the number of relevant levels in the traceback 118 # used by unittest to count the number of relevant levels in the traceback
92 __unittest = 1 119 __unittest = 1
93 120
94 121
95 def with_tempdir(callable): 122 def with_tempdir(callable):
96 """A decorator ensuring no temporary file left when the function return 123 """A decorator ensuring no temporary file left when the function return
97 Work only for temporary file create with the tempfile module""" 124 Work only for temporary file create with the tempfile module"""
98 if isgeneratorfunction(callable):
99 def proxy(*args, **kwargs):
100 old_tmpdir = tempfile.gettempdir()
101 new_tmpdir = tempfile.mkdtemp(prefix="temp-lgc-")
102 tempfile.tempdir = new_tmpdir
103 try:
104 for x in callable(*args, **kwargs):
105 yield x
106 finally:
107 try:
108 rmtree(new_tmpdir, ignore_errors=True)
109 finally:
110 tempfile.tempdir = old_tmpdir
111 return proxy
112
113 @wraps(callable) 125 @wraps(callable)
114 def proxy(*args, **kargs): 126 def proxy(*args, **kargs):
115 127
116 old_tmpdir = tempfile.gettempdir() 128 old_tmpdir = tempfile.gettempdir()
117 new_tmpdir = tempfile.mkdtemp(prefix="temp-lgc-") 129 new_tmpdir = tempfile.mkdtemp(prefix="temp-lgc-")
118 tempfile.tempdir = new_tmpdir 130 tempfile.tempdir = new_tmpdir
119 try: 131 try:
120 return callable(*args, **kargs) 132 return callable(*args, **kargs)
121 finally: 133 finally:
122 try: 134 try:
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 """starts an interactive shell so that the user can inspect errors 183 """starts an interactive shell so that the user can inspect errors
172 """ 184 """
173 debuggers = result.debuggers 185 debuggers = result.debuggers
174 descrs = result.error_descrs + result.fail_descrs 186 descrs = result.error_descrs + result.fail_descrs
175 if len(debuggers) == 1: 187 if len(debuggers) == 1:
176 # don't ask for test name if there's only one failure 188 # don't ask for test name if there's only one failure
177 debuggers[0].start() 189 debuggers[0].start()
178 else: 190 else:
179 while True: 191 while True:
180 testindex = 0 192 testindex = 0
181 print("Choose a test to debug:") 193 print "Choose a test to debug:"
182 # order debuggers in the same way than errors were printed 194 # order debuggers in the same way than errors were printed
183 print("\n".join(['\t%s : %s' % (i, descr) for i, (_, descr) 195 print "\n".join(['\t%s : %s' % (i, descr) for i, (_, descr)
184 in enumerate(descrs)])) 196 in enumerate(descrs)])
185 print("Type 'exit' (or ^D) to quit") 197 print "Type 'exit' (or ^D) to quit"
186 print() 198 print
187 try: 199 try:
188 todebug = input('Enter a test name: ') 200 todebug = raw_input('Enter a test name: ')
189 if todebug.strip().lower() == 'exit': 201 if todebug.strip().lower() == 'exit':
190 print() 202 print
191 break 203 break
192 else: 204 else:
193 try: 205 try:
194 testindex = int(todebug) 206 testindex = int(todebug)
195 debugger = debuggers[descrs[testindex][0]] 207 debugger = debuggers[descrs[testindex][0]]
196 except (ValueError, IndexError): 208 except (ValueError, IndexError):
197 print("ERROR: invalid test number %r" % (todebug, )) 209 print "ERROR: invalid test number %r" % (todebug, )
198 else: 210 else:
199 debugger.start() 211 debugger.start()
200 except (EOFError, KeyboardInterrupt): 212 except (EOFError, KeyboardInterrupt):
201 print() 213 print
202 break 214 break
203 215
204 216
205 # test utils ################################################################## 217 # test utils ##################################################################
206 218
207 class SkipAwareTestResult(unittest._TextTestResult): 219 class SkipAwareTestResult(unittest._TextTestResult):
208 220
209 def __init__(self, stream, descriptions, verbosity, 221 def __init__(self, stream, descriptions, verbosity,
210 exitfirst=False, pdbmode=False, cvg=None, colorize=False): 222 exitfirst=False, pdbmode=False, cvg=None, colorize=False):
211 super(SkipAwareTestResult, self).__init__(stream, 223 super(SkipAwareTestResult, self).__init__(stream,
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 # add testlib specific deprecation warning and switch to new api 357 # add testlib specific deprecation warning and switch to new api
346 if hasattr(module, 'teardown_module'): 358 if hasattr(module, 'teardown_module'):
347 warnings.warn('Please rename teardown_module() to tearDownModule() inste ad.', 359 warnings.warn('Please rename teardown_module() to tearDownModule() inste ad.',
348 DeprecationWarning) 360 DeprecationWarning)
349 setattr(module, 'tearDownModule', module.teardown_module) 361 setattr(module, 'tearDownModule', module.teardown_module)
350 # end of monkey-patching 362 # end of monkey-patching
351 tearDownModule = getattr(module, 'tearDownModule', None) 363 tearDownModule = getattr(module, 'tearDownModule', None)
352 if tearDownModule is not None: 364 if tearDownModule is not None:
353 try: 365 try:
354 tearDownModule() 366 tearDownModule()
355 except Exception as e: 367 except Exception, e:
356 if isinstance(result, _DebugResult): 368 if isinstance(result, _DebugResult):
357 raise 369 raise
358 errorName = 'tearDownModule (%s)' % previousModule 370 errorName = 'tearDownModule (%s)' % previousModule
359 self._addClassOrModuleLevelException(result, e, errorName) 371 self._addClassOrModuleLevelException(result, e, errorName)
360 372
361 @monkeypatch(unittest.TestSuite) 373 @monkeypatch(unittest.TestSuite)
362 def _handleModuleFixture(self, test, result): 374 def _handleModuleFixture(self, test, result):
363 previousModule = self._get_previous_module(result) 375 previousModule = self._get_previous_module(result)
364 currentModule = test.__class__.__module__ 376 currentModule = test.__class__.__module__
365 if currentModule == previousModule: 377 if currentModule == previousModule:
366 return 378 return
367 self._handleModuleTearDown(result) 379 self._handleModuleTearDown(result)
368 result._moduleSetUpFailed = False 380 result._moduleSetUpFailed = False
369 try: 381 try:
370 module = sys.modules[currentModule] 382 module = sys.modules[currentModule]
371 except KeyError: 383 except KeyError:
372 return 384 return
373 # add testlib specific deprecation warning and switch to new api 385 # add testlib specific deprecation warning and switch to new api
374 if hasattr(module, 'setup_module'): 386 if hasattr(module, 'setup_module'):
375 warnings.warn('Please rename setup_module() to setUpModule() instead.', 387 warnings.warn('Please rename setup_module() to setUpModule() instead.',
376 DeprecationWarning) 388 DeprecationWarning)
377 setattr(module, 'setUpModule', module.setup_module) 389 setattr(module, 'setUpModule', module.setup_module)
378 # end of monkey-patching 390 # end of monkey-patching
379 setUpModule = getattr(module, 'setUpModule', None) 391 setUpModule = getattr(module, 'setUpModule', None)
380 if setUpModule is not None: 392 if setUpModule is not None:
381 try: 393 try:
382 setUpModule() 394 setUpModule()
383 except Exception as e: 395 except Exception, e:
384 if isinstance(result, _DebugResult): 396 if isinstance(result, _DebugResult):
385 raise 397 raise
386 result._moduleSetUpFailed = True 398 result._moduleSetUpFailed = True
387 errorName = 'setUpModule (%s)' % currentModule 399 errorName = 'setUpModule (%s)' % currentModule
388 self._addClassOrModuleLevelException(result, e, errorName) 400 self._addClassOrModuleLevelException(result, e, errorName)
389 401
390 # backward compatibility: TestSuite might be imported from lgc.testlib 402 # backward compatibility: TestSuite might be imported from lgc.testlib
391 TestSuite = unittest.TestSuite 403 TestSuite = unittest.TestSuite
392 404
393 class keywords(dict): 405 class keywords(dict):
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 441
430 return args, kwargs 442 return args, kwargs
431 443
432 444
433 class InnerTest(tuple): 445 class InnerTest(tuple):
434 def __new__(cls, name, *data): 446 def __new__(cls, name, *data):
435 instance = tuple.__new__(cls, data) 447 instance = tuple.__new__(cls, data)
436 instance.name = name 448 instance.name = name
437 return instance 449 return instance
438 450
439 class Tags(set): 451 class Tags(InheritableSet): # 2.4 compat
440 """A set of tag able validate an expression""" 452 """A set of tag able validate an expression"""
441 453
442 def __init__(self, *tags, **kwargs): 454 def __init__(self, *tags, **kwargs):
443 self.inherit = kwargs.pop('inherit', True) 455 self.inherit = kwargs.pop('inherit', True)
444 if kwargs: 456 if kwargs:
445 raise TypeError("%s are an invalid keyword argument for this function " % kwargs.keys()) 457 raise TypeError("%s are an invalid keyword argument for this function " % kwargs.keys())
446 458
447 if len(tags) == 1 and not isinstance(tags[0], string_types): 459 if len(tags) == 1 and not isinstance(tags[0], basestring):
448 tags = tags[0] 460 tags = tags[0]
449 super(Tags, self).__init__(tags, **kwargs) 461 super(Tags, self).__init__(tags, **kwargs)
450 462
451 def __getitem__(self, key): 463 def __getitem__(self, key):
452 return key in self 464 return key in self
453 465
454 def match(self, exp): 466 def match(self, exp):
455 return eval(exp, {}, self) 467 return eval(exp, {}, self)
456 468
457 469
458 # duplicate definition from unittest2 of the _deprecate decorator 470 # duplicate definition from unittest2 of the _deprecate decorator
459 def _deprecate(original_func): 471 def _deprecate(original_func):
460 def deprecated_func(*args, **kwargs): 472 def deprecated_func(*args, **kwargs):
461 warnings.warn( 473 warnings.warn(
462 ('Please use %s instead.' % original_func.__name__), 474 ('Please use %s instead.' % original_func.__name__),
463 DeprecationWarning, 2) 475 DeprecationWarning, 2)
464 return original_func(*args, **kwargs) 476 return original_func(*args, **kwargs)
465 return deprecated_func 477 return deprecated_func
466 478
467 class TestCase(unittest.TestCase): 479 class TestCase(unittest.TestCase):
468 """A unittest.TestCase extension with some additional methods.""" 480 """A unittest.TestCase extension with some additional methods."""
469 maxDiff = None 481 maxDiff = None
470 pdbclass = Debugger 482 pdbclass = Debugger
471 tags = Tags() 483 tags = Tags()
472 484
473 def __init__(self, methodName='runTest'): 485 def __init__(self, methodName='runTest'):
474 super(TestCase, self).__init__(methodName) 486 super(TestCase, self).__init__(methodName)
475 self.__exc_info = sys.exc_info 487 # internal API changed in python2.4 and needed by DocTestCase
476 self.__testMethodName = self._testMethodName 488 if sys.version_info >= (2, 4):
489 self.__exc_info = sys.exc_info
490 self.__testMethodName = self._testMethodName
491 else:
492 # let's give easier access to _testMethodName to every subclasses
493 if hasattr(self, "__testMethodName"):
494 self._testMethodName = self.__testMethodName
477 self._current_test_descr = None 495 self._current_test_descr = None
478 self._options_ = None 496 self._options_ = None
479 497
480 @classproperty 498 @classproperty
481 @cached 499 @cached
482 def datadir(cls): # pylint: disable=E0213 500 def datadir(cls): # pylint: disable=E0213
483 """helper attribute holding the standard test's data directory 501 """helper attribute holding the standard test's data directory
484 502
485 NOTE: this is a logilab's standard 503 NOTE: this is a logilab's standard
486 """ 504 """
(...skipping 21 matching lines...) Expand all
508 """ 526 """
509 if self._current_test_descr is not None: 527 if self._current_test_descr is not None:
510 return self._current_test_descr 528 return self._current_test_descr
511 return super(TestCase, self).shortDescription() 529 return super(TestCase, self).shortDescription()
512 530
513 def quiet_run(self, result, func, *args, **kwargs): 531 def quiet_run(self, result, func, *args, **kwargs):
514 try: 532 try:
515 func(*args, **kwargs) 533 func(*args, **kwargs)
516 except (KeyboardInterrupt, SystemExit): 534 except (KeyboardInterrupt, SystemExit):
517 raise 535 raise
518 except unittest.SkipTest as e:
519 if hasattr(result, 'addSkip'):
520 result.addSkip(self, str(e))
521 else:
522 warnings.warn("TestResult has no addSkip method, skips not repor ted",
523 RuntimeWarning, 2)
524 result.addSuccess(self)
525 return False
526 except: 536 except:
527 result.addError(self, self.__exc_info()) 537 result.addError(self, self.__exc_info())
528 return False 538 return False
529 return True 539 return True
530 540
531 def _get_test_method(self): 541 def _get_test_method(self):
532 """return the test method""" 542 """return the test method"""
533 return getattr(self, self._testMethodName) 543 return getattr(self, self._testMethodName)
534 544
535 def optval(self, option, default=None): 545 def optval(self, option, default=None):
536 """return the option value or default if the option is not define""" 546 """return the option value or default if the option is not define"""
537 return getattr(self._options_, option, default) 547 return getattr(self._options_, option, default)
538 548
539 def __call__(self, result=None, runcondition=None, options=None): 549 def __call__(self, result=None, runcondition=None, options=None):
540 """rewrite TestCase.__call__ to support generative tests 550 """rewrite TestCase.__call__ to support generative tests
541 This is mostly a copy/paste from unittest.py (i.e same 551 This is mostly a copy/paste from unittest.py (i.e same
542 variable names, same logic, except for the generative tests part) 552 variable names, same logic, except for the generative tests part)
543 """ 553 """
544 from logilab.common.pytest import FILE_RESTART 554 from logilab.common.pytest import FILE_RESTART
545 if result is None: 555 if result is None:
546 result = self.defaultTestResult() 556 result = self.defaultTestResult()
547 result.pdbclass = self.pdbclass 557 result.pdbclass = self.pdbclass
548 self._options_ = options 558 self._options_ = options
549 # if result.cvg: 559 # if result.cvg:
550 # result.cvg.start() 560 # result.cvg.start()
551 testMethod = self._get_test_method() 561 testMethod = self._get_test_method()
552 if (getattr(self.__class__, "__unittest_skip__", False) or
553 getattr(testMethod, "__unittest_skip__", False)):
554 # If the class or method was skipped.
555 try:
556 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
557 or getattr(testMethod, '__unittest_skip_why__', ''))
558 self._addSkip(result, skip_why)
559 finally:
560 result.stopTest(self)
561 return
562 if runcondition and not runcondition(testMethod): 562 if runcondition and not runcondition(testMethod):
563 return # test is skipped 563 return # test is skipped
564 result.startTest(self) 564 result.startTest(self)
565 try: 565 try:
566 if not self.quiet_run(result, self.setUp): 566 if not self.quiet_run(result, self.setUp):
567 return 567 return
568 generative = isgeneratorfunction(testMethod) 568 generative = is_generator(testMethod.im_func)
569 # generative tests 569 # generative tests
570 if generative: 570 if generative:
571 self._proceed_generative(result, testMethod, 571 self._proceed_generative(result, testMethod,
572 runcondition) 572 runcondition)
573 else: 573 else:
574 status = self._proceed(result, testMethod) 574 status = self._proceed(result, testMethod)
575 success = (status == 0) 575 success = (status == 0)
576 if not self.quiet_run(result, self.tearDown): 576 if not self.quiet_run(result, self.tearDown):
577 return 577 return
578 if not generative and success: 578 if not generative and success:
579 if hasattr(options, "exitfirst") and options.exitfirst: 579 if hasattr(options, "exitfirst") and options.exitfirst:
580 # add this test to restart file 580 # add this test to restart file
581 try: 581 try:
582 restartfile = open(FILE_RESTART, 'a') 582 restartfile = open(FILE_RESTART, 'a')
583 try: 583 try:
584 descr = '.'.join((self.__class__.__module__, 584 descr = '.'.join((self.__class__.__module__,
585 self.__class__.__name__, 585 self.__class__.__name__,
586 self._testMethodName)) 586 self._testMethodName))
587 restartfile.write(descr+os.linesep) 587 restartfile.write(descr+os.linesep)
588 finally: 588 finally:
589 restartfile.close() 589 restartfile.close()
590 except Exception: 590 except Exception, ex:
591 print("Error while saving succeeded test into", 591 print >> sys.__stderr__, "Error while saving \
592 osp.join(os.getcwd(), FILE_RESTART), 592 succeeded test into", osp.join(os.getcwd(), FILE_RESTART)
593 file=sys.__stderr__) 593 raise ex
594 raise
595 result.addSuccess(self) 594 result.addSuccess(self)
596 finally: 595 finally:
597 # if result.cvg: 596 # if result.cvg:
598 # result.cvg.stop() 597 # result.cvg.stop()
599 result.stopTest(self) 598 result.stopTest(self)
600 599
601 def _proceed_generative(self, result, testfunc, runcondition=None): 600 def _proceed_generative(self, result, testfunc, runcondition=None):
602 # cancel startTest()'s increment 601 # cancel startTest()'s increment
603 result.testsRun -= 1 602 result.testsRun -= 1
604 success = True 603 success = True
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 successful 640 successful
642 """ 641 """
643 kwargs = kwargs or {} 642 kwargs = kwargs or {}
644 try: 643 try:
645 testfunc(*args, **kwargs) 644 testfunc(*args, **kwargs)
646 except self.failureException: 645 except self.failureException:
647 result.addFailure(self, self.__exc_info()) 646 result.addFailure(self, self.__exc_info())
648 return 1 647 return 1
649 except KeyboardInterrupt: 648 except KeyboardInterrupt:
650 raise 649 raise
651 except InnerTestSkipped as e: 650 except InnerTestSkipped, e:
652 result.addSkip(self, e) 651 result.addSkip(self, e)
653 return 1 652 return 1
654 except SkipTest as e: 653 except SkipTest, e:
655 result.addSkip(self, e) 654 result.addSkip(self, e)
656 return 0 655 return 0
657 except: 656 except:
658 result.addError(self, self.__exc_info()) 657 result.addError(self, self.__exc_info())
659 return 2 658 return 2
660 return 0 659 return 0
661 660
662 def defaultTestResult(self): 661 def defaultTestResult(self):
663 """return a new instance of the defaultTestResult""" 662 """return a new instance of the defaultTestResult"""
664 return SkipAwareTestResult() 663 return SkipAwareTestResult()
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 msgs.append('dict2 is lacking %r' % dict1) 697 msgs.append('dict2 is lacking %r' % dict1)
699 if msg: 698 if msg:
700 self.failureException(msg) 699 self.failureException(msg)
701 elif msgs: 700 elif msgs:
702 if context is not None: 701 if context is not None:
703 base = '%s\n' % context 702 base = '%s\n' % context
704 else: 703 else:
705 base = '' 704 base = ''
706 self.fail(base + '\n'.join(msgs)) 705 self.fail(base + '\n'.join(msgs))
707 706
708 @deprecated('Please use assertCountEqual instead.') 707 @deprecated('Please use assertItemsEqual instead.')
709 def assertUnorderedIterableEquals(self, got, expected, msg=None): 708 def assertUnorderedIterableEquals(self, got, expected, msg=None):
710 """compares two iterable and shows difference between both 709 """compares two iterable and shows difference between both
711 710
712 :param got: the unordered Iterable that we found 711 :param got: the unordered Iterable that we found
713 :param expected: the expected unordered Iterable 712 :param expected: the expected unordered Iterable
714 :param msg: custom message (String) in case of failure 713 :param msg: custom message (String) in case of failure
715 """ 714 """
716 got, expected = list(got), list(expected) 715 got, expected = list(got), list(expected)
717 self.assertSetEqual(set(got), set(expected), msg) 716 self.assertSetEqual(set(got), set(expected), msg)
718 if len(got) != len(expected): 717 if len(got) != len(expected):
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 Only available with element tree 819 Only available with element tree
821 """ 820 """
822 try: 821 try:
823 from xml.etree.ElementTree import parse 822 from xml.etree.ElementTree import parse
824 self._assertETXMLWellFormed(stream, parse, msg) 823 self._assertETXMLWellFormed(stream, parse, msg)
825 except ImportError: 824 except ImportError:
826 from xml.sax import make_parser, SAXParseException 825 from xml.sax import make_parser, SAXParseException
827 parser = make_parser() 826 parser = make_parser()
828 try: 827 try:
829 parser.parse(stream) 828 parser.parse(stream)
830 except SAXParseException as ex: 829 except SAXParseException, ex:
831 if msg is None: 830 if msg is None:
832 stream.seek(0) 831 stream.seek(0)
833 for _ in range(ex.getLineNumber()): 832 for _ in xrange(ex.getLineNumber()):
834 line = stream.readline() 833 line = stream.readline()
835 pointer = ('' * (ex.getLineNumber() - 1)) + '^' 834 pointer = ('' * (ex.getLineNumber() - 1)) + '^'
836 msg = 'XML stream not well formed: %s\n%s%s' % (ex, line, po inter) 835 msg = 'XML stream not well formed: %s\n%s%s' % (ex, line, po inter)
837 self.fail(msg) 836 self.fail(msg)
838 837
839 @deprecated('Non-standard: please copy test method to your TestCase class') 838 @deprecated('Non-standard: please copy test method to your TestCase class')
840 def assertXMLStringWellFormed(self, xml_string, msg=None, context=2): 839 def assertXMLStringWellFormed(self, xml_string, msg=None, context=2):
841 """asserts the XML string is well-formed (no DTD conformance check) 840 """asserts the XML string is well-formed (no DTD conformance check)
842 841
843 :param context: number of context lines in standard message 842 :param context: number of context lines in standard message
(...skipping 17 matching lines...) Expand all
861 Only available with element tree 860 Only available with element tree
862 """ 861 """
863 from xml.parsers.expat import ExpatError 862 from xml.parsers.expat import ExpatError
864 try: 863 try:
865 from xml.etree.ElementTree import ParseError 864 from xml.etree.ElementTree import ParseError
866 except ImportError: 865 except ImportError:
867 # compatibility for <python2.7 866 # compatibility for <python2.7
868 ParseError = ExpatError 867 ParseError = ExpatError
869 try: 868 try:
870 parse(data) 869 parse(data)
871 except (ExpatError, ParseError) as ex: 870 except (ExpatError, ParseError), ex:
872 if msg is None: 871 if msg is None:
873 if hasattr(data, 'readlines'): #file like object 872 if hasattr(data, 'readlines'): #file like object
874 data.seek(0) 873 data.seek(0)
875 lines = data.readlines() 874 lines = data.readlines()
876 else: 875 else:
877 lines = data.splitlines(True) 876 lines = data.splitlines(True)
878 nb_lines = len(lines) 877 nb_lines = len(lines)
879 context_lines = [] 878 context_lines = []
880 879
881 # catch when ParseError doesn't set valid lineno 880 # catch when ParseError doesn't set valid lineno
882 if ex.lineno is not None: 881 if ex.lineno is not None:
883 if context < 0: 882 if context < 0:
884 start = 1 883 start = 1
885 end = nb_lines 884 end = nb_lines
886 else: 885 else:
887 start = max(ex.lineno-context, 1) 886 start = max(ex.lineno-context, 1)
888 end = min(ex.lineno+context, nb_lines) 887 end = min(ex.lineno+context, nb_lines)
889 line_number_length = len('%i' % end) 888 line_number_length = len('%i' % end)
890 line_pattern = " %%%ii: %%s" % line_number_length 889 line_pattern = " %%%ii: %%s" % line_number_length
891 890
892 for line_no in range(start, ex.lineno): 891 for line_no in xrange(start, ex.lineno):
893 context_lines.append(line_pattern % (line_no, lines[line _no-1])) 892 context_lines.append(line_pattern % (line_no, lines[line _no-1]))
894 context_lines.append(line_pattern % (ex.lineno, lines[ex.lin eno-1])) 893 context_lines.append(line_pattern % (ex.lineno, lines[ex.lin eno-1]))
895 context_lines.append('%s^\n' % (' ' * (1 + line_number_lengt h + 2 +ex.offset))) 894 context_lines.append('%s^\n' % (' ' * (1 + line_number_lengt h + 2 +ex.offset)))
896 for line_no in range(ex.lineno+1, end+1): 895 for line_no in xrange(ex.lineno+1, end+1):
897 context_lines.append(line_pattern % (line_no, lines[line _no-1])) 896 context_lines.append(line_pattern % (line_no, lines[line _no-1]))
898 897
899 rich_context = ''.join(context_lines) 898 rich_context = ''.join(context_lines)
900 msg = 'XML stream not well formed: %s\n%s' % (ex, rich_context) 899 msg = 'XML stream not well formed: %s\n%s' % (ex, rich_context)
901 self.fail(msg) 900 self.fail(msg)
902 901
903 @deprecated('Non-standard: please copy test method to your TestCase class') 902 @deprecated('Non-standard: please copy test method to your TestCase class')
904 def assertXMLEqualsTuple(self, element, tup): 903 def assertXMLEqualsTuple(self, element, tup):
905 """compare an ElementTree Element to a tuple formatted as follow: 904 """compare an ElementTree Element to a tuple formatted as follow:
906 (tagname, [attrib[, children[, text[, tail]]]])""" 905 (tagname, [attrib[, children[, text[, tail]]]])"""
907 # check tag 906 # check tag
908 self.assertTextEquals(element.tag, tup[0]) 907 self.assertTextEquals(element.tag, tup[0])
909 # check attrib 908 # check attrib
910 if len(element.attrib) or len(tup)>1: 909 if len(element.attrib) or len(tup)>1:
911 if len(tup)<=1: 910 if len(tup)<=1:
912 self.fail( "tuple %s has no attributes (%s expected)"%(tup, 911 self.fail( "tuple %s has no attributes (%s expected)"%(tup,
913 dict(element.attrib))) 912 dict(element.attrib)))
914 self.assertDictEqual(element.attrib, tup[1]) 913 self.assertDictEqual(element.attrib, tup[1])
915 # check children 914 # check children
916 if len(element) or len(tup)>2: 915 if len(element) or len(tup)>2:
917 if len(tup)<=2: 916 if len(tup)<=2:
918 self.fail( "tuple %s has no children (%i expected)"%(tup, 917 self.fail( "tuple %s has no children (%i expected)"%(tup,
919 len(element))) 918 len(element)))
920 if len(element) != len(tup[2]): 919 if len(element) != len(tup[2]):
921 self.fail( "tuple %s has %i children%s (%i expected)"%(tup, 920 self.fail( "tuple %s has %i children%s (%i expected)"%(tup,
922 len(tup[2]), 921 len(tup[2]),
923 ('', 's')[len(tup[2])>1], len(element))) 922 ('', 's')[len(tup[2])>1], len(element)))
924 for index in range(len(tup[2])): 923 for index in xrange(len(tup[2])):
925 self.assertXMLEqualsTuple(element[index], tup[2][index]) 924 self.assertXMLEqualsTuple(element[index], tup[2][index])
926 #check text 925 #check text
927 if element.text or len(tup)>3: 926 if element.text or len(tup)>3:
928 if len(tup)<=3: 927 if len(tup)<=3:
929 self.fail( "tuple %s has no text value (%r expected)"%(tup, 928 self.fail( "tuple %s has no text value (%r expected)"%(tup,
930 element.text)) 929 element.text))
931 self.assertTextEquals(element.text, tup[3]) 930 self.assertTextEquals(element.text, tup[3])
932 #check tail 931 #check tail
933 if element.tail or len(tup)>4: 932 if element.tail or len(tup)>4:
934 if len(tup)<=4: 933 if len(tup)<=4:
935 self.fail( "tuple %s has no tail value (%r expected)"%(tup, 934 self.fail( "tuple %s has no tail value (%r expected)"%(tup,
936 element.tail)) 935 element.tail))
937 self.assertTextEquals(element.tail, tup[4]) 936 self.assertTextEquals(element.tail, tup[4])
938 937
939 def _difftext(self, lines1, lines2, junk=None, msg_prefix='Texts differ'): 938 def _difftext(self, lines1, lines2, junk=None, msg_prefix='Texts differ'):
940 junk = junk or (' ', '\t') 939 junk = junk or (' ', '\t')
941 # result is a generator 940 # result is a generator
942 result = difflib.ndiff(lines1, lines2, charjunk=lambda x: x in junk) 941 result = difflib.ndiff(lines1, lines2, charjunk=lambda x: x in junk)
943 read = [] 942 read = []
944 for line in result: 943 for line in result:
945 read.append(line) 944 read.append(line)
946 # lines that don't start with a ' ' are diff ones 945 # lines that don't start with a ' ' are diff ones
947 if not line.startswith(' '): 946 if not line.startswith(' '):
948 self.fail('\n'.join(['%s\n'%msg_prefix]+read + list(result))) 947 self.fail('\n'.join(['%s\n'%msg_prefix]+read + list(result)))
949 948
950 @deprecated('Non-standard. Please use assertMultiLineEqual instead.') 949 @deprecated('Non-standard. Please use assertMultiLineEqual instead.')
951 def assertTextEquals(self, text1, text2, junk=None, 950 def assertTextEquals(self, text1, text2, junk=None,
952 msg_prefix='Text differ', striplines=False): 951 msg_prefix='Text differ', striplines=False):
953 """compare two multiline strings (using difflib and splitlines()) 952 """compare two multiline strings (using difflib and splitlines())
954 953
955 :param text1: a Python BaseString 954 :param text1: a Python BaseString
956 :param text2: a second Python Basestring 955 :param text2: a second Python Basestring
957 :param junk: List of Caracters 956 :param junk: List of Caracters
958 :param msg_prefix: String (message prefix) 957 :param msg_prefix: String (message prefix)
959 :param striplines: Boolean to trigger line stripping before comparing 958 :param striplines: Boolean to trigger line stripping before comparing
960 """ 959 """
961 msg = [] 960 msg = []
962 if not isinstance(text1, string_types): 961 if not isinstance(text1, basestring):
963 msg.append('text1 is not a string (%s)'%(type(text1))) 962 msg.append('text1 is not a string (%s)'%(type(text1)))
964 if not isinstance(text2, string_types): 963 if not isinstance(text2, basestring):
965 msg.append('text2 is not a string (%s)'%(type(text2))) 964 msg.append('text2 is not a string (%s)'%(type(text2)))
966 if msg: 965 if msg:
967 self.fail('\n'.join(msg)) 966 self.fail('\n'.join(msg))
968 lines1 = text1.strip().splitlines(True) 967 lines1 = text1.strip().splitlines(True)
969 lines2 = text2.strip().splitlines(True) 968 lines2 = text2.strip().splitlines(True)
970 if striplines: 969 if striplines:
971 lines1 = [line.strip() for line in lines1] 970 lines1 = [line.strip() for line in lines1]
972 lines2 = [line.strip() for line in lines2] 971 lines2 = [line.strip() for line in lines2]
973 self._difftext(lines1, lines2, junk, msg_prefix) 972 self._difftext(lines1, lines2, junk, msg_prefix)
974 assertTextEqual = assertTextEquals 973 assertTextEqual = assertTextEquals
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 1009
1011 all_b = [ (ipath[len(path_b):].lstrip('/'), idirs, ifiles) 1010 all_b = [ (ipath[len(path_b):].lstrip('/'), idirs, ifiles)
1012 for ipath, idirs, ifiles in os.walk(path_b)] 1011 for ipath, idirs, ifiles in os.walk(path_b)]
1013 all_b.sort(key=itemgetter(0)) 1012 all_b.sort(key=itemgetter(0))
1014 1013
1015 iter_a, iter_b = iter(all_a), iter(all_b) 1014 iter_a, iter_b = iter(all_a), iter(all_b)
1016 partial_iter = True 1015 partial_iter = True
1017 ipath_a, idirs_a, ifiles_a = data_a = None, None, None 1016 ipath_a, idirs_a, ifiles_a = data_a = None, None, None
1018 while True: 1017 while True:
1019 try: 1018 try:
1020 ipath_a, idirs_a, ifiles_a = datas_a = next(iter_a) 1019 ipath_a, idirs_a, ifiles_a = datas_a = iter_a.next()
1021 partial_iter = False 1020 partial_iter = False
1022 ipath_b, idirs_b, ifiles_b = datas_b = next(iter_b) 1021 ipath_b, idirs_b, ifiles_b = datas_b = iter_b.next()
1023 partial_iter = True 1022 partial_iter = True
1024 1023
1025 1024
1026 self.assertTrue(ipath_a == ipath_b, 1025 self.assert_(ipath_a == ipath_b,
1027 "unexpected %s in %s while looking %s from %s" % 1026 "unexpected %s in %s while looking %s from %s" %
1028 (ipath_a, path_a, ipath_b, path_b)) 1027 (ipath_a, path_a, ipath_b, path_b))
1029 1028
1030 1029
1031 errors = {} 1030 errors = {}
1032 sdirs_a = set(idirs_a) 1031 sdirs_a = set(idirs_a)
1033 sdirs_b = set(idirs_b) 1032 sdirs_b = set(idirs_b)
1034 errors["unexpected directories"] = sdirs_a - sdirs_b 1033 errors["unexpected directories"] = sdirs_a - sdirs_b
1035 errors["missing directories"] = sdirs_b - sdirs_a 1034 errors["missing directories"] = sdirs_b - sdirs_a
1036 1035
1037 sfiles_a = set(ifiles_a) 1036 sfiles_a = set(ifiles_a)
1038 sfiles_b = set(ifiles_b) 1037 sfiles_b = set(ifiles_b)
1039 errors["unexpected files"] = sfiles_a - sfiles_b 1038 errors["unexpected files"] = sfiles_a - sfiles_b
1040 errors["missing files"] = sfiles_b - sfiles_a 1039 errors["missing files"] = sfiles_b - sfiles_a
1041 1040
1042 1041
1043 msgs = [ "%s: %s"% (name, items) 1042 msgs = [ "%s: %s"% (name, items)
1044 for name, items in errors.items() if items] 1043 for name, items in errors.iteritems() if items]
1045 1044
1046 if msgs: 1045 if msgs:
1047 msgs.insert(0, "%s and %s differ :" % ( 1046 msgs.insert(0, "%s and %s differ :" % (
1048 osp.join(path_a, ipath_a), 1047 osp.join(path_a, ipath_a),
1049 osp.join(path_b, ipath_b), 1048 osp.join(path_b, ipath_b),
1050 )) 1049 ))
1051 self.fail("\n".join(msgs)) 1050 self.fail("\n".join(msgs))
1052 1051
1053 for files in (ifiles_a, ifiles_b): 1052 for files in (ifiles_a, ifiles_b):
1054 files.sort() 1053 files.sort()
(...skipping 19 matching lines...) Expand all
1074 if strict: 1073 if strict:
1075 warnings.warn('[API] Non-standard. Strict parameter has vanished', 1074 warnings.warn('[API] Non-standard. Strict parameter has vanished',
1076 DeprecationWarning, stacklevel=2) 1075 DeprecationWarning, stacklevel=2)
1077 if msg is None: 1076 if msg is None:
1078 if strict: 1077 if strict:
1079 msg = '%r is not of class %s but of %s' 1078 msg = '%r is not of class %s but of %s'
1080 else: 1079 else:
1081 msg = '%r is not an instance of %s but of %s' 1080 msg = '%r is not an instance of %s but of %s'
1082 msg = msg % (obj, klass, type(obj)) 1081 msg = msg % (obj, klass, type(obj))
1083 if strict: 1082 if strict:
1084 self.assertTrue(obj.__class__ is klass, msg) 1083 self.assert_(obj.__class__ is klass, msg)
1085 else: 1084 else:
1086 self.assertTrue(isinstance(obj, klass), msg) 1085 self.assert_(isinstance(obj, klass), msg)
1087 1086
1088 @deprecated('Please use assertIsNone instead.') 1087 @deprecated('Please use assertIsNone instead.')
1089 def assertNone(self, obj, msg=None): 1088 def assertNone(self, obj, msg=None):
1090 """assert obj is None 1089 """assert obj is None
1091 1090
1092 :param obj: Python Object to be tested 1091 :param obj: Python Object to be tested
1093 """ 1092 """
1094 if msg is None: 1093 if msg is None:
1095 msg = "reference to %r when None expected"%(obj,) 1094 msg = "reference to %r when None expected"%(obj,)
1096 self.assertTrue( obj is None, msg ) 1095 self.assert_( obj is None, msg )
1097 1096
1098 @deprecated('Please use assertIsNotNone instead.') 1097 @deprecated('Please use assertIsNotNone instead.')
1099 def assertNotNone(self, obj, msg=None): 1098 def assertNotNone(self, obj, msg=None):
1100 """assert obj is not None""" 1099 """assert obj is not None"""
1101 if msg is None: 1100 if msg is None:
1102 msg = "unexpected reference to None" 1101 msg = "unexpected reference to None"
1103 self.assertTrue( obj is not None, msg ) 1102 self.assert_( obj is not None, msg )
1104 1103
1105 @deprecated('Non-standard. Please use assertAlmostEqual instead.') 1104 @deprecated('Non-standard. Please use assertAlmostEqual instead.')
1106 def assertFloatAlmostEquals(self, obj, other, prec=1e-5, 1105 def assertFloatAlmostEquals(self, obj, other, prec=1e-5,
1107 relative=False, msg=None): 1106 relative=False, msg=None):
1108 """compares if two floats have a distance smaller than expected 1107 """compares if two floats have a distance smaller than expected
1109 precision. 1108 precision.
1110 1109
1111 :param obj: a Float 1110 :param obj: a Float
1112 :param other: another Float to be comparted to <obj> 1111 :param other: another Float to be comparted to <obj>
1113 :param prec: a Float describing the precision 1112 :param prec: a Float describing the precision
1114 :param relative: boolean switching to relative/absolute precision 1113 :param relative: boolean switching to relative/absolute precision
1115 :param msg: a String for a custom message 1114 :param msg: a String for a custom message
1116 """ 1115 """
1117 if msg is None: 1116 if msg is None:
1118 msg = "%r != %r" % (obj, other) 1117 msg = "%r != %r" % (obj, other)
1119 if relative: 1118 if relative:
1120 prec = prec*math.fabs(obj) 1119 prec = prec*math.fabs(obj)
1121 self.assertTrue(math.fabs(obj - other) < prec, msg) 1120 self.assert_(math.fabs(obj - other) < prec, msg)
1122 1121
1123 def failUnlessRaises(self, excClass, callableObj=None, *args, **kwargs): 1122 def failUnlessRaises(self, excClass, callableObj=None, *args, **kwargs):
1124 """override default failUnlessRaises method to return the raised 1123 """override default failUnlessRaises method to return the raised
1125 exception instance. 1124 exception instance.
1126 1125
1127 Fail unless an exception of class excClass is thrown 1126 Fail unless an exception of class excClass is thrown
1128 by callableObj when invoked with arguments args and keyword 1127 by callableObj when invoked with arguments args and keyword
1129 arguments kwargs. If a different type of exception is 1128 arguments kwargs. If a different type of exception is
1130 thrown, it will not be caught, and the test case will be 1129 thrown, it will not be caught, and the test case will be
1131 deemed to have suffered an error, exactly as for an 1130 deemed to have suffered an error, exactly as for an
1132 unexpected exception. 1131 unexpected exception.
1133 1132
1134 CAUTION! There are subtle differences between Logilab and unittest2 1133 CAUTION! There are subtle differences between Logilab and unittest2
1135 - exc is not returned in standard version 1134 - exc is not returned in standard version
1136 - context capabilities in standard version 1135 - context capabilities in standard version
1137 - try/except/else construction (minor) 1136 - try/except/else construction (minor)
1138 1137
1139 :param excClass: the Exception to be raised 1138 :param excClass: the Exception to be raised
1140 :param callableObj: a callable Object which should raise <excClass> 1139 :param callableObj: a callable Object which should raise <excClass>
1141 :param args: a List of arguments for <callableObj> 1140 :param args: a List of arguments for <callableObj>
1142 :param kwargs: a List of keyword arguments for <callableObj> 1141 :param kwargs: a List of keyword arguments for <callableObj>
1143 """ 1142 """
1144 # XXX cube vcslib : test_branches_from_app 1143 # XXX cube vcslib : test_branches_from_app
1145 if callableObj is None: 1144 if callableObj is None:
1146 _assert = super(TestCase, self).assertRaises 1145 _assert = super(TestCase, self).assertRaises
1147 return _assert(excClass, callableObj, *args, **kwargs) 1146 return _assert(excClass, callableObj, *args, **kwargs)
1148 try: 1147 try:
1149 callableObj(*args, **kwargs) 1148 callableObj(*args, **kwargs)
1150 except excClass as exc: 1149 except excClass, exc:
1151 class ProxyException: 1150 class ProxyException:
1152 def __init__(self, obj): 1151 def __init__(self, obj):
1153 self._obj = obj 1152 self._obj = obj
1154 def __getattr__(self, attr): 1153 def __getattr__(self, attr):
1155 warn_msg = ("This exception was retrieved with the old testl ib way " 1154 warn_msg = ("This exception was retrieved with the old testl ib way "
1156 "`exc = self.assertRaises(Exc, callable)`, pleas e use " 1155 "`exc = self.assertRaises(Exc, callable)`, pleas e use "
1157 "the context manager instead'") 1156 "the context manager instead'")
1158 warnings.warn(warn_msg, DeprecationWarning, 2) 1157 warnings.warn(warn_msg, DeprecationWarning, 2)
1159 return self._obj.__getattribute__(attr) 1158 return self._obj.__getattribute__(attr)
1160 return ProxyException(exc) 1159 return ProxyException(exc)
1161 else: 1160 else:
1162 if hasattr(excClass, '__name__'): 1161 if hasattr(excClass, '__name__'):
1163 excName = excClass.__name__ 1162 excName = excClass.__name__
1164 else: 1163 else:
1165 excName = str(excClass) 1164 excName = str(excClass)
1166 raise self.failureException("%s not raised" % excName) 1165 raise self.failureException("%s not raised" % excName)
1167 1166
1168 assertRaises = failUnlessRaises 1167 assertRaises = failUnlessRaises
1169 1168
1170 if sys.version_info >= (3,2):
1171 assertItemsEqual = unittest.TestCase.assertCountEqual
1172 else:
1173 assertCountEqual = unittest.TestCase.assertItemsEqual
1174 if sys.version_info < (2,7):
1175 def assertIsNotNone(self, value, *args, **kwargs):
1176 self.assertNotEqual(None, value, *args, **kwargs)
1177
1178 TestCase.assertItemsEqual = deprecated('assertItemsEqual is deprecated, use asse rtCountEqual')(
1179 TestCase.assertItemsEqual)
1180 1169
1181 import doctest 1170 import doctest
1182 1171
1183 class SkippedSuite(unittest.TestSuite): 1172 class SkippedSuite(unittest.TestSuite):
1184 def test(self): 1173 def test(self):
1185 """just there to trigger test execution""" 1174 """just there to trigger test execution"""
1186 self.skipped_test('doctest module has no DocTestSuite class') 1175 self.skipped_test('doctest module has no DocTestSuite class')
1187 1176
1188 1177
1189 class DocTestFinder(doctest.DocTestFinder): 1178 class DocTestFinder(doctest.DocTestFinder):
1190 1179
1191 def __init__(self, *args, **kwargs): 1180 def __init__(self, *args, **kwargs):
1192 self.skipped = kwargs.pop('skipped', ()) 1181 self.skipped = kwargs.pop('skipped', ())
1193 doctest.DocTestFinder.__init__(self, *args, **kwargs) 1182 doctest.DocTestFinder.__init__(self, *args, **kwargs)
1194 1183
1195 def _get_test(self, obj, name, module, globs, source_lines): 1184 def _get_test(self, obj, name, module, globs, source_lines):
1196 """override default _get_test method to be able to skip tests 1185 """override default _get_test method to be able to skip tests
1197 according to skipped attribute's value 1186 according to skipped attribute's value
1187
1188 Note: Python (<=2.4) use a _name_filter which could be used for that
1189 purpose but it's no longer available in 2.5
1190 Python 2.5 seems to have a [SKIP] flag
1198 """ 1191 """
1199 if getattr(obj, '__name__', '') in self.skipped: 1192 if getattr(obj, '__name__', '') in self.skipped:
1200 return None 1193 return None
1201 return doctest.DocTestFinder._get_test(self, obj, name, module, 1194 return doctest.DocTestFinder._get_test(self, obj, name, module,
1202 globs, source_lines) 1195 globs, source_lines)
1203 1196
1204 1197
1205 class DocTest(TestCase): 1198 class DocTest(TestCase):
1206 """trigger module doctest 1199 """trigger module doctest
1207 I don't know how to make unittest.main consider the DocTestSuite instance 1200 I don't know how to make unittest.main consider the DocTestSuite instance
1208 without this hack 1201 without this hack
1209 """ 1202 """
1210 skipped = () 1203 skipped = ()
1211 def __call__(self, result=None, runcondition=None, options=None):\ 1204 def __call__(self, result=None, runcondition=None, options=None):\
1212 # pylint: disable=W0613 1205 # pylint: disable=W0613
1213 try: 1206 try:
1214 finder = DocTestFinder(skipped=self.skipped) 1207 finder = DocTestFinder(skipped=self.skipped)
1215 suite = doctest.DocTestSuite(self.module, test_finder=finder) 1208 if sys.version_info >= (2, 4):
1216 # XXX iirk 1209 suite = doctest.DocTestSuite(self.module, test_finder=finder)
1217 doctest.DocTestCase._TestCase__exc_info = sys.exc_info 1210 if sys.version_info >= (2, 5):
1211 # XXX iirk
1212 doctest.DocTestCase._TestCase__exc_info = sys.exc_info
1213 else:
1214 suite = doctest.DocTestSuite(self.module)
1218 except AttributeError: 1215 except AttributeError:
1219 suite = SkippedSuite() 1216 suite = SkippedSuite()
1220 # doctest may gork the builtins dictionnary 1217 return suite.run(result)
1221 # This happen to the "_" entry used by gettext
1222 old_builtins = builtins.__dict__.copy()
1223 try:
1224 return suite.run(result)
1225 finally:
1226 builtins.__dict__.clear()
1227 builtins.__dict__.update(old_builtins)
1228 run = __call__ 1218 run = __call__
1229 1219
1230 def test(self): 1220 def test(self):
1231 """just there to trigger test execution""" 1221 """just there to trigger test execution"""
1232 1222
1233 MAILBOX = None 1223 MAILBOX = None
1234 1224
1235 class MockSMTP: 1225 class MockSMTP:
1236 """fake smtplib.SMTP""" 1226 """fake smtplib.SMTP"""
1237 1227
1238 def __init__(self, host, port): 1228 def __init__(self, host, port):
1239 self.host = host 1229 self.host = host
1240 self.port = port 1230 self.port = port
1241 global MAILBOX 1231 global MAILBOX
1242 self.reveived = MAILBOX = [] 1232 self.reveived = MAILBOX = []
1243 1233
1244 def set_debuglevel(self, debuglevel): 1234 def set_debuglevel(self, debuglevel):
1245 """ignore debug level""" 1235 """ignore debug level"""
1246 1236
1247 def sendmail(self, fromaddr, toaddres, body): 1237 def sendmail(self, fromaddr, toaddres, body):
1248 """push sent mail in the mailbox""" 1238 """push sent mail in the mailbox"""
1249 self.reveived.append((fromaddr, toaddres, body)) 1239 self.reveived.append((fromaddr, toaddres, body))
1250 1240
1251 def quit(self): 1241 def quit(self):
1252 """ignore quit""" 1242 """ignore quit"""
1253 1243
1254 1244
1255 class MockConfigParser(configparser.ConfigParser): 1245 class MockConfigParser(ConfigParser):
1256 """fake ConfigParser.ConfigParser""" 1246 """fake ConfigParser.ConfigParser"""
1257 1247
1258 def __init__(self, options): 1248 def __init__(self, options):
1259 configparser.ConfigParser.__init__(self) 1249 ConfigParser.__init__(self)
1260 for section, pairs in options.iteritems(): 1250 for section, pairs in options.iteritems():
1261 self.add_section(section) 1251 self.add_section(section)
1262 for key, value in pairs.iteritems(): 1252 for key, value in pairs.iteritems():
1263 self.set(section, key, value) 1253 self.set(section, key, value)
1264 def write(self, _): 1254 def write(self, _):
1265 raise NotImplementedError() 1255 raise NotImplementedError()
1266 1256
1267 1257
1268 class MockConnection: 1258 class MockConnection:
1269 """fake DB-API 2.0 connexion AND cursor (i.e. cursor() return self)""" 1259 """fake DB-API 2.0 connexion AND cursor (i.e. cursor() return self)"""
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 try: 1373 try:
1384 __import__(module) 1374 __import__(module)
1385 return f 1375 return f
1386 except ImportError: 1376 except ImportError:
1387 def new_f(self, *args, **kwargs): 1377 def new_f(self, *args, **kwargs):
1388 self.skipTest('%s can not be imported.' % module) 1378 self.skipTest('%s can not be imported.' % module)
1389 new_f.__name__ = f.__name__ 1379 new_f.__name__ = f.__name__
1390 return new_f 1380 return new_f
1391 return check_require_module 1381 return check_require_module
1392 1382
OLDNEW
« no previous file with comments | « third_party/logilab/common/tasksqueue.py ('k') | third_party/logilab/common/textutils.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698