LSST Applications g0265f82a02+c6dfa2ddaf,g2079a07aa2+1b2e822518,g2ab2c8e58b+dcaebcd53c,g2bbee38e9b+c6dfa2ddaf,g337abbeb29+c6dfa2ddaf,g3ddfee87b4+971473b56f,g420f1b9425+9c5d1f27f4,g4770a20bdc+7962a82c67,g50ff169b8f+2eb0e556e8,g52b1c1532d+90ebb246c7,g555ede804d+971473b56f,g591dd9f2cf+601419b17e,g5ec818987f+105adce70b,g858d7b2824+dcaebcd53c,g876c692160+5450b3d607,g8a8a8dda67+90ebb246c7,g8cdfe0ae6a+4fd9e222a8,g99cad8db69+ed556ab06a,g9ddcbc5298+a1346535a5,ga1e77700b3+df8f93165b,ga8c6da7877+e280585b77,gae46bcf261+c6dfa2ddaf,gb0e22166c9+8634eb87fb,gb3f2274832+5f6d78177c,gba4ed39666+1ac82b564f,gbb8dafda3b+d1938d02c0,gbeb006f7da+2258dca5ef,gc28159a63d+c6dfa2ddaf,gc86a011abf+dcaebcd53c,gcf0d15dbbd+971473b56f,gd2a12a3803+6772067a4c,gdaeeff99f8+1cafcb7cd4,ge79ae78c31+c6dfa2ddaf,gee10cc3b42+90ebb246c7,gf1cff7945b+dcaebcd53c,w.2024.14
LSST Data Management Base Package
Loading...
Searching...
No Matches
testUtils.py
Go to the documentation of this file.
1# This file is part of afw.
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/>.
21
22__all__ = []
23
24from collections import Counter
25
26import numpy as np
27
29
30from lsst.afw.typehandling import Storable
31
32
33class GenericMapTestBaseClass(lsst.utils.tests.TestCase):
34 """Base class for unit tests of GenericMap.
35
36 Subclasses must call `GenericMapTestBaseClass.setUp(self)`
37 if they provide their own version.
38
39 This class is not *quite* a generic Mapping testbed, because it assumes
40 that the map being tested only accepts keys of a particular type, stored as
41 the `dtype` member.
42 """
43
45 """A subclass of Storable for testing purposes.
46 """
47 def __repr__(self):
48 return "Simplest possible representation"
49
50 def __hash__(self):
51 return 100
52
53 def __eq__(self, other):
54 """Warning: violates both substitution and equality symmetry!
55 """
56 return self.__class__ == other.__class__
57
59 """A subclass of Storable for testing purposes.
60 """
61 def __init__(self, storage):
62 super().__init__()
63 self._storage = storage
64
65 def __repr__(self):
66 return f"ComplexStorable({self._storage!r})"
67
68 def __hash__(self):
69 return hash(self._storage)
70
71 def __eq__(self, other):
72 """Warning: violates both substitution and equality symmetry!
73 """
74 if self.__class____class__ == other.__class__:
75 return self._storage == other._storage
76 else:
77 return False
78
80 """A class that should not be a legal value in a GenericMap.
81 """
82 def __str__(self):
83 return "Non-Storable"
84
85 _testData = {
86 0: True,
87 1: 42,
88 2: 42.0,
89 3: "How many roads must a man walk down?",
90 4: SimpleStorable(),
91 5: ComplexStorable(-100.0),
92 6: None,
93 }
94
95 @classmethod
96 def getTestData(cls, keyClass):
97 """Generic dataset for testing GenericMap classes that can handle it.
98
99 Parameters
100 ----------
101 keyClass : `type`
102 The type of key expected by the GenericMap.
103 """
104 return {keyClass(key): value for key, value in cls._testData.items()}
105
106 @staticmethod
107 def getValidKeys(mapClass):
108 """Return all keys suitable for a GenericMap.
109
110 Parameters
111 ----------
112 mapClass : `type`
113 A type object for a subclass of either `GenericMap` or a
114 key-specific specialization.
115
116 Returns
117 -------
118 keyTypes: `set` [`type`]
119 The types that can be used as keys. If ``mapClass`` is a
120 key-specific specialization, this set will contain exactly
121 one type.
122 """
123 try:
124 return {mapClass.dtype}
125 except AttributeError:
126 return {cls.dtype for cls in mapClass.__subclasses__()}
127
128 def setUp(self):
129 """Set up a test
130
131 Subclasses must call this method if they override setUp.
132 """
133 super().setUp()
134 # tell unittest to use the msg argument of asserts as a supplement
135 # to the error message, rather than as the whole error message
136 self.longMessage = True
137
138 # Mapping must have:
139 # __str__
140 # __repr__
141 # __eq__
142 # __ne__
143 # __contains__
144 # __getitem__
145 # get
146 # __iter__
147 # __len__
148 # __bool__
149 # keys
150 # items
151 # values
152
153 def checkInitMapping(self, mapClass, contents, msg=""):
154 """Check initialization from a mapping.
155
156 Parameters
157 ----------
158 mapClass : `lsst.afw.typehandling.GenericMap`-type
159 The class whose ``__init__`` method will be tested.
160 contents : `Mapping`
161 The key-value pairs to insert into the map
162 msg : `str`
163 Error message suffix describing test parameters
164 """
165 for keyType in self.getValidKeys(mapClass):
166 genericMap = mapClass(contents)
167 self.checkContents(genericMap, contents, msg=msg)
168
169 extraContents = {key: value for key, value in contents.items()} # contents need not define copy()
170 extraKey = keyType(101)
171 extraValue = 'Extra value'
172 extraContents[extraKey] = extraValue
173 genericMap = mapClass(contents, **{keyType(101): extraValue})
174 self.checkContents(genericMap, extraContents, msg=msg)
175
176 with self.assertRaises(TypeError, msg=msg):
177 mapClass({keyType(0): GenericMapTestBaseClass.NotAStorable()})
178
179 def checkInitPairs(self, mapClass, contents, msg=""):
180 """Check initialization from an iterable of pairs.
181
182 Parameters
183 ----------
184 mapClass: `lsst.afw.typehandling.GenericMap`-type
185 The class whose ``__init__`` method will be tested.
186 contents : `Mapping`
187 The key-value pairs to insert into the map
188 msg : `str`
189 Error message suffix describing test parameters
190 """
191 for keyType in self.getValidKeys(mapClass):
192 genericMap = mapClass(contents.items())
193 self.checkContents(genericMap, contents, msg=msg)
194
195 extraContents = {key: value for key, value in contents.items()} # contents need not define copy()
196 extraKey = keyType(101)
197 extraValue = 'Extra value'
198 extraContents[extraKey] = extraValue
199 genericMap = mapClass(contents.items(), **{keyType(101): extraValue})
200 self.checkContents(genericMap, extraContents, msg=msg)
201
202 with self.assertRaises(TypeError, msg=msg):
203 mapClass([(keyType(0), GenericMapTestBaseClass.NotAStorable())])
204
205 def checkInitKwargs(self, mapClass, contents, msg=""):
206 """Check bulk insertion from keywords into a GenericMap.
207
208 Parameters
209 ----------
210 mapClass: `lsst.afw.typehandling.GenericMapS`-type
211 The class whose ``__init__`` method will be tested.
212 Must allow string keys.
213 contents : `Mapping`
214 The key-value pairs to insert into the map
215 msg : `str`
216 Error message suffix describing test parameters
217 """
218 genericMap = mapClass(**contents)
219 self.checkContents(genericMap, contents, msg=msg)
220
221 with self.assertRaises(TypeError, msg=msg):
222 mapClass(notAKey=GenericMapTestBaseClass.NotAStorable())
223
224 def checkFromKeysDefault(self, mapClass, keys, msg=""):
225 """Check initialization using the ``fromkeys`` factory.
226
227 Unlike `checkFromKeys`, this method lets ``fromkeys`` use its default
228 value (which may give different behavior, in nonconforming
229 implementations, from explicitly passing `None`).
230
231 Parameters
232 ----------
233 mapClass: `lsst.afw.typehandling.GenericMap`-type
234 The class whose ``fromkeys`` method will be tested.
235 keys : `iterable`
236 The keys to insert into the map.
237 msg : `str`
238 Error message suffix describing test parameters
239 """
240 genericMap = mapClass.fromkeys(keys)
241 self.assertIsInstance(genericMap, mapClass, msg=msg)
242 self.checkContents(genericMap, dict.fromkeys(keys), msg=msg)
243
244 def checkFromKeys(self, mapClass, keys, value, msg=""):
245 """Check initialization using the ``fromkeys`` factory.
246
247 Parameters
248 ----------
249 mapClass: `lsst.afw.typehandling.GenericMap`-type
250 The class whose ``fromkeys`` method will be tested.
251 keys : `iterable`
252 The keys to insert into the map.
253 value
254 A legal value for a GenericMap.
255 msg : `str`
256 Error message suffix describing test parameters
257 """
258 genericMap = mapClass.fromkeys(keys, value)
259 self.assertIsInstance(genericMap, mapClass, msg=msg)
260 self.checkContents(genericMap, dict.fromkeys(keys, value), msg=msg)
261
262 def checkContains(self, genericMap, contents, msg=""):
263 """Check the contents of a GenericMap.
264
265 Parameters
266 ----------
267 genericMap : `lsst.afw.typehandling.GenericMap`
268 The map to test.
269 contents : `Mapping`
270 The key-value pairs that should be present in ``genericMap``
271 msg : `str`
272 Error message suffix describing test parameters
273 """
274 for key in contents:
275 self.assertIn(key, genericMap, msg=msg)
276
277 keyType = genericMap.dtype
278 for key in range(30):
279 if keyType(key) not in contents:
280 self.assertNotIn(keyType(key), genericMap, msg=msg)
281
282 wrongType = float if keyType is not float else int
283 with self.assertRaises(TypeError):
284 wrongType(0) in genericMap
285
286 def checkContents(self, genericMap, contents, msg=""):
287 """Check the contents of a GenericMap.
288
289 Parameters
290 ----------
291 genericMap : `lsst.afw.typehandling.GenericMap`
292 The map to test.
293 contents : `Mapping`
294 The key-value pairs that should be present in ``genericMap``
295 msg : `str`
296 Error message suffix describing test parameters
297 """
298 for key, value in contents.items():
299 self.assertEqual(genericMap[key], value, msg=msg)
300
301 keyType = genericMap.dtype
302 for key in (keyType(key) for key in range(30) if keyType(key) not in contents):
303 with self.assertRaises(KeyError, msg=msg):
304 genericMap[key]
305
306 wrongType = float if keyType is not float else int
307 with self.assertRaises(TypeError):
308 genericMap[wrongType(0)]
309
310 def checkGet(self, genericMap, contents, msg=""):
311 """Check that GenericMap.get works correctly.
312
313 Parameters
314 ----------
315 genericMap : `lsst.afw.typehandling.GenericMap`
316 The map to test.
317 contents : `Mapping`
318 The key-value pairs that should be present in ``genericMap``
319 msg : `str`
320 Error message suffix describing test parameters
321 """
322 default = "Not a default value"
323 for key, value in contents.items():
324 self.assertEqual(genericMap.get(key), value, msg=msg)
325 self.assertEqual(genericMap.get(key, default), value, msg=msg)
326
327 keyType = genericMap.dtype
328 for key in (keyType(key) for key in range(30) if keyType(key) not in contents):
329 self.assertEqual(genericMap.get(key), None, msg=msg)
330 self.assertEqual(genericMap.get(key, default), default, msg=msg)
331
332 wrongType = float if keyType is not float else int
333 with self.assertRaises(TypeError):
334 genericMap.get(wrongType(0))
335
336 def checkIteration(self, genericMap, contents, msg=""):
337 """Check the result of iterating over a GenericMap.
338
339 Parameters
340 ----------
341 genericMap : `lsst.afw.typehandling.GenericMap`
342 The map to test.
343 contents : `Mapping`
344 The key-value pairs that should be present in ``genericMap``
345 msg : `str`
346 Error message suffix describing test parameters
347 """
348 self.assertEqual({key: genericMap[key] for key in genericMap}, dict(contents), msg=msg)
349
350 def checkViews(self, genericMap, contents, msg=""):
351 """Check the views provided by a GenericMap.
352
353 Parameters
354 ----------
355 genericMap : `lsst.afw.typehandling.GenericMap`
356 The map to test.
357 contents : `Mapping`
358 The key-value pairs that should be present in ``genericMap``
359 msg : `str`
360 Error message suffix describing test parameters
361 """
362 self.assertEqual(set(genericMap.keys()), set(contents.keys()), msg=msg)
363 self.assertEqual(Counter(genericMap.values()), Counter(contents.values()), msg=msg)
364 self.assertEqual(Counter(genericMap.items()), Counter(contents.items()), msg=msg)
365
366
368 """Base class for unit tests of GenericMap that allow insertion/deletion.
369
370 Subclasses must call `MutableGenericMapTestBaseClass.setUp(self)`
371 if they provide their own version.
372 """
373
374 @classmethod
375 def _fillMap(cls, mapFactory, contents):
376 """Create a new GenericMap with particular contents.
377
378 Parameters
379 ----------
380 mapFactory : callable
381 A zero-argument callable that creates an empty
382 `lsst.afw.typehandling.GenericMap` object
383 contents : `Mapping`
384 The key-value pairs that should be present in the new map.
385
386 Returns
387 -------
388 map : `lsst.afw.typehandling.GenericMap`
389 a GenericMap equivalent to ``contents``
390 """
391 return cls._fillPartialMap(mapFactory, contents, len(contents))
392
393 @classmethod
394 def _fillPartialMap(cls, mapFactory, contents, numElements):
395 """Create a new GenericMap with particular contents.
396
397 Parameters
398 ----------
399 mapFactory : callable
400 A zero-argument callable that creates an empty
401 `lsst.afw.typehandling.GenericMap` object
402 contents : `Mapping`
403 The key-value pairs that should be present in the new map.
404 numElements : `int`
405 The number of elements from ``contents`` to be inserted.
406
407 Returns
408 -------
409 map : `lsst.afw.typehandling.GenericMap`
410 a GenericMap containing ``numElements`` of ``contents`` or all of
411 ``contents``, whichever is smaller
412 """
413 newMap = mapFactory()
414 for i, (key, value) in enumerate(contents.items()):
415 if i < numElements:
416 newMap[key] = value
417 else:
418 break
419 return newMap
420
421 # MutableMapping must have:
422 # __setitem__
423 # setdefault
424 # __delitem__
425 # pop
426 # popitem
427 # clear
428 # update
429
430 def checkInsertItem(self, mapFactory, contents, msg=""):
431 """Check element insertion in a GenericMap.
432
433 Parameters
434 ----------
435 mapFactory : callable
436 A zero-argument callable that creates an empty
437 `lsst.afw.typehandling.GenericMap` object of the type to be tested
438 contents : `Mapping`
439 The key-value pairs to insert into the map
440 msg : `str`
441 Error message suffix describing test parameters
442 """
443 genericMap = mapFactory()
444
445 for length, (key, value) in enumerate(contents.items()):
446 loopMsg = f"{msg} Inserting {key!r}={value!r}"
447 genericMap[key] = value
448 self.assertEqual(len(genericMap), length+1, msg=loopMsg)
449 self.assertEqual(genericMap[key], value, msg=loopMsg)
450
451 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
452
453 keyType = genericMap.dtype
454 with self.assertRaises(TypeError, msg=msg):
455 genericMap[keyType(0)] = GenericMapTestBaseClass.NotAStorable()
456
457 wrongType = float if keyType is not float else int
458 with self.assertRaises(TypeError):
459 genericMap[wrongType(0)] = 0
460
461 def checkSetdefault(self, mapFactory, contents, msg=""):
462 """Check that GenericMap.setdefault works correctly.
463
464 Parameters
465 ----------
466 mapFactory : callable
467 A zero-argument callable that creates an empty
468 `lsst.afw.typehandling.GenericMap` object of the type to be tested
469 contents : `Mapping`
470 The key-value pairs to insert into the map
471 msg : `str`
472 Error message suffix describing test parameters
473 """
474 genericMap = mapFactory()
475
476 keyType = genericMap.dtype
477 result = genericMap.setdefault(keyType(0))
478 self.assertEqual(len(genericMap), 1, msg=msg)
479 self.assertIsNone(result, msg=msg)
480 self.assertIsNone(genericMap[keyType(0)], msg=msg)
481 del genericMap[keyType(0)]
482
483 default = "This is a default"
484 for length, (key, _) in enumerate(contents.items()):
485 loopMsg = f"{msg} Defaulting {key!r}"
486 result = genericMap.setdefault(key, default)
487 self.assertEqual(len(genericMap), length+1, msg=loopMsg)
488 self.assertEqual(result, default, msg=loopMsg)
489 self.assertEqual(genericMap[key], default, msg=loopMsg)
490
491 self.assertEqual(genericMap.keys(), contents.keys(), msg=msg)
492
493 with self.assertRaises(TypeError, msg=msg):
494 genericMap.setdefault(keyType(100), GenericMapTestBaseClass.NotAStorable())
495
496 wrongType = float if keyType is not float else int
497 with self.assertRaises(TypeError):
498 genericMap.setdefault(wrongType(0), default)
499
500 genericMap = self._fillMap(mapFactory, contents)
501 for length, (key, value) in enumerate(contents.items()):
502 loopMsg = f"{msg} Defaulting existing {key!r}={value!r}"
503 result = genericMap.setdefault(key, default)
504 self.assertEqual(len(genericMap), len(contents), msg=loopMsg)
505 self.assertEqual(result, contents[key], msg=loopMsg)
506 self.assertEqual(genericMap[key], contents[key], msg=loopMsg)
507
508 def checkUpdateMapping(self, mapFactory, contents, msg=""):
509 """Check bulk insertion from a mapping into a GenericMap.
510
511 Parameters
512 ----------
513 mapFactory : callable
514 A zero-argument callable that creates an empty
515 `lsst.afw.typehandling.GenericMap` object of the type to be tested
516 contents : `Mapping`
517 The key-value pairs to insert into the map
518 msg : `str`
519 Error message suffix describing test parameters
520 """
521 genericMap = self._fillPartialMap(mapFactory, dict.fromkeys(contents, 0), len(contents)/2)
522 self.assertLess(len(genericMap), len(contents), msg=msg)
523
524 genericMap.update(contents)
525 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
526
527 keyType = genericMap.dtype
528 with self.assertRaises(TypeError, msg=msg):
529 genericMap.update({keyType(0): GenericMapTestBaseClass.NotAStorable()})
530
531 wrongType = float if keyType is not float else int
532 with self.assertRaises(TypeError, msg=msg):
533 genericMap.update({wrongType(0): 0})
534
535 def checkUpdatePairs(self, mapFactory, contents, msg=""):
536 """Check bulk insertion from an iterable of pairs into a GenericMap.
537
538 Parameters
539 ----------
540 mapFactory : callable
541 A zero-argument callable that creates an empty
542 `lsst.afw.typehandling.GenericMap` object of the type to be tested
543 contents : `Mapping`
544 The key-value pairs to insert into the map
545 msg : `str`
546 Error message suffix describing test parameters
547 """
548 genericMap = self._fillPartialMap(mapFactory, dict.fromkeys(contents, 0), len(contents)/2)
549 self.assertLess(len(genericMap), len(contents), msg=msg)
550
551 genericMap.update(contents.items())
552 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
553
554 keyType = genericMap.dtype
555 with self.assertRaises(TypeError, msg=msg):
556 genericMap.update([(keyType(0), GenericMapTestBaseClass.NotAStorable())])
557
558 wrongType = float if keyType is not float else int
559 with self.assertRaises(TypeError, msg=msg):
560 genericMap.update([(wrongType(0), 0)])
561
562 def checkUpdateKwargs(self, mapFactory, contents, msg=""):
563 """Check bulk insertion from keywords into a GenericMap.
564
565 Parameters
566 ----------
567 mapFactory : callable
568 A zero-argument callable that creates an empty
569 `lsst.afw.typehandling.GenericMap` object of the type to be tested
570 Must allow string keys.
571 contents : `Mapping`
572 The key-value pairs to insert into the map
573 msg : `str`
574 Error message suffix describing test parameters
575 """
576 genericMap = self._fillPartialMap(mapFactory, dict.fromkeys(contents, 0), len(contents)/2)
577 self.assertLess(len(genericMap), len(contents), msg=msg)
578
579 genericMap.update(**contents)
580 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
581
582 with self.assertRaises(TypeError, msg=msg):
583 genericMap.update(notAKey=GenericMapTestBaseClass.NotAStorable())
584
585 def checkReplaceItem(self, genericMap, msg=""):
586 """Check element replacement in a GenericMap.
587
588 Parameters
589 ----------
590 genericMap : `lsst.afw.typehandling.GenericMap`
591 The map to test. Must be empty.
592 msg : `str`
593 Error message suffix describing test parameters
594 """
595 self.assertFalse(genericMap, msg=msg)
596 keyType = genericMap.dtype
597 key = keyType(42)
598
599 for value in self.getTestData(keyType).values():
600 loopMsg = f"{msg} Inserting {key!r}={value!r}"
601 genericMap[key] = value # value may be of a different type
602 self.assertEqual(len(genericMap), 1, msg=loopMsg)
603 self.assertEqual(genericMap[key], value, msg=loopMsg)
604
605 self.assertEqual(dict(genericMap), {key: value}, msg=msg)
606
607 with self.assertRaises(TypeError, msg=msg):
608 genericMap[key] = GenericMapTestBaseClass.NotAStorable()
609
610 def checkRemoveItem(self, mapFactory, contents, msg=""):
611 """Check element removal from a GenericMap.
612
613 Parameters
614 ----------
615 mapFactory : callable
616 A zero-argument callable that creates an empty
617 `lsst.afw.typehandling.GenericMap` object of the type to be tested
618 contents : `Mapping`
619 The key-value pairs initially occupying the map
620 msg : `str`
621 Error message suffix describing test parameters
622 """
623 genericMap = self._fillMap(mapFactory, contents)
624
625 keyType = genericMap.dtype
626 with self.assertRaises(KeyError, msg=msg):
627 del genericMap[keyType(2019)]
628
629 keysToRemove = list(contents.keys())
630 np.random.shuffle(keysToRemove)
631 for numPrevious, rawKey in enumerate(keysToRemove):
632 key = keyType(rawKey)
633 loopMsg = f"{msg} Deleting {key!r}"
634 del genericMap[key]
635 self.assertEqual(len(genericMap), len(contents)-numPrevious-1, msg=loopMsg)
636 self.assertNotIn(key, genericMap, msg=loopMsg)
637
638 wrongType = float if keyType is not float else int
639 with self.assertRaises(TypeError):
640 del genericMap[wrongType(0)]
641
642 def checkPop(self, mapFactory, contents, msg=""):
643 """Check that GenericMap.pop works correctly.
644
645 Parameters
646 ----------
647 mapFactory : callable
648 A zero-argument callable that creates an empty
649 `lsst.afw.typehandling.GenericMap` object of the type to be tested
650 contents : `Mapping`
651 The key-value pairs initially occupying the map
652 msg : `str`
653 Error message suffix describing test parameters
654 """
655 genericMap = self._fillMap(mapFactory, contents)
656
657 keyType = genericMap.dtype
658 with self.assertRaises(KeyError, msg=msg):
659 genericMap.pop(keyType(2019))
660
661 default = "This is a default"
662 result = genericMap.pop(keyType(2019), default)
663 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
664 self.assertEqual(result, default)
665
666 wrongType = float if keyType is not float else int
667 with self.assertRaises(TypeError):
668 genericMap.pop(wrongType(0))
669
670 itemsToRemove = list(contents.items())
671 np.random.shuffle(itemsToRemove)
672 for numPrevious, (rawKey, value) in enumerate(itemsToRemove):
673 key = keyType(rawKey)
674 loopMsg = f"{msg} Popping {key}={value}"
675 result = genericMap.pop(key)
676 self.assertEqual(len(genericMap), len(contents)-numPrevious-1, msg=loopMsg)
677 self.assertNotIn(key, genericMap, msg=loopMsg)
678 self.assertEqual(result, value, msg=loopMsg)
679
680 def checkPopitem(self, mapFactory, contents, msg=""):
681 """Check that GenericMap.popitem works correctly.
682
683 Parameters
684 ----------
685 mapFactory : callable
686 A zero-argument callable that creates an empty
687 `lsst.afw.typehandling.GenericMap` object of the type to be tested
688 contents : `Mapping`
689 The key-value pairs initially occupying the map
690 msg : `str`
691 Error message suffix describing test parameters
692 """
693 genericMap = self._fillMap(mapFactory, contents)
694
695 for numPrevious in range(len(genericMap)):
696 key, value = genericMap.popitem()
697 loopMsg = f"{msg} Popping {key}={value}"
698 self.assertIn((key, value), contents.items(), msg=loopMsg)
699 self.assertEqual(len(genericMap), len(contents)-numPrevious-1, msg=loopMsg)
700 self.assertNotIn(key, genericMap, msg=loopMsg)
701
702 with self.assertRaises(KeyError, msg=msg):
703 genericMap.popitem()
704
705 def checkClear(self, mapFactory, contents, msg=""):
706 """Check erasing a GenericMap.
707
708 Parameters
709 ----------
710 mapFactory : callable
711 A zero-argument callable that creates an empty
712 `lsst.afw.typehandling.GenericMap` object of the type to be tested
713 contents : `Mapping`
714 The key-value pairs initially occupying the map
715 msg : `str`
716 Error message suffix describing test parameters
717 """
718 genericMap = self._fillMap(mapFactory, contents)
719 self.assertTrue(genericMap, msg=msg)
720
721 genericMap.clear()
722 self.assertFalse(genericMap, msg=msg)
723 self.assertEqual(len(genericMap), 0, msg=msg)
724 for key in genericMap:
725 self.fail(f"Unexpected key: {key}", msg=msg)
726
727 def checkMutableViews(self, mapFactory, contents, msg=""):
728 """Check that the views of a GenericMap update automatically.
729
730 This test supersedes `GenericMapTestBaseClass.checkViews`.
731
732 Parameters
733 ----------
734 genericMap : `lsst.afw.typehandling.GenericMap`
735 The map to test.
736 contents : `Mapping`
737 The key-value pairs that should be present in ``genericMap``
738 msg : `str`
739 Error message suffix describing test parameters
740 """
741 genericMap = mapFactory()
742 keyView = genericMap.keys()
743 valueView = genericMap.values()
744 itemView = genericMap.items()
745
746 for view in (keyView, valueView, itemView):
747 self.assertEqual(len(view), len(genericMap), msg=msg)
748 # is initial state correct?
749 self.checkViews(genericMap, {}, msg)
750
751 for key, value in contents.items():
752 genericMap[key] = value
753
754 for view in (keyView, valueView, itemView):
755 self.assertEqual(len(view), len(genericMap), msg=msg)
756 # is final state correct?
757 self.checkViews(genericMap, contents, msg)
std::vector< SchemaItem< Flag > > * items
Interface supporting iteration over heterogenous containers.
Definition Storable.h:58
checkGet(self, genericMap, contents, msg="")
Definition testUtils.py:310
checkIteration(self, genericMap, contents, msg="")
Definition testUtils.py:336
checkInitMapping(self, mapClass, contents, msg="")
Definition testUtils.py:153
checkInitKwargs(self, mapClass, contents, msg="")
Definition testUtils.py:205
checkInitPairs(self, mapClass, contents, msg="")
Definition testUtils.py:179
checkViews(self, genericMap, contents, msg="")
Definition testUtils.py:350
checkContents(self, genericMap, contents, msg="")
Definition testUtils.py:286
checkFromKeys(self, mapClass, keys, value, msg="")
Definition testUtils.py:244
checkContains(self, genericMap, contents, msg="")
Definition testUtils.py:262
_fillPartialMap(cls, mapFactory, contents, numElements)
Definition testUtils.py:394
daf::base::PropertySet * set
Definition fits.cc:931