feat: factor out property based tests
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
f74c582401
commit
9c3452f4b5
5 changed files with 77 additions and 163 deletions
46
test_avl.py
46
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",
|
||||
|
|
|
@ -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
|
||||
|
|
76
test_properties.py
Normal file
76
test_properties.py
Normal file
|
@ -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
|
61
test_ravl.py
61
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
|
||||
|
|
55
test_wavl.py
55
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",
|
||||
|
|
Loading…
Reference in a new issue