--- a/tests/misc.py Wed Jun 05 00:33:50 2019 +0300 +++ b/tests/misc.py Sat Jun 08 01:32:25 2019 +0300 @@ -1,83 +1,114 @@ -from testsuite import error, warning +from testsuite import problem_type, report_problem import linetypes +@problem_type('bad-colour', + severity = 'error', + message = lambda colour_index, count: str.format( + 'invalid colour {} used {} time(s)', + colour_index, + count, + ), +) def colours_test(model): ''' Checks that all colours used in the part model are valid. ''' - yield from ( - warning(element, 'bad-colour', colour_index = element.colour.index) - for element in model.body - if hasattr(element, 'colour') and not element.colour.is_valid - ) + from collections import defaultdict + bad_colours = defaultdict(lambda: {'count': 0, 'first-occurrence': None}) + for element in model.body: + if hasattr(element, 'colour') and not element.colour.is_valid: + bad_colours[element.colour.index]['count'] += 1 + if not bad_colours[element.colour.index]['first-occurrence']: + bad_colours[element.colour.index]['first-occurrence'] = element + yield from [ + report_problem( + 'bad-colour', + bad_object = bad_colour['first-occurrence'], + colour_index = colour_index, + count = bad_colour['count'], + ) + for colour_index, bad_colour in bad_colours.items() + ] +@problem_type('syntax-error', + severity = 'error', + message = lambda reason: str.format('syntax error: {}', reason), +) def syntax_errors(model): yield from ( - error(element, 'syntax-error', reason = element.reason) + report_problem('syntax-error', + bad_object = element, + reason = element.reason + ) for element in model.body if isinstance(element, linetypes.Error) ) +@problem_type('bad-header', + severity = 'error', + message = lambda reason: str.format('bad header: {}', reason), +) def bad_header(model): import header if isinstance(model.header, header.BadHeader): - yield error( - model.body[model.header.index], + yield report_problem( 'bad-header', + bad_object = model.body[model.header.index], reason = model.header.reason, ) +@problem_type('bfc-nocertify', + severity = 'error', + message = 'all new parts must be BFC certified', +) def nocertify_test(model): import header if model.header.valid and model.header.bfc == 'NOCERTIFY': - yield error( - model.body[model.header.first_occurrence['bfc']], - 'bfc-nocertify') + yield report_problem( + 'bfc-nocertify', + bad_object = model.body[model.header.first_occurrence['bfc']], + ) +@problem_type('physical-colour-part', + severity = 'error', + message = 'no new physical colour parts are accepted', +) def physical_colours_test(model): if model.header.valid and 'Physical_Colour' in model.header.qualifiers: - yield error( - model.body[model.header.first_occurrence['part type']], - 'physical-colour') + yield report_problem( + 'physical-colour-part', + bad_object = model.body[model.header.first_occurrence['part type']], + ) +@problem_type('official-part', + severity = 'error', + message = 'new parts must be unofficial', +) def unofficiality_test(model): if model.header.valid and not model.header.filetype.startswith('Unofficial_'): - yield error( - model.body[model.header.first_occurrence['part type']], - 'unofficial-type') + yield report_problem( + 'unofficial-part', + bad_object = model.body[model.header.first_occurrence['part type']]) +@problem_type('primitive-ccw', + severity = 'error', + message = 'primitives must have CCW winding', +) def primitive_ccw_test(model): if model.header.valid \ and model.header.filetype.endswith('Primitive') \ and model.header.bfc != 'CERTIFY CCW': - yield error( - model.body[model.header.first_occurrence['bfc']], - 'primitive-bfc-ccw') + yield report_problem( + 'primitive-bfc-ccw', + bad_object = model.body[model.header.first_occurrence['bfc']], + ) manifest = { - 'tests': { - 'colour-validity': colours_test, - 'syntax-errors': syntax_errors, - 'header-validity': bad_header, - 'bfc-nocertify': nocertify_test, - 'physical-colour': physical_colours_test, - 'unofficial-type': unofficiality_test, - 'primitive-ccw': primitive_ccw_test, - }, - 'messages': { - 'bad-colour': lambda colour_index: str.format( - 'invalid colour {}', - colour_index, - ), - 'syntax-error': lambda reason: str.format( - 'syntax error: {}', - reason, - ), - 'bad-header': lambda reason: str.format( - 'bad header: {}', - reason, - ), - 'bfc-nocertify': 'all new parts must be BFC certified', - 'physical-colour': 'no new physical colour parts are accepted', - 'unofficial-type': 'new parts must be unofficial', - 'primitive-bfc-ccw': 'primitives must have CCW winding', - }, + 'tests': [ + colours_test, + syntax_errors, + bad_header, + nocertify_test, + physical_colours_test, + unofficiality_test, + primitive_ccw_test, + ], }