transform_test.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. from pyrsistent import freeze, inc, discard, rex, ny, field, PClass, pmap
  2. def test_callable_command():
  3. m = freeze({'foo': {'bar': {'baz': 1}}})
  4. assert m.transform(['foo', 'bar', 'baz'], inc) == {'foo': {'bar': {'baz': 2}}}
  5. def test_predicate():
  6. m = freeze({'foo': {'bar': {'baz': 1}, 'qux': {'baz': 1}}})
  7. assert m.transform(['foo', lambda x: x.startswith('b'), 'baz'], inc) == {'foo': {'bar': {'baz': 2}, 'qux': {'baz': 1}}}
  8. def test_broken_predicate():
  9. broken_predicates = [
  10. lambda: None,
  11. lambda a, b, c: None,
  12. lambda a, b, c, d=None: None,
  13. lambda *args: None,
  14. lambda **kwargs: None,
  15. ]
  16. for pred in broken_predicates:
  17. try:
  18. freeze({}).transform([pred], None)
  19. assert False
  20. except ValueError as e:
  21. assert str(e) == "callable in transform path must take 1 or 2 arguments"
  22. def test_key_value_predicate():
  23. m = freeze({
  24. 'foo': 1,
  25. 'bar': 2,
  26. })
  27. assert m.transform([
  28. lambda k, v: (k, v) == ('foo', 1),
  29. ], lambda v: v * 3) == {"foo": 3, "bar": 2}
  30. def test_remove():
  31. m = freeze({'foo': {'bar': {'baz': 1}}})
  32. assert m.transform(['foo', 'bar', 'baz'], discard) == {'foo': {'bar': {}}}
  33. def test_remove_pvector():
  34. m = freeze({'foo': [1, 2, 3]})
  35. assert m.transform(['foo', 1], discard) == {'foo': [1, 3]}
  36. def test_remove_pclass():
  37. class MyClass(PClass):
  38. a = field()
  39. b = field()
  40. m = freeze({'foo': MyClass(a=1, b=2)})
  41. assert m.transform(['foo', 'b'], discard) == {'foo': MyClass(a=1)}
  42. def test_predicate_no_match():
  43. m = freeze({'foo': {'bar': {'baz': 1}}})
  44. assert m.transform(['foo', lambda x: x.startswith('c'), 'baz'], inc) == m
  45. def test_rex_predicate():
  46. m = freeze({'foo': {'bar': {'baz': 1},
  47. 'bof': {'baz': 1}}})
  48. assert m.transform(['foo', rex('^bo.*'), 'baz'], inc) == {'foo': {'bar': {'baz': 1},
  49. 'bof': {'baz': 2}}}
  50. def test_rex_with_non_string_key():
  51. m = freeze({'foo': 1, 5: 2})
  52. assert m.transform([rex(".*")], 5) == {'foo': 5, 5: 2}
  53. def test_ny_predicated_matches_any_key():
  54. m = freeze({'foo': 1, 5: 2})
  55. assert m.transform([ny], 5) == {'foo': 5, 5: 5}
  56. def test_new_elements_created_when_missing():
  57. m = freeze({})
  58. assert m.transform(['foo', 'bar', 'baz'], 7) == {'foo': {'bar': {'baz': 7}}}
  59. def test_mixed_vector_and_map():
  60. m = freeze({'foo': [1, 2, 3]})
  61. assert m.transform(['foo', 1], 5) == freeze({'foo': [1, 5, 3]})
  62. def test_vector_predicate_callable_command():
  63. v = freeze([1, 2, 3, 4, 5])
  64. assert v.transform([lambda i: 0 < i < 4], inc) == freeze(freeze([1, 3, 4, 5, 5]))
  65. def test_vector_insert_map_one_step_beyond_end():
  66. v = freeze([1, 2])
  67. assert v.transform([2, 'foo'], 3) == freeze([1, 2, {'foo': 3}])
  68. def test_multiple_transformations():
  69. v = freeze([1, 2])
  70. assert v.transform([2, 'foo'], 3, [2, 'foo'], inc) == freeze([1, 2, {'foo': 4}])
  71. def test_no_transformation_returns_the_same_structure():
  72. v = freeze([{'foo': 1}, {'bar': 2}])
  73. assert v.transform([ny, ny], lambda x: x) is v
  74. def test_discard_multiple_elements_in_pvector():
  75. assert freeze([0, 1, 2, 3, 4]).transform([lambda i: i % 2], discard) == freeze([0, 2, 4])
  76. def test_transform_insert_empty_pmap():
  77. m = pmap().transform(['123'], pmap())
  78. assert m == pmap({'123': pmap()})
  79. def test_discard_does_not_insert_nodes():
  80. m = freeze({}).transform(['foo', 'bar'], discard)
  81. assert m == pmap({})