From 7cbe2136b34d35b790257e25f4387b057782dca0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Sat, 6 May 2023 12:08:56 +0200 Subject: [PATCH] test: experimenting with hypothesis for property-based testing --- .gitignore | 1 + poetry.lock | 47 +++++++++++++++++++++++++++++++++- pyproject.toml | 1 + tests/test_transforms_hypot.py | 27 +++++++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 tests/test_transforms_hypot.py diff --git a/.gitignore b/.gitignore index aced738f..d2d5e164 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ dist venv* .*cache coverage_html +.hypothesis diff --git a/poetry.lock b/poetry.lock index 82604c3e..aa6dbd3a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -226,6 +226,39 @@ files = [ [package.extras] test = ["pytest (>=6)"] +[[package]] +name = "hypothesis" +version = "6.75.2" +description = "A library for property-based testing" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "hypothesis-6.75.2-py3-none-any.whl", hash = "sha256:29fee1fabf764eb021665d20e633ef7ba931c5841de20f9ff3e01e8a512d6a4d"}, + {file = "hypothesis-6.75.2.tar.gz", hash = "sha256:50c270b38d724ce0fefa71b8e3511d123f7a31a9af9ea003447d4e1489292fbc"}, +] + +[package.dependencies] +attrs = ">=19.2.0" +exceptiongroup = {version = ">=1.0.0", markers = "python_version < \"3.11\""} +sortedcontainers = ">=2.1.0,<3.0.0" + +[package.extras] +all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "django (>=3.2)", "dpcontracts (>=0.4)", "importlib-metadata (>=3.6)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.16.0)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2023.3)"] +cli = ["black (>=19.10b0)", "click (>=7.0)", "rich (>=9.0.0)"] +codemods = ["libcst (>=0.3.16)"] +dateutil = ["python-dateutil (>=1.4)"] +django = ["django (>=3.2)"] +dpcontracts = ["dpcontracts (>=0.4)"] +ghostwriter = ["black (>=19.10b0)"] +lark = ["lark (>=0.10.1)"] +numpy = ["numpy (>=1.16.0)"] +pandas = ["pandas (>=1.1)"] +pytest = ["pytest (>=4.6)"] +pytz = ["pytz (>=2014.1)"] +redis = ["redis (>=3.0.0)"] +zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2023.3)"] + [[package]] name = "importlib-resources" version = "5.12.0" @@ -684,6 +717,18 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +[[package]] +name = "sortedcontainers" +version = "2.4.0" +description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, + {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, +] + [[package]] name = "strict-rfc3339" version = "0.7" @@ -870,4 +915,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "71b205831169f9fa9b4e142992aa70cfe0bc543d7ba25f47ed1acb1ca9d25144" +content-hash = "2d386c187df64c833d72cbf8ee1c6d1c0cae54d2e67d27a7c2f86c9b02119361" diff --git a/pyproject.toml b/pyproject.toml index 46ff8b6c..acb64f03 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,6 +39,7 @@ pylint = "^2.4.4" black = "^22.1.0" ruff = "^0.0.254" pyupgrade = "^3.3.1" +hypothesis = "^6.75.2" [tool.ruff] ignore = ["E402", "E501"] diff --git a/tests/test_transforms_hypot.py b/tests/test_transforms_hypot.py new file mode 100644 index 00000000..9aa41aa1 --- /dev/null +++ b/tests/test_transforms_hypot.py @@ -0,0 +1,27 @@ +""" +Tests of aw-core transforms using hypothesis +""" + +from datetime import datetime, timedelta + +from aw_core.models import Event +from hypothesis import assume, given +from hypothesis import strategies as st + + +@st.composite +def events(draw, min_start=datetime.min): + start = draw(st.datetimes(min_value=min_start, timezones=st.timezones())) + duration = draw(st.timedeltas(min_value=timedelta(seconds=0))) + title = draw(st.text()) + + return Event(timestamp=start, duration=duration, data={"title": title}) + + +@given(eventlist=st.lists(events(), min_size=1)) +def test_sum_durations(eventlist): + from aw_transform import sum_durations + + assert sum_durations(eventlist) == sum( + [e.duration for e in eventlist], timedelta(seconds=0) + )