Commit work done on test loading

Mon, 22 Jan 2018 13:51:13 +0200

author
Santeri Piippo
date
Mon, 22 Jan 2018 13:51:13 +0200
changeset 16
09cc89622262
parent 15
45b3aeb25003
child 17
327da5d00360

Commit work done on test loading

tests/concave.py file | annotate | diff | comparison | revisions
testsuite.py file | annotate | diff | comparison | revisions
--- a/tests/concave.py	Mon Jan 22 01:01:10 2018 +0200
+++ b/tests/concave.py	Mon Jan 22 13:51:13 2018 +0200
@@ -14,23 +14,31 @@
             for v1, v2, v3 in pairs(geometry.vertices, count = 3)
         ]
         if not sign_consistency(z_scores):
-            yield error(quadrilateral, 'Concave quadrilateral')
-
-def bowtie_quadrilateral_test(model):
-    ...
+            yield error(quadrilateral, 'concave-error')
 
 def skew_test(model):
+    ''' Test for non-coplanar quadrilaterals. '''
     for quadrilateral in model.quadrilaterals:
         for triangles in split_quadrilateral(quadrilateral.geometry):
             plane_1 = triangle_plane_normal(triangles[0])
             plane_2 = triangle_plane_normal(triangles[1])
-            angle = vector_angle(plane_1, plane_2, normalized = True)
-            if angle > radians(0.1):
-                yield error(quadrilateral,
-                    'Skew quadrilateral (plane angle {}°)',
-                    '%.3f' % degrees(angle))
+            skew_angle = vector_angle(plane_1, plane_2, normalized = True)
+            if skew_angle > radians(0.1):
+                yield error(quadrilateral, 'skew-error',
+                    skew_angle = skew_angle,
+                )
                 break
 
 manifest = {
-    'tests': {skew_test, concave_test},
+    'tests': {
+        'skew': skew_test,
+        'concave': concave_test,
+    },
+    'messages': {
+        'skew-error': lambda skew_angle:
+            str.format('Skew quadrilateral (plane angle {}°)',
+                '%.2f' % degrees(skew_angle),
+            ),
+        'concave-error': 'Concave quadrilateral',
+    },
 }
--- a/testsuite.py	Mon Jan 22 01:01:10 2018 +0200
+++ b/testsuite.py	Mon Jan 22 13:51:13 2018 +0200
@@ -1,13 +1,72 @@
-def warning(object, *message):
+from warnings import warn
+
+def report_element(bad_object, type, error_name, args):
     return {
-        'type': 'warning',
-        'object': object,
-        'message': str.format(*message),
+        'type': type,
+        'object': bad_object,
+        'name': error_name,
+        'args': args,
     }
 
-def error(object, *message):
-    return {
-        'type': 'error',
-        'object': object,
-        'message': str.format(*message),
-    }
+def warning(bad_object, error_name, *args):
+    return report_element(bad_object, 'warning', error_name, args)
+
+def error(bad_object, error_name, *args):
+    return report_element(bad_object, 'error', error_name, args)
+
+def test_discovery():
+    '''
+        Finds all test modules and yields their names.
+    '''
+    from pkgutil import walk_packages
+    import tests
+    yield from sorted(
+        'tests.' + result.name
+        for result in walk_packages(tests.__path__)
+    )
+
+def do_manifest_integrity_checks(test_suite, module):
+    '''
+        Runs integrity checks on a given module's manifest.
+    '''
+    def check_for_extra_keys():
+        extra_keys = module.manifest.keys() - test_suite.keys()
+        if extra_keys:
+            warn(str.format(
+                '{}: extra keys in manifest: {}',
+                module.__name__,
+                ', '.join(map(str, extra_keys))
+            ))
+    def check_for_manifest_duplicates():
+        for key in test_suite.keys():
+            duplicates = module.manifest[key].keys() & test_suite[key].keys()
+            if duplicates:
+                warn(str.format(
+                    '{}: redefined {} in manifests: {}',
+                    module.__name__,
+                    key,
+                    duplicates,
+                ))
+    check_for_extra_keys()
+    check_for_manifest_duplicates()
+
+def load_tests():
+    '''
+        Imports test modules and combines their manifests into a test suite.
+    '''
+    test_suite = {'tests': {}, 'messages': {}}
+    for module_name in test_discovery():
+        from importlib import import_module
+        module = import_module(module_name)
+        if hasattr(module, 'manifest'):
+            do_manifest_integrity_checks(test_suite, module)
+            # Merge the data from the manifest
+            for key in module.manifest.keys() & test_suite.keys():
+                test_suite[key].update(module.manifest[key])
+        else:
+            warn(str.format('Module {} does not have a manifest', module_name))
+    return test_suite
+
+if __name__ == '__main__':
+    from pprint import pprint
+    pprint(load_tests())

mercurial