mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Copy parts of old code to make libregtest work
This commit is contained in:
144
Lib/test/support/__init__.py
vendored
144
Lib/test/support/__init__.py
vendored
@@ -7,7 +7,7 @@ import contextlib
|
||||
import dataclasses
|
||||
import functools
|
||||
import logging
|
||||
import _opcode
|
||||
# import _opcode # TODO: RUSTPYTHON
|
||||
import os
|
||||
import re
|
||||
import stat
|
||||
@@ -2811,3 +2811,145 @@ def linked_to_musl():
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
return False
|
||||
return ('musl' in stdout)
|
||||
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
# Every line of code below allowed us to update `Lib/test/support/__init__.py` without
|
||||
# needing to update `libregtest` and its dependencies.
|
||||
# Ideally we want to remove all code below and update `libregtest`.
|
||||
#
|
||||
# Code below was copied from: https://github.com/RustPython/RustPython/blob/9499d39f55b73535e2405bf208d5380241f79ada/Lib/test/support/__init__.py
|
||||
|
||||
from .testresult import get_test_runner
|
||||
|
||||
def _filter_suite(suite, pred):
|
||||
"""Recursively filter test cases in a suite based on a predicate."""
|
||||
newtests = []
|
||||
for test in suite._tests:
|
||||
if isinstance(test, unittest.TestSuite):
|
||||
_filter_suite(test, pred)
|
||||
newtests.append(test)
|
||||
else:
|
||||
if pred(test):
|
||||
newtests.append(test)
|
||||
suite._tests = newtests
|
||||
|
||||
# By default, don't filter tests
|
||||
_match_test_func = None
|
||||
|
||||
_accept_test_patterns = None
|
||||
_ignore_test_patterns = None
|
||||
|
||||
def match_test(test):
|
||||
# Function used by support.run_unittest() and regrtest --list-cases
|
||||
if _match_test_func is None:
|
||||
return True
|
||||
else:
|
||||
return _match_test_func(test.id())
|
||||
|
||||
def set_match_tests(accept_patterns=None, ignore_patterns=None):
|
||||
global _match_test_func, _accept_test_patterns, _ignore_test_patterns
|
||||
|
||||
if accept_patterns is None:
|
||||
accept_patterns = ()
|
||||
if ignore_patterns is None:
|
||||
ignore_patterns = ()
|
||||
|
||||
accept_func = ignore_func = None
|
||||
|
||||
if accept_patterns != _accept_test_patterns:
|
||||
accept_patterns, accept_func = _compile_match_function(accept_patterns)
|
||||
if ignore_patterns != _ignore_test_patterns:
|
||||
ignore_patterns, ignore_func = _compile_match_function(ignore_patterns)
|
||||
|
||||
# Create a copy since patterns can be mutable and so modified later
|
||||
_accept_test_patterns = tuple(accept_patterns)
|
||||
_ignore_test_patterns = tuple(ignore_patterns)
|
||||
|
||||
if accept_func is not None or ignore_func is not None:
|
||||
def match_function(test_id):
|
||||
accept = True
|
||||
ignore = False
|
||||
if accept_func:
|
||||
accept = accept_func(test_id)
|
||||
if ignore_func:
|
||||
ignore = ignore_func(test_id)
|
||||
return accept and not ignore
|
||||
|
||||
_match_test_func = match_function
|
||||
|
||||
def _compile_match_function(patterns):
|
||||
if not patterns:
|
||||
func = None
|
||||
# set_match_tests(None) behaves as set_match_tests(())
|
||||
patterns = ()
|
||||
elif all(map(_is_full_match_test, patterns)):
|
||||
# Simple case: all patterns are full test identifier.
|
||||
# The test.bisect_cmd utility only uses such full test identifiers.
|
||||
func = set(patterns).__contains__
|
||||
else:
|
||||
import fnmatch
|
||||
regex = '|'.join(map(fnmatch.translate, patterns))
|
||||
# The search *is* case sensitive on purpose:
|
||||
# don't use flags=re.IGNORECASE
|
||||
regex_match = re.compile(regex).match
|
||||
|
||||
def match_test_regex(test_id):
|
||||
if regex_match(test_id):
|
||||
# The regex matches the whole identifier, for example
|
||||
# 'test.test_os.FileTests.test_access'.
|
||||
return True
|
||||
else:
|
||||
# Try to match parts of the test identifier.
|
||||
# For example, split 'test.test_os.FileTests.test_access'
|
||||
# into: 'test', 'test_os', 'FileTests' and 'test_access'.
|
||||
return any(map(regex_match, test_id.split(".")))
|
||||
|
||||
func = match_test_regex
|
||||
|
||||
return patterns, func
|
||||
|
||||
def run_unittest(*classes):
|
||||
"""Run tests from unittest.TestCase-derived classes."""
|
||||
valid_types = (unittest.TestSuite, unittest.TestCase)
|
||||
loader = unittest.TestLoader()
|
||||
suite = unittest.TestSuite()
|
||||
for cls in classes:
|
||||
if isinstance(cls, str):
|
||||
if cls in sys.modules:
|
||||
suite.addTest(loader.loadTestsFromModule(sys.modules[cls]))
|
||||
else:
|
||||
raise ValueError("str arguments must be keys in sys.modules")
|
||||
elif isinstance(cls, valid_types):
|
||||
suite.addTest(cls)
|
||||
else:
|
||||
suite.addTest(loader.loadTestsFromTestCase(cls))
|
||||
_filter_suite(suite, match_test)
|
||||
return _run_suite(suite)
|
||||
|
||||
def _run_suite(suite):
|
||||
"""Run tests from a unittest.TestSuite-derived class."""
|
||||
runner = get_test_runner(sys.stdout,
|
||||
verbosity=verbose,
|
||||
capture_output=(junit_xml_list is not None))
|
||||
|
||||
result = runner.run(suite)
|
||||
|
||||
if junit_xml_list is not None:
|
||||
junit_xml_list.append(result.get_xml_element())
|
||||
|
||||
if not result.testsRun and not result.skipped and not result.errors:
|
||||
raise TestDidNotRun
|
||||
if not result.wasSuccessful():
|
||||
stats = TestStats.from_unittest(result)
|
||||
if len(result.errors) == 1 and not result.failures:
|
||||
err = result.errors[0][1]
|
||||
elif len(result.failures) == 1 and not result.errors:
|
||||
err = result.failures[0][1]
|
||||
else:
|
||||
err = "multiple errors occurred"
|
||||
if not verbose: err += "; run in verbose mode for details"
|
||||
errors = [(str(tc), exc_str) for tc, exc_str in result.errors]
|
||||
failures = [(str(tc), exc_str) for tc, exc_str in result.failures]
|
||||
raise TestFailedWithDetails(err, errors, failures, stats=stats)
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user