11 def warning(bad_object, error_name, **args): |
11 def warning(bad_object, error_name, **args): |
12 return report_element(bad_object, 'warning', error_name, args) |
12 return report_element(bad_object, 'warning', error_name, args) |
13 |
13 |
14 def error(bad_object, error_name, **args): |
14 def error(bad_object, error_name, **args): |
15 return report_element(bad_object, 'error', error_name, args) |
15 return report_element(bad_object, 'error', error_name, args) |
|
16 |
|
17 def notice(bad_object, error_name, **args): |
|
18 return report_element(bad_object, 'notice', error_name, args) |
16 |
19 |
17 def test_discovery(): |
20 def test_discovery(): |
18 ''' |
21 ''' |
19 Finds all test modules and yields their names. |
22 Finds all test modules and yields their names. |
20 ''' |
23 ''' |
65 test_suite[key].update(module.manifest[key]) |
68 test_suite[key].update(module.manifest[key]) |
66 else: |
69 else: |
67 warn(str.format('Module {} does not have a manifest', module_name)) |
70 warn(str.format('Module {} does not have a manifest', module_name)) |
68 return test_suite |
71 return test_suite |
69 |
72 |
|
73 def problem_key(problem): |
|
74 problem_hierarchy = ['error', 'warning', 'notice'] |
|
75 return (problem_hierarchy.index(problem['type']), problem['line-number']) |
|
76 |
70 def check_model(model, test_suite = None): |
77 def check_model(model, test_suite = None): |
71 if not test_suite: |
78 if not test_suite: |
72 test_suite = load_tests() |
79 test_suite = load_tests() |
73 report = [] |
80 problems = [] |
74 line_numbers = { |
81 line_numbers = { |
75 element: (i, i + 1 + model.body_offset) |
82 element: (i, i + 1 + model.body_offset) |
76 for i, element in enumerate(model.body) |
83 for i, element in enumerate(model.body) |
77 } |
84 } |
78 for test_name, test_function in test_suite['tests'].items(): |
85 for test_name, test_function in test_suite['tests'].items(): |
79 problems = test_function(model) |
86 for problem in test_function(model): |
80 for problem in problems: |
|
81 problem['body-index'], problem['line-number'] \ |
87 problem['body-index'], problem['line-number'] \ |
82 = line_numbers[problem['object']] |
88 = line_numbers[problem['object']] |
83 del problem['object'] |
89 del problem['object'] |
84 report.append(problem) |
90 problems.append(problem) |
85 return report |
91 return { |
|
92 'passed': not any( |
|
93 problem['type'] == 'error' |
|
94 for problem in problems |
|
95 ), |
|
96 'problems': sorted(problems, key = problem_key), |
|
97 } |
86 |
98 |
87 def problem_text(problem, test_suite): |
99 def problem_text(problem, test_suite): |
88 message = test_suite['messages'][problem['name']] |
100 message = test_suite['messages'][problem['name']] |
89 if callable(message): |
101 if callable(message): |
90 message = message(**problem['args']) |
102 message = message(**problem['args']) |
91 return message |
103 return message |
92 |
104 |
93 def format_report_html(report, model, test_suite): |
105 def format_report_html(report, model, test_suite): |
94 result = [] |
106 messages = [] |
95 for problem in report: |
107 for problem in report['problems']: |
96 ldraw_code = model.body[problem['body-index']].textual_representation() |
108 ldraw_code = model.body[problem['body-index']].textual_representation() |
97 message = str.format( |
109 message = str.format( |
98 '<li class="{problem_type}">{model_name}:{line_number}:' |
110 '<li class="{problem_type}">{model_name}:{line_number}:' |
99 '{problem_type}: {message}<br />{ldraw_code}</li>', |
111 '{problem_type}: {message}<br />{ldraw_code}</li>', |
100 model_name = model.name, |
112 model_name = model.name, |
101 line_number = problem['line-number'], |
113 line_number = problem['line-number'], |
102 problem_type = problem['type'], |
114 problem_type = problem['type'], |
103 message = problem_text(problem, test_suite), |
115 message = problem_text(problem, test_suite), |
104 ldraw_code = ldraw_code, |
116 ldraw_code = ldraw_code, |
105 ) |
117 ) |
106 result.append((problem['line-number'], message)) |
118 messages.append(message) |
107 return '\n'.join( |
119 return '\n'.join(messages) |
108 problem[1] |
|
109 for problem in sorted(result) |
|
110 ) |
|
111 |
120 |
112 def format_report(report, model, test_suite): |
121 def format_report(report, model, test_suite): |
113 import colorama |
122 import colorama |
114 colorama.init() |
123 colorama.init() |
115 result = [] |
124 messages = [] |
116 for problem in report: |
125 for problem in report['problems']: |
117 if problem['type'] == 'error': |
126 if problem['type'] == 'error': |
118 text_colour = colorama.Fore.LIGHTRED_EX |
127 text_colour = colorama.Fore.LIGHTRED_EX |
119 elif problem['type'] == 'warning': |
128 elif problem['type'] == 'warning': |
120 text_colour = colorama.Fore.LIGHTYELLOW_EX |
129 text_colour = colorama.Fore.LIGHTYELLOW_EX |
|
130 elif problem['type'] == 'notice': |
|
131 text_colour = colorama.Fore.LIGHTBLUE_EX |
121 else: |
132 else: |
122 text_colour = '' |
133 text_colour = '' |
123 ldraw_code = model.body[problem['body-index']].textual_representation() |
134 ldraw_code = model.body[problem['body-index']].textual_representation() |
124 message = str.format( |
135 message = str.format( |
125 '{text_colour}{model_name}:{line_number}: {problem_type}: {message}' |
136 '{text_colour}{model_name}:{line_number}: {problem_type}: {message}' |