6from dataclasses
import dataclass
13EXACT_MATCHING =
'exact'
14FUZZY_MATCHING =
'fuzzy'
16_PNG_OPTIMIZER =
'optipng'
20_COMMON_SUFFIX_ORDER = (
'_{os}',
'')
21_AGG_SUFFIX_ORDER = (
'_agg_{os}',
'_agg') + _COMMON_SUFFIX_ORDER
22_GDI_AGG_SUFFIX_ORDER = (
'_gdi_agg_{os}',
'_gdi_agg',
'_gdi_{os}',
23 '_gdi') + _COMMON_SUFFIX_ORDER
24_GDI_SKIA_SUFFIX_ORDER = (
'_gdi_skia_{os}',
'_gdi_skia',
'_gdi_{os}',
25 '_gdi') + _COMMON_SUFFIX_ORDER
26_SKIA_SUFFIX_ORDER = (
'_skia_{os}',
'_skia') + _COMMON_SUFFIX_ORDER
31 """Details about an image diff.
34 actual_path: Path to the actual image file.
35 expected_path: Path to the expected image file, or `None` if no matches.
36 diff_path: Path to the diff image file, or `None` if no diff.
37 reason: Optional reason for the diff.
40 expected_path: str =
None
46 def __init__(self, finder, reverse_byte_order, rendering_option,
53 if rendering_option ==
'gdi':
54 if default_renderer ==
'agg':
56 elif default_renderer ==
'skia':
58 elif rendering_option ==
'agg':
60 elif rendering_option ==
'skia':
64 raise ValueError(f
'rendering_option={rendering_option}')
67 if regenerate_expected
and not shutil.which(_PNG_OPTIMIZER):
68 return f
'Please install "{_PNG_OPTIMIZER}" to regenerate expected images.'
73 path_templates =
_PathTemplates(input_filename, source_dir, working_dir,
76 for page
in itertools.count():
77 actual_path = path_templates.GetActualPath(page)
78 if path_templates.GetExpectedPath(page, default_to_base=
False):
79 actual_paths.append(actual_path)
86 subprocess.run(cmd, capture_output=
True, check=
True)
88 except subprocess.CalledProcessError
as e:
94 cmd.append(
'--reverse-byte-order')
95 if image_matching_algorithm == FUZZY_MATCHING:
97 cmd.extend([image_diff.actual_path, image_diff.expected_path])
104 image_diff.expected_path, image_diff.diff_path
108 image_matching_algorithm):
109 """Computes differences between actual and expected image files.
112 A list of `ImageDiff` instances, one per differing page.
116 path_templates =
_PathTemplates(input_filename, source_dir, working_dir,
118 for page
in itertools.count():
119 page_diff =
ImageDiff(actual_path=path_templates.GetActualPath(page))
120 if not os.path.exists(page_diff.actual_path):
124 expected_path = path_templates.GetExpectedPath(page)
125 if os.path.exists(expected_path):
126 page_diff.expected_path = expected_path
129 image_matching_algorithm)
131 page_diff.reason =
str(compare_error)
134 page_diff.diff_path = path_templates.GetDiffPath(page)
136 print(f
'WARNING: No diff for {page_diff.actual_path}')
137 page_diff.diff_path =
None
140 for unexpected_path
in path_templates.GetExpectedPaths(page)[1:]:
141 page_diff.expected_path = unexpected_path
143 image_matching_algorithm):
144 page_diff.reason = f
'Also matches {unexpected_path}'
146 page_diff.expected_path = expected_path
149 print(f
'WARNING: no expected results files for {input_filename}')
150 page_diff.reason = f
'{expected_path} does not exist'
153 image_diffs.append(page_diff)
157 def Regenerate(self, input_filename, source_dir, working_dir,
158 image_matching_algorithm):
159 path_templates =
_PathTemplates(input_filename, source_dir, working_dir,
161 for page
in itertools.count():
162 expected_paths = path_templates.GetExpectedPaths(page)
166 page_diff =
ImageDiff(actual_path=path_templates.GetActualPath(page))
167 if os.path.exists(page_diff.actual_path):
169 for index, expected_path
in enumerate(expected_paths):
170 page_diff.expected_path = expected_path
172 image_matching_algorithm):
173 if first_match
is None:
183 print(f
'WARNING: {input_filename} has extra expected page {page}')
185 last_match = len(expected_paths)
195 if last_match
is not None:
197 print(f
'WARNING: {input_filename}.{page} has non-adjacent match')
198 if first_match != last_match:
199 print(f
'WARNING: {input_filename}.{page} has redundant matches')
201 for expected_path
in expected_paths[:last_match]:
202 os.rename(expected_path, expected_path +
'.bak')
207 expected_path = path_templates.GetExpectedPath(page)
208 shutil.copyfile(page_diff.actual_path, expected_path)
212_ACTUAL_TEMPLATE =
'.pdf.%d.png'
213_DIFF_TEMPLATE =
'.pdf.%d.diff.png'
218 def __init__(self, input_filename, source_dir, working_dir, os_name,
220 input_root, _ = os.path.splitext(input_filename)
222 input_root + _ACTUAL_TEMPLATE)
224 input_root + _DIFF_TEMPLATE)
229 for suffix
in suffix_order:
230 formatted_suffix = suffix.format(os=os_name)
234 f
'{input_root}_expected{formatted_suffix}{_ACTUAL_TEMPLATE}'))
250 """Returns the most specific expected path that exists."""
251 last_not_found_expected_path =
None
253 if os.path.exists(expected_path):
255 last_not_found_expected_path = expected_path
256 return last_not_found_expected_path
if default_to_base
else None
list append(new Employee("Blackpool", "Stephen"))
QDebug print(QDebug debug, QSslError::SslError error)