1 from testsuite import error, warning |
1 from testsuite import problem_type, report_problem |
2 import linetypes |
2 import linetypes |
3 |
3 |
|
4 @problem_type('bad-colour', |
|
5 severity = 'error', |
|
6 message = lambda colour_index, count: str.format( |
|
7 'invalid colour {} used {} time(s)', |
|
8 colour_index, |
|
9 count, |
|
10 ), |
|
11 ) |
4 def colours_test(model): |
12 def colours_test(model): |
5 ''' Checks that all colours used in the part model are valid. ''' |
13 ''' Checks that all colours used in the part model are valid. ''' |
6 yield from ( |
14 from collections import defaultdict |
7 warning(element, 'bad-colour', colour_index = element.colour.index) |
15 bad_colours = defaultdict(lambda: {'count': 0, 'first-occurrence': None}) |
8 for element in model.body |
16 for element in model.body: |
9 if hasattr(element, 'colour') and not element.colour.is_valid |
17 if hasattr(element, 'colour') and not element.colour.is_valid: |
10 ) |
18 bad_colours[element.colour.index]['count'] += 1 |
|
19 if not bad_colours[element.colour.index]['first-occurrence']: |
|
20 bad_colours[element.colour.index]['first-occurrence'] = element |
|
21 yield from [ |
|
22 report_problem( |
|
23 'bad-colour', |
|
24 bad_object = bad_colour['first-occurrence'], |
|
25 colour_index = colour_index, |
|
26 count = bad_colour['count'], |
|
27 ) |
|
28 for colour_index, bad_colour in bad_colours.items() |
|
29 ] |
11 |
30 |
|
31 @problem_type('syntax-error', |
|
32 severity = 'error', |
|
33 message = lambda reason: str.format('syntax error: {}', reason), |
|
34 ) |
12 def syntax_errors(model): |
35 def syntax_errors(model): |
13 yield from ( |
36 yield from ( |
14 error(element, 'syntax-error', reason = element.reason) |
37 report_problem('syntax-error', |
|
38 bad_object = element, |
|
39 reason = element.reason |
|
40 ) |
15 for element in model.body |
41 for element in model.body |
16 if isinstance(element, linetypes.Error) |
42 if isinstance(element, linetypes.Error) |
17 ) |
43 ) |
18 |
44 |
|
45 @problem_type('bad-header', |
|
46 severity = 'error', |
|
47 message = lambda reason: str.format('bad header: {}', reason), |
|
48 ) |
19 def bad_header(model): |
49 def bad_header(model): |
20 import header |
50 import header |
21 if isinstance(model.header, header.BadHeader): |
51 if isinstance(model.header, header.BadHeader): |
22 yield error( |
52 yield report_problem( |
23 model.body[model.header.index], |
|
24 'bad-header', |
53 'bad-header', |
|
54 bad_object = model.body[model.header.index], |
25 reason = model.header.reason, |
55 reason = model.header.reason, |
26 ) |
56 ) |
27 |
57 |
|
58 @problem_type('bfc-nocertify', |
|
59 severity = 'error', |
|
60 message = 'all new parts must be BFC certified', |
|
61 ) |
28 def nocertify_test(model): |
62 def nocertify_test(model): |
29 import header |
63 import header |
30 if model.header.valid and model.header.bfc == 'NOCERTIFY': |
64 if model.header.valid and model.header.bfc == 'NOCERTIFY': |
31 yield error( |
65 yield report_problem( |
32 model.body[model.header.first_occurrence['bfc']], |
66 'bfc-nocertify', |
33 'bfc-nocertify') |
67 bad_object = model.body[model.header.first_occurrence['bfc']], |
|
68 ) |
34 |
69 |
|
70 @problem_type('physical-colour-part', |
|
71 severity = 'error', |
|
72 message = 'no new physical colour parts are accepted', |
|
73 ) |
35 def physical_colours_test(model): |
74 def physical_colours_test(model): |
36 if model.header.valid and 'Physical_Colour' in model.header.qualifiers: |
75 if model.header.valid and 'Physical_Colour' in model.header.qualifiers: |
37 yield error( |
76 yield report_problem( |
38 model.body[model.header.first_occurrence['part type']], |
77 'physical-colour-part', |
39 'physical-colour') |
78 bad_object = model.body[model.header.first_occurrence['part type']], |
|
79 ) |
40 |
80 |
|
81 @problem_type('official-part', |
|
82 severity = 'error', |
|
83 message = 'new parts must be unofficial', |
|
84 ) |
41 def unofficiality_test(model): |
85 def unofficiality_test(model): |
42 if model.header.valid and not model.header.filetype.startswith('Unofficial_'): |
86 if model.header.valid and not model.header.filetype.startswith('Unofficial_'): |
43 yield error( |
87 yield report_problem( |
44 model.body[model.header.first_occurrence['part type']], |
88 'unofficial-part', |
45 'unofficial-type') |
89 bad_object = model.body[model.header.first_occurrence['part type']]) |
46 |
90 |
|
91 @problem_type('primitive-ccw', |
|
92 severity = 'error', |
|
93 message = 'primitives must have CCW winding', |
|
94 ) |
47 def primitive_ccw_test(model): |
95 def primitive_ccw_test(model): |
48 if model.header.valid \ |
96 if model.header.valid \ |
49 and model.header.filetype.endswith('Primitive') \ |
97 and model.header.filetype.endswith('Primitive') \ |
50 and model.header.bfc != 'CERTIFY CCW': |
98 and model.header.bfc != 'CERTIFY CCW': |
51 yield error( |
99 yield report_problem( |
52 model.body[model.header.first_occurrence['bfc']], |
100 'primitive-bfc-ccw', |
53 'primitive-bfc-ccw') |
101 bad_object = model.body[model.header.first_occurrence['bfc']], |
|
102 ) |
54 |
103 |
55 manifest = { |
104 manifest = { |
56 'tests': { |
105 'tests': [ |
57 'colour-validity': colours_test, |
106 colours_test, |
58 'syntax-errors': syntax_errors, |
107 syntax_errors, |
59 'header-validity': bad_header, |
108 bad_header, |
60 'bfc-nocertify': nocertify_test, |
109 nocertify_test, |
61 'physical-colour': physical_colours_test, |
110 physical_colours_test, |
62 'unofficial-type': unofficiality_test, |
111 unofficiality_test, |
63 'primitive-ccw': primitive_ccw_test, |
112 primitive_ccw_test, |
64 }, |
113 ], |
65 'messages': { |
|
66 'bad-colour': lambda colour_index: str.format( |
|
67 'invalid colour {}', |
|
68 colour_index, |
|
69 ), |
|
70 'syntax-error': lambda reason: str.format( |
|
71 'syntax error: {}', |
|
72 reason, |
|
73 ), |
|
74 'bad-header': lambda reason: str.format( |
|
75 'bad header: {}', |
|
76 reason, |
|
77 ), |
|
78 'bfc-nocertify': 'all new parts must be BFC certified', |
|
79 'physical-colour': 'no new physical colour parts are accepted', |
|
80 'unofficial-type': 'new parts must be unofficial', |
|
81 'primitive-bfc-ccw': 'primitives must have CCW winding', |
|
82 }, |
|
83 } |
114 } |