Coverage for tests/test_dict.py: 7%
190 statements
« prev ^ index » next coverage.py v7.2.4, created at 2023-04-29 02:59 -0700
« prev ^ index » next coverage.py v7.2.4, created at 2023-04-29 02:59 -0700
1# This file is part of daf_base
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://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 <http://www.gnu.org/licenses/>.
22"""Test dict emulation"""
24import unittest
25import copy
27import lsst.daf.base
30class DictTestCase(unittest.TestCase):
32 def setUp(self):
34 pl = lsst.daf.base.PropertyList()
35 pl.setBool("bool", True)
36 pl.setShort("short", 42)
37 pl.setInt("int", 2008)
38 pl.setLongLong("int64_t", 0xfeeddeadbeef)
39 pl.setFloat("float", 3.14159)
40 pl.setDouble("double", 2.718281828459045)
41 pl.set("char*", "foo", "char comment")
42 pl.setString("string", "bar")
43 pl.set("int2", 2009, "int comment")
44 pl.set("dt", lsst.daf.base.DateTime("20090402T072639.314159265Z", lsst.daf.base.DateTime.UTC))
45 pl.set("undef", None)
47 ps = lsst.daf.base.PropertySet()
48 ps.setBool("bool", True)
49 ps.setShort("short", 42)
50 ps.setInt("int", 2008)
51 ps.setLongLong("long", 5) # Deliberately small
52 ps.setLongLong("int64_t", 0xfeeddeadbeef)
53 ps.setFloat("float", 3.14159)
54 ps.setDouble("double", 2.718281828459045)
55 ps.set("char*", "foo")
56 ps.setString("string", "bar")
57 ps.set("char*", u"foo")
58 ps.setString("string", u"bar")
59 ps.set("int2", 2009)
60 ps.set("dt", lsst.daf.base.DateTime("20090402T072639.314159265Z", lsst.daf.base.DateTime.UTC))
61 ps.set("blank", "")
62 ps.addInt("int", 2009)
63 ps.set("undef", None)
65 ps2 = lsst.daf.base.PropertySet()
66 ps2.setBool("bool2", False)
67 ps2.setShort("short2", 16)
68 ps2.setInt("int2", 2018)
70 ps.setPropertySet("ps2", ps2)
71 pl.setPropertySet("ps2", ps2)
73 self.ps = ps
74 self.pl = pl
76 def testShallowCopyPropertySet(self):
77 shallow = copy.copy(self.ps)
78 self.assertIsInstance(shallow, lsst.daf.base.PropertySet)
79 self.assertIn("ps2", shallow)
80 self.assertEqual(shallow, self.ps)
82 # Modifying the attached property set should change both views
83 ps2 = self.ps.getScalar("ps2")
84 ps2s = shallow.getScalar("ps2")
85 self.assertEqual(ps2, ps2s)
87 ps2["int2"] = 2017
88 self.assertEqual(ps2, ps2s)
90 def testDeepCopyPropertySet(self):
91 deep = copy.deepcopy(self.ps)
92 self.assertIsInstance(deep, lsst.daf.base.PropertySet)
93 self.assertEqual(deep, self.ps)
95 # Modifying the contents of ps2 should not affect the original
96 ps2 = self.ps.getScalar("ps2")
97 ps2d = deep.getScalar("ps2")
98 self.assertEqual(ps2, ps2d)
100 ps2["int2"] = 2017
101 self.assertNotEqual(ps2, ps2d)
103 def testDictPropertySet(self):
104 container = self.ps
105 self.assertIn("string", container)
106 self.assertIn("ps2", container)
107 self.assertNotIn("ps2.bool2", container)
108 self.assertIn("bool2", container.getScalar("ps2"))
110 # Compare dict-like interface to pure dict version
111 d = container.toDict()
112 self.assertEqual(len(d), len(container))
113 self.assertIsNone(d["undef"])
115 # Set some values
116 container["new"] = "string"
117 container["array"] = [1, 2, 3]
118 container["dot.delimited"] = "delimited"
119 self.assertIn("dot", container)
121 keys = container.keys()
122 self.assertEqual(len(keys), 17)
123 for k in keys:
124 self.assertIn(k, container)
126 for k, v in container.items():
127 self.assertIn(k, container)
128 self.assertEqual(v, container[k])
130 # Check that string form of the non-PropertySet values are present
131 # when iterating over values. This is a simple test to ensure
132 # that values() does do something useful
133 values = {str(container[k]) for k in container if not isinstance(container[k],
134 lsst.daf.base.PropertySet)}
135 for v in container.values():
136 if not isinstance(v, lsst.daf.base.PropertySet):
137 self.assertIn(str(v), values)
139 # Assign a PropertySet
140 ps2 = lsst.daf.base.PropertySet()
141 ps2.setString("newstring", "stringValue")
142 container["newps2"] = ps2
143 ps2["newint"] = 5
144 self.assertEqual(container.getScalar("newps2.newint"), ps2.getScalar("newint"))
146 ps2["undef2"] = None
147 self.assertIn("undef2", ps2)
149 # Dict should be converted to a PropertySet
150 container["dict"] = {"a": 1, "b": 2}
151 self.assertEqual(container.getScalar("dict.b"), 2)
153 container["a_property_list"] = self.pl
155 # Upgrading of integer
156 key = "upgrade"
157 container[key] = 1
158 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_Int)
159 self.assertEqual(container[key], 1)
161 # Set to 64-bit int value
162 container[key] = 8589934592
163 self.assertEqual(container[key], 8589934592)
164 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_LongLong)
166 # Set to small int again, type should not change
167 container[key] = 42
168 self.assertEqual(container[key], 42)
169 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_LongLong)
171 def testPop(self):
172 container = self.ps
173 self.assertEqual(container.pop("int"), 2009)
174 self.assertNotIn("int", container)
175 self.assertEqual(container.pop("not_there", 42), 42)
176 with self.assertRaises(KeyError):
177 container.pop("not_there")
179 def testDictPropertyList(self):
180 container = self.pl
181 self.assertIn("string", container)
182 self.assertIn("ps2.bool2", container)
184 # Set a comment
185 container["int2#COMMENT"] = "new comment"
186 self.assertEqual(container.getComment("int2"), "new comment")
188 # Compare dict-like interface to pure dict version
189 d = container.toDict()
190 self.assertEqual(len(d), len(container))
191 self.assertIsNone(d["undef"])
193 # Set some values
194 container["new"] = "string"
195 container["array"] = [1, 2, 3]
196 container["dot.delimited"] = "delimited"
198 keys = container.keys()
199 self.assertEqual(len(keys), 17)
200 for k in keys:
201 self.assertIn(k, container)
203 for k, v in container.items():
204 self.assertIn(k, container)
205 self.assertEqual(v, container[k])
207 # Assign a PropertySet
208 ps2 = lsst.daf.base.PropertySet()
209 ps2["newstring"] = "stringValue"
210 container["newps2"] = ps2
211 ps2["newint"] = 5 # This should have no effect on container
212 self.assertEqual(container.getScalar("newps2.newstring"), ps2.getScalar("newstring"))
213 self.assertNotIn("newps2.newinst", container)
214 self.assertIn("newint", ps2)
216 ps2["undef2"] = None
217 self.assertIn("undef2", ps2)
219 # Dict should be converted to a PropertySet
220 container["dict"] = {"a": 1, "b": 2}
221 self.assertEqual(container.getScalar("dict.b"), 2)
223 # Upgrading of integer
224 key = "upgrade"
225 container[key] = 1
226 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_Int)
227 self.assertEqual(container[key], 1)
228 container[key] = 8589934592
229 self.assertEqual(container[key], 8589934592)
230 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_LongLong)
232 # Set to small int again, type should not change
233 container[key] = 42
234 self.assertEqual(container[key], 42)
235 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_LongLong)
237 # Check that 0 ends up with the correct type
238 key = "zero"
239 container[key] = 0
240 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_Int)
242 # And again but bouncing through an Undef
243 key = "zeroundef"
244 container[key] = None
245 container[key] = 0
246 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_Int)
248 # Store an array of integers with a large value
249 key = "intarray"
250 testArray = [1, 8589934592, 3]
251 container[key] = testArray
252 self.assertEqual(container.getArray(key), testArray)
253 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_LongLong)
255 container[key] = [-1, 2, 3]
256 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_LongLong)
258 container[key] = [1, 2, 2**63 + 1]
259 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_UnsignedLongLong)
261 # Store an empty list
262 container["emptylist"] = []
263 self.assertNotIn("emptylist", container)
265 with self.assertRaises(TypeError):
266 # This can't fit LongLong but also contains negative number
267 container[key] = [-1, 2, 2**63 + 1]
269 def testCopyPropertyList(self):
270 # For PropertyList shallow copy and deep copy are identical
271 shallow = copy.copy(self.pl)
272 self.assertIsInstance(shallow, lsst.daf.base.PropertyList)
273 self.assertIn("dt", shallow)
274 self.assertIn("int", shallow)
275 self.assertEqual(shallow, self.pl)
276 del shallow["dt"]
277 self.assertNotIn("dt", shallow)
278 self.assertIn("dt", self.pl)
280 deep = copy.deepcopy(self.pl)
281 self.assertIsInstance(deep, lsst.daf.base.PropertyList)
282 self.assertEqual(deep, self.pl)
283 del deep["dt"]
284 self.assertNotIn("dt", deep)
285 self.assertIn("dt", self.pl)
288if __name__ == '__main__': 288 ↛ 289line 288 didn't jump to line 289, because the condition on line 288 was never true
289 unittest.main()