added tests for strategy

This commit is contained in:
Simone Robutti 2021-05-05 14:29:13 +02:00
parent 3fe3c8efc6
commit 4f194ab01c
11 changed files with 117 additions and 134 deletions

View File

@ -1,8 +1,10 @@
from __future__ import annotations from __future__ import annotations
from dataclasses import dataclass, asdict from dataclasses import dataclass, asdict
from datetime import datetime from datetime import datetime
from enum import Enum from enum import Enum
from typing import Optional from typing import Optional
from jinja2 import Template from jinja2 import Template

View File

@ -1,5 +1,5 @@
from tortoise.models import Model
from tortoise import fields from tortoise import fields
from tortoise.models import Model
class Event(Model): class Event(Model):

View File

@ -1,4 +1,5 @@
from pathlib import Path from pathlib import Path
from tortoise import Tortoise from tortoise import Tortoise

46
poetry.lock generated
View File

@ -56,34 +56,6 @@ toml = ["toml"]
vault = ["hvac"] vault = ["hvac"]
yaml = ["ruamel.yaml"] yaml = ["ruamel.yaml"]
[[package]]
name = "hypothesis"
version = "6.10.1"
description = "A library for property-based testing"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
attrs = ">=19.2.0"
sortedcontainers = ">=2.1.0,<3.0.0"
[package.extras]
all = ["black (>=19.10b0)", "click (>=7.0)", "django (>=2.2)", "dpcontracts (>=0.4)", "lark-parser (>=0.6.5)", "libcst (>=0.3.16)", "numpy (>=1.9.0)", "pandas (>=0.25)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "importlib-resources (>=3.3.0)", "importlib-metadata (>=3.6)", "backports.zoneinfo (>=0.2.1)", "tzdata (>=2020.4)"]
cli = ["click (>=7.0)", "black (>=19.10b0)", "rich (>=9.0.0)"]
codemods = ["libcst (>=0.3.16)"]
dateutil = ["python-dateutil (>=1.4)"]
django = ["pytz (>=2014.1)", "django (>=2.2)"]
dpcontracts = ["dpcontracts (>=0.4)"]
ghostwriter = ["black (>=19.10b0)"]
lark = ["lark-parser (>=0.6.5)"]
numpy = ["numpy (>=1.9.0)"]
pandas = ["pandas (>=0.25)"]
pytest = ["pytest (>=4.6)"]
pytz = ["pytz (>=2014.1)"]
redis = ["redis (>=3.0.0)"]
zoneinfo = ["importlib-resources (>=3.3.0)", "backports.zoneinfo (>=0.2.1)", "tzdata (>=2020.4)"]
[[package]] [[package]]
name = "iso8601" name = "iso8601"
version = "0.1.14" version = "0.1.14"
@ -198,14 +170,6 @@ category = "main"
optional = false optional = false
python-versions = "*" python-versions = "*"
[[package]]
name = "sortedcontainers"
version = "2.3.0"
description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set"
category = "dev"
optional = false
python-versions = "*"
[[package]] [[package]]
name = "tortoise-orm" name = "tortoise-orm"
version = "0.17.2" version = "0.17.2"
@ -246,7 +210,7 @@ python-versions = "*"
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.9" python-versions = "^3.9"
content-hash = "f78f8e295d8c94dfe0e4e0f29ce5056f5cea948037cc62b9903b6bc8263a0db6" content-hash = "2a9d2f27ed4c4197d4dd022c2e1f8968ef7fff2ab73145a4bd74712f35d88855"
[metadata.files] [metadata.files]
aiosqlite = [ aiosqlite = [
@ -269,10 +233,6 @@ dynaconf = [
{file = "dynaconf-3.1.4-py2.py3-none-any.whl", hash = "sha256:e6f383b84150b70fc439c8b2757581a38a58d07962aa14517292dcce1a77e160"}, {file = "dynaconf-3.1.4-py2.py3-none-any.whl", hash = "sha256:e6f383b84150b70fc439c8b2757581a38a58d07962aa14517292dcce1a77e160"},
{file = "dynaconf-3.1.4.tar.gz", hash = "sha256:b2f472d83052f809c5925565b8a2ba76a103d5dc1dbb9748b693ed67212781b9"}, {file = "dynaconf-3.1.4.tar.gz", hash = "sha256:b2f472d83052f809c5925565b8a2ba76a103d5dc1dbb9748b693ed67212781b9"},
] ]
hypothesis = [
{file = "hypothesis-6.10.1-py3-none-any.whl", hash = "sha256:1d65f58d82d1cbd35b6441bda3bb11cb1adc879d6b2af191aea388fa412171b1"},
{file = "hypothesis-6.10.1.tar.gz", hash = "sha256:586b6c46e90878c2546743afbed348bca51e1f30e3461fa701fad58c2c47c650"},
]
iso8601 = [ iso8601 = [
{file = "iso8601-0.1.14-py2.py3-none-any.whl", hash = "sha256:e7e1122f064d626e17d47cd5106bed2c620cb38fe464999e0ddae2b6d2de6004"}, {file = "iso8601-0.1.14-py2.py3-none-any.whl", hash = "sha256:e7e1122f064d626e17d47cd5106bed2c620cb38fe464999e0ddae2b6d2de6004"},
{file = "iso8601-0.1.14.tar.gz", hash = "sha256:8aafd56fa0290496c5edbb13c311f78fa3a241f0853540da09d9363eae3ebd79"}, {file = "iso8601-0.1.14.tar.gz", hash = "sha256:8aafd56fa0290496c5edbb13c311f78fa3a241f0853540da09d9363eae3ebd79"},
@ -343,10 +303,6 @@ pytz = [
{file = "pytz-2020.5-py2.py3-none-any.whl", hash = "sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4"}, {file = "pytz-2020.5-py2.py3-none-any.whl", hash = "sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4"},
{file = "pytz-2020.5.tar.gz", hash = "sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5"}, {file = "pytz-2020.5.tar.gz", hash = "sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5"},
] ]
sortedcontainers = [
{file = "sortedcontainers-2.3.0-py2.py3-none-any.whl", hash = "sha256:37257a32add0a3ee490bb170b599e93095eed89a55da91fa9f48753ea12fd73f"},
{file = "sortedcontainers-2.3.0.tar.gz", hash = "sha256:59cc937650cf60d677c16775597c89a960658a09cf7c1a668f86e1e4464b10a1"},
]
tortoise-orm = [ tortoise-orm = [
{file = "tortoise-orm-0.17.2.tar.gz", hash = "sha256:1a742b2f15a31d47a8dea7706b478cc9a7ce9af268b61d77d0fa22cfbaea271a"}, {file = "tortoise-orm-0.17.2.tar.gz", hash = "sha256:1a742b2f15a31d47a8dea7706b478cc9a7ce9af268b61d77d0fa22cfbaea271a"},
{file = "tortoise_orm-0.17.2-py3-none-any.whl", hash = "sha256:b0c02be3800398053058377ddca91fa051eb98eebb704d2db2a3ab1c6a58e347"}, {file = "tortoise_orm-0.17.2-py3-none-any.whl", hash = "sha256:b0c02be3800398053058377ddca91fa051eb98eebb704d2db2a3ab1c6a58e347"},

View File

@ -13,7 +13,6 @@ Jinja2 = "^2.11.3"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
pytest = "^5.2" pytest = "^5.2"
hypothesis = "^6.10.1"
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]

View File

@ -1,33 +0,0 @@
import hypothesis
from hypothesis import assume
from hypothesis.provisional import urls
from hypothesis.strategies import characters, datetimes, text, sampled_from
from mobilizon_bots.event.event import MobilizonEvent, PublicationStatus
@hypothesis.strategies.composite
def events(draw, published: bool = False):
begin_datetime = draw(datetimes())
end_datetime = draw(datetimes())
assume(begin_datetime < end_datetime)
return MobilizonEvent(
name=draw(characters()),
description=draw(text()),
begin_datetime=begin_datetime,
end_datetime=end_datetime,
last_accessed=draw(datetimes()),
mobilizon_link=draw(urls()),
mobilizon_id=draw(characters()),
thumbnail_link=draw(urls()),
location=draw(text()),
publication_time=draw(datetimes()) if published else None,
publication_status=draw(
sampled_from(
[PublicationStatus.COMPLETED, PublicationStatus.PARTIAL]
if published
else [PublicationStatus.WAITING, PublicationStatus.FAILED]
)
),
)

View File

@ -1,14 +0,0 @@
import pytest
from dynaconf import settings
from tortoise.contrib.test import finalizer, initializer
@pytest.fixture(scope="session", autouse=True)
def initialize_tests(request):
settings.configure(FORCE_ENV_FOR_DYNACONF="testing")
initializer(
["tests.test_models"],
db_url=f"sqlite:///{settings.DB_PATH}",
app_label="models",
)
request.addfinalizer(finalizer)

50
tests/conftest.py Normal file
View File

@ -0,0 +1,50 @@
from datetime import datetime, timedelta
import pytest
from mobilizon_bots.event.event import MobilizonEvent, PublicationStatus
def generate_publication_status(published):
return PublicationStatus.COMPLETED if published else PublicationStatus.WAITING
@pytest.fixture
def event_generator():
def _event_generator(
begin_date=datetime(year=2021, month=1, day=1, hour=11, minute=30),
published=False,
publication_time=None,
):
return MobilizonEvent(
name="test event",
description="description of the event",
begin_datetime=begin_date,
end_datetime=begin_date + timedelta(hours=2),
last_accessed=datetime.now(),
mobilizon_link="http://some_link.com/123",
mobilizon_id="12345",
thumbnail_link="http://some_link.com/123.jpg",
location="location",
publication_status=generate_publication_status(published),
publication_time=publication_time
or (begin_date - timedelta(days=1) if published else None),
)
return _event_generator
@pytest.fixture()
def event() -> MobilizonEvent:
return MobilizonEvent(
name="test event",
description="description of the event",
begin_datetime=datetime(year=2021, month=1, day=1, hour=11, minute=30),
end_datetime=datetime(year=2021, month=1, day=1, hour=12, minute=30),
last_accessed=datetime.now(),
mobilizon_link="http://some_link.com/123",
mobilizon_id="12345",
thumbnail_link="http://some_link.com/123.jpg",
location="location",
)

View File

@ -1,10 +1,9 @@
from abc import ABC, abstractmethod
from datetime import timedelta, datetime from datetime import timedelta, datetime
from typing import List, Optional from typing import List, Optional
from mobilizon_bots.event.event import MobilizonEvent from mobilizon_bots.event.event import MobilizonEvent
from abc import ABC, abstractmethod
class EventSelectionStrategy(ABC): class EventSelectionStrategy(ABC):
@abstractmethod @abstractmethod
@ -28,13 +27,15 @@ class SelectNextEventStrategy(EventSelectionStrategy):
last_published_event = published_events[-1] last_published_event = published_events[-1]
first_unpublished_event = unpublished_events[0] first_unpublished_event = unpublished_events[0]
assert ( assert last_published_event.publication_time < datetime.now(), (
last_published_event.publication_time < datetime.now() f"Last published event has been published in the future\n"
), "Last published event has been published in the future" f"{last_published_event.publication_time}\n"
f"{datetime.now()}"
)
if ( if (
last_published_event.publication_time + self.minimum_break_between_events last_published_event.publication_time + self.minimum_break_between_events
> first_unpublished_event.begin_datetime > datetime.now()
): ):
return None return None

View File

@ -1,27 +1,6 @@
from datetime import datetime
import pytest import pytest
from hypothesis import given
from jinja2 import Template from jinja2 import Template
from mobilizon_bots.event.event import MobilizonEvent
from tests import events
@pytest.fixture()
def event() -> MobilizonEvent:
return MobilizonEvent(
name="test event",
description="description of the event",
begin_datetime=datetime(year=2021, month=1, day=1, hour=11, minute=30),
end_datetime=datetime(year=2021, month=1, day=1, hour=12, minute=30),
last_accessed=datetime.now(),
mobilizon_link="http://some_link.com/123",
mobilizon_id="12345",
thumbnail_link="http://some_link.com/123.jpg",
location="location",
)
@pytest.fixture() @pytest.fixture()
def simple_template(): def simple_template():
@ -42,8 +21,3 @@ def test_format(event, simple_template):
event.format(simple_template) event.format(simple_template)
== "test event|description of the event|location|2021-01-01, 11:30" == "test event|description of the event|location|2021-01-01, 11:30"
) )
@given(events())
def test_event_properties(event):
assert event.end_datetime > event.begin_datetime

View File

@ -1,12 +1,59 @@
from hypothesis import given from datetime import datetime, timedelta
from hypothesis.strategies import lists
from tests import events import pytest
from tests.event.event_selector import SelectNextEventStrategy
@given( @pytest.mark.parametrize(
unpublished_events=lists(events(published=True), max_size=5), "desired_break_window,days_passed_from_publication", [[2, 1], [3, 2]]
published_events=lists(events(published=False), max_size=3),
) )
def test_select_next_event_properties(unpublished_events, published_events): def test_window_simple_no_event(
pass event_generator, desired_break_window, days_passed_from_publication
):
"Testing that the break between events is respected"
unpublished_events = [
event_generator(
published=False,
begin_date=datetime(year=2021, month=1, day=5, hour=11, minute=30),
)
]
published_events = [
event_generator(
published=True,
publication_time=datetime.now()
- timedelta(days=days_passed_from_publication),
)
]
selected_event = SelectNextEventStrategy(
minimum_break_between_events=timedelta(days=desired_break_window)
).select(published_events, unpublished_events)
assert selected_event is None
@pytest.mark.parametrize(
"desired_break_window,days_passed_from_publication", [[1, 2], [2, 10], [4, 4]]
)
def test_window_simple_event_found(
event_generator, desired_break_window, days_passed_from_publication
):
"Testing that the break between events is respected"
unpublished_events = [
event_generator(
published=False,
begin_date=datetime(year=2021, month=1, day=5, hour=11, minute=30),
)
]
published_events = [
event_generator(
published=True,
publication_time=datetime.now()
- timedelta(days=days_passed_from_publication),
)
]
selected_event = SelectNextEventStrategy(
minimum_break_between_events=timedelta(days=desired_break_window)
).select(published_events, unpublished_events)
assert selected_event is unpublished_events[0]