LSSTApplications  17.0+11,17.0+34,17.0+56,17.0+57,17.0+59,17.0+7,17.0-1-g377950a+33,17.0.1-1-g114240f+2,17.0.1-1-g4d4fbc4+28,17.0.1-1-g55520dc+49,17.0.1-1-g5f4ed7e+52,17.0.1-1-g6dd7d69+17,17.0.1-1-g8de6c91+11,17.0.1-1-gb9095d2+7,17.0.1-1-ge9fec5e+5,17.0.1-1-gf4e0155+55,17.0.1-1-gfc65f5f+50,17.0.1-1-gfc6fb1f+20,17.0.1-10-g87f9f3f+1,17.0.1-11-ge9de802+16,17.0.1-16-ga14f7d5c+4,17.0.1-17-gc79d625+1,17.0.1-17-gdae4c4a+8,17.0.1-2-g26618f5+29,17.0.1-2-g54f2ebc+9,17.0.1-2-gf403422+1,17.0.1-20-g2ca2f74+6,17.0.1-23-gf3eadeb7+1,17.0.1-3-g7e86b59+39,17.0.1-3-gb5ca14a,17.0.1-3-gd08d533+40,17.0.1-30-g596af8797,17.0.1-4-g59d126d+4,17.0.1-4-gc69c472+5,17.0.1-6-g5afd9b9+4,17.0.1-7-g35889ee+1,17.0.1-7-gc7c8782+18,17.0.1-9-gc4bbfb2+3,w.2019.22
LSSTDataManagementBasePackage
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 
24 from collections import Counter
25 
26 import numpy as np
27 
28 import lsst.utils.tests
29 
30 from lsst.afw.typehandling import Storable
31 
32 
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.
41  """
42 
44  """A subclass of Storable for testing purposes.
45  """
46  def __repr__(self):
47  return "Simplest possible representation"
48 
49  def __hash__(self):
50  return 100
51 
52  def __eq__(self, other):
53  """Warning: violates both substitution and equality symmetry!
54  """
55  return self.__class__ == other.__class__
56 
58  """A subclass of Storable for testing purposes.
59  """
60  def __init__(self, storage):
61  super().__init__()
62  self._storage = storage
63 
64  def __repr__(self):
65  return "ComplexStorable(%r)" % self._storage
66 
67  def __hash__(self):
68  return hash(self._storage)
69 
70  def __eq__(self, other):
71  """Warning: violates both substitution and equality symmetry!
72  """
73  if self.__class__ == other.__class__:
74  return self._storage == other._storage
75  else:
76  return False
77 
78  class NotAStorable:
79  """A class that should not be a legal value in a GenericMap.
80  """
81  def __str__(self):
82  return "Non-Storable"
83 
84  _testData = {
85  0: True,
86  1: 42,
87  2: 42.0,
88  3: "How many roads must a man walk down?",
89  4: SimpleStorable(),
90  5: ComplexStorable(-100.0),
91  6: None,
92  }
93 
94  @classmethod
95  def getTestData(cls, keyClass):
96  """Generic dataset for testing GenericMap classes that can handle it.
97 
98  Parameters
99  ----------
100  keyClass : `type`
101  The type of key expected by the GenericMap.
102  """
103  return {keyClass(key): value for key, value in cls._testData.items()}
104 
105  def setUp(self):
106  """Set up a test
107 
108  Subclasses must call this method if they override setUp.
109  """
110  super().setUp()
111  # tell unittest to use the msg argument of asserts as a supplement
112  # to the error message, rather than as the whole error message
113  self.longMessage = True
114 
115  # Mapping must have:
116  # __str__
117  # __repr__
118  # __eq__
119  # __ne__
120  # __contains__
121  # __getitem__
122  # get
123  # __iter__
124  # __len__
125  # __bool__
126  # keys
127  # items
128  # values
129 
130  def checkInitMapping(self, keyType, mapClass, contents, msg=""):
131  """Check initialization from a mapping.
132 
133  Parameters
134  ----------
135  keyType : `type`
136  The type of key allowed by ``mapClass``.
137  mapClass : `lsst.afw.typehandling.GenericMap`-type
138  The class whose ``__init__`` method will be tested.
139  contents : `Mapping`
140  The key-value pairs to insert into the map
141  msg : `str`
142  Error message suffix describing test parameters
143  """
144  genericMap = mapClass(contents)
145  self.checkContents(keyType, genericMap, contents, msg=msg)
146 
147  extraContents = {key: value for key, value in contents.items()} # contents need not define copy()
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)
153 
154  with self.assertRaises(TypeError, msg=msg):
155  mapClass({keyType(0): GenericMapTestBaseClass.NotAStorable()})
156 
157  def checkInitPairs(self, keyType, mapClass, contents, msg=""):
158  """Check initialization from an iterable of pairs.
159 
160  Parameters
161  ----------
162  keyType : `type`
163  The type of key allowed by ``mapClass``.
164  mapClass: `lsst.afw.typehandling.GenericMap`-type
165  The class whose ``__init__`` method will be tested.
166  contents : `Mapping`
167  The key-value pairs to insert into the map
168  msg : `str`
169  Error message suffix describing test parameters
170  """
171  genericMap = mapClass(contents.items())
172  self.checkContents(keyType, genericMap, contents, msg=msg)
173 
174  extraContents = {key: value for key, value in contents.items()} # contents need not define copy()
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)
180 
181  with self.assertRaises(TypeError, msg=msg):
182  mapClass([(keyType(0), GenericMapTestBaseClass.NotAStorable())])
183 
184  def checkInitKwargs(self, mapClass, contents, msg=""):
185  """Check bulk insertion from keywords into a GenericMap.
186 
187  Parameters
188  ----------
189  mapClass: `lsst.afw.typehandling.GenericMapS`-type
190  The class whose ``__init__`` method will be tested.
191  Must allow string keys.
192  contents : `Mapping`
193  The key-value pairs to insert into the map
194  msg : `str`
195  Error message suffix describing test parameters
196  """
197  genericMap = mapClass(**contents)
198  self.checkContents(str, genericMap, contents, msg=msg)
199 
200  with self.assertRaises(TypeError, msg=msg):
201  mapClass(notAKey=GenericMapTestBaseClass.NotAStorable())
202 
203  def checkFromKeysDefault(self, keyType, mapClass, keys, msg=""):
204  """Check initialization using the ``fromkeys`` factory.
205 
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`).
209 
210  Parameters
211  ----------
212  keyType : `type`
213  The type of key allowed by ``mapClass``.
214  mapClass: `lsst.afw.typehandling.GenericMap`-type
215  The class whose ``fromkeys`` method will be tested.
216  keys : `iterable`
217  The keys to insert into the map.
218  msg : `str`
219  Error message suffix describing test parameters
220  """
221  genericMap = mapClass.fromkeys(keys)
222  self.assertIsInstance(genericMap, mapClass, msg=msg)
223  self.checkContents(keyType, genericMap, dict.fromkeys(keys), msg=msg)
224 
225  def checkFromKeys(self, keyType, mapClass, keys, value, msg=""):
226  """Check initialization using the ``fromkeys`` factory.
227 
228  Parameters
229  ----------
230  keyType : `type`
231  The type of key allowed by ``mapClass``.
232  mapClass: `lsst.afw.typehandling.GenericMap`-type
233  The class whose ``fromkeys`` method will be tested.
234  keys : `iterable`
235  The keys to insert into the map.
236  value
237  A legal value for a GenericMap.
238  msg : `str`
239  Error message suffix describing test parameters
240  """
241  genericMap = mapClass.fromkeys(keys, value)
242  self.assertIsInstance(genericMap, mapClass, msg=msg)
243  self.checkContents(keyType, genericMap, dict.fromkeys(keys, value), msg=msg)
244 
245  def checkContains(self, keyType, genericMap, contents, msg=""):
246  """Check the contents of a GenericMap.
247 
248  Parameters
249  ----------
250  keyType : `type`
251  The type of key allowed by ``mapClass``.
252  genericMap : `lsst.afw.typehandling.GenericMap`
253  The map to test.
254  contents : `Mapping`
255  The key-value pairs that should be present in ``genericMap``
256  msg : `str`
257  Error message suffix describing test parameters
258  """
259  for key in contents:
260  self.assertIn(key, genericMap, msg=msg)
261 
262  for key in range(30):
263  if keyType(key) not in contents:
264  self.assertNotIn(keyType(key), genericMap, msg=msg)
265 
266  wrongType = float if keyType is not float else int
267  with self.assertRaises(TypeError):
268  wrongType(0) in genericMap
269 
270  def checkContents(self, keyType, genericMap, contents, msg=""):
271  """Check the contents of a GenericMap.
272 
273  Parameters
274  ----------
275  keyType : `type`
276  The type of key allowed by ``mapClass``.
277  genericMap : `lsst.afw.typehandling.GenericMap`
278  The map to test.
279  contents : `Mapping`
280  The key-value pairs that should be present in ``genericMap``
281  msg : `str`
282  Error message suffix describing test parameters
283  """
284  for key, value in contents.items():
285  self.assertEqual(genericMap[key], value, msg=msg)
286 
287  for key in (keyType(key) for key in range(30) if keyType(key) not in contents):
288  with self.assertRaises(KeyError, msg=msg):
289  genericMap[key]
290 
291  wrongType = float if keyType is not float else int
292  with self.assertRaises(TypeError):
293  genericMap[wrongType(0)]
294 
295  def checkGet(self, keyType, genericMap, contents, msg=""):
296  """Check that GenericMap.get works correctly.
297 
298  Parameters
299  ----------
300  keyType : `type`
301  The type of key allowed by ``mapClass``.
302  genericMap : `lsst.afw.typehandling.GenericMap`
303  The map to test.
304  contents : `Mapping`
305  The key-value pairs that should be present in ``genericMap``
306  msg : `str`
307  Error message suffix describing test parameters
308  """
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)
313 
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)
317 
318  wrongType = float if keyType is not float else int
319  with self.assertRaises(TypeError):
320  genericMap.get(wrongType(0))
321 
322  def checkIteration(self, genericMap, contents, msg=""):
323  """Check the result of iterating over a GenericMap.
324 
325  Parameters
326  ----------
327  genericMap : `lsst.afw.typehandling.GenericMap`
328  The map to test.
329  contents : `Mapping`
330  The key-value pairs that should be present in ``genericMap``
331  msg : `str`
332  Error message suffix describing test parameters
333  """
334  self.assertEqual({key: genericMap[key] for key in genericMap}, dict(contents), msg=msg)
335 
336  def checkViews(self, genericMap, contents, msg=""):
337  """Check the views provided by 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(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)
351 
352 
354  """Base class for unit tests of GenericMap that allow insertion/deletion.
355 
356  Subclasses must call `MutableGenericMapTestBaseClass.setUp(self)`
357  if they provide their own version.
358  """
359 
360  @classmethod
361  def _fillMap(cls, mapFactory, contents):
362  """Create a new GenericMap with particular contents.
363 
364  Parameters
365  ----------
366  mapFactory : callable
367  A zero-argument callable that creates an empty
368  `lsst.afw.typehandling.GenericMap` object
369  contents : `Mapping`
370  The key-value pairs that should be present in the new map.
371 
372  Returns
373  -------
374  map : `lsst.afw.typehandling.GenericMap`
375  a GenericMap equivalent to ``contents``
376  """
377  return cls._fillPartialMap(mapFactory, contents, len(contents))
378 
379  @classmethod
380  def _fillPartialMap(cls, mapFactory, contents, numElements):
381  """Create a new GenericMap with particular contents.
382 
383  Parameters
384  ----------
385  mapFactory : callable
386  A zero-argument callable that creates an empty
387  `lsst.afw.typehandling.GenericMap` object
388  contents : `Mapping`
389  The key-value pairs that should be present in the new map.
390  numElements : `int`
391  The number of elements from ``contents`` to be inserted.
392 
393  Returns
394  -------
395  map : `lsst.afw.typehandling.GenericMap`
396  a GenericMap containing ``numElements`` of ``contents`` or all of
397  ``contents``, whichever is smaller
398  """
399  newMap = mapFactory()
400  for i, (key, value) in enumerate(contents.items()):
401  if i < numElements:
402  newMap[key] = value
403  else:
404  break
405  return newMap
406 
407  # MutableMapping must have:
408  # __setitem__
409  # setdefault
410  # __delitem__
411  # pop
412  # popitem
413  # clear
414  # update
415 
416  def checkInsertItem(self, keyType, mapFactory, contents, msg=""):
417  """Check element insertion in a GenericMap.
418 
419  Parameters
420  ----------
421  keyType : `type`
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
426  contents : `Mapping`
427  The key-value pairs to insert into the map
428  msg : `str`
429  Error message suffix describing test parameters
430  """
431  genericMap = mapFactory()
432 
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)
438 
439  self.assertEqual(dict(genericMap), dict(contents), msg=msg)
440 
441  with self.assertRaises(TypeError, msg=msg):
442  genericMap[keyType(0)] = GenericMapTestBaseClass.NotAStorable()
443 
444  wrongType = float if keyType is not float else int
445  with self.assertRaises(TypeError):
446  genericMap[wrongType(0)] = 0
447 
448  def checkSetdefault(self, keyType, mapFactory, contents, msg=""):
449  """Check that GenericMap.setdefault works correctly.
450 
451  Parameters
452  ----------
453  keyType : `type`
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
458  contents : `Mapping`
459  The key-value pairs to insert into the map
460  msg : `str`
461  Error message suffix describing test parameters
462  """
463  genericMap = mapFactory()
464 
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)]
470 
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)
478 
479  self.assertEqual(genericMap.keys(), contents.keys(), msg=msg)
480 
481  with self.assertRaises(TypeError, msg=msg):
482  genericMap.setdefault(keyType(100), GenericMapTestBaseClass.NotAStorable())
483 
484  wrongType = float if keyType is not float else int
485  with self.assertRaises(TypeError):
486  genericMap.setdefault(wrongType(0), default)
487 
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)
495 
496  def checkUpdateMapping(self, keyType, mapFactory, contents, msg=""):
497  """Check bulk insertion from a mapping into a GenericMap.
498 
499  Parameters
500  ----------
501  keyType : `type`
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
506  contents : `Mapping`
507  The key-value pairs to insert into the map
508  msg : `str`
509  Error message suffix describing test parameters
510  """
511  genericMap = self._fillPartialMap(mapFactory, dict.fromkeys(contents, 0), len(contents)/2)
512  self.assertLess(len(genericMap), len(contents), msg=msg)
513 
514  genericMap.update(contents)
515  self.assertEqual(dict(genericMap), dict(contents), msg=msg)
516 
517  with self.assertRaises(TypeError, msg=msg):
518  genericMap.update({keyType(0): GenericMapTestBaseClass.NotAStorable()})
519 
520  wrongType = float if keyType is not float else int
521  with self.assertRaises(TypeError, msg=msg):
522  genericMap.update({wrongType(0): 0})
523 
524  def checkUpdatePairs(self, keyType, mapFactory, contents, msg=""):
525  """Check bulk insertion from an iterable of pairs into a GenericMap.
526 
527  Parameters
528  ----------
529  keyType : `type`
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
534  contents : `Mapping`
535  The key-value pairs to insert into the map
536  msg : `str`
537  Error message suffix describing test parameters
538  """
539  genericMap = self._fillPartialMap(mapFactory, dict.fromkeys(contents, 0), len(contents)/2)
540  self.assertLess(len(genericMap), len(contents), msg=msg)
541 
542  genericMap.update(contents.items())
543  self.assertEqual(dict(genericMap), dict(contents), msg=msg)
544 
545  with self.assertRaises(TypeError, msg=msg):
546  genericMap.update([(keyType(0), GenericMapTestBaseClass.NotAStorable())])
547 
548  wrongType = float if keyType is not float else int
549  with self.assertRaises(TypeError, msg=msg):
550  genericMap.update([(wrongType(0), 0)])
551 
552  def checkUpdateKwargs(self, mapFactory, contents, msg=""):
553  """Check bulk insertion from keywords into a GenericMap.
554 
555  Parameters
556  ----------
557  keyType : `type`
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.
563  contents : `Mapping`
564  The key-value pairs to insert into the map
565  msg : `str`
566  Error message suffix describing test parameters
567  """
568  genericMap = self._fillPartialMap(mapFactory, dict.fromkeys(contents, 0), len(contents)/2)
569  self.assertLess(len(genericMap), len(contents), msg=msg)
570 
571  genericMap.update(**contents)
572  self.assertEqual(dict(genericMap), dict(contents), msg=msg)
573 
574  with self.assertRaises(TypeError, msg=msg):
575  genericMap.update(notAKey=GenericMapTestBaseClass.NotAStorable())
576 
577  def checkReplaceItem(self, keyType, genericMap, msg=""):
578  """Check element replacement in a GenericMap.
579 
580  Parameters
581  ----------
582  keyType : `type`
583  The type of key allowed by ``mapClass``.
584  genericMap : `lsst.afw.typehandling.GenericMap`
585  The map to test. Must be empty.
586  msg : `str`
587  Error message suffix describing test parameters
588  """
589  self.assertFalse(genericMap, msg=msg)
590  key = keyType(42)
591 
592  for value in self.getTestData(keyType).values():
593  loopMsg = msg + " Inserting %r=%r" % (key, value)
594  genericMap[key] = value # value may be of a different type
595  self.assertEqual(len(genericMap), 1, msg=loopMsg)
596  self.assertEqual(genericMap[key], value, msg=loopMsg)
597 
598  self.assertEqual(dict(genericMap), {key: value}, msg=msg)
599 
600  with self.assertRaises(TypeError, msg=msg):
601  genericMap[key] = GenericMapTestBaseClass.NotAStorable()
602 
603  def checkRemoveItem(self, keyType, mapFactory, contents, msg=""):
604  """Check element removal from a GenericMap.
605 
606  Parameters
607  ----------
608  keyType : `type`
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
613  contents : `Mapping`
614  The key-value pairs initially occupying the map
615  msg : `str`
616  Error message suffix describing test parameters
617  """
618  genericMap = self._fillMap(mapFactory, contents)
619 
620  with self.assertRaises(KeyError, msg=msg):
621  del genericMap[keyType(2019)]
622 
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)
628  del genericMap[key]
629  self.assertEqual(len(genericMap), len(contents)-numPrevious-1, msg=loopMsg)
630  self.assertNotIn(key, genericMap, msg=loopMsg)
631 
632  wrongType = float if keyType is not float else int
633  with self.assertRaises(TypeError):
634  del genericMap[wrongType(0)]
635 
636  def checkPop(self, keyType, mapFactory, contents, msg=""):
637  """Check that GenericMap.pop works correctly.
638 
639  Parameters
640  ----------
641  keyType : `type`
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
646  contents : `Mapping`
647  The key-value pairs initially occupying the map
648  msg : `str`
649  Error message suffix describing test parameters
650  """
651  genericMap = self._fillMap(mapFactory, contents)
652 
653  with self.assertRaises(KeyError, msg=msg):
654  genericMap.pop(keyType(2019))
655 
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)
660 
661  wrongType = float if keyType is not float else int
662  with self.assertRaises(TypeError):
663  genericMap.pop(wrongType(0))
664 
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)
674 
675  def checkPopitem(self, mapFactory, contents, msg=""):
676  """Check that GenericMap.popitem works correctly.
677 
678  Parameters
679  ----------
680  mapFactory : callable
681  A zero-argument callable that creates an empty
682  `lsst.afw.typehandling.GenericMap` object of the type to be tested
683  contents : `Mapping`
684  The key-value pairs initially occupying the map
685  msg : `str`
686  Error message suffix describing test parameters
687  """
688  genericMap = self._fillMap(mapFactory, contents)
689 
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)
696 
697  with self.assertRaises(KeyError, msg=msg):
698  genericMap.popitem()
699 
700  def checkClear(self, mapFactory, contents, msg=""):
701  """Check erasing a GenericMap.
702 
703  Parameters
704  ----------
705  mapFactory : callable
706  A zero-argument callable that creates an empty
707  `lsst.afw.typehandling.GenericMap` object of the type to be tested
708  contents : `Mapping`
709  The key-value pairs initially occupying the map
710  msg : `str`
711  Error message suffix describing test parameters
712  """
713  genericMap = self._fillMap(mapFactory, contents)
714  self.assertTrue(genericMap, msg=msg)
715 
716  genericMap.clear()
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)
721 
722  def checkMutableViews(self, mapFactory, contents, msg=""):
723  """Check that the views of a GenericMap update automatically.
724 
725  This test supersedes `GenericMapTestBaseClass.checkViews`.
726 
727  Parameters
728  ----------
729  genericMap : `lsst.afw.typehandling.GenericMap`
730  The map to test.
731  contents : `Mapping`
732  The key-value pairs that should be present in ``genericMap``
733  msg : `str`
734  Error message suffix describing test parameters
735  """
736  genericMap = mapFactory()
737  keyView = genericMap.keys()
738  valueView = genericMap.values()
739  itemView = genericMap.items()
740 
741  for view in (keyView, valueView, itemView):
742  self.assertEqual(len(view), len(genericMap), msg=msg)
743  # is initial state correct?
744  self.checkViews(genericMap, {}, msg)
745 
746  for key, value in contents.items():
747  genericMap[key] = value
748 
749  for view in (keyView, valueView, itemView):
750  self.assertEqual(len(view), len(genericMap), msg=msg)
751  # is final state correct?
752  self.checkViews(genericMap, contents, msg)
def checkSetdefault(self, keyType, mapFactory, contents, msg="")
Definition: testUtils.py:448
def checkViews(self, genericMap, contents, msg="")
Definition: testUtils.py:336
def checkPopitem(self, mapFactory, contents, msg="")
Definition: testUtils.py:675
def checkInitMapping(self, keyType, mapClass, contents, msg="")
Definition: testUtils.py:130
def checkFromKeysDefault(self, keyType, mapClass, keys, msg="")
Definition: testUtils.py:203
Interface supporting iteration over heterogenous containers.
Definition: Storable.h:56
def checkPop(self, keyType, mapFactory, contents, msg="")
Definition: testUtils.py:636
def checkContents(self, keyType, genericMap, contents, msg="")
Definition: testUtils.py:270
daf::base::PropertySet * set
Definition: fits.cc:884
def checkUpdateKwargs(self, mapFactory, contents, msg="")
Definition: testUtils.py:552
def checkInsertItem(self, keyType, mapFactory, contents, msg="")
Definition: testUtils.py:416
def checkReplaceItem(self, keyType, genericMap, msg="")
Definition: testUtils.py:577
def checkUpdatePairs(self, keyType, mapFactory, contents, msg="")
Definition: testUtils.py:524
def checkUpdateMapping(self, keyType, mapFactory, contents, msg="")
Definition: testUtils.py:496
def checkIteration(self, genericMap, contents, msg="")
Definition: testUtils.py:322
def checkFromKeys(self, keyType, mapClass, keys, value, msg="")
Definition: testUtils.py:225
def checkRemoveItem(self, keyType, mapFactory, contents, msg="")
Definition: testUtils.py:603
def checkClear(self, mapFactory, contents, msg="")
Definition: testUtils.py:700
def _fillPartialMap(cls, mapFactory, contents, numElements)
Definition: testUtils.py:380
def checkInitPairs(self, keyType, mapClass, contents, msg="")
Definition: testUtils.py:157
std::vector< SchemaItem< Flag > > * items
def checkInitKwargs(self, mapClass, contents, msg="")
Definition: testUtils.py:184
def checkMutableViews(self, mapFactory, contents, msg="")
Definition: testUtils.py:722
daf::base::PropertyList * list
Definition: fits.cc:885
def checkContains(self, keyType, genericMap, contents, msg="")
Definition: testUtils.py:245
def checkGet(self, keyType, genericMap, contents, msg="")
Definition: testUtils.py:295