chiark / gitweb /
documentation/python: reduce needed test boilerplate.
authorVladimír Vondruš <mosra@centrum.cz>
Sun, 14 Jul 2019 13:49:48 +0000 (15:49 +0200)
committerVladimír Vondruš <mosra@centrum.cz>
Sun, 14 Jul 2019 17:19:44 +0000 (19:19 +0200)
Will do the same for doxygen, plugin and theme tests too, but later.

documentation/test_python/__init__.py
documentation/test_python/inspect_object/.gitkeep [new file with mode: 0644]
documentation/test_python/test_content.py
documentation/test_python/test_inspect.py
documentation/test_python/test_layout.py
documentation/test_python/test_link_formatting.py
documentation/test_python/test_page.py
documentation/test_python/test_pybind.py

index 79c69555c3be9de8f48bbef6118f4609928eee23..92eae4513977161d3491b9c3b7a5e9c1ea20bb67 100644 (file)
@@ -26,19 +26,43 @@ import copy
 import sys
 import os
 import inspect
+import re
 import shutil
 import unittest
 
 from python import run, default_templates, default_config
 
+# https://stackoverflow.com/a/12867228
+_camelcase_to_snakecase = re.compile('((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))')
+
+# The test files are automatically detected from derived class name and
+# filesystem location. For a `test_inspect.NameMapping` class, it will look
+# for the `inspect_name_mapping` directory. If the class name is equivalent to
+# the filename (e.g. `test_page.Page`), then it will be looking for just `page`
+# instead of `page_page`. If needed, the directory name can be overriden by
+# passing it via dir to __init__().
 class BaseTestCase(unittest.TestCase):
-    def __init__(self, path, dir, *args, **kwargs):
+    def __init__(self, *args, dir=None, **kwargs):
         unittest.TestCase.__init__(self, *args, **kwargs)
-        # Full directory name (for test_something.py the directory is something_dir{}
-        self.dirname = os.path.splitext(os.path.basename(path))[0][5:] + ('_' + dir if dir else '')
+
+        # Get the test filename from the derived class module file. If path is
+        # not supplied, get it from derived class name converted to snake_case
+        path = sys.modules[self.__class__.__module__].__file__
+        if not dir: dir = _camelcase_to_snakecase.sub('_\\1', self.__class__.__name__).lower()
+
+        # Full directory name (for test_something.py the directory is
+        # something_{dir}
+        dir_prefix = os.path.splitext(os.path.basename(path))[0][5:]
+        if dir and dir_prefix != dir:
+            self.dirname = dir_prefix + '_' + dir
+        else:
+            self.dirname = dir_prefix
         # Absolute path to this directory
         self.path = os.path.join(os.path.dirname(os.path.realpath(path)), self.dirname)
 
+        if not os.path.exists(self.path):
+            raise AssertionError("autodetected path {} doesn't exist".format(self.path))
+
         # Display ALL THE DIFFS
         self.maxDiff = None
 
@@ -72,6 +96,8 @@ class BaseTestCase(unittest.TestCase):
             actual_contents = f.read().strip()
         return actual_contents, expected_contents
 
+# On top of the automagic of BaseTestCase this automatically sets INPUT_MODULES
+# to detected `dirname`, if not set already.
 class BaseInspectTestCase(BaseTestCase):
     def run_python(self, config_overrides={}, templates=default_templates):
         if 'INPUT_MODULES' not in config_overrides:
diff --git a/documentation/test_python/inspect_object/.gitkeep b/documentation/test_python/inspect_object/.gitkeep
new file mode 100644 (file)
index 0000000..e69de29
index e61778a1b71419adb12dae7b1e926d2028617a87..8cafecad00f0429828a87b809352a25744f99f63 100644 (file)
@@ -27,9 +27,6 @@ import os
 from . import BaseInspectTestCase
 
 class Content(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, '', *args, **kwargs)
