Format the codebase using Black (#2109)

This commit:
1. Formats all of our existing code using `black`.
2. Adds a note about using `black` to `CONTRIBUTING.rst`.
3. Runs `black --check` as part of CI (failing builds that aren't properly formatted).
This commit is contained in:
Stefan Wójcik
2019-06-27 13:05:54 +02:00
committed by GitHub
parent 91899acfe5
commit b47669403b
82 changed files with 8405 additions and 7075 deletions

View File

@@ -9,34 +9,32 @@ import warnings
from mongoengine import *
__all__ = ('AllWarnings', )
__all__ = ("AllWarnings",)
class AllWarnings(unittest.TestCase):
def setUp(self):
connect(db='mongoenginetest')
connect(db="mongoenginetest")
self.warning_list = []
self.showwarning_default = warnings.showwarning
warnings.showwarning = self.append_to_warning_list
def append_to_warning_list(self, message, category, *args):
self.warning_list.append({"message": message,
"category": category})
self.warning_list.append({"message": message, "category": category})
def tearDown(self):
# restore default handling of warnings
warnings.showwarning = self.showwarning_default
def test_document_collection_syntax_warning(self):
class NonAbstractBase(Document):
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
class InheritedDocumentFailTest(NonAbstractBase):
meta = {'collection': 'fail'}
meta = {"collection": "fail"}
warning = self.warning_list[0]
self.assertEqual(SyntaxWarning, warning["category"])
self.assertEqual('non_abstract_base',
InheritedDocumentFailTest._get_collection_name())
self.assertEqual(
"non_abstract_base", InheritedDocumentFailTest._get_collection_name()
)

View File

@@ -9,5 +9,5 @@ from .instance import *
from .json_serialisation import *
from .validation import *
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -7,13 +7,12 @@ from mongoengine.pymongo_support import list_collection_names
from mongoengine.queryset import NULLIFY, PULL
from mongoengine.connection import get_db
__all__ = ("ClassMethodsTest", )
__all__ = ("ClassMethodsTest",)
class ClassMethodsTest(unittest.TestCase):
def setUp(self):
connect(db='mongoenginetest')
connect(db="mongoenginetest")
self.db = get_db()
class Person(Document):
@@ -33,11 +32,13 @@ class ClassMethodsTest(unittest.TestCase):
def test_definition(self):
"""Ensure that document may be defined using fields.
"""
self.assertEqual(['_cls', 'age', 'id', 'name'],
sorted(self.Person._fields.keys()))
self.assertEqual(["IntField", "ObjectIdField", "StringField", "StringField"],
sorted([x.__class__.__name__ for x in
self.Person._fields.values()]))
self.assertEqual(
["_cls", "age", "id", "name"], sorted(self.Person._fields.keys())
)
self.assertEqual(
["IntField", "ObjectIdField", "StringField", "StringField"],
sorted([x.__class__.__name__ for x in self.Person._fields.values()]),
)
def test_get_db(self):
"""Ensure that get_db returns the expected db.
@@ -49,21 +50,21 @@ class ClassMethodsTest(unittest.TestCase):
"""Ensure that get_collection_name returns the expected collection
name.
"""
collection_name = 'person'
collection_name = "person"
self.assertEqual(collection_name, self.Person._get_collection_name())
def test_get_collection(self):
"""Ensure that get_collection returns the expected collection.
"""
collection_name = 'person'
collection_name = "person"
collection = self.Person._get_collection()
self.assertEqual(self.db[collection_name], collection)
def test_drop_collection(self):
"""Ensure that the collection may be dropped from the database.
"""
collection_name = 'person'
self.Person(name='Test').save()
collection_name = "person"
self.Person(name="Test").save()
self.assertIn(collection_name, list_collection_names(self.db))
self.Person.drop_collection()
@@ -73,14 +74,16 @@ class ClassMethodsTest(unittest.TestCase):
"""Ensure that register delete rule adds a delete rule to the document
meta.
"""
class Job(Document):
employee = ReferenceField(self.Person)
self.assertEqual(self.Person._meta.get('delete_rules'), None)
self.assertEqual(self.Person._meta.get("delete_rules"), None)
self.Person.register_delete_rule(Job, 'employee', NULLIFY)
self.assertEqual(self.Person._meta['delete_rules'],
{(Job, 'employee'): NULLIFY})
self.Person.register_delete_rule(Job, "employee", NULLIFY)
self.assertEqual(
self.Person._meta["delete_rules"], {(Job, "employee"): NULLIFY}
)
def test_compare_indexes(self):
""" Ensure that the indexes are properly created and that
@@ -93,23 +96,27 @@ class ClassMethodsTest(unittest.TestCase):
description = StringField()
tags = StringField()
meta = {
'indexes': [('author', 'title')]
}
meta = {"indexes": [("author", "title")]}
BlogPost.drop_collection()
BlogPost.ensure_indexes()
self.assertEqual(BlogPost.compare_indexes(), {'missing': [], 'extra': []})
self.assertEqual(BlogPost.compare_indexes(), {"missing": [], "extra": []})
BlogPost.ensure_index(['author', 'description'])
self.assertEqual(BlogPost.compare_indexes(), {'missing': [], 'extra': [[('author', 1), ('description', 1)]]})
BlogPost.ensure_index(["author", "description"])
self.assertEqual(
BlogPost.compare_indexes(),
{"missing": [], "extra": [[("author", 1), ("description", 1)]]},
)
BlogPost._get_collection().drop_index('author_1_description_1')
self.assertEqual(BlogPost.compare_indexes(), {'missing': [], 'extra': []})
BlogPost._get_collection().drop_index("author_1_description_1")
self.assertEqual(BlogPost.compare_indexes(), {"missing": [], "extra": []})
BlogPost._get_collection().drop_index('author_1_title_1')
self.assertEqual(BlogPost.compare_indexes(), {'missing': [[('author', 1), ('title', 1)]], 'extra': []})
BlogPost._get_collection().drop_index("author_1_title_1")
self.assertEqual(
BlogPost.compare_indexes(),
{"missing": [[("author", 1), ("title", 1)]], "extra": []},
)
def test_compare_indexes_inheritance(self):
""" Ensure that the indexes are properly created and that
@@ -122,32 +129,34 @@ class ClassMethodsTest(unittest.TestCase):
title = StringField()
description = StringField()
meta = {
'allow_inheritance': True
}
meta = {"allow_inheritance": True}
class BlogPostWithTags(BlogPost):
tags = StringField()
tag_list = ListField(StringField())
meta = {
'indexes': [('author', 'tags')]
}
meta = {"indexes": [("author", "tags")]}
BlogPost.drop_collection()
BlogPost.ensure_indexes()
BlogPostWithTags.ensure_indexes()
self.assertEqual(BlogPost.compare_indexes(), {'missing': [], 'extra': []})
self.assertEqual(BlogPost.compare_indexes(), {"missing": [], "extra": []})
BlogPostWithTags.ensure_index(['author', 'tag_list'])
self.assertEqual(BlogPost.compare_indexes(), {'missing': [], 'extra': [[('_cls', 1), ('author', 1), ('tag_list', 1)]]})
BlogPostWithTags.ensure_index(["author", "tag_list"])
self.assertEqual(
BlogPost.compare_indexes(),
{"missing": [], "extra": [[("_cls", 1), ("author", 1), ("tag_list", 1)]]},
)
BlogPostWithTags._get_collection().drop_index('_cls_1_author_1_tag_list_1')
self.assertEqual(BlogPost.compare_indexes(), {'missing': [], 'extra': []})
BlogPostWithTags._get_collection().drop_index("_cls_1_author_1_tag_list_1")
self.assertEqual(BlogPost.compare_indexes(), {"missing": [], "extra": []})
BlogPostWithTags._get_collection().drop_index('_cls_1_author_1_tags_1')
self.assertEqual(BlogPost.compare_indexes(), {'missing': [[('_cls', 1), ('author', 1), ('tags', 1)]], 'extra': []})
BlogPostWithTags._get_collection().drop_index("_cls_1_author_1_tags_1")
self.assertEqual(
BlogPost.compare_indexes(),
{"missing": [[("_cls", 1), ("author", 1), ("tags", 1)]], "extra": []},
)
def test_compare_indexes_multiple_subclasses(self):
""" Ensure that compare_indexes behaves correctly if called from a
@@ -159,32 +168,30 @@ class ClassMethodsTest(unittest.TestCase):
title = StringField()
description = StringField()
meta = {
'allow_inheritance': True
}
meta = {"allow_inheritance": True}
class BlogPostWithTags(BlogPost):
tags = StringField()
tag_list = ListField(StringField())
meta = {
'indexes': [('author', 'tags')]
}
meta = {"indexes": [("author", "tags")]}
class BlogPostWithCustomField(BlogPost):
custom = DictField()
meta = {
'indexes': [('author', 'custom')]
}
meta = {"indexes": [("author", "custom")]}
BlogPost.ensure_indexes()
BlogPostWithTags.ensure_indexes()
BlogPostWithCustomField.ensure_indexes()
self.assertEqual(BlogPost.compare_indexes(), {'missing': [], 'extra': []})
self.assertEqual(BlogPostWithTags.compare_indexes(), {'missing': [], 'extra': []})
self.assertEqual(BlogPostWithCustomField.compare_indexes(), {'missing': [], 'extra': []})
self.assertEqual(BlogPost.compare_indexes(), {"missing": [], "extra": []})
self.assertEqual(
BlogPostWithTags.compare_indexes(), {"missing": [], "extra": []}
)
self.assertEqual(
BlogPostWithCustomField.compare_indexes(), {"missing": [], "extra": []}
)
def test_compare_indexes_for_text_indexes(self):
""" Ensure that compare_indexes behaves correctly for text indexes """
@@ -192,17 +199,20 @@ class ClassMethodsTest(unittest.TestCase):
class Doc(Document):
a = StringField()
b = StringField()
meta = {'indexes': [
{'fields': ['$a', "$b"],
'default_language': 'english',
'weights': {'a': 10, 'b': 2}
}
]}
meta = {
"indexes": [
{
"fields": ["$a", "$b"],
"default_language": "english",
"weights": {"a": 10, "b": 2},
}
]
}
Doc.drop_collection()
Doc.ensure_indexes()
actual = Doc.compare_indexes()
expected = {'missing': [], 'extra': []}
expected = {"missing": [], "extra": []}
self.assertEqual(actual, expected)
def test_list_indexes_inheritance(self):
@@ -215,23 +225,17 @@ class ClassMethodsTest(unittest.TestCase):
title = StringField()
description = StringField()
meta = {
'allow_inheritance': True
}
meta = {"allow_inheritance": True}
class BlogPostWithTags(BlogPost):
tags = StringField()
meta = {
'indexes': [('author', 'tags')]
}
meta = {"indexes": [("author", "tags")]}
class BlogPostWithTagsAndExtraText(BlogPostWithTags):
extra_text = StringField()
meta = {
'indexes': [('author', 'tags', 'extra_text')]
}
meta = {"indexes": [("author", "tags", "extra_text")]}
BlogPost.drop_collection()
@@ -239,17 +243,21 @@ class ClassMethodsTest(unittest.TestCase):
BlogPostWithTags.ensure_indexes()
BlogPostWithTagsAndExtraText.ensure_indexes()
self.assertEqual(BlogPost.list_indexes(),
BlogPostWithTags.list_indexes())
self.assertEqual(BlogPost.list_indexes(),
BlogPostWithTagsAndExtraText.list_indexes())
self.assertEqual(BlogPost.list_indexes(),
[[('_cls', 1), ('author', 1), ('tags', 1)],
[('_cls', 1), ('author', 1), ('tags', 1), ('extra_text', 1)],
[(u'_id', 1)], [('_cls', 1)]])
self.assertEqual(BlogPost.list_indexes(), BlogPostWithTags.list_indexes())
self.assertEqual(
BlogPost.list_indexes(), BlogPostWithTagsAndExtraText.list_indexes()
)
self.assertEqual(
BlogPost.list_indexes(),
[
[("_cls", 1), ("author", 1), ("tags", 1)],
[("_cls", 1), ("author", 1), ("tags", 1), ("extra_text", 1)],
[(u"_id", 1)],
[("_cls", 1)],
],
)
def test_register_delete_rule_inherited(self):
class Vaccine(Document):
name = StringField(required=True)
@@ -257,15 +265,17 @@ class ClassMethodsTest(unittest.TestCase):
class Animal(Document):
family = StringField(required=True)
vaccine_made = ListField(ReferenceField("Vaccine", reverse_delete_rule=PULL))
vaccine_made = ListField(
ReferenceField("Vaccine", reverse_delete_rule=PULL)
)
meta = {"allow_inheritance": True, "indexes": ["family"]}
class Cat(Animal):
name = StringField(required=True)
self.assertEqual(Vaccine._meta['delete_rules'][(Animal, 'vaccine_made')], PULL)
self.assertEqual(Vaccine._meta['delete_rules'][(Cat, 'vaccine_made')], PULL)
self.assertEqual(Vaccine._meta["delete_rules"][(Animal, "vaccine_made")], PULL)
self.assertEqual(Vaccine._meta["delete_rules"][(Cat, "vaccine_made")], PULL)
def test_collection_naming(self):
"""Ensure that a collection with a specified name may be used.
@@ -273,74 +283,73 @@ class ClassMethodsTest(unittest.TestCase):
class DefaultNamingTest(Document):
pass
self.assertEqual('default_naming_test',
DefaultNamingTest._get_collection_name())
self.assertEqual(
"default_naming_test", DefaultNamingTest._get_collection_name()
)
class CustomNamingTest(Document):
meta = {'collection': 'pimp_my_collection'}
meta = {"collection": "pimp_my_collection"}
self.assertEqual('pimp_my_collection',
CustomNamingTest._get_collection_name())
self.assertEqual("pimp_my_collection", CustomNamingTest._get_collection_name())
class DynamicNamingTest(Document):
meta = {'collection': lambda c: "DYNAMO"}
self.assertEqual('DYNAMO', DynamicNamingTest._get_collection_name())
meta = {"collection": lambda c: "DYNAMO"}
self.assertEqual("DYNAMO", DynamicNamingTest._get_collection_name())
# Use Abstract class to handle backwards compatibility
class BaseDocument(Document):
meta = {
'abstract': True,
'collection': lambda c: c.__name__.lower()
}
meta = {"abstract": True, "collection": lambda c: c.__name__.lower()}
class OldNamingConvention(BaseDocument):
pass
self.assertEqual('oldnamingconvention',
OldNamingConvention._get_collection_name())
self.assertEqual(
"oldnamingconvention", OldNamingConvention._get_collection_name()
)
class InheritedAbstractNamingTest(BaseDocument):
meta = {'collection': 'wibble'}
self.assertEqual('wibble',
InheritedAbstractNamingTest._get_collection_name())
meta = {"collection": "wibble"}
self.assertEqual("wibble", InheritedAbstractNamingTest._get_collection_name())
# Mixin tests
class BaseMixin(object):
meta = {
'collection': lambda c: c.__name__.lower()
}
meta = {"collection": lambda c: c.__name__.lower()}
class OldMixinNamingConvention(Document, BaseMixin):
pass
self.assertEqual('oldmixinnamingconvention',
OldMixinNamingConvention._get_collection_name())
self.assertEqual(
"oldmixinnamingconvention", OldMixinNamingConvention._get_collection_name()
)
class BaseMixin(object):
meta = {
'collection': lambda c: c.__name__.lower()
}
meta = {"collection": lambda c: c.__name__.lower()}
class BaseDocument(Document, BaseMixin):
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
class MyDocument(BaseDocument):
pass
self.assertEqual('basedocument', MyDocument._get_collection_name())
self.assertEqual("basedocument", MyDocument._get_collection_name())
def test_custom_collection_name_operations(self):
"""Ensure that a collection with a specified name is used as expected.
"""
collection_name = 'personCollTest'
collection_name = "personCollTest"
class Person(Document):
name = StringField()
meta = {'collection': collection_name}
meta = {"collection": collection_name}
Person(name="Test User").save()
self.assertIn(collection_name, list_collection_names(self.db))
user_obj = self.db[collection_name].find_one()
self.assertEqual(user_obj['name'], "Test User")
self.assertEqual(user_obj["name"], "Test User")
user_obj = Person.objects[0]
self.assertEqual(user_obj.name, "Test User")
@@ -354,7 +363,7 @@ class ClassMethodsTest(unittest.TestCase):
class Person(Document):
name = StringField(primary_key=True)
meta = {'collection': 'app'}
meta = {"collection": "app"}
Person(name="Test User").save()
@@ -364,5 +373,5 @@ class ClassMethodsTest(unittest.TestCase):
Person.drop_collection()
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

File diff suppressed because it is too large Load Diff

View File

@@ -3,17 +3,16 @@ import unittest
from mongoengine import *
from tests.utils import MongoDBTestCase
__all__ = ("TestDynamicDocument", )
__all__ = ("TestDynamicDocument",)
class TestDynamicDocument(MongoDBTestCase):
def setUp(self):
super(TestDynamicDocument, self).setUp()
class Person(DynamicDocument):
name = StringField()
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
Person.drop_collection()
@@ -26,8 +25,7 @@ class TestDynamicDocument(MongoDBTestCase):
p.name = "James"
p.age = 34
self.assertEqual(p.to_mongo(), {"_cls": "Person", "name": "James",
"age": 34})
self.assertEqual(p.to_mongo(), {"_cls": "Person", "name": "James", "age": 34})
self.assertEqual(p.to_mongo().keys(), ["_cls", "name", "age"])
p.save()
self.assertEqual(p.to_mongo().keys(), ["_id", "_cls", "name", "age"])
@@ -35,7 +33,7 @@ class TestDynamicDocument(MongoDBTestCase):
self.assertEqual(self.Person.objects.first().age, 34)
# Confirm no changes to self.Person
self.assertFalse(hasattr(self.Person, 'age'))
self.assertFalse(hasattr(self.Person, "age"))
def test_change_scope_of_variable(self):
"""Test changing the scope of a dynamic field has no adverse effects"""
@@ -45,11 +43,11 @@ class TestDynamicDocument(MongoDBTestCase):
p.save()
p = self.Person.objects.get()
p.misc = {'hello': 'world'}
p.misc = {"hello": "world"}
p.save()
p = self.Person.objects.get()
self.assertEqual(p.misc, {'hello': 'world'})
self.assertEqual(p.misc, {"hello": "world"})
def test_delete_dynamic_field(self):
"""Test deleting a dynamic field works"""
@@ -60,23 +58,23 @@ class TestDynamicDocument(MongoDBTestCase):
p.save()
p = self.Person.objects.get()
p.misc = {'hello': 'world'}
p.misc = {"hello": "world"}
p.save()
p = self.Person.objects.get()
self.assertEqual(p.misc, {'hello': 'world'})
self.assertEqual(p.misc, {"hello": "world"})
collection = self.db[self.Person._get_collection_name()]
obj = collection.find_one()
self.assertEqual(sorted(obj.keys()), ['_cls', '_id', 'misc', 'name'])
self.assertEqual(sorted(obj.keys()), ["_cls", "_id", "misc", "name"])
del p.misc
p.save()
p = self.Person.objects.get()
self.assertFalse(hasattr(p, 'misc'))
self.assertFalse(hasattr(p, "misc"))
obj = collection.find_one()
self.assertEqual(sorted(obj.keys()), ['_cls', '_id', 'name'])
self.assertEqual(sorted(obj.keys()), ["_cls", "_id", "name"])
def test_reload_after_unsetting(self):
p = self.Person()
@@ -91,77 +89,52 @@ class TestDynamicDocument(MongoDBTestCase):
p.update(age=1)
self.assertEqual(len(p._data), 3)
self.assertEqual(sorted(p._data.keys()), ['_cls', 'id', 'name'])
self.assertEqual(sorted(p._data.keys()), ["_cls", "id", "name"])
p.reload()
self.assertEqual(len(p._data), 4)
self.assertEqual(sorted(p._data.keys()), ['_cls', 'age', 'id', 'name'])
self.assertEqual(sorted(p._data.keys()), ["_cls", "age", "id", "name"])
def test_fields_without_underscore(self):
"""Ensure we can query dynamic fields"""
Person = self.Person
p = self.Person(name='Dean')
p = self.Person(name="Dean")
p.save()
raw_p = Person.objects.as_pymongo().get(id=p.id)
self.assertEqual(
raw_p,
{
'_cls': u'Person',
'_id': p.id,
'name': u'Dean'
}
)
self.assertEqual(raw_p, {"_cls": u"Person", "_id": p.id, "name": u"Dean"})
p.name = 'OldDean'
p.newattr = 'garbage'
p.name = "OldDean"
p.newattr = "garbage"
p.save()
raw_p = Person.objects.as_pymongo().get(id=p.id)
self.assertEqual(
raw_p,
{
'_cls': u'Person',
'_id': p.id,
'name': 'OldDean',
'newattr': u'garbage'
}
{"_cls": u"Person", "_id": p.id, "name": "OldDean", "newattr": u"garbage"},
)
def test_fields_containing_underscore(self):
"""Ensure we can query dynamic fields"""
class WeirdPerson(DynamicDocument):
name = StringField()
_name = StringField()
WeirdPerson.drop_collection()
p = WeirdPerson(name='Dean', _name='Dean')
p = WeirdPerson(name="Dean", _name="Dean")
p.save()
raw_p = WeirdPerson.objects.as_pymongo().get(id=p.id)
self.assertEqual(
raw_p,
{
'_id': p.id,
'_name': u'Dean',
'name': u'Dean'
}
)
self.assertEqual(raw_p, {"_id": p.id, "_name": u"Dean", "name": u"Dean"})
p.name = 'OldDean'
p._name = 'NewDean'
p._newattr1 = 'garbage' # Unknown fields won't be added
p.name = "OldDean"
p._name = "NewDean"
p._newattr1 = "garbage" # Unknown fields won't be added
p.save()
raw_p = WeirdPerson.objects.as_pymongo().get(id=p.id)
self.assertEqual(
raw_p,
{
'_id': p.id,
'_name': u'NewDean',
'name': u'OldDean',
}
)
self.assertEqual(raw_p, {"_id": p.id, "_name": u"NewDean", "name": u"OldDean"})
def test_dynamic_document_queries(self):
"""Ensure we can query dynamic fields"""
@@ -193,26 +166,25 @@ class TestDynamicDocument(MongoDBTestCase):
p2.age = 10
p2.save()
self.assertEqual(Person.objects(age__icontains='ten').count(), 2)
self.assertEqual(Person.objects(age__icontains="ten").count(), 2)
self.assertEqual(Person.objects(age__gte=10).count(), 1)
def test_complex_data_lookups(self):
"""Ensure you can query dynamic document dynamic fields"""
p = self.Person()
p.misc = {'hello': 'world'}
p.misc = {"hello": "world"}
p.save()
self.assertEqual(1, self.Person.objects(misc__hello='world').count())
self.assertEqual(1, self.Person.objects(misc__hello="world").count())
def test_three_level_complex_data_lookups(self):
"""Ensure you can query three level document dynamic fields"""
p = self.Person.objects.create(
misc={'hello': {'hello2': 'world'}}
)
self.assertEqual(1, self.Person.objects(misc__hello__hello2='world').count())
p = self.Person.objects.create(misc={"hello": {"hello2": "world"}})
self.assertEqual(1, self.Person.objects(misc__hello__hello2="world").count())
def test_complex_embedded_document_validation(self):
"""Ensure embedded dynamic documents may be validated"""
class Embedded(DynamicEmbeddedDocument):
content = URLField()
@@ -222,10 +194,10 @@ class TestDynamicDocument(MongoDBTestCase):
Doc.drop_collection()
doc = Doc()
embedded_doc_1 = Embedded(content='http://mongoengine.org')
embedded_doc_1 = Embedded(content="http://mongoengine.org")
embedded_doc_1.validate()
embedded_doc_2 = Embedded(content='this is not a url')
embedded_doc_2 = Embedded(content="this is not a url")
self.assertRaises(ValidationError, embedded_doc_2.validate)
doc.embedded_field_1 = embedded_doc_1
@@ -234,15 +206,17 @@ class TestDynamicDocument(MongoDBTestCase):
def test_inheritance(self):
"""Ensure that dynamic document plays nice with inheritance"""
class Employee(self.Person):
salary = IntField()
Employee.drop_collection()
self.assertIn('name', Employee._fields)
self.assertIn('salary', Employee._fields)
self.assertEqual(Employee._get_collection_name(),
self.Person._get_collection_name())
self.assertIn("name", Employee._fields)
self.assertIn("salary", Employee._fields)
self.assertEqual(
Employee._get_collection_name(), self.Person._get_collection_name()
)
joe_bloggs = Employee()
joe_bloggs.name = "Joe Bloggs"
@@ -258,6 +232,7 @@ class TestDynamicDocument(MongoDBTestCase):
def test_embedded_dynamic_document(self):
"""Test dynamic embedded documents"""
class Embedded(DynamicEmbeddedDocument):
pass
@@ -268,78 +243,88 @@ class TestDynamicDocument(MongoDBTestCase):
doc = Doc()
embedded_1 = Embedded()
embedded_1.string_field = 'hello'
embedded_1.string_field = "hello"
embedded_1.int_field = 1
embedded_1.dict_field = {'hello': 'world'}
embedded_1.list_field = ['1', 2, {'hello': 'world'}]
embedded_1.dict_field = {"hello": "world"}
embedded_1.list_field = ["1", 2, {"hello": "world"}]
doc.embedded_field = embedded_1
self.assertEqual(doc.to_mongo(), {
"embedded_field": {
"_cls": "Embedded",
"string_field": "hello",
"int_field": 1,
"dict_field": {"hello": "world"},
"list_field": ['1', 2, {'hello': 'world'}]
}
})
doc.save()
doc = Doc.objects.first()
self.assertEqual(doc.embedded_field.__class__, Embedded)
self.assertEqual(doc.embedded_field.string_field, "hello")
self.assertEqual(doc.embedded_field.int_field, 1)
self.assertEqual(doc.embedded_field.dict_field, {'hello': 'world'})
self.assertEqual(doc.embedded_field.list_field,
['1', 2, {'hello': 'world'}])
def test_complex_embedded_documents(self):
"""Test complex dynamic embedded documents setups"""
class Embedded(DynamicEmbeddedDocument):
pass
class Doc(DynamicDocument):
pass
Doc.drop_collection()
doc = Doc()
embedded_1 = Embedded()
embedded_1.string_field = 'hello'
embedded_1.int_field = 1
embedded_1.dict_field = {'hello': 'world'}
embedded_2 = Embedded()
embedded_2.string_field = 'hello'
embedded_2.int_field = 1
embedded_2.dict_field = {'hello': 'world'}
embedded_2.list_field = ['1', 2, {'hello': 'world'}]
embedded_1.list_field = ['1', 2, embedded_2]
doc.embedded_field = embedded_1
self.assertEqual(doc.to_mongo(), {
"embedded_field": {
"_cls": "Embedded",
"string_field": "hello",
"int_field": 1,
"dict_field": {"hello": "world"},
"list_field": ['1', 2,
{"_cls": "Embedded",
self.assertEqual(
doc.to_mongo(),
{
"embedded_field": {
"_cls": "Embedded",
"string_field": "hello",
"int_field": 1,
"dict_field": {"hello": "world"},
"list_field": ['1', 2, {'hello': 'world'}]}
]
}
})
"list_field": ["1", 2, {"hello": "world"}],
}
},
)
doc.save()
doc = Doc.objects.first()
self.assertEqual(doc.embedded_field.__class__, Embedded)
self.assertEqual(doc.embedded_field.string_field, "hello")
self.assertEqual(doc.embedded_field.int_field, 1)
self.assertEqual(doc.embedded_field.dict_field, {"hello": "world"})
self.assertEqual(doc.embedded_field.list_field, ["1", 2, {"hello": "world"}])
def test_complex_embedded_documents(self):
"""Test complex dynamic embedded documents setups"""
class Embedded(DynamicEmbeddedDocument):
pass
class Doc(DynamicDocument):
pass
Doc.drop_collection()
doc = Doc()
embedded_1 = Embedded()
embedded_1.string_field = "hello"
embedded_1.int_field = 1
embedded_1.dict_field = {"hello": "world"}
embedded_2 = Embedded()
embedded_2.string_field = "hello"
embedded_2.int_field = 1
embedded_2.dict_field = {"hello": "world"}
embedded_2.list_field = ["1", 2, {"hello": "world"}]
embedded_1.list_field = ["1", 2, embedded_2]
doc.embedded_field = embedded_1
self.assertEqual(
doc.to_mongo(),
{
"embedded_field": {
"_cls": "Embedded",
"string_field": "hello",
"int_field": 1,
"dict_field": {"hello": "world"},
"list_field": [
"1",
2,
{
"_cls": "Embedded",
"string_field": "hello",
"int_field": 1,
"dict_field": {"hello": "world"},
"list_field": ["1", 2, {"hello": "world"}],
},
],
}
},
)
doc.save()
doc = Doc.objects.first()
self.assertEqual(doc.embedded_field.__class__, Embedded)
self.assertEqual(doc.embedded_field.string_field, "hello")
self.assertEqual(doc.embedded_field.int_field, 1)
self.assertEqual(doc.embedded_field.dict_field, {'hello': 'world'})
self.assertEqual(doc.embedded_field.list_field[0], '1')
self.assertEqual(doc.embedded_field.dict_field, {"hello": "world"})
self.assertEqual(doc.embedded_field.list_field[0], "1")
self.assertEqual(doc.embedded_field.list_field[1], 2)
embedded_field = doc.embedded_field.list_field[2]
@@ -347,9 +332,8 @@ class TestDynamicDocument(MongoDBTestCase):
self.assertEqual(embedded_field.__class__, Embedded)
self.assertEqual(embedded_field.string_field, "hello")
self.assertEqual(embedded_field.int_field, 1)
self.assertEqual(embedded_field.dict_field, {'hello': 'world'})
self.assertEqual(embedded_field.list_field, ['1', 2,
{'hello': 'world'}])
self.assertEqual(embedded_field.dict_field, {"hello": "world"})
self.assertEqual(embedded_field.list_field, ["1", 2, {"hello": "world"}])
def test_dynamic_and_embedded(self):
"""Ensure embedded documents play nicely"""
@@ -392,10 +376,15 @@ class TestDynamicDocument(MongoDBTestCase):
Person.drop_collection()
Person(name="Eric", address=Address(city="San Francisco", street_number="1337")).save()
Person(
name="Eric", address=Address(city="San Francisco", street_number="1337")
).save()
self.assertEqual(Person.objects.first().address.street_number, '1337')
self.assertEqual(Person.objects.only('address__street_number').first().address.street_number, '1337')
self.assertEqual(Person.objects.first().address.street_number, "1337")
self.assertEqual(
Person.objects.only("address__street_number").first().address.street_number,
"1337",
)
def test_dynamic_and_embedded_dict_access(self):
"""Ensure embedded dynamic documents work with dict[] style access"""
@@ -435,5 +424,5 @@ class TestDynamicDocument(MongoDBTestCase):
self.assertEqual(Person.objects.first().age, 35)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

File diff suppressed because it is too large Load Diff

View File

@@ -4,18 +4,24 @@ import warnings
from six import iteritems
from mongoengine import (BooleanField, Document, EmbeddedDocument,
EmbeddedDocumentField, GenericReferenceField,
IntField, ReferenceField, StringField)
from mongoengine import (
BooleanField,
Document,
EmbeddedDocument,
EmbeddedDocumentField,
GenericReferenceField,
IntField,
ReferenceField,
StringField,
)
from mongoengine.pymongo_support import list_collection_names
from tests.utils import MongoDBTestCase
from tests.fixtures import Base
__all__ = ('InheritanceTest', )
__all__ = ("InheritanceTest",)
class InheritanceTest(MongoDBTestCase):
def tearDown(self):
for collection in list_collection_names(self.db):
self.db.drop_collection(collection)
@@ -25,16 +31,16 @@ class InheritanceTest(MongoDBTestCase):
# and when object gets reloaded (prevent regression of #1950)
class EmbedData(EmbeddedDocument):
data = StringField()
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
class DataDoc(Document):
name = StringField()
embed = EmbeddedDocumentField(EmbedData)
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
test_doc = DataDoc(name='test', embed=EmbedData(data='data'))
self.assertEqual(test_doc._cls, 'DataDoc')
self.assertEqual(test_doc.embed._cls, 'EmbedData')
test_doc = DataDoc(name="test", embed=EmbedData(data="data"))
self.assertEqual(test_doc._cls, "DataDoc")
self.assertEqual(test_doc.embed._cls, "EmbedData")
test_doc.save()
saved_doc = DataDoc.objects.with_id(test_doc.id)
self.assertEqual(test_doc._cls, saved_doc._cls)
@@ -44,163 +50,234 @@ class InheritanceTest(MongoDBTestCase):
def test_superclasses(self):
"""Ensure that the correct list of superclasses is assembled.
"""
class Animal(Document):
meta = {'allow_inheritance': True}
class Fish(Animal): pass
class Guppy(Fish): pass
class Mammal(Animal): pass
class Dog(Mammal): pass
class Human(Mammal): pass
meta = {"allow_inheritance": True}
class Fish(Animal):
pass
class Guppy(Fish):
pass
class Mammal(Animal):
pass
class Dog(Mammal):
pass
class Human(Mammal):
pass
self.assertEqual(Animal._superclasses, ())
self.assertEqual(Fish._superclasses, ('Animal',))
self.assertEqual(Guppy._superclasses, ('Animal', 'Animal.Fish'))
self.assertEqual(Mammal._superclasses, ('Animal',))
self.assertEqual(Dog._superclasses, ('Animal', 'Animal.Mammal'))
self.assertEqual(Human._superclasses, ('Animal', 'Animal.Mammal'))
self.assertEqual(Fish._superclasses, ("Animal",))
self.assertEqual(Guppy._superclasses, ("Animal", "Animal.Fish"))
self.assertEqual(Mammal._superclasses, ("Animal",))
self.assertEqual(Dog._superclasses, ("Animal", "Animal.Mammal"))
self.assertEqual(Human._superclasses, ("Animal", "Animal.Mammal"))
def test_external_superclasses(self):
"""Ensure that the correct list of super classes is assembled when
importing part of the model.
"""
class Animal(Base): pass
class Fish(Animal): pass
class Guppy(Fish): pass
class Mammal(Animal): pass
class Dog(Mammal): pass
class Human(Mammal): pass
self.assertEqual(Animal._superclasses, ('Base', ))
self.assertEqual(Fish._superclasses, ('Base', 'Base.Animal',))
self.assertEqual(Guppy._superclasses, ('Base', 'Base.Animal',
'Base.Animal.Fish'))
self.assertEqual(Mammal._superclasses, ('Base', 'Base.Animal',))
self.assertEqual(Dog._superclasses, ('Base', 'Base.Animal',
'Base.Animal.Mammal'))
self.assertEqual(Human._superclasses, ('Base', 'Base.Animal',
'Base.Animal.Mammal'))
class Animal(Base):
pass
class Fish(Animal):
pass
class Guppy(Fish):
pass
class Mammal(Animal):
pass
class Dog(Mammal):
pass
class Human(Mammal):
pass
self.assertEqual(Animal._superclasses, ("Base",))
self.assertEqual(Fish._superclasses, ("Base", "Base.Animal"))
self.assertEqual(
Guppy._superclasses, ("Base", "Base.Animal", "Base.Animal.Fish")
)
self.assertEqual(Mammal._superclasses, ("Base", "Base.Animal"))
self.assertEqual(
Dog._superclasses, ("Base", "Base.Animal", "Base.Animal.Mammal")
)
self.assertEqual(
Human._superclasses, ("Base", "Base.Animal", "Base.Animal.Mammal")
)
def test_subclasses(self):
"""Ensure that the correct list of _subclasses (subclasses) is
assembled.
"""
class Animal(Document):
meta = {'allow_inheritance': True}
class Fish(Animal): pass
class Guppy(Fish): pass
class Mammal(Animal): pass
class Dog(Mammal): pass
class Human(Mammal): pass
self.assertEqual(Animal._subclasses, ('Animal',
'Animal.Fish',
'Animal.Fish.Guppy',
'Animal.Mammal',
'Animal.Mammal.Dog',
'Animal.Mammal.Human'))
self.assertEqual(Fish._subclasses, ('Animal.Fish',
'Animal.Fish.Guppy',))
self.assertEqual(Guppy._subclasses, ('Animal.Fish.Guppy',))
self.assertEqual(Mammal._subclasses, ('Animal.Mammal',
'Animal.Mammal.Dog',
'Animal.Mammal.Human'))
self.assertEqual(Human._subclasses, ('Animal.Mammal.Human',))
class Animal(Document):
meta = {"allow_inheritance": True}
class Fish(Animal):
pass
class Guppy(Fish):
pass
class Mammal(Animal):
pass
class Dog(Mammal):
pass
class Human(Mammal):
pass
self.assertEqual(
Animal._subclasses,
(
"Animal",
"Animal.Fish",
"Animal.Fish.Guppy",
"Animal.Mammal",
"Animal.Mammal.Dog",
"Animal.Mammal.Human",
),
)
self.assertEqual(Fish._subclasses, ("Animal.Fish", "Animal.Fish.Guppy"))
self.assertEqual(Guppy._subclasses, ("Animal.Fish.Guppy",))
self.assertEqual(
Mammal._subclasses,
("Animal.Mammal", "Animal.Mammal.Dog", "Animal.Mammal.Human"),
)
self.assertEqual(Human._subclasses, ("Animal.Mammal.Human",))
def test_external_subclasses(self):
"""Ensure that the correct list of _subclasses (subclasses) is
assembled when importing part of the model.
"""
class Animal(Base): pass
class Fish(Animal): pass
class Guppy(Fish): pass
class Mammal(Animal): pass
class Dog(Mammal): pass
class Human(Mammal): pass
self.assertEqual(Animal._subclasses, ('Base.Animal',
'Base.Animal.Fish',
'Base.Animal.Fish.Guppy',
'Base.Animal.Mammal',
'Base.Animal.Mammal.Dog',
'Base.Animal.Mammal.Human'))
self.assertEqual(Fish._subclasses, ('Base.Animal.Fish',
'Base.Animal.Fish.Guppy',))
self.assertEqual(Guppy._subclasses, ('Base.Animal.Fish.Guppy',))
self.assertEqual(Mammal._subclasses, ('Base.Animal.Mammal',
'Base.Animal.Mammal.Dog',
'Base.Animal.Mammal.Human'))
self.assertEqual(Human._subclasses, ('Base.Animal.Mammal.Human',))
class Animal(Base):
pass
class Fish(Animal):
pass
class Guppy(Fish):
pass
class Mammal(Animal):
pass
class Dog(Mammal):
pass
class Human(Mammal):
pass
self.assertEqual(
Animal._subclasses,
(
"Base.Animal",
"Base.Animal.Fish",
"Base.Animal.Fish.Guppy",
"Base.Animal.Mammal",
"Base.Animal.Mammal.Dog",
"Base.Animal.Mammal.Human",
),
)
self.assertEqual(
Fish._subclasses, ("Base.Animal.Fish", "Base.Animal.Fish.Guppy")
)
self.assertEqual(Guppy._subclasses, ("Base.Animal.Fish.Guppy",))
self.assertEqual(
Mammal._subclasses,
(
"Base.Animal.Mammal",
"Base.Animal.Mammal.Dog",
"Base.Animal.Mammal.Human",
),
)
self.assertEqual(Human._subclasses, ("Base.Animal.Mammal.Human",))
def test_dynamic_declarations(self):
"""Test that declaring an extra class updates meta data"""
class Animal(Document):
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
self.assertEqual(Animal._superclasses, ())
self.assertEqual(Animal._subclasses, ('Animal',))
self.assertEqual(Animal._subclasses, ("Animal",))
# Test dynamically adding a class changes the meta data
class Fish(Animal):
pass
self.assertEqual(Animal._superclasses, ())
self.assertEqual(Animal._subclasses, ('Animal', 'Animal.Fish'))
self.assertEqual(Animal._subclasses, ("Animal", "Animal.Fish"))
self.assertEqual(Fish._superclasses, ('Animal', ))
self.assertEqual(Fish._subclasses, ('Animal.Fish',))
self.assertEqual(Fish._superclasses, ("Animal",))
self.assertEqual(Fish._subclasses, ("Animal.Fish",))
# Test dynamically adding an inherited class changes the meta data
class Pike(Fish):
pass
self.assertEqual(Animal._superclasses, ())
self.assertEqual(Animal._subclasses, ('Animal', 'Animal.Fish',
'Animal.Fish.Pike'))
self.assertEqual(
Animal._subclasses, ("Animal", "Animal.Fish", "Animal.Fish.Pike")
)
self.assertEqual(Fish._superclasses, ('Animal', ))
self.assertEqual(Fish._subclasses, ('Animal.Fish', 'Animal.Fish.Pike'))
self.assertEqual(Fish._superclasses, ("Animal",))
self.assertEqual(Fish._subclasses, ("Animal.Fish", "Animal.Fish.Pike"))
self.assertEqual(Pike._superclasses, ('Animal', 'Animal.Fish'))
self.assertEqual(Pike._subclasses, ('Animal.Fish.Pike',))
self.assertEqual(Pike._superclasses, ("Animal", "Animal.Fish"))
self.assertEqual(Pike._subclasses, ("Animal.Fish.Pike",))
def test_inheritance_meta_data(self):
"""Ensure that document may inherit fields from a superclass document.
"""
class Person(Document):
name = StringField()
age = IntField()
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
class Employee(Person):
salary = IntField()
self.assertEqual(['_cls', 'age', 'id', 'name', 'salary'],
sorted(Employee._fields.keys()))
self.assertEqual(Employee._get_collection_name(),
Person._get_collection_name())
self.assertEqual(
["_cls", "age", "id", "name", "salary"], sorted(Employee._fields.keys())
)
self.assertEqual(Employee._get_collection_name(), Person._get_collection_name())
def test_inheritance_to_mongo_keys(self):
"""Ensure that document may inherit fields from a superclass document.
"""
class Person(Document):
name = StringField()
age = IntField()
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
class Employee(Person):
salary = IntField()
self.assertEqual(['_cls', 'age', 'id', 'name', 'salary'],
sorted(Employee._fields.keys()))
self.assertEqual(Person(name="Bob", age=35).to_mongo().keys(),
['_cls', 'name', 'age'])
self.assertEqual(Employee(name="Bob", age=35, salary=0).to_mongo().keys(),
['_cls', 'name', 'age', 'salary'])
self.assertEqual(Employee._get_collection_name(),
Person._get_collection_name())
self.assertEqual(
["_cls", "age", "id", "name", "salary"], sorted(Employee._fields.keys())
)
self.assertEqual(
Person(name="Bob", age=35).to_mongo().keys(), ["_cls", "name", "age"]
)
self.assertEqual(
Employee(name="Bob", age=35, salary=0).to_mongo().keys(),
["_cls", "name", "age", "salary"],
)
self.assertEqual(Employee._get_collection_name(), Person._get_collection_name())
def test_indexes_and_multiple_inheritance(self):
""" Ensure that all of the indexes are created for a document with
@@ -210,18 +287,12 @@ class InheritanceTest(MongoDBTestCase):
class A(Document):
a = StringField()
meta = {
'allow_inheritance': True,
'indexes': ['a']
}
meta = {"allow_inheritance": True, "indexes": ["a"]}
class B(Document):
b = StringField()
meta = {
'allow_inheritance': True,
'indexes': ['b']
}
meta = {"allow_inheritance": True, "indexes": ["b"]}
class C(A, B):
pass
@@ -233,8 +304,12 @@ class InheritanceTest(MongoDBTestCase):
C.ensure_indexes()
self.assertEqual(
sorted([idx['key'] for idx in C._get_collection().index_information().values()]),
sorted([[(u'_cls', 1), (u'b', 1)], [(u'_id', 1)], [(u'_cls', 1), (u'a', 1)]])
sorted(
[idx["key"] for idx in C._get_collection().index_information().values()]
),
sorted(
[[(u"_cls", 1), (u"b", 1)], [(u"_id", 1)], [(u"_cls", 1), (u"a", 1)]]
),
)
def test_polymorphic_queries(self):
@@ -242,11 +317,19 @@ class InheritanceTest(MongoDBTestCase):
"""
class Animal(Document):
meta = {'allow_inheritance': True}
class Fish(Animal): pass
class Mammal(Animal): pass
class Dog(Mammal): pass
class Human(Mammal): pass
meta = {"allow_inheritance": True}
class Fish(Animal):
pass
class Mammal(Animal):
pass
class Dog(Mammal):
pass
class Human(Mammal):
pass
Animal.drop_collection()
@@ -269,58 +352,68 @@ class InheritanceTest(MongoDBTestCase):
"""Ensure that inheritance is disabled by default on simple
classes and that _cls will not be used.
"""
class Animal(Document):
name = StringField()
# can't inherit because Animal didn't explicitly allow inheritance
with self.assertRaises(ValueError) as cm:
class Dog(Animal):
pass
self.assertIn("Document Animal may not be subclassed", str(cm.exception))
# Check that _cls etc aren't present on simple documents
dog = Animal(name='dog').save()
self.assertEqual(dog.to_mongo().keys(), ['_id', 'name'])
dog = Animal(name="dog").save()
self.assertEqual(dog.to_mongo().keys(), ["_id", "name"])
collection = self.db[Animal._get_collection_name()]
obj = collection.find_one()
self.assertNotIn('_cls', obj)
self.assertNotIn("_cls", obj)
def test_cant_turn_off_inheritance_on_subclass(self):
"""Ensure if inheritance is on in a subclass you cant turn it off.
"""
class Animal(Document):
name = StringField()
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
with self.assertRaises(ValueError) as cm:
class Mammal(Animal):
meta = {'allow_inheritance': False}
self.assertEqual(str(cm.exception), 'Only direct subclasses of Document may set "allow_inheritance" to False')
meta = {"allow_inheritance": False}
self.assertEqual(
str(cm.exception),
'Only direct subclasses of Document may set "allow_inheritance" to False',
)
def test_allow_inheritance_abstract_document(self):
"""Ensure that abstract documents can set inheritance rules and that
_cls will not be used.
"""
class FinalDocument(Document):
meta = {'abstract': True,
'allow_inheritance': False}
meta = {"abstract": True, "allow_inheritance": False}
class Animal(FinalDocument):
name = StringField()
with self.assertRaises(ValueError) as cm:
class Mammal(Animal):
pass
# Check that _cls isn't present in simple documents
doc = Animal(name='dog')
self.assertNotIn('_cls', doc.to_mongo())
doc = Animal(name="dog")
self.assertNotIn("_cls", doc.to_mongo())
def test_using_abstract_class_in_reference_field(self):
# Ensures no regression of #1920
class AbstractHuman(Document):
meta = {'abstract': True}
meta = {"abstract": True}
class Dad(AbstractHuman):
name = StringField()
@@ -329,130 +422,122 @@ class InheritanceTest(MongoDBTestCase):
dad = ReferenceField(AbstractHuman) # Referencing the abstract class
address = StringField()
dad = Dad(name='5').save()
Home(dad=dad, address='street').save()
dad = Dad(name="5").save()
Home(dad=dad, address="street").save()
home = Home.objects.first()
home.address = 'garbage'
home.save() # Was failing with ValidationError
home.address = "garbage"
home.save() # Was failing with ValidationError
def test_abstract_class_referencing_self(self):
# Ensures no regression of #1920
class Human(Document):
meta = {'abstract': True}
creator = ReferenceField('self', dbref=True)
meta = {"abstract": True}
creator = ReferenceField("self", dbref=True)
class User(Human):
name = StringField()
user = User(name='John').save()
user2 = User(name='Foo', creator=user).save()
user = User(name="John").save()
user2 = User(name="Foo", creator=user).save()
user2 = User.objects.with_id(user2.id)
user2.name = 'Bar'
user2.save() # Was failing with ValidationError
user2.name = "Bar"
user2.save() # Was failing with ValidationError
def test_abstract_handle_ids_in_metaclass_properly(self):
class City(Document):
continent = StringField()
meta = {'abstract': True,
'allow_inheritance': False}
meta = {"abstract": True, "allow_inheritance": False}
class EuropeanCity(City):
name = StringField()
berlin = EuropeanCity(name='Berlin', continent='Europe')
berlin = EuropeanCity(name="Berlin", continent="Europe")
self.assertEqual(len(berlin._db_field_map), len(berlin._fields_ordered))
self.assertEqual(len(berlin._reverse_db_field_map), len(berlin._fields_ordered))
self.assertEqual(len(berlin._fields_ordered), 3)
self.assertEqual(berlin._fields_ordered[0], 'id')
self.assertEqual(berlin._fields_ordered[0], "id")
def test_auto_id_not_set_if_specific_in_parent_class(self):
class City(Document):
continent = StringField()
city_id = IntField(primary_key=True)
meta = {'abstract': True,
'allow_inheritance': False}
meta = {"abstract": True, "allow_inheritance": False}
class EuropeanCity(City):
name = StringField()
berlin = EuropeanCity(name='Berlin', continent='Europe')
berlin = EuropeanCity(name="Berlin", continent="Europe")
self.assertEqual(len(berlin._db_field_map), len(berlin._fields_ordered))
self.assertEqual(len(berlin._reverse_db_field_map), len(berlin._fields_ordered))
self.assertEqual(len(berlin._fields_ordered), 3)
self.assertEqual(berlin._fields_ordered[0], 'city_id')
self.assertEqual(berlin._fields_ordered[0], "city_id")
def test_auto_id_vs_non_pk_id_field(self):
class City(Document):
continent = StringField()
id = IntField()
meta = {'abstract': True,
'allow_inheritance': False}
meta = {"abstract": True, "allow_inheritance": False}
class EuropeanCity(City):
name = StringField()
berlin = EuropeanCity(name='Berlin', continent='Europe')
berlin = EuropeanCity(name="Berlin", continent="Europe")
self.assertEqual(len(berlin._db_field_map), len(berlin._fields_ordered))
self.assertEqual(len(berlin._reverse_db_field_map), len(berlin._fields_ordered))
self.assertEqual(len(berlin._fields_ordered), 4)
self.assertEqual(berlin._fields_ordered[0], 'auto_id_0')
self.assertEqual(berlin._fields_ordered[0], "auto_id_0")
berlin.save()
self.assertEqual(berlin.pk, berlin.auto_id_0)
def test_abstract_document_creation_does_not_fail(self):
class City(Document):
continent = StringField()
meta = {'abstract': True,
'allow_inheritance': False}
meta = {"abstract": True, "allow_inheritance": False}
city = City(continent='asia')
city = City(continent="asia")
self.assertEqual(None, city.pk)
# TODO: expected error? Shouldn't we create a new error type?
with self.assertRaises(KeyError):
setattr(city, 'pk', 1)
setattr(city, "pk", 1)
def test_allow_inheritance_embedded_document(self):
"""Ensure embedded documents respect inheritance."""
class Comment(EmbeddedDocument):
content = StringField()
with self.assertRaises(ValueError):
class SpecialComment(Comment):
pass
doc = Comment(content='test')
self.assertNotIn('_cls', doc.to_mongo())
doc = Comment(content="test")
self.assertNotIn("_cls", doc.to_mongo())
class Comment(EmbeddedDocument):
content = StringField()
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
doc = Comment(content='test')
self.assertIn('_cls', doc.to_mongo())
doc = Comment(content="test")
self.assertIn("_cls", doc.to_mongo())
def test_document_inheritance(self):
"""Ensure mutliple inheritance of abstract documents
"""
class DateCreatedDocument(Document):
meta = {
'allow_inheritance': True,
'abstract': True,
}
meta = {"allow_inheritance": True, "abstract": True}
class DateUpdatedDocument(Document):
meta = {
'allow_inheritance': True,
'abstract': True,
}
meta = {"allow_inheritance": True, "abstract": True}
try:
class MyDocument(DateCreatedDocument, DateUpdatedDocument):
pass
except Exception:
self.assertTrue(False, "Couldn't create MyDocument class")
@@ -460,47 +545,55 @@ class InheritanceTest(MongoDBTestCase):
"""Ensure that a document superclass can be marked as abstract
thereby not using it as the name for the collection."""
defaults = {'index_background': True,
'index_drop_dups': True,
'index_opts': {'hello': 'world'},
'allow_inheritance': True,
'queryset_class': 'QuerySet',
'db_alias': 'myDB',
'shard_key': ('hello', 'world')}
defaults = {
"index_background": True,
"index_drop_dups": True,
"index_opts": {"hello": "world"},
"allow_inheritance": True,
"queryset_class": "QuerySet",
"db_alias": "myDB",
"shard_key": ("hello", "world"),
}
meta_settings = {'abstract': True}
meta_settings = {"abstract": True}
meta_settings.update(defaults)
class Animal(Document):
name = StringField()
meta = meta_settings
class Fish(Animal): pass
class Guppy(Fish): pass
class Fish(Animal):
pass
class Guppy(Fish):
pass
class Mammal(Animal):
meta = {'abstract': True}
class Human(Mammal): pass
meta = {"abstract": True}
class Human(Mammal):
pass
for k, v in iteritems(defaults):
for cls in [Animal, Fish, Guppy]:
self.assertEqual(cls._meta[k], v)
self.assertNotIn('collection', Animal._meta)
self.assertNotIn('collection', Mammal._meta)
self.assertNotIn("collection", Animal._meta)
self.assertNotIn("collection", Mammal._meta)
self.assertEqual(Animal._get_collection_name(), None)
self.assertEqual(Mammal._get_collection_name(), None)
self.assertEqual(Fish._get_collection_name(), 'fish')
self.assertEqual(Guppy._get_collection_name(), 'fish')
self.assertEqual(Human._get_collection_name(), 'human')
self.assertEqual(Fish._get_collection_name(), "fish")
self.assertEqual(Guppy._get_collection_name(), "fish")
self.assertEqual(Human._get_collection_name(), "human")
# ensure that a subclass of a non-abstract class can't be abstract
with self.assertRaises(ValueError):
class EvilHuman(Human):
evil = BooleanField(default=True)
meta = {'abstract': True}
meta = {"abstract": True}
def test_abstract_embedded_documents(self):
# 789: EmbeddedDocument shouldn't inherit abstract
@@ -519,7 +612,7 @@ class InheritanceTest(MongoDBTestCase):
class Drink(Document):
name = StringField()
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
class Drinker(Document):
drink = GenericReferenceField()
@@ -528,13 +621,13 @@ class InheritanceTest(MongoDBTestCase):
warnings.simplefilter("error")
class AcloholicDrink(Drink):
meta = {'collection': 'booze'}
meta = {"collection": "booze"}
except SyntaxWarning:
warnings.simplefilter("ignore")
class AlcoholicDrink(Drink):
meta = {'collection': 'booze'}
meta = {"collection": "booze"}
else:
raise AssertionError("SyntaxWarning should be triggered")
@@ -545,13 +638,13 @@ class InheritanceTest(MongoDBTestCase):
AlcoholicDrink.drop_collection()
Drinker.drop_collection()
red_bull = Drink(name='Red Bull')
red_bull = Drink(name="Red Bull")
red_bull.save()
programmer = Drinker(drink=red_bull)
programmer.save()
beer = AlcoholicDrink(name='Beer')
beer = AlcoholicDrink(name="Beer")
beer.save()
real_person = Drinker(drink=beer)
real_person.save()
@@ -560,5 +653,5 @@ class InheritanceTest(MongoDBTestCase):
self.assertEqual(Drinker.objects[1].drink.name, beer.name)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

File diff suppressed because it is too large Load Diff

View File

@@ -13,9 +13,8 @@ __all__ = ("TestJson",)
class TestJson(unittest.TestCase):
def setUp(self):
connect(db='mongoenginetest')
connect(db="mongoenginetest")
def test_json_names(self):
"""
@@ -25,22 +24,24 @@ class TestJson(unittest.TestCase):
a to_json with the original class names and not the abreviated
mongodb document keys
"""
class Embedded(EmbeddedDocument):
string = StringField(db_field='s')
string = StringField(db_field="s")
class Doc(Document):
string = StringField(db_field='s')
embedded = EmbeddedDocumentField(Embedded, db_field='e')
string = StringField(db_field="s")
embedded = EmbeddedDocumentField(Embedded, db_field="e")
doc = Doc(string="Hello", embedded=Embedded(string="Inner Hello"))
doc_json = doc.to_json(sort_keys=True, use_db_field=False, separators=(',', ':'))
doc_json = doc.to_json(
sort_keys=True, use_db_field=False, separators=(",", ":")
)
expected_json = """{"embedded":{"string":"Inner Hello"},"string":"Hello"}"""
self.assertEqual(doc_json, expected_json)
def test_json_simple(self):
class Embedded(EmbeddedDocument):
string = StringField()
@@ -49,12 +50,14 @@ class TestJson(unittest.TestCase):
embedded_field = EmbeddedDocumentField(Embedded)
def __eq__(self, other):
return (self.string == other.string and
self.embedded_field == other.embedded_field)
return (
self.string == other.string
and self.embedded_field == other.embedded_field
)
doc = Doc(string="Hi", embedded_field=Embedded(string="Hi"))
doc_json = doc.to_json(sort_keys=True, separators=(',', ':'))
doc_json = doc.to_json(sort_keys=True, separators=(",", ":"))
expected_json = """{"embedded_field":{"string":"Hi"},"string":"Hi"}"""
self.assertEqual(doc_json, expected_json)
@@ -68,41 +71,43 @@ class TestJson(unittest.TestCase):
pass
class Doc(Document):
string_field = StringField(default='1')
string_field = StringField(default="1")
int_field = IntField(default=1)
float_field = FloatField(default=1.1)
boolean_field = BooleanField(default=True)
datetime_field = DateTimeField(default=datetime.now)
embedded_document_field = EmbeddedDocumentField(EmbeddedDoc,
default=lambda: EmbeddedDoc())
embedded_document_field = EmbeddedDocumentField(
EmbeddedDoc, default=lambda: EmbeddedDoc()
)
list_field = ListField(default=lambda: [1, 2, 3])
dict_field = DictField(default=lambda: {"hello": "world"})
objectid_field = ObjectIdField(default=ObjectId)
reference_field = ReferenceField(Simple, default=lambda:
Simple().save())
reference_field = ReferenceField(Simple, default=lambda: Simple().save())
map_field = MapField(IntField(), default=lambda: {"simple": 1})
decimal_field = DecimalField(default=1.0)
complex_datetime_field = ComplexDateTimeField(default=datetime.now)
url_field = URLField(default="http://mongoengine.org")
dynamic_field = DynamicField(default=1)
generic_reference_field = GenericReferenceField(
default=lambda: Simple().save())
sorted_list_field = SortedListField(IntField(),
default=lambda: [1, 2, 3])
default=lambda: Simple().save()
)
sorted_list_field = SortedListField(IntField(), default=lambda: [1, 2, 3])
email_field = EmailField(default="ross@example.com")
geo_point_field = GeoPointField(default=lambda: [1, 2])
sequence_field = SequenceField()
uuid_field = UUIDField(default=uuid.uuid4)
generic_embedded_document_field = GenericEmbeddedDocumentField(
default=lambda: EmbeddedDoc())
default=lambda: EmbeddedDoc()
)
def __eq__(self, other):
import json
return json.loads(self.to_json()) == json.loads(other.to_json())
doc = Doc()
self.assertEqual(doc, Doc.from_json(doc.to_json()))
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -8,49 +8,56 @@ __all__ = ("ValidatorErrorTest",)
class ValidatorErrorTest(unittest.TestCase):
def setUp(self):
connect(db='mongoenginetest')
connect(db="mongoenginetest")
def test_to_dict(self):
"""Ensure a ValidationError handles error to_dict correctly.
"""
error = ValidationError('root')
error = ValidationError("root")
self.assertEqual(error.to_dict(), {})
# 1st level error schema
error.errors = {'1st': ValidationError('bad 1st'), }
self.assertIn('1st', error.to_dict())
self.assertEqual(error.to_dict()['1st'], 'bad 1st')
error.errors = {"1st": ValidationError("bad 1st")}
self.assertIn("1st", error.to_dict())
self.assertEqual(error.to_dict()["1st"], "bad 1st")
# 2nd level error schema
error.errors = {'1st': ValidationError('bad 1st', errors={
'2nd': ValidationError('bad 2nd'),
})}
self.assertIn('1st', error.to_dict())
self.assertIsInstance(error.to_dict()['1st'], dict)
self.assertIn('2nd', error.to_dict()['1st'])
self.assertEqual(error.to_dict()['1st']['2nd'], 'bad 2nd')
error.errors = {
"1st": ValidationError(
"bad 1st", errors={"2nd": ValidationError("bad 2nd")}
)
}
self.assertIn("1st", error.to_dict())
self.assertIsInstance(error.to_dict()["1st"], dict)
self.assertIn("2nd", error.to_dict()["1st"])
self.assertEqual(error.to_dict()["1st"]["2nd"], "bad 2nd")
# moar levels
error.errors = {'1st': ValidationError('bad 1st', errors={
'2nd': ValidationError('bad 2nd', errors={
'3rd': ValidationError('bad 3rd', errors={
'4th': ValidationError('Inception'),
}),
}),
})}
self.assertIn('1st', error.to_dict())
self.assertIn('2nd', error.to_dict()['1st'])
self.assertIn('3rd', error.to_dict()['1st']['2nd'])
self.assertIn('4th', error.to_dict()['1st']['2nd']['3rd'])
self.assertEqual(error.to_dict()['1st']['2nd']['3rd']['4th'],
'Inception')
error.errors = {
"1st": ValidationError(
"bad 1st",
errors={
"2nd": ValidationError(
"bad 2nd",
errors={
"3rd": ValidationError(
"bad 3rd", errors={"4th": ValidationError("Inception")}
)
},
)
},
)
}
self.assertIn("1st", error.to_dict())
self.assertIn("2nd", error.to_dict()["1st"])
self.assertIn("3rd", error.to_dict()["1st"]["2nd"])
self.assertIn("4th", error.to_dict()["1st"]["2nd"]["3rd"])
self.assertEqual(error.to_dict()["1st"]["2nd"]["3rd"]["4th"], "Inception")
self.assertEqual(error.message, "root(2nd.3rd.4th.Inception: ['1st'])")
def test_model_validation(self):
class User(Document):
username = StringField(primary_key=True)
name = StringField(required=True)
@@ -59,9 +66,10 @@ class ValidatorErrorTest(unittest.TestCase):
User().validate()
except ValidationError as e:
self.assertIn("User:None", e.message)
self.assertEqual(e.to_dict(), {
'username': 'Field is required',
'name': 'Field is required'})
self.assertEqual(
e.to_dict(),
{"username": "Field is required", "name": "Field is required"},
)
user = User(username="RossC0", name="Ross").save()
user.name = None
@@ -69,14 +77,13 @@ class ValidatorErrorTest(unittest.TestCase):
user.save()
except ValidationError as e:
self.assertIn("User:RossC0", e.message)
self.assertEqual(e.to_dict(), {
'name': 'Field is required'})
self.assertEqual(e.to_dict(), {"name": "Field is required"})
def test_fields_rewrite(self):
class BasePerson(Document):
name = StringField()
age = IntField()
meta = {'abstract': True}
meta = {"abstract": True}
class Person(BasePerson):
name = StringField(required=True)
@@ -87,6 +94,7 @@ class ValidatorErrorTest(unittest.TestCase):
def test_embedded_document_validation(self):
"""Ensure that embedded documents may be validated.
"""
class Comment(EmbeddedDocument):
date = DateTimeField()
content = StringField(required=True)
@@ -94,7 +102,7 @@ class ValidatorErrorTest(unittest.TestCase):
comment = Comment()
self.assertRaises(ValidationError, comment.validate)
comment.content = 'test'
comment.content = "test"
comment.validate()
comment.date = 4
@@ -105,20 +113,20 @@ class ValidatorErrorTest(unittest.TestCase):
self.assertEqual(comment._instance, None)
def test_embedded_db_field_validate(self):
class SubDoc(EmbeddedDocument):
val = IntField(required=True)
class Doc(Document):
id = StringField(primary_key=True)
e = EmbeddedDocumentField(SubDoc, db_field='eb')
e = EmbeddedDocumentField(SubDoc, db_field="eb")
try:
Doc(id="bad").validate()
except ValidationError as e:
self.assertIn("SubDoc:None", e.message)
self.assertEqual(e.to_dict(), {
"e": {'val': 'OK could not be converted to int'}})
self.assertEqual(
e.to_dict(), {"e": {"val": "OK could not be converted to int"}}
)
Doc.drop_collection()
@@ -127,24 +135,24 @@ class ValidatorErrorTest(unittest.TestCase):
doc = Doc.objects.first()
keys = doc._data.keys()
self.assertEqual(2, len(keys))
self.assertIn('e', keys)
self.assertIn('id', keys)
self.assertIn("e", keys)
self.assertIn("id", keys)
doc.e.val = "OK"
try:
doc.save()
except ValidationError as e:
self.assertIn("Doc:test", e.message)
self.assertEqual(e.to_dict(), {
"e": {'val': 'OK could not be converted to int'}})
self.assertEqual(
e.to_dict(), {"e": {"val": "OK could not be converted to int"}}
)
def test_embedded_weakref(self):
class SubDoc(EmbeddedDocument):
val = IntField(required=True)
class Doc(Document):
e = EmbeddedDocumentField(SubDoc, db_field='eb')
e = EmbeddedDocumentField(SubDoc, db_field="eb")
Doc.drop_collection()
@@ -167,9 +175,10 @@ class ValidatorErrorTest(unittest.TestCase):
Test to ensure a ReferenceField can store a reference to a parent
class when inherited. Issue #954.
"""
class Parent(Document):
meta = {'allow_inheritance': True}
reference = ReferenceField('self')
meta = {"allow_inheritance": True}
reference = ReferenceField("self")
class Child(Parent):
pass
@@ -190,9 +199,10 @@ class ValidatorErrorTest(unittest.TestCase):
Test to ensure a ReferenceField can store a reference to a parent
class when inherited and when set via attribute. Issue #954.
"""
class Parent(Document):
meta = {'allow_inheritance': True}
reference = ReferenceField('self')
meta = {"allow_inheritance": True}
reference = ReferenceField("self")
class Child(Parent):
pass
@@ -210,5 +220,5 @@ class ValidatorErrorTest(unittest.TestCase):
self.fail("ValidationError raised: %s" % e.message)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

File diff suppressed because it is too large Load Diff

View File

@@ -14,36 +14,37 @@ from mongoengine.python_support import StringIO
try:
from PIL import Image
HAS_PIL = True
except ImportError:
HAS_PIL = False
from tests.utils import MongoDBTestCase
TEST_IMAGE_PATH = os.path.join(os.path.dirname(__file__), 'mongoengine.png')
TEST_IMAGE2_PATH = os.path.join(os.path.dirname(__file__), 'mongodb_leaf.png')
TEST_IMAGE_PATH = os.path.join(os.path.dirname(__file__), "mongoengine.png")
TEST_IMAGE2_PATH = os.path.join(os.path.dirname(__file__), "mongodb_leaf.png")
def get_file(path):
"""Use a BytesIO instead of a file to allow
to have a one-liner and avoid that the file remains opened"""
bytes_io = StringIO()
with open(path, 'rb') as f:
with open(path, "rb") as f:
bytes_io.write(f.read())
bytes_io.seek(0)
return bytes_io
class FileTest(MongoDBTestCase):
def tearDown(self):
self.db.drop_collection('fs.files')
self.db.drop_collection('fs.chunks')
self.db.drop_collection("fs.files")
self.db.drop_collection("fs.chunks")
def test_file_field_optional(self):
# Make sure FileField is optional and not required
class DemoFile(Document):
the_file = FileField()
DemoFile.objects.create()
def test_file_fields(self):
@@ -55,8 +56,8 @@ class FileTest(MongoDBTestCase):
PutFile.drop_collection()
text = six.b('Hello, World!')
content_type = 'text/plain'
text = six.b("Hello, World!")
content_type = "text/plain"
putfile = PutFile()
putfile.the_file.put(text, content_type=content_type, filename="hello")
@@ -64,7 +65,10 @@ class FileTest(MongoDBTestCase):
result = PutFile.objects.first()
self.assertEqual(putfile, result)
self.assertEqual("%s" % result.the_file, "<GridFSProxy: hello (%s)>" % result.the_file.grid_id)
self.assertEqual(
"%s" % result.the_file,
"<GridFSProxy: hello (%s)>" % result.the_file.grid_id,
)
self.assertEqual(result.the_file.read(), text)
self.assertEqual(result.the_file.content_type, content_type)
result.the_file.delete() # Remove file from GridFS
@@ -89,14 +93,15 @@ class FileTest(MongoDBTestCase):
def test_file_fields_stream(self):
"""Ensure that file fields can be written to and their data retrieved
"""
class StreamFile(Document):
the_file = FileField()
StreamFile.drop_collection()
text = six.b('Hello, World!')
more_text = six.b('Foo Bar')
content_type = 'text/plain'
text = six.b("Hello, World!")
more_text = six.b("Foo Bar")
content_type = "text/plain"
streamfile = StreamFile()
streamfile.the_file.new_file(content_type=content_type)
@@ -124,14 +129,15 @@ class FileTest(MongoDBTestCase):
"""Ensure that a file field can be written to after it has been saved as
None
"""
class StreamFile(Document):
the_file = FileField()
StreamFile.drop_collection()
text = six.b('Hello, World!')
more_text = six.b('Foo Bar')
content_type = 'text/plain'
text = six.b("Hello, World!")
more_text = six.b("Foo Bar")
content_type = "text/plain"
streamfile = StreamFile()
streamfile.save()
@@ -157,12 +163,11 @@ class FileTest(MongoDBTestCase):
self.assertTrue(result.the_file.read() is None)
def test_file_fields_set(self):
class SetFile(Document):
the_file = FileField()
text = six.b('Hello, World!')
more_text = six.b('Foo Bar')
text = six.b("Hello, World!")
more_text = six.b("Foo Bar")
SetFile.drop_collection()
@@ -184,7 +189,6 @@ class FileTest(MongoDBTestCase):
result.the_file.delete()
def test_file_field_no_default(self):
class GridDocument(Document):
the_file = FileField()
@@ -199,7 +203,7 @@ class FileTest(MongoDBTestCase):
doc_a.save()
doc_b = GridDocument.objects.with_id(doc_a.id)
doc_b.the_file.replace(f, filename='doc_b')
doc_b.the_file.replace(f, filename="doc_b")
doc_b.save()
self.assertNotEqual(doc_b.the_file.grid_id, None)
@@ -208,13 +212,13 @@ class FileTest(MongoDBTestCase):
self.assertEqual(doc_b.the_file.grid_id, doc_c.the_file.grid_id)
# Test with default
doc_d = GridDocument(the_file=six.b(''))
doc_d = GridDocument(the_file=six.b(""))
doc_d.save()
doc_e = GridDocument.objects.with_id(doc_d.id)
self.assertEqual(doc_d.the_file.grid_id, doc_e.the_file.grid_id)
doc_e.the_file.replace(f, filename='doc_e')
doc_e.the_file.replace(f, filename="doc_e")
doc_e.save()
doc_f = GridDocument.objects.with_id(doc_e.id)
@@ -222,11 +226,12 @@ class FileTest(MongoDBTestCase):
db = GridDocument._get_db()
grid_fs = gridfs.GridFS(db)
self.assertEqual(['doc_b', 'doc_e'], grid_fs.list())
self.assertEqual(["doc_b", "doc_e"], grid_fs.list())
def test_file_uniqueness(self):
"""Ensure that each instance of a FileField is unique
"""
class TestFile(Document):
name = StringField()
the_file = FileField()
@@ -234,7 +239,7 @@ class FileTest(MongoDBTestCase):
# First instance
test_file = TestFile()
test_file.name = "Hello, World!"
test_file.the_file.put(six.b('Hello, World!'))
test_file.the_file.put(six.b("Hello, World!"))
test_file.save()
# Second instance
@@ -255,20 +260,21 @@ class FileTest(MongoDBTestCase):
photo = FileField()
Animal.drop_collection()
marmot = Animal(genus='Marmota', family='Sciuridae')
marmot = Animal(genus="Marmota", family="Sciuridae")
marmot_photo_content = get_file(TEST_IMAGE_PATH) # Retrieve a photo from disk
marmot.photo.put(marmot_photo_content, content_type='image/jpeg', foo='bar')
marmot.photo.put(marmot_photo_content, content_type="image/jpeg", foo="bar")
marmot.photo.close()
marmot.save()
marmot = Animal.objects.get()
self.assertEqual(marmot.photo.content_type, 'image/jpeg')
self.assertEqual(marmot.photo.foo, 'bar')
self.assertEqual(marmot.photo.content_type, "image/jpeg")
self.assertEqual(marmot.photo.foo, "bar")
def test_file_reassigning(self):
class TestFile(Document):
the_file = FileField()
TestFile.drop_collection()
test_file = TestFile(the_file=get_file(TEST_IMAGE_PATH)).save()
@@ -282,13 +288,15 @@ class FileTest(MongoDBTestCase):
def test_file_boolean(self):
"""Ensure that a boolean test of a FileField indicates its presence
"""
class TestFile(Document):
the_file = FileField()
TestFile.drop_collection()
test_file = TestFile()
self.assertFalse(bool(test_file.the_file))
test_file.the_file.put(six.b('Hello, World!'), content_type='text/plain')
test_file.the_file.put(six.b("Hello, World!"), content_type="text/plain")
test_file.save()
self.assertTrue(bool(test_file.the_file))
@@ -297,6 +305,7 @@ class FileTest(MongoDBTestCase):
def test_file_cmp(self):
"""Test comparing against other types"""
class TestFile(Document):
the_file = FileField()
@@ -305,11 +314,12 @@ class FileTest(MongoDBTestCase):
def test_file_disk_space(self):
""" Test disk space usage when we delete/replace a file """
class TestFile(Document):
the_file = FileField()
text = six.b('Hello, World!')
content_type = 'text/plain'
text = six.b("Hello, World!")
content_type = "text/plain"
testfile = TestFile()
testfile.the_file.put(text, content_type=content_type, filename="hello")
@@ -352,7 +362,7 @@ class FileTest(MongoDBTestCase):
testfile.the_file.put(text, content_type=content_type, filename="hello")
testfile.save()
text = six.b('Bonjour, World!')
text = six.b("Bonjour, World!")
testfile.the_file.replace(text, content_type=content_type, filename="hello")
testfile.save()
@@ -370,7 +380,7 @@ class FileTest(MongoDBTestCase):
def test_image_field(self):
if not HAS_PIL:
raise SkipTest('PIL not installed')
raise SkipTest("PIL not installed")
class TestImage(Document):
image = ImageField()
@@ -386,7 +396,9 @@ class FileTest(MongoDBTestCase):
t.image.put(f)
self.fail("Should have raised an invalidation error")
except ValidationError as e:
self.assertEqual("%s" % e, "Invalid image: cannot identify image file %s" % f)
self.assertEqual(
"%s" % e, "Invalid image: cannot identify image file %s" % f
)
t = TestImage()
t.image.put(get_file(TEST_IMAGE_PATH))
@@ -394,7 +406,7 @@ class FileTest(MongoDBTestCase):
t = TestImage.objects.first()
self.assertEqual(t.image.format, 'PNG')
self.assertEqual(t.image.format, "PNG")
w, h = t.image.size
self.assertEqual(w, 371)
@@ -404,10 +416,11 @@ class FileTest(MongoDBTestCase):
def test_image_field_reassigning(self):
if not HAS_PIL:
raise SkipTest('PIL not installed')
raise SkipTest("PIL not installed")
class TestFile(Document):
the_file = ImageField()
TestFile.drop_collection()
test_file = TestFile(the_file=get_file(TEST_IMAGE_PATH)).save()
@@ -420,7 +433,7 @@ class FileTest(MongoDBTestCase):
def test_image_field_resize(self):
if not HAS_PIL:
raise SkipTest('PIL not installed')
raise SkipTest("PIL not installed")
class TestImage(Document):
image = ImageField(size=(185, 37))
@@ -433,7 +446,7 @@ class FileTest(MongoDBTestCase):
t = TestImage.objects.first()
self.assertEqual(t.image.format, 'PNG')
self.assertEqual(t.image.format, "PNG")
w, h = t.image.size
self.assertEqual(w, 185)
@@ -443,7 +456,7 @@ class FileTest(MongoDBTestCase):
def test_image_field_resize_force(self):
if not HAS_PIL:
raise SkipTest('PIL not installed')
raise SkipTest("PIL not installed")
class TestImage(Document):
image = ImageField(size=(185, 37, True))
@@ -456,7 +469,7 @@ class FileTest(MongoDBTestCase):
t = TestImage.objects.first()
self.assertEqual(t.image.format, 'PNG')
self.assertEqual(t.image.format, "PNG")
w, h = t.image.size
self.assertEqual(w, 185)
@@ -466,7 +479,7 @@ class FileTest(MongoDBTestCase):
def test_image_field_thumbnail(self):
if not HAS_PIL:
raise SkipTest('PIL not installed')
raise SkipTest("PIL not installed")
class TestImage(Document):
image = ImageField(thumbnail_size=(92, 18))
@@ -479,19 +492,18 @@ class FileTest(MongoDBTestCase):
t = TestImage.objects.first()
self.assertEqual(t.image.thumbnail.format, 'PNG')
self.assertEqual(t.image.thumbnail.format, "PNG")
self.assertEqual(t.image.thumbnail.width, 92)
self.assertEqual(t.image.thumbnail.height, 18)
t.image.delete()
def test_file_multidb(self):
register_connection('test_files', 'test_files')
register_connection("test_files", "test_files")
class TestFile(Document):
name = StringField()
the_file = FileField(db_alias="test_files",
collection_name="macumba")
the_file = FileField(db_alias="test_files", collection_name="macumba")
TestFile.drop_collection()
@@ -502,23 +514,21 @@ class FileTest(MongoDBTestCase):
# First instance
test_file = TestFile()
test_file.name = "Hello, World!"
test_file.the_file.put(six.b('Hello, World!'),
name="hello.txt")
test_file.the_file.put(six.b("Hello, World!"), name="hello.txt")
test_file.save()
data = get_db("test_files").macumba.files.find_one()
self.assertEqual(data.get('name'), 'hello.txt')
self.assertEqual(data.get("name"), "hello.txt")
test_file = TestFile.objects.first()
self.assertEqual(test_file.the_file.read(), six.b('Hello, World!'))
self.assertEqual(test_file.the_file.read(), six.b("Hello, World!"))
test_file = TestFile.objects.first()
test_file.the_file = six.b('HELLO, WORLD!')
test_file.the_file = six.b("HELLO, WORLD!")
test_file.save()
test_file = TestFile.objects.first()
self.assertEqual(test_file.the_file.read(),
six.b('HELLO, WORLD!'))
self.assertEqual(test_file.the_file.read(), six.b("HELLO, WORLD!"))
def test_copyable(self):
class PutFile(Document):
@@ -526,8 +536,8 @@ class FileTest(MongoDBTestCase):
PutFile.drop_collection()
text = six.b('Hello, World!')
content_type = 'text/plain'
text = six.b("Hello, World!")
content_type = "text/plain"
putfile = PutFile()
putfile.the_file.put(text, content_type=content_type)
@@ -542,7 +552,7 @@ class FileTest(MongoDBTestCase):
def test_get_image_by_grid_id(self):
if not HAS_PIL:
raise SkipTest('PIL not installed')
raise SkipTest("PIL not installed")
class TestImage(Document):
@@ -559,8 +569,9 @@ class FileTest(MongoDBTestCase):
test = TestImage.objects.first()
grid_id = test.image1.grid_id
self.assertEqual(1, TestImage.objects(Q(image1=grid_id)
or Q(image2=grid_id)).count())
self.assertEqual(
1, TestImage.objects(Q(image1=grid_id) or Q(image2=grid_id)).count()
)
def test_complex_field_filefield(self):
"""Ensure you can add meta data to file"""
@@ -571,21 +582,21 @@ class FileTest(MongoDBTestCase):
photos = ListField(FileField())
Animal.drop_collection()
marmot = Animal(genus='Marmota', family='Sciuridae')
marmot = Animal(genus="Marmota", family="Sciuridae")
with open(TEST_IMAGE_PATH, 'rb') as marmot_photo: # Retrieve a photo from disk
photos_field = marmot._fields['photos'].field
new_proxy = photos_field.get_proxy_obj('photos', marmot)
new_proxy.put(marmot_photo, content_type='image/jpeg', foo='bar')
with open(TEST_IMAGE_PATH, "rb") as marmot_photo: # Retrieve a photo from disk
photos_field = marmot._fields["photos"].field
new_proxy = photos_field.get_proxy_obj("photos", marmot)
new_proxy.put(marmot_photo, content_type="image/jpeg", foo="bar")
marmot.photos.append(new_proxy)
marmot.save()
marmot = Animal.objects.get()
self.assertEqual(marmot.photos[0].content_type, 'image/jpeg')
self.assertEqual(marmot.photos[0].foo, 'bar')
self.assertEqual(marmot.photos[0].content_type, "image/jpeg")
self.assertEqual(marmot.photos[0].foo, "bar")
self.assertEqual(marmot.photos[0].get().length, 8313)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -4,28 +4,27 @@ import unittest
from mongoengine import *
from mongoengine.connection import get_db
__all__ = ("GeoFieldTest", )
__all__ = ("GeoFieldTest",)
class GeoFieldTest(unittest.TestCase):
def setUp(self):
connect(db='mongoenginetest')
connect(db="mongoenginetest")
self.db = get_db()
def _test_for_expected_error(self, Cls, loc, expected):
try:
Cls(loc=loc).validate()
self.fail('Should not validate the location {0}'.format(loc))
self.fail("Should not validate the location {0}".format(loc))
except ValidationError as e:
self.assertEqual(expected, e.to_dict()['loc'])
self.assertEqual(expected, e.to_dict()["loc"])
def test_geopoint_validation(self):
class Location(Document):
loc = GeoPointField()
invalid_coords = [{"x": 1, "y": 2}, 5, "a"]
expected = 'GeoPointField can only accept tuples or lists of (x, y)'
expected = "GeoPointField can only accept tuples or lists of (x, y)"
for coord in invalid_coords:
self._test_for_expected_error(Location, coord, expected)
@@ -40,7 +39,7 @@ class GeoFieldTest(unittest.TestCase):
expected = "Both values (%s) in point must be float or int" % repr(coord)
self._test_for_expected_error(Location, coord, expected)
invalid_coords = [21, 4, 'a']
invalid_coords = [21, 4, "a"]
for coord in invalid_coords:
expected = "GeoPointField can only accept tuples or lists of (x, y)"
self._test_for_expected_error(Location, coord, expected)
@@ -50,7 +49,9 @@ class GeoFieldTest(unittest.TestCase):
loc = PointField()
invalid_coords = {"x": 1, "y": 2}
expected = 'PointField can only accept a valid GeoJson dictionary or lists of (x, y)'
expected = (
"PointField can only accept a valid GeoJson dictionary or lists of (x, y)"
)
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = {"type": "MadeUp", "coordinates": []}
@@ -77,19 +78,16 @@ class GeoFieldTest(unittest.TestCase):
self._test_for_expected_error(Location, coord, expected)
Location(loc=[1, 2]).validate()
Location(loc={
"type": "Point",
"coordinates": [
81.4471435546875,
23.61432859499169
]}).validate()
Location(
loc={"type": "Point", "coordinates": [81.4471435546875, 23.61432859499169]}
).validate()
def test_linestring_validation(self):
class Location(Document):
loc = LineStringField()
invalid_coords = {"x": 1, "y": 2}
expected = 'LineStringField can only accept a valid GeoJson dictionary or lists of (x, y)'
expected = "LineStringField can only accept a valid GeoJson dictionary or lists of (x, y)"
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = {"type": "MadeUp", "coordinates": [[]]}
@@ -97,7 +95,9 @@ class GeoFieldTest(unittest.TestCase):
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = {"type": "LineString", "coordinates": [[1, 2, 3]]}
expected = "Invalid LineString:\nValue ([1, 2, 3]) must be a two-dimensional point"
expected = (
"Invalid LineString:\nValue ([1, 2, 3]) must be a two-dimensional point"
)
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = [5, "a"]
@@ -105,16 +105,25 @@ class GeoFieldTest(unittest.TestCase):
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = [[1]]
expected = "Invalid LineString:\nValue (%s) must be a two-dimensional point" % repr(invalid_coords[0])
expected = (
"Invalid LineString:\nValue (%s) must be a two-dimensional point"
% repr(invalid_coords[0])
)
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = [[1, 2, 3]]
expected = "Invalid LineString:\nValue (%s) must be a two-dimensional point" % repr(invalid_coords[0])
expected = (
"Invalid LineString:\nValue (%s) must be a two-dimensional point"
% repr(invalid_coords[0])
)
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = [[[{}, {}]], [("a", "b")]]
for coord in invalid_coords:
expected = "Invalid LineString:\nBoth values (%s) in point must be float or int" % repr(coord[0])
expected = (
"Invalid LineString:\nBoth values (%s) in point must be float or int"
% repr(coord[0])
)
self._test_for_expected_error(Location, coord, expected)
Location(loc=[[1, 2], [3, 4], [5, 6], [1, 2]]).validate()
@@ -124,7 +133,9 @@ class GeoFieldTest(unittest.TestCase):
loc = PolygonField()
invalid_coords = {"x": 1, "y": 2}
expected = 'PolygonField can only accept a valid GeoJson dictionary or lists of (x, y)'
expected = (
"PolygonField can only accept a valid GeoJson dictionary or lists of (x, y)"
)
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = {"type": "MadeUp", "coordinates": [[]]}
@@ -136,7 +147,9 @@ class GeoFieldTest(unittest.TestCase):
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = [[[5, "a"]]]
expected = "Invalid Polygon:\nBoth values ([5, 'a']) in point must be float or int"
expected = (
"Invalid Polygon:\nBoth values ([5, 'a']) in point must be float or int"
)
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = [[[]]]
@@ -162,7 +175,7 @@ class GeoFieldTest(unittest.TestCase):
loc = MultiPointField()
invalid_coords = {"x": 1, "y": 2}
expected = 'MultiPointField can only accept a valid GeoJson dictionary or lists of (x, y)'
expected = "MultiPointField can only accept a valid GeoJson dictionary or lists of (x, y)"
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = {"type": "MadeUp", "coordinates": [[]]}
@@ -188,19 +201,19 @@ class GeoFieldTest(unittest.TestCase):
self._test_for_expected_error(Location, coord, expected)
Location(loc=[[1, 2]]).validate()
Location(loc={
"type": "MultiPoint",
"coordinates": [
[1, 2],
[81.4471435546875, 23.61432859499169]
]}).validate()
Location(
loc={
"type": "MultiPoint",
"coordinates": [[1, 2], [81.4471435546875, 23.61432859499169]],
}
).validate()
def test_multilinestring_validation(self):
class Location(Document):
loc = MultiLineStringField()
invalid_coords = {"x": 1, "y": 2}
expected = 'MultiLineStringField can only accept a valid GeoJson dictionary or lists of (x, y)'
expected = "MultiLineStringField can only accept a valid GeoJson dictionary or lists of (x, y)"
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = {"type": "MadeUp", "coordinates": [[]]}
@@ -216,16 +229,25 @@ class GeoFieldTest(unittest.TestCase):
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = [[[1]]]
expected = "Invalid MultiLineString:\nValue (%s) must be a two-dimensional point" % repr(invalid_coords[0][0])
expected = (
"Invalid MultiLineString:\nValue (%s) must be a two-dimensional point"
% repr(invalid_coords[0][0])
)
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = [[[1, 2, 3]]]
expected = "Invalid MultiLineString:\nValue (%s) must be a two-dimensional point" % repr(invalid_coords[0][0])
expected = (
"Invalid MultiLineString:\nValue (%s) must be a two-dimensional point"
% repr(invalid_coords[0][0])
)
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = [[[[{}, {}]]], [[("a", "b")]]]
for coord in invalid_coords:
expected = "Invalid MultiLineString:\nBoth values (%s) in point must be float or int" % repr(coord[0][0])
expected = (
"Invalid MultiLineString:\nBoth values (%s) in point must be float or int"
% repr(coord[0][0])
)
self._test_for_expected_error(Location, coord, expected)
Location(loc=[[[1, 2], [3, 4], [5, 6], [1, 2]]]).validate()
@@ -235,7 +257,7 @@ class GeoFieldTest(unittest.TestCase):
loc = MultiPolygonField()
invalid_coords = {"x": 1, "y": 2}
expected = 'MultiPolygonField can only accept a valid GeoJson dictionary or lists of (x, y)'
expected = "MultiPolygonField can only accept a valid GeoJson dictionary or lists of (x, y)"
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = {"type": "MadeUp", "coordinates": [[]]}
@@ -243,7 +265,9 @@ class GeoFieldTest(unittest.TestCase):
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = {"type": "MultiPolygon", "coordinates": [[[[1, 2, 3]]]]}
expected = "Invalid MultiPolygon:\nValue ([1, 2, 3]) must be a two-dimensional point"
expected = (
"Invalid MultiPolygon:\nValue ([1, 2, 3]) must be a two-dimensional point"
)
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = [[[[5, "a"]]]]
@@ -255,7 +279,9 @@ class GeoFieldTest(unittest.TestCase):
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = [[[[1, 2, 3]]]]
expected = "Invalid MultiPolygon:\nValue ([1, 2, 3]) must be a two-dimensional point"
expected = (
"Invalid MultiPolygon:\nValue ([1, 2, 3]) must be a two-dimensional point"
)
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = [[[[{}, {}]]], [[("a", "b")]]]
@@ -263,7 +289,9 @@ class GeoFieldTest(unittest.TestCase):
self._test_for_expected_error(Location, invalid_coords, expected)
invalid_coords = [[[[1, 2], [3, 4]]]]
expected = "Invalid MultiPolygon:\nLineStrings must start and end at the same point"
expected = (
"Invalid MultiPolygon:\nLineStrings must start and end at the same point"
)
self._test_for_expected_error(Location, invalid_coords, expected)
Location(loc=[[[[1, 2], [3, 4], [5, 6], [1, 2]]]]).validate()
@@ -271,17 +299,19 @@ class GeoFieldTest(unittest.TestCase):
def test_indexes_geopoint(self):
"""Ensure that indexes are created automatically for GeoPointFields.
"""
class Event(Document):
title = StringField()
location = GeoPointField()
geo_indicies = Event._geo_indices()
self.assertEqual(geo_indicies, [{'fields': [('location', '2d')]}])
self.assertEqual(geo_indicies, [{"fields": [("location", "2d")]}])
def test_geopoint_embedded_indexes(self):
"""Ensure that indexes are created automatically for GeoPointFields on
embedded documents.
"""
class Venue(EmbeddedDocument):
location = GeoPointField()
name = StringField()
@@ -291,11 +321,12 @@ class GeoFieldTest(unittest.TestCase):
venue = EmbeddedDocumentField(Venue)
geo_indicies = Event._geo_indices()
self.assertEqual(geo_indicies, [{'fields': [('venue.location', '2d')]}])
self.assertEqual(geo_indicies, [{"fields": [("venue.location", "2d")]}])
def test_indexes_2dsphere(self):
"""Ensure that indexes are created automatically for GeoPointFields.
"""
class Event(Document):
title = StringField()
point = PointField()
@@ -303,13 +334,14 @@ class GeoFieldTest(unittest.TestCase):
polygon = PolygonField()
geo_indicies = Event._geo_indices()
self.assertIn({'fields': [('line', '2dsphere')]}, geo_indicies)
self.assertIn({'fields': [('polygon', '2dsphere')]}, geo_indicies)
self.assertIn({'fields': [('point', '2dsphere')]}, geo_indicies)
self.assertIn({"fields": [("line", "2dsphere")]}, geo_indicies)
self.assertIn({"fields": [("polygon", "2dsphere")]}, geo_indicies)
self.assertIn({"fields": [("point", "2dsphere")]}, geo_indicies)
def test_indexes_2dsphere_embedded(self):
"""Ensure that indexes are created automatically for GeoPointFields.
"""
class Venue(EmbeddedDocument):
name = StringField()
point = PointField()
@@ -321,12 +353,11 @@ class GeoFieldTest(unittest.TestCase):
venue = EmbeddedDocumentField(Venue)
geo_indicies = Event._geo_indices()
self.assertIn({'fields': [('venue.line', '2dsphere')]}, geo_indicies)
self.assertIn({'fields': [('venue.polygon', '2dsphere')]}, geo_indicies)
self.assertIn({'fields': [('venue.point', '2dsphere')]}, geo_indicies)
self.assertIn({"fields": [("venue.line", "2dsphere")]}, geo_indicies)
self.assertIn({"fields": [("venue.polygon", "2dsphere")]}, geo_indicies)
self.assertIn({"fields": [("venue.point", "2dsphere")]}, geo_indicies)
def test_geo_indexes_recursion(self):
class Location(Document):
name = StringField()
location = GeoPointField()
@@ -338,11 +369,11 @@ class GeoFieldTest(unittest.TestCase):
Location.drop_collection()
Parent.drop_collection()
Parent(name='Berlin').save()
Parent(name="Berlin").save()
info = Parent._get_collection().index_information()
self.assertNotIn('location_2d', info)
self.assertNotIn("location_2d", info)
info = Location._get_collection().index_information()
self.assertIn('location_2d', info)
self.assertIn("location_2d", info)
self.assertEqual(len(Parent._geo_indices()), 0)
self.assertEqual(len(Location._geo_indices()), 1)
@@ -354,9 +385,7 @@ class GeoFieldTest(unittest.TestCase):
location = PointField(auto_index=False)
datetime = DateTimeField()
meta = {
'indexes': [[("location", "2dsphere"), ("datetime", 1)]]
}
meta = {"indexes": [[("location", "2dsphere"), ("datetime", 1)]]}
self.assertEqual([], Log._geo_indices())
@@ -364,8 +393,10 @@ class GeoFieldTest(unittest.TestCase):
Log.ensure_indexes()
info = Log._get_collection().index_information()
self.assertEqual(info["location_2dsphere_datetime_1"]["key"],
[('location', '2dsphere'), ('datetime', 1)])
self.assertEqual(
info["location_2dsphere_datetime_1"]["key"],
[("location", "2dsphere"), ("datetime", 1)],
)
# Test listing explicitly
class Log(Document):
@@ -373,9 +404,7 @@ class GeoFieldTest(unittest.TestCase):
datetime = DateTimeField()
meta = {
'indexes': [
{'fields': [("location", "2dsphere"), ("datetime", 1)]}
]
"indexes": [{"fields": [("location", "2dsphere"), ("datetime", 1)]}]
}
self.assertEqual([], Log._geo_indices())
@@ -384,9 +413,11 @@ class GeoFieldTest(unittest.TestCase):
Log.ensure_indexes()
info = Log._get_collection().index_information()
self.assertEqual(info["location_2dsphere_datetime_1"]["key"],
[('location', '2dsphere'), ('datetime', 1)])
self.assertEqual(
info["location_2dsphere_datetime_1"]["key"],
[("location", "2dsphere"), ("datetime", 1)],
)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -9,19 +9,22 @@ from bson import Binary
from mongoengine import *
from tests.utils import MongoDBTestCase
BIN_VALUE = six.b('\xa9\xf3\x8d(\xd7\x03\x84\xb4k[\x0f\xe3\xa2\x19\x85p[J\xa3\xd2>\xde\xe6\x87\xb1\x7f\xc6\xe6\xd9r\x18\xf5')
BIN_VALUE = six.b(
"\xa9\xf3\x8d(\xd7\x03\x84\xb4k[\x0f\xe3\xa2\x19\x85p[J\xa3\xd2>\xde\xe6\x87\xb1\x7f\xc6\xe6\xd9r\x18\xf5"
)
class TestBinaryField(MongoDBTestCase):
def test_binary_fields(self):
"""Ensure that binary fields can be stored and retrieved.
"""
class Attachment(Document):
content_type = StringField()
blob = BinaryField()
BLOB = six.b('\xe6\x00\xc4\xff\x07')
MIME_TYPE = 'application/octet-stream'
BLOB = six.b("\xe6\x00\xc4\xff\x07")
MIME_TYPE = "application/octet-stream"
Attachment.drop_collection()
@@ -35,6 +38,7 @@ class TestBinaryField(MongoDBTestCase):
def test_validation_succeeds(self):
"""Ensure that valid values can be assigned to binary fields.
"""
class AttachmentRequired(Document):
blob = BinaryField(required=True)
@@ -43,11 +47,11 @@ class TestBinaryField(MongoDBTestCase):
attachment_required = AttachmentRequired()
self.assertRaises(ValidationError, attachment_required.validate)
attachment_required.blob = Binary(six.b('\xe6\x00\xc4\xff\x07'))
attachment_required.blob = Binary(six.b("\xe6\x00\xc4\xff\x07"))
attachment_required.validate()
_5_BYTES = six.b('\xe6\x00\xc4\xff\x07')
_4_BYTES = six.b('\xe6\x00\xc4\xff')
_5_BYTES = six.b("\xe6\x00\xc4\xff\x07")
_4_BYTES = six.b("\xe6\x00\xc4\xff")
self.assertRaises(ValidationError, AttachmentSizeLimit(blob=_5_BYTES).validate)
AttachmentSizeLimit(blob=_4_BYTES).validate()
@@ -57,7 +61,7 @@ class TestBinaryField(MongoDBTestCase):
class Attachment(Document):
blob = BinaryField()
for invalid_data in (2, u'Im_a_unicode', ['some_str']):
for invalid_data in (2, u"Im_a_unicode", ["some_str"]):
self.assertRaises(ValidationError, Attachment(blob=invalid_data).validate)
def test__primary(self):
@@ -108,17 +112,17 @@ class TestBinaryField(MongoDBTestCase):
def test_modify_operation__set(self):
"""Ensures no regression of bug #1127"""
class MyDocument(Document):
some_field = StringField()
bin_field = BinaryField()
MyDocument.drop_collection()
doc = MyDocument.objects(some_field='test').modify(
upsert=True, new=True,
set__bin_field=BIN_VALUE
doc = MyDocument.objects(some_field="test").modify(
upsert=True, new=True, set__bin_field=BIN_VALUE
)
self.assertEqual(doc.some_field, 'test')
self.assertEqual(doc.some_field, "test")
if six.PY3:
self.assertEqual(doc.bin_field, BIN_VALUE)
else:
@@ -126,15 +130,18 @@ class TestBinaryField(MongoDBTestCase):
def test_update_one(self):
"""Ensures no regression of bug #1127"""
class MyDocument(Document):
bin_field = BinaryField()
MyDocument.drop_collection()
bin_data = six.b('\xe6\x00\xc4\xff\x07')
bin_data = six.b("\xe6\x00\xc4\xff\x07")
doc = MyDocument(bin_field=bin_data).save()
n_updated = MyDocument.objects(bin_field=bin_data).update_one(bin_field=BIN_VALUE)
n_updated = MyDocument.objects(bin_field=bin_data).update_one(
bin_field=BIN_VALUE
)
self.assertEqual(n_updated, 1)
fetched = MyDocument.objects.with_id(doc.id)
if six.PY3:

View File

@@ -11,15 +11,13 @@ class TestBooleanField(MongoDBTestCase):
person = Person(admin=True)
person.save()
self.assertEqual(
get_as_pymongo(person),
{'_id': person.id,
'admin': True})
self.assertEqual(get_as_pymongo(person), {"_id": person.id, "admin": True})
def test_validation(self):
"""Ensure that invalid values cannot be assigned to boolean
fields.
"""
class Person(Document):
admin = BooleanField()
@@ -29,9 +27,9 @@ class TestBooleanField(MongoDBTestCase):
person.admin = 2
self.assertRaises(ValidationError, person.validate)
person.admin = 'Yes'
person.admin = "Yes"
self.assertRaises(ValidationError, person.validate)
person.admin = 'False'
person.admin = "False"
self.assertRaises(ValidationError, person.validate)
def test_weirdness_constructor(self):
@@ -39,11 +37,12 @@ class TestBooleanField(MongoDBTestCase):
which causes some weird behavior. We dont necessarily want to maintain this behavior
but its a known issue
"""
class Person(Document):
admin = BooleanField()
new_person = Person(admin='False')
new_person = Person(admin="False")
self.assertTrue(new_person.admin)
new_person = Person(admin='0')
new_person = Person(admin="0")
self.assertTrue(new_person.admin)

View File

@@ -7,12 +7,12 @@ from tests.utils import MongoDBTestCase
class TestCachedReferenceField(MongoDBTestCase):
def test_get_and_save(self):
"""
Tests #1047: CachedReferenceField creates DBRefs on to_python,
but can't save them on to_mongo.
"""
class Animal(Document):
name = StringField()
tag = StringField()
@@ -24,10 +24,11 @@ class TestCachedReferenceField(MongoDBTestCase):
Animal.drop_collection()
Ocorrence.drop_collection()
Ocorrence(person="testte",
animal=Animal(name="Leopard", tag="heavy").save()).save()
Ocorrence(
person="testte", animal=Animal(name="Leopard", tag="heavy").save()
).save()
p = Ocorrence.objects.get()
p.person = 'new_testte'
p.person = "new_testte"
p.save()
def test_general_things(self):
@@ -37,8 +38,7 @@ class TestCachedReferenceField(MongoDBTestCase):
class Ocorrence(Document):
person = StringField()
animal = CachedReferenceField(
Animal, fields=['tag'])
animal = CachedReferenceField(Animal, fields=["tag"])
Animal.drop_collection()
Ocorrence.drop_collection()
@@ -55,19 +55,18 @@ class TestCachedReferenceField(MongoDBTestCase):
self.assertEqual(Ocorrence.objects(animal=None).count(), 1)
self.assertEqual(
a.to_mongo(fields=['tag']), {'tag': 'heavy', "_id": a.pk})
self.assertEqual(a.to_mongo(fields=["tag"]), {"tag": "heavy", "_id": a.pk})
self.assertEqual(o.to_mongo()['animal']['tag'], 'heavy')
self.assertEqual(o.to_mongo()["animal"]["tag"], "heavy")
# counts
Ocorrence(person="teste 2").save()
Ocorrence(person="teste 3").save()
count = Ocorrence.objects(animal__tag='heavy').count()
count = Ocorrence.objects(animal__tag="heavy").count()
self.assertEqual(count, 1)
ocorrence = Ocorrence.objects(animal__tag='heavy').first()
ocorrence = Ocorrence.objects(animal__tag="heavy").first()
self.assertEqual(ocorrence.person, "teste")
self.assertIsInstance(ocorrence.animal, Animal)
@@ -78,28 +77,21 @@ class TestCachedReferenceField(MongoDBTestCase):
class SocialTest(Document):
group = StringField()
person = CachedReferenceField(
PersonAuto,
fields=('salary',))
person = CachedReferenceField(PersonAuto, fields=("salary",))
PersonAuto.drop_collection()
SocialTest.drop_collection()
p = PersonAuto(name="Alberto", salary=Decimal('7000.00'))
p = PersonAuto(name="Alberto", salary=Decimal("7000.00"))
p.save()
s = SocialTest(group="dev", person=p)
s.save()
self.assertEqual(
SocialTest.objects._collection.find_one({'person.salary': 7000.00}), {
'_id': s.pk,
'group': s.group,
'person': {
'_id': p.pk,
'salary': 7000.00
}
})
SocialTest.objects._collection.find_one({"person.salary": 7000.00}),
{"_id": s.pk, "group": s.group, "person": {"_id": p.pk, "salary": 7000.00}},
)
def test_cached_reference_field_reference(self):
class Group(Document):
@@ -111,17 +103,14 @@ class TestCachedReferenceField(MongoDBTestCase):
class SocialData(Document):
obs = StringField()
tags = ListField(
StringField())
person = CachedReferenceField(
Person,
fields=('group',))
tags = ListField(StringField())
person = CachedReferenceField(Person, fields=("group",))
Group.drop_collection()
Person.drop_collection()
SocialData.drop_collection()
g1 = Group(name='dev')
g1 = Group(name="dev")
g1.save()
g2 = Group(name="designers")
@@ -136,22 +125,21 @@ class TestCachedReferenceField(MongoDBTestCase):
p3 = Person(name="Afro design", group=g2)
p3.save()
s1 = SocialData(obs="testing 123", person=p1, tags=['tag1', 'tag2'])
s1 = SocialData(obs="testing 123", person=p1, tags=["tag1", "tag2"])
s1.save()
s2 = SocialData(obs="testing 321", person=p3, tags=['tag3', 'tag4'])
s2 = SocialData(obs="testing 321", person=p3, tags=["tag3", "tag4"])
s2.save()
self.assertEqual(SocialData.objects._collection.find_one(
{'tags': 'tag2'}), {
'_id': s1.pk,
'obs': 'testing 123',
'tags': ['tag1', 'tag2'],
'person': {
'_id': p1.pk,
'group': g1.pk
}
})
self.assertEqual(
SocialData.objects._collection.find_one({"tags": "tag2"}),
{
"_id": s1.pk,
"obs": "testing 123",
"tags": ["tag1", "tag2"],
"person": {"_id": p1.pk, "group": g1.pk},
},
)
self.assertEqual(SocialData.objects(person__group=g2).count(), 1)
self.assertEqual(SocialData.objects(person__group=g2).first(), s2)
@@ -163,23 +151,18 @@ class TestCachedReferenceField(MongoDBTestCase):
Product.drop_collection()
class Basket(Document):
products = ListField(CachedReferenceField(Product, fields=['name']))
products = ListField(CachedReferenceField(Product, fields=["name"]))
Basket.drop_collection()
product1 = Product(name='abc').save()
product2 = Product(name='def').save()
product1 = Product(name="abc").save()
product2 = Product(name="def").save()
basket = Basket(products=[product1]).save()
self.assertEqual(
Basket.objects._collection.find_one(),
{
'_id': basket.pk,
'products': [
{
'_id': product1.pk,
'name': product1.name
}
]
}
"_id": basket.pk,
"products": [{"_id": product1.pk, "name": product1.name}],
},
)
# push to list
basket.update(push__products=product2)
@@ -187,161 +170,135 @@ class TestCachedReferenceField(MongoDBTestCase):
self.assertEqual(
Basket.objects._collection.find_one(),
{
'_id': basket.pk,
'products': [
{
'_id': product1.pk,
'name': product1.name
},
{
'_id': product2.pk,
'name': product2.name
}
]
}
"_id": basket.pk,
"products": [
{"_id": product1.pk, "name": product1.name},
{"_id": product2.pk, "name": product2.name},
],
},
)
def test_cached_reference_field_update_all(self):
class Person(Document):
TYPES = (
('pf', "PF"),
('pj', "PJ")
)
TYPES = (("pf", "PF"), ("pj", "PJ"))
name = StringField()
tp = StringField(choices=TYPES)
father = CachedReferenceField('self', fields=('tp',))
father = CachedReferenceField("self", fields=("tp",))
Person.drop_collection()
a1 = Person(name="Wilson Father", tp="pj")
a1.save()
a2 = Person(name='Wilson Junior', tp='pf', father=a1)
a2 = Person(name="Wilson Junior", tp="pf", father=a1)
a2.save()
a2 = Person.objects.with_id(a2.id)
self.assertEqual(a2.father.tp, a1.tp)
self.assertEqual(dict(a2.to_mongo()), {
"_id": a2.pk,
"name": u"Wilson Junior",
"tp": u"pf",
"father": {
"_id": a1.pk,
"tp": u"pj"
}
})
self.assertEqual(
dict(a2.to_mongo()),
{
"_id": a2.pk,
"name": u"Wilson Junior",
"tp": u"pf",
"father": {"_id": a1.pk, "tp": u"pj"},
},
)
self.assertEqual(Person.objects(father=a1)._query, {
'father._id': a1.pk
})
self.assertEqual(Person.objects(father=a1)._query, {"father._id": a1.pk})
self.assertEqual(Person.objects(father=a1).count(), 1)
Person.objects.update(set__tp="pf")
Person.father.sync_all()
a2.reload()
self.assertEqual(dict(a2.to_mongo()), {
"_id": a2.pk,
"name": u"Wilson Junior",
"tp": u"pf",
"father": {
"_id": a1.pk,
"tp": u"pf"
}
})
self.assertEqual(
dict(a2.to_mongo()),
{
"_id": a2.pk,
"name": u"Wilson Junior",
"tp": u"pf",
"father": {"_id": a1.pk, "tp": u"pf"},
},
)
def test_cached_reference_fields_on_embedded_documents(self):
with self.assertRaises(InvalidDocumentError):
class Test(Document):
name = StringField()
type('WrongEmbeddedDocument', (
EmbeddedDocument,), {
'test': CachedReferenceField(Test)
})
type(
"WrongEmbeddedDocument",
(EmbeddedDocument,),
{"test": CachedReferenceField(Test)},
)
def test_cached_reference_auto_sync(self):
class Person(Document):
TYPES = (
('pf', "PF"),
('pj', "PJ")
)
TYPES = (("pf", "PF"), ("pj", "PJ"))
name = StringField()
tp = StringField(
choices=TYPES
)
tp = StringField(choices=TYPES)
father = CachedReferenceField('self', fields=('tp',))
father = CachedReferenceField("self", fields=("tp",))
Person.drop_collection()
a1 = Person(name="Wilson Father", tp="pj")
a1.save()
a2 = Person(name='Wilson Junior', tp='pf', father=a1)
a2 = Person(name="Wilson Junior", tp="pf", father=a1)
a2.save()
a1.tp = 'pf'
a1.tp = "pf"
a1.save()
a2.reload()
self.assertEqual(dict(a2.to_mongo()), {
'_id': a2.pk,
'name': 'Wilson Junior',
'tp': 'pf',
'father': {
'_id': a1.pk,
'tp': 'pf'
}
})
self.assertEqual(
dict(a2.to_mongo()),
{
"_id": a2.pk,
"name": "Wilson Junior",
"tp": "pf",
"father": {"_id": a1.pk, "tp": "pf"},
},
)
def test_cached_reference_auto_sync_disabled(self):
class Persone(Document):
TYPES = (
('pf', "PF"),
('pj', "PJ")
)
TYPES = (("pf", "PF"), ("pj", "PJ"))
name = StringField()
tp = StringField(
choices=TYPES
)
tp = StringField(choices=TYPES)
father = CachedReferenceField(
'self', fields=('tp',), auto_sync=False)
father = CachedReferenceField("self", fields=("tp",), auto_sync=False)
Persone.drop_collection()
a1 = Persone(name="Wilson Father", tp="pj")
a1.save()
a2 = Persone(name='Wilson Junior', tp='pf', father=a1)
a2 = Persone(name="Wilson Junior", tp="pf", father=a1)
a2.save()
a1.tp = 'pf'
a1.tp = "pf"
a1.save()
self.assertEqual(Persone.objects._collection.find_one({'_id': a2.pk}), {
'_id': a2.pk,
'name': 'Wilson Junior',
'tp': 'pf',
'father': {
'_id': a1.pk,
'tp': 'pj'
}
})
self.assertEqual(
Persone.objects._collection.find_one({"_id": a2.pk}),
{
"_id": a2.pk,
"name": "Wilson Junior",
"tp": "pf",
"father": {"_id": a1.pk, "tp": "pj"},
},
)
def test_cached_reference_embedded_fields(self):
class Owner(EmbeddedDocument):
TPS = (
('n', "Normal"),
('u', "Urgent")
)
TPS = (("n", "Normal"), ("u", "Urgent"))
name = StringField()
tp = StringField(
verbose_name="Type",
db_field="t",
choices=TPS)
tp = StringField(verbose_name="Type", db_field="t", choices=TPS)
class Animal(Document):
name = StringField()
@@ -351,43 +308,38 @@ class TestCachedReferenceField(MongoDBTestCase):
class Ocorrence(Document):
person = StringField()
animal = CachedReferenceField(
Animal, fields=['tag', 'owner.tp'])
animal = CachedReferenceField(Animal, fields=["tag", "owner.tp"])
Animal.drop_collection()
Ocorrence.drop_collection()
a = Animal(name="Leopard", tag="heavy",
owner=Owner(tp='u', name="Wilson Júnior")
)
a = Animal(
name="Leopard", tag="heavy", owner=Owner(tp="u", name="Wilson Júnior")
)
a.save()
o = Ocorrence(person="teste", animal=a)
o.save()
self.assertEqual(dict(a.to_mongo(fields=['tag', 'owner.tp'])), {
'_id': a.pk,
'tag': 'heavy',
'owner': {
't': 'u'
}
})
self.assertEqual(o.to_mongo()['animal']['tag'], 'heavy')
self.assertEqual(o.to_mongo()['animal']['owner']['t'], 'u')
self.assertEqual(
dict(a.to_mongo(fields=["tag", "owner.tp"])),
{"_id": a.pk, "tag": "heavy", "owner": {"t": "u"}},
)
self.assertEqual(o.to_mongo()["animal"]["tag"], "heavy")
self.assertEqual(o.to_mongo()["animal"]["owner"]["t"], "u")
# Check to_mongo with fields
self.assertNotIn('animal', o.to_mongo(fields=['person']))
self.assertNotIn("animal", o.to_mongo(fields=["person"]))
# counts
Ocorrence(person="teste 2").save()
Ocorrence(person="teste 3").save()
count = Ocorrence.objects(
animal__tag='heavy', animal__owner__tp='u').count()
count = Ocorrence.objects(animal__tag="heavy", animal__owner__tp="u").count()
self.assertEqual(count, 1)
ocorrence = Ocorrence.objects(
animal__tag='heavy',
animal__owner__tp='u').first()
animal__tag="heavy", animal__owner__tp="u"
).first()
self.assertEqual(ocorrence.person, "teste")
self.assertIsInstance(ocorrence.animal, Animal)
@@ -404,43 +356,39 @@ class TestCachedReferenceField(MongoDBTestCase):
class Ocorrence(Document):
person = StringField()
animal = CachedReferenceField(
Animal, fields=['tag', 'owner.tags'])
animal = CachedReferenceField(Animal, fields=["tag", "owner.tags"])
Animal.drop_collection()
Ocorrence.drop_collection()
a = Animal(name="Leopard", tag="heavy",
owner=Owner(tags=['cool', 'funny'],
name="Wilson Júnior")
)
a = Animal(
name="Leopard",
tag="heavy",
owner=Owner(tags=["cool", "funny"], name="Wilson Júnior"),
)
a.save()
o = Ocorrence(person="teste 2", animal=a)
o.save()
self.assertEqual(dict(a.to_mongo(fields=['tag', 'owner.tags'])), {
'_id': a.pk,
'tag': 'heavy',
'owner': {
'tags': ['cool', 'funny']
}
})
self.assertEqual(
dict(a.to_mongo(fields=["tag", "owner.tags"])),
{"_id": a.pk, "tag": "heavy", "owner": {"tags": ["cool", "funny"]}},
)
self.assertEqual(o.to_mongo()['animal']['tag'], 'heavy')
self.assertEqual(o.to_mongo()['animal']['owner']['tags'],
['cool', 'funny'])
self.assertEqual(o.to_mongo()["animal"]["tag"], "heavy")
self.assertEqual(o.to_mongo()["animal"]["owner"]["tags"], ["cool", "funny"])
# counts
Ocorrence(person="teste 2").save()
Ocorrence(person="teste 3").save()
query = Ocorrence.objects(
animal__tag='heavy', animal__owner__tags='cool')._query
self.assertEqual(
query, {'animal.owner.tags': 'cool', 'animal.tag': 'heavy'})
animal__tag="heavy", animal__owner__tags="cool"
)._query
self.assertEqual(query, {"animal.owner.tags": "cool", "animal.tag": "heavy"})
ocorrence = Ocorrence.objects(
animal__tag='heavy',
animal__owner__tags='cool').first()
animal__tag="heavy", animal__owner__tags="cool"
).first()
self.assertEqual(ocorrence.person, "teste 2")
self.assertIsInstance(ocorrence.animal, Animal)

View File

@@ -14,9 +14,10 @@ class ComplexDateTimeFieldTest(MongoDBTestCase):
"""Tests for complex datetime fields - which can handle
microseconds without rounding.
"""
class LogEntry(Document):
date = ComplexDateTimeField()
date_with_dots = ComplexDateTimeField(separator='.')
date_with_dots = ComplexDateTimeField(separator=".")
LogEntry.drop_collection()
@@ -62,17 +63,25 @@ class ComplexDateTimeFieldTest(MongoDBTestCase):
mm = dd = hh = ii = ss = [1, 10]
for values in itertools.product([2014], mm, dd, hh, ii, ss, microsecond):
stored = LogEntry(date=datetime.datetime(*values)).to_mongo()['date']
self.assertTrue(re.match('^\d{4},\d{2},\d{2},\d{2},\d{2},\d{2},\d{6}$', stored) is not None)
stored = LogEntry(date=datetime.datetime(*values)).to_mongo()["date"]
self.assertTrue(
re.match("^\d{4},\d{2},\d{2},\d{2},\d{2},\d{2},\d{6}$", stored)
is not None
)
# Test separator
stored = LogEntry(date_with_dots=datetime.datetime(2014, 1, 1)).to_mongo()['date_with_dots']
self.assertTrue(re.match('^\d{4}.\d{2}.\d{2}.\d{2}.\d{2}.\d{2}.\d{6}$', stored) is not None)
stored = LogEntry(date_with_dots=datetime.datetime(2014, 1, 1)).to_mongo()[
"date_with_dots"
]
self.assertTrue(
re.match("^\d{4}.\d{2}.\d{2}.\d{2}.\d{2}.\d{2}.\d{6}$", stored) is not None
)
def test_complexdatetime_usage(self):
"""Tests for complex datetime fields - which can handle
microseconds without rounding.
"""
class LogEntry(Document):
date = ComplexDateTimeField()
@@ -123,22 +132,21 @@ class ComplexDateTimeFieldTest(MongoDBTestCase):
# Test microsecond-level ordering/filtering
for microsecond in (99, 999, 9999, 10000):
LogEntry(
date=datetime.datetime(2015, 1, 1, 0, 0, 0, microsecond)
).save()
LogEntry(date=datetime.datetime(2015, 1, 1, 0, 0, 0, microsecond)).save()
logs = list(LogEntry.objects.order_by('date'))
logs = list(LogEntry.objects.order_by("date"))
for next_idx, log in enumerate(logs[:-1], start=1):
next_log = logs[next_idx]
self.assertTrue(log.date < next_log.date)
logs = list(LogEntry.objects.order_by('-date'))
logs = list(LogEntry.objects.order_by("-date"))
for next_idx, log in enumerate(logs[:-1], start=1):
next_log = logs[next_idx]
self.assertTrue(log.date > next_log.date)
logs = LogEntry.objects.filter(
date__lte=datetime.datetime(2015, 1, 1, 0, 0, 0, 10000))
date__lte=datetime.datetime(2015, 1, 1, 0, 0, 0, 10000)
)
self.assertEqual(logs.count(), 4)
def test_no_default_value(self):
@@ -156,6 +164,7 @@ class ComplexDateTimeFieldTest(MongoDBTestCase):
def test_default_static_value(self):
NOW = datetime.datetime.utcnow()
class Log(Document):
timestamp = ComplexDateTimeField(default=NOW)

View File

@@ -18,10 +18,11 @@ class TestDateField(MongoDBTestCase):
Ensure an exception is raised when trying to
cast an empty string to datetime.
"""
class MyDoc(Document):
dt = DateField()
md = MyDoc(dt='')
md = MyDoc(dt="")
self.assertRaises(ValidationError, md.save)
def test_date_from_whitespace_string(self):
@@ -29,16 +30,18 @@ class TestDateField(MongoDBTestCase):
Ensure an exception is raised when trying to
cast a whitespace-only string to datetime.
"""
class MyDoc(Document):
dt = DateField()
md = MyDoc(dt=' ')
md = MyDoc(dt=" ")
self.assertRaises(ValidationError, md.save)
def test_default_values_today(self):
"""Ensure that default field values are used when creating
a document.
"""
class Person(Document):
day = DateField(default=datetime.date.today)
@@ -46,13 +49,14 @@ class TestDateField(MongoDBTestCase):
person.validate()
self.assertEqual(person.day, person.day)
self.assertEqual(person.day, datetime.date.today())
self.assertEqual(person._data['day'], person.day)
self.assertEqual(person._data["day"], person.day)
def test_date(self):
"""Tests showing pymongo date fields
See: http://api.mongodb.org/python/current/api/bson/son.html#dt
"""
class LogEntry(Document):
date = DateField()
@@ -95,6 +99,7 @@ class TestDateField(MongoDBTestCase):
def test_regular_usage(self):
"""Tests for regular datetime fields"""
class LogEntry(Document):
date = DateField()
@@ -106,12 +111,12 @@ class TestDateField(MongoDBTestCase):
log.validate()
log.save()
for query in (d1, d1.isoformat(' ')):
for query in (d1, d1.isoformat(" ")):
log1 = LogEntry.objects.get(date=query)
self.assertEqual(log, log1)
if dateutil:
log1 = LogEntry.objects.get(date=d1.isoformat('T'))
log1 = LogEntry.objects.get(date=d1.isoformat("T"))
self.assertEqual(log, log1)
# create additional 19 log entries for a total of 20
@@ -142,6 +147,7 @@ class TestDateField(MongoDBTestCase):
"""Ensure that invalid values cannot be assigned to datetime
fields.
"""
class LogEntry(Document):
time = DateField()
@@ -152,14 +158,14 @@ class TestDateField(MongoDBTestCase):
log.time = datetime.date.today()
log.validate()
log.time = datetime.datetime.now().isoformat(' ')
log.time = datetime.datetime.now().isoformat(" ")
log.validate()
if dateutil:
log.time = datetime.datetime.now().isoformat('T')
log.time = datetime.datetime.now().isoformat("T")
log.validate()
log.time = -1
self.assertRaises(ValidationError, log.validate)
log.time = 'ABC'
log.time = "ABC"
self.assertRaises(ValidationError, log.validate)

View File

@@ -19,10 +19,11 @@ class TestDateTimeField(MongoDBTestCase):
Ensure an exception is raised when trying to
cast an empty string to datetime.
"""
class MyDoc(Document):
dt = DateTimeField()
md = MyDoc(dt='')
md = MyDoc(dt="")
self.assertRaises(ValidationError, md.save)
def test_datetime_from_whitespace_string(self):
@@ -30,16 +31,18 @@ class TestDateTimeField(MongoDBTestCase):
Ensure an exception is raised when trying to
cast a whitespace-only string to datetime.
"""
class MyDoc(Document):
dt = DateTimeField()
md = MyDoc(dt=' ')
md = MyDoc(dt=" ")
self.assertRaises(ValidationError, md.save)
def test_default_value_utcnow(self):
"""Ensure that default field values are used when creating
a document.
"""
class Person(Document):
created = DateTimeField(default=dt.datetime.utcnow)
@@ -48,8 +51,10 @@ class TestDateTimeField(MongoDBTestCase):
person.validate()
person_created_t0 = person.created
self.assertLess(person.created - utcnow, dt.timedelta(seconds=1))
self.assertEqual(person_created_t0, person.created) # make sure it does not change
self.assertEqual(person._data['created'], person.created)
self.assertEqual(
person_created_t0, person.created
) # make sure it does not change
self.assertEqual(person._data["created"], person.created)
def test_handling_microseconds(self):
"""Tests showing pymongo datetime fields handling of microseconds.
@@ -58,6 +63,7 @@ class TestDateTimeField(MongoDBTestCase):
See: http://api.mongodb.org/python/current/api/bson/son.html#dt
"""
class LogEntry(Document):
date = DateTimeField()
@@ -103,6 +109,7 @@ class TestDateTimeField(MongoDBTestCase):
def test_regular_usage(self):
"""Tests for regular datetime fields"""
class LogEntry(Document):
date = DateTimeField()
@@ -114,12 +121,12 @@ class TestDateTimeField(MongoDBTestCase):
log.validate()
log.save()
for query in (d1, d1.isoformat(' ')):
for query in (d1, d1.isoformat(" ")):
log1 = LogEntry.objects.get(date=query)
self.assertEqual(log, log1)
if dateutil:
log1 = LogEntry.objects.get(date=d1.isoformat('T'))
log1 = LogEntry.objects.get(date=d1.isoformat("T"))
self.assertEqual(log, log1)
# create additional 19 log entries for a total of 20
@@ -150,8 +157,7 @@ class TestDateTimeField(MongoDBTestCase):
self.assertEqual(logs.count(), 10)
logs = LogEntry.objects.filter(
date__lte=dt.datetime(1980, 1, 1),
date__gte=dt.datetime(1975, 1, 1),
date__lte=dt.datetime(1980, 1, 1), date__gte=dt.datetime(1975, 1, 1)
)
self.assertEqual(logs.count(), 5)
@@ -159,6 +165,7 @@ class TestDateTimeField(MongoDBTestCase):
"""Ensure that invalid values cannot be assigned to datetime
fields.
"""
class LogEntry(Document):
time = DateTimeField()
@@ -169,32 +176,32 @@ class TestDateTimeField(MongoDBTestCase):
log.time = dt.date.today()
log.validate()
log.time = dt.datetime.now().isoformat(' ')
log.time = dt.datetime.now().isoformat(" ")
log.validate()
log.time = '2019-05-16 21:42:57.897847'
log.time = "2019-05-16 21:42:57.897847"
log.validate()
if dateutil:
log.time = dt.datetime.now().isoformat('T')
log.time = dt.datetime.now().isoformat("T")
log.validate()
log.time = -1
self.assertRaises(ValidationError, log.validate)
log.time = 'ABC'
log.time = "ABC"
self.assertRaises(ValidationError, log.validate)
log.time = '2019-05-16 21:GARBAGE:12'
log.time = "2019-05-16 21:GARBAGE:12"
self.assertRaises(ValidationError, log.validate)
log.time = '2019-05-16 21:42:57.GARBAGE'
log.time = "2019-05-16 21:42:57.GARBAGE"
self.assertRaises(ValidationError, log.validate)
log.time = '2019-05-16 21:42:57.123.456'
log.time = "2019-05-16 21:42:57.123.456"
self.assertRaises(ValidationError, log.validate)
def test_parse_datetime_as_str(self):
class DTDoc(Document):
date = DateTimeField()
date_str = '2019-03-02 22:26:01'
date_str = "2019-03-02 22:26:01"
# make sure that passing a parsable datetime works
dtd = DTDoc()
@@ -206,7 +213,7 @@ class TestDateTimeField(MongoDBTestCase):
self.assertIsInstance(dtd.date, dt.datetime)
self.assertEqual(str(dtd.date), date_str)
dtd.date = 'January 1st, 9999999999'
dtd.date = "January 1st, 9999999999"
self.assertRaises(ValidationError, dtd.validate)
@@ -217,7 +224,7 @@ class TestDateTimeTzAware(MongoDBTestCase):
connection._connections = {}
connection._dbs = {}
connect(db='mongoenginetest', tz_aware=True)
connect(db="mongoenginetest", tz_aware=True)
class LogEntry(Document):
time = DateTimeField()
@@ -228,4 +235,4 @@ class TestDateTimeTzAware(MongoDBTestCase):
log = LogEntry.objects.first()
log.time = dt.datetime(2013, 1, 1, 0, 0, 0)
self.assertEqual(['time'], log._changed_fields)
self.assertEqual(["time"], log._changed_fields)

View File

@@ -7,32 +7,31 @@ 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'))
height = DecimalField(min_value=Decimal("0.1"), max_value=Decimal("3.5"))
Person.drop_collection()
Person(height=Decimal('1.89')).save()
Person(height=Decimal("1.89")).save()
person = Person.objects.first()
self.assertEqual(person.height, Decimal('1.89'))
self.assertEqual(person.height, Decimal("1.89"))
person.height = '2.0'
person.height = "2.0"
person.save()
person.height = 0.01
self.assertRaises(ValidationError, person.validate)
person.height = Decimal('0.01')
person.height = Decimal("0.01")
self.assertRaises(ValidationError, person.validate)
person.height = Decimal('4.0')
person.height = Decimal("4.0")
self.assertRaises(ValidationError, person.validate)
person.height = 'something invalid'
person.height = "something invalid"
self.assertRaises(ValidationError, person.validate)
person_2 = Person(height='something invalid')
person_2 = Person(height="something invalid")
self.assertRaises(ValidationError, person_2.validate)
def test_comparison(self):
@@ -58,7 +57,14 @@ class TestDecimalField(MongoDBTestCase):
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")]
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__
@@ -72,20 +78,27 @@ class TestDecimalField(MongoDBTestCase):
# 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'}]
{"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())
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 = [
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']:
for field_name in ["float_value", "string_value"]:
actual = list(Person.objects().scalar(field_name))
self.assertEqual(expected, actual)

View File

@@ -6,95 +6,92 @@ from tests.utils import MongoDBTestCase, get_as_pymongo
class TestDictField(MongoDBTestCase):
def test_storage(self):
class BlogPost(Document):
info = DictField()
BlogPost.drop_collection()
info = {'testkey': 'testvalue'}
info = {"testkey": "testvalue"}
post = BlogPost(info=info).save()
self.assertEqual(
get_as_pymongo(post),
{
'_id': post.id,
'info': info
}
)
self.assertEqual(get_as_pymongo(post), {"_id": post.id, "info": info})
def test_general_things(self):
"""Ensure that dict types work as expected."""
class BlogPost(Document):
info = DictField()
BlogPost.drop_collection()
post = BlogPost()
post.info = 'my post'
post.info = "my post"
self.assertRaises(ValidationError, post.validate)
post.info = ['test', 'test']
post.info = ["test", "test"]
self.assertRaises(ValidationError, post.validate)
post.info = {'$title': 'test'}
post.info = {"$title": "test"}
self.assertRaises(ValidationError, post.validate)
post.info = {'nested': {'$title': 'test'}}
post.info = {"nested": {"$title": "test"}}
self.assertRaises(ValidationError, post.validate)
post.info = {'the.title': 'test'}
post.info = {"the.title": "test"}
self.assertRaises(ValidationError, post.validate)
post.info = {'nested': {'the.title': 'test'}}
post.info = {"nested": {"the.title": "test"}}
self.assertRaises(ValidationError, post.validate)
post.info = {1: 'test'}
post.info = {1: "test"}
self.assertRaises(ValidationError, post.validate)
post.info = {'title': 'test'}
post.info = {"title": "test"}
post.save()
post = BlogPost()
post.info = {'title': 'dollar_sign', 'details': {'te$t': 'test'}}
post.info = {"title": "dollar_sign", "details": {"te$t": "test"}}
post.save()
post = BlogPost()
post.info = {'details': {'test': 'test'}}
post.info = {"details": {"test": "test"}}
post.save()
post = BlogPost()
post.info = {'details': {'test': 3}}
post.info = {"details": {"test": 3}}
post.save()
self.assertEqual(BlogPost.objects.count(), 4)
self.assertEqual(BlogPost.objects.filter(info__title__exact="test").count(), 1)
self.assertEqual(
BlogPost.objects.filter(info__title__exact='test').count(), 1)
self.assertEqual(
BlogPost.objects.filter(info__details__test__exact='test').count(), 1)
BlogPost.objects.filter(info__details__test__exact="test").count(), 1
)
post = BlogPost.objects.filter(info__title__exact='dollar_sign').first()
self.assertIn('te$t', post['info']['details'])
post = BlogPost.objects.filter(info__title__exact="dollar_sign").first()
self.assertIn("te$t", post["info"]["details"])
# Confirm handles non strings or non existing keys
self.assertEqual(
BlogPost.objects.filter(info__details__test__exact=5).count(), 0)
BlogPost.objects.filter(info__details__test__exact=5).count(), 0
)
self.assertEqual(
BlogPost.objects.filter(info__made_up__test__exact='test').count(), 0)
BlogPost.objects.filter(info__made_up__test__exact="test").count(), 0
)
post = BlogPost.objects.create(info={'title': 'original'})
post.info.update({'title': 'updated'})
post = BlogPost.objects.create(info={"title": "original"})
post.info.update({"title": "updated"})
post.save()
post.reload()
self.assertEqual('updated', post.info['title'])
self.assertEqual("updated", post.info["title"])
post.info.setdefault('authors', [])
post.info.setdefault("authors", [])
post.save()
post.reload()
self.assertEqual([], post.info['authors'])
self.assertEqual([], post.info["authors"])
def test_dictfield_dump_document(self):
"""Ensure a DictField can handle another document's dump."""
class Doc(Document):
field = DictField()
@@ -106,51 +103,62 @@ class TestDictField(MongoDBTestCase):
id = IntField(primary_key=True, default=1)
recursive = DictField()
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
class ToEmbedChild(ToEmbedParent):
pass
to_embed_recursive = ToEmbed(id=1).save()
to_embed = ToEmbed(
id=2, recursive=to_embed_recursive.to_mongo().to_dict()).save()
id=2, recursive=to_embed_recursive.to_mongo().to_dict()
).save()
doc = Doc(field=to_embed.to_mongo().to_dict())
doc.save()
self.assertIsInstance(doc.field, dict)
self.assertEqual(doc.field, {'_id': 2, 'recursive': {'_id': 1, 'recursive': {}}})
self.assertEqual(
doc.field, {"_id": 2, "recursive": {"_id": 1, "recursive": {}}}
)
# Same thing with a Document with a _cls field
to_embed_recursive = ToEmbedChild(id=1).save()
to_embed_child = ToEmbedChild(
id=2, recursive=to_embed_recursive.to_mongo().to_dict()).save()
id=2, recursive=to_embed_recursive.to_mongo().to_dict()
).save()
doc = Doc(field=to_embed_child.to_mongo().to_dict())
doc.save()
self.assertIsInstance(doc.field, dict)
expected = {
'_id': 2, '_cls': 'ToEmbedParent.ToEmbedChild',
'recursive': {'_id': 1, '_cls': 'ToEmbedParent.ToEmbedChild', 'recursive': {}}
"_id": 2,
"_cls": "ToEmbedParent.ToEmbedChild",
"recursive": {
"_id": 1,
"_cls": "ToEmbedParent.ToEmbedChild",
"recursive": {},
},
}
self.assertEqual(doc.field, expected)
def test_dictfield_strict(self):
"""Ensure that dict field handles validation if provided a strict field type."""
class Simple(Document):
mapping = DictField(field=IntField())
Simple.drop_collection()
e = Simple()
e.mapping['someint'] = 1
e.mapping["someint"] = 1
e.save()
# try creating an invalid mapping
with self.assertRaises(ValidationError):
e.mapping['somestring'] = "abc"
e.mapping["somestring"] = "abc"
e.save()
def test_dictfield_complex(self):
"""Ensure that the dict field can handle the complex types."""
class SettingBase(EmbeddedDocument):
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
class StringSetting(SettingBase):
value = StringField()
@@ -164,70 +172,72 @@ class TestDictField(MongoDBTestCase):
Simple.drop_collection()
e = Simple()
e.mapping['somestring'] = StringSetting(value='foo')
e.mapping['someint'] = IntegerSetting(value=42)
e.mapping['nested_dict'] = {'number': 1, 'string': 'Hi!',
'float': 1.001,
'complex': IntegerSetting(value=42),
'list': [IntegerSetting(value=42),
StringSetting(value='foo')]}
e.mapping["somestring"] = StringSetting(value="foo")
e.mapping["someint"] = IntegerSetting(value=42)
e.mapping["nested_dict"] = {
"number": 1,
"string": "Hi!",
"float": 1.001,
"complex": IntegerSetting(value=42),
"list": [IntegerSetting(value=42), StringSetting(value="foo")],
}
e.save()
e2 = Simple.objects.get(id=e.id)
self.assertIsInstance(e2.mapping['somestring'], StringSetting)
self.assertIsInstance(e2.mapping['someint'], IntegerSetting)
self.assertIsInstance(e2.mapping["somestring"], StringSetting)
self.assertIsInstance(e2.mapping["someint"], IntegerSetting)
# Test querying
self.assertEqual(Simple.objects.filter(mapping__someint__value=42).count(), 1)
self.assertEqual(
Simple.objects.filter(mapping__someint__value=42).count(), 1)
Simple.objects.filter(mapping__nested_dict__number=1).count(), 1
)
self.assertEqual(
Simple.objects.filter(mapping__nested_dict__number=1).count(), 1)
Simple.objects.filter(mapping__nested_dict__complex__value=42).count(), 1
)
self.assertEqual(
Simple.objects.filter(mapping__nested_dict__complex__value=42).count(), 1)
Simple.objects.filter(mapping__nested_dict__list__0__value=42).count(), 1
)
self.assertEqual(
Simple.objects.filter(mapping__nested_dict__list__0__value=42).count(), 1)
self.assertEqual(
Simple.objects.filter(mapping__nested_dict__list__1__value='foo').count(), 1)
Simple.objects.filter(mapping__nested_dict__list__1__value="foo").count(), 1
)
# Confirm can update
Simple.objects().update(set__mapping={"someint": IntegerSetting(value=10)})
Simple.objects().update(
set__mapping={"someint": IntegerSetting(value=10)})
Simple.objects().update(
set__mapping__nested_dict__list__1=StringSetting(value='Boo'))
set__mapping__nested_dict__list__1=StringSetting(value="Boo")
)
self.assertEqual(
Simple.objects.filter(mapping__nested_dict__list__1__value='foo').count(), 0)
Simple.objects.filter(mapping__nested_dict__list__1__value="foo").count(), 0
)
self.assertEqual(
Simple.objects.filter(mapping__nested_dict__list__1__value='Boo').count(), 1)
Simple.objects.filter(mapping__nested_dict__list__1__value="Boo").count(), 1
)
def test_push_dict(self):
class MyModel(Document):
events = ListField(DictField())
doc = MyModel(events=[{'a': 1}]).save()
doc = MyModel(events=[{"a": 1}]).save()
raw_doc = get_as_pymongo(doc)
expected_raw_doc = {
'_id': doc.id,
'events': [{'a': 1}]
}
expected_raw_doc = {"_id": doc.id, "events": [{"a": 1}]}
self.assertEqual(raw_doc, expected_raw_doc)
MyModel.objects(id=doc.id).update(push__events={})
raw_doc = get_as_pymongo(doc)
expected_raw_doc = {
'_id': doc.id,
'events': [{'a': 1}, {}]
}
expected_raw_doc = {"_id": doc.id, "events": [{"a": 1}, {}]}
self.assertEqual(raw_doc, expected_raw_doc)
def test_ensure_unique_default_instances(self):
"""Ensure that every field has it's own unique default instance."""
class D(Document):
data = DictField()
data2 = DictField(default=lambda: {})
d1 = D()
d1.data['foo'] = 'bar'
d1.data2['foo'] = 'bar'
d1.data["foo"] = "bar"
d1.data2["foo"] = "bar"
d2 = D()
self.assertEqual(d2.data, {})
self.assertEqual(d2.data2, {})
@@ -255,22 +265,25 @@ class TestDictField(MongoDBTestCase):
class Embedded(EmbeddedDocument):
name = StringField()
embed = Embedded(name='garbage')
embed = Embedded(name="garbage")
doc = DictFieldTest(dictionary=embed)
with self.assertRaises(ValidationError) as ctx_err:
doc.validate()
self.assertIn("'dictionary'", str(ctx_err.exception))
self.assertIn('Only dictionaries may be used in a DictField', str(ctx_err.exception))
self.assertIn(
"Only dictionaries may be used in a DictField", str(ctx_err.exception)
)
def test_atomic_update_dict_field(self):
"""Ensure that the entire DictField can be atomically updated."""
class Simple(Document):
mapping = DictField(field=ListField(IntField(required=True)))
Simple.drop_collection()
e = Simple()
e.mapping['someints'] = [1, 2]
e.mapping["someints"] = [1, 2]
e.save()
e.update(set__mapping={"ints": [3, 4]})
e.reload()
@@ -279,7 +292,7 @@ class TestDictField(MongoDBTestCase):
# try creating an invalid mapping
with self.assertRaises(ValueError):
e.update(set__mapping={"somestrings": ["foo", "bar", ]})
e.update(set__mapping={"somestrings": ["foo", "bar"]})
def test_dictfield_with_referencefield_complex_nesting_cases(self):
"""Ensure complex nesting inside DictField handles dereferencing of ReferenceField(dbref=True | False)"""
@@ -296,29 +309,33 @@ class TestDictField(MongoDBTestCase):
mapping5 = DictField(DictField(field=ReferenceField(Doc, dbref=False)))
mapping6 = DictField(ListField(DictField(ReferenceField(Doc, dbref=True))))
mapping7 = DictField(ListField(DictField(ReferenceField(Doc, dbref=False))))
mapping8 = DictField(ListField(DictField(ListField(ReferenceField(Doc, dbref=True)))))
mapping9 = DictField(ListField(DictField(ListField(ReferenceField(Doc, dbref=False)))))
mapping8 = DictField(
ListField(DictField(ListField(ReferenceField(Doc, dbref=True))))
)
mapping9 = DictField(
ListField(DictField(ListField(ReferenceField(Doc, dbref=False))))
)
Doc.drop_collection()
Simple.drop_collection()
d = Doc(s='aa').save()
d = Doc(s="aa").save()
e = Simple()
e.mapping0['someint'] = e.mapping1['someint'] = d
e.mapping2['someint'] = e.mapping3['someint'] = [d]
e.mapping4['someint'] = e.mapping5['someint'] = {'d': d}
e.mapping6['someint'] = e.mapping7['someint'] = [{'d': d}]
e.mapping8['someint'] = e.mapping9['someint'] = [{'d': [d]}]
e.mapping0["someint"] = e.mapping1["someint"] = d
e.mapping2["someint"] = e.mapping3["someint"] = [d]
e.mapping4["someint"] = e.mapping5["someint"] = {"d": d}
e.mapping6["someint"] = e.mapping7["someint"] = [{"d": d}]
e.mapping8["someint"] = e.mapping9["someint"] = [{"d": [d]}]
e.save()
s = Simple.objects.first()
self.assertIsInstance(s.mapping0['someint'], Doc)
self.assertIsInstance(s.mapping1['someint'], Doc)
self.assertIsInstance(s.mapping2['someint'][0], Doc)
self.assertIsInstance(s.mapping3['someint'][0], Doc)
self.assertIsInstance(s.mapping4['someint']['d'], Doc)
self.assertIsInstance(s.mapping5['someint']['d'], Doc)
self.assertIsInstance(s.mapping6['someint'][0]['d'], Doc)
self.assertIsInstance(s.mapping7['someint'][0]['d'], Doc)
self.assertIsInstance(s.mapping8['someint'][0]['d'][0], Doc)
self.assertIsInstance(s.mapping9['someint'][0]['d'][0], Doc)
self.assertIsInstance(s.mapping0["someint"], Doc)
self.assertIsInstance(s.mapping1["someint"], Doc)
self.assertIsInstance(s.mapping2["someint"][0], Doc)
self.assertIsInstance(s.mapping3["someint"][0], Doc)
self.assertIsInstance(s.mapping4["someint"]["d"], Doc)
self.assertIsInstance(s.mapping5["someint"]["d"], Doc)
self.assertIsInstance(s.mapping6["someint"][0]["d"], Doc)
self.assertIsInstance(s.mapping7["someint"][0]["d"], Doc)
self.assertIsInstance(s.mapping8["someint"][0]["d"][0], Doc)
self.assertIsInstance(s.mapping9["someint"][0]["d"][0], Doc)

View File

@@ -12,28 +12,29 @@ class TestEmailField(MongoDBTestCase):
class User(Document):
email = EmailField()
user = User(email='ross@example.com')
user = User(email="ross@example.com")
user.validate()
user = User(email='ross@example.co.uk')
user = User(email="ross@example.co.uk")
user.validate()
user = User(email=('Kofq@rhom0e4klgauOhpbpNdogawnyIKvQS0wk2mjqrgGQ5S'
'aJIazqqWkm7.net'))
user = User(
email=("Kofq@rhom0e4klgauOhpbpNdogawnyIKvQS0wk2mjqrgGQ5SaJIazqqWkm7.net")
)
user.validate()
user = User(email='new-tld@example.technology')
user = User(email="new-tld@example.technology")
user.validate()
user = User(email='ross@example.com.')
user = User(email="ross@example.com.")
self.assertRaises(ValidationError, user.validate)
# unicode domain
user = User(email=u'user@пример.рф')
user = User(email=u"user@пример.рф")
user.validate()
# invalid unicode domain
user = User(email=u'user@пример')
user = User(email=u"user@пример")
self.assertRaises(ValidationError, user.validate)
# invalid data type
@@ -44,20 +45,20 @@ class TestEmailField(MongoDBTestCase):
# Don't run this test on pypy3, which doesn't support unicode regex:
# https://bitbucket.org/pypy/pypy/issues/1821/regular-expression-doesnt-find-unicode
if sys.version_info[:2] == (3, 2):
raise SkipTest('unicode email addresses are not supported on PyPy 3')
raise SkipTest("unicode email addresses are not supported on PyPy 3")
class User(Document):
email = EmailField()
# unicode user shouldn't validate by default...
user = User(email=u'Dörte@Sörensen.example.com')
user = User(email=u"Dörte@Sörensen.example.com")
self.assertRaises(ValidationError, user.validate)
# ...but it should be fine with allow_utf8_user set to True
class User(Document):
email = EmailField(allow_utf8_user=True)
user = User(email=u'Dörte@Sörensen.example.com')
user = User(email=u"Dörte@Sörensen.example.com")
user.validate()
def test_email_field_domain_whitelist(self):
@@ -65,22 +66,22 @@ class TestEmailField(MongoDBTestCase):
email = EmailField()
# localhost domain shouldn't validate by default...
user = User(email='me@localhost')
user = User(email="me@localhost")
self.assertRaises(ValidationError, user.validate)
# ...but it should be fine if it's whitelisted
class User(Document):
email = EmailField(domain_whitelist=['localhost'])
email = EmailField(domain_whitelist=["localhost"])
user = User(email='me@localhost')
user = User(email="me@localhost")
user.validate()
def test_email_domain_validation_fails_if_invalid_idn(self):
class User(Document):
email = EmailField()
invalid_idn = '.google.com'
user = User(email='me@%s' % invalid_idn)
invalid_idn = ".google.com"
user = User(email="me@%s" % invalid_idn)
with self.assertRaises(ValidationError) as ctx_err:
user.validate()
self.assertIn("domain failed IDN encoding", str(ctx_err.exception))
@@ -89,9 +90,9 @@ class TestEmailField(MongoDBTestCase):
class User(Document):
email = EmailField()
valid_ipv4 = 'email@[127.0.0.1]'
valid_ipv6 = 'email@[2001:dB8::1]'
invalid_ip = 'email@[324.0.0.1]'
valid_ipv4 = "email@[127.0.0.1]"
valid_ipv6 = "email@[2001:dB8::1]"
invalid_ip = "email@[324.0.0.1]"
# IP address as a domain shouldn't validate by default...
user = User(email=valid_ipv4)
@@ -119,12 +120,12 @@ class TestEmailField(MongoDBTestCase):
def test_email_field_honors_regex(self):
class User(Document):
email = EmailField(regex=r'\w+@example.com')
email = EmailField(regex=r"\w+@example.com")
# Fails regex validation
user = User(email='me@foo.com')
user = User(email="me@foo.com")
self.assertRaises(ValidationError, user.validate)
# Passes regex validation
user = User(email='me@example.com')
user = User(email="me@example.com")
self.assertIsNone(user.validate())

View File

@@ -1,7 +1,18 @@
# -*- coding: utf-8 -*-
from mongoengine import Document, StringField, ValidationError, EmbeddedDocument, EmbeddedDocumentField, \
InvalidQueryError, LookUpError, IntField, GenericEmbeddedDocumentField, ListField, EmbeddedDocumentListField, \
ReferenceField
from mongoengine import (
Document,
StringField,
ValidationError,
EmbeddedDocument,
EmbeddedDocumentField,
InvalidQueryError,
LookUpError,
IntField,
GenericEmbeddedDocumentField,
ListField,
EmbeddedDocumentListField,
ReferenceField,
)
from tests.utils import MongoDBTestCase
@@ -14,22 +25,24 @@ class TestEmbeddedDocumentField(MongoDBTestCase):
field = EmbeddedDocumentField(MyDoc)
self.assertEqual(field.document_type_obj, MyDoc)
field2 = EmbeddedDocumentField('MyDoc')
self.assertEqual(field2.document_type_obj, 'MyDoc')
field2 = EmbeddedDocumentField("MyDoc")
self.assertEqual(field2.document_type_obj, "MyDoc")
def test___init___throw_error_if_document_type_is_not_EmbeddedDocument(self):
with self.assertRaises(ValidationError):
EmbeddedDocumentField(dict)
def test_document_type_throw_error_if_not_EmbeddedDocument_subclass(self):
class MyDoc(Document):
name = StringField()
emb = EmbeddedDocumentField('MyDoc')
emb = EmbeddedDocumentField("MyDoc")
with self.assertRaises(ValidationError) as ctx:
emb.document_type
self.assertIn('Invalid embedded document class provided to an EmbeddedDocumentField', str(ctx.exception))
self.assertIn(
"Invalid embedded document class provided to an EmbeddedDocumentField",
str(ctx.exception),
)
def test_embedded_document_field_only_allow_subclasses_of_embedded_document(self):
# Relates to #1661
@@ -37,12 +50,14 @@ class TestEmbeddedDocumentField(MongoDBTestCase):
name = StringField()
with self.assertRaises(ValidationError):
class MyFailingDoc(Document):
emb = EmbeddedDocumentField(MyDoc)
with self.assertRaises(ValidationError):
class MyFailingdoc2(Document):
emb = EmbeddedDocumentField('MyDoc')
emb = EmbeddedDocumentField("MyDoc")
def test_query_embedded_document_attribute(self):
class AdminSettings(EmbeddedDocument):
@@ -55,34 +70,31 @@ class TestEmbeddedDocumentField(MongoDBTestCase):
Person.drop_collection()
p = Person(
settings=AdminSettings(foo1='bar1', foo2='bar2'),
name='John',
).save()
p = Person(settings=AdminSettings(foo1="bar1", foo2="bar2"), name="John").save()
# Test non exiting attribute
with self.assertRaises(InvalidQueryError) as ctx_err:
Person.objects(settings__notexist='bar').first()
Person.objects(settings__notexist="bar").first()
self.assertEqual(unicode(ctx_err.exception), u'Cannot resolve field "notexist"')
with self.assertRaises(LookUpError):
Person.objects.only('settings.notexist')
Person.objects.only("settings.notexist")
# Test existing attribute
self.assertEqual(Person.objects(settings__foo1='bar1').first().id, p.id)
only_p = Person.objects.only('settings.foo1').first()
self.assertEqual(Person.objects(settings__foo1="bar1").first().id, p.id)
only_p = Person.objects.only("settings.foo1").first()
self.assertEqual(only_p.settings.foo1, p.settings.foo1)
self.assertIsNone(only_p.settings.foo2)
self.assertIsNone(only_p.name)
exclude_p = Person.objects.exclude('settings.foo1').first()
exclude_p = Person.objects.exclude("settings.foo1").first()
self.assertIsNone(exclude_p.settings.foo1)
self.assertEqual(exclude_p.settings.foo2, p.settings.foo2)
self.assertEqual(exclude_p.name, p.name)
def test_query_embedded_document_attribute_with_inheritance(self):
class BaseSettings(EmbeddedDocument):
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
base_foo = StringField()
class AdminSettings(BaseSettings):
@@ -93,26 +105,26 @@ class TestEmbeddedDocumentField(MongoDBTestCase):
Person.drop_collection()
p = Person(settings=AdminSettings(base_foo='basefoo', sub_foo='subfoo'))
p = Person(settings=AdminSettings(base_foo="basefoo", sub_foo="subfoo"))
p.save()
# Test non exiting attribute
with self.assertRaises(InvalidQueryError) as ctx_err:
self.assertEqual(Person.objects(settings__notexist='bar').first().id, p.id)
self.assertEqual(Person.objects(settings__notexist="bar").first().id, p.id)
self.assertEqual(unicode(ctx_err.exception), u'Cannot resolve field "notexist"')
# Test existing attribute
self.assertEqual(Person.objects(settings__base_foo='basefoo').first().id, p.id)
self.assertEqual(Person.objects(settings__sub_foo='subfoo').first().id, p.id)
self.assertEqual(Person.objects(settings__base_foo="basefoo").first().id, p.id)
self.assertEqual(Person.objects(settings__sub_foo="subfoo").first().id, p.id)
only_p = Person.objects.only('settings.base_foo', 'settings._cls').first()
self.assertEqual(only_p.settings.base_foo, 'basefoo')
only_p = Person.objects.only("settings.base_foo", "settings._cls").first()
self.assertEqual(only_p.settings.base_foo, "basefoo")
self.assertIsNone(only_p.settings.sub_foo)
def test_query_list_embedded_document_with_inheritance(self):
class Post(EmbeddedDocument):
title = StringField(max_length=120, required=True)
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
class TextPost(Post):
content = StringField()
@@ -123,8 +135,8 @@ class TestEmbeddedDocumentField(MongoDBTestCase):
class Record(Document):
posts = ListField(EmbeddedDocumentField(Post))
record_movie = Record(posts=[MoviePost(author='John', title='foo')]).save()
record_text = Record(posts=[TextPost(content='a', title='foo')]).save()
record_movie = Record(posts=[MoviePost(author="John", title="foo")]).save()
record_text = Record(posts=[TextPost(content="a", title="foo")]).save()
records = list(Record.objects(posts__author=record_movie.posts[0].author))
self.assertEqual(len(records), 1)
@@ -134,11 +146,10 @@ class TestEmbeddedDocumentField(MongoDBTestCase):
self.assertEqual(len(records), 1)
self.assertEqual(records[0].id, record_text.id)
self.assertEqual(Record.objects(posts__title='foo').count(), 2)
self.assertEqual(Record.objects(posts__title="foo").count(), 2)
class TestGenericEmbeddedDocumentField(MongoDBTestCase):
def test_generic_embedded_document(self):
class Car(EmbeddedDocument):
name = StringField()
@@ -153,8 +164,8 @@ class TestGenericEmbeddedDocumentField(MongoDBTestCase):
Person.drop_collection()
person = Person(name='Test User')
person.like = Car(name='Fiat')
person = Person(name="Test User")
person.like = Car(name="Fiat")
person.save()
person = Person.objects.first()
@@ -168,6 +179,7 @@ class TestGenericEmbeddedDocumentField(MongoDBTestCase):
def test_generic_embedded_document_choices(self):
"""Ensure you can limit GenericEmbeddedDocument choices."""
class Car(EmbeddedDocument):
name = StringField()
@@ -181,8 +193,8 @@ class TestGenericEmbeddedDocumentField(MongoDBTestCase):
Person.drop_collection()
person = Person(name='Test User')
person.like = Car(name='Fiat')
person = Person(name="Test User")
person.like = Car(name="Fiat")
self.assertRaises(ValidationError, person.validate)
person.like = Dish(food="arroz", number=15)
@@ -195,6 +207,7 @@ class TestGenericEmbeddedDocumentField(MongoDBTestCase):
"""Ensure you can limit GenericEmbeddedDocument choices inside
a list field.
"""
class Car(EmbeddedDocument):
name = StringField()
@@ -208,8 +221,8 @@ class TestGenericEmbeddedDocumentField(MongoDBTestCase):
Person.drop_collection()
person = Person(name='Test User')
person.likes = [Car(name='Fiat')]
person = Person(name="Test User")
person.likes = [Car(name="Fiat")]
self.assertRaises(ValidationError, person.validate)
person.likes = [Dish(food="arroz", number=15)]
@@ -222,25 +235,23 @@ class TestGenericEmbeddedDocumentField(MongoDBTestCase):
"""
Ensure fields with document choices validate given a valid choice.
"""
class UserComments(EmbeddedDocument):
author = StringField()
message = StringField()
class BlogPost(Document):
comments = ListField(
GenericEmbeddedDocumentField(choices=(UserComments,))
)
comments = ListField(GenericEmbeddedDocumentField(choices=(UserComments,)))
# Ensure Validation Passes
BlogPost(comments=[
UserComments(author='user2', message='message2'),
]).save()
BlogPost(comments=[UserComments(author="user2", message="message2")]).save()
def test_choices_validation_documents_invalid(self):
"""
Ensure fields with document choices validate given an invalid choice.
This should throw a ValidationError exception.
"""
class UserComments(EmbeddedDocument):
author = StringField()
message = StringField()
@@ -250,31 +261,28 @@ class TestGenericEmbeddedDocumentField(MongoDBTestCase):
message = StringField()
class BlogPost(Document):
comments = ListField(
GenericEmbeddedDocumentField(choices=(UserComments,))
)
comments = ListField(GenericEmbeddedDocumentField(choices=(UserComments,)))
# Single Entry Failure
post = BlogPost(comments=[
ModeratorComments(author='mod1', message='message1'),
])
post = BlogPost(comments=[ModeratorComments(author="mod1", message="message1")])
self.assertRaises(ValidationError, post.save)
# Mixed Entry Failure
post = BlogPost(comments=[
ModeratorComments(author='mod1', message='message1'),
UserComments(author='user2', message='message2'),
])
post = BlogPost(
comments=[
ModeratorComments(author="mod1", message="message1"),
UserComments(author="user2", message="message2"),
]
)
self.assertRaises(ValidationError, post.save)
def test_choices_validation_documents_inheritance(self):
"""
Ensure fields with document choices validate given subclass of choice.
"""
class Comments(EmbeddedDocument):
meta = {
'abstract': True
}
meta = {"abstract": True}
author = StringField()
message = StringField()
@@ -282,14 +290,10 @@ class TestGenericEmbeddedDocumentField(MongoDBTestCase):
pass
class BlogPost(Document):
comments = ListField(
GenericEmbeddedDocumentField(choices=(Comments,))
)
comments = ListField(GenericEmbeddedDocumentField(choices=(Comments,)))
# Save Valid EmbeddedDocument Type
BlogPost(comments=[
UserComments(author='user2', message='message2'),
]).save()
BlogPost(comments=[UserComments(author="user2", message="message2")]).save()
def test_query_generic_embedded_document_attribute(self):
class AdminSettings(EmbeddedDocument):
@@ -299,28 +303,30 @@ class TestGenericEmbeddedDocumentField(MongoDBTestCase):
foo2 = StringField()
class Person(Document):
settings = GenericEmbeddedDocumentField(choices=(AdminSettings, NonAdminSettings))
settings = GenericEmbeddedDocumentField(
choices=(AdminSettings, NonAdminSettings)
)
Person.drop_collection()
p1 = Person(settings=AdminSettings(foo1='bar1')).save()
p2 = Person(settings=NonAdminSettings(foo2='bar2')).save()
p1 = Person(settings=AdminSettings(foo1="bar1")).save()
p2 = Person(settings=NonAdminSettings(foo2="bar2")).save()
# Test non exiting attribute
with self.assertRaises(InvalidQueryError) as ctx_err:
Person.objects(settings__notexist='bar').first()
Person.objects(settings__notexist="bar").first()
self.assertEqual(unicode(ctx_err.exception), u'Cannot resolve field "notexist"')
with self.assertRaises(LookUpError):
Person.objects.only('settings.notexist')
Person.objects.only("settings.notexist")
# Test existing attribute
self.assertEqual(Person.objects(settings__foo1='bar1').first().id, p1.id)
self.assertEqual(Person.objects(settings__foo2='bar2').first().id, p2.id)
self.assertEqual(Person.objects(settings__foo1="bar1").first().id, p1.id)
self.assertEqual(Person.objects(settings__foo2="bar2").first().id, p2.id)
def test_query_generic_embedded_document_attribute_with_inheritance(self):
class BaseSettings(EmbeddedDocument):
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
base_foo = StringField()
class AdminSettings(BaseSettings):
@@ -331,14 +337,14 @@ class TestGenericEmbeddedDocumentField(MongoDBTestCase):
Person.drop_collection()
p = Person(settings=AdminSettings(base_foo='basefoo', sub_foo='subfoo'))
p = Person(settings=AdminSettings(base_foo="basefoo", sub_foo="subfoo"))
p.save()
# Test non exiting attribute
with self.assertRaises(InvalidQueryError) as ctx_err:
self.assertEqual(Person.objects(settings__notexist='bar').first().id, p.id)
self.assertEqual(Person.objects(settings__notexist="bar").first().id, p.id)
self.assertEqual(unicode(ctx_err.exception), u'Cannot resolve field "notexist"')
# Test existing attribute
self.assertEqual(Person.objects(settings__base_foo='basefoo').first().id, p.id)
self.assertEqual(Person.objects(settings__sub_foo='subfoo').first().id, p.id)
self.assertEqual(Person.objects(settings__base_foo="basefoo").first().id, p.id)
self.assertEqual(Person.objects(settings__sub_foo="subfoo").first().id, p.id)

View File

@@ -7,7 +7,6 @@ from tests.utils import MongoDBTestCase
class TestFloatField(MongoDBTestCase):
def test_float_ne_operator(self):
class TestDocument(Document):
float_fld = FloatField()
@@ -23,6 +22,7 @@ class TestFloatField(MongoDBTestCase):
def test_validation(self):
"""Ensure that invalid values cannot be assigned to float fields.
"""
class Person(Document):
height = FloatField(min_value=0.1, max_value=3.5)
@@ -33,7 +33,7 @@ class TestFloatField(MongoDBTestCase):
person.height = 1.89
person.validate()
person.height = '2.0'
person.height = "2.0"
self.assertRaises(ValidationError, person.validate)
person.height = 0.01
@@ -42,7 +42,7 @@ class TestFloatField(MongoDBTestCase):
person.height = 4.0
self.assertRaises(ValidationError, person.validate)
person_2 = Person(height='something invalid')
person_2 = Person(height="something invalid")
self.assertRaises(ValidationError, person_2.validate)
big_person = BigPerson()

View File

@@ -5,10 +5,10 @@ from tests.utils import MongoDBTestCase
class TestIntField(MongoDBTestCase):
def test_int_validation(self):
"""Ensure that invalid values cannot be assigned to int fields.
"""
class Person(Document):
age = IntField(min_value=0, max_value=110)
@@ -26,7 +26,7 @@ class TestIntField(MongoDBTestCase):
self.assertRaises(ValidationError, person.validate)
person.age = 120
self.assertRaises(ValidationError, person.validate)
person.age = 'ten'
person.age = "ten"
self.assertRaises(ValidationError, person.validate)
def test_ne_operator(self):

View File

@@ -25,7 +25,7 @@ class TestLazyReferenceField(MongoDBTestCase):
animal = Animal()
oc = Ocurrence(animal=animal)
self.assertIn('LazyReference', repr(oc.animal))
self.assertIn("LazyReference", repr(oc.animal))
def test___getattr___unknown_attr_raises_attribute_error(self):
class Animal(Document):
@@ -93,7 +93,7 @@ class TestLazyReferenceField(MongoDBTestCase):
def test_lazy_reference_set(self):
class Animal(Document):
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
name = StringField()
tag = StringField()
@@ -109,18 +109,17 @@ class TestLazyReferenceField(MongoDBTestCase):
nick = StringField()
animal = Animal(name="Leopard", tag="heavy").save()
sub_animal = SubAnimal(nick='doggo', name='dog').save()
sub_animal = SubAnimal(nick="doggo", name="dog").save()
for ref in (
animal,
animal.pk,
DBRef(animal._get_collection_name(), animal.pk),
LazyReference(Animal, animal.pk),
sub_animal,
sub_animal.pk,
DBRef(sub_animal._get_collection_name(), sub_animal.pk),
LazyReference(SubAnimal, sub_animal.pk),
):
animal,
animal.pk,
DBRef(animal._get_collection_name(), animal.pk),
LazyReference(Animal, animal.pk),
sub_animal,
sub_animal.pk,
DBRef(sub_animal._get_collection_name(), sub_animal.pk),
LazyReference(SubAnimal, sub_animal.pk),
):
p = Ocurrence(person="test", animal=ref).save()
p.reload()
self.assertIsInstance(p.animal, LazyReference)
@@ -144,12 +143,12 @@ class TestLazyReferenceField(MongoDBTestCase):
animal = Animal(name="Leopard", tag="heavy").save()
baddoc = BadDoc().save()
for bad in (
42,
'foo',
baddoc,
DBRef(baddoc._get_collection_name(), animal.pk),
LazyReference(BadDoc, animal.pk)
):
42,
"foo",
baddoc,
DBRef(baddoc._get_collection_name(), animal.pk),
LazyReference(BadDoc, animal.pk),
):
with self.assertRaises(ValidationError):
p = Ocurrence(person="test", animal=bad).save()
@@ -157,6 +156,7 @@ class TestLazyReferenceField(MongoDBTestCase):
"""Ensure that LazyReferenceFields can be queried using objects and values
of the type of the primary key of the referenced object.
"""
class Member(Document):
user_num = IntField(primary_key=True)
@@ -172,10 +172,10 @@ class TestLazyReferenceField(MongoDBTestCase):
m2 = Member(user_num=2)
m2.save()
post1 = BlogPost(title='post 1', author=m1)
post1 = BlogPost(title="post 1", author=m1)
post1.save()
post2 = BlogPost(title='post 2', author=m2)
post2 = BlogPost(title="post 2", author=m2)
post2.save()
post = BlogPost.objects(author=m1).first()
@@ -192,6 +192,7 @@ class TestLazyReferenceField(MongoDBTestCase):
"""Ensure that LazyReferenceFields can be queried using objects and values
of the type of the primary key of the referenced object.
"""
class Member(Document):
user_num = IntField(primary_key=True)
@@ -207,10 +208,10 @@ class TestLazyReferenceField(MongoDBTestCase):
m2 = Member(user_num=2)
m2.save()
post1 = BlogPost(title='post 1', author=m1)
post1 = BlogPost(title="post 1", author=m1)
post1.save()
post2 = BlogPost(title='post 2', author=m2)
post2 = BlogPost(title="post 2", author=m2)
post2.save()
post = BlogPost.objects(author=m1).first()
@@ -240,19 +241,19 @@ class TestLazyReferenceField(MongoDBTestCase):
p = Ocurrence.objects.get()
self.assertIsInstance(p.animal, LazyReference)
with self.assertRaises(KeyError):
p.animal['name']
p.animal["name"]
with self.assertRaises(AttributeError):
p.animal.name
self.assertEqual(p.animal.pk, animal.pk)
self.assertEqual(p.animal_passthrough.name, "Leopard")
self.assertEqual(p.animal_passthrough['name'], "Leopard")
self.assertEqual(p.animal_passthrough["name"], "Leopard")
# Should not be able to access referenced document's methods
with self.assertRaises(AttributeError):
p.animal.save
with self.assertRaises(KeyError):
p.animal['save']
p.animal["save"]
def test_lazy_reference_not_set(self):
class Animal(Document):
@@ -266,7 +267,7 @@ class TestLazyReferenceField(MongoDBTestCase):
Animal.drop_collection()
Ocurrence.drop_collection()
Ocurrence(person='foo').save()
Ocurrence(person="foo").save()
p = Ocurrence.objects.get()
self.assertIs(p.animal, None)
@@ -303,8 +304,8 @@ class TestLazyReferenceField(MongoDBTestCase):
Animal.drop_collection()
Ocurrence.drop_collection()
animal1 = Animal(name='doggo').save()
animal2 = Animal(name='cheeta').save()
animal1 = Animal(name="doggo").save()
animal2 = Animal(name="cheeta").save()
def check_fields_type(occ):
self.assertIsInstance(occ.direct, LazyReference)
@@ -316,8 +317,8 @@ class TestLazyReferenceField(MongoDBTestCase):
occ = Ocurrence(
in_list=[animal1, animal2],
in_embedded={'in_list': [animal1, animal2], 'direct': animal1},
direct=animal1
in_embedded={"in_list": [animal1, animal2], "direct": animal1},
direct=animal1,
).save()
check_fields_type(occ)
occ.reload()
@@ -403,7 +404,7 @@ class TestGenericLazyReferenceField(MongoDBTestCase):
def test_generic_lazy_reference_set(self):
class Animal(Document):
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
name = StringField()
tag = StringField()
@@ -419,16 +420,18 @@ class TestGenericLazyReferenceField(MongoDBTestCase):
nick = StringField()
animal = Animal(name="Leopard", tag="heavy").save()
sub_animal = SubAnimal(nick='doggo', name='dog').save()
sub_animal = SubAnimal(nick="doggo", name="dog").save()
for ref in (
animal,
LazyReference(Animal, animal.pk),
{'_cls': 'Animal', '_ref': DBRef(animal._get_collection_name(), animal.pk)},
sub_animal,
LazyReference(SubAnimal, sub_animal.pk),
{'_cls': 'SubAnimal', '_ref': DBRef(sub_animal._get_collection_name(), sub_animal.pk)},
):
animal,
LazyReference(Animal, animal.pk),
{"_cls": "Animal", "_ref": DBRef(animal._get_collection_name(), animal.pk)},
sub_animal,
LazyReference(SubAnimal, sub_animal.pk),
{
"_cls": "SubAnimal",
"_ref": DBRef(sub_animal._get_collection_name(), sub_animal.pk),
},
):
p = Ocurrence(person="test", animal=ref).save()
p.reload()
self.assertIsInstance(p.animal, (LazyReference, Document))
@@ -441,7 +444,7 @@ class TestGenericLazyReferenceField(MongoDBTestCase):
class Ocurrence(Document):
person = StringField()
animal = GenericLazyReferenceField(choices=['Animal'])
animal = GenericLazyReferenceField(choices=["Animal"])
Animal.drop_collection()
Ocurrence.drop_collection()
@@ -451,12 +454,7 @@ class TestGenericLazyReferenceField(MongoDBTestCase):
animal = Animal(name="Leopard", tag="heavy").save()
baddoc = BadDoc().save()
for bad in (
42,
'foo',
baddoc,
LazyReference(BadDoc, animal.pk)
):
for bad in (42, "foo", baddoc, LazyReference(BadDoc, animal.pk)):
with self.assertRaises(ValidationError):
p = Ocurrence(person="test", animal=bad).save()
@@ -476,10 +474,10 @@ class TestGenericLazyReferenceField(MongoDBTestCase):
m2 = Member(user_num=2)
m2.save()
post1 = BlogPost(title='post 1', author=m1)
post1 = BlogPost(title="post 1", author=m1)
post1.save()
post2 = BlogPost(title='post 2', author=m2)
post2 = BlogPost(title="post 2", author=m2)
post2.save()
post = BlogPost.objects(author=m1).first()
@@ -504,7 +502,7 @@ class TestGenericLazyReferenceField(MongoDBTestCase):
Animal.drop_collection()
Ocurrence.drop_collection()
Ocurrence(person='foo').save()
Ocurrence(person="foo").save()
p = Ocurrence.objects.get()
self.assertIs(p.animal, None)
@@ -515,7 +513,7 @@ class TestGenericLazyReferenceField(MongoDBTestCase):
class Ocurrence(Document):
person = StringField()
animal = GenericLazyReferenceField('Animal')
animal = GenericLazyReferenceField("Animal")
Animal.drop_collection()
Ocurrence.drop_collection()
@@ -542,8 +540,8 @@ class TestGenericLazyReferenceField(MongoDBTestCase):
Animal.drop_collection()
Ocurrence.drop_collection()
animal1 = Animal(name='doggo').save()
animal2 = Animal(name='cheeta').save()
animal1 = Animal(name="doggo").save()
animal2 = Animal(name="cheeta").save()
def check_fields_type(occ):
self.assertIsInstance(occ.direct, LazyReference)
@@ -555,14 +553,20 @@ class TestGenericLazyReferenceField(MongoDBTestCase):
occ = Ocurrence(
in_list=[animal1, animal2],
in_embedded={'in_list': [animal1, animal2], 'direct': animal1},
direct=animal1
in_embedded={"in_list": [animal1, animal2], "direct": animal1},
direct=animal1,
).save()
check_fields_type(occ)
occ.reload()
check_fields_type(occ)
animal1_ref = {'_cls': 'Animal', '_ref': DBRef(animal1._get_collection_name(), animal1.pk)}
animal2_ref = {'_cls': 'Animal', '_ref': DBRef(animal2._get_collection_name(), animal2.pk)}
animal1_ref = {
"_cls": "Animal",
"_ref": DBRef(animal1._get_collection_name(), animal1.pk),
}
animal2_ref = {
"_cls": "Animal",
"_ref": DBRef(animal2._get_collection_name(), animal2.pk),
}
occ.direct = animal1_ref
occ.in_list = [animal1_ref, animal2_ref]
occ.in_embedded.direct = animal1_ref

View File

@@ -13,23 +13,26 @@ from tests.utils import MongoDBTestCase
class TestLongField(MongoDBTestCase):
def test_long_field_is_considered_as_int64(self):
"""
Tests that long fields are stored as long in mongo, even if long
value is small enough to be an int.
"""
class TestLongFieldConsideredAsInt64(Document):
some_long = LongField()
doc = TestLongFieldConsideredAsInt64(some_long=42).save()
db = get_db()
self.assertIsInstance(db.test_long_field_considered_as_int64.find()[0]['some_long'], Int64)
self.assertIsInstance(
db.test_long_field_considered_as_int64.find()[0]["some_long"], Int64
)
self.assertIsInstance(doc.some_long, six.integer_types)
def test_long_validation(self):
"""Ensure that invalid values cannot be assigned to long fields.
"""
class TestDocument(Document):
value = LongField(min_value=0, max_value=110)
@@ -41,7 +44,7 @@ class TestLongField(MongoDBTestCase):
self.assertRaises(ValidationError, doc.validate)
doc.value = 120
self.assertRaises(ValidationError, doc.validate)
doc.value = 'ten'
doc.value = "ten"
self.assertRaises(ValidationError, doc.validate)
def test_long_ne_operator(self):

View File

@@ -7,23 +7,24 @@ from tests.utils import MongoDBTestCase
class TestMapField(MongoDBTestCase):
def test_mapfield(self):
"""Ensure that the MapField handles the declared type."""
class Simple(Document):
mapping = MapField(IntField())
Simple.drop_collection()
e = Simple()
e.mapping['someint'] = 1
e.mapping["someint"] = 1
e.save()
with self.assertRaises(ValidationError):
e.mapping['somestring'] = "abc"
e.mapping["somestring"] = "abc"
e.save()
with self.assertRaises(ValidationError):
class NoDeclaredType(Document):
mapping = MapField()
@@ -45,38 +46,37 @@ class TestMapField(MongoDBTestCase):
Extensible.drop_collection()
e = Extensible()
e.mapping['somestring'] = StringSetting(value='foo')
e.mapping['someint'] = IntegerSetting(value=42)
e.mapping["somestring"] = StringSetting(value="foo")
e.mapping["someint"] = IntegerSetting(value=42)
e.save()
e2 = Extensible.objects.get(id=e.id)
self.assertIsInstance(e2.mapping['somestring'], StringSetting)
self.assertIsInstance(e2.mapping['someint'], IntegerSetting)
self.assertIsInstance(e2.mapping["somestring"], StringSetting)
self.assertIsInstance(e2.mapping["someint"], IntegerSetting)
with self.assertRaises(ValidationError):
e.mapping['someint'] = 123
e.mapping["someint"] = 123
e.save()
def test_embedded_mapfield_db_field(self):
class Embedded(EmbeddedDocument):
number = IntField(default=0, db_field='i')
number = IntField(default=0, db_field="i")
class Test(Document):
my_map = MapField(field=EmbeddedDocumentField(Embedded),
db_field='x')
my_map = MapField(field=EmbeddedDocumentField(Embedded), db_field="x")
Test.drop_collection()
test = Test()
test.my_map['DICTIONARY_KEY'] = Embedded(number=1)
test.my_map["DICTIONARY_KEY"] = Embedded(number=1)
test.save()
Test.objects.update_one(inc__my_map__DICTIONARY_KEY__number=1)
test = Test.objects.get()
self.assertEqual(test.my_map['DICTIONARY_KEY'].number, 2)
self.assertEqual(test.my_map["DICTIONARY_KEY"].number, 2)
doc = self.db.test.find_one()
self.assertEqual(doc['x']['DICTIONARY_KEY']['i'], 2)
self.assertEqual(doc["x"]["DICTIONARY_KEY"]["i"], 2)
def test_mapfield_numerical_index(self):
"""Ensure that MapField accept numeric strings as indexes."""
@@ -90,9 +90,9 @@ class TestMapField(MongoDBTestCase):
Test.drop_collection()
test = Test()
test.my_map['1'] = Embedded(name='test')
test.my_map["1"] = Embedded(name="test")
test.save()
test.my_map['1'].name = 'test updated'
test.my_map["1"].name = "test updated"
test.save()
def test_map_field_lookup(self):
@@ -110,15 +110,20 @@ class TestMapField(MongoDBTestCase):
actions = MapField(EmbeddedDocumentField(Action))
Log.drop_collection()
Log(name="wilson", visited={'friends': datetime.datetime.now()},
actions={'friends': Action(operation='drink', object='beer')}).save()
Log(
name="wilson",
visited={"friends": datetime.datetime.now()},
actions={"friends": Action(operation="drink", object="beer")},
).save()
self.assertEqual(1, Log.objects(
visited__friends__exists=True).count())
self.assertEqual(1, Log.objects(visited__friends__exists=True).count())
self.assertEqual(1, Log.objects(
actions__friends__operation='drink',
actions__friends__object='beer').count())
self.assertEqual(
1,
Log.objects(
actions__friends__operation="drink", actions__friends__object="beer"
).count(),
)
def test_map_field_unicode(self):
class Info(EmbeddedDocument):
@@ -130,15 +135,11 @@ class TestMapField(MongoDBTestCase):
BlogPost.drop_collection()
tree = BlogPost(info_dict={
u"éééé": {
'description': u"VALUE: éééé"
}
})
tree = BlogPost(info_dict={u"éééé": {"description": u"VALUE: éééé"}})
tree.save()
self.assertEqual(
BlogPost.objects.get(id=tree.id).info_dict[u"éééé"].description,
u"VALUE: éééé"
u"VALUE: éééé",
)

View File

@@ -26,15 +26,15 @@ class TestReferenceField(MongoDBTestCase):
# with a document class name.
self.assertRaises(ValidationError, ReferenceField, EmbeddedDocument)
user = User(name='Test User')
user = User(name="Test User")
# Ensure that the referenced object must have been saved
post1 = BlogPost(content='Chips and gravy taste good.')
post1 = BlogPost(content="Chips and gravy taste good.")
post1.author = user
self.assertRaises(ValidationError, post1.save)
# Check that an invalid object type cannot be used
post2 = BlogPost(content='Chips and chilli taste good.')
post2 = BlogPost(content="Chips and chilli taste good.")
post1.author = post2
self.assertRaises(ValidationError, post1.validate)
@@ -59,7 +59,7 @@ class TestReferenceField(MongoDBTestCase):
class Person(Document):
name = StringField()
parent = ReferenceField('self')
parent = ReferenceField("self")
Person.drop_collection()
@@ -74,7 +74,7 @@ class TestReferenceField(MongoDBTestCase):
class Person(Document):
name = StringField()
parent = ReferenceField('self', dbref=True)
parent = ReferenceField("self", dbref=True)
Person.drop_collection()
@@ -82,8 +82,8 @@ class TestReferenceField(MongoDBTestCase):
Person(name="Ross", parent=p1).save()
self.assertEqual(
Person._get_collection().find_one({'name': 'Ross'})['parent'],
DBRef('person', p1.pk)
Person._get_collection().find_one({"name": "Ross"})["parent"],
DBRef("person", p1.pk),
)
p = Person.objects.get(name="Ross")
@@ -97,21 +97,17 @@ class TestReferenceField(MongoDBTestCase):
class Person(Document):
name = StringField()
parent = ReferenceField('self', dbref=False)
parent = ReferenceField("self", dbref=False)
p = Person(
name='Steve',
parent=DBRef('person', 'abcdefghijklmnop')
p = Person(name="Steve", parent=DBRef("person", "abcdefghijklmnop"))
self.assertEqual(
p.to_mongo(), SON([("name", u"Steve"), ("parent", "abcdefghijklmnop")])
)
self.assertEqual(p.to_mongo(), SON([
('name', u'Steve'),
('parent', 'abcdefghijklmnop')
]))
def test_objectid_reference_fields(self):
class Person(Document):
name = StringField()
parent = ReferenceField('self', dbref=False)
parent = ReferenceField("self", dbref=False)
Person.drop_collection()
@@ -119,8 +115,8 @@ class TestReferenceField(MongoDBTestCase):
Person(name="Ross", parent=p1).save()
col = Person._get_collection()
data = col.find_one({'name': 'Ross'})
self.assertEqual(data['parent'], p1.pk)
data = col.find_one({"name": "Ross"})
self.assertEqual(data["parent"], p1.pk)
p = Person.objects.get(name="Ross")
self.assertEqual(p.parent, p1)
@@ -128,9 +124,10 @@ class TestReferenceField(MongoDBTestCase):
def test_undefined_reference(self):
"""Ensure that ReferenceFields may reference undefined Documents.
"""
class Product(Document):
name = StringField()
company = ReferenceField('Company')
company = ReferenceField("Company")
class Company(Document):
name = StringField()
@@ -138,12 +135,12 @@ class TestReferenceField(MongoDBTestCase):
Product.drop_collection()
Company.drop_collection()
ten_gen = Company(name='10gen')
ten_gen = Company(name="10gen")
ten_gen.save()
mongodb = Product(name='MongoDB', company=ten_gen)
mongodb = Product(name="MongoDB", company=ten_gen)
mongodb.save()
me = Product(name='MongoEngine')
me = Product(name="MongoEngine")
me.save()
obj = Product.objects(company=ten_gen).first()
@@ -160,6 +157,7 @@ class TestReferenceField(MongoDBTestCase):
"""Ensure that ReferenceFields can be queried using objects and values
of the type of the primary key of the referenced object.
"""
class Member(Document):
user_num = IntField(primary_key=True)
@@ -175,10 +173,10 @@ class TestReferenceField(MongoDBTestCase):
m2 = Member(user_num=2)
m2.save()
post1 = BlogPost(title='post 1', author=m1)
post1 = BlogPost(title="post 1", author=m1)
post1.save()
post2 = BlogPost(title='post 2', author=m2)
post2 = BlogPost(title="post 2", author=m2)
post2.save()
post = BlogPost.objects(author=m1).first()
@@ -191,6 +189,7 @@ class TestReferenceField(MongoDBTestCase):
"""Ensure that ReferenceFields can be queried using objects and values
of the type of the primary key of the referenced object.
"""
class Member(Document):
user_num = IntField(primary_key=True)
@@ -206,10 +205,10 @@ class TestReferenceField(MongoDBTestCase):
m2 = Member(user_num=2)
m2.save()
post1 = BlogPost(title='post 1', author=m1)
post1 = BlogPost(title="post 1", author=m1)
post1.save()
post2 = BlogPost(title='post 2', author=m2)
post2 = BlogPost(title="post 2", author=m2)
post2.save()
post = BlogPost.objects(author=m1).first()

View File

@@ -11,38 +11,38 @@ class TestSequenceField(MongoDBTestCase):
id = SequenceField(primary_key=True)
name = StringField()
self.db['mongoengine.counters'].drop()
self.db["mongoengine.counters"].drop()
Person.drop_collection()
for x in range(10):
Person(name="Person %s" % x).save()
c = self.db['mongoengine.counters'].find_one({'_id': 'person.id'})
self.assertEqual(c['next'], 10)
c = self.db["mongoengine.counters"].find_one({"_id": "person.id"})
self.assertEqual(c["next"], 10)
ids = [i.id for i in Person.objects]
self.assertEqual(ids, range(1, 11))
c = self.db['mongoengine.counters'].find_one({'_id': 'person.id'})
self.assertEqual(c['next'], 10)
c = self.db["mongoengine.counters"].find_one({"_id": "person.id"})
self.assertEqual(c["next"], 10)
Person.id.set_next_value(1000)
c = self.db['mongoengine.counters'].find_one({'_id': 'person.id'})
self.assertEqual(c['next'], 1000)
c = self.db["mongoengine.counters"].find_one({"_id": "person.id"})
self.assertEqual(c["next"], 1000)
def test_sequence_field_get_next_value(self):
class Person(Document):
id = SequenceField(primary_key=True)
name = StringField()
self.db['mongoengine.counters'].drop()
self.db["mongoengine.counters"].drop()
Person.drop_collection()
for x in range(10):
Person(name="Person %s" % x).save()
self.assertEqual(Person.id.get_next_value(), 11)
self.db['mongoengine.counters'].drop()
self.db["mongoengine.counters"].drop()
self.assertEqual(Person.id.get_next_value(), 1)
@@ -50,40 +50,40 @@ class TestSequenceField(MongoDBTestCase):
id = SequenceField(primary_key=True, value_decorator=str)
name = StringField()
self.db['mongoengine.counters'].drop()
self.db["mongoengine.counters"].drop()
Person.drop_collection()
for x in range(10):
Person(name="Person %s" % x).save()
self.assertEqual(Person.id.get_next_value(), '11')
self.db['mongoengine.counters'].drop()
self.assertEqual(Person.id.get_next_value(), "11")
self.db["mongoengine.counters"].drop()
self.assertEqual(Person.id.get_next_value(), '1')
self.assertEqual(Person.id.get_next_value(), "1")
def test_sequence_field_sequence_name(self):
class Person(Document):
id = SequenceField(primary_key=True, sequence_name='jelly')
id = SequenceField(primary_key=True, sequence_name="jelly")
name = StringField()
self.db['mongoengine.counters'].drop()
self.db["mongoengine.counters"].drop()
Person.drop_collection()
for x in range(10):
Person(name="Person %s" % x).save()
c = self.db['mongoengine.counters'].find_one({'_id': 'jelly.id'})
self.assertEqual(c['next'], 10)
c = self.db["mongoengine.counters"].find_one({"_id": "jelly.id"})
self.assertEqual(c["next"], 10)
ids = [i.id for i in Person.objects]
self.assertEqual(ids, range(1, 11))
c = self.db['mongoengine.counters'].find_one({'_id': 'jelly.id'})
self.assertEqual(c['next'], 10)
c = self.db["mongoengine.counters"].find_one({"_id": "jelly.id"})
self.assertEqual(c["next"], 10)
Person.id.set_next_value(1000)
c = self.db['mongoengine.counters'].find_one({'_id': 'jelly.id'})
self.assertEqual(c['next'], 1000)
c = self.db["mongoengine.counters"].find_one({"_id": "jelly.id"})
self.assertEqual(c["next"], 1000)
def test_multiple_sequence_fields(self):
class Person(Document):
@@ -91,14 +91,14 @@ class TestSequenceField(MongoDBTestCase):
counter = SequenceField()
name = StringField()
self.db['mongoengine.counters'].drop()
self.db["mongoengine.counters"].drop()
Person.drop_collection()
for x in range(10):
Person(name="Person %s" % x).save()
c = self.db['mongoengine.counters'].find_one({'_id': 'person.id'})
self.assertEqual(c['next'], 10)
c = self.db["mongoengine.counters"].find_one({"_id": "person.id"})
self.assertEqual(c["next"], 10)
ids = [i.id for i in Person.objects]
self.assertEqual(ids, range(1, 11))
@@ -106,23 +106,23 @@ class TestSequenceField(MongoDBTestCase):
counters = [i.counter for i in Person.objects]
self.assertEqual(counters, range(1, 11))
c = self.db['mongoengine.counters'].find_one({'_id': 'person.id'})
self.assertEqual(c['next'], 10)
c = self.db["mongoengine.counters"].find_one({"_id": "person.id"})
self.assertEqual(c["next"], 10)
Person.id.set_next_value(1000)
c = self.db['mongoengine.counters'].find_one({'_id': 'person.id'})
self.assertEqual(c['next'], 1000)
c = self.db["mongoengine.counters"].find_one({"_id": "person.id"})
self.assertEqual(c["next"], 1000)
Person.counter.set_next_value(999)
c = self.db['mongoengine.counters'].find_one({'_id': 'person.counter'})
self.assertEqual(c['next'], 999)
c = self.db["mongoengine.counters"].find_one({"_id": "person.counter"})
self.assertEqual(c["next"], 999)
def test_sequence_fields_reload(self):
class Animal(Document):
counter = SequenceField()
name = StringField()
self.db['mongoengine.counters'].drop()
self.db["mongoengine.counters"].drop()
Animal.drop_collection()
a = Animal(name="Boi").save()
@@ -151,7 +151,7 @@ class TestSequenceField(MongoDBTestCase):
id = SequenceField(primary_key=True)
name = StringField()
self.db['mongoengine.counters'].drop()
self.db["mongoengine.counters"].drop()
Animal.drop_collection()
Person.drop_collection()
@@ -159,11 +159,11 @@ class TestSequenceField(MongoDBTestCase):
Animal(name="Animal %s" % x).save()
Person(name="Person %s" % x).save()
c = self.db['mongoengine.counters'].find_one({'_id': 'person.id'})
self.assertEqual(c['next'], 10)
c = self.db["mongoengine.counters"].find_one({"_id": "person.id"})
self.assertEqual(c["next"], 10)
c = self.db['mongoengine.counters'].find_one({'_id': 'animal.id'})
self.assertEqual(c['next'], 10)
c = self.db["mongoengine.counters"].find_one({"_id": "animal.id"})
self.assertEqual(c["next"], 10)
ids = [i.id for i in Person.objects]
self.assertEqual(ids, range(1, 11))
@@ -171,32 +171,32 @@ class TestSequenceField(MongoDBTestCase):
id = [i.id for i in Animal.objects]
self.assertEqual(id, range(1, 11))
c = self.db['mongoengine.counters'].find_one({'_id': 'person.id'})
self.assertEqual(c['next'], 10)
c = self.db["mongoengine.counters"].find_one({"_id": "person.id"})
self.assertEqual(c["next"], 10)
c = self.db['mongoengine.counters'].find_one({'_id': 'animal.id'})
self.assertEqual(c['next'], 10)
c = self.db["mongoengine.counters"].find_one({"_id": "animal.id"})
self.assertEqual(c["next"], 10)
def test_sequence_field_value_decorator(self):
class Person(Document):
id = SequenceField(primary_key=True, value_decorator=str)
name = StringField()
self.db['mongoengine.counters'].drop()
self.db["mongoengine.counters"].drop()
Person.drop_collection()
for x in range(10):
p = Person(name="Person %s" % x)
p.save()
c = self.db['mongoengine.counters'].find_one({'_id': 'person.id'})
self.assertEqual(c['next'], 10)
c = self.db["mongoengine.counters"].find_one({"_id": "person.id"})
self.assertEqual(c["next"], 10)
ids = [i.id for i in Person.objects]
self.assertEqual(ids, map(str, range(1, 11)))
c = self.db['mongoengine.counters'].find_one({'_id': 'person.id'})
self.assertEqual(c['next'], 10)
c = self.db["mongoengine.counters"].find_one({"_id": "person.id"})
self.assertEqual(c["next"], 10)
def test_embedded_sequence_field(self):
class Comment(EmbeddedDocument):
@@ -207,14 +207,18 @@ class TestSequenceField(MongoDBTestCase):
title = StringField(required=True)
comments = ListField(EmbeddedDocumentField(Comment))
self.db['mongoengine.counters'].drop()
self.db["mongoengine.counters"].drop()
Post.drop_collection()
Post(title="MongoEngine",
comments=[Comment(content="NoSQL Rocks"),
Comment(content="MongoEngine Rocks")]).save()
c = self.db['mongoengine.counters'].find_one({'_id': 'comment.id'})
self.assertEqual(c['next'], 2)
Post(
title="MongoEngine",
comments=[
Comment(content="NoSQL Rocks"),
Comment(content="MongoEngine Rocks"),
],
).save()
c = self.db["mongoengine.counters"].find_one({"_id": "comment.id"})
self.assertEqual(c["next"], 2)
post = Post.objects.first()
self.assertEqual(1, post.comments[0].id)
self.assertEqual(2, post.comments[1].id)
@@ -223,7 +227,7 @@ class TestSequenceField(MongoDBTestCase):
class Base(Document):
name = StringField()
counter = SequenceField()
meta = {'abstract': True}
meta = {"abstract": True}
class Foo(Base):
pass
@@ -231,24 +235,27 @@ class TestSequenceField(MongoDBTestCase):
class Bar(Base):
pass
bar = Bar(name='Bar')
bar = Bar(name="Bar")
bar.save()
foo = Foo(name='Foo')
foo = Foo(name="Foo")
foo.save()
self.assertTrue('base.counter' in
self.db['mongoengine.counters'].find().distinct('_id'))
self.assertFalse(('foo.counter' or 'bar.counter') in
self.db['mongoengine.counters'].find().distinct('_id'))
self.assertTrue(
"base.counter" in self.db["mongoengine.counters"].find().distinct("_id")
)
self.assertFalse(
("foo.counter" or "bar.counter")
in self.db["mongoengine.counters"].find().distinct("_id")
)
self.assertNotEqual(foo.counter, bar.counter)
self.assertEqual(foo._fields['counter'].owner_document, Base)
self.assertEqual(bar._fields['counter'].owner_document, Base)
self.assertEqual(foo._fields["counter"].owner_document, Base)
self.assertEqual(bar._fields["counter"].owner_document, Base)
def test_no_inherited_sequencefield(self):
class Base(Document):
name = StringField()
meta = {'abstract': True}
meta = {"abstract": True}
class Foo(Base):
counter = SequenceField()
@@ -256,16 +263,19 @@ class TestSequenceField(MongoDBTestCase):
class Bar(Base):
counter = SequenceField()
bar = Bar(name='Bar')
bar = Bar(name="Bar")
bar.save()
foo = Foo(name='Foo')
foo = Foo(name="Foo")
foo.save()
self.assertFalse('base.counter' in
self.db['mongoengine.counters'].find().distinct('_id'))
self.assertTrue(('foo.counter' and 'bar.counter') in
self.db['mongoengine.counters'].find().distinct('_id'))
self.assertFalse(
"base.counter" in self.db["mongoengine.counters"].find().distinct("_id")
)
self.assertTrue(
("foo.counter" and "bar.counter")
in self.db["mongoengine.counters"].find().distinct("_id")
)
self.assertEqual(foo.counter, bar.counter)
self.assertEqual(foo._fields['counter'].owner_document, Foo)
self.assertEqual(bar._fields['counter'].owner_document, Bar)
self.assertEqual(foo._fields["counter"].owner_document, Foo)
self.assertEqual(bar._fields["counter"].owner_document, Bar)

View File

@@ -5,49 +5,53 @@ from tests.utils import MongoDBTestCase
class TestURLField(MongoDBTestCase):
def test_validation(self):
"""Ensure that URLFields validate urls properly."""
class Link(Document):
url = URLField()
link = Link()
link.url = 'google'
link.url = "google"
self.assertRaises(ValidationError, link.validate)
link.url = 'http://www.google.com:8080'
link.url = "http://www.google.com:8080"
link.validate()
def test_unicode_url_validation(self):
"""Ensure unicode URLs are validated properly."""
class Link(Document):
url = URLField()
link = Link()
link.url = u'http://привет.com'
link.url = u"http://привет.com"
# TODO fix URL validation - this *IS* a valid URL
# For now we just want to make sure that the error message is correct
with self.assertRaises(ValidationError) as ctx_err:
link.validate()
self.assertEqual(unicode(ctx_err.exception),
u"ValidationError (Link:None) (Invalid URL: http://\u043f\u0440\u0438\u0432\u0435\u0442.com: ['url'])")
self.assertEqual(
unicode(ctx_err.exception),
u"ValidationError (Link:None) (Invalid URL: http://\u043f\u0440\u0438\u0432\u0435\u0442.com: ['url'])",
)
def test_url_scheme_validation(self):
"""Ensure that URLFields validate urls with specific schemes properly.
"""
class Link(Document):
url = URLField()
class SchemeLink(Document):
url = URLField(schemes=['ws', 'irc'])
url = URLField(schemes=["ws", "irc"])
link = Link()
link.url = 'ws://google.com'
link.url = "ws://google.com"
self.assertRaises(ValidationError, link.validate)
scheme_link = SchemeLink()
scheme_link.url = 'ws://google.com'
scheme_link.url = "ws://google.com"
scheme_link.validate()
def test_underscore_allowed_in_domains_names(self):
@@ -55,5 +59,5 @@ class TestURLField(MongoDBTestCase):
url = URLField()
link = Link()
link.url = 'https://san_leandro-ca.geebo.com'
link.url = "https://san_leandro-ca.geebo.com"
link.validate()

View File

@@ -15,11 +15,8 @@ class TestUUIDField(MongoDBTestCase):
uid = uuid.uuid4()
person = Person(api_key=uid).save()
self.assertEqual(
get_as_pymongo(person),
{'_id': person.id,
'api_key': str(uid)
}
)
get_as_pymongo(person), {"_id": person.id, "api_key": str(uid)}
)
def test_field_string(self):
"""Test UUID fields storing as String
@@ -37,8 +34,10 @@ class TestUUIDField(MongoDBTestCase):
person.api_key = api_key
person.validate()
invalid = ('9d159858-549b-4975-9f98-dd2f987c113g',
'9d159858-549b-4975-9f98-dd2f987c113')
invalid = (
"9d159858-549b-4975-9f98-dd2f987c113g",
"9d159858-549b-4975-9f98-dd2f987c113",
)
for api_key in invalid:
person.api_key = api_key
self.assertRaises(ValidationError, person.validate)
@@ -58,8 +57,10 @@ class TestUUIDField(MongoDBTestCase):
person.api_key = api_key
person.validate()
invalid = ('9d159858-549b-4975-9f98-dd2f987c113g',
'9d159858-549b-4975-9f98-dd2f987c113')
invalid = (
"9d159858-549b-4975-9f98-dd2f987c113g",
"9d159858-549b-4975-9f98-dd2f987c113",
)
for api_key in invalid:
person.api_key = api_key
self.assertRaises(ValidationError, person.validate)

View File

@@ -11,7 +11,7 @@ class PickleEmbedded(EmbeddedDocument):
class PickleTest(Document):
number = IntField()
string = StringField(choices=(('One', '1'), ('Two', '2')))
string = StringField(choices=(("One", "1"), ("Two", "2")))
embedded = EmbeddedDocumentField(PickleEmbedded)
lists = ListField(StringField())
photo = FileField()
@@ -19,7 +19,7 @@ class PickleTest(Document):
class NewDocumentPickleTest(Document):
number = IntField()
string = StringField(choices=(('One', '1'), ('Two', '2')))
string = StringField(choices=(("One", "1"), ("Two", "2")))
embedded = EmbeddedDocumentField(PickleEmbedded)
lists = ListField(StringField())
photo = FileField()
@@ -36,7 +36,7 @@ class PickleDynamicTest(DynamicDocument):
class PickleSignalsTest(Document):
number = IntField()
string = StringField(choices=(('One', '1'), ('Two', '2')))
string = StringField(choices=(("One", "1"), ("Two", "2")))
embedded = EmbeddedDocumentField(PickleEmbedded)
lists = ListField(StringField())
@@ -58,4 +58,4 @@ class Mixin(object):
class Base(Document):
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}

View File

@@ -7,79 +7,78 @@ __all__ = ("QueryFieldListTest", "OnlyExcludeAllTest")
class QueryFieldListTest(unittest.TestCase):
def test_empty(self):
q = QueryFieldList()
self.assertFalse(q)
q = QueryFieldList(always_include=['_cls'])
q = QueryFieldList(always_include=["_cls"])
self.assertFalse(q)
def test_include_include(self):
q = QueryFieldList()
q += QueryFieldList(fields=['a', 'b'], value=QueryFieldList.ONLY, _only_called=True)
self.assertEqual(q.as_dict(), {'a': 1, 'b': 1})
q += QueryFieldList(fields=['b', 'c'], value=QueryFieldList.ONLY)
self.assertEqual(q.as_dict(), {'a': 1, 'b': 1, 'c': 1})
q += QueryFieldList(
fields=["a", "b"], value=QueryFieldList.ONLY, _only_called=True
)
self.assertEqual(q.as_dict(), {"a": 1, "b": 1})
q += QueryFieldList(fields=["b", "c"], value=QueryFieldList.ONLY)
self.assertEqual(q.as_dict(), {"a": 1, "b": 1, "c": 1})
def test_include_exclude(self):
q = QueryFieldList()
q += QueryFieldList(fields=['a', 'b'], value=QueryFieldList.ONLY)
self.assertEqual(q.as_dict(), {'a': 1, 'b': 1})
q += QueryFieldList(fields=['b', 'c'], value=QueryFieldList.EXCLUDE)
self.assertEqual(q.as_dict(), {'a': 1})
q += QueryFieldList(fields=["a", "b"], value=QueryFieldList.ONLY)
self.assertEqual(q.as_dict(), {"a": 1, "b": 1})
q += QueryFieldList(fields=["b", "c"], value=QueryFieldList.EXCLUDE)
self.assertEqual(q.as_dict(), {"a": 1})
def test_exclude_exclude(self):
q = QueryFieldList()
q += QueryFieldList(fields=['a', 'b'], value=QueryFieldList.EXCLUDE)
self.assertEqual(q.as_dict(), {'a': 0, 'b': 0})
q += QueryFieldList(fields=['b', 'c'], value=QueryFieldList.EXCLUDE)
self.assertEqual(q.as_dict(), {'a': 0, 'b': 0, 'c': 0})
q += QueryFieldList(fields=["a", "b"], value=QueryFieldList.EXCLUDE)
self.assertEqual(q.as_dict(), {"a": 0, "b": 0})
q += QueryFieldList(fields=["b", "c"], value=QueryFieldList.EXCLUDE)
self.assertEqual(q.as_dict(), {"a": 0, "b": 0, "c": 0})
def test_exclude_include(self):
q = QueryFieldList()
q += QueryFieldList(fields=['a', 'b'], value=QueryFieldList.EXCLUDE)
self.assertEqual(q.as_dict(), {'a': 0, 'b': 0})
q += QueryFieldList(fields=['b', 'c'], value=QueryFieldList.ONLY)
self.assertEqual(q.as_dict(), {'c': 1})
q += QueryFieldList(fields=["a", "b"], value=QueryFieldList.EXCLUDE)
self.assertEqual(q.as_dict(), {"a": 0, "b": 0})
q += QueryFieldList(fields=["b", "c"], value=QueryFieldList.ONLY)
self.assertEqual(q.as_dict(), {"c": 1})
def test_always_include(self):
q = QueryFieldList(always_include=['x', 'y'])
q += QueryFieldList(fields=['a', 'b', 'x'], value=QueryFieldList.EXCLUDE)
q += QueryFieldList(fields=['b', 'c'], value=QueryFieldList.ONLY)
self.assertEqual(q.as_dict(), {'x': 1, 'y': 1, 'c': 1})
q = QueryFieldList(always_include=["x", "y"])
q += QueryFieldList(fields=["a", "b", "x"], value=QueryFieldList.EXCLUDE)
q += QueryFieldList(fields=["b", "c"], value=QueryFieldList.ONLY)
self.assertEqual(q.as_dict(), {"x": 1, "y": 1, "c": 1})
def test_reset(self):
q = QueryFieldList(always_include=['x', 'y'])
q += QueryFieldList(fields=['a', 'b', 'x'], value=QueryFieldList.EXCLUDE)
q += QueryFieldList(fields=['b', 'c'], value=QueryFieldList.ONLY)
self.assertEqual(q.as_dict(), {'x': 1, 'y': 1, 'c': 1})
q = QueryFieldList(always_include=["x", "y"])
q += QueryFieldList(fields=["a", "b", "x"], value=QueryFieldList.EXCLUDE)
q += QueryFieldList(fields=["b", "c"], value=QueryFieldList.ONLY)
self.assertEqual(q.as_dict(), {"x": 1, "y": 1, "c": 1})
q.reset()
self.assertFalse(q)
q += QueryFieldList(fields=['b', 'c'], value=QueryFieldList.ONLY)
self.assertEqual(q.as_dict(), {'x': 1, 'y': 1, 'b': 1, 'c': 1})
q += QueryFieldList(fields=["b", "c"], value=QueryFieldList.ONLY)
self.assertEqual(q.as_dict(), {"x": 1, "y": 1, "b": 1, "c": 1})
def test_using_a_slice(self):
q = QueryFieldList()
q += QueryFieldList(fields=['a'], value={"$slice": 5})
self.assertEqual(q.as_dict(), {'a': {"$slice": 5}})
q += QueryFieldList(fields=["a"], value={"$slice": 5})
self.assertEqual(q.as_dict(), {"a": {"$slice": 5}})
class OnlyExcludeAllTest(unittest.TestCase):
def setUp(self):
connect(db='mongoenginetest')
connect(db="mongoenginetest")
class Person(Document):
name = StringField()
age = IntField()
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
Person.drop_collection()
self.Person = Person
def test_mixing_only_exclude(self):
class MyDoc(Document):
a = StringField()
b = StringField()
@@ -88,32 +87,32 @@ class OnlyExcludeAllTest(unittest.TestCase):
e = StringField()
f = StringField()
include = ['a', 'b', 'c', 'd', 'e']
exclude = ['d', 'e']
only = ['b', 'c']
include = ["a", "b", "c", "d", "e"]
exclude = ["d", "e"]
only = ["b", "c"]
qs = MyDoc.objects.fields(**{i: 1 for i in include})
self.assertEqual(qs._loaded_fields.as_dict(),
{'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1})
self.assertEqual(
qs._loaded_fields.as_dict(), {"a": 1, "b": 1, "c": 1, "d": 1, "e": 1}
)
qs = qs.only(*only)
self.assertEqual(qs._loaded_fields.as_dict(), {'b': 1, 'c': 1})
self.assertEqual(qs._loaded_fields.as_dict(), {"b": 1, "c": 1})
qs = qs.exclude(*exclude)
self.assertEqual(qs._loaded_fields.as_dict(), {'b': 1, 'c': 1})
self.assertEqual(qs._loaded_fields.as_dict(), {"b": 1, "c": 1})
qs = MyDoc.objects.fields(**{i: 1 for i in include})
qs = qs.exclude(*exclude)
self.assertEqual(qs._loaded_fields.as_dict(), {'a': 1, 'b': 1, 'c': 1})
self.assertEqual(qs._loaded_fields.as_dict(), {"a": 1, "b": 1, "c": 1})
qs = qs.only(*only)
self.assertEqual(qs._loaded_fields.as_dict(), {'b': 1, 'c': 1})
self.assertEqual(qs._loaded_fields.as_dict(), {"b": 1, "c": 1})
qs = MyDoc.objects.exclude(*exclude)
qs = qs.fields(**{i: 1 for i in include})
self.assertEqual(qs._loaded_fields.as_dict(), {'a': 1, 'b': 1, 'c': 1})
self.assertEqual(qs._loaded_fields.as_dict(), {"a": 1, "b": 1, "c": 1})
qs = qs.only(*only)
self.assertEqual(qs._loaded_fields.as_dict(), {'b': 1, 'c': 1})
self.assertEqual(qs._loaded_fields.as_dict(), {"b": 1, "c": 1})
def test_slicing(self):
class MyDoc(Document):
a = ListField()
b = ListField()
@@ -122,24 +121,23 @@ class OnlyExcludeAllTest(unittest.TestCase):
e = ListField()
f = ListField()
include = ['a', 'b', 'c', 'd', 'e']
exclude = ['d', 'e']
only = ['b', 'c']
include = ["a", "b", "c", "d", "e"]
exclude = ["d", "e"]
only = ["b", "c"]
qs = MyDoc.objects.fields(**{i: 1 for i in include})
qs = qs.exclude(*exclude)
qs = qs.only(*only)
qs = qs.fields(slice__b=5)
self.assertEqual(qs._loaded_fields.as_dict(),
{'b': {'$slice': 5}, 'c': 1})
self.assertEqual(qs._loaded_fields.as_dict(), {"b": {"$slice": 5}, "c": 1})
qs = qs.fields(slice__c=[5, 1])
self.assertEqual(qs._loaded_fields.as_dict(),
{'b': {'$slice': 5}, 'c': {'$slice': [5, 1]}})
self.assertEqual(
qs._loaded_fields.as_dict(), {"b": {"$slice": 5}, "c": {"$slice": [5, 1]}}
)
qs = qs.exclude('c')
self.assertEqual(qs._loaded_fields.as_dict(),
{'b': {'$slice': 5}})
qs = qs.exclude("c")
self.assertEqual(qs._loaded_fields.as_dict(), {"b": {"$slice": 5}})
def test_mix_slice_with_other_fields(self):
class MyDoc(Document):
@@ -148,43 +146,42 @@ class OnlyExcludeAllTest(unittest.TestCase):
c = ListField()
qs = MyDoc.objects.fields(a=1, b=0, slice__c=2)
self.assertEqual(qs._loaded_fields.as_dict(),
{'c': {'$slice': 2}, 'a': 1})
self.assertEqual(qs._loaded_fields.as_dict(), {"c": {"$slice": 2}, "a": 1})
def test_only(self):
"""Ensure that QuerySet.only only returns the requested fields.
"""
person = self.Person(name='test', age=25)
person = self.Person(name="test", age=25)
person.save()
obj = self.Person.objects.only('name').get()
obj = self.Person.objects.only("name").get()
self.assertEqual(obj.name, person.name)
self.assertEqual(obj.age, None)
obj = self.Person.objects.only('age').get()
obj = self.Person.objects.only("age").get()
self.assertEqual(obj.name, None)
self.assertEqual(obj.age, person.age)
obj = self.Person.objects.only('name', 'age').get()
obj = self.Person.objects.only("name", "age").get()
self.assertEqual(obj.name, person.name)
self.assertEqual(obj.age, person.age)
obj = self.Person.objects.only(*('id', 'name',)).get()
obj = self.Person.objects.only(*("id", "name")).get()
self.assertEqual(obj.name, person.name)
self.assertEqual(obj.age, None)
# Check polymorphism still works
class Employee(self.Person):
salary = IntField(db_field='wage')
salary = IntField(db_field="wage")
employee = Employee(name='test employee', age=40, salary=30000)
employee = Employee(name="test employee", age=40, salary=30000)
employee.save()
obj = self.Person.objects(id=employee.id).only('age').get()
obj = self.Person.objects(id=employee.id).only("age").get()
self.assertIsInstance(obj, Employee)
# Check field names are looked up properly
obj = Employee.objects(id=employee.id).only('salary').get()
obj = Employee.objects(id=employee.id).only("salary").get()
self.assertEqual(obj.salary, employee.salary)
self.assertEqual(obj.name, None)
@@ -208,35 +205,41 @@ class OnlyExcludeAllTest(unittest.TestCase):
BlogPost.drop_collection()
post = BlogPost(content='Had a good coffee today...', various={'test_dynamic': {'some': True}})
post.author = User(name='Test User')
post.comments = [Comment(title='I aggree', text='Great post!'), Comment(title='Coffee', text='I hate coffee')]
post = BlogPost(
content="Had a good coffee today...",
various={"test_dynamic": {"some": True}},
)
post.author = User(name="Test User")
post.comments = [
Comment(title="I aggree", text="Great post!"),
Comment(title="Coffee", text="I hate coffee"),
]
post.save()
obj = BlogPost.objects.only('author.name',).get()
obj = BlogPost.objects.only("author.name").get()
self.assertEqual(obj.content, None)
self.assertEqual(obj.author.email, None)
self.assertEqual(obj.author.name, 'Test User')
self.assertEqual(obj.author.name, "Test User")
self.assertEqual(obj.comments, [])
obj = BlogPost.objects.only('various.test_dynamic.some').get()
obj = BlogPost.objects.only("various.test_dynamic.some").get()
self.assertEqual(obj.various["test_dynamic"].some, True)
obj = BlogPost.objects.only('content', 'comments.title',).get()
self.assertEqual(obj.content, 'Had a good coffee today...')
obj = BlogPost.objects.only("content", "comments.title").get()
self.assertEqual(obj.content, "Had a good coffee today...")
self.assertEqual(obj.author, None)
self.assertEqual(obj.comments[0].title, 'I aggree')
self.assertEqual(obj.comments[1].title, 'Coffee')
self.assertEqual(obj.comments[0].title, "I aggree")
self.assertEqual(obj.comments[1].title, "Coffee")
self.assertEqual(obj.comments[0].text, None)
self.assertEqual(obj.comments[1].text, None)
obj = BlogPost.objects.only('comments',).get()
obj = BlogPost.objects.only("comments").get()
self.assertEqual(obj.content, None)
self.assertEqual(obj.author, None)
self.assertEqual(obj.comments[0].title, 'I aggree')
self.assertEqual(obj.comments[1].title, 'Coffee')
self.assertEqual(obj.comments[0].text, 'Great post!')
self.assertEqual(obj.comments[1].text, 'I hate coffee')
self.assertEqual(obj.comments[0].title, "I aggree")
self.assertEqual(obj.comments[1].title, "Coffee")
self.assertEqual(obj.comments[0].text, "Great post!")
self.assertEqual(obj.comments[1].text, "I hate coffee")
BlogPost.drop_collection()
@@ -256,15 +259,18 @@ class OnlyExcludeAllTest(unittest.TestCase):
BlogPost.drop_collection()
post = BlogPost(content='Had a good coffee today...')
post.author = User(name='Test User')
post.comments = [Comment(title='I aggree', text='Great post!'), Comment(title='Coffee', text='I hate coffee')]
post = BlogPost(content="Had a good coffee today...")
post.author = User(name="Test User")
post.comments = [
Comment(title="I aggree", text="Great post!"),
Comment(title="Coffee", text="I hate coffee"),
]
post.save()
obj = BlogPost.objects.exclude('author', 'comments.text').get()
obj = BlogPost.objects.exclude("author", "comments.text").get()
self.assertEqual(obj.author, None)
self.assertEqual(obj.content, 'Had a good coffee today...')
self.assertEqual(obj.comments[0].title, 'I aggree')
self.assertEqual(obj.content, "Had a good coffee today...")
self.assertEqual(obj.comments[0].title, "I aggree")
self.assertEqual(obj.comments[0].text, None)
BlogPost.drop_collection()
@@ -283,32 +289,43 @@ class OnlyExcludeAllTest(unittest.TestCase):
attachments = ListField(EmbeddedDocumentField(Attachment))
Email.drop_collection()
email = Email(sender='me', to='you', subject='From Russia with Love', body='Hello!', content_type='text/plain')
email = Email(
sender="me",
to="you",
subject="From Russia with Love",
body="Hello!",
content_type="text/plain",
)
email.attachments = [
Attachment(name='file1.doc', content='ABC'),
Attachment(name='file2.doc', content='XYZ'),
Attachment(name="file1.doc", content="ABC"),
Attachment(name="file2.doc", content="XYZ"),
]
email.save()
obj = Email.objects.exclude('content_type').exclude('body').get()
self.assertEqual(obj.sender, 'me')
self.assertEqual(obj.to, 'you')
self.assertEqual(obj.subject, 'From Russia with Love')
obj = Email.objects.exclude("content_type").exclude("body").get()
self.assertEqual(obj.sender, "me")
self.assertEqual(obj.to, "you")
self.assertEqual(obj.subject, "From Russia with Love")
self.assertEqual(obj.body, None)
self.assertEqual(obj.content_type, None)
obj = Email.objects.only('sender', 'to').exclude('body', 'sender').get()
obj = Email.objects.only("sender", "to").exclude("body", "sender").get()
self.assertEqual(obj.sender, None)
self.assertEqual(obj.to, 'you')
self.assertEqual(obj.to, "you")
self.assertEqual(obj.subject, None)
self.assertEqual(obj.body, None)
self.assertEqual(obj.content_type, None)
obj = Email.objects.exclude('attachments.content').exclude('body').only('to', 'attachments.name').get()
self.assertEqual(obj.attachments[0].name, 'file1.doc')
obj = (
Email.objects.exclude("attachments.content")
.exclude("body")
.only("to", "attachments.name")
.get()
)
self.assertEqual(obj.attachments[0].name, "file1.doc")
self.assertEqual(obj.attachments[0].content, None)
self.assertEqual(obj.sender, None)
self.assertEqual(obj.to, 'you')
self.assertEqual(obj.to, "you")
self.assertEqual(obj.subject, None)
self.assertEqual(obj.body, None)
self.assertEqual(obj.content_type, None)
@@ -316,7 +333,6 @@ class OnlyExcludeAllTest(unittest.TestCase):
Email.drop_collection()
def test_all_fields(self):
class Email(Document):
sender = StringField()
to = StringField()
@@ -326,21 +342,33 @@ class OnlyExcludeAllTest(unittest.TestCase):
Email.drop_collection()
email = Email(sender='me', to='you', subject='From Russia with Love', body='Hello!', content_type='text/plain')
email = Email(
sender="me",
to="you",
subject="From Russia with Love",
body="Hello!",
content_type="text/plain",
)
email.save()
obj = Email.objects.exclude('content_type', 'body').only('to', 'body').all_fields().get()
self.assertEqual(obj.sender, 'me')
self.assertEqual(obj.to, 'you')
self.assertEqual(obj.subject, 'From Russia with Love')
self.assertEqual(obj.body, 'Hello!')
self.assertEqual(obj.content_type, 'text/plain')
obj = (
Email.objects.exclude("content_type", "body")
.only("to", "body")
.all_fields()
.get()
)
self.assertEqual(obj.sender, "me")
self.assertEqual(obj.to, "you")
self.assertEqual(obj.subject, "From Russia with Love")
self.assertEqual(obj.body, "Hello!")
self.assertEqual(obj.content_type, "text/plain")
Email.drop_collection()
def test_slicing_fields(self):
"""Ensure that query slicing an array works.
"""
class Numbers(Document):
n = ListField(IntField())
@@ -414,11 +442,10 @@ class OnlyExcludeAllTest(unittest.TestCase):
self.assertEqual(numbers.embedded.n, [-5, -4, -3, -2, -1])
def test_exclude_from_subclasses_docs(self):
class Base(Document):
username = StringField()
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
class Anon(Base):
anon = BooleanField()
@@ -436,5 +463,5 @@ class OnlyExcludeAllTest(unittest.TestCase):
self.assertRaises(LookUpError, Base.objects.exclude, "made_up")
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -10,9 +10,9 @@ __all__ = ("GeoQueriesTest",)
class GeoQueriesTest(MongoDBTestCase):
def _create_event_data(self, point_field_class=GeoPointField):
"""Create some sample data re-used in many of the tests below."""
class Event(Document):
title = StringField()
date = DateTimeField()
@@ -28,15 +28,18 @@ class GeoQueriesTest(MongoDBTestCase):
event1 = Event.objects.create(
title="Coltrane Motion @ Double Door",
date=datetime.datetime.now() - datetime.timedelta(days=1),
location=[-87.677137, 41.909889])
location=[-87.677137, 41.909889],
)
event2 = Event.objects.create(
title="Coltrane Motion @ Bottom of the Hill",
date=datetime.datetime.now() - datetime.timedelta(days=10),
location=[-122.4194155, 37.7749295])
location=[-122.4194155, 37.7749295],
)
event3 = Event.objects.create(
title="Coltrane Motion @ Empty Bottle",
date=datetime.datetime.now(),
location=[-87.686638, 41.900474])
location=[-87.686638, 41.900474],
)
return event1, event2, event3
@@ -65,8 +68,7 @@ class GeoQueriesTest(MongoDBTestCase):
# find events within 10 degrees of san francisco
point = [-122.415579, 37.7566023]
events = self.Event.objects(location__near=point,
location__max_distance=10)
events = self.Event.objects(location__near=point, location__max_distance=10)
self.assertEqual(events.count(), 1)
self.assertEqual(events[0], event2)
@@ -78,8 +80,7 @@ class GeoQueriesTest(MongoDBTestCase):
# find events at least 10 degrees away of san francisco
point = [-122.415579, 37.7566023]
events = self.Event.objects(location__near=point,
location__min_distance=10)
events = self.Event.objects(location__near=point, location__min_distance=10)
self.assertEqual(events.count(), 2)
def test_within_distance(self):
@@ -88,8 +89,7 @@ class GeoQueriesTest(MongoDBTestCase):
# find events within 5 degrees of pitchfork office, chicago
point_and_distance = [[-87.67892, 41.9120459], 5]
events = self.Event.objects(
location__within_distance=point_and_distance)
events = self.Event.objects(location__within_distance=point_and_distance)
self.assertEqual(events.count(), 2)
events = list(events)
self.assertNotIn(event2, events)
@@ -98,21 +98,18 @@ class GeoQueriesTest(MongoDBTestCase):
# find events within 10 degrees of san francisco
point_and_distance = [[-122.415579, 37.7566023], 10]
events = self.Event.objects(
location__within_distance=point_and_distance)
events = self.Event.objects(location__within_distance=point_and_distance)
self.assertEqual(events.count(), 1)
self.assertEqual(events[0], event2)
# find events within 1 degree of greenpoint, broolyn, nyc, ny
point_and_distance = [[-73.9509714, 40.7237134], 1]
events = self.Event.objects(
location__within_distance=point_and_distance)
events = self.Event.objects(location__within_distance=point_and_distance)
self.assertEqual(events.count(), 0)
# ensure ordering is respected by "within_distance"
point_and_distance = [[-87.67892, 41.9120459], 10]
events = self.Event.objects(
location__within_distance=point_and_distance)
events = self.Event.objects(location__within_distance=point_and_distance)
events = events.order_by("-date")
self.assertEqual(events.count(), 2)
self.assertEqual(events[0], event3)
@@ -145,7 +142,7 @@ class GeoQueriesTest(MongoDBTestCase):
polygon2 = [
(-1.742249, 54.033586),
(-1.225891, 52.792797),
(-4.40094, 53.389881)
(-4.40094, 53.389881),
]
events = self.Event.objects(location__within_polygon=polygon2)
self.assertEqual(events.count(), 0)
@@ -154,9 +151,7 @@ class GeoQueriesTest(MongoDBTestCase):
"""Make sure the "near" operator works with a PointField, which
corresponds to a 2dsphere index.
"""
event1, event2, event3 = self._create_event_data(
point_field_class=PointField
)
event1, event2, event3 = self._create_event_data(point_field_class=PointField)
# find all events "near" pitchfork office, chicago.
# note that "near" will show the san francisco event, too,
@@ -175,26 +170,23 @@ class GeoQueriesTest(MongoDBTestCase):
"""Ensure the "max_distance" operator works alongside the "near"
operator with a 2dsphere index.
"""
event1, event2, event3 = self._create_event_data(
point_field_class=PointField
)
event1, event2, event3 = self._create_event_data(point_field_class=PointField)
# find events within 10km of san francisco
point = [-122.415579, 37.7566023]
events = self.Event.objects(location__near=point,
location__max_distance=10000)
events = self.Event.objects(location__near=point, location__max_distance=10000)
self.assertEqual(events.count(), 1)
self.assertEqual(events[0], event2)
# find events within 1km of greenpoint, broolyn, nyc, ny
events = self.Event.objects(location__near=[-73.9509714, 40.7237134],
location__max_distance=1000)
events = self.Event.objects(
location__near=[-73.9509714, 40.7237134], location__max_distance=1000
)
self.assertEqual(events.count(), 0)
# ensure ordering is respected by "near"
events = self.Event.objects(
location__near=[-87.67892, 41.9120459],
location__max_distance=10000
location__near=[-87.67892, 41.9120459], location__max_distance=10000
).order_by("-date")
self.assertEqual(events.count(), 2)
self.assertEqual(events[0], event3)
@@ -203,9 +195,7 @@ class GeoQueriesTest(MongoDBTestCase):
"""Ensure the "geo_within_box" operator works with a 2dsphere
index.
"""
event1, event2, event3 = self._create_event_data(
point_field_class=PointField
)
event1, event2, event3 = self._create_event_data(point_field_class=PointField)
# check that within_box works
box = [(-125.0, 35.0), (-100.0, 40.0)]
@@ -217,9 +207,7 @@ class GeoQueriesTest(MongoDBTestCase):
"""Ensure the "geo_within_polygon" operator works with a
2dsphere index.
"""
event1, event2, event3 = self._create_event_data(
point_field_class=PointField
)
event1, event2, event3 = self._create_event_data(point_field_class=PointField)
polygon = [
(-87.694445, 41.912114),
@@ -235,7 +223,7 @@ class GeoQueriesTest(MongoDBTestCase):
polygon2 = [
(-1.742249, 54.033586),
(-1.225891, 52.792797),
(-4.40094, 53.389881)
(-4.40094, 53.389881),
]
events = self.Event.objects(location__geo_within_polygon=polygon2)
self.assertEqual(events.count(), 0)
@@ -244,23 +232,20 @@ class GeoQueriesTest(MongoDBTestCase):
"""Ensure "min_distace" and "max_distance" operators work well
together with the "near" operator in a 2dsphere index.
"""
event1, event2, event3 = self._create_event_data(
point_field_class=PointField
)
event1, event2, event3 = self._create_event_data(point_field_class=PointField)
# ensure min_distance and max_distance combine well
events = self.Event.objects(
location__near=[-87.67892, 41.9120459],
location__min_distance=1000,
location__max_distance=10000
location__max_distance=10000,
).order_by("-date")
self.assertEqual(events.count(), 1)
self.assertEqual(events[0], event3)
# ensure ordering is respected by "near" with "min_distance"
events = self.Event.objects(
location__near=[-87.67892, 41.9120459],
location__min_distance=10000
location__near=[-87.67892, 41.9120459], location__min_distance=10000
).order_by("-date")
self.assertEqual(events.count(), 1)
self.assertEqual(events[0], event2)
@@ -269,14 +254,11 @@ class GeoQueriesTest(MongoDBTestCase):
"""Make sure the "geo_within_center" operator works with a
2dsphere index.
"""
event1, event2, event3 = self._create_event_data(
point_field_class=PointField
)
event1, event2, event3 = self._create_event_data(point_field_class=PointField)
# find events within 5 degrees of pitchfork office, chicago
point_and_distance = [[-87.67892, 41.9120459], 2]
events = self.Event.objects(
location__geo_within_center=point_and_distance)
events = self.Event.objects(location__geo_within_center=point_and_distance)
self.assertEqual(events.count(), 2)
events = list(events)
self.assertNotIn(event2, events)
@@ -287,6 +269,7 @@ class GeoQueriesTest(MongoDBTestCase):
"""Helper test method ensuring given point field class works
well in an embedded document.
"""
class Venue(EmbeddedDocument):
location = point_field_class()
name = StringField()
@@ -300,12 +283,11 @@ class GeoQueriesTest(MongoDBTestCase):
venue1 = Venue(name="The Rock", location=[-87.677137, 41.909889])
venue2 = Venue(name="The Bridge", location=[-122.4194155, 37.7749295])
event1 = Event(title="Coltrane Motion @ Double Door",
venue=venue1).save()
event2 = Event(title="Coltrane Motion @ Bottom of the Hill",
venue=venue2).save()
event3 = Event(title="Coltrane Motion @ Empty Bottle",
venue=venue1).save()
event1 = Event(title="Coltrane Motion @ Double Door", venue=venue1).save()
event2 = Event(
title="Coltrane Motion @ Bottom of the Hill", venue=venue2
).save()
event3 = Event(title="Coltrane Motion @ Empty Bottle", venue=venue1).save()
# find all events "near" pitchfork office, chicago.
# note that "near" will show the san francisco event, too,
@@ -324,6 +306,7 @@ class GeoQueriesTest(MongoDBTestCase):
def test_spherical_geospatial_operators(self):
"""Ensure that spherical geospatial queries are working."""
class Point(Document):
location = GeoPointField()
@@ -343,26 +326,26 @@ class GeoQueriesTest(MongoDBTestCase):
# Same behavior for _within_spherical_distance
points = Point.objects(
location__within_spherical_distance=[
[-122, 37.5],
60 / earth_radius
]
location__within_spherical_distance=[[-122, 37.5], 60 / earth_radius]
)
self.assertEqual(points.count(), 2)
points = Point.objects(location__near_sphere=[-122, 37.5],
location__max_distance=60 / earth_radius)
points = Point.objects(
location__near_sphere=[-122, 37.5], location__max_distance=60 / earth_radius
)
self.assertEqual(points.count(), 2)
# Test query works with max_distance, being farer from one point
points = Point.objects(location__near_sphere=[-122, 37.8],
location__max_distance=60 / earth_radius)
points = Point.objects(
location__near_sphere=[-122, 37.8], location__max_distance=60 / earth_radius
)
close_point = points.first()
self.assertEqual(points.count(), 1)
# Test query works with min_distance, being farer from one point
points = Point.objects(location__near_sphere=[-122, 37.8],
location__min_distance=60 / earth_radius)
points = Point.objects(
location__near_sphere=[-122, 37.8], location__min_distance=60 / earth_radius
)
self.assertEqual(points.count(), 1)
far_point = points.first()
self.assertNotEqual(close_point, far_point)
@@ -384,10 +367,7 @@ class GeoQueriesTest(MongoDBTestCase):
# Finds only one point because only the first point is within 60km of
# the reference point to the south.
points = Point.objects(
location__within_spherical_distance=[
[-122, 36.5],
60 / earth_radius
]
location__within_spherical_distance=[[-122, 36.5], 60 / earth_radius]
)
self.assertEqual(points.count(), 1)
self.assertEqual(points[0].id, south_point.id)
@@ -413,8 +393,10 @@ class GeoQueriesTest(MongoDBTestCase):
self.assertEqual(1, roads)
# Within
polygon = {"type": "Polygon",
"coordinates": [[[40, 5], [40, 6], [41, 6], [41, 5], [40, 5]]]}
polygon = {
"type": "Polygon",
"coordinates": [[[40, 5], [40, 6], [41, 6], [41, 5], [40, 5]]],
}
roads = Road.objects.filter(line__geo_within=polygon["coordinates"]).count()
self.assertEqual(1, roads)
@@ -425,8 +407,7 @@ class GeoQueriesTest(MongoDBTestCase):
self.assertEqual(1, roads)
# Intersects
line = {"type": "LineString",
"coordinates": [[40, 5], [40, 6]]}
line = {"type": "LineString", "coordinates": [[40, 5], [40, 6]]}
roads = Road.objects.filter(line__geo_intersects=line["coordinates"]).count()
self.assertEqual(1, roads)
@@ -436,8 +417,10 @@ class GeoQueriesTest(MongoDBTestCase):
roads = Road.objects.filter(line__geo_intersects={"$geometry": line}).count()
self.assertEqual(1, roads)
polygon = {"type": "Polygon",
"coordinates": [[[40, 5], [40, 6], [41, 6], [41, 5], [40, 5]]]}
polygon = {
"type": "Polygon",
"coordinates": [[[40, 5], [40, 6], [41, 6], [41, 5], [40, 5]]],
}
roads = Road.objects.filter(line__geo_intersects=polygon["coordinates"]).count()
self.assertEqual(1, roads)
@@ -468,8 +451,10 @@ class GeoQueriesTest(MongoDBTestCase):
self.assertEqual(1, roads)
# Within
polygon = {"type": "Polygon",
"coordinates": [[[40, 5], [40, 6], [41, 6], [41, 5], [40, 5]]]}
polygon = {
"type": "Polygon",
"coordinates": [[[40, 5], [40, 6], [41, 6], [41, 5], [40, 5]]],
}
roads = Road.objects.filter(poly__geo_within=polygon["coordinates"]).count()
self.assertEqual(1, roads)
@@ -480,8 +465,7 @@ class GeoQueriesTest(MongoDBTestCase):
self.assertEqual(1, roads)
# Intersects
line = {"type": "LineString",
"coordinates": [[40, 5], [41, 6]]}
line = {"type": "LineString", "coordinates": [[40, 5], [41, 6]]}
roads = Road.objects.filter(poly__geo_intersects=line["coordinates"]).count()
self.assertEqual(1, roads)
@@ -491,8 +475,10 @@ class GeoQueriesTest(MongoDBTestCase):
roads = Road.objects.filter(poly__geo_intersects={"$geometry": line}).count()
self.assertEqual(1, roads)
polygon = {"type": "Polygon",
"coordinates": [[[40, 5], [40, 6], [41, 6], [41, 5], [40, 5]]]}
polygon = {
"type": "Polygon",
"coordinates": [[[40, 5], [40, 6], [41, 6], [41, 5], [40, 5]]],
}
roads = Road.objects.filter(poly__geo_intersects=polygon["coordinates"]).count()
self.assertEqual(1, roads)
@@ -504,20 +490,20 @@ class GeoQueriesTest(MongoDBTestCase):
def test_aspymongo_with_only(self):
"""Ensure as_pymongo works with only"""
class Place(Document):
location = PointField()
Place.drop_collection()
p = Place(location=[24.946861267089844, 60.16311983618494])
p.save()
qs = Place.objects().only('location')
qs = Place.objects().only("location")
self.assertDictEqual(
qs.as_pymongo()[0]['location'],
{u'type': u'Point',
u'coordinates': [
24.946861267089844,
60.16311983618494]
}
qs.as_pymongo()[0]["location"],
{
u"type": u"Point",
u"coordinates": [24.946861267089844, 60.16311983618494],
},
)
def test_2dsphere_point_sets_correctly(self):
@@ -542,11 +528,15 @@ class GeoQueriesTest(MongoDBTestCase):
Location(line=[[1, 2], [2, 2]]).save()
loc = Location.objects.as_pymongo()[0]
self.assertEqual(loc["line"], {"type": "LineString", "coordinates": [[1, 2], [2, 2]]})
self.assertEqual(
loc["line"], {"type": "LineString", "coordinates": [[1, 2], [2, 2]]}
)
Location.objects.update(set__line=[[2, 1], [1, 2]])
loc = Location.objects.as_pymongo()[0]
self.assertEqual(loc["line"], {"type": "LineString", "coordinates": [[2, 1], [1, 2]]})
self.assertEqual(
loc["line"], {"type": "LineString", "coordinates": [[2, 1], [1, 2]]}
)
def test_geojson_PolygonField(self):
class Location(Document):
@@ -556,12 +546,18 @@ class GeoQueriesTest(MongoDBTestCase):
Location(poly=[[[40, 5], [40, 6], [41, 6], [40, 5]]]).save()
loc = Location.objects.as_pymongo()[0]
self.assertEqual(loc["poly"], {"type": "Polygon", "coordinates": [[[40, 5], [40, 6], [41, 6], [40, 5]]]})
self.assertEqual(
loc["poly"],
{"type": "Polygon", "coordinates": [[[40, 5], [40, 6], [41, 6], [40, 5]]]},
)
Location.objects.update(set__poly=[[[40, 4], [40, 6], [41, 6], [40, 4]]])
loc = Location.objects.as_pymongo()[0]
self.assertEqual(loc["poly"], {"type": "Polygon", "coordinates": [[[40, 4], [40, 6], [41, 6], [40, 4]]]})
self.assertEqual(
loc["poly"],
{"type": "Polygon", "coordinates": [[[40, 4], [40, 6], [41, 6], [40, 4]]]},
)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -11,7 +11,6 @@ class Doc(Document):
class FindAndModifyTest(unittest.TestCase):
def setUp(self):
connect(db="mongoenginetest")
Doc.drop_collection()
@@ -82,9 +81,14 @@ class FindAndModifyTest(unittest.TestCase):
old_doc = Doc.objects().order_by("-id").modify(set__value=-1)
self.assertEqual(old_doc.to_json(), doc.to_json())
self.assertDbEqual([
{"_id": 0, "value": 3}, {"_id": 1, "value": 2},
{"_id": 2, "value": 1}, {"_id": 3, "value": -1}])
self.assertDbEqual(
[
{"_id": 0, "value": 3},
{"_id": 1, "value": 2},
{"_id": 2, "value": 1},
{"_id": 3, "value": -1},
]
)
def test_modify_with_fields(self):
Doc(id=0, value=0).save()
@@ -103,27 +107,25 @@ class FindAndModifyTest(unittest.TestCase):
blog = BlogPost.objects.create()
# Push a new tag via modify with new=False (default).
BlogPost(id=blog.id).modify(push__tags='code')
BlogPost(id=blog.id).modify(push__tags="code")
self.assertEqual(blog.tags, [])
blog.reload()
self.assertEqual(blog.tags, ['code'])
self.assertEqual(blog.tags, ["code"])
# Push a new tag via modify with new=True.
blog = BlogPost.objects(id=blog.id).modify(push__tags='java', new=True)
self.assertEqual(blog.tags, ['code', 'java'])
blog = BlogPost.objects(id=blog.id).modify(push__tags="java", new=True)
self.assertEqual(blog.tags, ["code", "java"])
# Push a new tag with a positional argument.
blog = BlogPost.objects(id=blog.id).modify(
push__tags__0='python',
new=True)
self.assertEqual(blog.tags, ['python', 'code', 'java'])
blog = BlogPost.objects(id=blog.id).modify(push__tags__0="python", new=True)
self.assertEqual(blog.tags, ["python", "code", "java"])
# Push multiple new tags with a positional argument.
blog = BlogPost.objects(id=blog.id).modify(
push__tags__1=['go', 'rust'],
new=True)
self.assertEqual(blog.tags, ['python', 'go', 'rust', 'code', 'java'])
push__tags__1=["go", "rust"], new=True
)
self.assertEqual(blog.tags, ["python", "go", "rust", "code", "java"])
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -4,7 +4,7 @@ from pymongo.mongo_client import MongoClient
from mongoengine import Document, StringField, IntField
from mongoengine.connection import connect
__author__ = 'stas'
__author__ = "stas"
class Person(Document):
@@ -17,6 +17,7 @@ class TestQuerysetPickable(unittest.TestCase):
Test for adding pickling support for QuerySet instances
See issue https://github.com/MongoEngine/mongoengine/issues/442
"""
def setUp(self):
super(TestQuerysetPickable, self).setUp()
@@ -24,10 +25,7 @@ class TestQuerysetPickable(unittest.TestCase):
connection.drop_database("test")
self.john = Person.objects.create(
name="John",
age=21
)
self.john = Person.objects.create(name="John", age=21)
def test_picke_simple_qs(self):
@@ -54,15 +52,9 @@ class TestQuerysetPickable(unittest.TestCase):
self.assertEqual(Person.objects.first().age, 23)
def test_pickle_support_filtration(self):
Person.objects.create(
name="Alice",
age=22
)
Person.objects.create(name="Alice", age=22)
Person.objects.create(
name="Bob",
age=23
)
Person.objects.create(name="Bob", age=23)
qs = Person.objects.filter(age__gte=22)
self.assertEqual(qs.count(), 2)
@@ -71,9 +63,3 @@ class TestQuerysetPickable(unittest.TestCase):
self.assertEqual(loaded.count(), 2)
self.assertEqual(loaded.filter(name="Bob").first().age, 23)

File diff suppressed because it is too large Load Diff

View File

@@ -9,25 +9,29 @@ __all__ = ("TransformTest",)
class TransformTest(unittest.TestCase):
def setUp(self):
connect(db='mongoenginetest')
connect(db="mongoenginetest")
def test_transform_query(self):
"""Ensure that the _transform_query function operates correctly.
"""
self.assertEqual(transform.query(name='test', age=30),
{'name': 'test', 'age': 30})
self.assertEqual(transform.query(age__lt=30),
{'age': {'$lt': 30}})
self.assertEqual(transform.query(age__gt=20, age__lt=50),
{'age': {'$gt': 20, '$lt': 50}})
self.assertEqual(transform.query(age=20, age__gt=50),
{'$and': [{'age': {'$gt': 50}}, {'age': 20}]})
self.assertEqual(transform.query(friend__age__gte=30),
{'friend.age': {'$gte': 30}})
self.assertEqual(transform.query(name__exists=True),
{'name': {'$exists': True}})
self.assertEqual(
transform.query(name="test", age=30), {"name": "test", "age": 30}
)
self.assertEqual(transform.query(age__lt=30), {"age": {"$lt": 30}})
self.assertEqual(
transform.query(age__gt=20, age__lt=50), {"age": {"$gt": 20, "$lt": 50}}
)
self.assertEqual(
transform.query(age=20, age__gt=50),
{"$and": [{"age": {"$gt": 50}}, {"age": 20}]},
)
self.assertEqual(
transform.query(friend__age__gte=30), {"friend.age": {"$gte": 30}}
)
self.assertEqual(
transform.query(name__exists=True), {"name": {"$exists": True}}
)
def test_transform_update(self):
class LisDoc(Document):
@@ -46,7 +50,11 @@ class TransformTest(unittest.TestCase):
DicDoc().save()
doc = Doc().save()
for k, v in (("set", "$set"), ("set_on_insert", "$setOnInsert"), ("push", "$push")):
for k, v in (
("set", "$set"),
("set_on_insert", "$setOnInsert"),
("push", "$push"),
):
update = transform.update(DicDoc, **{"%s__dictField__test" % k: doc})
self.assertIsInstance(update[v]["dictField.test"], dict)
@@ -57,55 +65,61 @@ class TransformTest(unittest.TestCase):
update = transform.update(DicDoc, pull__dictField__test=doc)
self.assertIsInstance(update["$pull"]["dictField"]["test"], dict)
update = transform.update(LisDoc, pull__foo__in=['a'])
self.assertEqual(update, {'$pull': {'foo': {'$in': ['a']}}})
update = transform.update(LisDoc, pull__foo__in=["a"])
self.assertEqual(update, {"$pull": {"foo": {"$in": ["a"]}}})
def test_transform_update_push(self):
"""Ensure the differences in behvaior between 'push' and 'push_all'"""
class BlogPost(Document):
tags = ListField(StringField())
update = transform.update(BlogPost, push__tags=['mongo', 'db'])
self.assertEqual(update, {'$push': {'tags': ['mongo', 'db']}})
update = transform.update(BlogPost, push__tags=["mongo", "db"])
self.assertEqual(update, {"$push": {"tags": ["mongo", "db"]}})
update = transform.update(BlogPost, push_all__tags=['mongo', 'db'])
self.assertEqual(update, {'$push': {'tags': {'$each': ['mongo', 'db']}}})
update = transform.update(BlogPost, push_all__tags=["mongo", "db"])
self.assertEqual(update, {"$push": {"tags": {"$each": ["mongo", "db"]}}})
def test_transform_update_no_operator_default_to_set(self):
"""Ensure the differences in behvaior between 'push' and 'push_all'"""
class BlogPost(Document):
tags = ListField(StringField())
update = transform.update(BlogPost, tags=['mongo', 'db'])
self.assertEqual(update, {'$set': {'tags': ['mongo', 'db']}})
update = transform.update(BlogPost, tags=["mongo", "db"])
self.assertEqual(update, {"$set": {"tags": ["mongo", "db"]}})
def test_query_field_name(self):
"""Ensure that the correct field name is used when querying.
"""
class Comment(EmbeddedDocument):
content = StringField(db_field='commentContent')
content = StringField(db_field="commentContent")
class BlogPost(Document):
title = StringField(db_field='postTitle')
comments = ListField(EmbeddedDocumentField(Comment),
db_field='postComments')
title = StringField(db_field="postTitle")
comments = ListField(
EmbeddedDocumentField(Comment), db_field="postComments"
)
BlogPost.drop_collection()
data = {'title': 'Post 1', 'comments': [Comment(content='test')]}
data = {"title": "Post 1", "comments": [Comment(content="test")]}
post = BlogPost(**data)
post.save()
self.assertIn('postTitle', BlogPost.objects(title=data['title'])._query)
self.assertFalse('title' in
BlogPost.objects(title=data['title'])._query)
self.assertEqual(BlogPost.objects(title=data['title']).count(), 1)
self.assertIn("postTitle", BlogPost.objects(title=data["title"])._query)
self.assertFalse("title" in BlogPost.objects(title=data["title"])._query)
self.assertEqual(BlogPost.objects(title=data["title"]).count(), 1)
self.assertIn('_id', BlogPost.objects(pk=post.id)._query)
self.assertIn("_id", BlogPost.objects(pk=post.id)._query)
self.assertEqual(BlogPost.objects(pk=post.id).count(), 1)
self.assertIn('postComments.commentContent', BlogPost.objects(comments__content='test')._query)
self.assertEqual(BlogPost.objects(comments__content='test').count(), 1)
self.assertIn(
"postComments.commentContent",
BlogPost.objects(comments__content="test")._query,
)
self.assertEqual(BlogPost.objects(comments__content="test").count(), 1)
BlogPost.drop_collection()
@@ -113,18 +127,19 @@ class TransformTest(unittest.TestCase):
"""Ensure that the correct "primary key" field name is used when
querying
"""
class BlogPost(Document):
title = StringField(primary_key=True, db_field='postTitle')
title = StringField(primary_key=True, db_field="postTitle")
BlogPost.drop_collection()
data = {'title': 'Post 1'}
data = {"title": "Post 1"}
post = BlogPost(**data)
post.save()
self.assertIn('_id', BlogPost.objects(pk=data['title'])._query)
self.assertIn('_id', BlogPost.objects(title=data['title'])._query)
self.assertEqual(BlogPost.objects(pk=data['title']).count(), 1)
self.assertIn("_id", BlogPost.objects(pk=data["title"])._query)
self.assertIn("_id", BlogPost.objects(title=data["title"])._query)
self.assertEqual(BlogPost.objects(pk=data["title"]).count(), 1)
BlogPost.drop_collection()
@@ -156,78 +171,125 @@ class TransformTest(unittest.TestCase):
"""
Test raw plays nicely
"""
class Foo(Document):
name = StringField()
a = StringField()
b = StringField()
c = StringField()
meta = {
'allow_inheritance': False
}
meta = {"allow_inheritance": False}
query = Foo.objects(__raw__={'$nor': [{'name': 'bar'}]})._query
self.assertEqual(query, {'$nor': [{'name': 'bar'}]})
query = Foo.objects(__raw__={"$nor": [{"name": "bar"}]})._query
self.assertEqual(query, {"$nor": [{"name": "bar"}]})
q1 = {'$or': [{'a': 1}, {'b': 1}]}
q1 = {"$or": [{"a": 1}, {"b": 1}]}
query = Foo.objects(Q(__raw__=q1) & Q(c=1))._query
self.assertEqual(query, {'$or': [{'a': 1}, {'b': 1}], 'c': 1})
self.assertEqual(query, {"$or": [{"a": 1}, {"b": 1}], "c": 1})
def test_raw_and_merging(self):
class Doc(Document):
meta = {'allow_inheritance': False}
meta = {"allow_inheritance": False}
raw_query = Doc.objects(__raw__={
'deleted': False,
'scraped': 'yes',
'$nor': [
{'views.extracted': 'no'},
{'attachments.views.extracted': 'no'}
]
})._query
raw_query = Doc.objects(
__raw__={
"deleted": False,
"scraped": "yes",
"$nor": [
{"views.extracted": "no"},
{"attachments.views.extracted": "no"},
],
}
)._query
self.assertEqual(raw_query, {
'deleted': False,
'scraped': 'yes',
'$nor': [
{'views.extracted': 'no'},
{'attachments.views.extracted': 'no'}
]
})
self.assertEqual(
raw_query,
{
"deleted": False,
"scraped": "yes",
"$nor": [
{"views.extracted": "no"},
{"attachments.views.extracted": "no"},
],
},
)
def test_geojson_PointField(self):
class Location(Document):
loc = PointField()
update = transform.update(Location, set__loc=[1, 2])
self.assertEqual(update, {'$set': {'loc': {"type": "Point", "coordinates": [1, 2]}}})
self.assertEqual(
update, {"$set": {"loc": {"type": "Point", "coordinates": [1, 2]}}}
)
update = transform.update(Location, set__loc={"type": "Point", "coordinates": [1, 2]})
self.assertEqual(update, {'$set': {'loc': {"type": "Point", "coordinates": [1, 2]}}})
update = transform.update(
Location, set__loc={"type": "Point", "coordinates": [1, 2]}
)
self.assertEqual(
update, {"$set": {"loc": {"type": "Point", "coordinates": [1, 2]}}}
)
def test_geojson_LineStringField(self):
class Location(Document):
line = LineStringField()
update = transform.update(Location, set__line=[[1, 2], [2, 2]])
self.assertEqual(update, {'$set': {'line': {"type": "LineString", "coordinates": [[1, 2], [2, 2]]}}})
self.assertEqual(
update,
{"$set": {"line": {"type": "LineString", "coordinates": [[1, 2], [2, 2]]}}},
)
update = transform.update(Location, set__line={"type": "LineString", "coordinates": [[1, 2], [2, 2]]})
self.assertEqual(update, {'$set': {'line': {"type": "LineString", "coordinates": [[1, 2], [2, 2]]}}})
update = transform.update(
Location, set__line={"type": "LineString", "coordinates": [[1, 2], [2, 2]]}
)
self.assertEqual(
update,
{"$set": {"line": {"type": "LineString", "coordinates": [[1, 2], [2, 2]]}}},
)
def test_geojson_PolygonField(self):
class Location(Document):
poly = PolygonField()
update = transform.update(Location, set__poly=[[[40, 5], [40, 6], [41, 6], [40, 5]]])
self.assertEqual(update, {'$set': {'poly': {"type": "Polygon", "coordinates": [[[40, 5], [40, 6], [41, 6], [40, 5]]]}}})
update = transform.update(
Location, set__poly=[[[40, 5], [40, 6], [41, 6], [40, 5]]]
)
self.assertEqual(
update,
{
"$set": {
"poly": {
"type": "Polygon",
"coordinates": [[[40, 5], [40, 6], [41, 6], [40, 5]]],
}
}
},
)
update = transform.update(Location, set__poly={"type": "Polygon", "coordinates": [[[40, 5], [40, 6], [41, 6], [40, 5]]]})
self.assertEqual(update, {'$set': {'poly': {"type": "Polygon", "coordinates": [[[40, 5], [40, 6], [41, 6], [40, 5]]]}}})
update = transform.update(
Location,
set__poly={
"type": "Polygon",
"coordinates": [[[40, 5], [40, 6], [41, 6], [40, 5]]],
},
)
self.assertEqual(
update,
{
"$set": {
"poly": {
"type": "Polygon",
"coordinates": [[[40, 5], [40, 6], [41, 6], [40, 5]]],
}
}
},
)
def test_type(self):
class Doc(Document):
df = DynamicField()
Doc(df=True).save()
Doc(df=7).save()
Doc(df="df").save()
@@ -252,7 +314,7 @@ class TransformTest(unittest.TestCase):
self.assertEqual(1, Doc.objects(item__type__="axe").count())
self.assertEqual(1, Doc.objects(item__name__="Heroic axe").count())
Doc.objects(id=doc.id).update(set__item__type__='sword')
Doc.objects(id=doc.id).update(set__item__type__="sword")
self.assertEqual(1, Doc.objects(item__type__="sword").count())
self.assertEqual(0, Doc.objects(item__type__="axe").count())
@@ -272,6 +334,7 @@ class TransformTest(unittest.TestCase):
Test added to check pull operation in update for
EmbeddedDocumentListField which is inside a EmbeddedDocumentField
"""
class Word(EmbeddedDocument):
word = StringField()
index = IntField()
@@ -284,18 +347,27 @@ class TransformTest(unittest.TestCase):
title = StringField()
content = EmbeddedDocumentField(SubDoc)
word = Word(word='abc', index=1)
word = Word(word="abc", index=1)
update = transform.update(MainDoc, pull__content__text=word)
self.assertEqual(update, {'$pull': {'content.text': SON([('word', u'abc'), ('index', 1)])}})
self.assertEqual(
update, {"$pull": {"content.text": SON([("word", u"abc"), ("index", 1)])}}
)
update = transform.update(MainDoc, pull__content__heading='xyz')
self.assertEqual(update, {'$pull': {'content.heading': 'xyz'}})
update = transform.update(MainDoc, pull__content__heading="xyz")
self.assertEqual(update, {"$pull": {"content.heading": "xyz"}})
update = transform.update(MainDoc, pull__content__text__word__in=['foo', 'bar'])
self.assertEqual(update, {'$pull': {'content.text': {'word': {'$in': ['foo', 'bar']}}}})
update = transform.update(MainDoc, pull__content__text__word__in=["foo", "bar"])
self.assertEqual(
update, {"$pull": {"content.text": {"word": {"$in": ["foo", "bar"]}}}}
)
update = transform.update(MainDoc, pull__content__text__word__nin=['foo', 'bar'])
self.assertEqual(update, {'$pull': {'content.text': {'word': {'$nin': ['foo', 'bar']}}}})
update = transform.update(
MainDoc, pull__content__text__word__nin=["foo", "bar"]
)
self.assertEqual(
update, {"$pull": {"content.text": {"word": {"$nin": ["foo", "bar"]}}}}
)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -12,14 +12,13 @@ __all__ = ("QTest",)
class QTest(unittest.TestCase):
def setUp(self):
connect(db='mongoenginetest')
connect(db="mongoenginetest")
class Person(Document):
name = StringField()
age = IntField()
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
Person.drop_collection()
self.Person = Person
@@ -30,22 +29,22 @@ class QTest(unittest.TestCase):
q1 = Q()
q2 = Q(age__gte=18)
q3 = Q()
q4 = Q(name='test')
q4 = Q(name="test")
q5 = Q()
class Person(Document):
name = StringField()
age = IntField()
query = {'$or': [{'age': {'$gte': 18}}, {'name': 'test'}]}
query = {"$or": [{"age": {"$gte": 18}}, {"name": "test"}]}
self.assertEqual((q1 | q2 | q3 | q4 | q5).to_query(Person), query)
query = {'age': {'$gte': 18}, 'name': 'test'}
query = {"age": {"$gte": 18}, "name": "test"}
self.assertEqual((q1 & q2 & q3 & q4 & q5).to_query(Person), query)
def test_q_with_dbref(self):
"""Ensure Q objects handle DBRefs correctly"""
connect(db='mongoenginetest')
connect(db="mongoenginetest")
class User(Document):
pass
@@ -62,15 +61,18 @@ class QTest(unittest.TestCase):
def test_and_combination(self):
"""Ensure that Q-objects correctly AND together.
"""
class TestDoc(Document):
x = IntField()
y = StringField()
query = (Q(x__lt=7) & Q(x__lt=3)).to_query(TestDoc)
self.assertEqual(query, {'$and': [{'x': {'$lt': 7}}, {'x': {'$lt': 3}}]})
self.assertEqual(query, {"$and": [{"x": {"$lt": 7}}, {"x": {"$lt": 3}}]})
query = (Q(y="a") & Q(x__lt=7) & Q(x__lt=3)).to_query(TestDoc)
self.assertEqual(query, {'$and': [{'y': "a"}, {'x': {'$lt': 7}}, {'x': {'$lt': 3}}]})
self.assertEqual(
query, {"$and": [{"y": "a"}, {"x": {"$lt": 7}}, {"x": {"$lt": 3}}]}
)
# Check normal cases work without an error
query = Q(x__lt=7) & Q(x__gt=3)
@@ -78,69 +80,74 @@ class QTest(unittest.TestCase):
q1 = Q(x__lt=7)
q2 = Q(x__gt=3)
query = (q1 & q2).to_query(TestDoc)
self.assertEqual(query, {'x': {'$lt': 7, '$gt': 3}})
self.assertEqual(query, {"x": {"$lt": 7, "$gt": 3}})
# More complex nested example
query = Q(x__lt=100) & Q(y__ne='NotMyString')
query &= Q(y__in=['a', 'b', 'c']) & Q(x__gt=-100)
query = Q(x__lt=100) & Q(y__ne="NotMyString")
query &= Q(y__in=["a", "b", "c"]) & Q(x__gt=-100)
mongo_query = {
'x': {'$lt': 100, '$gt': -100},
'y': {'$ne': 'NotMyString', '$in': ['a', 'b', 'c']},
"x": {"$lt": 100, "$gt": -100},
"y": {"$ne": "NotMyString", "$in": ["a", "b", "c"]},
}
self.assertEqual(query.to_query(TestDoc), mongo_query)
def test_or_combination(self):
"""Ensure that Q-objects correctly OR together.
"""
class TestDoc(Document):
x = IntField()
q1 = Q(x__lt=3)
q2 = Q(x__gt=7)
query = (q1 | q2).to_query(TestDoc)
self.assertEqual(query, {
'$or': [
{'x': {'$lt': 3}},
{'x': {'$gt': 7}},
]
})
self.assertEqual(query, {"$or": [{"x": {"$lt": 3}}, {"x": {"$gt": 7}}]})
def test_and_or_combination(self):
"""Ensure that Q-objects handle ANDing ORed components.
"""
class TestDoc(Document):
x = IntField()
y = BooleanField()
TestDoc.drop_collection()
query = (Q(x__gt=0) | Q(x__exists=False))
query = Q(x__gt=0) | Q(x__exists=False)
query &= Q(x__lt=100)
self.assertEqual(query.to_query(TestDoc), {'$and': [
{'$or': [{'x': {'$gt': 0}},
{'x': {'$exists': False}}]},
{'x': {'$lt': 100}}]
})
self.assertEqual(
query.to_query(TestDoc),
{
"$and": [
{"$or": [{"x": {"$gt": 0}}, {"x": {"$exists": False}}]},
{"x": {"$lt": 100}},
]
},
)
q1 = (Q(x__gt=0) | Q(x__exists=False))
q2 = (Q(x__lt=100) | Q(y=True))
q1 = Q(x__gt=0) | Q(x__exists=False)
q2 = Q(x__lt=100) | Q(y=True)
query = (q1 & q2).to_query(TestDoc)
TestDoc(x=101).save()
TestDoc(x=10).save()
TestDoc(y=True).save()
self.assertEqual(query, {
'$and': [
{'$or': [{'x': {'$gt': 0}}, {'x': {'$exists': False}}]},
{'$or': [{'x': {'$lt': 100}}, {'y': True}]}
]
})
self.assertEqual(
query,
{
"$and": [
{"$or": [{"x": {"$gt": 0}}, {"x": {"$exists": False}}]},
{"$or": [{"x": {"$lt": 100}}, {"y": True}]},
]
},
)
self.assertEqual(2, TestDoc.objects(q1 & q2).count())
def test_or_and_or_combination(self):
"""Ensure that Q-objects handle ORing ANDed ORed components. :)
"""
class TestDoc(Document):
x = IntField()
y = BooleanField()
@@ -151,18 +158,29 @@ class QTest(unittest.TestCase):
TestDoc(x=99, y=False).save()
TestDoc(x=101, y=False).save()
q1 = (Q(x__gt=0) & (Q(y=True) | Q(y__exists=False)))
q2 = (Q(x__lt=100) & (Q(y=False) | Q(y__exists=False)))
q1 = Q(x__gt=0) & (Q(y=True) | Q(y__exists=False))
q2 = Q(x__lt=100) & (Q(y=False) | Q(y__exists=False))
query = (q1 | q2).to_query(TestDoc)
self.assertEqual(query, {
'$or': [
{'$and': [{'x': {'$gt': 0}},
{'$or': [{'y': True}, {'y': {'$exists': False}}]}]},
{'$and': [{'x': {'$lt': 100}},
{'$or': [{'y': False}, {'y': {'$exists': False}}]}]}
]
})
self.assertEqual(
query,
{
"$or": [
{
"$and": [
{"x": {"$gt": 0}},
{"$or": [{"y": True}, {"y": {"$exists": False}}]},
]
},
{
"$and": [
{"x": {"$lt": 100}},
{"$or": [{"y": False}, {"y": {"$exists": False}}]},
]
},
]
},
)
self.assertEqual(2, TestDoc.objects(q1 | q2).count())
def test_multiple_occurence_in_field(self):
@@ -170,8 +188,8 @@ class QTest(unittest.TestCase):
name = StringField(max_length=40)
title = StringField(max_length=40)
q1 = Q(name__contains='te') | Q(title__contains='te')
q2 = Q(name__contains='12') | Q(title__contains='12')
q1 = Q(name__contains="te") | Q(title__contains="te")
q2 = Q(name__contains="12") | Q(title__contains="12")
q3 = q1 & q2
@@ -180,7 +198,6 @@ class QTest(unittest.TestCase):
self.assertEqual(query["$and"][1], q2.to_query(Test))
def test_q_clone(self):
class TestDoc(Document):
x = IntField()
@@ -205,6 +222,7 @@ class QTest(unittest.TestCase):
def test_q(self):
"""Ensure that Q objects may be used to query for documents.
"""
class BlogPost(Document):
title = StringField()
publish_date = DateTimeField()
@@ -212,22 +230,26 @@ class QTest(unittest.TestCase):
BlogPost.drop_collection()
post1 = BlogPost(title='Test 1', publish_date=datetime.datetime(2010, 1, 8), published=False)
post1 = BlogPost(
title="Test 1", publish_date=datetime.datetime(2010, 1, 8), published=False
)
post1.save()
post2 = BlogPost(title='Test 2', publish_date=datetime.datetime(2010, 1, 15), published=True)
post2 = BlogPost(
title="Test 2", publish_date=datetime.datetime(2010, 1, 15), published=True
)
post2.save()
post3 = BlogPost(title='Test 3', published=True)
post3 = BlogPost(title="Test 3", published=True)
post3.save()
post4 = BlogPost(title='Test 4', publish_date=datetime.datetime(2010, 1, 8))
post4 = BlogPost(title="Test 4", publish_date=datetime.datetime(2010, 1, 8))
post4.save()
post5 = BlogPost(title='Test 1', publish_date=datetime.datetime(2010, 1, 15))
post5 = BlogPost(title="Test 1", publish_date=datetime.datetime(2010, 1, 15))
post5.save()
post6 = BlogPost(title='Test 1', published=False)
post6 = BlogPost(title="Test 1", published=False)
post6.save()
# Check ObjectId lookup works
@@ -235,13 +257,13 @@ class QTest(unittest.TestCase):
self.assertEqual(obj, post1)
# Check Q object combination with one does not exist
q = BlogPost.objects(Q(title='Test 5') | Q(published=True))
q = BlogPost.objects(Q(title="Test 5") | Q(published=True))
posts = [post.id for post in q]
published_posts = (post2, post3)
self.assertTrue(all(obj.id in posts for obj in published_posts))
q = BlogPost.objects(Q(title='Test 1') | Q(published=True))
q = BlogPost.objects(Q(title="Test 1") | Q(published=True))
posts = [post.id for post in q]
published_posts = (post1, post2, post3, post5, post6)
self.assertTrue(all(obj.id in posts for obj in published_posts))
@@ -259,85 +281,91 @@ class QTest(unittest.TestCase):
BlogPost.drop_collection()
# Check the 'in' operator
self.Person(name='user1', age=20).save()
self.Person(name='user2', age=20).save()
self.Person(name='user3', age=30).save()
self.Person(name='user4', age=40).save()
self.Person(name="user1", age=20).save()
self.Person(name="user2", age=20).save()
self.Person(name="user3", age=30).save()
self.Person(name="user4", age=40).save()
self.assertEqual(self.Person.objects(Q(age__in=[20])).count(), 2)
self.assertEqual(self.Person.objects(Q(age__in=[20, 30])).count(), 3)
# Test invalid query objs
with self.assertRaises(InvalidQueryError):
self.Person.objects('user1')
self.Person.objects("user1")
# filter should fail, too
with self.assertRaises(InvalidQueryError):
self.Person.objects.filter('user1')
self.Person.objects.filter("user1")
def test_q_regex(self):
"""Ensure that Q objects can be queried using regexes.
"""
person = self.Person(name='Guido van Rossum')
person = self.Person(name="Guido van Rossum")
person.save()
obj = self.Person.objects(Q(name=re.compile('^Gui'))).first()
obj = self.Person.objects(Q(name=re.compile("^Gui"))).first()
self.assertEqual(obj, person)
obj = self.Person.objects(Q(name=re.compile('^gui'))).first()
obj = self.Person.objects(Q(name=re.compile("^gui"))).first()
self.assertEqual(obj, None)
obj = self.Person.objects(Q(name=re.compile('^gui', re.I))).first()
obj = self.Person.objects(Q(name=re.compile("^gui", re.I))).first()
self.assertEqual(obj, person)
obj = self.Person.objects(Q(name__not=re.compile('^bob'))).first()
obj = self.Person.objects(Q(name__not=re.compile("^bob"))).first()
self.assertEqual(obj, person)
obj = self.Person.objects(Q(name__not=re.compile('^Gui'))).first()
obj = self.Person.objects(Q(name__not=re.compile("^Gui"))).first()
self.assertEqual(obj, None)
def test_q_repr(self):
self.assertEqual(repr(Q()), 'Q(**{})')
self.assertEqual(repr(Q(name='test')), "Q(**{'name': 'test'})")
self.assertEqual(repr(Q()), "Q(**{})")
self.assertEqual(repr(Q(name="test")), "Q(**{'name': 'test'})")
self.assertEqual(
repr(Q(name='test') & Q(age__gte=18)),
"(Q(**{'name': 'test'}) & Q(**{'age__gte': 18}))")
repr(Q(name="test") & Q(age__gte=18)),
"(Q(**{'name': 'test'}) & Q(**{'age__gte': 18}))",
)
self.assertEqual(
repr(Q(name='test') | Q(age__gte=18)),
"(Q(**{'name': 'test'}) | Q(**{'age__gte': 18}))")
repr(Q(name="test") | Q(age__gte=18)),
"(Q(**{'name': 'test'}) | Q(**{'age__gte': 18}))",
)
def test_q_lists(self):
"""Ensure that Q objects query ListFields correctly.
"""
class BlogPost(Document):
tags = ListField(StringField())
BlogPost.drop_collection()
BlogPost(tags=['python', 'mongo']).save()
BlogPost(tags=['python']).save()
BlogPost(tags=["python", "mongo"]).save()
BlogPost(tags=["python"]).save()
self.assertEqual(BlogPost.objects(Q(tags='mongo')).count(), 1)
self.assertEqual(BlogPost.objects(Q(tags='python')).count(), 2)
self.assertEqual(BlogPost.objects(Q(tags="mongo")).count(), 1)
self.assertEqual(BlogPost.objects(Q(tags="python")).count(), 2)
BlogPost.drop_collection()
def test_q_merge_queries_edge_case(self):
class User(Document):
email = EmailField(required=False)
name = StringField()
User.drop_collection()
pk = ObjectId()
User(email='example@example.com', pk=pk).save()
User(email="example@example.com", pk=pk).save()
self.assertEqual(1, User.objects.filter(Q(email='example@example.com') |
Q(name='John Doe')).limit(2).filter(pk=pk).count())
self.assertEqual(
1,
User.objects.filter(Q(email="example@example.com") | Q(name="John Doe"))
.limit(2)
.filter(pk=pk)
.count(),
)
def test_chained_q_or_filtering(self):
class Post(EmbeddedDocument):
name = StringField(required=True)
@@ -350,9 +378,16 @@ class QTest(unittest.TestCase):
Item(postables=[Post(name="a"), Post(name="c")]).save()
Item(postables=[Post(name="a"), Post(name="b"), Post(name="c")]).save()
self.assertEqual(Item.objects(Q(postables__name="a") & Q(postables__name="b")).count(), 2)
self.assertEqual(Item.objects.filter(postables__name="a").filter(postables__name="b").count(), 2)
self.assertEqual(
Item.objects(Q(postables__name="a") & Q(postables__name="b")).count(), 2
)
self.assertEqual(
Item.objects.filter(postables__name="a")
.filter(postables__name="b")
.count(),
2,
)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -5,7 +5,6 @@ from mongoengine import Document
class TestCommon(unittest.TestCase):
def test__import_class(self):
doc_cls = _import_class("Document")
self.assertIs(doc_cls, Document)

View File

@@ -14,12 +14,21 @@ import pymongo
from bson.tz_util import utc
from mongoengine import (
connect, register_connection,
Document, DateTimeField,
disconnect_all, StringField)
connect,
register_connection,
Document,
DateTimeField,
disconnect_all,
StringField,
)
import mongoengine.connection
from mongoengine.connection import (MongoEngineConnectionError, get_db,
get_connection, disconnect, DEFAULT_DATABASE_NAME)
from mongoengine.connection import (
MongoEngineConnectionError,
get_db,
get_connection,
disconnect,
DEFAULT_DATABASE_NAME,
)
def get_tz_awareness(connection):
@@ -27,7 +36,6 @@ def get_tz_awareness(connection):
class ConnectionTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
disconnect_all()
@@ -43,44 +51,46 @@ class ConnectionTest(unittest.TestCase):
def test_connect(self):
"""Ensure that the connect() method works properly."""
connect('mongoenginetest')
connect("mongoenginetest")
conn = get_connection()
self.assertIsInstance(conn, pymongo.mongo_client.MongoClient)
db = get_db()
self.assertIsInstance(db, pymongo.database.Database)
self.assertEqual(db.name, 'mongoenginetest')
self.assertEqual(db.name, "mongoenginetest")
connect('mongoenginetest2', alias='testdb')
conn = get_connection('testdb')
connect("mongoenginetest2", alias="testdb")
conn = get_connection("testdb")
self.assertIsInstance(conn, pymongo.mongo_client.MongoClient)
def test_connect_disconnect_works_properly(self):
class History1(Document):
name = StringField()
meta = {'db_alias': 'db1'}
meta = {"db_alias": "db1"}
class History2(Document):
name = StringField()
meta = {'db_alias': 'db2'}
meta = {"db_alias": "db2"}
connect('db1', alias='db1')
connect('db2', alias='db2')
connect("db1", alias="db1")
connect("db2", alias="db2")
History1.drop_collection()
History2.drop_collection()
h = History1(name='default').save()
h1 = History2(name='db1').save()
h = History1(name="default").save()
h1 = History2(name="db1").save()
self.assertEqual(list(History1.objects().as_pymongo()),
[{'_id': h.id, 'name': 'default'}])
self.assertEqual(list(History2.objects().as_pymongo()),
[{'_id': h1.id, 'name': 'db1'}])
self.assertEqual(
list(History1.objects().as_pymongo()), [{"_id": h.id, "name": "default"}]
)
self.assertEqual(
list(History2.objects().as_pymongo()), [{"_id": h1.id, "name": "db1"}]
)
disconnect('db1')
disconnect('db2')
disconnect("db1")
disconnect("db2")
with self.assertRaises(MongoEngineConnectionError):
list(History1.objects().as_pymongo())
@@ -88,13 +98,15 @@ class ConnectionTest(unittest.TestCase):
with self.assertRaises(MongoEngineConnectionError):
list(History2.objects().as_pymongo())
connect('db1', alias='db1')
connect('db2', alias='db2')
connect("db1", alias="db1")
connect("db2", alias="db2")
self.assertEqual(list(History1.objects().as_pymongo()),
[{'_id': h.id, 'name': 'default'}])
self.assertEqual(list(History2.objects().as_pymongo()),
[{'_id': h1.id, 'name': 'db1'}])
self.assertEqual(
list(History1.objects().as_pymongo()), [{"_id": h.id, "name": "default"}]
)
self.assertEqual(
list(History2.objects().as_pymongo()), [{"_id": h1.id, "name": "db1"}]
)
def test_connect_different_documents_to_different_database(self):
class History(Document):
@@ -102,99 +114,110 @@ class ConnectionTest(unittest.TestCase):
class History1(Document):
name = StringField()
meta = {'db_alias': 'db1'}
meta = {"db_alias": "db1"}
class History2(Document):
name = StringField()
meta = {'db_alias': 'db2'}
meta = {"db_alias": "db2"}
connect()
connect('db1', alias='db1')
connect('db2', alias='db2')
connect("db1", alias="db1")
connect("db2", alias="db2")
History.drop_collection()
History1.drop_collection()
History2.drop_collection()
h = History(name='default').save()
h1 = History1(name='db1').save()
h2 = History2(name='db2').save()
h = History(name="default").save()
h1 = History1(name="db1").save()
h2 = History2(name="db2").save()
self.assertEqual(History._collection.database.name, DEFAULT_DATABASE_NAME)
self.assertEqual(History1._collection.database.name, 'db1')
self.assertEqual(History2._collection.database.name, 'db2')
self.assertEqual(History1._collection.database.name, "db1")
self.assertEqual(History2._collection.database.name, "db2")
self.assertEqual(list(History.objects().as_pymongo()),
[{'_id': h.id, 'name': 'default'}])
self.assertEqual(list(History1.objects().as_pymongo()),
[{'_id': h1.id, 'name': 'db1'}])
self.assertEqual(list(History2.objects().as_pymongo()),
[{'_id': h2.id, 'name': 'db2'}])
self.assertEqual(
list(History.objects().as_pymongo()), [{"_id": h.id, "name": "default"}]
)
self.assertEqual(
list(History1.objects().as_pymongo()), [{"_id": h1.id, "name": "db1"}]
)
self.assertEqual(
list(History2.objects().as_pymongo()), [{"_id": h2.id, "name": "db2"}]
)
def test_connect_fails_if_connect_2_times_with_default_alias(self):
connect('mongoenginetest')
connect("mongoenginetest")
with self.assertRaises(MongoEngineConnectionError) as ctx_err:
connect('mongoenginetest2')
self.assertEqual("A different connection with alias `default` was already registered. Use disconnect() first", str(ctx_err.exception))
connect("mongoenginetest2")
self.assertEqual(
"A different connection with alias `default` was already registered. Use disconnect() first",
str(ctx_err.exception),
)
def test_connect_fails_if_connect_2_times_with_custom_alias(self):
connect('mongoenginetest', alias='alias1')
connect("mongoenginetest", alias="alias1")
with self.assertRaises(MongoEngineConnectionError) as ctx_err:
connect('mongoenginetest2', alias='alias1')
connect("mongoenginetest2", alias="alias1")
self.assertEqual("A different connection with alias `alias1` was already registered. Use disconnect() first", str(ctx_err.exception))
self.assertEqual(
"A different connection with alias `alias1` was already registered. Use disconnect() first",
str(ctx_err.exception),
)
def test_connect_fails_if_similar_connection_settings_arent_defined_the_same_way(self):
def test_connect_fails_if_similar_connection_settings_arent_defined_the_same_way(
self
):
"""Intended to keep the detecton function simple but robust"""
db_name = 'mongoenginetest'
db_alias = 'alias1'
connect(db=db_name, alias=db_alias, host='localhost', port=27017)
db_name = "mongoenginetest"
db_alias = "alias1"
connect(db=db_name, alias=db_alias, host="localhost", port=27017)
with self.assertRaises(MongoEngineConnectionError):
connect(host='mongodb://localhost:27017/%s' % db_name, alias=db_alias)
connect(host="mongodb://localhost:27017/%s" % db_name, alias=db_alias)
def test_connect_passes_silently_connect_multiple_times_with_same_config(self):
# test default connection to `test`
connect()
connect()
self.assertEqual(len(mongoengine.connection._connections), 1)
connect('test01', alias='test01')
connect('test01', alias='test01')
connect("test01", alias="test01")
connect("test01", alias="test01")
self.assertEqual(len(mongoengine.connection._connections), 2)
connect(host='mongodb://localhost:27017/mongoenginetest02', alias='test02')
connect(host='mongodb://localhost:27017/mongoenginetest02', alias='test02')
connect(host="mongodb://localhost:27017/mongoenginetest02", alias="test02")
connect(host="mongodb://localhost:27017/mongoenginetest02", alias="test02")
self.assertEqual(len(mongoengine.connection._connections), 3)
def test_connect_with_invalid_db_name(self):
"""Ensure that connect() method fails fast if db name is invalid
"""
with self.assertRaises(InvalidName):
connect('mongomock://localhost')
connect("mongomock://localhost")
def test_connect_with_db_name_external(self):
"""Ensure that connect() works if db name is $external
"""
"""Ensure that the connect() method works properly."""
connect('$external')
connect("$external")
conn = get_connection()
self.assertIsInstance(conn, pymongo.mongo_client.MongoClient)
db = get_db()
self.assertIsInstance(db, pymongo.database.Database)
self.assertEqual(db.name, '$external')
self.assertEqual(db.name, "$external")
connect('$external', alias='testdb')
conn = get_connection('testdb')
connect("$external", alias="testdb")
conn = get_connection("testdb")
self.assertIsInstance(conn, pymongo.mongo_client.MongoClient)
def test_connect_with_invalid_db_name_type(self):
"""Ensure that connect() method fails fast if db name has invalid type
"""
with self.assertRaises(TypeError):
non_string_db_name = ['e. g. list instead of a string']
non_string_db_name = ["e. g. list instead of a string"]
connect(non_string_db_name)
def test_connect_in_mocking(self):
@@ -203,34 +226,47 @@ class ConnectionTest(unittest.TestCase):
try:
import mongomock
except ImportError:
raise SkipTest('you need mongomock installed to run this testcase')
raise SkipTest("you need mongomock installed to run this testcase")
connect('mongoenginetest', host='mongomock://localhost')
connect("mongoenginetest", host="mongomock://localhost")
conn = get_connection()
self.assertIsInstance(conn, mongomock.MongoClient)
connect('mongoenginetest2', host='mongomock://localhost', alias='testdb2')
conn = get_connection('testdb2')
connect("mongoenginetest2", host="mongomock://localhost", alias="testdb2")
conn = get_connection("testdb2")
self.assertIsInstance(conn, mongomock.MongoClient)
connect('mongoenginetest3', host='mongodb://localhost', is_mock=True, alias='testdb3')
conn = get_connection('testdb3')
connect(
"mongoenginetest3",
host="mongodb://localhost",
is_mock=True,
alias="testdb3",
)
conn = get_connection("testdb3")
self.assertIsInstance(conn, mongomock.MongoClient)
connect('mongoenginetest4', is_mock=True, alias='testdb4')
conn = get_connection('testdb4')
connect("mongoenginetest4", is_mock=True, alias="testdb4")
conn = get_connection("testdb4")
self.assertIsInstance(conn, mongomock.MongoClient)
connect(host='mongodb://localhost:27017/mongoenginetest5', is_mock=True, alias='testdb5')
conn = get_connection('testdb5')
connect(
host="mongodb://localhost:27017/mongoenginetest5",
is_mock=True,
alias="testdb5",
)
conn = get_connection("testdb5")
self.assertIsInstance(conn, mongomock.MongoClient)
connect(host='mongomock://localhost:27017/mongoenginetest6', alias='testdb6')
conn = get_connection('testdb6')
connect(host="mongomock://localhost:27017/mongoenginetest6", alias="testdb6")
conn = get_connection("testdb6")
self.assertIsInstance(conn, mongomock.MongoClient)
connect(host='mongomock://localhost:27017/mongoenginetest7', is_mock=True, alias='testdb7')
conn = get_connection('testdb7')
connect(
host="mongomock://localhost:27017/mongoenginetest7",
is_mock=True,
alias="testdb7",
)
conn = get_connection("testdb7")
self.assertIsInstance(conn, mongomock.MongoClient)
def test_connect_with_host_list(self):
@@ -241,30 +277,39 @@ class ConnectionTest(unittest.TestCase):
try:
import mongomock
except ImportError:
raise SkipTest('you need mongomock installed to run this testcase')
raise SkipTest("you need mongomock installed to run this testcase")
connect(host=['mongomock://localhost'])
connect(host=["mongomock://localhost"])
conn = get_connection()
self.assertIsInstance(conn, mongomock.MongoClient)
connect(host=['mongodb://localhost'], is_mock=True, alias='testdb2')
conn = get_connection('testdb2')
connect(host=["mongodb://localhost"], is_mock=True, alias="testdb2")
conn = get_connection("testdb2")
self.assertIsInstance(conn, mongomock.MongoClient)
connect(host=['localhost'], is_mock=True, alias='testdb3')
conn = get_connection('testdb3')
connect(host=["localhost"], is_mock=True, alias="testdb3")
conn = get_connection("testdb3")
self.assertIsInstance(conn, mongomock.MongoClient)
connect(host=['mongomock://localhost:27017', 'mongomock://localhost:27018'], alias='testdb4')
conn = get_connection('testdb4')
connect(
host=["mongomock://localhost:27017", "mongomock://localhost:27018"],
alias="testdb4",
)
conn = get_connection("testdb4")
self.assertIsInstance(conn, mongomock.MongoClient)
connect(host=['mongodb://localhost:27017', 'mongodb://localhost:27018'], is_mock=True, alias='testdb5')
conn = get_connection('testdb5')
connect(
host=["mongodb://localhost:27017", "mongodb://localhost:27018"],
is_mock=True,
alias="testdb5",
)
conn = get_connection("testdb5")
self.assertIsInstance(conn, mongomock.MongoClient)
connect(host=['localhost:27017', 'localhost:27018'], is_mock=True, alias='testdb6')
conn = get_connection('testdb6')
connect(
host=["localhost:27017", "localhost:27018"], is_mock=True, alias="testdb6"
)
conn = get_connection("testdb6")
self.assertIsInstance(conn, mongomock.MongoClient)
def test_disconnect_cleans_globals(self):
@@ -273,7 +318,7 @@ class ConnectionTest(unittest.TestCase):
dbs = mongoengine.connection._dbs
connection_settings = mongoengine.connection._connection_settings
connect('mongoenginetest')
connect("mongoenginetest")
self.assertEqual(len(connections), 1)
self.assertEqual(len(dbs), 0)
@@ -292,7 +337,7 @@ class ConnectionTest(unittest.TestCase):
def test_disconnect_cleans_cached_collection_attribute_in_document(self):
"""Ensure that the disconnect() method works properly"""
conn1 = connect('mongoenginetest')
conn1 = connect("mongoenginetest")
class History(Document):
pass
@@ -301,7 +346,7 @@ class ConnectionTest(unittest.TestCase):
History.drop_collection()
History.objects.first() # will trigger the caching of _collection attribute
History.objects.first() # will trigger the caching of _collection attribute
self.assertIsNotNone(History._collection)
disconnect()
@@ -310,15 +355,17 @@ class ConnectionTest(unittest.TestCase):
with self.assertRaises(MongoEngineConnectionError) as ctx_err:
History.objects.first()
self.assertEqual("You have not defined a default connection", str(ctx_err.exception))
self.assertEqual(
"You have not defined a default connection", str(ctx_err.exception)
)
def test_connect_disconnect_works_on_same_document(self):
"""Ensure that the connect/disconnect works properly with a single Document"""
db1 = 'db1'
db2 = 'db2'
db1 = "db1"
db2 = "db2"
# Ensure freshness of the 2 databases through pymongo
client = MongoClient('localhost', 27017)
client = MongoClient("localhost", 27017)
client.drop_database(db1)
client.drop_database(db2)
@@ -328,44 +375,44 @@ class ConnectionTest(unittest.TestCase):
class User(Document):
name = StringField(required=True)
user1 = User(name='John is in db1').save()
user1 = User(name="John is in db1").save()
disconnect()
# Make sure save doesnt work at this stage
with self.assertRaises(MongoEngineConnectionError):
User(name='Wont work').save()
User(name="Wont work").save()
# Save in db2
connect(db2)
user2 = User(name='Bob is in db2').save()
user2 = User(name="Bob is in db2").save()
disconnect()
db1_users = list(client[db1].user.find())
self.assertEqual(db1_users, [{'_id': user1.id, 'name': 'John is in db1'}])
self.assertEqual(db1_users, [{"_id": user1.id, "name": "John is in db1"}])
db2_users = list(client[db2].user.find())
self.assertEqual(db2_users, [{'_id': user2.id, 'name': 'Bob is in db2'}])
self.assertEqual(db2_users, [{"_id": user2.id, "name": "Bob is in db2"}])
def test_disconnect_silently_pass_if_alias_does_not_exist(self):
connections = mongoengine.connection._connections
self.assertEqual(len(connections), 0)
disconnect(alias='not_exist')
disconnect(alias="not_exist")
def test_disconnect_all(self):
connections = mongoengine.connection._connections
dbs = mongoengine.connection._dbs
connection_settings = mongoengine.connection._connection_settings
connect('mongoenginetest')
connect('mongoenginetest2', alias='db1')
connect("mongoenginetest")
connect("mongoenginetest2", alias="db1")
class History(Document):
pass
class History1(Document):
name = StringField()
meta = {'db_alias': 'db1'}
meta = {"db_alias": "db1"}
History.drop_collection() # will trigger the caching of _collection attribute
History.drop_collection() # will trigger the caching of _collection attribute
History.objects.first()
History1.drop_collection()
History1.objects.first()
@@ -398,11 +445,11 @@ class ConnectionTest(unittest.TestCase):
def test_sharing_connections(self):
"""Ensure that connections are shared when the connection settings are exactly the same
"""
connect('mongoenginetests', alias='testdb1')
expected_connection = get_connection('testdb1')
connect("mongoenginetests", alias="testdb1")
expected_connection = get_connection("testdb1")
connect('mongoenginetests', alias='testdb2')
actual_connection = get_connection('testdb2')
connect("mongoenginetests", alias="testdb2")
actual_connection = get_connection("testdb2")
expected_connection.server_info()
@@ -410,7 +457,7 @@ class ConnectionTest(unittest.TestCase):
def test_connect_uri(self):
"""Ensure that the connect() method works properly with URIs."""
c = connect(db='mongoenginetest', alias='admin')
c = connect(db="mongoenginetest", alias="admin")
c.admin.system.users.delete_many({})
c.mongoenginetest.system.users.delete_many({})
@@ -418,14 +465,16 @@ class ConnectionTest(unittest.TestCase):
c.admin.authenticate("admin", "password")
c.admin.command("createUser", "username", pwd="password", roles=["dbOwner"])
connect("testdb_uri", host='mongodb://username:password@localhost/mongoenginetest')
connect(
"testdb_uri", host="mongodb://username:password@localhost/mongoenginetest"
)
conn = get_connection()
self.assertIsInstance(conn, pymongo.mongo_client.MongoClient)
db = get_db()
self.assertIsInstance(db, pymongo.database.Database)
self.assertEqual(db.name, 'mongoenginetest')
self.assertEqual(db.name, "mongoenginetest")
c.admin.system.users.delete_many({})
c.mongoenginetest.system.users.delete_many({})
@@ -434,35 +483,35 @@ class ConnectionTest(unittest.TestCase):
"""Ensure connect() method works properly if the URI doesn't
include a database name.
"""
connect("mongoenginetest", host='mongodb://localhost/')
connect("mongoenginetest", host="mongodb://localhost/")
conn = get_connection()
self.assertIsInstance(conn, pymongo.mongo_client.MongoClient)
db = get_db()
self.assertIsInstance(db, pymongo.database.Database)
self.assertEqual(db.name, 'mongoenginetest')
self.assertEqual(db.name, "mongoenginetest")
def test_connect_uri_default_db(self):
"""Ensure connect() defaults to the right database name if
the URI and the database_name don't explicitly specify it.
"""
connect(host='mongodb://localhost/')
connect(host="mongodb://localhost/")
conn = get_connection()
self.assertIsInstance(conn, pymongo.mongo_client.MongoClient)
db = get_db()
self.assertIsInstance(db, pymongo.database.Database)
self.assertEqual(db.name, 'test')
self.assertEqual(db.name, "test")
def test_uri_without_credentials_doesnt_override_conn_settings(self):
"""Ensure connect() uses the username & password params if the URI
doesn't explicitly specify them.
"""
c = connect(host='mongodb://localhost/mongoenginetest',
username='user',
password='pass')
c = connect(
host="mongodb://localhost/mongoenginetest", username="user", password="pass"
)
# OperationFailure means that mongoengine attempted authentication
# w/ the provided username/password and failed - that's the desired
@@ -474,27 +523,31 @@ class ConnectionTest(unittest.TestCase):
option in the URI.
"""
# Create users
c = connect('mongoenginetest')
c = connect("mongoenginetest")
c.admin.system.users.delete_many({})
c.admin.command("createUser", "username2", pwd="password", roles=["dbOwner"])
# Authentication fails without "authSource"
test_conn = connect(
'mongoenginetest', alias='test1',
host='mongodb://username2:password@localhost/mongoenginetest'
"mongoenginetest",
alias="test1",
host="mongodb://username2:password@localhost/mongoenginetest",
)
self.assertRaises(OperationFailure, test_conn.server_info)
# Authentication succeeds with "authSource"
authd_conn = connect(
'mongoenginetest', alias='test2',
host=('mongodb://username2:password@localhost/'
'mongoenginetest?authSource=admin')
"mongoenginetest",
alias="test2",
host=(
"mongodb://username2:password@localhost/"
"mongoenginetest?authSource=admin"
),
)
db = get_db('test2')
db = get_db("test2")
self.assertIsInstance(db, pymongo.database.Database)
self.assertEqual(db.name, 'mongoenginetest')
self.assertEqual(db.name, "mongoenginetest")
# Clear all users
authd_conn.admin.system.users.delete_many({})
@@ -502,82 +555,86 @@ class ConnectionTest(unittest.TestCase):
def test_register_connection(self):
"""Ensure that connections with different aliases may be registered.
"""
register_connection('testdb', 'mongoenginetest2')
register_connection("testdb", "mongoenginetest2")
self.assertRaises(MongoEngineConnectionError, get_connection)
conn = get_connection('testdb')
conn = get_connection("testdb")
self.assertIsInstance(conn, pymongo.mongo_client.MongoClient)
db = get_db('testdb')
db = get_db("testdb")
self.assertIsInstance(db, pymongo.database.Database)
self.assertEqual(db.name, 'mongoenginetest2')
self.assertEqual(db.name, "mongoenginetest2")
def test_register_connection_defaults(self):
"""Ensure that defaults are used when the host and port are None.
"""
register_connection('testdb', 'mongoenginetest', host=None, port=None)
register_connection("testdb", "mongoenginetest", host=None, port=None)
conn = get_connection('testdb')
conn = get_connection("testdb")
self.assertIsInstance(conn, pymongo.mongo_client.MongoClient)
def test_connection_kwargs(self):
"""Ensure that connection kwargs get passed to pymongo."""
connect('mongoenginetest', alias='t1', tz_aware=True)
conn = get_connection('t1')
connect("mongoenginetest", alias="t1", tz_aware=True)
conn = get_connection("t1")
self.assertTrue(get_tz_awareness(conn))
connect('mongoenginetest2', alias='t2')
conn = get_connection('t2')
connect("mongoenginetest2", alias="t2")
conn = get_connection("t2")
self.assertFalse(get_tz_awareness(conn))
def test_connection_pool_via_kwarg(self):
"""Ensure we can specify a max connection pool size using
a connection kwarg.
"""
pool_size_kwargs = {'maxpoolsize': 100}
pool_size_kwargs = {"maxpoolsize": 100}
conn = connect('mongoenginetest', alias='max_pool_size_via_kwarg', **pool_size_kwargs)
conn = connect(
"mongoenginetest", alias="max_pool_size_via_kwarg", **pool_size_kwargs
)
self.assertEqual(conn.max_pool_size, 100)
def test_connection_pool_via_uri(self):
"""Ensure we can specify a max connection pool size using
an option in a connection URI.
"""
conn = connect(host='mongodb://localhost/test?maxpoolsize=100', alias='max_pool_size_via_uri')
conn = connect(
host="mongodb://localhost/test?maxpoolsize=100",
alias="max_pool_size_via_uri",
)
self.assertEqual(conn.max_pool_size, 100)
def test_write_concern(self):
"""Ensure write concern can be specified in connect() via
a kwarg or as part of the connection URI.
"""
conn1 = connect(alias='conn1', host='mongodb://localhost/testing?w=1&j=true')
conn2 = connect('testing', alias='conn2', w=1, j=True)
self.assertEqual(conn1.write_concern.document, {'w': 1, 'j': True})
self.assertEqual(conn2.write_concern.document, {'w': 1, 'j': True})
conn1 = connect(alias="conn1", host="mongodb://localhost/testing?w=1&j=true")
conn2 = connect("testing", alias="conn2", w=1, j=True)
self.assertEqual(conn1.write_concern.document, {"w": 1, "j": True})
self.assertEqual(conn2.write_concern.document, {"w": 1, "j": True})
def test_connect_with_replicaset_via_uri(self):
"""Ensure connect() works when specifying a replicaSet via the
MongoDB URI.
"""
c = connect(host='mongodb://localhost/test?replicaSet=local-rs')
c = connect(host="mongodb://localhost/test?replicaSet=local-rs")
db = get_db()
self.assertIsInstance(db, pymongo.database.Database)
self.assertEqual(db.name, 'test')
self.assertEqual(db.name, "test")
def test_connect_with_replicaset_via_kwargs(self):
"""Ensure connect() works when specifying a replicaSet via the
connection kwargs
"""
c = connect(replicaset='local-rs')
self.assertEqual(c._MongoClient__options.replica_set_name,
'local-rs')
c = connect(replicaset="local-rs")
self.assertEqual(c._MongoClient__options.replica_set_name, "local-rs")
db = get_db()
self.assertIsInstance(db, pymongo.database.Database)
self.assertEqual(db.name, 'test')
self.assertEqual(db.name, "test")
def test_connect_tz_aware(self):
connect('mongoenginetest', tz_aware=True)
connect("mongoenginetest", tz_aware=True)
d = datetime.datetime(2010, 5, 5, tzinfo=utc)
class DateDoc(Document):
@@ -590,37 +647,39 @@ class ConnectionTest(unittest.TestCase):
self.assertEqual(d, date_doc.the_date)
def test_read_preference_from_parse(self):
conn = connect(host="mongodb://a1.vpc,a2.vpc,a3.vpc/prod?readPreference=secondaryPreferred")
conn = connect(
host="mongodb://a1.vpc,a2.vpc,a3.vpc/prod?readPreference=secondaryPreferred"
)
self.assertEqual(conn.read_preference, ReadPreference.SECONDARY_PREFERRED)
def test_multiple_connection_settings(self):
connect('mongoenginetest', alias='t1', host="localhost")
connect("mongoenginetest", alias="t1", host="localhost")
connect('mongoenginetest2', alias='t2', host="127.0.0.1")
connect("mongoenginetest2", alias="t2", host="127.0.0.1")
mongo_connections = mongoengine.connection._connections
self.assertEqual(len(mongo_connections.items()), 2)
self.assertIn('t1', mongo_connections.keys())
self.assertIn('t2', mongo_connections.keys())
self.assertIn("t1", mongo_connections.keys())
self.assertIn("t2", mongo_connections.keys())
# Handle PyMongo 3+ Async Connection
# Ensure we are connected, throws ServerSelectionTimeoutError otherwise.
# Purposely not catching exception to fail test if thrown.
mongo_connections['t1'].server_info()
mongo_connections['t2'].server_info()
self.assertEqual(mongo_connections['t1'].address[0], 'localhost')
self.assertEqual(mongo_connections['t2'].address[0], '127.0.0.1')
mongo_connections["t1"].server_info()
mongo_connections["t2"].server_info()
self.assertEqual(mongo_connections["t1"].address[0], "localhost")
self.assertEqual(mongo_connections["t2"].address[0], "127.0.0.1")
def test_connect_2_databases_uses_same_client_if_only_dbname_differs(self):
c1 = connect(alias='testdb1', db='testdb1')
c2 = connect(alias='testdb2', db='testdb2')
c1 = connect(alias="testdb1", db="testdb1")
c2 = connect(alias="testdb2", db="testdb2")
self.assertIs(c1, c2)
def test_connect_2_databases_uses_different_client_if_different_parameters(self):
c1 = connect(alias='testdb1', db='testdb1', username='u1')
c2 = connect(alias='testdb2', db='testdb2', username='u2')
c1 = connect(alias="testdb1", db="testdb1", username="u1")
c2 = connect(alias="testdb2", db="testdb2", username="u2")
self.assertIsNot(c1, c2)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -2,17 +2,20 @@ import unittest
from mongoengine import *
from mongoengine.connection import get_db
from mongoengine.context_managers import (switch_db, switch_collection,
no_sub_classes, no_dereference,
query_counter)
from mongoengine.context_managers import (
switch_db,
switch_collection,
no_sub_classes,
no_dereference,
query_counter,
)
from mongoengine.pymongo_support import count_documents
class ContextManagersTest(unittest.TestCase):
def test_switch_db_context_manager(self):
connect('mongoenginetest')
register_connection('testdb-1', 'mongoenginetest2')
connect("mongoenginetest")
register_connection("testdb-1", "mongoenginetest2")
class Group(Document):
name = StringField()
@@ -22,7 +25,7 @@ class ContextManagersTest(unittest.TestCase):
Group(name="hello - default").save()
self.assertEqual(1, Group.objects.count())
with switch_db(Group, 'testdb-1') as Group:
with switch_db(Group, "testdb-1") as Group:
self.assertEqual(0, Group.objects.count())
@@ -36,21 +39,21 @@ class ContextManagersTest(unittest.TestCase):
self.assertEqual(1, Group.objects.count())
def test_switch_collection_context_manager(self):
connect('mongoenginetest')
register_connection(alias='testdb-1', db='mongoenginetest2')
connect("mongoenginetest")
register_connection(alias="testdb-1", db="mongoenginetest2")
class Group(Document):
name = StringField()
Group.drop_collection() # drops in default
Group.drop_collection() # drops in default
with switch_collection(Group, 'group1') as Group:
Group.drop_collection() # drops in group1
with switch_collection(Group, "group1") as Group:
Group.drop_collection() # drops in group1
Group(name="hello - group").save()
self.assertEqual(1, Group.objects.count())
with switch_collection(Group, 'group1') as Group:
with switch_collection(Group, "group1") as Group:
self.assertEqual(0, Group.objects.count())
@@ -66,7 +69,7 @@ class ContextManagersTest(unittest.TestCase):
def test_no_dereference_context_manager_object_id(self):
"""Ensure that DBRef items in ListFields aren't dereferenced.
"""
connect('mongoenginetest')
connect("mongoenginetest")
class User(Document):
name = StringField()
@@ -80,14 +83,14 @@ class ContextManagersTest(unittest.TestCase):
Group.drop_collection()
for i in range(1, 51):
User(name='user %s' % i).save()
User(name="user %s" % i).save()
user = User.objects.first()
Group(ref=user, members=User.objects, generic=user).save()
with no_dereference(Group) as NoDeRefGroup:
self.assertTrue(Group._fields['members']._auto_dereference)
self.assertFalse(NoDeRefGroup._fields['members']._auto_dereference)
self.assertTrue(Group._fields["members"]._auto_dereference)
self.assertFalse(NoDeRefGroup._fields["members"]._auto_dereference)
with no_dereference(Group) as Group:
group = Group.objects.first()
@@ -104,7 +107,7 @@ class ContextManagersTest(unittest.TestCase):
def test_no_dereference_context_manager_dbref(self):
"""Ensure that DBRef items in ListFields aren't dereferenced.
"""
connect('mongoenginetest')
connect("mongoenginetest")
class User(Document):
name = StringField()
@@ -118,31 +121,29 @@ class ContextManagersTest(unittest.TestCase):
Group.drop_collection()
for i in range(1, 51):
User(name='user %s' % i).save()
User(name="user %s" % i).save()
user = User.objects.first()
Group(ref=user, members=User.objects, generic=user).save()
with no_dereference(Group) as NoDeRefGroup:
self.assertTrue(Group._fields['members']._auto_dereference)
self.assertFalse(NoDeRefGroup._fields['members']._auto_dereference)
self.assertTrue(Group._fields["members"]._auto_dereference)
self.assertFalse(NoDeRefGroup._fields["members"]._auto_dereference)
with no_dereference(Group) as Group:
group = Group.objects.first()
self.assertTrue(all([not isinstance(m, User)
for m in group.members]))
self.assertTrue(all([not isinstance(m, User) for m in group.members]))
self.assertNotIsInstance(group.ref, User)
self.assertNotIsInstance(group.generic, User)
self.assertTrue(all([isinstance(m, User)
for m in group.members]))
self.assertTrue(all([isinstance(m, User) for m in group.members]))
self.assertIsInstance(group.ref, User)
self.assertIsInstance(group.generic, User)
def test_no_sub_classes(self):
class A(Document):
x = IntField()
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
class B(A):
z = IntField()
@@ -188,20 +189,20 @@ class ContextManagersTest(unittest.TestCase):
def test_no_sub_classes_modification_to_document_class_are_temporary(self):
class A(Document):
x = IntField()
meta = {'allow_inheritance': True}
meta = {"allow_inheritance": True}
class B(A):
z = IntField()
self.assertEqual(A._subclasses, ('A', 'A.B'))
self.assertEqual(A._subclasses, ("A", "A.B"))
with no_sub_classes(A):
self.assertEqual(A._subclasses, ('A',))
self.assertEqual(A._subclasses, ('A', 'A.B'))
self.assertEqual(A._subclasses, ("A",))
self.assertEqual(A._subclasses, ("A", "A.B"))
self.assertEqual(B._subclasses, ('A.B',))
self.assertEqual(B._subclasses, ("A.B",))
with no_sub_classes(B):
self.assertEqual(B._subclasses, ('A.B',))
self.assertEqual(B._subclasses, ('A.B',))
self.assertEqual(B._subclasses, ("A.B",))
self.assertEqual(B._subclasses, ("A.B",))
def test_no_subclass_context_manager_does_not_swallow_exception(self):
class User(Document):
@@ -218,7 +219,7 @@ class ContextManagersTest(unittest.TestCase):
raise TypeError()
def test_query_counter_temporarily_modifies_profiling_level(self):
connect('mongoenginetest')
connect("mongoenginetest")
db = get_db()
initial_profiling_level = db.profiling_level()
@@ -231,11 +232,13 @@ class ContextManagersTest(unittest.TestCase):
self.assertEqual(db.profiling_level(), 2)
self.assertEqual(db.profiling_level(), NEW_LEVEL)
except Exception:
db.set_profiling_level(initial_profiling_level) # Ensures it gets reseted no matter the outcome of the test
db.set_profiling_level(
initial_profiling_level
) # Ensures it gets reseted no matter the outcome of the test
raise
def test_query_counter(self):
connect('mongoenginetest')
connect("mongoenginetest")
db = get_db()
collection = db.query_counter
@@ -245,7 +248,7 @@ class ContextManagersTest(unittest.TestCase):
count_documents(collection, {})
def issue_1_insert_query():
collection.insert_one({'test': 'garbage'})
collection.insert_one({"test": "garbage"})
def issue_1_find_query():
collection.find_one()
@@ -253,7 +256,9 @@ class ContextManagersTest(unittest.TestCase):
counter = 0
with query_counter() as q:
self.assertEqual(q, counter)
self.assertEqual(q, counter) # Ensures previous count query did not get counted
self.assertEqual(
q, counter
) # Ensures previous count query did not get counted
for _ in range(10):
issue_1_insert_query()
@@ -270,23 +275,25 @@ class ContextManagersTest(unittest.TestCase):
counter += 1
self.assertEqual(q, counter)
self.assertEqual(int(q), counter) # test __int__
self.assertEqual(int(q), counter) # test __int__
self.assertEqual(repr(q), str(int(q))) # test __repr__
self.assertGreater(q, -1) # test __gt__
self.assertGreaterEqual(q, int(q)) # test __gte__
self.assertGreater(q, -1) # test __gt__
self.assertGreaterEqual(q, int(q)) # test __gte__
self.assertNotEqual(q, -1)
self.assertLess(q, 1000)
self.assertLessEqual(q, int(q))
def test_query_counter_counts_getmore_queries(self):
connect('mongoenginetest')
connect("mongoenginetest")
db = get_db()
collection = db.query_counter
collection.drop()
many_docs = [{'test': 'garbage %s' % i} for i in range(150)]
collection.insert_many(many_docs) # first batch of documents contains 101 documents
many_docs = [{"test": "garbage %s" % i} for i in range(150)]
collection.insert_many(
many_docs
) # first batch of documents contains 101 documents
with query_counter() as q:
self.assertEqual(q, 0)
@@ -294,24 +301,26 @@ class ContextManagersTest(unittest.TestCase):
self.assertEqual(q, 2) # 1st select + 1 getmore
def test_query_counter_ignores_particular_queries(self):
connect('mongoenginetest')
connect("mongoenginetest")
db = get_db()
collection = db.query_counter
collection.insert_many([{'test': 'garbage %s' % i} for i in range(10)])
collection.insert_many([{"test": "garbage %s" % i} for i in range(10)])
with query_counter() as q:
self.assertEqual(q, 0)
cursor = collection.find()
self.assertEqual(q, 0) # cursor wasn't opened yet
_ = next(cursor) # opens the cursor and fires the find query
self.assertEqual(q, 0) # cursor wasn't opened yet
_ = next(cursor) # opens the cursor and fires the find query
self.assertEqual(q, 1)
cursor.close() # issues a `killcursors` query that is ignored by the context
cursor.close() # issues a `killcursors` query that is ignored by the context
self.assertEqual(q, 1)
_ = db.system.indexes.find_one() # queries on db.system.indexes are ignored as well
_ = (
db.system.indexes.find_one()
) # queries on db.system.indexes are ignored as well
self.assertEqual(q, 1)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -14,128 +14,129 @@ class DocumentStub(object):
class TestBaseDict(unittest.TestCase):
@staticmethod
def _get_basedict(dict_items):
"""Get a BaseList bound to a fake document instance"""
fake_doc = DocumentStub()
base_list = BaseDict(dict_items, instance=None, name='my_name')
base_list._instance = fake_doc # hack to inject the mock, it does not work in the constructor
base_list = BaseDict(dict_items, instance=None, name="my_name")
base_list._instance = (
fake_doc
) # hack to inject the mock, it does not work in the constructor
return base_list
def test___init___(self):
class MyDoc(Document):
pass
dict_items = {'k': 'v'}
dict_items = {"k": "v"}
doc = MyDoc()
base_dict = BaseDict(dict_items, instance=doc, name='my_name')
base_dict = BaseDict(dict_items, instance=doc, name="my_name")
self.assertIsInstance(base_dict._instance, Document)
self.assertEqual(base_dict._name, 'my_name')
self.assertEqual(base_dict._name, "my_name")
self.assertEqual(base_dict, dict_items)
def test_setdefault_calls_mark_as_changed(self):
base_dict = self._get_basedict({})
base_dict.setdefault('k', 'v')
base_dict.setdefault("k", "v")
self.assertEqual(base_dict._instance._changed_fields, [base_dict._name])
def test_popitems_calls_mark_as_changed(self):
base_dict = self._get_basedict({'k': 'v'})
self.assertEqual(base_dict.popitem(), ('k', 'v'))
base_dict = self._get_basedict({"k": "v"})
self.assertEqual(base_dict.popitem(), ("k", "v"))
self.assertEqual(base_dict._instance._changed_fields, [base_dict._name])
self.assertFalse(base_dict)
def test_pop_calls_mark_as_changed(self):
base_dict = self._get_basedict({'k': 'v'})
self.assertEqual(base_dict.pop('k'), 'v')
base_dict = self._get_basedict({"k": "v"})
self.assertEqual(base_dict.pop("k"), "v")
self.assertEqual(base_dict._instance._changed_fields, [base_dict._name])
self.assertFalse(base_dict)
def test_pop_calls_does_not_mark_as_changed_when_it_fails(self):
base_dict = self._get_basedict({'k': 'v'})
base_dict = self._get_basedict({"k": "v"})
with self.assertRaises(KeyError):
base_dict.pop('X')
base_dict.pop("X")
self.assertFalse(base_dict._instance._changed_fields)
def test_clear_calls_mark_as_changed(self):
base_dict = self._get_basedict({'k': 'v'})
base_dict = self._get_basedict({"k": "v"})
base_dict.clear()
self.assertEqual(base_dict._instance._changed_fields, ['my_name'])
self.assertEqual(base_dict._instance._changed_fields, ["my_name"])
self.assertEqual(base_dict, {})
def test___delitem___calls_mark_as_changed(self):
base_dict = self._get_basedict({'k': 'v'})
del base_dict['k']
self.assertEqual(base_dict._instance._changed_fields, ['my_name.k'])
base_dict = self._get_basedict({"k": "v"})
del base_dict["k"]
self.assertEqual(base_dict._instance._changed_fields, ["my_name.k"])
self.assertEqual(base_dict, {})
def test___getitem____KeyError(self):
base_dict = self._get_basedict({})
with self.assertRaises(KeyError):
base_dict['new']
base_dict["new"]
def test___getitem____simple_value(self):
base_dict = self._get_basedict({'k': 'v'})
base_dict['k'] = 'v'
base_dict = self._get_basedict({"k": "v"})
base_dict["k"] = "v"
def test___getitem____sublist_gets_converted_to_BaseList(self):
base_dict = self._get_basedict({'k': [0, 1, 2]})
sub_list = base_dict['k']
base_dict = self._get_basedict({"k": [0, 1, 2]})
sub_list = base_dict["k"]
self.assertEqual(sub_list, [0, 1, 2])
self.assertIsInstance(sub_list, BaseList)
self.assertIs(sub_list._instance, base_dict._instance)
self.assertEqual(sub_list._name, 'my_name.k')
self.assertEqual(sub_list._name, "my_name.k")
self.assertEqual(base_dict._instance._changed_fields, [])
# Challenge mark_as_changed from sublist
sub_list[1] = None
self.assertEqual(base_dict._instance._changed_fields, ['my_name.k.1'])
self.assertEqual(base_dict._instance._changed_fields, ["my_name.k.1"])
def test___getitem____subdict_gets_converted_to_BaseDict(self):
base_dict = self._get_basedict({'k': {'subk': 'subv'}})
sub_dict = base_dict['k']
self.assertEqual(sub_dict, {'subk': 'subv'})
base_dict = self._get_basedict({"k": {"subk": "subv"}})
sub_dict = base_dict["k"]
self.assertEqual(sub_dict, {"subk": "subv"})
self.assertIsInstance(sub_dict, BaseDict)
self.assertIs(sub_dict._instance, base_dict._instance)
self.assertEqual(sub_dict._name, 'my_name.k')
self.assertEqual(sub_dict._name, "my_name.k")
self.assertEqual(base_dict._instance._changed_fields, [])
# Challenge mark_as_changed from subdict
sub_dict['subk'] = None
self.assertEqual(base_dict._instance._changed_fields, ['my_name.k.subk'])
sub_dict["subk"] = None
self.assertEqual(base_dict._instance._changed_fields, ["my_name.k.subk"])
def test_get_sublist_gets_converted_to_BaseList_just_like__getitem__(self):
base_dict = self._get_basedict({'k': [0, 1, 2]})
sub_list = base_dict.get('k')
base_dict = self._get_basedict({"k": [0, 1, 2]})
sub_list = base_dict.get("k")
self.assertEqual(sub_list, [0, 1, 2])
self.assertIsInstance(sub_list, BaseList)
def test_get_returns_the_same_as___getitem__(self):
base_dict = self._get_basedict({'k': [0, 1, 2]})
get_ = base_dict.get('k')
getitem_ = base_dict['k']
base_dict = self._get_basedict({"k": [0, 1, 2]})
get_ = base_dict.get("k")
getitem_ = base_dict["k"]
self.assertEqual(get_, getitem_)
def test_get_default(self):
base_dict = self._get_basedict({})
sentinel = object()
self.assertEqual(base_dict.get('new'), None)
self.assertIs(base_dict.get('new', sentinel), sentinel)
self.assertEqual(base_dict.get("new"), None)
self.assertIs(base_dict.get("new", sentinel), sentinel)
def test___setitem___calls_mark_as_changed(self):
base_dict = self._get_basedict({})
base_dict['k'] = 'v'
self.assertEqual(base_dict._instance._changed_fields, ['my_name.k'])
self.assertEqual(base_dict, {'k': 'v'})
base_dict["k"] = "v"
self.assertEqual(base_dict._instance._changed_fields, ["my_name.k"])
self.assertEqual(base_dict, {"k": "v"})
def test_update_calls_mark_as_changed(self):
base_dict = self._get_basedict({})
base_dict.update({'k': 'v'})
self.assertEqual(base_dict._instance._changed_fields, ['my_name'])
base_dict.update({"k": "v"})
self.assertEqual(base_dict._instance._changed_fields, ["my_name"])
def test___setattr____not_tracked_by_changes(self):
base_dict = self._get_basedict({})
base_dict.a_new_attr = 'test'
base_dict.a_new_attr = "test"
self.assertEqual(base_dict._instance._changed_fields, [])
def test___delattr____tracked_by_changes(self):
@@ -143,19 +144,20 @@ class TestBaseDict(unittest.TestCase):
# This is even bad because it could be that there is an attribute
# with the same name as a key
base_dict = self._get_basedict({})
base_dict.a_new_attr = 'test'
base_dict.a_new_attr = "test"
del base_dict.a_new_attr
self.assertEqual(base_dict._instance._changed_fields, ['my_name.a_new_attr'])
self.assertEqual(base_dict._instance._changed_fields, ["my_name.a_new_attr"])
class TestBaseList(unittest.TestCase):
@staticmethod
def _get_baselist(list_items):
"""Get a BaseList bound to a fake document instance"""
fake_doc = DocumentStub()
base_list = BaseList(list_items, instance=None, name='my_name')
base_list._instance = fake_doc # hack to inject the mock, it does not work in the constructor
base_list = BaseList(list_items, instance=None, name="my_name")
base_list._instance = (
fake_doc
) # hack to inject the mock, it does not work in the constructor
return base_list
def test___init___(self):
@@ -164,19 +166,19 @@ class TestBaseList(unittest.TestCase):
list_items = [True]
doc = MyDoc()
base_list = BaseList(list_items, instance=doc, name='my_name')
base_list = BaseList(list_items, instance=doc, name="my_name")
self.assertIsInstance(base_list._instance, Document)
self.assertEqual(base_list._name, 'my_name')
self.assertEqual(base_list._name, "my_name")
self.assertEqual(base_list, list_items)
def test___iter__(self):
values = [True, False, True, False]
base_list = BaseList(values, instance=None, name='my_name')
base_list = BaseList(values, instance=None, name="my_name")
self.assertEqual(values, list(base_list))
def test___iter___allow_modification_while_iterating_withou_error(self):
# regular list allows for this, thus this subclass must comply to that
base_list = BaseList([True, False, True, False], instance=None, name='my_name')
base_list = BaseList([True, False, True, False], instance=None, name="my_name")
for idx, val in enumerate(base_list):
if val:
base_list.pop(idx)
@@ -185,7 +187,7 @@ class TestBaseList(unittest.TestCase):
base_list = self._get_baselist([])
self.assertFalse(base_list._instance._changed_fields)
base_list.append(True)
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
def test_subclass_append(self):
# Due to the way mark_as_changed_wrapper is implemented
@@ -193,7 +195,7 @@ class TestBaseList(unittest.TestCase):
class SubBaseList(BaseList):
pass
base_list = SubBaseList([], instance=None, name='my_name')
base_list = SubBaseList([], instance=None, name="my_name")
base_list.append(True)
def test___getitem__using_simple_index(self):
@@ -217,54 +219,45 @@ class TestBaseList(unittest.TestCase):
self.assertEqual(base_list._instance._changed_fields, [])
def test___getitem__sublist_returns_BaseList_bound_to_instance(self):
base_list = self._get_baselist(
[
[1, 2],
[3, 4]
]
)
base_list = self._get_baselist([[1, 2], [3, 4]])
sub_list = base_list[0]
self.assertEqual(sub_list, [1, 2])
self.assertIsInstance(sub_list, BaseList)
self.assertIs(sub_list._instance, base_list._instance)
self.assertEqual(sub_list._name, 'my_name.0')
self.assertEqual(sub_list._name, "my_name.0")
self.assertEqual(base_list._instance._changed_fields, [])
# Challenge mark_as_changed from sublist
sub_list[1] = None
self.assertEqual(base_list._instance._changed_fields, ['my_name.0.1'])
self.assertEqual(base_list._instance._changed_fields, ["my_name.0.1"])
def test___getitem__subdict_returns_BaseList_bound_to_instance(self):
base_list = self._get_baselist(
[
{'subk': 'subv'}
]
)
base_list = self._get_baselist([{"subk": "subv"}])
sub_dict = base_list[0]
self.assertEqual(sub_dict, {'subk': 'subv'})
self.assertEqual(sub_dict, {"subk": "subv"})
self.assertIsInstance(sub_dict, BaseDict)
self.assertIs(sub_dict._instance, base_list._instance)
self.assertEqual(sub_dict._name, 'my_name.0')
self.assertEqual(sub_dict._name, "my_name.0")
self.assertEqual(base_list._instance._changed_fields, [])
# Challenge mark_as_changed from subdict
sub_dict['subk'] = None
self.assertEqual(base_list._instance._changed_fields, ['my_name.0.subk'])
sub_dict["subk"] = None
self.assertEqual(base_list._instance._changed_fields, ["my_name.0.subk"])
def test_extend_calls_mark_as_changed(self):
base_list = self._get_baselist([])
base_list.extend([True])
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
def test_insert_calls_mark_as_changed(self):
base_list = self._get_baselist([])
base_list.insert(0, True)
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
def test_remove_calls_mark_as_changed(self):
base_list = self._get_baselist([True])
base_list.remove(True)
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
def test_remove_not_mark_as_changed_when_it_fails(self):
base_list = self._get_baselist([True])
@@ -275,70 +268,76 @@ class TestBaseList(unittest.TestCase):
def test_pop_calls_mark_as_changed(self):
base_list = self._get_baselist([True])
base_list.pop()
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
def test_reverse_calls_mark_as_changed(self):
base_list = self._get_baselist([True, False])
base_list.reverse()
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
def test___delitem___calls_mark_as_changed(self):
base_list = self._get_baselist([True])
del base_list[0]
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
def test___setitem___calls_with_full_slice_mark_as_changed(self):
base_list = self._get_baselist([])
base_list[:] = [0, 1] # Will use __setslice__ under py2 and __setitem__ under py3
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
base_list[:] = [
0,
1,
] # Will use __setslice__ under py2 and __setitem__ under py3
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
self.assertEqual(base_list, [0, 1])
def test___setitem___calls_with_partial_slice_mark_as_changed(self):
base_list = self._get_baselist([0, 1, 2])
base_list[0:2] = [1, 0] # Will use __setslice__ under py2 and __setitem__ under py3
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
base_list[0:2] = [
1,
0,
] # Will use __setslice__ under py2 and __setitem__ under py3
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
self.assertEqual(base_list, [1, 0, 2])
def test___setitem___calls_with_step_slice_mark_as_changed(self):
base_list = self._get_baselist([0, 1, 2])
base_list[0:3:2] = [-1, -2] # uses __setitem__ in both py2 & 3
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
base_list[0:3:2] = [-1, -2] # uses __setitem__ in both py2 & 3
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
self.assertEqual(base_list, [-1, 1, -2])
def test___setitem___with_slice(self):
base_list = self._get_baselist([0, 1, 2, 3, 4, 5])
base_list[0:6:2] = [None, None, None]
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
self.assertEqual(base_list, [None, 1, None, 3, None, 5])
def test___setitem___item_0_calls_mark_as_changed(self):
base_list = self._get_baselist([True])
base_list[0] = False
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
self.assertEqual(base_list, [False])
def test___setitem___item_1_calls_mark_as_changed(self):
base_list = self._get_baselist([True, True])
base_list[1] = False
self.assertEqual(base_list._instance._changed_fields, ['my_name.1'])
self.assertEqual(base_list._instance._changed_fields, ["my_name.1"])
self.assertEqual(base_list, [True, False])
def test___delslice___calls_mark_as_changed(self):
base_list = self._get_baselist([0, 1])
del base_list[0:1]
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
self.assertEqual(base_list, [1])
def test___iadd___calls_mark_as_changed(self):
base_list = self._get_baselist([True])
base_list += [False]
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
def test___imul___calls_mark_as_changed(self):
base_list = self._get_baselist([True])
self.assertEqual(base_list._instance._changed_fields, [])
base_list *= 2
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
def test_sort_calls_not_marked_as_changed_when_it_fails(self):
base_list = self._get_baselist([True])
@@ -350,7 +349,7 @@ class TestBaseList(unittest.TestCase):
def test_sort_calls_mark_as_changed(self):
base_list = self._get_baselist([True, False])
base_list.sort()
self.assertEqual(base_list._instance._changed_fields, ['my_name'])
self.assertEqual(base_list._instance._changed_fields, ["my_name"])
def test_sort_calls_with_key(self):
base_list = self._get_baselist([1, 2, 11])
@@ -371,7 +370,7 @@ class TestStrictDict(unittest.TestCase):
def test_iterkeys(self):
d = self.dtype(a=1)
self.assertEqual(list(iterkeys(d)), ['a'])
self.assertEqual(list(iterkeys(d)), ["a"])
def test_len(self):
d = self.dtype(a=1)
@@ -379,9 +378,9 @@ class TestStrictDict(unittest.TestCase):
def test_pop(self):
d = self.dtype(a=1)
self.assertIn('a', d)
d.pop('a')
self.assertNotIn('a', d)
self.assertIn("a", d)
d.pop("a")
self.assertNotIn("a", d)
def test_repr(self):
d = self.dtype(a=1, b=2, c=3)
@@ -416,7 +415,7 @@ class TestStrictDict(unittest.TestCase):
d = self.dtype()
d.a = 1
self.assertEqual(d.a, 1)
self.assertRaises(AttributeError, getattr, d, 'b')
self.assertRaises(AttributeError, getattr, d, "b")
def test_setattr_raises_on_nonexisting_attr(self):
d = self.dtype()
@@ -430,20 +429,20 @@ class TestStrictDict(unittest.TestCase):
def test_get(self):
d = self.dtype(a=1)
self.assertEqual(d.get('a'), 1)
self.assertEqual(d.get('b', 'bla'), 'bla')
self.assertEqual(d.get("a"), 1)
self.assertEqual(d.get("b", "bla"), "bla")
def test_items(self):
d = self.dtype(a=1)
self.assertEqual(d.items(), [('a', 1)])
self.assertEqual(d.items(), [("a", 1)])
d = self.dtype(a=1, b=2)
self.assertEqual(d.items(), [('a', 1), ('b', 2)])
self.assertEqual(d.items(), [("a", 1), ("b", 2)])
def test_mappings_protocol(self):
d = self.dtype(a=1, b=2)
self.assertEqual(dict(d), {'a': 1, 'b': 2})
self.assertEqual(dict(**d), {'a': 1, 'b': 2})
self.assertEqual(dict(d), {"a": 1, "b": 2})
self.assertEqual(dict(**d), {"a": 1, "b": 2})
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -10,18 +10,18 @@ from mongoengine.context_managers import query_counter
class FieldTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.db = connect(db='mongoenginetest')
cls.db = connect(db="mongoenginetest")
@classmethod
def tearDownClass(cls):
cls.db.drop_database('mongoenginetest')
cls.db.drop_database("mongoenginetest")
def test_list_item_dereference(self):
"""Ensure that DBRef items in ListFields are dereferenced.
"""
class User(Document):
name = StringField()
@@ -32,7 +32,7 @@ class FieldTest(unittest.TestCase):
Group.drop_collection()
for i in range(1, 51):
user = User(name='user %s' % i)
user = User(name="user %s" % i)
user.save()
group = Group(members=User.objects)
@@ -47,7 +47,7 @@ class FieldTest(unittest.TestCase):
group_obj = Group.objects.first()
self.assertEqual(q, 1)
len(group_obj._data['members'])
len(group_obj._data["members"])
self.assertEqual(q, 1)
len(group_obj.members)
@@ -80,6 +80,7 @@ class FieldTest(unittest.TestCase):
def test_list_item_dereference_dref_false(self):
"""Ensure that DBRef items in ListFields are dereferenced.
"""
class User(Document):
name = StringField()
@@ -90,7 +91,7 @@ class FieldTest(unittest.TestCase):
Group.drop_collection()
for i in range(1, 51):
user = User(name='user %s' % i)
user = User(name="user %s" % i)
user.save()
group = Group(members=User.objects)
@@ -105,14 +106,14 @@ class FieldTest(unittest.TestCase):
[m for m in group_obj.members]
self.assertEqual(q, 2)
self.assertTrue(group_obj._data['members']._dereferenced)
self.assertTrue(group_obj._data["members"]._dereferenced)
# verifies that no additional queries gets executed
# if we re-iterate over the ListField once it is
# dereferenced
[m for m in group_obj.members]
self.assertEqual(q, 2)
self.assertTrue(group_obj._data['members']._dereferenced)
self.assertTrue(group_obj._data["members"]._dereferenced)
# Document select_related
with query_counter() as q:
@@ -136,6 +137,7 @@ class FieldTest(unittest.TestCase):
def test_list_item_dereference_orphan_dbref(self):
"""Ensure that orphan DBRef items in ListFields are dereferenced.
"""
class User(Document):
name = StringField()
@@ -146,7 +148,7 @@ class FieldTest(unittest.TestCase):
Group.drop_collection()
for i in range(1, 51):
user = User(name='user %s' % i)
user = User(name="user %s" % i)
user.save()
group = Group(members=User.objects)
@@ -164,14 +166,14 @@ class FieldTest(unittest.TestCase):
[m for m in group_obj.members]
self.assertEqual(q, 2)
self.assertTrue(group_obj._data['members']._dereferenced)
self.assertTrue(group_obj._data["members"]._dereferenced)
# verifies that no additional queries gets executed
# if we re-iterate over the ListField once it is
# dereferenced
[m for m in group_obj.members]
self.assertEqual(q, 2)
self.assertTrue(group_obj._data['members']._dereferenced)
self.assertTrue(group_obj._data["members"]._dereferenced)
User.drop_collection()
Group.drop_collection()
@@ -179,6 +181,7 @@ class FieldTest(unittest.TestCase):
def test_list_item_dereference_dref_false_stores_as_type(self):
"""Ensure that DBRef items are stored as their type
"""
class User(Document):
my_id = IntField(primary_key=True)
name = StringField()
@@ -189,17 +192,18 @@ class FieldTest(unittest.TestCase):
User.drop_collection()
Group.drop_collection()
user = User(my_id=1, name='user 1').save()
user = User(my_id=1, name="user 1").save()
Group(members=User.objects).save()
group = Group.objects.first()
self.assertEqual(Group._get_collection().find_one()['members'], [1])
self.assertEqual(Group._get_collection().find_one()["members"], [1])
self.assertEqual(group.members, [user])
def test_handle_old_style_references(self):
"""Ensure that DBRef items in ListFields are dereferenced.
"""
class User(Document):
name = StringField()
@@ -210,7 +214,7 @@ class FieldTest(unittest.TestCase):
Group.drop_collection()
for i in range(1, 26):
user = User(name='user %s' % i)
user = User(name="user %s" % i)
user.save()
group = Group(members=User.objects)
@@ -227,8 +231,8 @@ class FieldTest(unittest.TestCase):
group.save()
group = Group.objects.first()
self.assertEqual(group.members[0].name, 'user 1')
self.assertEqual(group.members[-1].name, 'String!')
self.assertEqual(group.members[0].name, "user 1")
self.assertEqual(group.members[-1].name, "String!")
def test_migrate_references(self):
"""Example of migrating ReferenceField storage
@@ -249,8 +253,8 @@ class FieldTest(unittest.TestCase):
group = Group(author=user, members=[user]).save()
raw_data = Group._get_collection().find_one()
self.assertIsInstance(raw_data['author'], DBRef)
self.assertIsInstance(raw_data['members'][0], DBRef)
self.assertIsInstance(raw_data["author"], DBRef)
self.assertIsInstance(raw_data["members"][0], DBRef)
group = Group.objects.first()
self.assertEqual(group.author, user)
@@ -264,8 +268,8 @@ class FieldTest(unittest.TestCase):
# Migrate the data
for g in Group.objects():
# Explicitly mark as changed so resets
g._mark_as_changed('author')
g._mark_as_changed('members')
g._mark_as_changed("author")
g._mark_as_changed("members")
g.save()
group = Group.objects.first()
@@ -273,35 +277,36 @@ class FieldTest(unittest.TestCase):
self.assertEqual(group.members, [user])
raw_data = Group._get_collection().find_one()
self.assertIsInstance(raw_data['author'], ObjectId)
self.assertIsInstance(raw_data['members'][0], ObjectId)
self.assertIsInstance(raw_data["author"], ObjectId)
self.assertIsInstance(raw_data["members"][0], ObjectId)
def test_recursive_reference(self):
"""Ensure that ReferenceFields can reference their own documents.
"""
class Employee(Document):
name = StringField()
boss = ReferenceField('self')
friends = ListField(ReferenceField('self'))
boss = ReferenceField("self")
friends = ListField(ReferenceField("self"))
Employee.drop_collection()
bill = Employee(name='Bill Lumbergh')
bill = Employee(name="Bill Lumbergh")
bill.save()
michael = Employee(name='Michael Bolton')
michael = Employee(name="Michael Bolton")
michael.save()
samir = Employee(name='Samir Nagheenanajar')
samir = Employee(name="Samir Nagheenanajar")
samir.save()
friends = [michael, samir]
peter = Employee(name='Peter Gibbons', boss=bill, friends=friends)
peter = Employee(name="Peter Gibbons", boss=bill, friends=friends)
peter.save()
Employee(name='Funky Gibbon', boss=bill, friends=friends).save()
Employee(name='Funky Gibbon', boss=bill, friends=friends).save()
Employee(name='Funky Gibbon', boss=bill, friends=friends).save()
Employee(name="Funky Gibbon", boss=bill, friends=friends).save()
Employee(name="Funky Gibbon", boss=bill, friends=friends).save()
Employee(name="Funky Gibbon", boss=bill, friends=friends).save()
with query_counter() as q:
self.assertEqual(q, 0)
@@ -343,7 +348,6 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 2)
def test_list_of_lists_of_references(self):
class User(Document):
name = StringField()
@@ -357,9 +361,9 @@ class FieldTest(unittest.TestCase):
Post.drop_collection()
SimpleList.drop_collection()
u1 = User.objects.create(name='u1')
u2 = User.objects.create(name='u2')
u3 = User.objects.create(name='u3')
u1 = User.objects.create(name="u1")
u2 = User.objects.create(name="u2")
u3 = User.objects.create(name="u3")
SimpleList.objects.create(users=[u1, u2, u3])
self.assertEqual(SimpleList.objects.all()[0].users, [u1, u2, u3])
@@ -370,13 +374,14 @@ class FieldTest(unittest.TestCase):
def test_circular_reference(self):
"""Ensure you can handle circular references
"""
class Relation(EmbeddedDocument):
name = StringField()
person = ReferenceField('Person')
person = ReferenceField("Person")
class Person(Document):
name = StringField()
relations = ListField(EmbeddedDocumentField('Relation'))
relations = ListField(EmbeddedDocumentField("Relation"))
def __repr__(self):
return "<Person: %s>" % self.name
@@ -398,14 +403,17 @@ class FieldTest(unittest.TestCase):
daughter.relations.append(self_rel)
daughter.save()
self.assertEqual("[<Person: Mother>, <Person: Daughter>]", "%s" % Person.objects())
self.assertEqual(
"[<Person: Mother>, <Person: Daughter>]", "%s" % Person.objects()
)
def test_circular_reference_on_self(self):
"""Ensure you can handle circular references
"""
class Person(Document):
name = StringField()
relations = ListField(ReferenceField('self'))
relations = ListField(ReferenceField("self"))
def __repr__(self):
return "<Person: %s>" % self.name
@@ -424,14 +432,17 @@ class FieldTest(unittest.TestCase):
daughter.relations.append(daughter)
daughter.save()
self.assertEqual("[<Person: Mother>, <Person: Daughter>]", "%s" % Person.objects())
self.assertEqual(
"[<Person: Mother>, <Person: Daughter>]", "%s" % Person.objects()
)
def test_circular_tree_reference(self):
"""Ensure you can handle circular references with more than one level
"""
class Other(EmbeddedDocument):
name = StringField()
friends = ListField(ReferenceField('Person'))
friends = ListField(ReferenceField("Person"))
class Person(Document):
name = StringField()
@@ -443,8 +454,8 @@ class FieldTest(unittest.TestCase):
Person.drop_collection()
paul = Person(name="Paul").save()
maria = Person(name="Maria").save()
julia = Person(name='Julia').save()
anna = Person(name='Anna').save()
julia = Person(name="Julia").save()
anna = Person(name="Anna").save()
paul.other.friends = [maria, julia, anna]
paul.other.name = "Paul's friends"
@@ -464,11 +475,10 @@ class FieldTest(unittest.TestCase):
self.assertEqual(
"[<Person: Paul>, <Person: Maria>, <Person: Julia>, <Person: Anna>]",
"%s" % Person.objects()
"%s" % Person.objects(),
)
def test_generic_reference(self):
class UserA(Document):
name = StringField()
@@ -488,13 +498,13 @@ class FieldTest(unittest.TestCase):
members = []
for i in range(1, 51):
a = UserA(name='User A %s' % i)
a = UserA(name="User A %s" % i)
a.save()
b = UserB(name='User B %s' % i)
b = UserB(name="User B %s" % i)
b.save()
c = UserC(name='User C %s' % i)
c = UserC(name="User C %s" % i)
c.save()
members += [a, b, c]
@@ -518,7 +528,7 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 4)
for m in group_obj.members:
self.assertIn('User', m.__class__.__name__)
self.assertIn("User", m.__class__.__name__)
# Document select_related
with query_counter() as q:
@@ -534,7 +544,7 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 4)
for m in group_obj.members:
self.assertIn('User', m.__class__.__name__)
self.assertIn("User", m.__class__.__name__)
# Queryset select_related
with query_counter() as q:
@@ -551,8 +561,7 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 4)
for m in group_obj.members:
self.assertIn('User', m.__class__.__name__)
self.assertIn("User", m.__class__.__name__)
def test_generic_reference_orphan_dbref(self):
"""Ensure that generic orphan DBRef items in ListFields are dereferenced.
@@ -577,13 +586,13 @@ class FieldTest(unittest.TestCase):
members = []
for i in range(1, 51):
a = UserA(name='User A %s' % i)
a = UserA(name="User A %s" % i)
a.save()
b = UserB(name='User B %s' % i)
b = UserB(name="User B %s" % i)
b.save()
c = UserC(name='User C %s' % i)
c = UserC(name="User C %s" % i)
c.save()
members += [a, b, c]
@@ -602,11 +611,11 @@ class FieldTest(unittest.TestCase):
[m for m in group_obj.members]
self.assertEqual(q, 4)
self.assertTrue(group_obj._data['members']._dereferenced)
self.assertTrue(group_obj._data["members"]._dereferenced)
[m for m in group_obj.members]
self.assertEqual(q, 4)
self.assertTrue(group_obj._data['members']._dereferenced)
self.assertTrue(group_obj._data["members"]._dereferenced)
UserA.drop_collection()
UserB.drop_collection()
@@ -614,7 +623,6 @@ class FieldTest(unittest.TestCase):
Group.drop_collection()
def test_list_field_complex(self):
class UserA(Document):
name = StringField()
@@ -634,13 +642,13 @@ class FieldTest(unittest.TestCase):
members = []
for i in range(1, 51):
a = UserA(name='User A %s' % i)
a = UserA(name="User A %s" % i)
a.save()
b = UserB(name='User B %s' % i)
b = UserB(name="User B %s" % i)
b.save()
c = UserC(name='User C %s' % i)
c = UserC(name="User C %s" % i)
c.save()
members += [a, b, c]
@@ -664,7 +672,7 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 4)
for m in group_obj.members:
self.assertIn('User', m.__class__.__name__)
self.assertIn("User", m.__class__.__name__)
# Document select_related
with query_counter() as q:
@@ -680,7 +688,7 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 4)
for m in group_obj.members:
self.assertIn('User', m.__class__.__name__)
self.assertIn("User", m.__class__.__name__)
# Queryset select_related
with query_counter() as q:
@@ -697,7 +705,7 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 4)
for m in group_obj.members:
self.assertIn('User', m.__class__.__name__)
self.assertIn("User", m.__class__.__name__)
UserA.drop_collection()
UserB.drop_collection()
@@ -705,7 +713,6 @@ class FieldTest(unittest.TestCase):
Group.drop_collection()
def test_map_field_reference(self):
class User(Document):
name = StringField()
@@ -717,7 +724,7 @@ class FieldTest(unittest.TestCase):
members = []
for i in range(1, 51):
user = User(name='user %s' % i)
user = User(name="user %s" % i)
user.save()
members.append(user)
@@ -752,7 +759,7 @@ class FieldTest(unittest.TestCase):
for k, m in iteritems(group_obj.members):
self.assertIsInstance(m, User)
# Queryset select_related
# Queryset select_related
with query_counter() as q:
self.assertEqual(q, 0)
@@ -770,7 +777,6 @@ class FieldTest(unittest.TestCase):
Group.drop_collection()
def test_dict_field(self):
class UserA(Document):
name = StringField()
@@ -790,13 +796,13 @@ class FieldTest(unittest.TestCase):
members = []
for i in range(1, 51):
a = UserA(name='User A %s' % i)
a = UserA(name="User A %s" % i)
a.save()
b = UserB(name='User B %s' % i)
b = UserB(name="User B %s" % i)
b.save()
c = UserC(name='User C %s' % i)
c = UserC(name="User C %s" % i)
c.save()
members += [a, b, c]
@@ -819,7 +825,7 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 4)
for k, m in iteritems(group_obj.members):
self.assertIn('User', m.__class__.__name__)
self.assertIn("User", m.__class__.__name__)
# Document select_related
with query_counter() as q:
@@ -835,7 +841,7 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 4)
for k, m in iteritems(group_obj.members):
self.assertIn('User', m.__class__.__name__)
self.assertIn("User", m.__class__.__name__)
# Queryset select_related
with query_counter() as q:
@@ -852,7 +858,7 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 4)
for k, m in iteritems(group_obj.members):
self.assertIn('User', m.__class__.__name__)
self.assertIn("User", m.__class__.__name__)
Group.objects.delete()
Group().save()
@@ -873,10 +879,9 @@ class FieldTest(unittest.TestCase):
Group.drop_collection()
def test_dict_field_no_field_inheritance(self):
class UserA(Document):
name = StringField()
meta = {'allow_inheritance': False}
meta = {"allow_inheritance": False}
class Group(Document):
members = DictField()
@@ -886,7 +891,7 @@ class FieldTest(unittest.TestCase):
members = []
for i in range(1, 51):
a = UserA(name='User A %s' % i)
a = UserA(name="User A %s" % i)
a.save()
members += [a]
@@ -949,7 +954,6 @@ class FieldTest(unittest.TestCase):
Group.drop_collection()
def test_generic_reference_map_field(self):
class UserA(Document):
name = StringField()
@@ -969,13 +973,13 @@ class FieldTest(unittest.TestCase):
members = []
for i in range(1, 51):
a = UserA(name='User A %s' % i)
a = UserA(name="User A %s" % i)
a.save()
b = UserB(name='User B %s' % i)
b = UserB(name="User B %s" % i)
b.save()
c = UserC(name='User C %s' % i)
c = UserC(name="User C %s" % i)
c.save()
members += [a, b, c]
@@ -998,7 +1002,7 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 4)
for k, m in iteritems(group_obj.members):
self.assertIn('User', m.__class__.__name__)
self.assertIn("User", m.__class__.__name__)
# Document select_related
with query_counter() as q:
@@ -1014,7 +1018,7 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 4)
for k, m in iteritems(group_obj.members):
self.assertIn('User', m.__class__.__name__)
self.assertIn("User", m.__class__.__name__)
# Queryset select_related
with query_counter() as q:
@@ -1031,7 +1035,7 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 4)
for k, m in iteritems(group_obj.members):
self.assertIn('User', m.__class__.__name__)
self.assertIn("User", m.__class__.__name__)
Group.objects.delete()
Group().save()
@@ -1051,7 +1055,6 @@ class FieldTest(unittest.TestCase):
Group.drop_collection()
def test_multidirectional_lists(self):
class Asset(Document):
name = StringField(max_length=250, required=True)
path = StringField()
@@ -1062,10 +1065,10 @@ class FieldTest(unittest.TestCase):
Asset.drop_collection()
root = Asset(name='', path="/", title="Site Root")
root = Asset(name="", path="/", title="Site Root")
root.save()
company = Asset(name='company', title='Company', parent=root, parents=[root])
company = Asset(name="company", title="Company", parent=root, parents=[root])
company.save()
root.children = [company]
@@ -1076,7 +1079,6 @@ class FieldTest(unittest.TestCase):
self.assertEqual(company.parents, [root])
def test_dict_in_dbref_instance(self):
class Person(Document):
name = StringField(max_length=250, required=True)
@@ -1087,34 +1089,35 @@ class FieldTest(unittest.TestCase):
Person.drop_collection()
Room.drop_collection()
bob = Person.objects.create(name='Bob')
bob = Person.objects.create(name="Bob")
bob.save()
sarah = Person.objects.create(name='Sarah')
sarah = Person.objects.create(name="Sarah")
sarah.save()
room_101 = Room.objects.create(number="101")
room_101.staffs_with_position = [
{'position_key': 'window', 'staff': sarah},
{'position_key': 'door', 'staff': bob.to_dbref()}]
{"position_key": "window", "staff": sarah},
{"position_key": "door", "staff": bob.to_dbref()},
]
room_101.save()
room = Room.objects.first().select_related()
self.assertEqual(room.staffs_with_position[0]['staff'], sarah)
self.assertEqual(room.staffs_with_position[1]['staff'], bob)
self.assertEqual(room.staffs_with_position[0]["staff"], sarah)
self.assertEqual(room.staffs_with_position[1]["staff"], bob)
def test_document_reload_no_inheritance(self):
class Foo(Document):
meta = {'allow_inheritance': False}
bar = ReferenceField('Bar')
baz = ReferenceField('Baz')
meta = {"allow_inheritance": False}
bar = ReferenceField("Bar")
baz = ReferenceField("Baz")
class Bar(Document):
meta = {'allow_inheritance': False}
msg = StringField(required=True, default='Blammo!')
meta = {"allow_inheritance": False}
msg = StringField(required=True, default="Blammo!")
class Baz(Document):
meta = {'allow_inheritance': False}
msg = StringField(required=True, default='Kaboom!')
meta = {"allow_inheritance": False}
msg = StringField(required=True, default="Kaboom!")
Foo.drop_collection()
Bar.drop_collection()
@@ -1138,11 +1141,14 @@ class FieldTest(unittest.TestCase):
Ensure reloading a document with multiple similar id
in different collections doesn't mix them.
"""
class Topic(Document):
id = IntField(primary_key=True)
class User(Document):
id = IntField(primary_key=True)
name = StringField()
class Message(Document):
id = IntField(primary_key=True)
topic = ReferenceField(Topic)
@@ -1154,23 +1160,24 @@ class FieldTest(unittest.TestCase):
# All objects share the same id, but each in a different collection
topic = Topic(id=1).save()
user = User(id=1, name='user-name').save()
user = User(id=1, name="user-name").save()
Message(id=1, topic=topic, author=user).save()
concurrent_change_user = User.objects.get(id=1)
concurrent_change_user.name = 'new-name'
concurrent_change_user.name = "new-name"
concurrent_change_user.save()
self.assertNotEqual(user.name, 'new-name')
self.assertNotEqual(user.name, "new-name")
msg = Message.objects.get(id=1)
msg.reload()
self.assertEqual(msg.topic, topic)
self.assertEqual(msg.author, user)
self.assertEqual(msg.author.name, 'new-name')
self.assertEqual(msg.author.name, "new-name")
def test_list_lookup_not_checked_in_map(self):
"""Ensure we dereference list data correctly
"""
class Comment(Document):
id = IntField(primary_key=True)
text = StringField()
@@ -1182,8 +1189,8 @@ class FieldTest(unittest.TestCase):
Comment.drop_collection()
Message.drop_collection()
c1 = Comment(id=0, text='zero').save()
c2 = Comment(id=1, text='one').save()
c1 = Comment(id=0, text="zero").save()
c2 = Comment(id=1, text="one").save()
Message(id=1, comments=[c1, c2]).save()
msg = Message.objects.get(id=1)
@@ -1193,6 +1200,7 @@ class FieldTest(unittest.TestCase):
def test_list_item_dereference_dref_false_save_doesnt_cause_extra_queries(self):
"""Ensure that DBRef items in ListFields are dereferenced.
"""
class User(Document):
name = StringField()
@@ -1204,7 +1212,7 @@ class FieldTest(unittest.TestCase):
Group.drop_collection()
for i in range(1, 51):
User(name='user %s' % i).save()
User(name="user %s" % i).save()
Group(name="Test", members=User.objects).save()
@@ -1222,6 +1230,7 @@ class FieldTest(unittest.TestCase):
def test_list_item_dereference_dref_true_save_doesnt_cause_extra_queries(self):
"""Ensure that DBRef items in ListFields are dereferenced.
"""
class User(Document):
name = StringField()
@@ -1233,7 +1242,7 @@ class FieldTest(unittest.TestCase):
Group.drop_collection()
for i in range(1, 51):
User(name='user %s' % i).save()
User(name="user %s" % i).save()
Group(name="Test", members=User.objects).save()
@@ -1249,7 +1258,6 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 2)
def test_generic_reference_save_doesnt_cause_extra_queries(self):
class UserA(Document):
name = StringField()
@@ -1270,9 +1278,9 @@ class FieldTest(unittest.TestCase):
members = []
for i in range(1, 51):
a = UserA(name='User A %s' % i).save()
b = UserB(name='User B %s' % i).save()
c = UserC(name='User C %s' % i).save()
a = UserA(name="User A %s" % i).save()
b = UserB(name="User B %s" % i).save()
c = UserC(name="User C %s" % i).save()
members += [a, b, c]
@@ -1292,7 +1300,7 @@ class FieldTest(unittest.TestCase):
def test_objectid_reference_across_databases(self):
# mongoenginetest - Is default connection alias from setUp()
# Register Aliases
register_connection('testdb-1', 'mongoenginetest2')
register_connection("testdb-1", "mongoenginetest2")
class User(Document):
name = StringField()
@@ -1311,16 +1319,17 @@ class FieldTest(unittest.TestCase):
# Can't use query_counter across databases - so test the _data object
book = Book.objects.first()
self.assertNotIsInstance(book._data['author'], User)
self.assertNotIsInstance(book._data["author"], User)
book.select_related()
self.assertIsInstance(book._data['author'], User)
self.assertIsInstance(book._data["author"], User)
def test_non_ascii_pk(self):
"""
Ensure that dbref conversion to string does not fail when
non-ascii characters are used in primary key
"""
class Brand(Document):
title = StringField(max_length=255, primary_key=True)
@@ -1341,7 +1350,7 @@ class FieldTest(unittest.TestCase):
def test_dereferencing_embedded_listfield_referencefield(self):
class Tag(Document):
meta = {'collection': 'tags'}
meta = {"collection": "tags"}
name = StringField()
class Post(EmbeddedDocument):
@@ -1349,22 +1358,21 @@ class FieldTest(unittest.TestCase):
tags = ListField(ReferenceField("Tag", dbref=True))
class Page(Document):
meta = {'collection': 'pages'}
meta = {"collection": "pages"}
tags = ListField(ReferenceField("Tag", dbref=True))
posts = ListField(EmbeddedDocumentField(Post))
Tag.drop_collection()
Page.drop_collection()
tag = Tag(name='test').save()
post = Post(body='test body', tags=[tag])
tag = Tag(name="test").save()
post = Post(body="test body", tags=[tag])
Page(tags=[tag], posts=[post]).save()
page = Page.objects.first()
self.assertEqual(page.tags[0], page.posts[0].tags[0])
def test_select_related_follows_embedded_referencefields(self):
class Song(Document):
title = StringField()
@@ -1390,5 +1398,5 @@ class FieldTest(unittest.TestCase):
self.assertEqual(q, 2)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -12,7 +12,6 @@ READ_PREF = ReadPreference.SECONDARY
class ConnectionTest(unittest.TestCase):
def setUp(self):
mongoengine.connection._connection_settings = {}
mongoengine.connection._connections = {}
@@ -28,9 +27,11 @@ class ConnectionTest(unittest.TestCase):
"""
try:
conn = mongoengine.connect(db='mongoenginetest',
host="mongodb://localhost/mongoenginetest?replicaSet=rs",
read_preference=READ_PREF)
conn = mongoengine.connect(
db="mongoenginetest",
host="mongodb://localhost/mongoenginetest?replicaSet=rs",
read_preference=READ_PREF,
)
except MongoEngineConnectionError as e:
return
@@ -41,5 +42,5 @@ class ConnectionTest(unittest.TestCase):
self.assertEqual(conn.read_preference, READ_PREF)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -20,7 +20,7 @@ class SignalTests(unittest.TestCase):
return signal_output
def setUp(self):
connect(db='mongoenginetest')
connect(db="mongoenginetest")
class Author(Document):
# Make the id deterministic for easier testing
@@ -32,60 +32,63 @@ class SignalTests(unittest.TestCase):
@classmethod
def pre_init(cls, sender, document, *args, **kwargs):
signal_output.append('pre_init signal, %s' % cls.__name__)
signal_output.append(kwargs['values'])
signal_output.append("pre_init signal, %s" % cls.__name__)
signal_output.append(kwargs["values"])
@classmethod
def post_init(cls, sender, document, **kwargs):
signal_output.append('post_init signal, %s, document._created = %s' % (document, document._created))
signal_output.append(
"post_init signal, %s, document._created = %s"
% (document, document._created)
)
@classmethod
def pre_save(cls, sender, document, **kwargs):
signal_output.append('pre_save signal, %s' % document)
signal_output.append("pre_save signal, %s" % document)
signal_output.append(kwargs)
@classmethod
def pre_save_post_validation(cls, sender, document, **kwargs):
signal_output.append('pre_save_post_validation signal, %s' % document)
if kwargs.pop('created', False):
signal_output.append('Is created')
signal_output.append("pre_save_post_validation signal, %s" % document)
if kwargs.pop("created", False):
signal_output.append("Is created")
else:
signal_output.append('Is updated')
signal_output.append("Is updated")
signal_output.append(kwargs)
@classmethod
def post_save(cls, sender, document, **kwargs):
dirty_keys = document._delta()[0].keys() + document._delta()[1].keys()
signal_output.append('post_save signal, %s' % document)
signal_output.append('post_save dirty keys, %s' % dirty_keys)
if kwargs.pop('created', False):
signal_output.append('Is created')
signal_output.append("post_save signal, %s" % document)
signal_output.append("post_save dirty keys, %s" % dirty_keys)
if kwargs.pop("created", False):
signal_output.append("Is created")
else:
signal_output.append('Is updated')
signal_output.append("Is updated")
signal_output.append(kwargs)
@classmethod
def pre_delete(cls, sender, document, **kwargs):
signal_output.append('pre_delete signal, %s' % document)
signal_output.append("pre_delete signal, %s" % document)
signal_output.append(kwargs)
@classmethod
def post_delete(cls, sender, document, **kwargs):
signal_output.append('post_delete signal, %s' % document)
signal_output.append("post_delete signal, %s" % document)
signal_output.append(kwargs)
@classmethod
def pre_bulk_insert(cls, sender, documents, **kwargs):
signal_output.append('pre_bulk_insert signal, %s' % documents)
signal_output.append("pre_bulk_insert signal, %s" % documents)
signal_output.append(kwargs)
@classmethod
def post_bulk_insert(cls, sender, documents, **kwargs):
signal_output.append('post_bulk_insert signal, %s' % documents)
if kwargs.pop('loaded', False):
signal_output.append('Is loaded')
signal_output.append("post_bulk_insert signal, %s" % documents)
if kwargs.pop("loaded", False):
signal_output.append("Is loaded")
else:
signal_output.append('Not loaded')
signal_output.append("Not loaded")
signal_output.append(kwargs)
self.Author = Author
@@ -101,12 +104,12 @@ class SignalTests(unittest.TestCase):
@classmethod
def pre_delete(cls, sender, document, **kwargs):
signal_output.append('pre_delete signal, %s' % document)
signal_output.append("pre_delete signal, %s" % document)
signal_output.append(kwargs)
@classmethod
def post_delete(cls, sender, document, **kwargs):
signal_output.append('post_delete signal, %s' % document)
signal_output.append("post_delete signal, %s" % document)
signal_output.append(kwargs)
self.Another = Another
@@ -117,11 +120,11 @@ class SignalTests(unittest.TestCase):
@classmethod
def post_save(cls, sender, document, **kwargs):
if 'created' in kwargs:
if kwargs['created']:
signal_output.append('Is created')
if "created" in kwargs:
if kwargs["created"]:
signal_output.append("Is created")
else:
signal_output.append('Is updated')
signal_output.append("Is updated")
self.ExplicitId = ExplicitId
ExplicitId.drop_collection()
@@ -136,9 +139,13 @@ class SignalTests(unittest.TestCase):
@classmethod
def pre_bulk_insert(cls, sender, documents, **kwargs):
signal_output.append('pre_bulk_insert signal, %s' %
[(doc, {'active': documents[n].active})
for n, doc in enumerate(documents)])
signal_output.append(
"pre_bulk_insert signal, %s"
% [
(doc, {"active": documents[n].active})
for n, doc in enumerate(documents)
]
)
# make changes here, this is just an example -
# it could be anything that needs pre-validation or looks-ups before bulk bulk inserting
@@ -149,13 +156,17 @@ class SignalTests(unittest.TestCase):
@classmethod
def post_bulk_insert(cls, sender, documents, **kwargs):
signal_output.append('post_bulk_insert signal, %s' %
[(doc, {'active': documents[n].active})
for n, doc in enumerate(documents)])
if kwargs.pop('loaded', False):
signal_output.append('Is loaded')
signal_output.append(
"post_bulk_insert signal, %s"
% [
(doc, {"active": documents[n].active})
for n, doc in enumerate(documents)
]
)
if kwargs.pop("loaded", False):
signal_output.append("Is loaded")
else:
signal_output.append('Not loaded')
signal_output.append("Not loaded")
signal_output.append(kwargs)
self.Post = Post
@@ -178,7 +189,9 @@ class SignalTests(unittest.TestCase):
signals.pre_init.connect(Author.pre_init, sender=Author)
signals.post_init.connect(Author.post_init, sender=Author)
signals.pre_save.connect(Author.pre_save, sender=Author)
signals.pre_save_post_validation.connect(Author.pre_save_post_validation, sender=Author)
signals.pre_save_post_validation.connect(
Author.pre_save_post_validation, sender=Author
)
signals.post_save.connect(Author.post_save, sender=Author)
signals.pre_delete.connect(Author.pre_delete, sender=Author)
signals.post_delete.connect(Author.post_delete, sender=Author)
@@ -199,7 +212,9 @@ class SignalTests(unittest.TestCase):
signals.post_delete.disconnect(self.Author.post_delete)
signals.pre_delete.disconnect(self.Author.pre_delete)
signals.post_save.disconnect(self.Author.post_save)
signals.pre_save_post_validation.disconnect(self.Author.pre_save_post_validation)
signals.pre_save_post_validation.disconnect(
self.Author.pre_save_post_validation
)
signals.pre_save.disconnect(self.Author.pre_save)
signals.pre_bulk_insert.disconnect(self.Author.pre_bulk_insert)
signals.post_bulk_insert.disconnect(self.Author.post_bulk_insert)
@@ -236,203 +251,236 @@ class SignalTests(unittest.TestCase):
""" Model saves should throw some signals. """
def create_author():
self.Author(name='Bill Shakespeare')
self.Author(name="Bill Shakespeare")
def bulk_create_author_with_load():
a1 = self.Author(name='Bill Shakespeare')
a1 = self.Author(name="Bill Shakespeare")
self.Author.objects.insert([a1], load_bulk=True)
def bulk_create_author_without_load():
a1 = self.Author(name='Bill Shakespeare')
a1 = self.Author(name="Bill Shakespeare")
self.Author.objects.insert([a1], load_bulk=False)
def load_existing_author():
a = self.Author(name='Bill Shakespeare')
a = self.Author(name="Bill Shakespeare")
a.save()
self.get_signal_output(lambda: None) # eliminate signal output
a1 = self.Author.objects(name='Bill Shakespeare')[0]
a1 = self.Author.objects(name="Bill Shakespeare")[0]
self.assertEqual(self.get_signal_output(create_author), [
"pre_init signal, Author",
{'name': 'Bill Shakespeare'},
"post_init signal, Bill Shakespeare, document._created = True",
])
self.assertEqual(
self.get_signal_output(create_author),
[
"pre_init signal, Author",
{"name": "Bill Shakespeare"},
"post_init signal, Bill Shakespeare, document._created = True",
],
)
a1 = self.Author(name='Bill Shakespeare')
self.assertEqual(self.get_signal_output(a1.save), [
"pre_save signal, Bill Shakespeare",
{},
"pre_save_post_validation signal, Bill Shakespeare",
"Is created",
{},
"post_save signal, Bill Shakespeare",
"post_save dirty keys, ['name']",
"Is created",
{}
])
a1 = self.Author(name="Bill Shakespeare")
self.assertEqual(
self.get_signal_output(a1.save),
[
"pre_save signal, Bill Shakespeare",
{},
"pre_save_post_validation signal, Bill Shakespeare",
"Is created",
{},
"post_save signal, Bill Shakespeare",
"post_save dirty keys, ['name']",
"Is created",
{},
],
)
a1.reload()
a1.name = 'William Shakespeare'
self.assertEqual(self.get_signal_output(a1.save), [
"pre_save signal, William Shakespeare",
{},
"pre_save_post_validation signal, William Shakespeare",
"Is updated",
{},
"post_save signal, William Shakespeare",
"post_save dirty keys, ['name']",
"Is updated",
{}
])
a1.name = "William Shakespeare"
self.assertEqual(
self.get_signal_output(a1.save),
[
"pre_save signal, William Shakespeare",
{},
"pre_save_post_validation signal, William Shakespeare",
"Is updated",
{},
"post_save signal, William Shakespeare",
"post_save dirty keys, ['name']",
"Is updated",
{},
],
)
self.assertEqual(self.get_signal_output(a1.delete), [
'pre_delete signal, William Shakespeare',
{},
'post_delete signal, William Shakespeare',
{}
])
self.assertEqual(
self.get_signal_output(a1.delete),
[
"pre_delete signal, William Shakespeare",
{},
"post_delete signal, William Shakespeare",
{},
],
)
self.assertEqual(self.get_signal_output(load_existing_author), [
"pre_init signal, Author",
{'id': 2, 'name': 'Bill Shakespeare'},
"post_init signal, Bill Shakespeare, document._created = False"
])
self.assertEqual(
self.get_signal_output(load_existing_author),
[
"pre_init signal, Author",
{"id": 2, "name": "Bill Shakespeare"},
"post_init signal, Bill Shakespeare, document._created = False",
],
)
self.assertEqual(self.get_signal_output(bulk_create_author_with_load), [
'pre_init signal, Author',
{'name': 'Bill Shakespeare'},
'post_init signal, Bill Shakespeare, document._created = True',
'pre_bulk_insert signal, [<Author: Bill Shakespeare>]',
{},
'pre_init signal, Author',
{'id': 3, 'name': 'Bill Shakespeare'},
'post_init signal, Bill Shakespeare, document._created = False',
'post_bulk_insert signal, [<Author: Bill Shakespeare>]',
'Is loaded',
{}
])
self.assertEqual(
self.get_signal_output(bulk_create_author_with_load),
[
"pre_init signal, Author",
{"name": "Bill Shakespeare"},
"post_init signal, Bill Shakespeare, document._created = True",
"pre_bulk_insert signal, [<Author: Bill Shakespeare>]",
{},
"pre_init signal, Author",
{"id": 3, "name": "Bill Shakespeare"},
"post_init signal, Bill Shakespeare, document._created = False",
"post_bulk_insert signal, [<Author: Bill Shakespeare>]",
"Is loaded",
{},
],
)
self.assertEqual(self.get_signal_output(bulk_create_author_without_load), [
"pre_init signal, Author",
{'name': 'Bill Shakespeare'},
"post_init signal, Bill Shakespeare, document._created = True",
"pre_bulk_insert signal, [<Author: Bill Shakespeare>]",
{},
"post_bulk_insert signal, [<Author: Bill Shakespeare>]",
"Not loaded",
{}
])
self.assertEqual(
self.get_signal_output(bulk_create_author_without_load),
[
"pre_init signal, Author",
{"name": "Bill Shakespeare"},
"post_init signal, Bill Shakespeare, document._created = True",
"pre_bulk_insert signal, [<Author: Bill Shakespeare>]",
{},
"post_bulk_insert signal, [<Author: Bill Shakespeare>]",
"Not loaded",
{},
],
)
def test_signal_kwargs(self):
""" Make sure signal_kwargs is passed to signals calls. """
def live_and_let_die():
a = self.Author(name='Bill Shakespeare')
a.save(signal_kwargs={'live': True, 'die': False})
a.delete(signal_kwargs={'live': False, 'die': True})
a = self.Author(name="Bill Shakespeare")
a.save(signal_kwargs={"live": True, "die": False})
a.delete(signal_kwargs={"live": False, "die": True})
self.assertEqual(self.get_signal_output(live_and_let_die), [
"pre_init signal, Author",
{'name': 'Bill Shakespeare'},
"post_init signal, Bill Shakespeare, document._created = True",
"pre_save signal, Bill Shakespeare",
{'die': False, 'live': True},
"pre_save_post_validation signal, Bill Shakespeare",
"Is created",
{'die': False, 'live': True},
"post_save signal, Bill Shakespeare",
"post_save dirty keys, ['name']",
"Is created",
{'die': False, 'live': True},
'pre_delete signal, Bill Shakespeare',
{'die': True, 'live': False},
'post_delete signal, Bill Shakespeare',
{'die': True, 'live': False}
])
self.assertEqual(
self.get_signal_output(live_and_let_die),
[
"pre_init signal, Author",
{"name": "Bill Shakespeare"},
"post_init signal, Bill Shakespeare, document._created = True",
"pre_save signal, Bill Shakespeare",
{"die": False, "live": True},
"pre_save_post_validation signal, Bill Shakespeare",
"Is created",
{"die": False, "live": True},
"post_save signal, Bill Shakespeare",
"post_save dirty keys, ['name']",
"Is created",
{"die": False, "live": True},
"pre_delete signal, Bill Shakespeare",
{"die": True, "live": False},
"post_delete signal, Bill Shakespeare",
{"die": True, "live": False},
],
)
def bulk_create_author():
a1 = self.Author(name='Bill Shakespeare')
self.Author.objects.insert([a1], signal_kwargs={'key': True})
a1 = self.Author(name="Bill Shakespeare")
self.Author.objects.insert([a1], signal_kwargs={"key": True})
self.assertEqual(self.get_signal_output(bulk_create_author), [
'pre_init signal, Author',
{'name': 'Bill Shakespeare'},
'post_init signal, Bill Shakespeare, document._created = True',
'pre_bulk_insert signal, [<Author: Bill Shakespeare>]',
{'key': True},
'pre_init signal, Author',
{'id': 2, 'name': 'Bill Shakespeare'},
'post_init signal, Bill Shakespeare, document._created = False',
'post_bulk_insert signal, [<Author: Bill Shakespeare>]',
'Is loaded',
{'key': True}
])
self.assertEqual(
self.get_signal_output(bulk_create_author),
[
"pre_init signal, Author",
{"name": "Bill Shakespeare"},
"post_init signal, Bill Shakespeare, document._created = True",
"pre_bulk_insert signal, [<Author: Bill Shakespeare>]",
{"key": True},
"pre_init signal, Author",
{"id": 2, "name": "Bill Shakespeare"},
"post_init signal, Bill Shakespeare, document._created = False",
"post_bulk_insert signal, [<Author: Bill Shakespeare>]",
"Is loaded",
{"key": True},
],
)
def test_queryset_delete_signals(self):
""" Queryset delete should throw some signals. """
self.Another(name='Bill Shakespeare').save()
self.assertEqual(self.get_signal_output(self.Another.objects.delete), [
'pre_delete signal, Bill Shakespeare',
{},
'post_delete signal, Bill Shakespeare',
{}
])
self.Another(name="Bill Shakespeare").save()
self.assertEqual(
self.get_signal_output(self.Another.objects.delete),
[
"pre_delete signal, Bill Shakespeare",
{},
"post_delete signal, Bill Shakespeare",
{},
],
)
def test_signals_with_explicit_doc_ids(self):
""" Model saves must have a created flag the first time."""
ei = self.ExplicitId(id=123)
# post save must received the created flag, even if there's already
# an object id present
self.assertEqual(self.get_signal_output(ei.save), ['Is created'])
self.assertEqual(self.get_signal_output(ei.save), ["Is created"])
# second time, it must be an update
self.assertEqual(self.get_signal_output(ei.save), ['Is updated'])
self.assertEqual(self.get_signal_output(ei.save), ["Is updated"])
def test_signals_with_switch_collection(self):
ei = self.ExplicitId(id=123)
ei.switch_collection("explicit__1")
self.assertEqual(self.get_signal_output(ei.save), ['Is created'])
self.assertEqual(self.get_signal_output(ei.save), ["Is created"])
ei.switch_collection("explicit__1")
self.assertEqual(self.get_signal_output(ei.save), ['Is updated'])
self.assertEqual(self.get_signal_output(ei.save), ["Is updated"])
ei.switch_collection("explicit__1", keep_created=False)
self.assertEqual(self.get_signal_output(ei.save), ['Is created'])
self.assertEqual(self.get_signal_output(ei.save), ["Is created"])
ei.switch_collection("explicit__1", keep_created=False)
self.assertEqual(self.get_signal_output(ei.save), ['Is created'])
self.assertEqual(self.get_signal_output(ei.save), ["Is created"])
def test_signals_with_switch_db(self):
connect('mongoenginetest')
register_connection('testdb-1', 'mongoenginetest2')
connect("mongoenginetest")
register_connection("testdb-1", "mongoenginetest2")
ei = self.ExplicitId(id=123)
ei.switch_db("testdb-1")
self.assertEqual(self.get_signal_output(ei.save), ['Is created'])
self.assertEqual(self.get_signal_output(ei.save), ["Is created"])
ei.switch_db("testdb-1")
self.assertEqual(self.get_signal_output(ei.save), ['Is updated'])
self.assertEqual(self.get_signal_output(ei.save), ["Is updated"])
ei.switch_db("testdb-1", keep_created=False)
self.assertEqual(self.get_signal_output(ei.save), ['Is created'])
self.assertEqual(self.get_signal_output(ei.save), ["Is created"])
ei.switch_db("testdb-1", keep_created=False)
self.assertEqual(self.get_signal_output(ei.save), ['Is created'])
self.assertEqual(self.get_signal_output(ei.save), ["Is created"])
def test_signals_bulk_insert(self):
def bulk_set_active_post():
posts = [
self.Post(title='Post 1'),
self.Post(title='Post 2'),
self.Post(title='Post 3')
self.Post(title="Post 1"),
self.Post(title="Post 2"),
self.Post(title="Post 3"),
]
self.Post.objects.insert(posts)
results = self.get_signal_output(bulk_set_active_post)
self.assertEqual(results, [
"pre_bulk_insert signal, [(<Post: Post 1>, {'active': False}), (<Post: Post 2>, {'active': False}), (<Post: Post 3>, {'active': False})]",
{},
"post_bulk_insert signal, [(<Post: Post 1>, {'active': True}), (<Post: Post 2>, {'active': True}), (<Post: Post 3>, {'active': True})]",
'Is loaded',
{}
])
self.assertEqual(
results,
[
"pre_bulk_insert signal, [(<Post: Post 1>, {'active': False}), (<Post: Post 2>, {'active': False}), (<Post: Post 3>, {'active': False})]",
{},
"post_bulk_insert signal, [(<Post: Post 1>, {'active': True}), (<Post: Post 2>, {'active': True}), (<Post: Post 3>, {'active': True})]",
"Is loaded",
{},
],
)
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View File

@@ -7,32 +7,33 @@ signal_output = []
class LazyRegexCompilerTest(unittest.TestCase):
def test_lazy_regex_compiler_verify_laziness_of_descriptor(self):
class UserEmail(object):
EMAIL_REGEX = LazyRegexCompiler('@', flags=32)
EMAIL_REGEX = LazyRegexCompiler("@", flags=32)
descriptor = UserEmail.__dict__['EMAIL_REGEX']
descriptor = UserEmail.__dict__["EMAIL_REGEX"]
self.assertIsNone(descriptor._compiled_regex)
regex = UserEmail.EMAIL_REGEX
self.assertEqual(regex, re.compile('@', flags=32))
self.assertEqual(regex.search('user@domain.com').group(), '@')
self.assertEqual(regex, re.compile("@", flags=32))
self.assertEqual(regex.search("user@domain.com").group(), "@")
user_email = UserEmail()
self.assertIs(user_email.EMAIL_REGEX, UserEmail.EMAIL_REGEX)
def test_lazy_regex_compiler_verify_cannot_set_descriptor_on_instance(self):
class UserEmail(object):
EMAIL_REGEX = LazyRegexCompiler('@')
EMAIL_REGEX = LazyRegexCompiler("@")
user_email = UserEmail()
with self.assertRaises(AttributeError):
user_email.EMAIL_REGEX = re.compile('@')
user_email.EMAIL_REGEX = re.compile("@")
def test_lazy_regex_compiler_verify_can_override_class_attr(self):
class UserEmail(object):
EMAIL_REGEX = LazyRegexCompiler('@')
EMAIL_REGEX = LazyRegexCompiler("@")
UserEmail.EMAIL_REGEX = re.compile('cookies')
self.assertEqual(UserEmail.EMAIL_REGEX.search('Cake & cookies').group(), 'cookies')
UserEmail.EMAIL_REGEX = re.compile("cookies")
self.assertEqual(
UserEmail.EMAIL_REGEX.search("Cake & cookies").group(), "cookies"
)

View File

@@ -8,7 +8,7 @@ from mongoengine.connection import get_db, disconnect_all
from mongoengine.mongodb_support import get_mongodb_version
MONGO_TEST_DB = 'mongoenginetest' # standard name for the test database
MONGO_TEST_DB = "mongoenginetest" # standard name for the test database
class MongoDBTestCase(unittest.TestCase):
@@ -53,12 +53,15 @@ def _decorated_with_ver_requirement(func, mongo_version_req, oper):
:param mongo_version_req: The mongodb version requirement (tuple(int, int))
:param oper: The operator to apply (e.g: operator.ge)
"""
def _inner(*args, **kwargs):
mongodb_v = get_mongodb_version()
if oper(mongodb_v, mongo_version_req):
return func(*args, **kwargs)
raise SkipTest('Needs MongoDB v{}+'.format('.'.join(str(n) for n in mongo_version_req)))
raise SkipTest(
"Needs MongoDB v{}+".format(".".join(str(n) for n in mongo_version_req))
)
_inner.__name__ = func.__name__
_inner.__doc__ = func.__doc__