Added code to run the test suite.

Mon, 22 Jan 2018 17:05:10 +0200

author
Santeri Piippo
date
Mon, 22 Jan 2018 17:05:10 +0200
changeset 17
327da5d00360
parent 16
09cc89622262
child 18
672ebc45685a

Added code to run the test suite.

ldcheck.py file | annotate | diff | comparison | revisions
parse.py file | annotate | diff | comparison | revisions
testsuite.py file | annotate | diff | comparison | revisions
--- a/ldcheck.py	Mon Jan 22 13:51:13 2018 +0200
+++ b/ldcheck.py	Mon Jan 22 17:05:10 2018 +0200
@@ -35,27 +35,27 @@
 
 def find_ldconfig_ldr_paths(config):
     for library_path in library_paths(config):
-        ldconfig_paths = [
-            library_path / 'LDConfig.ldr',
-            library_path / 'ldconfig.ldr',
+        yield from [
+            library_path / path
+            for path in ['LDConfig.ldr', 'ldconfig.ldr']
+            if (library_path / path).is_file()
         ]
-        for path in ldconfig_paths:
-            print(path)
-            if path.is_file():
-                yield path
 
 def hairline_score(smallest_angle):
     from math import log10
     return max(0, -log10(smallest_angle))
 
 class Model:
-	def __init__(self, body):
-		self.body = body
-	@property
-	def quadrilaterals(self):
-		yield from filter(
-			lambda element: isinstance(element, linetypes.Quadrilateral),
-			self.body)
+    def __init__(self, body):
+        self.body = body
+        self.body_offset = 0
+    @property
+    def quadrilaterals(self):
+        yield from [
+            element
+            for element in self.body
+            if isinstance(element, linetypes.Quadrilateral)
+        ]
 
 if __name__ == '__main__':
     from sys import argv
@@ -66,15 +66,7 @@
     with open(argv[1], 'r') as file:
         model_body = read_ldraw(file, config = config)
         model = Model(body = model_body)
-        for line_number, entry in enumerate(model_body, 1):
-            if hasattr(entry, 'colour'):
-                print(repr(entry.colour))
-            if hasattr(entry, 'geometry') and len(entry.geometry) >= 3:
-                if hairline_score(entry.geometry.smallest_angle) >= 2.0:
-                    print(str.format(
-                        'Hairline {type} at line {line_number}',
-                        type = entry.typename(),
-                        line_number = line_number,
-                    ))
-                    print(entry.textual_representation())
-                    print('-' * 25)
+        from testsuite import load_tests, check_model, format_report
+        test_suite = load_tests()
+        report = check_model(model, test_suite)
+        print(format_report(report, model, test_suite))
--- a/parse.py	Mon Jan 22 13:51:13 2018 +0200
+++ b/parse.py	Mon Jan 22 17:05:10 2018 +0200
@@ -9,23 +9,25 @@
 def parse_ldraw_code(line):
     line = line.strip()
     if not line:
-        return linetypes.EmptyLine()
+        object = linetypes.EmptyLine()
     elif line == '0':
-        return linetypes.Comment('')
+        object = linetypes.Comment('')
     elif line.startswith('0 '):
-        return linetypes.Comment(line[2:].strip())
+        object = linetypes.Comment(line[2:].strip())
     elif line.startswith('1 '):
-        return parse_ldraw_subfile_reference(line)
+        object = parse_ldraw_subfile_reference(line)
     elif line.startswith('2 '):
-        return parse_ldraw_line(line)
+        object = parse_ldraw_line(line)
     elif line.startswith('3 '):
-        return parse_ldraw_triangle(line)
+        object = parse_ldraw_triangle(line)
     elif line.startswith('4 '):
-        return parse_ldraw_quadrilateral(line)
+        object = parse_ldraw_quadrilateral(line)
     elif line.startswith('5 '):
-        return parse_ldraw_contour(line)
+        object = parse_ldraw_contour(line)
     else:
         raise BadLdrawLine('unknown line type')
+    object.original_code = line
+    return object
 
 def parse_ldraw_subfile_reference(line):
     pattern = r'^1\s+([^ ]+)' + r'\s+([^ ]+)' * (3 + 9 + 1) + r'\s*$'
--- a/testsuite.py	Mon Jan 22 13:51:13 2018 +0200
+++ b/testsuite.py	Mon Jan 22 17:05:10 2018 +0200
@@ -8,10 +8,10 @@
         'args': args,
     }
 
-def warning(bad_object, error_name, *args):
+def warning(bad_object, error_name, **args):
     return report_element(bad_object, 'warning', error_name, args)
 
-def error(bad_object, error_name, *args):
+def error(bad_object, error_name, **args):
     return report_element(bad_object, 'error', error_name, args)
 
 def test_discovery():
@@ -67,6 +67,41 @@
             warn(str.format('Module {} does not have a manifest', module_name))
     return test_suite
 
+def check_model(model, test_suite = None):
+    if not test_suite:
+        test_suite = load_tests()
+    report = []
+    line_numbers = {
+        element: (i, i + 1 + model.body_offset)
+        for i, element in enumerate(model.body)
+    }
+    for test_name, test_function in test_suite['tests'].items():
+        problems = test_function(model)
+        for problem in problems:
+            problem['body-index'], problem['line-number'] \
+                = line_numbers[problem['object']]
+            del problem['object']
+            report.append(problem)
+    return report
+
+def format_report(report, model, test_suite):
+    result = []
+    for problem in report:
+        problem_text = test_suite['messages'][problem['name']]
+        if callable(problem_text):
+            problem_text = problem_text(**problem['args'])
+        message = str.format(
+            'Line {}: {}\n\t{}',
+            problem['line-number'],
+            problem_text,
+            model.body[problem['body-index']].original_code
+        )
+        result.append((problem['line-number'], message))
+    return '\n'.join(
+        problem[1]
+        for problem in sorted(result)
+    )
+
 if __name__ == '__main__':
     from pprint import pprint
     pprint(load_tests())

mercurial