From 8f2a43eac41cd4449e67c68a93d6ad94ffb1d746 Mon Sep 17 00:00:00 2001 From: mat Date: Wed, 11 Jan 2023 07:05:54 +0800 Subject: [PATCH 1/4] Put test in place --- tests/test_map.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/test_map.py b/tests/test_map.py index 25a957e0..bc2a4292 100644 --- a/tests/test_map.py +++ b/tests/test_map.py @@ -5,6 +5,7 @@ from expression import pipe from expression.collections import Block, Map, map +from expression.core.option import Some def test_map_empty(): @@ -123,3 +124,37 @@ def test_map_iterate(xs: Dict[str, int]): ys = [k for k in map.of(**xs)] assert sorted(ys) == sorted(list(xs.keys())) + + +# @given( +# st.dictionaries(keys=st.text(), values=st.integers()), +# st.dictionaries(keys=st.text(), values=st.integers()), +# st.text(), +# st.text(), +# ) +# def test_map_change(d_1: Dict[str, int], d_2: Dict[str, int], key_1: str, key_2: str): +def test_map_change(): + d_1 = {} + d_2 = {} + key_1 = "a" + key_2 = "b" + m: Map[str, Dict[str, int]] = Map.empty() + m = m.add(key_1, d_1) + m = m.add(key_2, d_2) + m = m.change(key_2, lambda x: Some({**x.value, "other": 42})) + # m = m.change(key_1, lambda x: Some({**x.value, "some key": 5})) + + def verify( + original: Dict[str, int], map_key: str, override_key: str, override_value: int + ): + value = m.get(map_key) + assert value + assert override_key in value + for k, v in value.items(): + if k == override_key: + assert v == override_value + else: + assert v == original[k] + + # verify(d_1, key_1, "some key", 5) + verify(d_2, key_2, "other", 42) From 1cdc37b03aefb8de5456df25365002876c866557 Mon Sep 17 00:00:00 2001 From: mat Date: Wed, 11 Jan 2023 08:07:36 +0800 Subject: [PATCH 2/4] Return maptree Add test for change --- expression/collections/maptree.py | 4 ++-- tests/test_map.py | 33 +++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/expression/collections/maptree.py b/expression/collections/maptree.py index 95678801..8cf1f885 100644 --- a/expression/collections/maptree.py +++ b/expression/collections/maptree.py @@ -312,7 +312,7 @@ def change( if isinstance(m2, MapTreeNode): mn = m2 if k < mn.key: - rebalance(change(k, u, mn.left), mn.key, mn.value, mn.right) + return rebalance(change(k, u, mn.left), mn.key, mn.value, mn.right) elif k == mn.key: for v in u(Some(mn.value)).to_list(): return Some(MapTreeNode(k, v, mn.left, mn.right, mn.height)) @@ -325,7 +325,7 @@ def change( sk, sv, r_ = splice_out_successor(mn.right) return mk(mn.left, sk, sv, r_) else: - rebalance(mn.left, mn.key, mn.value, change(k, u, mn.right)) + return rebalance(mn.left, mn.key, mn.value, change(k, u, mn.right)) else: if k < m2.key: for v in u(Nothing).to_list(): diff --git a/tests/test_map.py b/tests/test_map.py index bc2a4292..ab6f5a1b 100644 --- a/tests/test_map.py +++ b/tests/test_map.py @@ -126,6 +126,16 @@ def test_map_iterate(xs: Dict[str, int]): assert sorted(ys) == sorted(list(xs.keys())) +def test_expression_issue_105(): + m: Map[str, int] = Map.empty() + m = m.add("1", 1).add("2", 2).add("3", 3).add("4", 4) + m = m.change("2", lambda x: Some(0)) # <- works cause "2" is second added item + m = m.change("1", lambda x: Some(42)) + m = m.change("3", lambda x: x) + + assert m == Map.of_list([("1", 42), ("2", 0), ("3", 3), ("4", 4)]) + + # @given( # st.dictionaries(keys=st.text(), values=st.integers()), # st.dictionaries(keys=st.text(), values=st.integers()), @@ -134,15 +144,22 @@ def test_map_iterate(xs: Dict[str, int]): # ) # def test_map_change(d_1: Dict[str, int], d_2: Dict[str, int], key_1: str, key_2: str): def test_map_change(): - d_1 = {} - d_2 = {} - key_1 = "a" - key_2 = "b" + d_1 = {"a": 1, "b": 3} + d_2 = {"some": 0, "values": -1} + key_1 = "1" + key_2 = "2" m: Map[str, Dict[str, int]] = Map.empty() - m = m.add(key_1, d_1) - m = m.add(key_2, d_2) + m = ( + m.add(key_1, d_1) + .add(key_2, d_2) + .add("3", {}) + .add("4", {}) + .add("5", {}) + .add("6", {}) + .add("7", {}) + ) m = m.change(key_2, lambda x: Some({**x.value, "other": 42})) - # m = m.change(key_1, lambda x: Some({**x.value, "some key": 5})) + m = m.change(key_1, lambda x: Some({**x.value, "some key": 5})) def verify( original: Dict[str, int], map_key: str, override_key: str, override_value: int @@ -156,5 +173,5 @@ def verify( else: assert v == original[k] - # verify(d_1, key_1, "some key", 5) + verify(d_1, key_1, "some key", 5) verify(d_2, key_2, "other", 42) From 319e1c109a0e8ddbc2ac53dcb0412d5ad089bfcf Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sat, 4 Feb 2023 06:51:31 +0100 Subject: [PATCH 3/4] Update tests/test_map.py --- tests/test_map.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_map.py b/tests/test_map.py index 8bb5d446..30523538 100644 --- a/tests/test_map.py +++ b/tests/test_map.py @@ -145,6 +145,7 @@ def test_expression_change_non_empty(): assert m == Map.of_list([("1", 42), ("2", 0), ("3", 3), ("4", 4)]) + def test_map_change(): d_1 = {"a": 1, "b": 3} d_2 = {"some": 0, "values": -1} From c5d65970176ef2e3f3237a27377495ed04613244 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sat, 4 Feb 2023 06:51:49 +0100 Subject: [PATCH 4/4] Update tests/test_map.py --- tests/test_map.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_map.py b/tests/test_map.py index 30523538..7516eae8 100644 --- a/tests/test_map.py +++ b/tests/test_map.py @@ -136,6 +136,7 @@ def test_map_change_empty(): assert xs == Map.of_seq([(1, 1), (2, 2), (3, 3)]) + def test_expression_change_non_empty(): m: Map[str, int] = Map.empty() m = m.add("1", 1).add("2", 2).add("3", 3).add("4", 4)