Skip to content

Commit

Permalink
tests: Move enums into non-nested classes
Browse files Browse the repository at this point in the history
Refs #57
  • Loading branch information
akx committed Jun 23, 2016
1 parent b82ee91 commit d16df45
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 97 deletions.
50 changes: 50 additions & 0 deletions tests/enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# coding=utf-8
from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy

from enumfields import Enum, IntEnum


class Color(Enum):
__order__ = 'RED GREEN BLUE'

RED = 'r'
GREEN = 'g'
BLUE = 'b'

class Labels:
RED = 'Reddish'
BLUE = ugettext_lazy('bluë')


class Taste(Enum):
SWEET = 1
SOUR = 2
BITTER = 3
SALTY = 4
UMAMI = 5


class ZeroEnum(Enum):
ZERO = 0
ONE = 1


class IntegerEnum(IntEnum):
A = 0
B = 1

class Labels:
A = 'foo'


class LabeledEnum(Enum):
FOO = 'foo'
BAR = 'bar'
FOOBAR = 'foobar'

class Labels:
FOO = 'Foo'
BAR = 'Bar'
# this is intentional. see test_nonunique_label
FOOBAR = 'Foo'
37 changes: 2 additions & 35 deletions tests/models.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,11 @@
from django.db import models

from enumfields import Enum, IntEnum, EnumField, EnumIntegerField
from enumfields import EnumField, EnumIntegerField
from .enums import Color, Taste, IntegerEnum, LabeledEnum, ZeroEnum


class MyModel(models.Model):
class Color(Enum):
RED = 'r'
GREEN = 'g'
BLUE = 'b'

color = EnumField(Color, max_length=1)

class Taste(Enum):
SWEET = 1
SOUR = 2
BITTER = 3
SALTY = 4
UMAMI = 5

class ZeroEnum(Enum):
ZERO = 0
ONE = 1

class IntegerEnum(IntEnum):
A = 0
B = 1
class Labels:
A = 'foo'

class LabeledEnum(Enum):
FOO = 'foo'
BAR = 'bar'
FOOBAR = 'foobar'

class Labels:
FOO = 'Foo'
BAR = 'Bar'
# this is intentional. see test_nonunique_label
FOOBAR = 'Foo'

taste = EnumField(Taste, default=Taste.SWEET)
taste_null_default = EnumField(Taste, null=True, blank=True, default=None)
taste_int = EnumIntegerField(Taste, default=Taste.SWEET)
Expand Down
37 changes: 19 additions & 18 deletions tests/test_django_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from django.test import Client
import pytest
from enumfields import EnumIntegerField
from .enums import Color, Taste, ZeroEnum, IntegerEnum
from .models import MyModel


Expand Down Expand Up @@ -46,11 +47,11 @@ def test_model_admin_post(superuser_client):
url = reverse("admin:tests_mymodel_add")
secret_uuid = str(uuid.uuid4())
post_data = {
'color': MyModel.Color.RED.value,
'taste': MyModel.Taste.UMAMI.value,
'taste_int': MyModel.Taste.SWEET.value,
'color': Color.RED.value,
'taste': Taste.UMAMI.value,
'taste_int': Taste.SWEET.value,
'random_code': secret_uuid,
'zero2': MyModel.ZeroEnum.ZERO.value,
'zero2': ZeroEnum.ZERO.value,
}
response = superuser_client.post(url, follow=True, data=post_data)
response.render()
Expand All @@ -60,29 +61,29 @@ def test_model_admin_post(superuser_client):
assert b"Select a valid choice" not in text
try:
inst = MyModel.objects.get(random_code=secret_uuid)
except MyModel.DoesNotExist:
except DoesNotExist:
assert False, "Object wasn't created in the database"
assert inst.color == MyModel.Color.RED, "Redness not assured"
assert inst.taste == MyModel.Taste.UMAMI, "Umami not there"
assert inst.taste_int == MyModel.Taste.SWEET, "Not sweet enough"
assert inst.color == Color.RED, "Redness not assured"
assert inst.taste == Taste.UMAMI, "Umami not there"
assert inst.taste_int == Taste.SWEET, "Not sweet enough"


