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, stored as 45 """A subclass of Storable for testing purposes. 48 return "Simplest possible representation" 54 """Warning: violates both substitution and equality symmetry! 59 """A subclass of Storable for testing purposes. 66 return "ComplexStorable(%r)" % self.
_storage 72 """Warning: violates both substitution and equality symmetry! 75 return self.
_storage == other._storage
80 """A class that should not be a legal value in a GenericMap. 89 3:
"How many roads must a man walk down?",
97 """Generic dataset for testing GenericMap classes that can handle it. 102 The type of key expected by the GenericMap. 104 return {keyClass(key): value
for key, value
in cls.
_testData.
items()}
108 """Return all keys suitable for a GenericMap. 113 A type object for a subclass of either `GenericMap` or a 114 key-specific specialization. 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 124 return {mapClass.dtype}
125 except AttributeError:
126 return {cls.dtype
for cls
in mapClass.__subclasses__()}
131 Subclasses must call this method if they override setUp. 154 """Check initialization from a mapping. 158 mapClass : `lsst.afw.typehandling.GenericMap`-type 159 The class whose ``__init__`` method will be tested. 161 The key-value pairs to insert into the map 163 Error message suffix describing test parameters 166 genericMap = mapClass(contents)
169 extraContents = {key: value
for key, value
in contents.items()}
170 extraKey = keyType(101)
171 extraValue =
'Extra value' 172 extraContents[extraKey] = extraValue
173 genericMap = mapClass(contents, **{keyType(101): extraValue})
176 with self.assertRaises(TypeError, msg=msg):
180 """Check initialization from an iterable of pairs. 184 mapClass: `lsst.afw.typehandling.GenericMap`-type 185 The class whose ``__init__`` method will be tested. 187 The key-value pairs to insert into the map 189 Error message suffix describing test parameters 192 genericMap = mapClass(contents.items())
195 extraContents = {key: value
for key, value
in contents.items()}
196 extraKey = keyType(101)
197 extraValue =
'Extra value' 198 extraContents[extraKey] = extraValue
199 genericMap = mapClass(contents.items(), **{keyType(101): extraValue})
202 with self.assertRaises(TypeError, msg=msg):
206 """Check bulk insertion from keywords into a GenericMap. 210 mapClass: `lsst.afw.typehandling.GenericMapS`-type 211 The class whose ``__init__`` method will be tested. 212 Must allow string keys. 214 The key-value pairs to insert into the map 216 Error message suffix describing test parameters 218 genericMap = mapClass(**contents)
221 with self.assertRaises(TypeError, msg=msg):
225 """Check initialization using the ``fromkeys`` factory. 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`). 233 mapClass: `lsst.afw.typehandling.GenericMap`-type 234 The class whose ``fromkeys`` method will be tested. 236 The keys to insert into the map. 238 Error message suffix describing test parameters 240 genericMap = mapClass.fromkeys(keys)
241 self.assertIsInstance(genericMap, mapClass, msg=msg)
245 """Check initialization using the ``fromkeys`` factory. 249 mapClass: `lsst.afw.typehandling.GenericMap`-type 250 The class whose ``fromkeys`` method will be tested. 252 The keys to insert into the map. 254 A legal value for a GenericMap. 256 Error message suffix describing test parameters 258 genericMap = mapClass.fromkeys(keys, value)
259 self.assertIsInstance(genericMap, mapClass, msg=msg)
260 self.
checkContents(genericMap, dict.fromkeys(keys, value), msg=msg)
263 """Check the contents of a GenericMap. 267 genericMap : `lsst.afw.typehandling.GenericMap` 270 The key-value pairs that should be present in ``genericMap`` 272 Error message suffix describing test parameters 275 self.assertIn(key, genericMap, msg=msg)
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)
282 wrongType = float
if keyType
is not float
else int
283 with self.assertRaises(TypeError):
284 wrongType(0)
in genericMap
287 """Check the contents of a GenericMap. 291 genericMap : `lsst.afw.typehandling.GenericMap` 294 The key-value pairs that should be present in ``genericMap`` 296 Error message suffix describing test parameters 298 for key, value
in contents.items():
299 self.assertEqual(genericMap[key], value, msg=msg)
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):
306 wrongType = float
if keyType
is not float
else int
307 with self.assertRaises(TypeError):
308 genericMap[wrongType(0)]
311 """Check that GenericMap.get works correctly. 315 genericMap : `lsst.afw.typehandling.GenericMap` 318 The key-value pairs that should be present in ``genericMap`` 320 Error message suffix describing test parameters 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)
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)
332 wrongType = float
if keyType
is not float
else int
333 with self.assertRaises(TypeError):
334 genericMap.get(wrongType(0))
337 """Check the result of iterating over 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({key: genericMap[key]
for key
in genericMap}, dict(contents), msg=msg)
351 """Check the views provided by a GenericMap. 355 genericMap : `lsst.afw.typehandling.GenericMap` 358 The key-value pairs that should be present in ``genericMap`` 360 Error message suffix describing test parameters 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)
368 """Base class for unit tests of GenericMap that allow insertion/deletion. 370 Subclasses must call `MutableGenericMapTestBaseClass.setUp(self)` 371 if they provide their own version. 375 def _fillMap(cls, mapFactory, contents):
376 """Create a new GenericMap with particular contents. 380 mapFactory : callable 381 A zero-argument callable that creates an empty 382 `lsst.afw.typehandling.GenericMap` object 384 The key-value pairs that should be present in the new map. 388 map : `lsst.afw.typehandling.GenericMap` 389 a GenericMap equivalent to ``contents`` 394 def _fillPartialMap(cls, mapFactory, contents, numElements):
395 """Create a new GenericMap with particular contents. 399 mapFactory : callable 400 A zero-argument callable that creates an empty 401 `lsst.afw.typehandling.GenericMap` object 403 The key-value pairs that should be present in the new map. 405 The number of elements from ``contents`` to be inserted. 409 map : `lsst.afw.typehandling.GenericMap` 410 a GenericMap containing ``numElements`` of ``contents`` or all of 411 ``contents``, whichever is smaller 413 newMap = mapFactory()
414 for i, (key, value)
in enumerate(contents.items()):
431 """Check element insertion in a GenericMap. 435 mapFactory : callable 436 A zero-argument callable that creates an empty 437 `lsst.afw.typehandling.GenericMap` object of the type to be tested 439 The key-value pairs to insert into the map 441 Error message suffix describing test parameters 443 genericMap = mapFactory()
445 for length, (key, value)
in enumerate(contents.items()):
446 loopMsg = msg +
" Inserting %r=%r" % (key, value)
447 genericMap[key] = value
448 self.assertEqual(len(genericMap), length+1, msg=loopMsg)
449 self.assertEqual(genericMap[key], value, msg=loopMsg)
451 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
453 keyType = genericMap.dtype
454 with self.assertRaises(TypeError, msg=msg):
457 wrongType = float
if keyType
is not float
else int
458 with self.assertRaises(TypeError):
459 genericMap[wrongType(0)] = 0
462 """Check that GenericMap.setdefault works correctly. 466 mapFactory : callable 467 A zero-argument callable that creates an empty 468 `lsst.afw.typehandling.GenericMap` object of the type to be tested 470 The key-value pairs to insert into the map 472 Error message suffix describing test parameters 474 genericMap = mapFactory()
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)]
483 default =
"This is a default" 484 for length, (key, _)
in enumerate(contents.items()):
485 loopMsg = msg +
" Defaulting %r" % (key)
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)
491 self.assertEqual(genericMap.keys(), contents.keys(), msg=msg)
493 with self.assertRaises(TypeError, msg=msg):
496 wrongType = float
if keyType
is not float
else int
497 with self.assertRaises(TypeError):
498 genericMap.setdefault(wrongType(0), default)
500 genericMap = self.
_fillMap(mapFactory, contents)
501 for length, (key, value)
in enumerate(contents.items()):
502 loopMsg = msg +
" Defaulting existing %r=%r" % (key, value)
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)
509 """Check bulk insertion from a mapping into a GenericMap. 513 mapFactory : callable 514 A zero-argument callable that creates an empty 515 `lsst.afw.typehandling.GenericMap` object of the type to be tested 517 The key-value pairs to insert into the map 519 Error message suffix describing test parameters 521 genericMap = self.
_fillPartialMap(mapFactory, dict.fromkeys(contents, 0), len(contents)/2)
522 self.assertLess(len(genericMap), len(contents), msg=msg)
524 genericMap.update(contents)
525 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
527 keyType = genericMap.dtype
528 with self.assertRaises(TypeError, msg=msg):
531 wrongType = float
if keyType
is not float
else int
532 with self.assertRaises(TypeError, msg=msg):
533 genericMap.update({wrongType(0): 0})
536 """Check bulk insertion from an iterable of pairs into a GenericMap. 540 mapFactory : callable 541 A zero-argument callable that creates an empty 542 `lsst.afw.typehandling.GenericMap` object of the type to be tested 544 The key-value pairs to insert into the map 546 Error message suffix describing test parameters 548 genericMap = self.
_fillPartialMap(mapFactory, dict.fromkeys(contents, 0), len(contents)/2)
549 self.assertLess(len(genericMap), len(contents), msg=msg)
551 genericMap.update(contents.items())
552 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
554 keyType = genericMap.dtype
555 with self.assertRaises(TypeError, msg=msg):
558 wrongType = float
if keyType
is not float
else int
559 with self.assertRaises(TypeError, msg=msg):
560 genericMap.update([(wrongType(0), 0)])
563 """Check bulk insertion from keywords into a GenericMap. 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. 572 The key-value pairs to insert into the map 574 Error message suffix describing test parameters 576 genericMap = self.
_fillPartialMap(mapFactory, dict.fromkeys(contents, 0), len(contents)/2)
577 self.assertLess(len(genericMap), len(contents), msg=msg)
579 genericMap.update(**contents)
580 self.assertEqual(dict(genericMap), dict(contents), msg=msg)
582 with self.assertRaises(TypeError, msg=msg):
586 """Check element replacement in a GenericMap. 590 genericMap : `lsst.afw.typehandling.GenericMap` 591 The map to test. Must be empty. 593 Error message suffix describing test parameters 595 self.assertFalse(genericMap, msg=msg)
596 keyType = genericMap.dtype
600 loopMsg = msg +
" Inserting %r=%r" % (key, value)
601 genericMap[key] = value
602 self.assertEqual(len(genericMap), 1, msg=loopMsg)
603 self.assertEqual(genericMap[key], value, msg=loopMsg)
605 self.assertEqual(dict(genericMap), {key: value}, msg=msg)
607 with self.assertRaises(TypeError, msg=msg):
611 """Check element removal from a GenericMap. 615 mapFactory : callable 616 A zero-argument callable that creates an empty 617 `lsst.afw.typehandling.GenericMap` object of the type to be tested 619 The key-value pairs initially occupying the map 621 Error message suffix describing test parameters 623 genericMap = self.
_fillMap(mapFactory, contents)
625 keyType = genericMap.dtype
626 with self.assertRaises(KeyError, msg=msg):
627 del genericMap[keyType(2019)]
629 keysToRemove =
list(contents.keys())
630 np.random.shuffle(keysToRemove)
631 for numPrevious, rawKey
in enumerate(keysToRemove):
632 key = keyType(rawKey)
633 loopMsg = msg +
" Deleting %r" % (key)
635 self.assertEqual(len(genericMap), len(contents)-numPrevious-1, msg=loopMsg)
636 self.assertNotIn(key, genericMap, msg=loopMsg)
638 wrongType = float
if keyType
is not float
else int
639 with self.assertRaises(TypeError):
640 del genericMap[wrongType(0)]
643 """Check that GenericMap.pop works correctly. 647 mapFactory : callable 648 A zero-argument callable that creates an empty 649 `lsst.afw.typehandling.GenericMap` object of the type to be tested 651 The key-value pairs initially occupying the map 653 Error message suffix describing test parameters 655 genericMap = self.
_fillMap(mapFactory, contents)
657 keyType = genericMap.dtype
658 with self.assertRaises(KeyError, msg=msg):
659 genericMap.pop(keyType(2019))
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)
666 wrongType = float
if keyType
is not float
else int
667 with self.assertRaises(TypeError):
668 genericMap.pop(wrongType(0))
670 itemsToRemove =
list(contents.items())
671 np.random.shuffle(itemsToRemove)
672 for numPrevious, (rawKey, value)
in enumerate(itemsToRemove):
673 key = keyType(rawKey)
674 loopMsg = msg +
" Popping %r=%r" % (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)
681 """Check that GenericMap.popitem works correctly. 685 mapFactory : callable 686 A zero-argument callable that creates an empty 687 `lsst.afw.typehandling.GenericMap` object of the type to be tested 689 The key-value pairs initially occupying the map 691 Error message suffix describing test parameters 693 genericMap = self.
_fillMap(mapFactory, contents)
695 for numPrevious
in range(len(genericMap)):
696 key, value = genericMap.popitem()
697 loopMsg = msg +
" Popping %r=%r" % (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)
702 with self.assertRaises(KeyError, msg=msg):
706 """Check erasing a GenericMap. 710 mapFactory : callable 711 A zero-argument callable that creates an empty 712 `lsst.afw.typehandling.GenericMap` object of the type to be tested 714 The key-value pairs initially occupying the map 716 Error message suffix describing test parameters 718 genericMap = self.
_fillMap(mapFactory, contents)
719 self.assertTrue(genericMap, msg=msg)
722 self.assertFalse(genericMap, msg=msg)
723 self.assertEqual(len(genericMap), 0, msg=msg)
724 for key
in genericMap:
725 self.fail(
"Unexpected key: %s" % key, msg=msg)
728 """Check that the views of a GenericMap update automatically. 730 This test supersedes `GenericMapTestBaseClass.checkViews`. 734 genericMap : `lsst.afw.typehandling.GenericMap` 737 The key-value pairs that should be present in ``genericMap`` 739 Error message suffix describing test parameters 741 genericMap = mapFactory()
742 keyView = genericMap.keys()
743 valueView = genericMap.values()
744 itemView = genericMap.items()
746 for view
in (keyView, valueView, itemView):
747 self.assertEqual(len(view), len(genericMap), msg=msg)
751 for key, value
in contents.items():
752 genericMap[key] = value
754 for view
in (keyView, valueView, itemView):
755 self.assertEqual(len(view), len(genericMap), msg=msg)
def checkViews(self, genericMap, contents, msg="")
def checkRemoveItem(self, mapFactory, contents, msg="")
def checkPopitem(self, mapFactory, contents, msg="")
def checkPop(self, mapFactory, contents, msg="")
def checkSetdefault(self, mapFactory, contents, msg="")
def getValidKeys(mapClass)
std::vector< SchemaItem< Flag > > * items
Interface supporting iteration over heterogenous containers.
def _fillMap(cls, mapFactory, contents)
daf::base::PropertySet * set
def checkFromKeys(self, mapClass, keys, value, msg="")
def checkUpdatePairs(self, mapFactory, contents, msg="")
def checkUpdateKwargs(self, mapFactory, contents, msg="")
def checkInitPairs(self, mapClass, contents, msg="")
def checkInsertItem(self, mapFactory, contents, msg="")
def checkGet(self, genericMap, contents, msg="")
def checkReplaceItem(self, genericMap, msg="")
def checkIteration(self, genericMap, contents, msg="")
def checkInitMapping(self, mapClass, contents, msg="")
def checkContents(self, genericMap, contents, msg="")
def checkClear(self, mapFactory, contents, msg="")
def _fillPartialMap(cls, mapFactory, contents, numElements)
def __init__(self, storage)
def checkUpdateMapping(self, mapFactory, contents, msg="")
def checkContains(self, genericMap, contents, msg="")
def getTestData(cls, keyClass)
def checkInitKwargs(self, mapClass, contents, msg="")
def checkMutableViews(self, mapFactory, contents, msg="")
daf::base::PropertyList * list
def checkFromKeysDefault(self, mapClass, keys, msg="")