90 lines
2.4 KiB
Python
90 lines
2.4 KiB
Python
import inspect
|
|
import random
|
|
import re
|
|
import unittest
|
|
|
|
try:
|
|
from StringIO import StringIO
|
|
except ImportError:
|
|
from io import StringIO
|
|
|
|
from . import import_submodule
|
|
|
|
|
|
class PygameTestLoader(unittest.TestLoader):
|
|
def __init__(
|
|
self, randomize_tests=False, include_incomplete=False, exclude=("interactive",)
|
|
):
|
|
super().__init__()
|
|
self.randomize_tests = randomize_tests
|
|
|
|
if exclude is None:
|
|
self.exclude = set()
|
|
else:
|
|
self.exclude = set(exclude)
|
|
|
|
if include_incomplete:
|
|
self.testMethodPrefix = ("test", "todo_")
|
|
|
|
def getTestCaseNames(self, testCaseClass):
|
|
res = []
|
|
for name in super().getTestCaseNames(testCaseClass):
|
|
tags = get_tags(testCaseClass, getattr(testCaseClass, name))
|
|
if self.exclude.isdisjoint(tags):
|
|
res.append(name)
|
|
|
|
if self.randomize_tests:
|
|
random.shuffle(res)
|
|
|
|
return res
|
|
|
|
|
|
# Exclude by tags:
|
|
|
|
TAGS_RE = re.compile(r"\|[tT]ags:(-?[ a-zA-Z,0-9_\n]+)\|", re.M)
|
|
|
|
|
|
class TestTags:
|
|
def __init__(self):
|
|
self.memoized = {}
|
|
self.parent_modules = {}
|
|
|
|
def get_parent_module(self, class_):
|
|
if class_ not in self.parent_modules:
|
|
self.parent_modules[class_] = import_submodule(class_.__module__)
|
|
return self.parent_modules[class_]
|
|
|
|
def __call__(self, parent_class, meth):
|
|
key = (parent_class, meth.__name__)
|
|
if key not in self.memoized:
|
|
parent_module = self.get_parent_module(parent_class)
|
|
|
|
module_tags = getattr(parent_module, "__tags__", [])
|
|
class_tags = getattr(parent_class, "__tags__", [])
|
|
|
|
tags = TAGS_RE.search(inspect.getdoc(meth) or "")
|
|
if tags:
|
|
test_tags = [t.strip() for t in tags.group(1).split(",")]
|
|
else:
|
|
test_tags = []
|
|
|
|
combined = set()
|
|
for tags in (module_tags, class_tags, test_tags):
|
|
if not tags:
|
|
continue
|
|
|
|
add = {t for t in tags if not t.startswith("-")}
|
|
remove = {t[1:] for t in tags if t not in add}
|
|
|
|
if add:
|
|
combined.update(add)
|
|
if remove:
|
|
combined.difference_update(remove)
|
|
|
|
self.memoized[key] = combined
|
|
|
|
return self.memoized[key]
|
|
|
|
|
|
get_tags = TestTags()
|