92 lines
3.4 KiB
Python
92 lines
3.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
from decimal import Decimal
|
|
|
|
from mongoengine import *
|
|
|
|
from tests.utils import MongoDBTestCase
|
|
|
|
|
|
class TestDecimalField(MongoDBTestCase):
|
|
|
|
def test_validation(self):
|
|
"""Ensure that invalid values cannot be assigned to decimal fields.
|
|
"""
|
|
class Person(Document):
|
|
height = DecimalField(min_value=Decimal('0.1'),
|
|
max_value=Decimal('3.5'))
|
|
|
|
Person.drop_collection()
|
|
|
|
Person(height=Decimal('1.89')).save()
|
|
person = Person.objects.first()
|
|
self.assertEqual(person.height, Decimal('1.89'))
|
|
|
|
person.height = '2.0'
|
|
person.save()
|
|
person.height = 0.01
|
|
self.assertRaises(ValidationError, person.validate)
|
|
person.height = Decimal('0.01')
|
|
self.assertRaises(ValidationError, person.validate)
|
|
person.height = Decimal('4.0')
|
|
self.assertRaises(ValidationError, person.validate)
|
|
person.height = 'something invalid'
|
|
self.assertRaises(ValidationError, person.validate)
|
|
|
|
person_2 = Person(height='something invalid')
|
|
self.assertRaises(ValidationError, person_2.validate)
|
|
|
|
def test_comparison(self):
|
|
class Person(Document):
|
|
money = DecimalField()
|
|
|
|
Person.drop_collection()
|
|
|
|
Person(money=6).save()
|
|
Person(money=7).save()
|
|
Person(money=8).save()
|
|
Person(money=10).save()
|
|
|
|
self.assertEqual(2, Person.objects(money__gt=Decimal("7")).count())
|
|
self.assertEqual(2, Person.objects(money__gt=7).count())
|
|
self.assertEqual(2, Person.objects(money__gt="7").count())
|
|
|
|
self.assertEqual(3, Person.objects(money__gte="7").count())
|
|
|
|
def test_storage(self):
|
|
class Person(Document):
|
|
float_value = DecimalField(precision=4)
|
|
string_value = DecimalField(precision=4, force_string=True)
|
|
|
|
Person.drop_collection()
|
|
values_to_store = [10, 10.1, 10.11, "10.111", Decimal("10.1111"), Decimal("10.11111")]
|
|
for store_at_creation in [True, False]:
|
|
for value in values_to_store:
|
|
# to_python is called explicitly if values were sent in the kwargs of __init__
|
|
if store_at_creation:
|
|
Person(float_value=value, string_value=value).save()
|
|
else:
|
|
person = Person.objects.create()
|
|
person.float_value = value
|
|
person.string_value = value
|
|
person.save()
|
|
|
|
# How its stored
|
|
expected = [
|
|
{'float_value': 10.0, 'string_value': '10.0000'},
|
|
{'float_value': 10.1, 'string_value': '10.1000'},
|
|
{'float_value': 10.11, 'string_value': '10.1100'},
|
|
{'float_value': 10.111, 'string_value': '10.1110'},
|
|
{'float_value': 10.1111, 'string_value': '10.1111'},
|
|
{'float_value': 10.1111, 'string_value': '10.1111'}]
|
|
expected.extend(expected)
|
|
actual = list(Person.objects.exclude('id').as_pymongo())
|
|
self.assertEqual(expected, actual)
|
|
|
|
# How it comes out locally
|
|
expected = [Decimal('10.0000'), Decimal('10.1000'), Decimal('10.1100'),
|
|
Decimal('10.1110'), Decimal('10.1111'), Decimal('10.1111')]
|
|
expected.extend(expected)
|
|
for field_name in ['float_value', 'string_value']:
|
|
actual = list(Person.objects().scalar(field_name))
|
|
self.assertEqual(expected, actual)
|