Coverage for tests/test_datum.py: 19%
98 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-23 09:10 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-23 09:10 +0000
1# This file is part of verify.
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# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
21import unittest
23import astropy.units as u
24import yaml
26from lsst.verify import Datum
29class DatumTestCase(unittest.TestCase):
30 """Test Datum functionality"""
32 def test_properties(self):
33 """Validate basic setters and getters."""
34 d = Datum(5., 'mmag', label='millimag', description='Hello world')
36 self.assertIsInstance(d.quantity, u.Quantity)
38 self.assertEqual(d.quantity.value, 5.)
40 d.quantity = 7 * u.mmag
41 self.assertEqual(d.quantity.value, 7)
43 self.assertEqual(d.unit_str, 'mmag')
44 self.assertEqual(d.unit, u.mmag)
46 # change units
47 d.quantity = 5 * u.mag
48 self.assertEqual(d.unit, u.mag)
50 self.assertEqual(d.label, 'millimag')
51 d.label = 'magnitudes'
52 self.assertEqual(d.label, 'magnitudes')
54 self.assertEqual(d.description, 'Hello world')
55 d.description = 'Updated description.'
56 self.assertEqual(d.description, 'Updated description.')
58 def test_bad_unit(self):
59 """Ensure that units are being validated by astropy."""
60 with self.assertRaises(ValueError):
61 Datum(5., 'millimag')
63 def test_no_units(self):
64 """Ensure an exception is raised if not units are provided to Datum.
65 """
66 with self.assertRaises(ValueError):
67 Datum(5.)
69 def test_init_with_quantity(self):
70 """Ensure a Datum can be build from a Quantity."""
71 d = Datum(5 * u.mag)
73 self.assertEqual(d.quantity.value, 5.)
74 self.assertEqual(d.unit_str, 'mag')
76 def test_quantity_update(self):
77 """Verify that when a quantity is updated the unit attributes
78 are updated.
79 """
80 d = Datum(5 * u.mag)
81 self.assertEqual(d.quantity.value, 5.)
82 self.assertEqual(d.unit_str, 'mag')
84 d.quantity = 100. * u.mmag
85 self.assertEqual(d.quantity.value, 100.)
86 self.assertEqual(d.unit_str, 'mmag')
88 def _assertDatumsEqual(self, datum1, datum2):
89 """Test that two Datums are equal without calling ``__eq__``.
90 """
91 self.assertEqual(datum1.quantity, datum2.quantity)
92 self.assertEqual(datum1.unit, datum2.unit)
93 self.assertEqual(datum1.label, datum2.label)
94 self.assertEqual(datum1.description, datum2.description)
96 def _checkRoundTrip(self, d):
97 """Test that a Datum can be serialized and restored.
98 """
99 json_data = d.json
100 d2 = Datum.deserialize(**json_data)
101 self._assertDatumsEqual(d, d2)
103 yaml_data = yaml.dump(d)
104 d3 = yaml.safe_load(yaml_data)
105 self._assertDatumsEqual(d, d3)
107 def test_unitless(self):
108 """Ensure that Datums can be unitless too."""
109 d = Datum(5., '')
110 self.assertEqual(d.unit_str, '')
111 self.assertEqual(d.unit, u.dimensionless_unscaled)
113 self._checkRoundTrip(d)
115 def test_str_quantity(self):
116 """Quantity as a string."""
117 d = Datum('Hello world', label='Test string',
118 description='Test description.')
119 self.assertEqual(d.quantity, 'Hello world')
120 self.assertIsNone(d.unit)
121 self.assertEqual(d.unit_str, '')
122 self.assertEqual(d.label, 'Test string')
123 self.assertEqual(d.description, 'Test description.')
125 self._checkRoundTrip(d)
127 def test_bool_quantity(self):
128 """Quantity as a boolean."""
129 d = Datum(True, label='Test boolean',
130 description='Test description.')
131 self.assertTrue(d.quantity)
132 self.assertIsNone(d.unit)
133 self.assertEqual(d.unit_str, '')
134 self.assertEqual(d.label, 'Test boolean')
135 self.assertEqual(d.description, 'Test description.')
137 self._checkRoundTrip(d)
139 def test_int_quantity(self):
140 """Quantity as a unitless int."""
141 d = Datum(5, label='Test int',
142 description='Test description.')
143 self.assertEqual(d.quantity, 5)
144 self.assertIsNone(d.unit)
145 self.assertEqual(d.unit_str, '')
146 self.assertEqual(d.label, 'Test int')
147 self.assertEqual(d.description, 'Test description.')
149 self._checkRoundTrip(d)
151 def test_none(self):
152 """Quantity as None."""
153 d = Datum(None, label='Test None',
154 description='Test description.')
155 self.assertIsNone(d.quantity)
156 self.assertIsNone(d.unit)
157 self.assertEqual(d.unit_str, '')
158 self.assertEqual(d.label, 'Test None')
159 self.assertEqual(d.description, 'Test description.')
161 self._checkRoundTrip(d)
163 def test_json_output(self):
164 """Verify content from json property and deserialization."""
165 d = Datum(5., 'mmag', label='millimag', description='Hello world')
166 dj = d.json
168 self.assertEqual(d.quantity.value, dj['value'])
169 self.assertEqual(d.unit_str, dj['unit'])
170 self.assertEqual(d.label, dj['label'])
171 self.assertEqual(d.description, dj['description'])
173 new_datum = Datum.deserialize(**dj)
174 self.assertEqual(d, new_datum)
177if __name__ == "__main__": 177 ↛ 178line 177 didn't jump to line 178, because the condition on line 177 was never true
178 unittest.main()