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 } |