|
6 | 6 | from unittest import TestCase
|
7 | 7 |
|
8 | 8 | import matplotlib
|
9 |
| -import matplotlib.ft2font |
10 | 9 | import matplotlib.pyplot as plt
|
11 | 10 | import pytest
|
12 | 11 | from helpers import skip_if_format_unsupported
|
13 |
| -from packaging.version import Version |
14 |
| - |
15 |
| -MPL_VERSION = Version(matplotlib.__version__) |
16 | 12 |
|
17 | 13 | baseline_dir = 'baseline'
|
18 |
| - |
19 |
| -if MPL_VERSION >= Version('2'): |
20 |
| - baseline_subdir = '2.0.x' |
| 14 | +baseline_subdir = '2.0.x' |
21 | 15 |
|
22 | 16 | baseline_dir_local = os.path.join(baseline_dir, baseline_subdir)
|
23 | 17 | baseline_dir_remote = 'http://matplotlib.github.io/pytest-mpl/' + baseline_subdir + '/'
|
24 | 18 |
|
25 |
| -ftv = matplotlib.ft2font.__freetype_version__.replace('.', '') |
26 |
| -hash_filename = f"mpl{MPL_VERSION.major}{MPL_VERSION.minor}_ft{ftv}.json" |
27 |
| - |
28 |
| -if "+" in matplotlib.__version__: |
29 |
| - hash_filename = "mpldev.json" |
30 |
| - |
31 |
| -hash_library = (Path(__file__).parent / "baseline" / # noqa |
32 |
| - "hashes" / hash_filename) |
33 |
| - |
34 |
| -fail_hash_library = Path(__file__).parent / "baseline" / "test_hash_lib.json" |
35 | 19 | baseline_dir_abs = Path(__file__).parent / "baseline" / baseline_subdir
|
36 |
| -hash_baseline_dir_abs = Path(__file__).parent / "baseline" / "hybrid" |
37 | 20 |
|
38 | 21 |
|
39 | 22 | WIN = sys.platform.startswith('win')
|
@@ -277,228 +260,6 @@ def test_succeeds(self):
|
277 | 260 | return fig
|
278 | 261 |
|
279 | 262 |
|
280 |
| -# hashlib |
281 |
| - |
282 |
| -@pytest.mark.skipif(not hash_library.exists(), reason="No hash library for this mpl version") |
283 |
| -@pytest.mark.mpl_image_compare(hash_library=hash_library, deterministic=True) |
284 |
| -def test_hash_succeeds(): |
285 |
| - fig = plt.figure() |
286 |
| - ax = fig.add_subplot(1, 1, 1) |
287 |
| - ax.plot([1, 2, 3]) |
288 |
| - return fig |
289 |
| - |
290 |
| - |
291 |
| -TEST_FAILING_HASH = rf""" |
292 |
| -import pytest |
293 |
| -import matplotlib.pyplot as plt |
294 |
| -@pytest.mark.mpl_image_compare(hash_library=r"{fail_hash_library}", deterministic=True) |
295 |
| -def test_hash_fails(): |
296 |
| - fig = plt.figure() |
297 |
| - ax = fig.add_subplot(1,1,1) |
298 |
| - ax.plot([1,2,2]) |
299 |
| - return fig |
300 |
| -""" |
301 |
| - |
302 |
| - |
303 |
| -def test_hash_fails(tmp_path): |
304 |
| - test_file = tmp_path / "test.py" |
305 |
| - test_file.write_text(TEST_FAILING_HASH, encoding="ascii") |
306 |
| - test_file = str(test_file) |
307 |
| - |
308 |
| - # If we use --mpl, it should detect that the figure is wrong |
309 |
| - output = assert_pytest_fails_with(['--mpl', test_file], "doesn't match hash FAIL in library") |
310 |
| - # We didn't specify a baseline dir so we shouldn't attempt to find one |
311 |
| - assert "Image file not found for comparison test" not in output, output |
312 |
| - |
313 |
| - # Check that the summary path is printed and that it exists. |
314 |
| - output = assert_pytest_fails_with(['--mpl', test_file, '--mpl-generate-summary=html'], |
315 |
| - "doesn't match hash FAIL in library") |
316 |
| - # We didn't specify a baseline dir so we shouldn't attempt to find one |
317 |
| - print_message = "A summary of test results can be found at:" |
318 |
| - assert print_message in output, output |
319 |
| - printed_path = Path(output.split(print_message)[1].strip()) |
320 |
| - assert printed_path.exists() |
321 |
| - |
322 |
| - # If we don't use --mpl option, the test should succeed |
323 |
| - code = call_pytest([test_file]) |
324 |
| - assert code == 0 |
325 |
| - |
326 |
| - |
327 |
| -TEST_FAILING_HYBRID = rf""" |
328 |
| -import pytest |
329 |
| -import matplotlib.pyplot as plt |
330 |
| -@pytest.mark.mpl_image_compare(hash_library=r"{fail_hash_library}", |
331 |
| - tolerance=2, deterministic=True) |
332 |
| -def test_hash_fail_hybrid(): |
333 |
| - fig = plt.figure() |
334 |
| - ax = fig.add_subplot(1,1,1) |
335 |
| - ax.plot([1,2,3]) |
336 |
| - return fig |
337 |
| -""" |
338 |
| - |
339 |
| - |
340 |
| -@pytest.mark.skipif(ftv != '261', reason="Incorrect freetype version for hash check") |
341 |
| -def test_hash_fail_hybrid(tmp_path): |
342 |
| - |
343 |
| - test_file = tmp_path / "test.py" |
344 |
| - test_file.write_text(TEST_FAILING_HYBRID, encoding="ascii") |
345 |
| - test_file = str(test_file) |
346 |
| - |
347 |
| - # Assert that image comparison runs and fails |
348 |
| - output = assert_pytest_fails_with(['--mpl', test_file, |
349 |
| - rf'--mpl-baseline-path={hash_baseline_dir_abs / "fail"}'], |
350 |
| - "doesn't match hash FAIL in library") |
351 |
| - assert "Error: Image files did not match." in output, output |
352 |
| - |
353 |
| - # Assert reports missing baseline image |
354 |
| - output = assert_pytest_fails_with(['--mpl', test_file, |
355 |
| - '--mpl-baseline-path=/not/a/path'], |
356 |
| - "doesn't match hash FAIL in library") |
357 |
| - assert "Image file not found for comparison test" in output, output |
358 |
| - |
359 |
| - # Assert reports image comparison succeeds |
360 |
| - output = assert_pytest_fails_with(['--mpl', test_file, |
361 |
| - rf'--mpl-baseline-path={hash_baseline_dir_abs / "succeed"}'], |
362 |
| - "doesn't match hash FAIL in library") |
363 |
| - assert "The comparison to the baseline image succeeded." in output, output |
364 |
| - |
365 |
| - # If we don't use --mpl option, the test should succeed |
366 |
| - code = call_pytest([test_file]) |
367 |
| - assert code == 0 |
368 |
| - |
369 |
| - |
370 |
| -TEST_FAILING_NEW_HASH = r""" |
371 |
| -import pytest |
372 |
| -import matplotlib.pyplot as plt |
373 |
| -@pytest.mark.mpl_image_compare |
374 |
| -def test_hash_fails(): |
375 |
| - fig = plt.figure() |
376 |
| - ax = fig.add_subplot(1,1,1) |
377 |
| - ax.plot([1,2,2]) |
378 |
| - return fig |
379 |
| -""" |
380 |
| - |
381 |
| - |
382 |
| -@pytest.mark.skipif(ftv != '261', reason="Incorrect freetype version for hash check") |
383 |
| -def test_hash_fail_new_hashes(tmp_path): |
384 |
| - # Check that the hash comparison fails even if a new hash file is requested |
385 |
| - test_file = tmp_path / "test.py" |
386 |
| - test_file.write_text(TEST_FAILING_NEW_HASH, encoding="ascii") |
387 |
| - test_file = str(test_file) |
388 |
| - |
389 |
| - # Assert that image comparison runs and fails |
390 |
| - assert_pytest_fails_with(['--mpl', test_file, |
391 |
| - f'--mpl-hash-library={fail_hash_library}'], |
392 |
| - "doesn't match hash FAIL in library") |
393 |
| - |
394 |
| - hash_file = tmp_path / "new_hashes.json" |
395 |
| - # Assert that image comparison runs and fails |
396 |
| - assert_pytest_fails_with(['--mpl', test_file, |
397 |
| - f'--mpl-hash-library={fail_hash_library}', |
398 |
| - f'--mpl-generate-hash-library={hash_file}'], |
399 |
| - "doesn't match hash FAIL") |
400 |
| - |
401 |
| - |
402 |
| -TEST_MISSING_HASH = """ |
403 |
| -import pytest |
404 |
| -import matplotlib.pyplot as plt |
405 |
| -@pytest.mark.mpl_image_compare |
406 |
| -def test_hash_missing(): |
407 |
| - fig = plt.figure() |
408 |
| - ax = fig.add_subplot(1,1,1) |
409 |
| - ax.plot([1,2,2]) |
410 |
| - return fig |
411 |
| -""" |
412 |
| - |
413 |
| - |
414 |
| -def test_hash_missing(tmp_path): |
415 |
| - test_file = tmp_path / "test.py" |
416 |
| - test_file.write_text(TEST_MISSING_HASH) |
417 |
| - test_file = str(test_file) |
418 |
| - |
419 |
| - # Assert fails if hash library missing |
420 |
| - assert_pytest_fails_with(['--mpl', test_file, '--mpl-hash-library=/not/a/path'], |
421 |
| - "Can't find hash library at path") |
422 |
| - |
423 |
| - # Assert fails if hash not in library |
424 |
| - assert_pytest_fails_with(['--mpl', test_file, f'--mpl-hash-library={fail_hash_library}'], |
425 |
| - "Hash for test 'test.test_hash_missing' not found in") |
426 |
| - |
427 |
| - # If we don't use --mpl option, the test should succeed |
428 |
| - code = call_pytest([test_file]) |
429 |
| - assert code == 0 |
430 |
| - |
431 |
| - |
432 |
| -TEST_RESULTS_ALWAYS = """ |
433 |
| -import pytest |
434 |
| -import matplotlib.pyplot as plt |
435 |
| -def plot(): |
436 |
| - fig = plt.figure() |
437 |
| - ax = fig.add_subplot(1,1,1) |
438 |
| - ax.plot([1,2,2]) |
439 |
| - return fig |
440 |
| -@pytest.mark.mpl_image_compare(deterministic=True) |
441 |
| -def test_modified(): return plot() |
442 |
| -@pytest.mark.mpl_image_compare(deterministic=True) |
443 |
| -def test_new(): return plot() |
444 |
| -@pytest.mark.mpl_image_compare(deterministic=True) |
445 |
| -def test_unmodified(): return plot() |
446 |
| -""" |
447 |
| - |
448 |
| - |
449 |
| -@pytest.mark.skipif(not hash_library.exists(), reason="No hash library for this mpl version") |
450 |
| -def test_results_always(tmp_path): |
451 |
| - test_file = tmp_path / "test.py" |
452 |
| - test_file.write_text(TEST_RESULTS_ALWAYS) |
453 |
| - results_path = tmp_path / "results" |
454 |
| - results_path.mkdir() |
455 |
| - |
456 |
| - code = call_pytest(['--mpl', str(test_file), '--mpl-results-always', |
457 |
| - rf'--mpl-hash-library={hash_library}', |
458 |
| - rf'--mpl-baseline-path={baseline_dir_abs}', |
459 |
| - '--mpl-generate-summary=html,json,basic-html', |
460 |
| - rf'--mpl-results-path={results_path}']) |
461 |
| - assert code == 0 # hashes correct, so all should pass |
462 |
| - |
463 |
| - # assert files for interactive HTML exist |
464 |
| - assert (results_path / "fig_comparison.html").exists() |
465 |
| - assert (results_path / "styles.css").exists() |
466 |
| - assert (results_path / "extra.js").exists() |
467 |
| - |
468 |
| - html = (results_path / "fig_comparison_basic.html").read_text() |
469 |
| - with (results_path / "results.json").open("r") as f: |
470 |
| - json_results = json.load(f) |
471 |
| - |
472 |
| - # each test, and which images should exist |
473 |
| - for test, exists in [ |
474 |
| - ('test_modified', ['baseline', 'result-failed-diff', 'result']), |
475 |
| - ('test_new', ['result']), |
476 |
| - ('test_unmodified', ['baseline', 'result']), |
477 |
| - ]: |
478 |
| - |
479 |
| - test_name = f'test.{test}' |
480 |
| - |
481 |
| - summary = f'<div class="test-name">{test_name.split(".")[-1]}</div>' |
482 |
| - assert summary in html |
483 |
| - |
484 |
| - assert test_name in json_results.keys() |
485 |
| - json_res = json_results[test_name] |
486 |
| - assert json_res['status'] == 'passed' |
487 |
| - |
488 |
| - for image_type in ['baseline', 'result-failed-diff', 'result']: |
489 |
| - image = f'{test_name}/{image_type}.png' |
490 |
| - image_exists = (results_path / image).exists() |
491 |
| - json_image_key = f"{image_type.split('-')[-1]}_image" |
492 |
| - if image_type in exists: # assert image so pytest prints it on error |
493 |
| - assert image and image_exists |
494 |
| - assert image in html |
495 |
| - assert json_res[json_image_key] == image |
496 |
| - else: |
497 |
| - assert image and not image_exists |
498 |
| - assert image not in html |
499 |
| - assert json_res[json_image_key] is None |
500 |
| - |
501 |
| - |
502 | 263 | TEST_FAILING_CLASS = """
|
503 | 264 | import pytest
|
504 | 265 | import matplotlib.pyplot as plt
|
|
0 commit comments