diff --git a/test_avl.py b/test_avl.py index b802b73..b28a3d9 100644 --- a/test_avl.py +++ b/test_avl.py @@ -116,58 +116,12 @@ def test_rotate(values): assert tree.is_correct -@hypothesis.settings(max_examples=10000, deadline=None) -@hypothesis.given(values=st.sets(st.integers())) -def test_insert_random(values): - tree = AVLTree() - - for value in values: - tree.insert(value) - assert tree.is_correct - assert tree.search(value) is not None - - -@st.composite -def delete_strategy(draw): - values = list(draw(st.sets(st.integers()))) - delete_order = values.copy() - random.shuffle(delete_order) - return (values, delete_order) - - def _report(t_before: str, t_after: str) -> None: with open("before.dot", "w") as before, open("after.dot", "w") as after: print(t_before, file=before) print(t_after, file=after) -@hypothesis.settings(max_examples=10000, deadline=None) -@hypothesis.given(config=delete_strategy()) -def test_delete_random(config): - values, delete_order = config - - tree = AVLTree() - - for value in values: - tree.insert(value) - - for value in delete_order: - before = str(tree) - tree.delete(value) - after = str(tree) - - try: - assert tree.is_correct - except AssertionError: - logger.info( - f"[FAIL] Delete {value} from {values} in order {delete_order}" - ) - _report(before, after) - logger.info(f"Before:\n{before}") - logger.info(f"After:\n{after}") - raise - - # @unittest.skip("Only for replicating hypothesis") @pytest.mark.parametrize( "values, delete_order", diff --git a/test_generate.py b/test_generate.py index d9df2bc..a573115 100644 --- a/test_generate.py +++ b/test_generate.py @@ -1,7 +1,7 @@ from avl import AVLTree from wavl import WAVLTree from comparator import Comparator -from test_wavl import delete_strategy +from test_properties import delete_strategy import hypothesis import pytest diff --git a/test_properties.py b/test_properties.py new file mode 100644 index 0000000..20a75cb --- /dev/null +++ b/test_properties.py @@ -0,0 +1,76 @@ +from avl import AVLTree +from wavl import WAVLTree +from ravl import RAVLTree + +import logging +import random +from typing import List + +import hypothesis +import hypothesis.strategies as st +import pytest + +logger = logging.getLogger(__name__) + + +@pytest.mark.parametrize( + ("RankBalancedTree"), + [AVLTree, WAVLTree, RAVLTree] +) +@hypothesis.settings(max_examples=10000) +@hypothesis.given(values=st.sets(st.integers())) +def test_insert_random(RankBalancedTree, values): + tree = RankBalancedTree() + + for value in values: + tree.insert(value) + assert tree.is_correct + assert tree.search(value) is not None + + assert all(tree.search(key) is not None for key in values) + + +@st.composite +def delete_strategy(draw): + values = list(draw(st.sets(st.integers()))) + delete_order = values.copy() + random.shuffle(delete_order) + return (values, delete_order) + + +def _report(t_before: str, t_after: str) -> None: + with open("before.dot", "w") as before, open("after.dot", "w") as after: + print(t_before, file=before) + print(t_after, file=after) + + +@pytest.mark.parametrize( + ("RankBalancedTree"), + [AVLTree, WAVLTree, RAVLTree] +) +@hypothesis.settings(max_examples=10000) +@hypothesis.given(config=delete_strategy()) +def test_delete_random(RankBalancedTree, config): + values, delete_order = config + + tree = RankBalancedTree() + + for value in values: + tree.insert(value) + + for value in delete_order: + before = str(tree) + tree.delete(value) + after = str(tree) + + try: + assert tree.is_correct + assert tree.search(value) is None + except AssertionError: + logger.info( + f"[FAIL] Delete {value} from {values} in order {delete_order}" + ) + _report(before, after) + logger.info(f"Before:\n{before}") + logger.info(f"After:\n{after}") + raise diff --git a/test_ravl.py b/test_ravl.py index 56ad51c..3e02490 100644 --- a/test_ravl.py +++ b/test_ravl.py @@ -70,64 +70,3 @@ def test_promote(): for value in (0, 1, -1): tree.insert(value) assert tree.is_correct - - -@pytest.mark.parametrize( - "values", - [ - [0, 1, -2, -1, -3], - [0, 1, -2, -1, -3, -4, 4, 9, 7], - [0, 1, -2, -1, -3, -4, 4, 9, 7, 5, -5, 8], - ], -) -def test_rotate(values): - tree = RAVLTree() - - for value in values: - tree.insert(value) - assert tree.is_correct - - -@hypothesis.settings(max_examples=10000, deadline=None) -@hypothesis.given(values=st.sets(st.integers())) -def test_insert_random(values): - tree = RAVLTree() - - for value in values: - tree.insert(value) - assert tree.is_correct - assert tree.search(value) is not None - - -@st.composite -def delete_strategy(draw): - values = list(draw(st.sets(st.integers()))) - delete_order = values.copy() - random.shuffle(delete_order) - return (values, delete_order) - - -@hypothesis.settings(max_examples=10000, deadline=None) -@hypothesis.given(config=delete_strategy()) -def test_delete_random(config): - values, delete_order = config - - tree = RAVLTree() - - for value in values: - tree.insert(value) - - for value in delete_order: - before = str(tree) - tree.delete(value) - after = str(tree) - - try: - assert tree.is_correct - except AssertionError: - logger.info( - f"[FAIL] Delete {value} from {values} in order {delete_order}" - ) - logger.info(f"Before:\n{before}") - logger.info(f"After:\n{after}") - raise diff --git a/test_wavl.py b/test_wavl.py index 340fc3c..c943df4 100644 --- a/test_wavl.py +++ b/test_wavl.py @@ -4,7 +4,6 @@ import hypothesis import hypothesis.strategies as st import logging import pytest -import random logger = logging.getLogger(__name__) @@ -88,25 +87,6 @@ def test_rotate(values): assert tree.is_correct -@hypothesis.settings(max_examples=10000, deadline=None) -@hypothesis.given(values=st.sets(st.integers())) -def test_insert_random(values): - tree = WAVLTree() - - for value in values: - tree.insert(value) - assert tree.is_correct - assert tree.search(value) is not None - - for value in values: - assert tree.search(value) is not None - - -def test_search_empty(): - tree = WAVLTree() - assert tree.search(0) is None - - @hypothesis.given(values=st.sets(st.integers())) def test_search_random(values): tree = WAVLTree() @@ -119,41 +99,6 @@ def test_search_random(values): assert tree.search(value) is not None -@st.composite -def delete_strategy(draw): - values = list(draw(st.sets(st.integers()))) - delete_order = values.copy() - random.shuffle(delete_order) - return (values, delete_order) - - -@hypothesis.settings(max_examples=10000, deadline=None) -@hypothesis.given(config=delete_strategy()) -def test_delete_random(config): - values, delete_order = config - - tree = WAVLTree() - - for value in values: - tree.insert(value) - - for value in delete_order: - before = str(tree) - tree.delete(value) - after = str(tree) - - try: - assert tree.search(value) is None - assert tree.is_correct - except AssertionError: - logger.info( - f"[FAIL] Delete {value} from {values} in order {delete_order}" - ) - logger.info(f"Before:\n{before}") - logger.info(f"After:\n{after}") - raise - - # @unittest.skip("Only for replicating hypothesis") @pytest.mark.parametrize( "values, delete_order",