Coverage for tests/test_tests_checks.py: 100%

64 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-09-10 09:12 +0000

1# This file is part of lsst-images. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# Use of this source code is governed by a 3-clause BSD-style 

10# license that can be found in the LICENSE file. 

11 

12from __future__ import annotations 

13 

14import astropy.units as u 

15import numpy as np 

16import pytest 

17 

18from lsst.images import Box, Mask, MaskPlane, MaskSchema 

19from lsst.images.tests import annotate_errors, assert_masks_equal, assert_values_equal 

20 

21 

22def test_assert_values_equal_passes(): 

23 """Assert equal arrays pass.""" 

24 assert_values_equal(np.array([1, 2, 3]), np.array([1, 2, 3])) 

25 

26 

27def test_assert_values_equal_nan_equal_by_default(): 

28 """Assert NaN compares equal by default.""" 

29 a = np.array([1.0, np.nan]) 

30 assert_values_equal(a, a.copy()) 

31 

32 

33def test_assert_values_equal_exact_by_default(): 

34 """Assert a small difference fails by default (exact equality).""" 

35 with pytest.raises(AssertionError, match="max abs diff"): 

36 assert_values_equal(np.array([1.0]), np.array([1.0 + 1e-6])) 

37 

38 

39def test_assert_values_equal_rtol_passes(): 

40 """Assert an explicit relative tolerance passes.""" 

41 assert_values_equal(np.array([1.0]), np.array([1.0 + 1e-6]), rtol=1e-5) 

42 

43 

44def test_assert_values_equal_fails_with_report(): 

45 """Assert a mismatch raises a report message.""" 

46 a = np.array([1.0, 2.0, 3.0]) 

47 b = np.array([1.0, 2.0, 4.0]) 

48 with pytest.raises(AssertionError, match="1/3 values differ"): 

49 assert_values_equal(a, b) 

50 

51 

52def test_assert_values_equal_label_prefix(): 

53 """Assert the label prefixes the failure message.""" 

54 with pytest.raises(AssertionError, match=r"^mask\[BAD\]: "): 

55 assert_values_equal(np.array([True]), np.array([False]), label="mask[BAD]") 

56 

57 

58def test_assert_values_equal_shape_mismatch(): 

59 """Assert a shape mismatch raises.""" 

60 with pytest.raises(AssertionError, match="shape"): 

61 assert_values_equal(np.zeros((2, 2)), np.zeros((3, 3))) 

62 

63 

64def test_assert_values_equal_non_numeric_reports_indices(): 

65 """Assert non-numeric arrays report differing indices.""" 

66 a = np.array(["a", "b", "c"]) 

67 b = np.array(["a", "b", "z"]) 

68 with pytest.raises(AssertionError, match="values differ"): 

69 assert_values_equal(a, b) 

70 

71 

72def test_assert_values_equal_nan_not_equal_to_number(): 

73 """Assert NaN still does not equal a finite number.""" 

74 with pytest.raises(AssertionError): 

75 assert_values_equal(np.array([np.nan]), np.array([1.0])) 

76 

77 

78def test_assert_values_equal_atol_quantity_unit_aware(): 

79 """Assert a Quantity atol is converted to the unit of a.""" 

80 a = np.array([1.0, 2.0]) * u.deg 

81 b = a.to(u.arcsec) 

82 assert_values_equal(a, b, rtol=0.0, atol=1e-7 * u.arcsec) 

83 

84 

85def test_assert_values_equal_unit_aware(): 

86 """Assert unit-aware comparison converts b to the unit of a.""" 

87 a = np.array([1.0, 2.0]) * u.deg 

88 b = a.to(u.arcsec) 

89 assert_values_equal(a, b, rtol=1e-5, atol=0.0) 

90 

91 

92def test_assert_values_equal_incompatible_units_raise(): 

93 """Assert incompatible units raise.""" 

94 with pytest.raises(u.UnitConversionError): 

95 assert_values_equal(np.array([1.0]) * u.deg, np.array([1.0]) * u.s) 

96 

97 

98def test_label_assertions_notes(): 

99 """Assert a failing check is re-raised with the label as a note.""" 

100 with pytest.raises(AssertionError) as exc_info: 

101 with annotate_errors("psf"): 

102 raise AssertionError("inner") 

103 assert exc_info.value.args == ("inner",) 

104 assert exc_info.value.__notes__ == ["psf"] 

105 

106 

107def test_label_assertions_passthrough_on_success(): 

108 """Assert a passing block is not re-raised.""" 

109 with annotate_errors("psf"): 

110 pass # must not raise 

111 

112 

113def test_assert_masks_equal_notes_plane_diff() -> None: 

114 """Assert that a mask mismatch adds a per-plane +/- note.""" 

115 schema = MaskSchema([MaskPlane("A", "dA")], dtype=np.uint8) 

116 m1 = Mask(0, schema=schema, bbox=Box.factory[0:2, 0:1]) 

117 m1.set("A", np.array([[True], [False]])) 

118 m2 = Mask(0, schema=schema, bbox=Box.factory[0:2, 0:1]) 

119 m2.set("A", np.array([[True], [True]])) 

120 with pytest.raises(AssertionError) as excinfo: 

121 assert_masks_equal(m1, m2) 

122 notes = excinfo.value.__notes__ or [] 

123 assert any("mask[A]: +0 -1" in n for n in notes)