24 from collections
import Counter
34 """Base class for unit tests of GenericMap. 36 Subclasses must call `GenericMapTestBaseClass.setUp(self)` 37 if they provide their own version. 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. 44 """A subclass of Storable for testing purposes. 47 return "Simplest possible representation" 53 """Warning: violates both substitution and equality symmetry! 58 """A subclass of Storable for testing purposes. 65 return "ComplexStorable(%r)" % self.
_storage 71 """Warning: violates both substitution and equality symmetry! 74 return self.
_storage == other._storage
79 """A class that should not be a legal value in a GenericMap. 88 3:
"How many roads must a man walk down?",
96 """Generic dataset for testing GenericMap classes that can handle it. 101 The type of key expected by the GenericMap. 103 return {keyClass(key): value
for key, value
in cls.
_testData.
items()}
108 Subclasses must call this method if they override setUp. 131 """Check initialization from a mapping. 136 The type of key allowed by ``mapClass``. 137 mapClass : `lsst.afw.typehandling.GenericMap`-type 138 The class whose ``__init__`` method will be tested. 140 The key-value pairs to insert into the map 142 Error message suffix describing test parameters 144 genericMap = mapClass(contents)
147 extraContents = {key: value
for key, value
in contents.items()}
148 extraKey = keyType(101)
149 extraValue =
'Extra value' 150 extraContents[extraKey] = extraValue
151 genericMap = mapClass(contents, **{keyType(101): extraValue})
152 self.
checkContents(keyType, genericMap, extraContents, msg=msg)
154 with self.assertRaises(TypeError, msg=msg):
158 """Check initialization from an iterable of pairs. 163 The type of key allowed by ``mapClass``. 164 mapClass: `lsst.afw.typehandling.GenericMap`-type 165 The class whose ``__init__`` method will be tested. 167 The key-value pairs to insert into the map 169 Error message suffix describing test parameters 171 genericMap = mapClass(contents.items())
174 extraContents = {key: value
for key, value
in contents.items()}
175 extraKey = keyType(101)
176 extraValue =
'Extra value' 177 extraContents[extraKey] = extraValue
178 genericMap = mapClass(contents.items(), **{keyType(101): extraValue})
179 self.
checkContents(keyType, genericMap, extraContents, msg=msg)
181 with self.assertRaises(TypeError, msg=msg):
185 """Check bulk insertion from keywords into a GenericMap. 189 mapClass: `lsst.afw.typehandling.GenericMapS`-type 190 The class whose ``__init__`` method will be tested. 191 Must allow string keys. 193 The key-value pairs to insert into the map 195 Error message suffix describing test parameters 197 genericMap = mapClass(**contents)
200 with self.assertRaises(TypeError, msg=msg):
204 """Check initialization using the ``fromkeys`` factory. 206 Unlike `checkFromKeys`, this method lets ``fromkeys`` use its default 207 value (which may give different behavior, in nonconforming 208 implementations, from explicitly passing `None`). 213 The type of key allowed by ``mapClass``. 214 mapClass: `lsst.afw.typehandling.GenericMap`-type 215 The class whose ``fromkeys`` method will be tested. 217 The keys to insert into the map. 219 Error message suffix describing test parameters 221 genericMap = mapClass.fromkeys(keys)
222 self.assertIsInstance(genericMap, mapClass, msg=msg)
223 self.
checkContents(keyType, genericMap, dict.fromkeys(keys), msg=msg)
226 """Check initialization using the ``fromkeys`` factory. 231 The type of key allowed by ``mapClass``. 232 mapClass: `lsst.afw.typehandling.GenericMap`-type 233 The class whose ``fromkeys`` method will be tested. 235 The keys to insert into the map. 237 A legal value for a GenericMap. 239 Error message suffix describing test parameters 241 genericMap = mapClass.fromkeys(keys, value)
242 self.assertIsInstance(genericMap, mapClass, msg=msg)
243 self.
checkContents(keyType, genericMap, dict.fromkeys(keys, value), msg=msg)
246 """Check the contents of a GenericMap. 251 The type of key allowed by ``mapClass``. 252 genericMap : `lsst.afw.typehandling.GenericMap` 255 The key-value pairs that should be present in ``genericMap`` 257 Error message suffix describing test parameters 260 self.assertIn(key, genericMap, msg=msg)
262 for key
in range(30):
263 if keyType(key)
not in contents:
264 self.assertNotIn(keyType(key), genericMap, msg=msg)
266 wrongType = float
if keyType
is not float
else int
267 with self.assertRaises(TypeError):
268 wrongType(0)
in genericMap
271 """Check the contents of a GenericMap. 276 The type of key allowed by ``mapClass``. 277 genericMap : `lsst.afw.typehandling.GenericMap` 280 The key-value pairs that should be present in ``genericMap`` 282 Error message suffix describing test parameters 284 for key, value
in contents.items():
285 self.assertEqual(genericMap[key], value, msg=msg)
287 for key
in (keyType(key)
for key
in range(30)
if keyType(key)
not in contents):
288 with self.assertRaises(KeyError, msg=msg):
291 wrongType = float
if keyType
is not float
else int
292 with self.assertRaises(TypeError):
293 genericMap[wrongType(0)]
295 def checkGet(self, keyType, genericMap, contents, msg=""):
296 """Check that GenericMap.get works correctly. 301 The type of key allowed by ``mapClass``. 302 genericMap : `lsst.afw.typehandling.GenericMap` 305 The key-value pairs that should be present in ``genericMap`` 307 Error message suffix describing test parameters 309 default =
"Not a default value" 310 for key, value
in contents.items():
311 self.assertEqual(genericMap.get(key), value, msg=msg)
312 self.assertEqual(genericMap.get(key, default), value, msg=msg)
314 for key
in (keyType(key)
for key
in range(30)
if keyType(key)
not in contents):
315 self.assertEqual(genericMap.get(key),
None, msg=msg)
316 self.assertEqual(genericMap.get(key, default), default, msg=msg)
318 wrongType = float
if keyType
is not float
else int
319 with self.assertRaises(TypeError):
320 genericMap.get(wrongType(0))
323 """Check the result of iterating over a GenericMap. 327 genericMap : `lsst.afw.typehandling.GenericMap` 330 The key-value pairs that should be present in ``genericMap`` 332 Error message suffix describing test parameters 334 self.assertEqual({key: genericMap[key]
for key
in genericMap}, dict(contents), msg=msg)
337 """Check the views provided by a GenericMap. 341 genericMap : `lsst.afw.typehandling.GenericMap` 344 The key-value pairs that should be present in ``genericMap`` 346 Error message suffix describing test parameters 348 self.assertEqual(
set(genericMap.keys()),
set(contents.keys()), msg=msg)
349 self.assertEqual(Counter(genericMap.values()), Counter(contents.values()), msg=msg)
350 self.assertEqual(Counter(genericMap.items()), Counter(contents.items()), msg=msg)
354 """Base class for unit tests of GenericMap that allow insertion/deletion. 356 Subclasses must call `MutableGenericMapTestBaseClass.setUp(self)` 357 if they provide their own version. 361 def _fillMap(cls, mapFactory, contents):
362 """Create a new GenericMap with particular contents. 366 mapFactory : callable 367 A zero-argument callable that creates an empty 368 `lsst.afw.typehandling.GenericMap` object 370 The key-value pairs that should be present in the new map. 374 map : `lsst.afw.typehandling.GenericMap` 375 a GenericMap equivalent to ``contents`` 380 def _fillPartialMap(cls, mapFactory, contents, numElements):
381 """Create a new GenericMap with particular contents. 385 mapFactory : callable 386 A zero-argument callable that creates an empty 387 `lsst.afw.typehandling.GenericMap` object 389 The key-value pairs that should be present in the new map. 391 The number of elements from ``contents`` to be inserted. 395 map : `lsst.afw.typehandling.GenericMap` 396 a GenericMap containing ``numElements`` of ``contents`` or all of 397 ``contents``, whichever is smaller 399 newMap = mapFactory()
400 for i, (key, value)
in enumerate(contents.items()):
417 """Check element insertion in a GenericMap. 422 The type of key allowed by ``mapClass``. 423 mapFactory : callable 424 A zero-argument callable that creates an empty 425 `lsst.afw.typehandling.GenericMap` object of the type to be tested 427 The key-value pairs to insert into the map 429 Error message suffix describing test parameters 431 genericMap = mapFactory()
433 for length, (key, value)
in enumerate(contents.items()):
434 loopMsg = msg +
" Inserting %r=%r" % (key, value)
435 genericMap[key] = value
436 self.assertEqual(len(genericMap), length+1, msg=loopMsg)
437 self.assertEqual(genericMap[key], value, msg=loopMsg)
439 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
441 with self.assertRaises(TypeError, msg=msg):
444 wrongType = float
if keyType
is not float
else int
445 with self.assertRaises(TypeError):
446 genericMap[wrongType(0)] = 0
449 """Check that GenericMap.setdefault works correctly. 454 The type of key allowed by ``mapClass``. 455 mapFactory : callable 456 A zero-argument callable that creates an empty 457 `lsst.afw.typehandling.GenericMap` object of the type to be tested 459 The key-value pairs to insert into the map 461 Error message suffix describing test parameters 463 genericMap = mapFactory()
465 result = genericMap.setdefault(keyType(0))
466 self.assertEqual(len(genericMap), 1, msg=msg)
467 self.assertIsNone(result, msg=msg)
468 self.assertIsNone(genericMap[keyType(0)], msg=msg)
469 del genericMap[keyType(0)]
471 default =
"This is a default" 472 for length, (key, _)
in enumerate(contents.items()):
473 loopMsg = msg +
" Defaulting %r" % (key)
474 result = genericMap.setdefault(key, default)
475 self.assertEqual(len(genericMap), length+1, msg=loopMsg)
476 self.assertEqual(result, default, msg=loopMsg)
477 self.assertEqual(genericMap[key], default, msg=loopMsg)
479 self.assertEqual(genericMap.keys(), contents.keys(), msg=msg)
481 with self.assertRaises(TypeError, msg=msg):
484 wrongType = float
if keyType
is not float
else int
485 with self.assertRaises(TypeError):
486 genericMap.setdefault(wrongType(0), default)
488 genericMap = self.
_fillMap(mapFactory, contents)
489 for length, (key, value)
in enumerate(contents.items()):
490 loopMsg = msg +
" Defaulting existing %r=%r" % (key, value)
491 result = genericMap.setdefault(key, default)
492 self.assertEqual(len(genericMap), len(contents), msg=loopMsg)
493 self.assertEqual(result, contents[key], msg=loopMsg)
494 self.assertEqual(genericMap[key], contents[key], msg=loopMsg)
497 """Check bulk insertion from a mapping into a GenericMap. 502 The type of key allowed by ``mapClass``. 503 mapFactory : callable 504 A zero-argument callable that creates an empty 505 `lsst.afw.typehandling.GenericMap` object of the type to be tested 507 The key-value pairs to insert into the map 509 Error message suffix describing test parameters 511 genericMap = self.
_fillPartialMap(mapFactory, dict.fromkeys(contents, 0), len(contents)/2)
512 self.assertLess(len(genericMap), len(contents), msg=msg)
514 genericMap.update(contents)
515 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
517 with self.assertRaises(TypeError, msg=msg):
520 wrongType = float
if keyType
is not float
else int
521 with self.assertRaises(TypeError, msg=msg):
522 genericMap.update({wrongType(0): 0})
525 """Check bulk insertion from an iterable of pairs into a GenericMap. 530 The type of key allowed by ``mapClass``. 531 mapFactory : callable 532 A zero-argument callable that creates an empty 533 `lsst.afw.typehandling.GenericMap` object of the type to be tested 535 The key-value pairs to insert into the map 537 Error message suffix describing test parameters 539 genericMap = self.
_fillPartialMap(mapFactory, dict.fromkeys(contents, 0), len(contents)/2)
540 self.assertLess(len(genericMap), len(contents), msg=msg)
542 genericMap.update(contents.items())
543 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
545 with self.assertRaises(TypeError, msg=msg):
548 wrongType = float
if keyType
is not float
else int
549 with self.assertRaises(TypeError, msg=msg):
550 genericMap.update([(wrongType(0), 0)])
553 """Check bulk insertion from keywords into a GenericMap. 558 The type of key allowed by ``mapClass``. 559 mapFactory : callable 560 A zero-argument callable that creates an empty 561 `lsst.afw.typehandling.GenericMap` object of the type to be tested 562 Must allow string keys. 564 The key-value pairs to insert into the map 566 Error message suffix describing test parameters 568 genericMap = self.
_fillPartialMap(mapFactory, dict.fromkeys(contents, 0), len(contents)/2)
569 self.assertLess(len(genericMap), len(contents), msg=msg)
571 genericMap.update(**contents)
572 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
574 with self.assertRaises(TypeError, msg=msg):
578 """Check element replacement in a GenericMap. 583 The type of key allowed by ``mapClass``. 584 genericMap : `lsst.afw.typehandling.GenericMap` 585 The map to test. Must be empty. 587 Error message suffix describing test parameters 589 self.assertFalse(genericMap, msg=msg)
593 loopMsg = msg +
" Inserting %r=%r" % (key, value)
594 genericMap[key] = value
595 self.assertEqual(len(genericMap), 1, msg=loopMsg)
596 self.assertEqual(genericMap[key], value, msg=loopMsg)
598 self.assertEqual(dict(genericMap), {key: value}, msg=msg)
600 with self.assertRaises(TypeError, msg=msg):
604 """Check element removal from a GenericMap. 609 The type of key allowed by ``mapClass``. 610 mapFactory : callable 611 A zero-argument callable that creates an empty 612 `lsst.afw.typehandling.GenericMap` object of the type to be tested 614 The key-value pairs initially occupying the map 616 Error message suffix describing test parameters 618 genericMap = self.
_fillMap(mapFactory, contents)
620 with self.assertRaises(KeyError, msg=msg):
621 del genericMap[keyType(2019)]
623 keysToRemove =
list(contents.keys())
624 np.random.shuffle(keysToRemove)
625 for numPrevious, rawKey
in enumerate(keysToRemove):
626 key = keyType(rawKey)
627 loopMsg = msg +
" Deleting %r" % (key)
629 self.assertEqual(len(genericMap), len(contents)-numPrevious-1, msg=loopMsg)
630 self.assertNotIn(key, genericMap, msg=loopMsg)
632 wrongType = float
if keyType
is not float
else int
633 with self.assertRaises(TypeError):
634 del genericMap[wrongType(0)]
636 def checkPop(self, keyType, mapFactory, contents, msg=""):
637 """Check that GenericMap.pop works correctly. 642 The type of key allowed by ``mapClass``. 643 mapFactory : callable 644 A zero-argument callable that creates an empty 645 `lsst.afw.typehandling.GenericMap` object of the type to be tested 647 The key-value pairs initially occupying the map 649 Error message suffix describing test parameters 651 genericMap = self.
_fillMap(mapFactory, contents)
653 with self.assertRaises(KeyError, msg=msg):
654 genericMap.pop(keyType(2019))
656 default =
"This is a default" 657 result = genericMap.pop(keyType(2019), default)
658 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
659 self.assertEqual(result, default)
661 wrongType = float
if keyType
is not float
else int
662 with self.assertRaises(TypeError):
663 genericMap.pop(wrongType(0))
665 itemsToRemove =
list(contents.items())
666 np.random.shuffle(itemsToRemove)
667 for numPrevious, (rawKey, value)
in enumerate(itemsToRemove):
668 key = keyType(rawKey)
669 loopMsg = msg +
" Popping %r=%r" % (key, value)
670 result = genericMap.pop(key)
671 self.assertEqual(len(genericMap), len(contents)-numPrevious-1, msg=loopMsg)
672 self.assertNotIn(key, genericMap, msg=loopMsg)
673 self.assertEqual(result, value, msg=loopMsg)
676 """Check that GenericMap.popitem works correctly. 680 mapFactory : callable 681 A zero-argument callable that creates an empty 682 `lsst.afw.typehandling.GenericMap` object of the type to be tested 684 The key-value pairs initially occupying the map 686 Error message suffix describing test parameters 688 genericMap = self.
_fillMap(mapFactory, contents)
690 for numPrevious
in range(len(genericMap)):
691 key, value = genericMap.popitem()
692 loopMsg = msg +
" Popping %r=%r" % (key, value)
693 self.assertIn((key, value), contents.items(), msg=loopMsg)
694 self.assertEqual(len(genericMap), len(contents)-numPrevious-1, msg=loopMsg)
695 self.assertNotIn(key, genericMap, msg=loopMsg)
697 with self.assertRaises(KeyError, msg=msg):
701 """Check erasing a GenericMap. 705 mapFactory : callable 706 A zero-argument callable that creates an empty 707 `lsst.afw.typehandling.GenericMap` object of the type to be tested 709 The key-value pairs initially occupying the map 711 Error message suffix describing test parameters 713 genericMap = self.
_fillMap(mapFactory, contents)
714 self.assertTrue(genericMap, msg=msg)
717 self.assertFalse(genericMap, msg=msg)
718 self.assertEqual(len(genericMap), 0, msg=msg)
719 for key
in genericMap:
720 self.fail(
"Unexpected key: %s" % key, msg=msg)
723 """Check that the views of a GenericMap update automatically. 725 This test supersedes `GenericMapTestBaseClass.checkViews`. 729 genericMap : `lsst.afw.typehandling.GenericMap` 732 The key-value pairs that should be present in ``genericMap`` 734 Error message suffix describing test parameters 736 genericMap = mapFactory()
737 keyView = genericMap.keys()
738 valueView = genericMap.values()
739 itemView = genericMap.items()
741 for view
in (keyView, valueView, itemView):
742 self.assertEqual(len(view), len(genericMap), msg=msg)
746 for key, value
in contents.items():
747 genericMap[key] = value
749 for view
in (keyView, valueView, itemView):
750 self.assertEqual(len(view), len(genericMap), msg=msg)
def checkSetdefault(self, keyType, mapFactory, contents, msg="")
def checkViews(self, genericMap, contents, msg="")
def checkPopitem(self, mapFactory, contents, msg="")
def checkInitMapping(self, keyType, mapClass, contents, msg="")
def checkFromKeysDefault(self, keyType, mapClass, keys, msg="")
Interface supporting iteration over heterogenous containers.
def checkPop(self, keyType, mapFactory, contents, msg="")
def _fillMap(cls, mapFactory, contents)
def checkContents(self, keyType, genericMap, contents, msg="")
daf::base::PropertySet * set
def checkUpdateKwargs(self, mapFactory, contents, msg="")
def checkInsertItem(self, keyType, mapFactory, contents, msg="")
def checkReplaceItem(self, keyType, genericMap, msg="")
def checkUpdatePairs(self, keyType, mapFactory, contents, msg="")
def checkUpdateMapping(self, keyType, mapFactory, contents, msg="")
def checkIteration(self, genericMap, contents, msg="")
def checkFromKeys(self, keyType, mapClass, keys, value, msg="")
def checkRemoveItem(self, keyType, mapFactory, contents, msg="")
def checkClear(self, mapFactory, contents, msg="")
def _fillPartialMap(cls, mapFactory, contents, numElements)
def __init__(self, storage)
def checkInitPairs(self, keyType, mapClass, contents, msg="")
def getTestData(cls, keyClass)
std::vector< SchemaItem< Flag > > * items
def checkInitKwargs(self, mapClass, contents, msg="")
def checkMutableViews(self, mapFactory, contents, msg="")
daf::base::PropertyList * list
def checkContains(self, keyType, genericMap, contents, msg="")
def checkGet(self, keyType, genericMap, contents, msg="")