Sat, 01 Jun 2019 10:47:58 +0300
fixed BFC INVERTNEXT being interpreted as a header command
24 | 1 | from testsuite import warning, error |
54
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
2 | import testsuite |
24 | 3 | from geometry import * |
4 | from os.path import dirname | |
5 | from pathlib import Path | |
6 | from configparser import ConfigParser | |
54
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
7 | import math |
24 | 8 | ini_path = Path(dirname(__file__)) / 'library-standards.ini' |
9 | library_standards = ConfigParser() | |
10 | ||
37
e46fa477007b
Fix operation under Python 3.4
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
11 | with ini_path.open() as file: |
24 | 12 | library_standards.read_file(file) |
23 | 13 | |
14 | def determinant_test(model): | |
26
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
24
diff
changeset
|
15 | ''' |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
24
diff
changeset
|
16 | Checks all subfile references for matrices with rows or columns all |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
24
diff
changeset
|
17 | zero. |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
24
diff
changeset
|
18 | ''' |
24 | 19 | yield from ( |
23 | 20 | error(subfile_reference, 'zero-determinant') |
21 | for subfile_reference in model.subfile_references | |
22 | if abs(subfile_reference.matrix.determinant() - 0) < 1e-15 | |
24 | 23 | ) |
24 | ||
25 | def scaling_description(scaling, axes = 'xyz'): | |
26 | ''' | |
27 | Returns a pretty description of a scaling vector. The axes parameter | |
28 | controls what axes are printed and can be used to filter away | |
29 | uninteresting values. | |
30 | ''' | |
31 | return ', '.join( | |
32 | str.format('{} = {}', letter, getattr(scaling, letter)) | |
33 | for letter in axes | |
34 | ) | |
35 | ||
36 | def check_scaling(scaling, axes): | |
37 | ''' Returns whether all given axes on the given scaling vector are 1. ''' | |
38 | return all( | |
39 | abs(getattr(scaling, axis) - 1) < 1e-5 | |
40 | for axis in axes | |
41 | ) | |
42 | ||
43 | # Restriction to checking function mapping. | |
44 | restriction_tests = { | |
45 | 'no scaling': lambda scaling: check_scaling(scaling, 'xyz'), | |
46 | 'y-scaling only': lambda scaling: check_scaling(scaling, 'xz'), | |
47 | 'stud3-like scaling': lambda scaling: all([ | |
48 | check_scaling(scaling, 'xz'), | |
49 | # check if y-scaling is 1 or -1 | |
50 | abs(abs(scaling.y) - 1) < 1e-5, | |
51 | ]), | |
52 | } | |
53 | ||
54 | def scaling_legality_test(model): | |
26
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
24
diff
changeset
|
55 | ''' |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
24
diff
changeset
|
56 | Checks the part against primitive references with bad scaling. Some |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
24
diff
changeset
|
57 | primitives (e.g. pegs) are not allowed to be scaled in the |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
24
diff
changeset
|
58 | X or Z directions. Some (e.g. most studs) are not allowed to be scaled |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
24
diff
changeset
|
59 | in the Y direction either. |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
24
diff
changeset
|
60 | ''' |
24 | 61 | from fnmatch import fnmatch |
62 | scaling_restrictions = library_standards['scaling restrictions'] | |
63 | for subfile_reference in model.subfile_references: | |
64 | primitive = subfile_reference.subfile_path.lower() | |
65 | scaling = subfile_reference.matrix.scaling_vector() | |
66 | # Find all restrictions that apply to this subfile reference. | |
67 | restrictions = { | |
68 | restriction | |
69 | for pattern, restriction in scaling_restrictions.items() | |
70 | if fnmatch(primitive, pattern) | |
71 | } | |
72 | # Check restrictions against the subfile. If any restrictions were | |
73 | # found then the scaling vector must pass at least one of them. | |
74 | if restrictions and not any( | |
75 | restriction_tests[restriction](scaling) | |
76 | for restriction in restrictions | |
77 | ): | |
78 | interesting_axes = ''.join( | |
79 | axis | |
80 | for axis in 'xyz' | |
81 | if abs(getattr(scaling, axis) - 1) > 1e-5 | |
82 | ) | |
83 | yield warning(subfile_reference, 'illegal-scaling', | |
84 | primitive = primitive, | |
85 | axes = interesting_axes, | |
86 | scaling = scaling) | |
23 | 87 | |
54
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
88 | def dependent_subfile_tests(model): |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
89 | ''' |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
90 | Tests subfile references for such qualities that are dependent on the |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
91 | actual contents of the subfiles. Checks whether moved-to files are used. |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
92 | Checks whether flat subfiles are scaled in the flat direction. |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
93 | ''' |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
94 | import filecache |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
95 | cache = filecache.SubfileCache(model.ldraw_directories) |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
96 | failed_subfiles = set() |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
97 | for subfile_reference in model.subfile_references: |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
98 | path = subfile_reference.subfile_path.lower() |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
99 | if path in failed_subfiles: |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
100 | # Already proven to be a bad apple, don't complain twice |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
101 | pass |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
102 | else: |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
103 | try: |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
104 | subfile = cache.prepare_file(path) |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
105 | except filecache.CyclicalReferenceError as e: |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
106 | failed_subfiles.add(path) |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
107 | yield error(subfile_reference, 'cyclical-reference', |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
108 | chain = str(e), |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
109 | ) |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
110 | if not subfile.valid: |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
111 | yield error(subfile_reference, 'bad-subfile', |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
112 | path = path, |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
113 | problem_text = subfile.problem, |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
114 | ) |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
115 | failed_subfiles.add(path) |
55
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
116 | else: |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
117 | import re |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
118 | match = re.search(r'^\~Moved(?: to (\w+))?$', subfile.description) |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
119 | if match: |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
120 | yield error(subfile_reference, 'moved-file-used', |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
121 | moved_file = path, |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
122 | new_file = match.group(1)) |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
123 | scaling_vector = subfile_reference.matrix.scaling_vector() |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
124 | scaled_dimensions = { |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
125 | dimension |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
126 | for dimension in subfile.flatness |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
127 | if not math.isclose( |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
128 | getattr(scaling_vector, dimension), |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
129 | 1, |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
130 | abs_tol = 1.0e-05 |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
131 | ) |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
132 | } |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
133 | scaled_flat_dimensions = subfile.flatness & scaled_dimensions |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
134 | if scaled_flat_dimensions: |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
135 | yield testsuite.notice(subfile_reference, 'unnecessary-scaling', |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
136 | scaled_flat_dimensions = scaled_flat_dimensions, |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
137 | scaling_vector = scaling_vector, |
388df1fa18a2
fixed handling of invalid subfiles
Teemu Piippo <teemu@hecknology.net>
parents:
54
diff
changeset
|
138 | ) |
54
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
139 | |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
140 | def dimensions_description(dimensions): |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
141 | sorted_dims = sorted(dimensions) |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
142 | if len(sorted_dims) == 1: |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
143 | return sorted_dims[0] + ' dimension' |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
144 | else: |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
145 | return str.format('{} and {} dimensions', |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
146 | ', '.join(sorted_dims[:-1]), |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
147 | sorted_dims[-1], |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
148 | ) |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
149 | |
23 | 150 | manifest = { |
151 | 'tests': { | |
152 | 'determinant': determinant_test, | |
24 | 153 | 'scaling-legality': scaling_legality_test, |
54
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
154 | 'dependent-subfiles': dependent_subfile_tests, |
23 | 155 | }, |
156 | 'messages': { | |
157 | 'zero-determinant': 'matrix determinant is zero ' | |
158 | '(row or column all zero)', | |
24 | 159 | 'illegal-scaling': lambda primitive, scaling, axes: |
160 | str.format('scaling of unscalable primitive {} ({})', | |
161 | primitive, | |
162 | scaling_description(scaling, axes), | |
163 | ), | |
54
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
164 | 'cyclical-reference': lambda chain: |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
165 | str.format('cyclical subfile dependency: {chain}', |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
166 | **locals(), |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
167 | ), |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
168 | 'bad-subfile': lambda path, problem_text: |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
169 | str.format('cannot process subfile "{path}": {problem_text}', |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
170 | **locals(), |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
171 | ), |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
172 | 'moved-file-used': lambda moved_file, new_file: |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
173 | str.format('subfile "{moved_file}" has been moved to "{new_file}"', |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
174 | **locals(), |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
175 | ), |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
176 | 'unnecessary-scaling': lambda scaled_flat_dimensions, scaling_vector: |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
177 | str.format( |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
178 | 'subfile unnecessarily scaled in the {dims} ({scaling})', |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
179 | dims = dimensions_description(scaled_flat_dimensions), |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
180 | scaling = scaling_description(scaling_vector), |
0c686d10eb49
added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
37
diff
changeset
|
181 | ) |
23 | 182 | }, |
183 | } |