tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

unittest_util.py (5024B)


      1 # Copyright 2013 The Chromium Authors
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """Utilities for dealing with the python unittest module."""
      6 
      7 import fnmatch
      8 import re
      9 import sys
     10 import unittest
     11 
     12 
     13 class _TextTestResult(unittest._TextTestResult):
     14  """A test result class that can print formatted text results to a stream.
     15 
     16  Results printed in conformance with gtest output format, like:
     17  [ RUN        ] autofill.AutofillTest.testAutofillInvalid: "test desc."
     18  [         OK ] autofill.AutofillTest.testAutofillInvalid
     19  [ RUN        ] autofill.AutofillTest.testFillProfile: "test desc."
     20  [         OK ] autofill.AutofillTest.testFillProfile
     21  [ RUN        ] autofill.AutofillTest.testFillProfileCrazyCharacters: "Test."
     22  [         OK ] autofill.AutofillTest.testFillProfileCrazyCharacters
     23  """
     24  def __init__(self, stream, descriptions, verbosity):
     25    unittest._TextTestResult.__init__(self, stream, descriptions, verbosity)
     26    self._fails = set()
     27 
     28  def _GetTestURI(self, test):
     29    return '%s.%s.%s' % (test.__class__.__module__,
     30                         test.__class__.__name__,
     31                         test._testMethodName)
     32 
     33  def getDescription(self, test):
     34    return '%s: "%s"' % (self._GetTestURI(test), test.shortDescription())
     35 
     36  def startTest(self, test):
     37    unittest.TestResult.startTest(self, test)
     38    self.stream.writeln('[ RUN        ] %s' % self.getDescription(test))
     39 
     40  def addSuccess(self, test):
     41    unittest.TestResult.addSuccess(self, test)
     42    self.stream.writeln('[         OK ] %s' % self._GetTestURI(test))
     43 
     44  def addError(self, test, err):
     45    unittest.TestResult.addError(self, test, err)
     46    self.stream.writeln('[      ERROR ] %s' % self._GetTestURI(test))
     47    self._fails.add(self._GetTestURI(test))
     48 
     49  def addFailure(self, test, err):
     50    unittest.TestResult.addFailure(self, test, err)
     51    self.stream.writeln('[     FAILED ] %s' % self._GetTestURI(test))
     52    self._fails.add(self._GetTestURI(test))
     53 
     54  def getRetestFilter(self):
     55    return ':'.join(self._fails)
     56 
     57 
     58 class TextTestRunner(unittest.TextTestRunner):
     59  """Test Runner for displaying test results in textual format.
     60 
     61  Results are displayed in conformance with google test output.
     62  """
     63 
     64  def __init__(self, verbosity=1):
     65    unittest.TextTestRunner.__init__(self, stream=sys.stderr,
     66                                     verbosity=verbosity)
     67 
     68  def _makeResult(self):
     69    return _TextTestResult(self.stream, self.descriptions, self.verbosity)
     70 
     71 
     72 def GetTestsFromSuite(suite):
     73  """Returns all the tests from a given test suite."""
     74  tests = []
     75  for x in suite:
     76    if isinstance(x, unittest.TestSuite):
     77      tests += GetTestsFromSuite(x)
     78    else:
     79      tests += [x]
     80  return tests
     81 
     82 
     83 def GetTestNamesFromSuite(suite):
     84  """Returns a list of every test name in the given suite."""
     85  return map(lambda x: GetTestName(x), GetTestsFromSuite(suite))
     86 
     87 
     88 def GetTestName(test):
     89  """Gets the test name of the given unittest test."""
     90  return '.'.join([test.__class__.__module__,
     91                   test.__class__.__name__,
     92                   test._testMethodName])
     93 
     94 
     95 def FilterTestSuite(suite, gtest_filter):
     96  """Returns a new filtered tests suite based on the given gtest filter.
     97 
     98  See https://github.com/google/googletest/blob/main/docs/advanced.md
     99  for gtest_filter specification.
    100  """
    101  return unittest.TestSuite(FilterTests(GetTestsFromSuite(suite), gtest_filter))
    102 
    103 
    104 def FilterTests(all_tests, gtest_filter):
    105  """Filter a list of tests based on the given gtest filter.
    106 
    107  Args:
    108    all_tests: List of tests (unittest.TestSuite)
    109    gtest_filter: Filter to apply.
    110 
    111  Returns:
    112    Filtered subset of the given list of tests.
    113  """
    114  test_names = [GetTestName(test) for test in all_tests]
    115  filtered_names = FilterTestNames(test_names, gtest_filter)
    116  return [test for test in all_tests if GetTestName(test) in filtered_names]
    117 
    118 
    119 def FilterTestNames(all_tests, gtest_filter):
    120  """Filter a list of test names based on the given gtest filter.
    121 
    122  See https://github.com/google/googletest/blob/main/docs/advanced.md
    123  for gtest_filter specification.
    124 
    125  Args:
    126    all_tests: List of test names.
    127    gtest_filter: Filter to apply.
    128 
    129  Returns:
    130    Filtered subset of the given list of test names.
    131  """
    132  pattern_groups = gtest_filter.split('-')
    133  positive_patterns = ['*']
    134  if pattern_groups[0]:
    135    positive_patterns = pattern_groups[0].split(':')
    136  negative_patterns = []
    137  if len(pattern_groups) > 1:
    138    negative_patterns = pattern_groups[1].split(':')
    139 
    140  neg_pats = None
    141  if negative_patterns:
    142    neg_pats = re.compile('|'.join(fnmatch.translate(p) for p in
    143                                   negative_patterns))
    144 
    145  tests = []
    146  test_set = set()
    147  for pattern in positive_patterns:
    148    pattern_tests = [
    149        test for test in all_tests
    150        if (fnmatch.fnmatch(test, pattern)
    151            and not (neg_pats and neg_pats.match(test))
    152            and test not in test_set)]
    153    tests.extend(pattern_tests)
    154    test_set.update(pattern_tests)
    155  return tests