Skip to content

Commit

Permalink
Merge pull request #5 from cuenca-mx/asyncio
Browse files Browse the repository at this point in the history
testing async methods
  • Loading branch information
felipao-mx authored May 4, 2021
2 parents f961042 + 7e6a377 commit 3129d4a
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 4 deletions.
3 changes: 3 additions & 0 deletions mongoengine_plus/aio/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__all__ = ['AsyncDocument']

from .async_document import AsyncDocument
22 changes: 22 additions & 0 deletions mongoengine_plus/aio/async_document.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from mongoengine import Document

from .async_query_set import AsyncQuerySet
from .utils import create_awaitable


class AsyncDocument(Document):
meta = dict(
allow_inheritance=True,
queryset_class=AsyncQuerySet,
)

async def async_save(self, *args, **kwargs):
return await create_awaitable(self.save, *args, **kwargs)

async def async_reload(self, *fields, **kwargs):
return await create_awaitable(self.reload, *fields, **kwargs)

async def async_delete(self, signal_kwargs=None, **write_concern):
return await create_awaitable(
self.delete, signal_kwargs, **write_concern
)
14 changes: 14 additions & 0 deletions mongoengine_plus/aio/async_query_set.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from mongoengine import QuerySet

from .utils import create_awaitable


class AsyncQuerySet(QuerySet):
async def async_get(self, *q_objs, **query):
return await create_awaitable(self.get, *q_objs, **query)

async def async_count(self, with_limit_and_skip=False):
return await create_awaitable(self.count, with_limit_and_skip)

async def async_to_list(self):
return await create_awaitable(list, self)
8 changes: 8 additions & 0 deletions mongoengine_plus/aio/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import asyncio
from functools import partial
from typing import Any, Callable


async def create_awaitable(func: Callable, *args, **kwargs) -> Any:
loop = asyncio.get_running_loop()
return await loop.run_in_executor(None, partial(func, *args, **kwargs))
2 changes: 1 addition & 1 deletion mongoengine_plus/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.0.1'
__version__ = '0.0.2'
7 changes: 4 additions & 3 deletions requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
pytest==6.2.*
pytest-cov==2.11.*
black==20.8b1
isort==5.8.*
flake8==3.9.*
isort==5.8.*
mypy==0.812
mongomock==3.22.*
pytest==6.2.*
pytest-asyncio==0.15.1
pytest-cov==2.11.*
pytest-freezegun==0.4.*
Empty file added tests/aio/__init__.py
Empty file.
10 changes: 10 additions & 0 deletions tests/aio/cities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from mongoengine import StringField

from mongoengine_plus.aio import AsyncDocument
from mongoengine_plus.models import uuid_field


class City(AsyncDocument):
id = StringField(primary_key=True, default=uuid_field('C'))
name = StringField()
state = StringField()
21 changes: 21 additions & 0 deletions tests/aio/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from typing import Generator, List

import pytest

from .cities import City


@pytest.fixture
def cities() -> Generator[List[City], None, None]:
cities = [
City(name='Villahermosa', state='Tabasco'),
City(name='Ciudad de México', state='CDMX'),
City(name='Monterrey', state='Nuevo León'),
City(name='San Cristobal', state='Chiapas'),
City(name='Tuxtla Gutiérrez', state='Chiapas'),
]
for city in cities:
city.save()
yield cities
for city in cities:
city.delete()
30 changes: 30 additions & 0 deletions tests/aio/test_async_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pytest
from mongoengine import DoesNotExist

from .cities import City


@pytest.mark.asyncio
async def test_save():
city = City(name='Tuxtla Gutierrez')
await city.async_save()
city = await City.objects.async_get()
assert city.id is not None
assert city.name == 'Tuxtla Gutierrez'
await city.async_delete()
with pytest.raises(DoesNotExist):
await City.objects.async_get(id=city.id)


@pytest.mark.asyncio
async def test_reload():
city = City(name='Tuxtla Gutierrez')
await city.async_save()
same_city = await City.objects.async_get(id=city.id)
assert same_city.name == city.name
city.name = 'Tuxtla'
await city.async_save()
await same_city.async_reload()
assert same_city.id == city.id
assert same_city.name == city.name
await city.async_delete()
27 changes: 27 additions & 0 deletions tests/aio/test_async_query_set.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import pytest
from mongoengine import Q

from tests.aio.cities import City


@pytest.mark.asyncio
async def test_count(cities):
count = await City.objects.async_count()
assert len(cities) == count
filtered = await City.objects(state='Chiapas').async_count()
assert filtered == 2
filtered = await City.objects.filter(
Q(state='Chiapas') | Q(state='Tabasco')
).async_count()
assert filtered == 3


@pytest.mark.asyncio
async def test_to_list(cities):
cities_from_db = await City.objects.async_to_list()
assert len(cities_from_db) == len(cities)
assert all(a.id == b.id for a, b in zip(cities, cities_from_db))
filtered = await City.objects.filter(
Q(state='Chiapas') | Q(state='Tabasco')
).async_to_list()
assert len(filtered) == 3

0 comments on commit 3129d4a

Please sign in to comment.