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:
@@ -9,5 +9,5 @@ from .instance import *
|
||||
from .json_serialisation import *
|
||||
from .validation import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user