Skip to content

Commit

Permalink
Add django point field for factories (#19)
Browse files Browse the repository at this point in the history
* add django point field for factories

* fix flake8

* install gdal in github workflow

* install spatialite github workflow

* dont specify spatialite path, so github workflow hopefully works ...

* inherit from proper test case ...

* rename test case

* mark explicitly for db, even though other test cases dont need it ..

* threw in the towel trying to get osx to work, added simple dockerfile setup ..

* run against many versions

* try to also replace DRF in github workflow

* terminate regex replace

* fix replacing DRF version

* debug prints

* fix sed replace

* fix drf ver ...

* drop support for django < 2?

* bump version -> 0.0.4
  • Loading branch information
ckcollab authored Jun 3, 2021
1 parent 553e879 commit 9855da6
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 8 deletions.
15 changes: 13 additions & 2 deletions .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ jobs:
strategy:
matrix:
python-version: [3.6, 3.7, 3.8]
django-version: ['<2', '<3', '>=3']
django-version: ['<3', '>=3']

steps:
- uses: actions/checkout@v2
- name: Install GDAL & spatialite
run: |
sudo add-apt-repository ppa:ubuntugis/ppa && sudo apt-get update
sudo apt-get install libgdal-dev libsqlite3-mod-spatialite
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
Expand All @@ -30,8 +34,15 @@ jobs:
${{ runner.os }}-
- name: Install dependencies
run: |
echo "Django version set to '${{ matrix.django-version }}' in requirements.txt"
export DRF_VERSION=3.12.4
if [ '${{ matrix.django-version }}' == '<2' ]; then
DRF_VERSION=3.11.2
fi
echo "Setting versions Django -> ${{ matrix.django-version }} DRF -> $DRF_VERSION in requirements.txt"
sed -i 's/Django==.*/Django${{ matrix.django-version }}/' requirements.txt
sed -i "s/djangorestframework==.*/djangorestframework==$DRF_VERSION/" requirements.txt
pip install -r requirements.txt
- name: Lint with flake8
run: |
Expand Down
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM python:3.9.2

# Spatial packages and such
RUN apt-get update && apt-get install -y libgdal-dev libsqlite3-mod-spatialite

# Python reqs
ADD requirements.txt .
RUN pip install -r requirements.txt

# add all of our source + config
ADD ckc/ /src/ckc/
ADD testproject/ /src/testproject
ADD tests/ /src/tests
ADD setup.cfg /src
WORKDIR /src
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ $ twine upload dist/*
## tests

```bash
# get into a virtual env of some kind
$ pip install -r requirements.txt
$ pytest
$ docker build -t django-ckc . && docker run django-ckc pytest
```

## what's in this
Expand All @@ -60,6 +58,29 @@ class MySerializer(DefaultUserCreateMixin, ModelSerializer):
model = YourModel
```

#### `DjangoGeoPointProvider`

Helps generate geo points in Factory Boy factories.

```py
# factories.py
class SomeLocationFactory(DjangoModelFactory):
location = factory.Faker('geo_point', country_code='US')

class Meta:
model = SomeLocation

# test_whatever.py
from django.contrib.gis.geos import Point


class WhateverTest(TestCase):
def test_something(self):
SomeLocationFactory() # random location
SomeLocationFactory(location=Point(x=60, y=60)) # specified location
```


#### `./manage.py` commands

| command | description|
Expand Down
2 changes: 2 additions & 0 deletions ckc/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# We import here to run the faker factory add_provider stuff...
from . import providers # noqa: F401
28 changes: 28 additions & 0 deletions ckc/providers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Doing a try/except here so we don't force end users of the
# django-ckc module to install factory boy.
try:
import factory
from django.contrib.gis.geos import Point
from faker.providers import BaseProvider

class DjangoGeoPointProvider(BaseProvider):
"""Custom helper class giving us the 'geo_point' provider, example:
location = factory.Faker('geo_point', country_code='US')
(note, you must call factory.Faker.add_provider(DjangoGeoPointProvider) to add
this provider!)
"""

def geo_point(self, **kwargs):
kwargs['coords_only'] = True
faker = factory.faker.faker.Faker()

# local_latlng returns something like:
# ('40.72371', '-73.95097', 'Greenpoint', 'US', 'America/New_York')
coords = faker.local_latlng(**kwargs)
return Point(x=float(coords[1]), y=float(coords[0]), srid=4326)

factory.Faker.add_provider(DjangoGeoPointProvider)
except ImportError:
pass
7 changes: 6 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# These requirements are for local development and testing of the module

# python packaging
twine==3.1.1

# django stuff
Django==3.1.8
djangorestframework==3.11.2
djangorestframework==3.12.4

# factories
factory-boy==3.2.0

# tests
pytest==5.4.1
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ name = django-ckc
author = Eric Carmichael
author_email = [email protected]
description = tools, utilities, etc. we use across projects @ ckc
version = 0.0.3
version = 0.0.4
url = https://github.com/ckcollab/django-ckc
keywords =
django
Expand Down
4 changes: 3 additions & 1 deletion testproject/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

BASE_DIR = os.path.dirname(__file__)

# NOTE: We're using Geospatial sqlite jazz
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"ENGINE": "django.contrib.gis.db.backends.spatialite",
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
}
}
Expand All @@ -32,6 +33,7 @@
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.staticfiles",
"django.contrib.gis",

"ckc",

Expand Down
12 changes: 12 additions & 0 deletions testproject/testapp/factories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import factory

from factory.django import DjangoModelFactory

from testapp.models import Location


class LocationFactory(DjangoModelFactory):
geo_point = factory.Faker('geo_point', country_code='US')

class Meta:
model = Location
5 changes: 5 additions & 0 deletions testproject/testapp/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.contrib.auth import get_user_model
from django.contrib.gis.db.models import PointField
from django.db import models

from ckc.models import SoftDeletableModel
Expand All @@ -17,3 +18,7 @@ class ModelWithACreator(models.Model):

class ModelWithADifferentNamedCreator(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)


class Location(models.Model):
geo_point = PointField()
16 changes: 16 additions & 0 deletions tests/integration/test_factories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from django.test import TestCase

from django.contrib.gis.geos import Point

from testapp.factories import LocationFactory


class TestFactories(TestCase):
def test_location_factory_point_works(self):
location = LocationFactory()
assert location.geo_point.x
assert location.geo_point.y

location = LocationFactory(geo_point=Point(x=50, y=50))
assert location.geo_point.x == 50
assert location.geo_point.y == 50

0 comments on commit 9855da6

Please sign in to comment.