checked_map_test.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import pickle
  2. import pytest
  3. from pyrsistent import CheckedPMap, InvariantException, PMap, CheckedType, CheckedPSet, CheckedPVector, \
  4. CheckedKeyTypeError, CheckedValueTypeError
  5. class FloatToIntMap(CheckedPMap):
  6. __key_type__ = float
  7. __value_type__ = int
  8. __invariant__ = lambda key, value: (int(key) == value, 'Invalid mapping')
  9. def test_instantiate():
  10. x = FloatToIntMap({1.25: 1, 2.5: 2})
  11. assert dict(x.items()) == {1.25: 1, 2.5: 2}
  12. assert isinstance(x, FloatToIntMap)
  13. assert isinstance(x, PMap)
  14. assert isinstance(x, CheckedType)
  15. def test_instantiate_empty():
  16. x = FloatToIntMap()
  17. assert dict(x.items()) == {}
  18. assert isinstance(x, FloatToIntMap)
  19. def test_set():
  20. x = FloatToIntMap()
  21. x2 = x.set(1.0, 1)
  22. assert x2[1.0] == 1
  23. assert isinstance(x2, FloatToIntMap)
  24. def test_invalid_key_type():
  25. with pytest.raises(CheckedKeyTypeError):
  26. FloatToIntMap({1: 1})
  27. def test_invalid_value_type():
  28. with pytest.raises(CheckedValueTypeError):
  29. FloatToIntMap({1.0: 1.0})
  30. def test_breaking_invariant():
  31. try:
  32. FloatToIntMap({1.5: 2})
  33. assert False
  34. except InvariantException as e:
  35. assert e.invariant_errors == ('Invalid mapping',)
  36. def test_repr():
  37. x = FloatToIntMap({1.25: 1})
  38. assert str(x) == 'FloatToIntMap({1.25: 1})'
  39. def test_default_serialization():
  40. x = FloatToIntMap({1.25: 1, 2.5: 2})
  41. assert x.serialize() == {1.25: 1, 2.5: 2}
  42. class StringFloatToIntMap(FloatToIntMap):
  43. @staticmethod
  44. def __serializer__(format, key, value):
  45. return format.format(key), format.format(value)
  46. def test_custom_serialization():
  47. x = StringFloatToIntMap({1.25: 1, 2.5: 2})
  48. assert x.serialize("{0}") == {"1.25": "1", "2.5": "2"}
  49. class FloatSet(CheckedPSet):
  50. __type__ = float
  51. class IntToFloatSetMap(CheckedPMap):
  52. __key_type__ = int
  53. __value_type__ = FloatSet
  54. def test_multi_level_serialization():
  55. x = IntToFloatSetMap.create({1: [1.25, 1.50], 2: [2.5, 2.75]})
  56. assert str(x) == "IntToFloatSetMap({1: FloatSet([1.5, 1.25]), 2: FloatSet([2.75, 2.5])})"
  57. sx = x.serialize()
  58. assert sx == {1: set([1.5, 1.25]), 2: set([2.75, 2.5])}
  59. assert isinstance(sx[1], set)
  60. def test_create_non_checked_types():
  61. assert FloatToIntMap.create({1.25: 1, 2.5: 2}) == FloatToIntMap({1.25: 1, 2.5: 2})
  62. def test_create_checked_types():
  63. class IntSet(CheckedPSet):
  64. __type__ = int
  65. class FloatVector(CheckedPVector):
  66. __type__ = float
  67. class IntSetToFloatVectorMap(CheckedPMap):
  68. __key_type__ = IntSet
  69. __value_type__ = FloatVector
  70. x = IntSetToFloatVectorMap.create({frozenset([1, 2]): [1.25, 2.5]})
  71. assert str(x) == "IntSetToFloatVectorMap({IntSet([1, 2]): FloatVector([1.25, 2.5])})"
  72. def test_evolver_returns_same_instance_when_no_updates():
  73. x = FloatToIntMap({1.25: 1, 2.25: 2})
  74. assert x.evolver().persistent() is x
  75. def test_map_with_no_types_or_invariants():
  76. class NoCheckPMap(CheckedPMap):
  77. pass
  78. x = NoCheckPMap({1: 2, 3: 4})
  79. assert x[1] == 2
  80. assert x[3] == 4
  81. def test_pickling():
  82. x = FloatToIntMap({1.25: 1, 2.5: 2})
  83. y = pickle.loads(pickle.dumps(x, -1))
  84. assert x == y
  85. assert isinstance(y, FloatToIntMap)
  86. class FloatVector(CheckedPVector):
  87. __type__ = float
  88. class VectorToSetMap(CheckedPMap):
  89. __key_type__ = '__tests__.checked_map_test.FloatVector'
  90. __value_type__ = '__tests__.checked_map_test.FloatSet'
  91. def test_type_check_with_string_specification():
  92. content = [1.5, 2.0]
  93. vec = FloatVector(content)
  94. sett = FloatSet(content)
  95. map = VectorToSetMap({vec: sett})
  96. assert map[vec] == sett
  97. def test_type_creation_with_string_specification():
  98. content = (1.5, 2.0)
  99. map = VectorToSetMap.create({content: content})
  100. assert map[FloatVector(content)] == set(content)
  101. def test_supports_weakref():
  102. import weakref
  103. weakref.ref(VectorToSetMap({}))