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
|
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:
|
def _report(t_before: str, t_after: str) -> None:
|
||||||
with open("before.dot", "w") as before, open("after.dot", "w") as after:
|
with open("before.dot", "w") as before, open("after.dot", "w") as after:
|
||||||
print(t_before, file=before)
|
print(t_before, file=before)
|
||||||
print(t_after, file=after)
|
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")
|
# @unittest.skip("Only for replicating hypothesis")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"values, delete_order",
|
"values, delete_order",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from avl import AVLTree
|
from avl import AVLTree
|
||||||
from wavl import WAVLTree
|
from wavl import WAVLTree
|
||||||
from comparator import Comparator
|
from comparator import Comparator
|
||||||
from test_wavl import delete_strategy
|
from test_properties import delete_strategy
|
||||||
|
|
||||||
import hypothesis
|
import hypothesis
|
||||||
import pytest
|
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):
|
for value in (0, 1, -1):
|
||||||
tree.insert(value)
|
tree.insert(value)
|
||||||
assert tree.is_correct
|
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 hypothesis.strategies as st
|
||||||
import logging
|
import logging
|
||||||
import pytest
|
import pytest
|
||||||
import random
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -88,25 +87,6 @@ def test_rotate(values):
|
||||||
assert tree.is_correct
|
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()))
|
@hypothesis.given(values=st.sets(st.integers()))
|
||||||
def test_search_random(values):
|
def test_search_random(values):
|
||||||
tree = WAVLTree()
|
tree = WAVLTree()
|
||||||
|
@ -119,41 +99,6 @@ def test_search_random(values):
|
||||||
assert tree.search(value) is not None
|
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")
|
# @unittest.skip("Only for replicating hypothesis")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"values, delete_order",
|
"values, delete_order",
|
||||||
|
|
Loading…
Reference in a new issue