tests/subfiles.py

changeset 54
0c686d10eb49
parent 37
e46fa477007b
child 55
388df1fa18a2
equal deleted inserted replaced
53:0cc196c634f1 54:0c686d10eb49
1 from testsuite import warning, error 1 from testsuite import warning, error
2 import testsuite
2 from geometry import * 3 from geometry import *
3 from os.path import dirname 4 from os.path import dirname
4 from pathlib import Path 5 from pathlib import Path
5 from configparser import ConfigParser 6 from configparser import ConfigParser
7 import math
6 ini_path = Path(dirname(__file__)) / 'library-standards.ini' 8 ini_path = Path(dirname(__file__)) / 'library-standards.ini'
7 library_standards = ConfigParser() 9 library_standards = ConfigParser()
8 10
9 with ini_path.open() as file: 11 with ini_path.open() as file:
10 library_standards.read_file(file) 12 library_standards.read_file(file)
81 yield warning(subfile_reference, 'illegal-scaling', 83 yield warning(subfile_reference, 'illegal-scaling',
82 primitive = primitive, 84 primitive = primitive,
83 axes = interesting_axes, 85 axes = interesting_axes,
84 scaling = scaling) 86 scaling = scaling)
85 87
88 def dependent_subfile_tests(model):
89 '''
90 Tests subfile references for such qualities that are dependent on the
91 actual contents of the subfiles. Checks whether moved-to files are used.
92 Checks whether flat subfiles are scaled in the flat direction.
93 '''
94 import filecache
95 cache = filecache.SubfileCache(model.ldraw_directories)
96 failed_subfiles = set()
97 for subfile_reference in model.subfile_references:
98 path = subfile_reference.subfile_path.lower()
99 if path in failed_subfiles:
100 # Already proven to be a bad apple, don't complain twice
101 pass
102 else:
103 try:
104 subfile = cache.prepare_file(path)
105 except filecache.CyclicalReferenceError as e:
106 failed_subfiles.add(path)
107 yield error(subfile_reference, 'cyclical-reference',
108 chain = str(e),
109 )
110 if not subfile.valid:
111 yield error(subfile_reference, 'bad-subfile',
112 path = path,
113 problem_text = subfile.problem,
114 )
115 failed_subfiles.add(path)
116 import re
117 match = re.search(r'^\~Moved(?: to (\w+))?$', subfile.description)
118 if match:
119 yield error(subfile_reference, 'moved-file-used',
120 moved_file = path,
121 new_file = match.group(1))
122 scaling_vector = subfile_reference.matrix.scaling_vector()
123 scaled_dimensions = {
124 dimension
125 for dimension in subfile.flatness
126 if not math.isclose(
127 getattr(scaling_vector, dimension),
128 1,
129 abs_tol = 1.0e-05
130 )
131 }
132 scaled_flat_dimensions = subfile.flatness & scaled_dimensions
133 if scaled_flat_dimensions:
134 yield testsuite.notice(subfile_reference, 'unnecessary-scaling',
135 scaled_flat_dimensions = scaled_flat_dimensions,
136 scaling_vector = scaling_vector,
137 )
138
139 def dimensions_description(dimensions):
140 sorted_dims = sorted(dimensions)
141 if len(sorted_dims) == 1:
142 return sorted_dims[0] + ' dimension'
143 else:
144 return str.format('{} and {} dimensions',
145 ', '.join(sorted_dims[:-1]),
146 sorted_dims[-1],
147 )
148
86 manifest = { 149 manifest = {
87 'tests': { 150 'tests': {
88 'determinant': determinant_test, 151 'determinant': determinant_test,
89 'scaling-legality': scaling_legality_test, 152 'scaling-legality': scaling_legality_test,
153 'dependent-subfiles': dependent_subfile_tests,
90 }, 154 },
91 'messages': { 155 'messages': {
92 'zero-determinant': 'matrix determinant is zero ' 156 'zero-determinant': 'matrix determinant is zero '
93 '(row or column all zero)', 157 '(row or column all zero)',
94 'illegal-scaling': lambda primitive, scaling, axes: 158 'illegal-scaling': lambda primitive, scaling, axes:
95 str.format('scaling of unscalable primitive {} ({})', 159 str.format('scaling of unscalable primitive {} ({})',
96 primitive, 160 primitive,
97 scaling_description(scaling, axes), 161 scaling_description(scaling, axes),
98 ), 162 ),
163 'cyclical-reference': lambda chain:
164 str.format('cyclical subfile dependency: {chain}',
165 **locals(),
166 ),
167 'bad-subfile': lambda path, problem_text:
168 str.format('cannot process subfile "{path}": {problem_text}',
169 **locals(),
170 ),
171 'moved-file-used': lambda moved_file, new_file:
172 str.format('subfile "{moved_file}" has been moved to "{new_file}"',
173 **locals(),
174 ),
175 'unnecessary-scaling': lambda scaled_flat_dimensions, scaling_vector:
176 str.format(
177 'subfile unnecessarily scaled in the {dims} ({scaling})',
178 dims = dimensions_description(scaled_flat_dimensions),
179 scaling = scaling_description(scaling_vector),
180 )
99 }, 181 },
100 } 182 }

mercurial