2022-05-18 13:39:54 +02:00
|
|
|
from avl import AVLTree
|
|
|
|
from wavl import WAVLTree
|
|
|
|
from ravl import RAVLTree
|
2022-05-20 00:01:04 +02:00
|
|
|
from rbt import RBTree
|
2022-05-18 13:39:54 +02:00
|
|
|
|
|
|
|
import logging
|
|
|
|
import random
|
|
|
|
|
|
|
|
import hypothesis
|
|
|
|
import hypothesis.strategies as st
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
2022-05-20 00:01:04 +02:00
|
|
|
("RankBalancedTree"), [RBTree, AVLTree, WAVLTree, RAVLTree]
|
2022-05-18 13:39:54 +02:00
|
|
|
)
|
|
|
|
@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(
|
2022-05-20 00:01:04 +02:00
|
|
|
("RankBalancedTree"), [RBTree, AVLTree, WAVLTree, RAVLTree]
|
2022-05-18 13:39:54 +02:00
|
|
|
)
|
|
|
|
@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
|