-
     def test(self):
         self.run_python({
             'PLUGINS': ['m.sphinx'],
index f28ed0de626aaa7bebed4df4139b7c21b4cc0a8f..c6d767910e6726987aed2c3b453c42fa2a14877d 100644 (file)
@@ -34,9 +34,6 @@ from python import default_templates
 from . import BaseInspectTestCase
 
 class String(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'string', *args, **kwargs)
-
     def test(self):
         self.run_python({
             'LINKS_NAVBAR1': [
@@ -52,9 +49,6 @@ class String(BaseInspectTestCase):
         self.assertEqual(*self.actual_expected_contents('modules.html'))
 
 class Object(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'object', *args, **kwargs)
-
     def test(self):
         # Reuse the stuff from inspect_string, but this time reference it via
         # an object and not a string
@@ -77,17 +71,11 @@ class Object(BaseInspectTestCase):
         self.assertEqual(*self.actual_expected_contents('modules.html', '../inspect_string/modules.html'))
 
 class AllProperty(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'all_property', *args, **kwargs)
-
     def test(self):
         self.run_python()
         self.assertEqual(*self.actual_expected_contents('inspect_all_property.html'))
 
 class Annotations(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'annotations', *args, **kwargs)
-
     def test(self):
         self.run_python()
         self.assertEqual(*self.actual_expected_contents('inspect_annotations.html'))
@@ -128,9 +116,6 @@ class Annotations(BaseInspectTestCase):
         self.assertEqual(*self.actual_expected_contents('math.html', 'math36.html'))
 
 class NameMapping(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'name_mapping', *args, **kwargs)
-
     def test(self):
         self.run_python()
         self.assertEqual(*self.actual_expected_contents('inspect_name_mapping.html'))
@@ -138,9 +123,6 @@ class NameMapping(BaseInspectTestCase):
         self.assertEqual(*self.actual_expected_contents('inspect_name_mapping.submodule.html'))
 
 class Recursive(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'recursive', *args, **kwargs)
-
     def test(self):
         self.run_python()
         self.assertEqual(*self.actual_expected_contents('inspect_recursive.html'))
@@ -148,9 +130,6 @@ class Recursive(BaseInspectTestCase):
         self.assertEqual(*self.actual_expected_contents('inspect_recursive.a.html'))
 
 class TypeLinks(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'type_links', *args, **kwargs)
-
     def test(self):
         self.run_python()
         self.assertEqual(*self.actual_expected_contents('inspect_type_links.first.html'))
index 0dedeb4f8b90724da6800bec89f14152ead3baa0..7a7278ae5197d200c0d3cd1dcc2f8b45e7406357 100644 (file)
@@ -27,9 +27,6 @@ import os
 from . import BaseTestCase
 
 class Layout(BaseTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, '', *args, **kwargs)
-
     def test(self):
         self.run_python({
             'PROJECT_TITLE': "A project",
index bfc9563ed6d2a65c2213154d37e9fa6eaf607b6d..4623e9456496eef68d31a08a9998d084039ea470 100644 (file)
@@ -60,10 +60,7 @@ def custom_id_formatter(type: EntryType, path: List[str]) -> str:
 
     assert False
 
-class Test(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, '', *args, **kwargs)
-
+class LinkFormatting(BaseInspectTestCase):
     def test(self):
         self.run_python({
             'INPUT_PAGES': ['page.rst'],
index 0dd6a6ecd24b3b99b4a9ef1c40b3df649acacf36..19ed9f747f4b9224f4b0bf7f1b55cf806f14881d 100644 (file)
@@ -35,9 +35,6 @@ def dot_version():
     return re.match(".*version (?P<version>\d+\.\d+\.\d+).*", subprocess.check_output(['dot', '-V'], stderr=subprocess.STDOUT).decode('utf-8').strip()).group('version')
 
 class Page(BaseTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, '', *args, **kwargs)
-
     def test(self):
         self.run_python({
             'INPUT_PAGES': ['index.rst', 'another.rst']
@@ -46,10 +43,7 @@ class Page(BaseTestCase):
         self.assertEqual(*self.actual_expected_contents('another.html'))
         self.assertEqual(*self.actual_expected_contents('pages.html'))
 
-class PageInputSubdir(BaseTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'input_subdir', *args, **kwargs)
-
+class InputSubdir(BaseTestCase):
     def test(self):
         self.run_python({
             'INPUT': 'sub',
@@ -59,9 +53,6 @@ class PageInputSubdir(BaseTestCase):
         self.assertEqual(*self.actual_expected_contents('index.html', '../page/index.html'))
 
 class Plugins(BaseTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'plugins', *args, **kwargs)
-
     def test(self):
         self.run_python({
             # Test all of them to check the registration works well
index e27526945af96ae2060bd94a38fd62fe67c11aa5..21b5e44e92dc96d558f6ad0a1f1a88b026b00b79 100644 (file)
@@ -174,9 +174,6 @@ class Signature(unittest.TestCase):
                          ('b', 'Tuple[int, module.Bar]', 'Tuple[int, module.Bar]', None)], 'module.Baz'))
 
 class Signatures(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'signatures', *args, **kwargs)
-
     def test_positional_args(self):
         sys.path.append(self.path)
         import pybind_signatures
@@ -217,9 +214,6 @@ class Signatures(BaseInspectTestCase):
             self.assertEqual(*self.actual_expected_contents('pybind_signatures.MyClass23.html'))
 
 class Enums(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'enums', *args, **kwargs)
-
     def test(self):
         self.run_python({
             'PYBIND11_COMPATIBILITY': True
@@ -227,9 +221,6 @@ class Enums(BaseInspectTestCase):
         self.assertEqual(*self.actual_expected_contents('pybind_enums.html'))
 
 class Submodules(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'submodules', *args, **kwargs)
-
     def test(self):
         self.run_python({
             'PYBIND11_COMPATIBILITY': True
@@ -237,9 +228,6 @@ class Submodules(BaseInspectTestCase):
         self.assertEqual(*self.actual_expected_contents('pybind_submodules.html'))
 
 class SubmodulesPackage(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'submodules_package', *args, **kwargs)
-
     def test(self):
         self.run_python({
             'PYBIND11_COMPATIBILITY': True
@@ -247,9 +235,6 @@ class SubmodulesPackage(BaseInspectTestCase):
         self.assertEqual(*self.actual_expected_contents('pybind_submodules_package.sub.html'))
 
 class NameMapping(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'name_mapping', *args, **kwargs)
-
     def test(self):
         self.run_python({
             'PYBIND11_COMPATIBILITY': True
@@ -259,9 +244,6 @@ class NameMapping(BaseInspectTestCase):
         self.assertEqual(*self.actual_expected_contents('pybind_name_mapping.submodule.html'))
 
 class TypeLinks(BaseInspectTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(__file__, 'type_links', *args, **kwargs)
-
     def test(self):
         sys.path.append(self.path)
         import pybind_type_links