1 from testsuite import problem_type, report_problem |
1 from testsuite import problem_type, report_problem |
2 import testsuite |
2 import testsuite |
3 from geometry import * |
3 from geometry import * |
4 from os.path import dirname |
|
5 from pathlib import Path |
|
6 from configparser import ConfigParser |
|
7 import math |
4 import math |
8 ini_path = Path(dirname(__file__)) / 'library-standards.ini' |
5 from librarystandards import library_standards |
9 library_standards = ConfigParser() |
|
10 |
|
11 with ini_path.open() as file: |
|
12 library_standards.read_file(file) |
|
13 |
6 |
14 @problem_type('zero-determinant', |
7 @problem_type('zero-determinant', |
15 severity = 'hold', |
8 severity = 'hold', |
16 message = 'matrix row or column all zero' |
9 message = 'matrix row or column all zero' |
17 ) |
10 ) |
228 return str.format('{} and {} dimensions', |
221 return str.format('{} and {} dimensions', |
229 ', '.join(sorted_dims[:-1]), |
222 ', '.join(sorted_dims[:-1]), |
230 sorted_dims[-1], |
223 sorted_dims[-1], |
231 ) |
224 ) |
232 |
225 |
233 @problem_type('bad-category', |
|
234 severity = 'hold', |
|
235 message = lambda category: str.format( |
|
236 '"{category}" is not an official category', |
|
237 category = category, |
|
238 ) |
|
239 ) |
|
240 @problem_type('bad-category-in-description', |
|
241 severity = 'hold', |
|
242 message = lambda category: str.format( |
|
243 'the category "{category}" must be set using !CATEGORY ' |
|
244 'and not by description', |
|
245 category = category, |
|
246 ) |
|
247 ) |
|
248 def category_test(model): |
|
249 if model.header.valid: |
|
250 categories = library_standards['categories'] |
|
251 illegal_categories_in_description = [ |
|
252 category_name.lower() |
|
253 for category_name in categories.keys() |
|
254 if ' ' in category_name |
|
255 ] |
|
256 has_bad_category = False |
|
257 if model.header.effective_category not in categories.keys(): |
|
258 try: |
|
259 bad_object = model.find_first_header_object('category') |
|
260 except KeyError: |
|
261 # category was not specified using !CATEGORY, blame |
|
262 # the description instead |
|
263 bad_object = model.body[0] |
|
264 has_bad_category = True |
|
265 yield report_problem( |
|
266 'bad-category', |
|
267 bad_object = bad_object, |
|
268 category = model.header.effective_category, |
|
269 ) |
|
270 # Check if the description sets a multi-word category |
|
271 if not has_bad_category and model.header.category is None: |
|
272 for category_name in illegal_categories_in_description: |
|
273 if model.header.description.lower().startswith(category_name): |
|
274 yield report_problem( |
|
275 'bad-category-in-description', |
|
276 bad_object = model.body[0], |
|
277 category = category_name.title(), |
|
278 ) |
|
279 break |
|
280 |
|
281 @problem_type('mirrored-studs', |
|
282 severity = 'warning', |
|
283 message = lambda primitive: str.format( |
|
284 '"{primitive}" should not be mirrored', |
|
285 primitive = primitive, |
|
286 ) |
|
287 ) |
|
288 def mirrored_studs_test(model): |
|
289 for subfile_reference in model.subfile_references: |
|
290 # Test whether any stud subfile is mirrored. |
|
291 # A subfile is mirrored if its determinant is negative. |
|
292 if subfile_reference.subfile_path.startswith('stu') \ |
|
293 and subfile_reference.subfile_path != 'stud4.dat' \ |
|
294 and subfile_reference.matrix.determinant() < 0: |
|
295 yield report_problem( |
|
296 'mirrored-studs', |
|
297 bad_object = subfile_reference, |
|
298 primitive = subfile_reference.subfile_path, |
|
299 ) |
|
300 |
|
301 manifest = { |
226 manifest = { |
302 'tests': [ |
227 'tests': [ |
303 determinant_test, |
228 determinant_test, |
304 scaling_legality_test, |
229 scaling_legality_test, |
305 dependent_subfile_tests, |
230 dependent_subfile_tests, |
306 category_test, |
|
307 mirrored_studs_test, |
|
308 ], |
231 ], |
309 } |
232 } |