making django-records more release worthy

This commit is contained in:
Gabor Körber
2021-06-02 10:24:33 +02:00
parent e19c5fc38e
commit bed4ae6bbd
5 changed files with 244 additions and 164 deletions

View File

@@ -3,11 +3,11 @@ from unittest.case import skipIf
from django.db.models import F
from django.test.testcases import TestCase
from django.test.utils import tag
import mock
from ..records import Lambda, Adjunct, Callback
from django.test.utils import tag
from click.types import INT
from ..adjuncts import Lambda, Adjunct, Callback
from ..handlers import RecordDictHandler
try:
@@ -22,6 +22,7 @@ except RuntimeError:
class Entity:
id: int
@dataclass
class SpaceRock:
id: int
@@ -29,6 +30,7 @@ class SpaceRock:
orbits_name: str
is_moon: bool
@tag('library')
@skipIf(not celestials_installed, "Celestials Testpackage not installed into INSTALLED_APPS.")
class TestQueryBuilder(TestCase):
@@ -46,11 +48,16 @@ class TestQueryBuilder(TestCase):
# find moons. test whether i can use entities to do an SQL query. works because i have only one key.
self.assertEqual(len(self.moons), Celestial.objects.filter(orbits__in=entities).count())
# this is pretty much the same as
self.assertEqual(len(self.moons), len(Celestial.objects.filter(
orbits__in=Celestial.objects.filter(orbits__name='Sol', celestial_type__lte=4)).values_list('id', flat=True)))
def test_handler_dict(self):
entities = Celestial.objects.filter(orbits__name='Sol', celestial_type__lte=4).records(RecordDictHandler())
self.assertEqual(len(entities), len(self.planets))
self.assertIsInstance(entities.first(), dict)
def test_lambda(self):
# this tests whether our own celestial type or the celestial type of what we orbit is correct for being a moon. parameter is a dictionary.
@@ -82,7 +89,7 @@ class TestQueryBuilder(TestCase):
self.assertEqual(len(entities), len(self.celestials))
self.assertEqual(callback_one.call_count, len(self.celestials))
self.assertEqual(callback_two.call_count, len(self.celestials))
def test_double_value_technique(self):
"""
Records open a new sort of technique for late calling details from dataclasses.
@@ -92,28 +99,30 @@ class TestQueryBuilder(TestCase):
you could e.g. use it in a subquery, while still access the data.
however this will hit the database twice if you evaluate the iterator yourself, as the lambda is not lazy.
note this is mainly a thought experiment.
"""
planet_queryset = Celestial.objects.filter(orbits__name='Sol', celestial_type__lte=4)
@dataclass
class DetailedEntity:
id: int
name: str
@dataclass
class IndexEntity:
id: int
detail: DetailedEntity
def get_details_exec(data):
return Celestial.objects.filter(pk=data.get('id')).records(DetailedEntity).first()
get_details = mock.Mock(side_effect=get_details_exec)
# retrieves data per key only.
my_planets = planet_queryset.records(IndexEntity, detail=Lambda(get_details))
my_moons = Celestial.objects.filter(orbits__in=my_planets).records(IndexEntity, detail=Lambda(get_details)) # legal
my_moons = Celestial.objects.filter(orbits__in=my_planets).records(IndexEntity, detail=Lambda(get_details)) # legal
# django does not consume the iterator internally for subqueries:
self.assertEqual(get_details.call_count, 0)
# consume it ourselves...
@@ -123,4 +132,3 @@ class TestQueryBuilder(TestCase):
# but...
self.assertEqual(len(my_moons), len(self.moons))
self.assertEqual(get_details.call_count, len(self.planets) + len(self.moons))