from __future__ import with_statement import pickle from datetime import date, datetime, timedelta from django.db import models from django.db.models.fields import FieldDoesNotExist from django.core.exceptions import ImproperlyConfigured from django.test import TestCase from model_utils import Choices from model_utils.fields import get_excerpt, MonitorField from model_utils.managers import QueryManager from model_utils.models import StatusModel, TimeFramedModel from model_utils.tests.models import ( InheritanceManagerTestRelated, InheritanceManagerTestParent, InheritanceManagerTestChild1, InheritanceManagerTestChild2, TimeStamp, Post, Article, Status, StatusPlainTuple, TimeFrame, Monitored, StatusManagerAdded, TimeFrameManagerAdded, Dude, SplitFieldAbstractParent, Car, Spot, Person) class GetExcerptTests(TestCase): def test_split(self): e = get_excerpt("some content\n\n\n\nsome more") self.assertEquals(e, 'some content\n') def test_auto_split(self): e = get_excerpt("para one\n\npara two\n\npara three") self.assertEquals(e, 'para one\n\npara two') def test_middle_of_para(self): e = get_excerpt("some text\n\nmore text") self.assertEquals(e, 'some text') def test_middle_of_line(self): e = get_excerpt("some text more text") self.assertEquals(e, "some text more text") class SplitFieldTests(TestCase): full_text = u'summary\n\n\n\nmore' excerpt = u'summary\n' def setUp(self): self.post = Article.objects.create( title='example post', body=self.full_text) def test_unicode_content(self): self.assertEquals(unicode(self.post.body), self.full_text) def test_excerpt(self): self.assertEquals(self.post.body.excerpt, self.excerpt) def test_content(self): self.assertEquals(self.post.body.content, self.full_text) def test_has_more(self): self.failUnless(self.post.body.has_more) def test_not_has_more(self): post = Article.objects.create(title='example 2', body='some text\n\nsome more\n') self.failIf(post.body.has_more) def test_load_back(self): post = Article.objects.get(pk=self.post.pk) self.assertEquals(post.body.content, self.post.body.content) self.assertEquals(post.body.excerpt, self.post.body.excerpt) def test_assign_to_body(self): new_text = u'different\n\n\n\nother' self.post.body = new_text self.post.save() self.assertEquals(unicode(self.post.body), new_text) def test_assign_to_content(self): new_text = u'different\n\n\n\nother' self.post.body.content = new_text self.post.save() self.assertEquals(unicode(self.post.body), new_text) def test_assign_to_excerpt(self): def _invalid_assignment(): self.post.body.excerpt = 'this should fail' self.assertRaises(AttributeError, _invalid_assignment) def test_access_via_class(self): def _invalid_access(): Article.body self.assertRaises(AttributeError, _invalid_access) def test_none(self): a = Article(title='Some Title', body=None) self.assertEquals(a.body, None) def test_assign_splittext(self): a = Article(title='Some Title') a.body = self.post.body self.assertEquals(a.body.excerpt, u'summary\n') def test_value_to_string(self): f = self.post._meta.get_field('body') self.assertEquals(f.value_to_string(self.post), self.full_text) def test_abstract_inheritance(self): class Child(SplitFieldAbstractParent): pass self.assertEqual( [f.name for f in Child._meta.fields], ["id", "content", "_content_excerpt"]) class MonitorFieldTests(TestCase): def setUp(self): self.instance = Monitored(name='Charlie') self.created = self.instance.name_changed def test_save_no_change(self): self.instance.save() self.assertEquals(self.instance.name_changed, self.created) def test_save_changed(self): self.instance.name = 'Maria' self.instance.save() self.failUnless(self.instance.name_changed > self.created) def test_double_save(self): self.instance.name = 'Jose' self.instance.save() changed = self.instance.name_changed self.instance.save() self.assertEquals(self.instance.name_changed, changed) def test_no_monitor_arg(self): self.assertRaises(TypeError, MonitorField) class ChoicesTests(TestCase): def setUp(self): self.STATUS = Choices('DRAFT', 'PUBLISHED') def test_getattr(self): self.assertEquals(self.STATUS.DRAFT, 'DRAFT') def test_indexing(self): self.assertEquals(self.STATUS[1], ('PUBLISHED', 'PUBLISHED')) def test_iteration(self): self.assertEquals(tuple(self.STATUS), (('DRAFT', 'DRAFT'), ('PUBLISHED', 'PUBLISHED'))) def test_len(self): self.assertEqual(len(self.STATUS), 2) def test_repr(self): self.assertEquals(repr(self.STATUS), "Choices(" "('DRAFT', 'DRAFT', 'DRAFT'), " "('PUBLISHED', 'PUBLISHED', 'PUBLISHED'))") def test_wrong_length_tuple(self): self.assertRaises(ValueError, Choices, ('a',)) class LabelChoicesTests(ChoicesTests): def setUp(self): self.STATUS = Choices( ('DRAFT', 'is draft'), ('PUBLISHED', 'is published'), 'DELETED', ) def test_iteration(self): self.assertEquals(tuple(self.STATUS), ( ('DRAFT', 'is draft'), ('PUBLISHED', 'is published'), ('DELETED', 'DELETED')) ) def test_indexing(self): self.assertEquals(self.STATUS[1], ('PUBLISHED', 'is published')) def test_default(self): self.assertEquals(self.STATUS.DELETED, 'DELETED') def test_provided(self): self.assertEquals(self.STATUS.DRAFT, 'DRAFT') def test_len(self): self.assertEqual(len(self.STATUS), 3) def test_repr(self): self.assertEquals(repr(self.STATUS), "Choices(" "('DRAFT', 'DRAFT', 'is draft'), " "('PUBLISHED', 'PUBLISHED', 'is published'), " "('DELETED', 'DELETED', 'DELETED'))") class IdentifierChoicesTests(ChoicesTests): def setUp(self): self.STATUS = Choices( (0, 'DRAFT', 'is draft'), (1, 'PUBLISHED', 'is published'), (2, 'DELETED', 'is deleted')) def test_iteration(self): self.assertEqual(tuple(self.STATUS), ( (0, 'is draft'), (1, 'is published'), (2, 'is deleted'))) def test_indexing(self): self.assertEquals(self.STATUS[1], (1, 'is published')) def test_getattr(self): self.assertEquals(self.STATUS.DRAFT, 0) def test_len(self): self.assertEqual(len(self.STATUS), 3) def test_repr(self): self.assertEquals(repr(self.STATUS), "Choices(" "(0, 'DRAFT', 'is draft'), " "(1, 'PUBLISHED', 'is published'), " "(2, 'DELETED', 'is deleted'))") class InheritanceManagerTests(TestCase): def setUp(self): self.child1 = InheritanceManagerTestChild1.objects.create() self.child2 = InheritanceManagerTestChild2.objects.create() def get_manager(self): return InheritanceManagerTestParent.objects def test_normal(self): self.assertEquals(set(self.get_manager().all()), set([ InheritanceManagerTestParent(pk=self.child1.pk), InheritanceManagerTestParent(pk=self.child2.pk), ])) def test_select_all_subclasses(self): self.assertEquals( set(self.get_manager().select_subclasses()), set([self.child1, self.child2])) def test_select_specific_subclasses(self): self.assertEquals( set(self.get_manager().select_subclasses( "inheritancemanagertestchild1")), set([self.child1, InheritanceManagerTestParent(pk=self.child2.pk)])) def test_get_subclass(self): self.assertEquals( self.get_manager().get_subclass(pk=self.child1.pk), self.child1) class InheritanceManagerRelatedTests(InheritanceManagerTests): def setUp(self): self.related = InheritanceManagerTestRelated.objects.create() self.child1 = InheritanceManagerTestChild1.objects.create( related=self.related) self.child2 = InheritanceManagerTestChild2.objects.create( related=self.related) def get_manager(self): return self.related.imtests def test_get_method_with_select_subclasses(self): self.assertEqual( InheritanceManagerTestParent.objects.select_subclasses().get( id=self.child1.id), self.child1) def test_annotate_with_select_subclasses(self): qs = InheritanceManagerTestParent.objects.select_subclasses().annotate( models.Count('id')) self.assertEqual(qs.get(id=self.child1.id).id__count, 1) def test_annotate_with_named_arguments_with_select_subclasses(self): qs = InheritanceManagerTestParent.objects.select_subclasses().annotate( test_count=models.Count('id')) self.assertEqual(qs.get(id=self.child1.id).test_count, 1) def test_annotate_before_select_subclasses(self): qs = InheritanceManagerTestParent.objects.annotate( models.Count('id')).select_subclasses() self.assertEqual(qs.get(id=self.child1.id).id__count, 1) def test_annotate_with_named_arguments_before_select_subclasses(self): qs = InheritanceManagerTestParent.objects.annotate( test_count=models.Count('id')).select_subclasses() self.assertEqual(qs.get(id=self.child1.id).test_count, 1) class TimeStampedModelTests(TestCase): def test_created(self): t1 = TimeStamp.objects.create() t2 = TimeStamp.objects.create() self.assert_(t2.created > t1.created) def test_modified(self): t1 = TimeStamp.objects.create() t2 = TimeStamp.objects.create() t1.save() self.assert_(t2.modified < t1.modified) class TimeFramedModelTests(TestCase): def setUp(self): self.now = datetime.now() def test_not_yet_begun(self): TimeFrame.objects.create(start=self.now+timedelta(days=2)) self.assertEquals(TimeFrame.timeframed.count(), 0) def test_finished(self): TimeFrame.objects.create(end=self.now-timedelta(days=1)) self.assertEquals(TimeFrame.timeframed.count(), 0) def test_no_end(self): TimeFrame.objects.create(start=self.now-timedelta(days=10)) self.assertEquals(TimeFrame.timeframed.count(), 1) def test_no_start(self): TimeFrame.objects.create(end=self.now+timedelta(days=2)) self.assertEquals(TimeFrame.timeframed.count(), 1) def test_within_range(self): TimeFrame.objects.create(start=self.now-timedelta(days=1), end=self.now+timedelta(days=1)) self.assertEquals(TimeFrame.timeframed.count(), 1) class TimeFrameManagerAddedTests(TestCase): def test_manager_available(self): self.assert_(isinstance(TimeFrameManagerAdded.timeframed, QueryManager)) def test_conflict_error(self): def _run(): class ErrorModel(TimeFramedModel): timeframed = models.BooleanField() self.assertRaises(ImproperlyConfigured, _run) class StatusModelTests(TestCase): def setUp(self): self.model = Status self.on_hold = Status.STATUS.on_hold self.active = Status.STATUS.active def test_created(self): c1 = self.model.objects.create() c2 = self.model.objects.create() self.assert_(c2.status_changed > c1.status_changed) self.assertEquals(self.model.active.count(), 2) self.assertEquals(self.model.deleted.count(), 0) def test_modification(self): t1 = self.model.objects.create() date_created = t1.status_changed t1.status = self.on_hold t1.save() self.assertEquals(self.model.active.count(), 0) self.assertEquals(self.model.on_hold.count(), 1) self.assert_(t1.status_changed > date_created) date_changed = t1.status_changed t1.save() self.assertEquals(t1.status_changed, date_changed) date_active_again = t1.status_changed t1.status = self.active t1.save() self.assert_(t1.status_changed > date_active_again) class StatusModelPlainTupleTests(StatusModelTests): def setUp(self): self.model = StatusPlainTuple self.on_hold = StatusPlainTuple.STATUS[2][0] self.active = StatusPlainTuple.STATUS[0][0] class StatusManagerAddedTests(TestCase): def test_manager_available(self): self.assert_(isinstance(StatusManagerAdded.active, QueryManager)) def test_conflict_error(self): def _run(): class ErrorModel(StatusModel): STATUS = ( ('active', 'active'), ('deleted', 'deleted'), ) active = models.BooleanField() self.assertRaises(ImproperlyConfigured, _run) class QueryManagerTests(TestCase): def setUp(self): data = ((True, True, 0), (True, False, 4), (False, False, 2), (False, True, 3), (True, True, 1), (True, False, 5)) for p, c, o in data: Post.objects.create(published=p, confirmed=c, order=o) def test_passing_kwargs(self): qs = Post.public.all() self.assertEquals([p.order for p in qs], [0, 1, 4, 5]) def test_passing_Q(self): qs = Post.public_confirmed.all() self.assertEquals([p.order for p in qs], [0, 1]) def test_ordering(self): qs = Post.public_reversed.all() self.assertEquals([p.order for p in qs], [5, 4, 1, 0]) try: from south.modelsinspector import introspector except ImportError: introspector = None # @@@ use skipUnless once Django 1.3 is minimum supported version if introspector: class SouthFreezingTests(TestCase): def test_introspector_adds_no_excerpt_field(self): mf = Article._meta.get_field('body') args, kwargs = introspector(mf) self.assertEquals(kwargs['no_excerpt_field'], 'True') def test_no_excerpt_field_works(self): from models import NoRendered self.assertRaises(FieldDoesNotExist, NoRendered._meta.get_field, '_body_excerpt') class PassThroughManagerTests(TestCase): def setUp(self): Dude.objects.create(name='The Dude', abides=True, has_rug=False) Dude.objects.create(name='His Dudeness', abides=False, has_rug=True) Dude.objects.create(name='Duder', abides=False, has_rug=False) Dude.objects.create(name='El Duderino', abides=True, has_rug=True) def test_chaining(self): self.assertEqual(Dude.objects.by_name('Duder').count(), 1) self.assertEqual(Dude.objects.all().by_name('Duder').count(), 1) self.assertEqual(Dude.abiders.rug_positive().count(), 1) self.assertEqual(Dude.abiders.all().rug_positive().count(), 1) def test_manager_only_methods(self): stats = Dude.abiders.get_stats() self.assertEqual(stats['rug_count'], 1) def notonqs(): Dude.abiders.all().get_stats() self.assertRaises(AttributeError, notonqs) def test_queryset_pickling(self): qs = Dude.objects.all() saltyqs = pickle.dumps(qs) unqs = pickle.loads(saltyqs) self.assertEqual(unqs.by_name('The Dude').count(), 1) def test_queryset_not_available_on_related_manager(self): dude = Dude.objects.by_name('Duder').get() Car.objects.create(name='Ford', owner=dude) self.assertFalse(hasattr(dude.cars_owned, 'by_name')) class CreatePassThroughManagerTests(TestCase): def setUp(self): self.dude = Dude.objects.create(name='El Duderino') Spot.objects.create(name='The Crib', owner=self.dude, closed=True, secure=True) def test_reverse_manager(self): self.assertEqual(self.dude.spots_owned.closed().count(), 1) def test_related_queryset_pickling(self): qs = self.dude.spots_owned.closed() pickled_qs = pickle.dumps(qs) unpickled_qs = pickle.loads(pickled_qs) self.assertEqual(unpickled_qs.secured().count(), 1) class UpdateOrCreateTests(TestCase): def test_update_or_create(self): Person.objects.create( first_name='John', last_name='Lennon', birthday=date(1940, 10, 9) ) p, created = Person.objects.update_or_create( first_name='John', last_name='Lennon', defaults={ 'birthday': date(1970, 10, 9) } ) self.assertFalse(created) self.assertEqual(Person.objects.count(), 1) self.assertEqual(Person.objects.get().birthday, date(1970, 10, 9)) p, created = Person.objects.update_or_create( first_name='George', last_name='Harrison', defaults={ 'birthday': date(1943, 2, 25) } ) self.assertTrue(created) self.assertEqual(Person.objects.count(), 2) # If we execute the exact same statement, it won't create a Person. p, created = Person.objects.update_or_create( first_name='George', last_name='Harrison', defaults={ 'birthday': date(1943, 2, 25) } ) self.assertFalse(created) self.assertEqual(Person.objects.count(), 2) # update_or_create() can take an empty 'defaults' parameter, but in # this situation behaves exactly like get_or_create(). This is useful # if you are building the 'defaults' dictionary dynamically. p, created = Person.objects.update_or_create( first_name='George', last_name='Harrison', defaults={} ) self.assertFalse(created) # A different name with an empty 'defaults'. p, created = Person.objects.update_or_create( first_name='John', last_name='Smith', birthday=date(1950, 2, 10), defaults={} ) self.assertTrue(created) self.assertEqual(Person.objects.count(), 3)