summaryrefslogtreecommitdiff
path: root/deps/v8/build/util/lib/common/unittest_util.py
blob: 9683ab717a8f96d83d69e0b87342da587799e389 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Utilities for dealing with the python unittest module."""

import fnmatch
import re
import sys
import unittest


class _TextTestResult(unittest._TextTestResult):
  """A test result class that can print formatted text results to a stream.

  Results printed in conformance with gtest output format, like:
  [ RUN        ] autofill.AutofillTest.testAutofillInvalid: "test desc."
  [         OK ] autofill.AutofillTest.testAutofillInvalid
  [ RUN        ] autofill.AutofillTest.testFillProfile: "test desc."
  [         OK ] autofill.AutofillTest.testFillProfile
  [ RUN        ] autofill.AutofillTest.testFillProfileCrazyCharacters: "Test."
  [         OK ] autofill.AutofillTest.testFillProfileCrazyCharacters
  """
  def __init__(self, stream, descriptions, verbosity):
    unittest._TextTestResult.__init__(self, stream, descriptions, verbosity)
    self._fails = set()

  def _GetTestURI(self, test):
    return '%s.%s.%s' % (test.__class__.__module__,
                         test.__class__.__name__,
                         test._testMethodName)

  def getDescription(self, test):
    return '%s: "%s"' % (self._GetTestURI(test), test.shortDescription())

  def startTest(self, test):
    unittest.TestResult.startTest(self, test)
    self.stream.writeln('[ RUN        ] %s' % self.getDescription(test))

  def addSuccess(self, test):
    unittest.TestResult.addSuccess(self, test)
    self.stream.writeln('[         OK ] %s' % self._GetTestURI(test))

  def addError(self, test, err):
    unittest.TestResult.addError(self, test, err)
    self.stream.writeln('[      ERROR ] %s' % self._GetTestURI(test))
    self._fails.add(self._GetTestURI(test))

  def addFailure(self, test, err):
    unittest.TestResult.addFailure(self, test, err)
    self.stream.writeln('[     FAILED ] %s' % self._GetTestURI(test))
    self._fails.add(self._GetTestURI(test))

  def getRetestFilter(self):
    return ':'.join(self._fails)


class TextTestRunner(unittest.TextTestRunner):
  """Test Runner for displaying test results in textual format.

  Results are displayed in conformance with google test output.
  """

  def __init__(self, verbosity=1):
    unittest.TextTestRunner.__init__(self, stream=sys.stderr,
                                     verbosity=verbosity)

  def _makeResult(self):
    return _TextTestResult(self.stream, self.descriptions, self.verbosity)


def GetTestsFromSuite(suite):
  """Returns all the tests from a given test suite."""
  tests = []
  for x in suite:
    if isinstance(x, unittest.TestSuite):
      tests += GetTestsFromSuite(x)
    else:
      tests += [x]
  return tests


def GetTestNamesFromSuite(suite):
  """Returns a list of every test name in the given suite."""
  return map(lambda x: GetTestName(x), GetTestsFromSuite(suite))


def GetTestName(test):
  """Gets the test name of the given unittest test."""
  return '.'.join([test.__class__.__module__,
                   test.__class__.__name__,
                   test._testMethodName])


def FilterTestSuite(suite, gtest_filter):
  """Returns a new filtered tests suite based on the given gtest filter.

  See https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md
  for gtest_filter specification.
  """
  return unittest.TestSuite(FilterTests(GetTestsFromSuite(suite), gtest_filter))


def FilterTests(all_tests, gtest_filter):
  """Filter a list of tests based on the given gtest filter.

  Args:
    all_tests: List of tests (unittest.TestSuite)
    gtest_filter: Filter to apply.

  Returns:
    Filtered subset of the given list of tests.
  """
  test_names = [GetTestName(test) for test in all_tests]
  filtered_names = FilterTestNames(test_names, gtest_filter)
  return [test for test in all_tests if GetTestName(test) in filtered_names]


def FilterTestNames(all_tests, gtest_filter):
  """Filter a list of test names based on the given gtest filter.

  See https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md
  for gtest_filter specification.

  Args:
    all_tests: List of test names.
    gtest_filter: Filter to apply.

  Returns:
    Filtered subset of the given list of test names.
  """
  pattern_groups = gtest_filter.split('-')
  positive_patterns = ['*']
  if pattern_groups[0]:
    positive_patterns = pattern_groups[0].split(':')
  negative_patterns = []
  if len(pattern_groups) > 1:
    negative_patterns = pattern_groups[1].split(':')

  neg_pats = None
  if negative_patterns:
    neg_pats = re.compile('|'.join(fnmatch.translate(p) for p in
                                   negative_patterns))

  tests = []
  test_set = set()
  for pattern in positive_patterns:
    pattern_tests = [
        test for test in all_tests
        if (fnmatch.fnmatch(test, pattern)
            and not (neg_pats and neg_pats.match(test))
            and test not in test_set)]
    tests.extend(pattern_tests)
    test_set.update(pattern_tests)
  return tests