@pytest.mark.django_db
@pytest.mark.urls('tests.urls')
@pytest.mark.parametrize('q_color', (None, MyModel.Color.BLUE, MyModel.Color.RED))
@pytest.mark.parametrize('q_taste', (None, MyModel.Taste.SWEET, MyModel.Taste.SOUR))
@pytest.mark.parametrize('q_int_enum', (None, MyModel.IntegerEnum.A, MyModel.IntegerEnum.B))
@pytest.mark.parametrize('q_color', (None, Color.BLUE, Color.RED))
@pytest.mark.parametrize('q_taste', (None, Taste.SWEET, Taste.SOUR))
@pytest.mark.parametrize('q_int_enum', (None, IntegerEnum.A, IntegerEnum.B))
def test_model_admin_filter(superuser_client, q_color, q_taste, q_int_enum):
"""
Test that various combinations of Enum filters seem to do the right thing in the change list.
"""

# Create a bunch of objects...
MyModel.objects.create(color=MyModel.Color.RED)
for taste in MyModel.Taste:
MyModel.objects.create(color=MyModel.Color.BLUE, taste=taste)
MyModel.objects.create(color=MyModel.Color.BLUE, taste=MyModel.Taste.UMAMI, int_enum=MyModel.IntegerEnum.A)
MyModel.objects.create(color=MyModel.Color.GREEN, int_enum=MyModel.IntegerEnum.B)
MyModel.objects.create(color=Color.RED)
for taste in Taste:
MyModel.objects.create(color=Color.BLUE, taste=taste)
MyModel.objects.create(color=Color.BLUE, taste=Taste.UMAMI, int_enum=IntegerEnum.A)
MyModel.objects.create(color=Color.GREEN, int_enum=IntegerEnum.B)

