diff --git a/.gitignore b/.gitignore index dde3895..c79189e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .DS_Store *.pyc +/coverage \ No newline at end of file diff --git a/polls/forms.py b/polls/forms.py index 8e81a5e..accb3ef 100644 --- a/polls/forms.py +++ b/polls/forms.py @@ -6,20 +6,22 @@ class PollForm(forms.Form): def __init__(self, *args, **kwargs): # We require an ``instance`` parameter. self.instance = kwargs.pop('instance') - + # We call ``super`` (without the ``instance`` param) to finish # off the setup. super(PollForm, self).__init__(*args, **kwargs) - + # We add on a ``choice`` field based on the instance we've got. # This has to be done here (instead of declaratively) because the # ``Poll`` instance will change from request to request. self.fields['choice'] = forms.ModelChoiceField(queryset=Choice.objects.filter(poll=self.instance.pk), empty_label=None, widget=forms.RadioSelect) - + def save(self): - if not self.is_valid(): + + try: + choice = self.cleaned_data['choice'] + except AttributeError: raise forms.ValidationError("PollForm was not validated first before trying to call 'save'.") - - choice = self.cleaned_data['choice'] + choice.record_vote() return choice diff --git a/polls/tests/forms.py b/polls/tests/forms.py index 783fa66..f10a194 100644 --- a/polls/tests/forms.py +++ b/polls/tests/forms.py @@ -1,57 +1,64 @@ from django.test import TestCase +from django.forms import ValidationError from polls.forms import PollForm -from polls.models import Poll, Choice +from polls.models import Poll class PollFormTestCase(TestCase): fixtures = ['polls_forms_testdata.json'] - + def setUp(self): super(PollFormTestCase, self).setUp() self.poll_1 = Poll.objects.get(pk=1) self.poll_2 = Poll.objects.get(pk=2) - + def test_init(self): # Test successful init without data. form = PollForm(instance=self.poll_1) self.assertTrue(isinstance(form.instance, Poll)) self.assertEqual(form.instance.pk, self.poll_1.pk) self.assertEqual([c for c in form.fields['choice'].choices], [(1, u'Yes'), (2, u'No')]) - + # Test successful init with data. form = PollForm({'choice': 3}, instance=self.poll_2) self.assertTrue(isinstance(form.instance, Poll)) self.assertEqual(form.instance.pk, self.poll_2.pk) self.assertEqual([c for c in form.fields['choice'].choices], [(3, u'Alright.'), (4, u'Meh.'), (5, u'Not so good.')]) - + # Test a failed init without data. self.assertRaises(KeyError, PollForm) - + # Test a failed init with data. self.assertRaises(KeyError, PollForm, {}) - + def test_save(self): self.assertEqual(self.poll_1.choice_set.get(pk=1).votes, 1) self.assertEqual(self.poll_1.choice_set.get(pk=2).votes, 0) - - # Test the first choice. + + # Test non-validate form error. form_1 = PollForm({'choice': 1}, instance=self.poll_1) + self.assertRaises(ValidationError, form_1.save) + + # Test the first choice. + self.assertTrue(form_1.is_valid()) form_1.save() self.assertEqual(self.poll_1.choice_set.get(pk=1).votes, 2) self.assertEqual(self.poll_1.choice_set.get(pk=2).votes, 0) - + # Test the second choice. form_2 = PollForm({'choice': 2}, instance=self.poll_1) + self.assertTrue(form_2.is_valid()) form_2.save() self.assertEqual(self.poll_1.choice_set.get(pk=1).votes, 2) self.assertEqual(self.poll_1.choice_set.get(pk=2).votes, 1) - + # Test the other poll. self.assertEqual(self.poll_2.choice_set.get(pk=3).votes, 1) self.assertEqual(self.poll_2.choice_set.get(pk=4).votes, 0) self.assertEqual(self.poll_2.choice_set.get(pk=5).votes, 0) - + form_3 = PollForm({'choice': 5}, instance=self.poll_2) + self.assertTrue(form_3.is_valid()) form_3.save() self.assertEqual(self.poll_2.choice_set.get(pk=3).votes, 1) self.assertEqual(self.poll_2.choice_set.get(pk=4).votes, 0) diff --git a/settings.py b/settings.py index b23edba..cacc858 100644 --- a/settings.py +++ b/settings.py @@ -11,7 +11,7 @@ DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. + 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 'NAME': 'polls.db', # Or path to database file if using sqlite3. 'USER': '', # Not used with sqlite3. 'PASSWORD': '', # Not used with sqlite3. @@ -115,6 +115,7 @@ 'django.contrib.staticfiles', 'django.contrib.admin', 'django.contrib.admindocs', + 'django_coverage', 'polls', ) @@ -133,10 +134,13 @@ } }, 'loggers': { - 'django.request':{ + 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': True, }, } } + +# Django-coverage settings +COVERAGE_REPORT_HTML_OUTPUT_DIR = os.path.join(PROJECT_ROOT, 'coverage')