diff -r 1c0884f5506e -r f2dc17b830e0 testsuite.py --- a/testsuite.py Sat Jun 08 01:51:50 2019 +0300 +++ b/testsuite.py Sat Jun 08 11:17:17 2019 +0300 @@ -1,6 +1,13 @@ +#!/usr/bin/env python3 +''' + Routines for assembling the test suite, and running it on a model. +''' from warnings import warn class ProblemType: + ''' + Represents a type of issue in the part + ''' severities = ['hold', 'warning'] # in descending order def __init__(self, name, severity, message): if severity not in ProblemType.severities: @@ -18,6 +25,10 @@ **args, ) def placeholder_message(self): + ''' + Returns the error message of this problem type, with placeholders + filled in. + ''' if callable(self.message): import inspect spec = inspect.getfullargspec(self.message) @@ -30,6 +41,9 @@ return self.message class Problem: + ''' + Represents a single issue in the part + ''' def __init__(self, problem_class, bad_object, **args): self.problem_class = problem_class self.severity = problem_class.severity @@ -42,6 +56,10 @@ return self.problem_class.message def problem_type(problem_name, **args): + ''' + A decorator that creates a new ProblemType and attaches it to the + decoratable function. + ''' def wrapper(function): if not hasattr(function, 'ldcheck_problem_types'): function.ldcheck_problem_types = {} @@ -51,6 +69,10 @@ return wrapper def report_problem(problem_name, *, bad_object, **args): + ''' + Called from test functions to report issues. This gets later mapped + into Problem objects. + ''' return {'type': problem_name, 'bad-object': bad_object, 'args': args} def name_of_package(package): @@ -87,6 +109,9 @@ return test_suite def problem_key(problem): + ''' + Sorts problems by rank and line number. + ''' rank = ProblemType.severities.index(problem.severity) # sort by severity return (rank, problem.line_number) @@ -100,6 +125,9 @@ return problem_object def check_model(model, test_suite = None): + ''' + Runs the test suite on the model and prepares a report. + ''' if not test_suite: test_suite = load_tests() problems = [] @@ -123,65 +151,18 @@ 'problems': sorted(problems, key = problem_key), } -def problem_text(problem, test_suite): - message = problem.problem_class.message - if callable(message): - message = message(**problem.args) - return message - -def format_report_html(report, model, test_suite): - messages = [] - for problem in report['problems']: - ldraw_code = model.body[problem.body_index].textual_representation() - message = str.format( - '
  • {model_name}:{line_number}:' - '{problem_type}: {message}
    {ldraw_code}
  • ', - model_name = model.name, - line_number = problem.line_number, - problem_type = problem.severity, - message = problem_text(problem, test_suite), - ldraw_code = ldraw_code, - ) - messages.append(message) - return '\n'.join(messages) - -def format_report(report, model, test_suite): - import colorama - colorama.init() - messages = [] - for problem in report['problems']: - if problem.severity == 'hold': - text_colour = colorama.Fore.LIGHTRED_EX - elif problem.severity == 'warning': - text_colour = colorama.Fore.LIGHTBLUE_EX - else: - text_colour = '' - ldraw_code = model.body[problem.body_index].textual_representation() - message = str.format( - '{text_colour}{model_name}:{line_number}: {problem_type}: {message}' - '{colour_reset}\n\t{ldraw_code}', - text_colour = text_colour, - model_name = model.name, - line_number = problem.line_number, - problem_type = problem.severity, - message = problem_text(problem, test_suite), - colour_reset = colorama.Fore.RESET, - ldraw_code = ldraw_code, - ) - messages.append(message) - return '\n'.join(messages) - def iterate_problems(test_suite): + ''' + Yields all problem types. + ''' for test_function in test_suite['tests']: yield from test_function.ldcheck_problem_types.values() def all_problem_types(test_suite): + ''' + Returns a sorted list of problem types. + ''' return sorted( iterate_problems(test_suite), key = lambda problem_type: problem_type.name ) - - -if __name__ == '__main__': - from pprint import pprint - pprint(load_tests())