# Build a Django lookup...
lookup = dict((k, v) for (k, v) in {
Expand All @@ -103,6 +104,6 @@ def test_model_admin_filter(superuser_client, q_color, q_taste, q_int_enum):


def test_django_admin_lookup_value_for_integer_enum_field():
field = EnumIntegerField(MyModel.Taste)
field = EnumIntegerField(Taste)

assert field.get_prep_value(str(MyModel.Taste.BITTER)) == 3, "get_prep_value should be able to convert from strings"
assert field.get_prep_value(str(Taste.BITTER)) == 3, "get_prep_value should be able to convert from strings"
43 changes: 22 additions & 21 deletions tests/test_django_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,35 @@
from django.db import connection
from enum import IntEnum

from .enums import Color, IntegerEnum, LabeledEnum, Taste, ZeroEnum
from .models import MyModel


@pytest.mark.django_db
def test_field_value():
m = MyModel(color=MyModel.Color.RED)
m = MyModel(color=Color.RED)
m.save()
assert m.color == MyModel.Color.RED
assert m.color == Color.RED

m = MyModel.objects.filter(color=MyModel.Color.RED)[0]
assert m.color == MyModel.Color.RED
m = MyModel.objects.filter(color=Color.RED)[0]
assert m.color == Color.RED

# Passing the value should work the same way as passing the enum
assert MyModel.Color.RED.value == 'r'
assert Color.RED.value == 'r'
m = MyModel.objects.filter(color='r')[0]
assert m.color == MyModel.Color.RED
assert m.color == Color.RED

with pytest.raises(ValueError):
MyModel.objects.filter(color='xx')[0]


@pytest.mark.django_db
def test_db_value():
m = MyModel(color=MyModel.Color.RED)
m = MyModel(color=Color.RED)
m.save()
cursor = connection.cursor()
cursor.execute('SELECT color FROM %s WHERE id = %%s' % MyModel._meta.db_table, [m.pk])
assert cursor.fetchone()[0] == MyModel.Color.RED.value
assert cursor.fetchone()[0] == Color.RED.value


@pytest.mark.django_db
Expand All @@ -44,7 +45,7 @@ def test_enum_int_field_validators():
orig_method = connection.ops.integer_field_range
connection.ops.integer_field_range = (lambda *args: (-100, 100))

m = MyModel(color=MyModel.Color.RED)
m = MyModel(color=Color.RED)

# Uncache validators property of taste_int
for f in m._meta.fields:
Expand All @@ -62,28 +63,28 @@ def test_enum_int_field_validators():
@pytest.mark.django_db
def test_zero_enum_loads():
# Verifies that we can save and load enums with the value of 0 (zero).
m = MyModel(zero_field=MyModel.ZeroEnum.ZERO,
color=MyModel.Color.GREEN)
m = MyModel(zero_field=ZeroEnum.ZERO,
color=Color.GREEN)
m.save()
assert m.zero_field == MyModel.ZeroEnum.ZERO
assert m.zero_field == ZeroEnum.ZERO

m = MyModel.objects.get(id=m.id)
assert m.zero_field == MyModel.ZeroEnum.ZERO
assert m.zero_field == ZeroEnum.ZERO


@pytest.mark.django_db
def test_int_enum():
m = MyModel(int_enum=MyModel.IntegerEnum.A, color=MyModel.Color.RED)
m = MyModel(int_enum=IntegerEnum.A, color=Color.RED)
m.save()

m = MyModel.objects.get(id=m.id)
assert m.int_enum == MyModel.IntegerEnum.A
assert isinstance(m.int_enum, MyModel.IntegerEnum)
assert m.int_enum == IntegerEnum.A
assert isinstance(m.int_enum, IntegerEnum)


def test_serialization():
from django.core.serializers.python import Serializer as PythonSerializer
m = MyModel(color=MyModel.Color.RED, taste=MyModel.Taste.SALTY)
m = MyModel(color=Color.RED, taste=Taste.SALTY)
ser = PythonSerializer()
ser.serialize([m])
fields = ser.getvalue()[0]["fields"]
Expand All @@ -94,10 +95,10 @@ def test_serialization():
@pytest.mark.django_db
def test_nonunique_label():
obj = MyModel.objects.create(
color=MyModel.Color.BLUE,
labeled_enum=MyModel.LabeledEnum.FOOBAR
color=Color.BLUE,
labeled_enum=LabeledEnum.FOOBAR
)
assert obj.labeled_enum is MyModel.LabeledEnum.FOOBAR
assert obj.labeled_enum is LabeledEnum.FOOBAR

obj = MyModel.objects.get(pk=obj.pk)
assert obj.labeled_enum is MyModel.LabeledEnum.FOOBAR
assert obj.labeled_enum is LabeledEnum.FOOBAR
30 changes: 8 additions & 22 deletions tests/test_enums.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,19 @@
# -- encoding: UTF-8 --
from __future__ import unicode_literals
from django.core.exceptions import ValidationError

from django.forms import BaseForm
from django.utils.translation import ugettext_lazy
from enumfields import Enum, EnumField
from enumfields import EnumField
import pytest
import six
from six import u

from tests.models import MyModel


class Color(Enum):
__order__ = 'RED GREEN BLUE'

RED = 'r'
GREEN = 'g'
BLUE = 'b'

class Labels:
RED = 'Reddish'
BLUE = ugettext_lazy(u('bluë'))

from .enums import Color, IntegerEnum

def test_choice_ordering():
EXPECTED_CHOICES = (
('r', 'Reddish'),
('g', 'Green'),
('b', u('bluë')),
('b', 'bluë'),
)
for ((ex_key, ex_val), (key, val)) in zip(EXPECTED_CHOICES, Color.choices()):
assert key == ex_key
Expand All @@ -37,18 +23,18 @@ def test_custom_labels():
# Custom label
assert Color.RED.label == 'Reddish'
assert six.text_type(Color.RED) == 'Reddish'
assert six.text_type(MyModel.IntegerEnum.A) == 'foo'
assert six.text_type(IntegerEnum.A) == 'foo'

def test_automatic_labels():
# Automatic label
assert Color.GREEN.label == 'Green'
assert six.text_type(Color.GREEN) == 'Green'
assert six.text_type(MyModel.IntegerEnum.B) == 'B'
assert six.text_type(IntegerEnum.B) == 'B'

def test_lazy_labels():
# Lazy label
assert isinstance(six.text_type(Color.BLUE), six.string_types)
assert six.text_type(Color.BLUE) == u('bluë')
assert six.text_type(Color.BLUE) == 'bluë'

def test_formfield_labels():
# Formfield choice label
Expand All @@ -59,7 +45,7 @@ def test_formfield_labels():
assert text == expectations[value]

def test_formfield_functionality():
form_cls = type("FauxForm", (BaseForm,), {
form_cls = type(str("FauxForm"), (BaseForm,), {
"base_fields": {"color": EnumField(Color).formfield()}
})
form = form_cls(data={"color": "r"})
Expand Down
3 changes: 2 additions & 1 deletion tests/test_form_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
from django.db.models import BLANK_CHOICE_DASH
from django.forms.models import modelform_factory
import pytest
from .enums import Color
from .models import MyModel
import six


def get_form(**kwargs):
instance = MyModel(color=MyModel.Color.RED)
instance = MyModel(color=Color.RED)
FormClass = modelform_factory(MyModel, fields=("color", "zero2", "int_enum"))
return FormClass(instance=instance, **kwargs)

Expand Down

0 comments on commit d16df45

Please sign in to comment.