Fixed #12991 -- Added unittest2 support. Thanks to PaulM for the draft patch, and to Luke, Karen, Justin, Alex, Łukasz Rekucki, and Chuck Harmston for their help testing and reviewing the final patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14139 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2010-10-11 12:55:17 +00:00
parent 1070c57b83
commit 121d2e3678
106 changed files with 3841 additions and 1020 deletions

View File

@ -1,7 +1,8 @@
import unittest
import fields
from django.contrib.admindocs import views
from django.db.models import fields as builtin_fields
from django.utils import unittest
import fields
class TestFieldType(unittest.TestCase):

View File

@ -1,8 +1,8 @@
import unittest
from django import forms
from django.contrib.formtools import preview, wizard, utils
from django import http
from django.contrib.formtools import preview, wizard, utils
from django.test import TestCase
from django.utils import unittest
success_string = "Done was called!"
@ -115,7 +115,7 @@ class SecurityHashTests(unittest.TestCase):
hash1 = utils.security_hash(None, f1)
hash2 = utils.security_hash(None, f2)
self.assertEqual(hash1, hash2)
def test_empty_permitted(self):
"""
Regression test for #10643: the security hash should allow forms with

View File

@ -22,8 +22,8 @@ class SpatiaLiteCreation(DatabaseCreation):
self.connection.close()
self.connection.settings_dict["NAME"] = test_database_name
can_rollback = self._rollback_works()
self.connection.settings_dict["SUPPORTS_TRANSACTIONS"] = can_rollback
# Confirm the feature set of the test database
self.connection.features.confirm()
# Need to load the SpatiaLite initialization SQL before running `syncdb`.
self.load_spatialite_sql()
call_command('syncdb', verbosity=verbosity, interactive=False, database=self.connection.alias)

View File

@ -2,7 +2,7 @@
Module for executing all of the GDAL tests. None
of these tests require the use of the database.
"""
from unittest import TestSuite, TextTestRunner
from django.utils.unittest import TestSuite, TextTestRunner
# Importing the GDAL test modules.
import test_driver, test_ds, test_envelope, test_geom, test_srs

View File

@ -1,5 +1,6 @@
import unittest
from django.contrib.gis.gdal import Envelope, OGRException
from django.utils import unittest
class TestPoint(object):
def __init__(self, x, y):
@ -8,8 +9,8 @@ class TestPoint(object):
class EnvelopeTest(unittest.TestCase):
def setUp(self):
self.e = Envelope(0, 0, 5, 5)
def setUp(self):
self.e = Envelope(0, 0, 5, 5)
def test01_init(self):
"Testing Envelope initilization."
@ -23,10 +24,10 @@ class EnvelopeTest(unittest.TestCase):
self.assertRaises(OGRException, Envelope, ())
self.assertRaises(ValueError, Envelope, 0, 'a', 5, 5)
self.assertRaises(TypeError, Envelope, u'foo')
self.assertRaises(OGRException, Envelope, (1, 1, 0, 0))
try:
Envelope(0, 0, 0, 0)
except OGRException:
self.assertRaises(OGRException, Envelope, (1, 1, 0, 0))
try:
Envelope(0, 0, 0, 0)
except OGRException:
self.fail("shouldn't raise an exception for min_x == max_x or min_y == max_y")
def test02_properties(self):
@ -49,41 +50,41 @@ class EnvelopeTest(unittest.TestCase):
self.assertEqual(e1, e2)
self.assertEqual((0.523, 0.217, 253.23, 523.69), e1)
def test04_expand_to_include_pt_2_params(self):
"Testing Envelope expand_to_include -- point as two parameters."
self.e.expand_to_include(2, 6)
self.assertEqual((0, 0, 5, 6), self.e)
self.e.expand_to_include(-1, -1)
self.assertEqual((-1, -1, 5, 6), self.e)
def test05_expand_to_include_pt_2_tuple(self):
"Testing Envelope expand_to_include -- point as a single 2-tuple parameter."
self.e.expand_to_include((10, 10))
self.assertEqual((0, 0, 10, 10), self.e)
self.e.expand_to_include((-10, -10))
self.assertEqual((-10, -10, 10, 10), self.e)
def test04_expand_to_include_pt_2_params(self):
"Testing Envelope expand_to_include -- point as two parameters."
self.e.expand_to_include(2, 6)
self.assertEqual((0, 0, 5, 6), self.e)
self.e.expand_to_include(-1, -1)
self.assertEqual((-1, -1, 5, 6), self.e)
def test06_expand_to_include_extent_4_params(self):
"Testing Envelope expand_to_include -- extent as 4 parameters."
self.e.expand_to_include(-1, 1, 3, 7)
self.assertEqual((-1, 0, 5, 7), self.e)
def test06_expand_to_include_extent_4_tuple(self):
"Testing Envelope expand_to_include -- extent as a single 4-tuple parameter."
self.e.expand_to_include((-1, 1, 3, 7))
self.assertEqual((-1, 0, 5, 7), self.e)
def test07_expand_to_include_envelope(self):
"Testing Envelope expand_to_include with Envelope as parameter."
self.e.expand_to_include(Envelope(-1, 1, 3, 7))
self.assertEqual((-1, 0, 5, 7), self.e)
def test08_expand_to_include_point(self):
"Testing Envelope expand_to_include with Point as parameter."
self.e.expand_to_include(TestPoint(-1, 1))
self.assertEqual((-1, 0, 5, 5), self.e)
self.e.expand_to_include(TestPoint(10, 10))
self.assertEqual((-1, 0, 10, 10), self.e)
def test05_expand_to_include_pt_2_tuple(self):
"Testing Envelope expand_to_include -- point as a single 2-tuple parameter."
self.e.expand_to_include((10, 10))
self.assertEqual((0, 0, 10, 10), self.e)
self.e.expand_to_include((-10, -10))
self.assertEqual((-10, -10, 10, 10), self.e)
def test06_expand_to_include_extent_4_params(self):
"Testing Envelope expand_to_include -- extent as 4 parameters."
self.e.expand_to_include(-1, 1, 3, 7)
self.assertEqual((-1, 0, 5, 7), self.e)
def test06_expand_to_include_extent_4_tuple(self):
"Testing Envelope expand_to_include -- extent as a single 4-tuple parameter."
self.e.expand_to_include((-1, 1, 3, 7))
self.assertEqual((-1, 0, 5, 7), self.e)
def test07_expand_to_include_envelope(self):
"Testing Envelope expand_to_include with Envelope as parameter."
self.e.expand_to_include(Envelope(-1, 1, 3, 7))
self.assertEqual((-1, 0, 5, 7), self.e)
def test08_expand_to_include_point(self):
"Testing Envelope expand_to_include with Point as parameter."
self.e.expand_to_include(TestPoint(-1, 1))
self.assertEqual((-1, 0, 5, 5), self.e)
self.e.expand_to_include(TestPoint(10, 10))
self.assertEqual((-1, 0, 10, 10), self.e)
def suite():
s = unittest.TestSuite()

View File

@ -1,8 +1,9 @@
import unittest
from django.contrib.gis.gdal import OGRGeometry, OGRGeomType, \
OGRException, OGRIndexError, SpatialReference, CoordTransform, \
gdal_version
from django.contrib.gis.tests.geometries import *
from django.utils import unittest
class OGRGeomTest(unittest.TestCase):
"This tests the OGR Geometry."

View File

@ -1,5 +1,6 @@
import unittest
from django.contrib.gis.gdal import SpatialReference, CoordTransform, OGRException, SRSException
from django.utils import unittest
class TestSRS:
def __init__(self, wkt, **kwargs):
@ -79,7 +80,7 @@ class SpatialRefTest(unittest.TestCase):
srs1 = SpatialReference(s.wkt)
srs2 = SpatialReference(s.proj)
self.assertEqual(srs1.proj, srs2.proj)
def test05_epsg(self):
"Test EPSG import."
for s in srlist:
@ -159,7 +160,7 @@ class SpatialRefTest(unittest.TestCase):
self.assertEqual(4326, int(s1['AUTHORITY', 1]))
#for i in range(7): self.assertEqual(0, int(s1['TOWGS84', i]))
self.assertEqual(None, s1['FOOBAR'])
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(SpatialRefTest))

View File

@ -1,7 +1,7 @@
"""
GEOS Testing module.
"""
from unittest import TestSuite, TextTestRunner
from django.utils.unittest import TestSuite, TextTestRunner
import test_geos, test_io, test_geos_mutation, test_mutable_list
test_suites = [

View File

@ -1,12 +1,12 @@
# Copyright (c) 2008-2009 Aryeh Leib Taurog, all rights reserved.
# Modified from original contribution by Aryeh Leib Taurog, which was
# released under the New BSD license.
import unittest
import django.utils.copycompat as copy
from django.contrib.gis.geos import *
from django.contrib.gis.geos.error import GEOSIndexError
from django.utils import unittest
def getItem(o,i): return o[i]
def delItem(o,i): del o[i]

View File

@ -3,8 +3,9 @@
#
# Modified from original contribution by Aryeh Leib Taurog, which was
# released under the New BSD license.
import unittest
from django.contrib.gis.geos.mutable_list import ListMixin
from django.utils import unittest
class UserListA(ListMixin):
_mytype = tuple

View File

@ -1,9 +1,10 @@
import sys
import unittest
from django.conf import settings
from django.db.models import get_app
from django.test.simple import build_suite, DjangoTestSuiteRunner
from django.utils import unittest
def run_tests(*args, **kwargs):
from django.test.simple import run_tests as base_run_tests

View File

@ -1,9 +1,11 @@
import unittest
from xml.dom import minidom
from django.test import Client
from django.utils import unittest
from models import City
class GeoFeedTest(unittest.TestCase):
client = Client()

View File

@ -1,9 +1,13 @@
import unittest, zipfile, cStringIO
import cStringIO
from xml.dom import minidom
import zipfile
from django.test import Client
from django.utils import unittest
from models import City, Country
class GeoSitemapTest(unittest.TestCase):
client = Client()
@ -30,7 +34,7 @@ class GeoSitemapTest(unittest.TestCase):
urlset = doc.firstChild
self.assertEqual(urlset.getAttribute(u'xmlns'), u'http://www.sitemaps.org/schemas/sitemap/0.9')
self.assertEqual(urlset.getAttribute(u'xmlns:geo'), u'http://www.google.com/geo/schemas/sitemap/1.0')
urls = urlset.getElementsByTagName('url')
self.assertEqual(2, len(urls)) # Should only be 2 sitemaps.
for url in urls:
@ -42,7 +46,7 @@ class GeoSitemapTest(unittest.TestCase):
# Getting the relative URL since we don't have a real site.
kml_url = url.getElementsByTagName('loc')[0].childNodes[0].data.split('http://example.com')[1]
if kml_type == 'kml':
kml_doc = minidom.parseString(self.client.get(kml_url).content)
elif kml_type == 'kmz':
@ -52,7 +56,7 @@ class GeoSitemapTest(unittest.TestCase):
self.assertEqual(1, len(zf.filelist))
self.assertEqual('doc.kml', zf.filelist[0].filename)
kml_doc = minidom.parseString(zf.read('doc.kml'))
# Ensuring the correct number of placemarks are in the KML doc.
if 'city' in kml_url:
model = City
@ -65,7 +69,7 @@ class GeoSitemapTest(unittest.TestCase):
from feeds import feed_dict
doc = minidom.parseString(self.client.get('/geoapp/sitemaps/georss.xml').content)
# Ensuring the right sitemaps namespaces are present.
urlset = doc.firstChild
self.assertEqual(urlset.getAttribute(u'xmlns'), u'http://www.sitemaps.org/schemas/sitemap/0.9')

View File

@ -1,7 +1,7 @@
import os
import unittest
from decimal import Decimal
from django.utils import unittest
from django.utils.copycompat import copy
from django.contrib.gis.gdal import DataSource
@ -15,9 +15,9 @@ city_shp = os.path.join(shp_path, 'cities', 'cities.shp')
co_shp = os.path.join(shp_path, 'counties', 'counties.shp')
inter_shp = os.path.join(shp_path, 'interstates', 'interstates.shp')
# Dictionaries to hold what's expected in the county shapefile.
# Dictionaries to hold what's expected in the county shapefile.
NAMES = ['Bexar', 'Galveston', 'Harris', 'Honolulu', 'Pueblo']
NUMS = [1, 2, 1, 19, 1] # Number of polygons for each.
NUMS = [1, 2, 1, 19, 1] # Number of polygons for each.
STATES = ['Texas', 'Texas', 'Texas', 'Hawaii', 'Colorado']
class LayerMapTest(unittest.TestCase):
@ -98,7 +98,7 @@ class LayerMapTest(unittest.TestCase):
# Two interstate should have imported correctly.
self.assertEqual(2, Interstate.objects.count())
# Verifying the values in the layer w/the model.
ds = DataSource(inter_shp)
@ -106,7 +106,7 @@ class LayerMapTest(unittest.TestCase):
valid_feats = ds[0][:2]
for feat in valid_feats:
istate = Interstate.objects.get(name=feat['Name'].value)
if feat.fid == 0:
self.assertEqual(Decimal(str(feat['Length'])), istate.length)
elif feat.fid == 1:
@ -125,7 +125,7 @@ class LayerMapTest(unittest.TestCase):
c = County.objects.get(name=name)
self.assertEqual(n, len(c.mpoly))
self.assertEqual(st, c.state.name) # Checking ForeignKey mapping.
# Multiple records because `unique` was not set.
if county_feat:
qs = CountyFeat.objects.filter(name=name)
@ -137,7 +137,7 @@ class LayerMapTest(unittest.TestCase):
try:
# Telling LayerMapping that we want no transformations performed on the data.
lm = LayerMapping(County, co_shp, co_mapping, transform=False)
# Specifying the source spatial reference system via the `source_srs` keyword.
lm = LayerMapping(County, co_shp, co_mapping, source_srs=4269)
lm = LayerMapping(County, co_shp, co_mapping, source_srs='NAD83')
@ -147,7 +147,7 @@ class LayerMapTest(unittest.TestCase):
lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique=arg)
except:
self.fail('No exception should be raised for proper use of keywords.')
# Testing invalid params for the `unique` keyword.
for e, arg in ((TypeError, 5.0), (ValueError, 'foobar'), (ValueError, ('name', 'mpolygon'))):
self.assertRaises(e, LayerMapping, County, co_shp, co_mapping, transform=False, unique=arg)
@ -177,11 +177,11 @@ class LayerMapTest(unittest.TestCase):
# are not collections will be converted into them. For example,
# a Point column would be converted to MultiPoint. Other things being done
# w/the keyword args:
# `transform=False`: Specifies that no transform is to be done; this
# `transform=False`: Specifies that no transform is to be done; this
# has the effect of ignoring the spatial reference check (because the
# county shapefile does not have implicit spatial reference info).
#
# `unique='name'`: Creates models on the condition that they have
#
# `unique='name'`: Creates models on the condition that they have
# unique county names; geometries from each feature however will be
# appended to the geometry collection of the unique model. Thus,
# all of the various islands in Honolulu county will be in in one
@ -201,7 +201,7 @@ class LayerMapTest(unittest.TestCase):
"Tests the `fid_range` keyword and the `step` keyword of .save()."
# Function for clearing out all the counties before testing.
def clear_counties(): County.objects.all().delete()
# Initializing the LayerMapping object to use in these tests.
lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique='name')
@ -213,9 +213,9 @@ class LayerMapTest(unittest.TestCase):
# Step keyword should not be allowed w/`fid_range`.
fr = (3, 5) # layer[3:5]
self.assertRaises(LayerMapError, lm.save, fid_range=fr, step=10)
self.assertRaises(LayerMapError, lm.save, fid_range=fr, step=10)
lm.save(fid_range=fr)
# Features IDs 3 & 4 are for Galveston County, Texas -- only
# one model is returned because the `unique` keyword was set.
qs = County.objects.all()
@ -229,9 +229,9 @@ class LayerMapTest(unittest.TestCase):
lm.save(fid_range=slice(None, 1), silent=True, strict=True) # layer[:1]
# Only Pueblo & Honolulu counties should be present because of
# the `unique` keyword. Have to set `order_by` on this QuerySet
# the `unique` keyword. Have to set `order_by` on this QuerySet
# or else MySQL will return a different ordering than the other dbs.
qs = County.objects.order_by('name')
qs = County.objects.order_by('name')
self.assertEqual(2, qs.count())
hi, co = tuple(qs)
hi_idx, co_idx = tuple(map(NAMES.index, ('Honolulu', 'Pueblo')))
@ -265,7 +265,7 @@ class LayerMapTest(unittest.TestCase):
self.assertEqual(6, ICity1.objects.count())
self.assertEqual(3, ICity2.objects.count())
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(LayerMapTest))

View File

@ -1,8 +1,8 @@
import unittest
from django.forms import ValidationError
from django.contrib.gis import forms
from django.contrib.gis.geos import GEOSGeometry
from django.utils import unittest
class GeometryFieldTest(unittest.TestCase):

View File

@ -1,10 +1,11 @@
"""
Distance and Area objects to allow for sensible and convienient calculation
Distance and Area objects to allow for sensible and convienient calculation
and conversions. Here are some tests.
"""
import unittest
from django.contrib.gis.measure import Distance, Area, D, A
from django.utils import unittest
class DistanceTest(unittest.TestCase):
"Testing the Distance object"
@ -30,7 +31,7 @@ class DistanceTest(unittest.TestCase):
self.assertEqual(d.m, 1.0)
self.assertEqual(d.mm, 1000.0)
def testInitInvalid(self):
"Testing initialisation from invalid units"
self.assertRaises(AttributeError, D, banana=100)
@ -40,7 +41,7 @@ class DistanceTest(unittest.TestCase):
d = D(m=100)
self.assertEqual(d.km, 0.1)
self.assertAlmostEqual(d.ft, 328.084, 3)
def testAccessInvalid(self):
"Testing access in invalid units"
d = D(m=100)
@ -55,12 +56,12 @@ class DistanceTest(unittest.TestCase):
self.assertEqual(d3.m, 300)
d3 += d1
self.assertEqual(d3.m, 400)
d4 = d1 - d2
self.assertEqual(d4.m, -100)
d4 -= d1
self.assertEqual(d4.m, -200)
try:
d5 = d1 + 1
except TypeError, e:
@ -88,7 +89,7 @@ class DistanceTest(unittest.TestCase):
pass
else:
self.fail('Distance -= number should raise TypeError')
def testMultiplication(self):
"Test multiplication & division"
d1 = D(m=100)
@ -99,12 +100,12 @@ class DistanceTest(unittest.TestCase):
self.assertEqual(d3.m, 200)
d3 *= 5
self.assertEqual(d3.m, 1000)
d4 = d1 / 2
self.assertEqual(d4.m, 50)
d4 /= 5
self.assertEqual(d4.m, 10)
a5 = d1 * D(m=10)
self.assert_(isinstance(a5, Area))
self.assertEqual(a5.sq_m, 100*10)
@ -115,7 +116,7 @@ class DistanceTest(unittest.TestCase):
pass
else:
self.fail('Distance *= Distance should raise TypeError')
try:
d5 = d1 / D(m=1)
except TypeError, e:
@ -143,23 +144,23 @@ class DistanceTest(unittest.TestCase):
self.assertEqual(d5._default_unit, 'm')
d6 = d1 / 2
self.assertEqual(d6._default_unit, 'm')
def testComparisons(self):
"Testing comparisons"
d1 = D(m=100)
d2 = D(km=1)
d3 = D(km=0)
self.assert_(d2 > d1)
self.assert_(d1 == d1)
self.assert_(d1 < d2)
self.failIf(d3)
def testUnitsStr(self):
"Testing conversion to strings"
d1 = D(m=100)
d2 = D(km=3.5)
self.assertEqual(str(d1), '100.0 m')
self.assertEqual(str(d2), '3.5 km')
self.assertEqual(repr(d1), 'Distance(m=100.0)')
@ -185,7 +186,7 @@ class AreaTest(unittest.TestCase):
a = A(sq_mi=100)
self.assertEqual(a.sq_m, 258998811.0336)
def testInitInvaliA(self):
"Testing initialisation from invalid units"
self.assertRaises(AttributeError, A, banana=100)
@ -195,7 +196,7 @@ class AreaTest(unittest.TestCase):
a = A(sq_m=100)
self.assertEqual(a.sq_km, 0.0001)
self.assertAlmostEqual(a.sq_ft, 1076.391, 3)
def testAccessInvaliA(self):
"Testing access in invalid units"
a = A(sq_m=100)
@ -210,12 +211,12 @@ class AreaTest(unittest.TestCase):
self.assertEqual(a3.sq_m, 300)
a3 += a1
self.assertEqual(a3.sq_m, 400)
a4 = a1 - a2
self.assertEqual(a4.sq_m, -100)
a4 -= a1
self.assertEqual(a4.sq_m, -200)
try:
a5 = a1 + 1
except TypeError, e:
@ -243,7 +244,7 @@ class AreaTest(unittest.TestCase):
pass
else:
self.fail('Area -= number should raise TypeError')
def testMultiplication(self):
"Test multiplication & division"
a1 = A(sq_m=100)
@ -254,12 +255,12 @@ class AreaTest(unittest.TestCase):
self.assertEqual(a3.sq_m, 200)
a3 *= 5
self.assertEqual(a3.sq_m, 1000)
a4 = a1 / 2
self.assertEqual(a4.sq_m, 50)
a4 /= 5
self.assertEqual(a4.sq_m, 10)
try:
a5 = a1 * A(sq_m=1)
except TypeError, e:
@ -273,7 +274,7 @@ class AreaTest(unittest.TestCase):
pass
else:
self.fail('Area *= Area should raise TypeError')
try:
a5 = a1 / A(sq_m=1)
except TypeError, e:
@ -301,23 +302,23 @@ class AreaTest(unittest.TestCase):
self.assertEqual(a5._default_unit, 'sq_m')
a6 = a1 / 2
self.assertEqual(a6._default_unit, 'sq_m')
def testComparisons(self):
"Testing comparisons"
a1 = A(sq_m=100)
a2 = A(sq_km=1)
a3 = A(sq_km=0)
self.assert_(a2 > a1)
self.assert_(a1 == a1)
self.assert_(a1 < a2)
self.failIf(a3)
def testUnitsStr(self):
"Testing conversion to strings"
a1 = A(sq_m=100)
a2 = A(sq_km=3.5)
self.assertEqual(str(a1), '100.0 sq_m')
self.assertEqual(str(a2), '3.5 sq_km')
self.assertEqual(repr(a1), 'Area(sq_m=100.0)')

View File

@ -1,7 +1,7 @@
import unittest
from django.db import connection
from django.contrib.gis.tests.utils import mysql, no_mysql, oracle, postgis, spatialite
from django.utils import unittest
test_srs = ({'srid' : 4326,
'auth_name' : ('EPSG', True),
@ -9,7 +9,7 @@ test_srs = ({'srid' : 4326,
'srtext' : 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]',
'srtext14' : 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]',
'proj4' : '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ',
'spheroid' : 'WGS 84', 'name' : 'WGS 84',
'spheroid' : 'WGS 84', 'name' : 'WGS 84',
'geographic' : True, 'projected' : False, 'spatialite' : True,
'ellipsoid' : (6378137.0, 6356752.3, 298.257223563), # From proj's "cs2cs -le" and Wikipedia (semi-minor only)
'eprec' : (1, 1, 9),
@ -49,7 +49,7 @@ class SpatialRefSysTest(unittest.TestCase):
auth_name, oracle_flag = sd['auth_name']
if postgis or (oracle and oracle_flag):
self.assertEqual(True, srs.auth_name.startswith(auth_name))
self.assertEqual(sd['auth_srid'], srs.auth_srid)
# No proj.4 and different srtext on oracle backends :(

View File

@ -1,77 +1,90 @@
# Quick tests for the markup templatetags (django.contrib.markup)
import re
import unittest
from django.template import Template, Context, add_to_builtins
from django.utils import unittest
from django.utils.html import escape
add_to_builtins('django.contrib.markup.templatetags.markup')
class Templates(unittest.TestCase):
def test_textile(self):
try:
import textile
except ImportError:
textile = None
try:
import textile
except ImportError:
textile = None
textile_content = """Paragraph 1
try:
import markdown
except ImportError:
markdown = None
try:
import docutils
except ImportError:
docutils = None
class Templates(unittest.TestCase):
textile_content = """Paragraph 1
Paragraph 2 with "quotes" and @code@"""
t = Template("{{ textile_content|textile }}")
rendered = t.render(Context(locals())).strip()
if textile:
self.assertEqual(rendered.replace('\t', ''), """<p>Paragraph 1</p>
<p>Paragraph 2 with &#8220;quotes&#8221; and <code>code</code></p>""")
else:
self.assertEqual(rendered, escape(textile_content))
def test_markdown(self):
try:
import markdown
except ImportError:
markdown = None
markdown_content = """Paragraph 1
markdown_content = """Paragraph 1
## An h2"""
t = Template("{{ markdown_content|markdown }}")
rendered = t.render(Context(locals())).strip()
if markdown:
pattern = re.compile("""<p>Paragraph 1\s*</p>\s*<h2>\s*An h2</h2>""")
self.assert_(pattern.match(rendered))
else:
self.assertEqual(rendered, markdown_content)
def test_docutils(self):
try:
import docutils
except ImportError:
docutils = None
rest_content = """Paragraph 1
rest_content = """Paragraph 1
Paragraph 2 with a link_
.. _link: http://www.example.com/"""
@unittest.skipUnless(textile, 'texttile not installed')
def test_textile(self):
t = Template("{{ textile_content|textile }}")
rendered = t.render(Context({'textile_content':self.textile_content})).strip()
self.assertEqual(rendered.replace('\t', ''), """<p>Paragraph 1</p>
<p>Paragraph 2 with &#8220;quotes&#8221; and <code>code</code></p>""")
@unittest.skipIf(textile, 'texttile is installed')
def test_no_textile(self):
t = Template("{{ textile_content|textile }}")
rendered = t.render(Context({'textile_content':self.textile_content})).strip()
self.assertEqual(rendered, escape(self.textile_content))
@unittest.skipUnless(markdown, 'markdown not installed')
def test_markdown(self):
t = Template("{{ markdown_content|markdown }}")
rendered = t.render(Context({'markdown_content':self.markdown_content})).strip()
pattern = re.compile("""<p>Paragraph 1\s*</p>\s*<h2>\s*An h2</h2>""")
self.assertTrue(pattern.match(rendered))
@unittest.skipIf(markdown, 'markdown is installed')
def test_no_markdown(self):
t = Template("{{ markdown_content|markdown }}")
rendered = t.render(Context({'markdown_content':self.markdown_content})).strip()
self.assertEqual(rendered, self.markdown_content)
@unittest.skipUnless(docutils, 'docutils not installed')
def test_docutils(self):
t = Template("{{ rest_content|restructuredtext }}")
rendered = t.render(Context(locals())).strip()
if docutils:
# Different versions of docutils return slightly different HTML
try:
# Docutils v0.4 and earlier
self.assertEqual(rendered, """<p>Paragraph 1</p>
rendered = t.render(Context({'rest_content':self.rest_content})).strip()
# Different versions of docutils return slightly different HTML
try:
# Docutils v0.4 and earlier
self.assertEqual(rendered, """<p>Paragraph 1</p>
<p>Paragraph 2 with a <a class="reference" href="http://www.example.com/">link</a></p>""")
except AssertionError, e:
# Docutils from SVN (which will become 0.5)
self.assertEqual(rendered, """<p>Paragraph 1</p>
except AssertionError, e:
# Docutils from SVN (which will become 0.5)
self.assertEqual(rendered, """<p>Paragraph 1</p>
<p>Paragraph 2 with a <a class="reference external" href="http://www.example.com/">link</a></p>""")
else:
self.assertEqual(rendered, rest_content)
@unittest.skipIf(docutils, 'docutils is installed')
def test_no_docutils(self):
t = Template("{{ rest_content|restructuredtext }}")
rendered = t.render(Context({'rest_content':self.rest_content})).strip()
self.assertEqual(rendered, self.rest_content)
if __name__ == '__main__':

View File

@ -1,6 +1,6 @@
import unittest
from django import http
from django.contrib.messages.middleware import MessageMiddleware
from django.utils import unittest
class MiddlewareTest(unittest.TestCase):

View File

@ -1,4 +1,7 @@
from datetime import datetime, timedelta
import shutil
import tempfile
from django.conf import settings
from django.contrib.sessions.backends.db import SessionStore as DatabaseSession
from django.contrib.sessions.backends.cache import SessionStore as CacheSession
@ -8,9 +11,7 @@ from django.contrib.sessions.backends.base import SessionBase
from django.contrib.sessions.models import Session
from django.core.exceptions import ImproperlyConfigured
from django.test import TestCase
import shutil
import tempfile
import unittest
from django.utils import unittest
class SessionTestsMixin(object):

View File

@ -20,6 +20,7 @@ class BaseDatabaseWrapper(local):
self.queries = []
self.settings_dict = settings_dict
self.alias = alias
self.vendor = 'unknown'
def __eq__(self, other):
return self.settings_dict == other.settings_dict
@ -87,16 +88,105 @@ class BaseDatabaseFeatures(object):
needs_datetime_string_cast = True
empty_fetchmany_value = []
update_can_self_select = True
# Does the backend distinguish between '' and None?
interprets_empty_strings_as_nulls = False
can_use_chunked_reads = True
can_return_id_from_insert = False
uses_autocommit = False
uses_savepoints = False
# If True, don't use integer foreign keys referring to, e.g., positive
# integer primary keys.
related_fields_match_type = False
allow_sliced_subqueries = True
# Does the default test database allow multiple connections?
# Usually an indication that the test database is in-memory
test_db_allows_multiple_connections = True
# Can an object be saved without an explicit primary key?
supports_unspecified_pk = False
# Can a fixture contain forward references? i.e., are
# FK constraints checked at the end of transaction, or
# at the end of each save operation?
supports_forward_references = True
# Does a dirty transaction need to be rolled back
# before the cursor can be used again?
requires_rollback_on_dirty_transaction = False
# Does the backend allow very long model names without error?
supports_long_model_names = True
# Is there a REAL datatype in addition to floats/doubles?
has_real_datatype = False
supports_subqueries_in_group_by = True
supports_bitwise_or = True
# Do time/datetime fields have microsecond precision?
supports_microsecond_precision = True
# Does the __regex lookup support backreferencing and grouping?
supports_regex_backreferencing = True
# Can date/datetime lookups be performed using a string?
supports_date_lookup_using_string = True
# Can datetimes with timezones be used?
supports_timezones = True
# When performing a GROUP BY, is an ORDER BY NULL required
# to remove any ordering?
requires_explicit_null_ordering_when_grouping = False
# Is there a 1000 item limit on query parameters?
supports_1000_query_paramters = True
# Can an object have a primary key of 0? MySQL says No.
allows_primary_key_0 = True
# Features that need to be confirmed at runtime
# Cache whether the confirmation has been performed.
_confirmed = False
supports_transactions = None
supports_stddev = None
def __init__(self, connection):
self.connection = connection
def confirm(self):
"Perform manual checks of any database features that might vary between installs"
self._confirmed = True
self.supports_transactions = self._supports_transactions()
self.supports_stddev = self._supports_stddev()
def _supports_transactions(self):
"Confirm support for transactions"
cursor = self.connection.cursor()
cursor.execute('CREATE TABLE ROLLBACK_TEST (X INT)')
self.connection._commit()
cursor.execute('INSERT INTO ROLLBACK_TEST (X) VALUES (8)')
self.connection._rollback()
cursor.execute('SELECT COUNT(X) FROM ROLLBACK_TEST')
count, = cursor.fetchone()
cursor.execute('DROP TABLE ROLLBACK_TEST')
self.connection._commit()
return count == 0
def _supports_stddev(self):
"Confirm support for STDDEV and related stats functions"
class StdDevPop(object):
sql_function = 'STDDEV_POP'
try:
self.connection.ops.check_aggregate_support(StdDevPop())
except DatabaseError:
self.supports_stddev = False
class BaseDatabaseOperations(object):
"""
This class encapsulates all backend-specific differences, such as the way

View File

@ -347,8 +347,9 @@ class BaseDatabaseCreation(object):
self.connection.close()
self.connection.settings_dict["NAME"] = test_database_name
can_rollback = self._rollback_works()
self.connection.settings_dict["SUPPORTS_TRANSACTIONS"] = can_rollback
# Confirm the feature set of the test database
self.connection.features.confirm()
# Report syncdb messages at one level lower than that requested.
# This ensures we don't get flooded with messages during testing
@ -405,18 +406,6 @@ class BaseDatabaseCreation(object):
return test_database_name
def _rollback_works(self):
cursor = self.connection.cursor()
cursor.execute('CREATE TABLE ROLLBACK_TEST (X INT)')
self.connection._commit()
cursor.execute('INSERT INTO ROLLBACK_TEST (X) VALUES (8)')
self.connection._rollback()
cursor.execute('SELECT COUNT(X) FROM ROLLBACK_TEST')
count, = cursor.fetchone()
cursor.execute('DROP TABLE ROLLBACK_TEST')
self.connection._commit()
return count == 0
def destroy_test_db(self, old_database_name, verbosity=1):
"""
Destroy a test database, prompting the user for confirmation if the

View File

@ -42,7 +42,7 @@ class DatabaseWrapper(object):
_rollback = ignore
def __init__(self, settings_dict, alias, *args, **kwargs):
self.features = BaseDatabaseFeatures()
self.features = BaseDatabaseFeatures(self)
self.ops = DatabaseOperations()
self.client = DatabaseClient(self)
self.creation = BaseDatabaseCreation(self)

View File

@ -124,6 +124,14 @@ class DatabaseFeatures(BaseDatabaseFeatures):
allows_group_by_pk = True
related_fields_match_type = True
allow_sliced_subqueries = False
supports_forward_references = False
supports_long_model_names = False
supports_microsecond_precision = False
supports_regex_backreferencing = False
supports_date_lookup_using_string = False
supports_timezones = False
requires_explicit_null_ordering_when_grouping = True
allows_primary_key_0 = False
class DatabaseOperations(BaseDatabaseOperations):
compiler_module = "django.db.backends.mysql.compiler"
@ -231,7 +239,7 @@ class DatabaseOperations(BaseDatabaseOperations):
return 64
class DatabaseWrapper(BaseDatabaseWrapper):
vendor = 'mysql'
operators = {
'exact': '= %s',
'iexact': 'LIKE %s',
@ -253,7 +261,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
super(DatabaseWrapper, self).__init__(*args, **kwargs)
self.server_version = None
self.features = DatabaseFeatures()
self.features = DatabaseFeatures(self)
self.ops = DatabaseOperations()
self.client = DatabaseClient(self)
self.creation = DatabaseCreation(self)

View File

@ -50,7 +50,9 @@ class DatabaseFeatures(BaseDatabaseFeatures):
uses_savepoints = True
can_return_id_from_insert = True
allow_sliced_subqueries = False
supports_subqueries_in_group_by = True
supports_timezones = False
supports_bitwise_or = False
class DatabaseOperations(BaseDatabaseOperations):
compiler_module = "django.db.backends.oracle.compiler"
@ -314,7 +316,7 @@ WHEN (new.%(col_name)s IS NULL)
class DatabaseWrapper(BaseDatabaseWrapper):
vendor = 'oracle'
operators = {
'exact': '= %s',
'iexact': '= UPPER(%s)',
@ -334,7 +336,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
def __init__(self, *args, **kwargs):
super(DatabaseWrapper, self).__init__(*args, **kwargs)
self.features = DatabaseFeatures()
self.features = DatabaseFeatures(self)
self.ops = DatabaseOperations()
self.client = DatabaseClient(self)
self.creation = DatabaseCreation(self)

View File

@ -80,8 +80,11 @@ class UnicodeCursorWrapper(object):
class DatabaseFeatures(BaseDatabaseFeatures):
uses_savepoints = True
requires_rollback_on_dirty_transaction = True
has_real_datatype = True
class DatabaseWrapper(BaseDatabaseWrapper):
vendor = 'postgresql'
operators = {
'exact': '= %s',
'iexact': '= UPPER(%s)',
@ -108,7 +111,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
DeprecationWarning
)
self.features = DatabaseFeatures()
self.features = DatabaseFeatures(self)
self.ops = DatabaseOperations(self)
self.client = DatabaseClient(self)
self.creation = DatabaseCreation(self)

View File

@ -67,6 +67,8 @@ class CursorWrapper(object):
class DatabaseFeatures(BaseDatabaseFeatures):
needs_datetime_string_cast = False
can_return_id_from_insert = False
requires_rollback_on_dirty_transaction = True
has_real_datatype = True
class DatabaseOperations(PostgresqlDatabaseOperations):
def last_executed_query(self, cursor, sql, params):
@ -79,6 +81,7 @@ class DatabaseOperations(PostgresqlDatabaseOperations):
return "RETURNING %s", ()
class DatabaseWrapper(BaseDatabaseWrapper):
vendor = 'postgresql'
operators = {
'exact': '= %s',
'iexact': '= UPPER(%s)',
@ -99,7 +102,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
def __init__(self, *args, **kwargs):
super(DatabaseWrapper, self).__init__(*args, **kwargs)
self.features = DatabaseFeatures()
self.features = DatabaseFeatures(self)
autocommit = self.settings_dict["OPTIONS"].get('autocommit', False)
self.features.uses_autocommit = autocommit
self._set_isolation_level(int(not autocommit))

View File

@ -60,6 +60,27 @@ class DatabaseFeatures(BaseDatabaseFeatures):
# setting ensures we always read result sets fully into memory all in one
# go.
can_use_chunked_reads = False
test_db_allows_multiple_connections = False
supports_unspecified_pk = True
supports_1000_query_paramters = False
def _supports_stddev(self):
"""Confirm support for STDDEV and related stats functions
SQLite supports STDDEV as an extension package; so
connection.ops.check_aggregate_support() can't unilaterally
rule out support for STDDEV. We need to manually check
whether the call works.
"""
cursor = self.connection.cursor()
cursor.execute('CREATE TABLE STDDEV_TEST (X INT)')
try:
cursor.execute('SELECT STDDEV(*) FROM STDDEV_TEST')
has_support = True
except utils.DatabaseError:
has_support = False
cursor.execute('DROP TABLE STDDEV_TEST')
return has_support
class DatabaseOperations(BaseDatabaseOperations):
def date_extract_sql(self, lookup_type, field_name):
@ -129,7 +150,7 @@ class DatabaseOperations(BaseDatabaseOperations):
return value
class DatabaseWrapper(BaseDatabaseWrapper):
vendor = 'sqlite'
# SQLite requires LIKE statements to include an ESCAPE clause if the value
# being escaped has a percent or underscore in it.
# See http://www.sqlite.org/lang_expr.html for an explanation.
@ -153,7 +174,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
def __init__(self, *args, **kwargs):
super(DatabaseWrapper, self).__init__(*args, **kwargs)
self.features = DatabaseFeatures()
self.features = DatabaseFeatures(self)
self.ops = DatabaseOperations()
self.client = DatabaseClient(self)
self.creation = DatabaseCreation(self)

View File

@ -3,5 +3,5 @@ Django Unit Test and Doctest framework.
"""
from django.test.client import Client
from django.test.testcases import TestCase, TransactionTestCase
from django.test.testcases import TestCase, TransactionTestCase, skipIfDBFeature, skipUnlessDBFeature
from django.test.utils import Approximate

View File

@ -1,12 +1,12 @@
import sys
import signal
import unittest
from django.conf import settings
from django.db.models import get_app, get_apps
from django.test import _doctest as doctest
from django.test.utils import setup_test_environment, teardown_test_environment
from django.test.testcases import OutputChecker, DocTestRunner, TestCase
from django.utils import unittest
# The module name for tests outside models.py
TEST_MODULE = 'tests'
@ -14,52 +14,13 @@ TEST_MODULE = 'tests'
doctestOutputChecker = OutputChecker()
class DjangoTestRunner(unittest.TextTestRunner):
def __init__(self, verbosity=0, failfast=False, **kwargs):
super(DjangoTestRunner, self).__init__(verbosity=verbosity, **kwargs)
self.failfast = failfast
self._keyboard_interrupt_intercepted = False
def run(self, *args, **kwargs):
"""
Runs the test suite after registering a custom signal handler
that triggers a graceful exit when Ctrl-C is pressed.
"""
self._default_keyboard_interrupt_handler = signal.signal(signal.SIGINT,
self._keyboard_interrupt_handler)
try:
result = super(DjangoTestRunner, self).run(*args, **kwargs)
finally:
signal.signal(signal.SIGINT, self._default_keyboard_interrupt_handler)
return result
def _keyboard_interrupt_handler(self, signal_number, stack_frame):
"""
Handles Ctrl-C by setting a flag that will stop the test run when
the currently running test completes.
"""
self._keyboard_interrupt_intercepted = True
sys.stderr.write(" <Test run halted by Ctrl-C> ")
# Set the interrupt handler back to the default handler, so that
# another Ctrl-C press will trigger immediate exit.
signal.signal(signal.SIGINT, self._default_keyboard_interrupt_handler)
def _makeResult(self):
result = super(DjangoTestRunner, self)._makeResult()
failfast = self.failfast
def stoptest_override(func):
def stoptest(test):
# If we were set to failfast and the unit test failed,
# or if the user has typed Ctrl-C, report and quit
if (failfast and not result.wasSuccessful()) or \
self._keyboard_interrupt_intercepted:
result.stop()
func(test)
return stoptest
result.stopTest = stoptest_override(result.stopTest)
return result
def __init__(self, *args, **kwargs):
import warnings
warnings.warn(
"DjangoTestRunner is deprecated; it's functionality is indistinguishable from TextTestRunner",
PendingDeprecationWarning
)
super(DjangoTestRunner, self).__init__(*args, **kwargs)
def get_tests(app_module):
try:
@ -232,6 +193,7 @@ class DjangoTestSuiteRunner(object):
def setup_test_environment(self, **kwargs):
setup_test_environment()
settings.DEBUG = False
unittest.installHandler()
def build_suite(self, test_labels, extra_tests=None, **kwargs):
suite = unittest.TestSuite()
@ -271,7 +233,7 @@ class DjangoTestSuiteRunner(object):
return old_names, mirrors
def run_suite(self, suite, **kwargs):
return DjangoTestRunner(verbosity=self.verbosity, failfast=self.failfast).run(suite)
return unittest.TextTestRunner(verbosity=self.verbosity, failfast=self.failfast).run(suite)
def teardown_databases(self, old_config, **kwargs):
from django.db import connections
@ -284,6 +246,7 @@ class DjangoTestSuiteRunner(object):
connection.creation.destroy_test_db(old_name, self.verbosity)
def teardown_test_environment(self, **kwargs):
unittest.removeHandler()
teardown_test_environment()
def suite_result(self, suite, result, **kwargs):

View File

@ -1,5 +1,4 @@
import re
import unittest
from urlparse import urlsplit, urlunsplit
from xml.dom.minidom import parseString, Node
@ -7,12 +6,14 @@ from django.conf import settings
from django.core import mail
from django.core.management import call_command
from django.core.urlresolvers import clear_url_caches
from django.db import transaction, connections, DEFAULT_DB_ALIAS
from django.db import transaction, connection, connections, DEFAULT_DB_ALIAS
from django.http import QueryDict
from django.test import _doctest as doctest
from django.test.client import Client
from django.utils import simplejson
from django.utils import simplejson, unittest
from django.utils.encoding import smart_str
from django.utils.functional import wraps
try:
all
@ -22,6 +23,7 @@ except NameError:
normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s)
normalize_decimals = lambda s: re.sub(r"Decimal\('(\d+(\.\d*)?)'\)", lambda m: "Decimal(\"%s\")" % m.groups()[0], s)
def to_list(value):
"""
Puts value into a list if it's not already one.
@ -472,7 +474,7 @@ def connections_support_transactions():
Returns True if all connections support transactions. This is messy
because 2.4 doesn't support any or all.
"""
return all(conn.settings_dict['SUPPORTS_TRANSACTIONS']
return all(conn.features.supports_transactions
for conn in connections.all())
class TestCase(TransactionTestCase):
@ -528,3 +530,25 @@ class TestCase(TransactionTestCase):
for connection in connections.all():
connection.close()
def _deferredSkip(condition, reason):
def decorator(test_item):
if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
@wraps(test_item)
def skip_wrapper(*args, **kwargs):
if condition():
raise unittest.SkipTest(reason)
test_item = skip_wrapper
test_item.__unittest_skip_why__ = reason
return test_item
return decorator
def skipIfDBFeature(feature):
"Skip a test if a database has the named feature"
return _deferredSkip(lambda: getattr(connection.features, feature),
"Database has feature %s" % feature)
def skipUnlessDBFeature(feature):
"Skip a test unless a database has the named feature"
return _deferredSkip(lambda: not getattr(connection.features, feature),
"Database doesn't support feature %s" % feature)

View File

@ -0,0 +1,80 @@
"""
unittest2
unittest2 is a backport of the new features added to the unittest testing
framework in Python 2.7. It is tested to run on Python 2.4 - 2.6.
To use unittest2 instead of unittest simply replace ``import unittest`` with
``import unittest2``.
Copyright (c) 1999-2003 Steve Purcell
Copyright (c) 2003-2010 Python Software Foundation
This module is free software, and you may redistribute it and/or modify
it under the same terms as Python itself, so long as this copyright message
and disclaimer are retained in their original form.
IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
"""
import sys
# Django hackery to load the appropriate version of unittest
if sys.version_info >= (2,7):
# unittest2 features are native in Python 2.7
from unittest import *
else:
try:
# check the system path first
from unittest2 import *
except ImportError:
# otherwise use our bundled version
__all__ = ['TestResult', 'TestCase', 'TestSuite',
'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main',
'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless',
'expectedFailure', 'TextTestResult', '__version__', 'collector']
__version__ = '0.5.1'
# Expose obsolete functions for backwards compatibility
__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
from django.utils.unittest.collector import collector
from django.utils.unittest.result import TestResult
from django.utils.unittest.case import \
TestCase, FunctionTestCase, SkipTest, skip, skipIf,\
skipUnless, expectedFailure
from django.utils.unittest.suite import BaseTestSuite, TestSuite
from django.utils.unittest.loader import \
TestLoader, defaultTestLoader, makeSuite, getTestCaseNames,\
findTestCases
from django.utils.unittest.main import TestProgram, main, main_
from django.utils.unittest.runner import TextTestRunner, TextTestResult
try:
from django.utils.unittest.signals import\
installHandler, registerResult, removeResult, removeHandler
except ImportError:
# Compatibility with platforms that don't have the signal module
pass
else:
__all__.extend(['installHandler', 'registerResult', 'removeResult',
'removeHandler'])
# deprecated
_TextTestResult = TextTestResult
__unittest = True

View File

@ -0,0 +1,10 @@
"""Main entry point"""
import sys
if sys.argv[0].endswith("__main__.py"):
sys.argv[0] = "unittest2"
__unittest = True
from django.utils.unittest.main import main_
main_()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
import os
import sys
from django.utils.unittest.loader import defaultTestLoader
def collector():
# import __main__ triggers code re-execution
__main__ = sys.modules['__main__']
setupDir = os.path.abspath(os.path.dirname(__main__.__file__))
return defaultTestLoader.discover(setupDir)

View File

@ -0,0 +1,64 @@
import os
import sys
try:
from functools import wraps
except ImportError:
# only needed for Python 2.4
def wraps(_):
def _wraps(func):
return func
return _wraps
__unittest = True
def _relpath_nt(path, start=os.path.curdir):
"""Return a relative version of a path"""
if not path:
raise ValueError("no path specified")
start_list = os.path.abspath(start).split(os.path.sep)
path_list = os.path.abspath(path).split(os.path.sep)
if start_list[0].lower() != path_list[0].lower():
unc_path, rest = os.path.splitunc(path)
unc_start, rest = os.path.splitunc(start)
if bool(unc_path) ^ bool(unc_start):
raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
% (path, start))
else:
raise ValueError("path is on drive %s, start on drive %s"
% (path_list[0], start_list[0]))
# Work out how much of the filepath is shared by start and path.
for i in range(min(len(start_list), len(path_list))):
if start_list[i].lower() != path_list[i].lower():
break
else:
i += 1
rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
if not rel_list:
return os.path.curdir
return os.path.join(*rel_list)
# default to posixpath definition
def _relpath_posix(path, start=os.path.curdir):
"""Return a relative version of a path"""
if not path:
raise ValueError("no path specified")
start_list = os.path.abspath(start).split(os.path.sep)
path_list = os.path.abspath(path).split(os.path.sep)
# Work out how much of the filepath is shared by start and path.
i = len(os.path.commonprefix([start_list, path_list]))
rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
if not rel_list:
return os.path.curdir
return os.path.join(*rel_list)
if os.path is sys.modules.get('ntpath'):
relpath = _relpath_nt
else:
relpath = _relpath_posix

View File

@ -0,0 +1,322 @@
"""Loading unittests."""
import os
import re
import sys
import traceback
import types
import unittest
from fnmatch import fnmatch
from django.utils.unittest import case, suite
try:
from os.path import relpath
except ImportError:
from django.utils.unittest.compatibility import relpath
__unittest = True
def _CmpToKey(mycmp):
'Convert a cmp= function into a key= function'
class K(object):
def __init__(self, obj):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) == -1
return K
# what about .pyc or .pyo (etc)
# we would need to avoid loading the same tests multiple times
# from '.py', '.pyc' *and* '.pyo'
VALID_MODULE_NAME = re.compile(r'[_a-z]\w*\.py$', re.IGNORECASE)
def _make_failed_import_test(name, suiteClass):
message = 'Failed to import test module: %s' % name
if hasattr(traceback, 'format_exc'):
# Python 2.3 compatibility
# format_exc returns two frames of discover.py as well
message += '\n%s' % traceback.format_exc()
return _make_failed_test('ModuleImportFailure', name, ImportError(message),
suiteClass)
def _make_failed_load_tests(name, exception, suiteClass):
return _make_failed_test('LoadTestsFailure', name, exception, suiteClass)
def _make_failed_test(classname, methodname, exception, suiteClass):
def testFailure(self):
raise exception
attrs = {methodname: testFailure}
TestClass = type(classname, (case.TestCase,), attrs)
return suiteClass((TestClass(methodname),))
class TestLoader(unittest.TestLoader):
"""
This class is responsible for loading tests according to various criteria
and returning them wrapped in a TestSuite
"""
testMethodPrefix = 'test'
sortTestMethodsUsing = cmp
suiteClass = suite.TestSuite
_top_level_dir = None
def loadTestsFromTestCase(self, testCaseClass):
"""Return a suite of all tests cases contained in testCaseClass"""
if issubclass(testCaseClass, suite.TestSuite):
raise TypeError("Test cases should not be derived from TestSuite."
" Maybe you meant to derive from TestCase?")
testCaseNames = self.getTestCaseNames(testCaseClass)
if not testCaseNames and hasattr(testCaseClass, 'runTest'):
testCaseNames = ['runTest']
loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
return loaded_suite
def loadTestsFromModule(self, module, use_load_tests=True):
"""Return a suite of all tests cases contained in the given module"""
tests = []
for name in dir(module):
obj = getattr(module, name)
if isinstance(obj, type) and issubclass(obj, unittest.TestCase):
tests.append(self.loadTestsFromTestCase(obj))
load_tests = getattr(module, 'load_tests', None)
tests = self.suiteClass(tests)
if use_load_tests and load_tests is not None:
try:
return load_tests(self, tests, None)
except Exception, e:
return _make_failed_load_tests(module.__name__, e,
self.suiteClass)
return tests
def loadTestsFromName(self, name, module=None):
"""Return a suite of all tests cases given a string specifier.
The name may resolve either to a module, a test case class, a
test method within a test case class, or a callable object which
returns a TestCase or TestSuite instance.
The method optionally resolves the names relative to a given module.
"""
parts = name.split('.')
if module is None:
parts_copy = parts[:]
while parts_copy:
try:
module = __import__('.'.join(parts_copy))
break
except ImportError:
del parts_copy[-1]
if not parts_copy:
raise
parts = parts[1:]
obj = module
for part in parts:
parent, obj = obj, getattr(obj, part)
if isinstance(obj, types.ModuleType):
return self.loadTestsFromModule(obj)
elif isinstance(obj, type) and issubclass(obj, unittest.TestCase):
return self.loadTestsFromTestCase(obj)
elif (isinstance(obj, types.UnboundMethodType) and
isinstance(parent, type) and
issubclass(parent, case.TestCase)):
return self.suiteClass([parent(obj.__name__)])
elif isinstance(obj, unittest.TestSuite):
return obj
elif hasattr(obj, '__call__'):
test = obj()
if isinstance(test, unittest.TestSuite):
return test
elif isinstance(test, unittest.TestCase):
return self.suiteClass([test])
else:
raise TypeError("calling %s returned %s, not a test" %
(obj, test))
else:
raise TypeError("don't know how to make test from: %s" % obj)
def loadTestsFromNames(self, names, module=None):
"""Return a suite of all tests cases found using the given sequence
of string specifiers. See 'loadTestsFromName()'.
"""
suites = [self.loadTestsFromName(name, module) for name in names]
return self.suiteClass(suites)
def getTestCaseNames(self, testCaseClass):
"""Return a sorted sequence of method names found within testCaseClass
"""
def isTestMethod(attrname, testCaseClass=testCaseClass,
prefix=self.testMethodPrefix):
return attrname.startswith(prefix) and \
hasattr(getattr(testCaseClass, attrname), '__call__')
testFnNames = filter(isTestMethod, dir(testCaseClass))
if self.sortTestMethodsUsing:
testFnNames.sort(key=_CmpToKey(self.sortTestMethodsUsing))
return testFnNames
def discover(self, start_dir, pattern='test*.py', top_level_dir=None):
"""Find and return all test modules from the specified start
directory, recursing into subdirectories to find them. Only test files
that match the pattern will be loaded. (Using shell style pattern
matching.)
All test modules must be importable from the top level of the project.
If the start directory is not the top level directory then the top
level directory must be specified separately.
If a test package name (directory with '__init__.py') matches the
pattern then the package will be checked for a 'load_tests' function. If
this exists then it will be called with loader, tests, pattern.
If load_tests exists then discovery does *not* recurse into the package,
load_tests is responsible for loading all tests in the package.
The pattern is deliberately not stored as a loader attribute so that
packages can continue discovery themselves. top_level_dir is stored so
load_tests does not need to pass this argument in to loader.discover().
"""
set_implicit_top = False
if top_level_dir is None and self._top_level_dir is not None:
# make top_level_dir optional if called from load_tests in a package
top_level_dir = self._top_level_dir
elif top_level_dir is None:
set_implicit_top = True
top_level_dir = start_dir
top_level_dir = os.path.abspath(top_level_dir)
if not top_level_dir in sys.path:
# all test modules must be importable from the top level directory
# should we *unconditionally* put the start directory in first
# in sys.path to minimise likelihood of conflicts between installed
# modules and development versions?
sys.path.insert(0, top_level_dir)
self._top_level_dir = top_level_dir
is_not_importable = False
if os.path.isdir(os.path.abspath(start_dir)):
start_dir = os.path.abspath(start_dir)
if start_dir != top_level_dir:
is_not_importable = not os.path.isfile(os.path.join(start_dir, '__init__.py'))
else:
# support for discovery from dotted module names
try:
__import__(start_dir)
except ImportError:
is_not_importable = True
else:
the_module = sys.modules[start_dir]
top_part = start_dir.split('.')[0]
start_dir = os.path.abspath(os.path.dirname((the_module.__file__)))
if set_implicit_top:
self._top_level_dir = os.path.abspath(os.path.dirname(os.path.dirname(sys.modules[top_part].__file__)))
sys.path.remove(top_level_dir)
if is_not_importable:
raise ImportError('Start directory is not importable: %r' % start_dir)
tests = list(self._find_tests(start_dir, pattern))
return self.suiteClass(tests)
def _get_name_from_path(self, path):
path = os.path.splitext(os.path.normpath(path))[0]
_relpath = relpath(path, self._top_level_dir)
assert not os.path.isabs(_relpath), "Path must be within the project"
assert not _relpath.startswith('..'), "Path must be within the project"
name = _relpath.replace(os.path.sep, '.')
return name
def _get_module_from_name(self, name):
__import__(name)
return sys.modules[name]
def _match_path(self, path, full_path, pattern):
# override this method to use alternative matching strategy
return fnmatch(path, pattern)
def _find_tests(self, start_dir, pattern):
"""Used by discovery. Yields test suites it loads."""
paths = os.listdir(start_dir)
for path in paths:
full_path = os.path.join(start_dir, path)
if os.path.isfile(full_path):
if not VALID_MODULE_NAME.match(path):
# valid Python identifiers only
continue
if not self._match_path(path, full_path, pattern):
continue
# if the test file matches, load it
name = self._get_name_from_path(full_path)
try:
module = self._get_module_from_name(name)
except:
yield _make_failed_import_test(name, self.suiteClass)
else:
mod_file = os.path.abspath(getattr(module, '__file__', full_path))
realpath = os.path.splitext(mod_file)[0]
fullpath_noext = os.path.splitext(full_path)[0]
if realpath.lower() != fullpath_noext.lower():
module_dir = os.path.dirname(realpath)
mod_name = os.path.splitext(os.path.basename(full_path))[0]
expected_dir = os.path.dirname(full_path)
msg = ("%r module incorrectly imported from %r. Expected %r. "
"Is this module globally installed?")
raise ImportError(msg % (mod_name, module_dir, expected_dir))
yield self.loadTestsFromModule(module)
elif os.path.isdir(full_path):
if not os.path.isfile(os.path.join(full_path, '__init__.py')):
continue
load_tests = None
tests = None
if fnmatch(path, pattern):
# only check load_tests if the package directory itself matches the filter
name = self._get_name_from_path(full_path)
package = self._get_module_from_name(name)
load_tests = getattr(package, 'load_tests', None)
tests = self.loadTestsFromModule(package, use_load_tests=False)
if load_tests is None:
if tests is not None:
# tests loaded from package file
yield tests
# recurse into the package
for test in self._find_tests(full_path, pattern):
yield test
else:
try:
yield load_tests(self, tests, pattern)
except Exception, e:
yield _make_failed_load_tests(package.__name__, e,
self.suiteClass)
defaultTestLoader = TestLoader()
def _makeLoader(prefix, sortUsing, suiteClass=None):
loader = TestLoader()
loader.sortTestMethodsUsing = sortUsing
loader.testMethodPrefix = prefix
if suiteClass:
loader.suiteClass = suiteClass
return loader
def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
def makeSuite(testCaseClass, prefix='test', sortUsing=cmp,
suiteClass=suite.TestSuite):
return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
def findTestCases(module, prefix='test', sortUsing=cmp,
suiteClass=suite.TestSuite):
return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)

View File

@ -0,0 +1,241 @@
"""Unittest main program"""
import sys
import os
import types
from django.utils.unittest import loader, runner
try:
from django.utils.unittest.signals import installHandler
except ImportError:
installHandler = None
__unittest = True
FAILFAST = " -f, --failfast Stop on first failure\n"
CATCHBREAK = " -c, --catch Catch control-C and display results\n"
BUFFEROUTPUT = " -b, --buffer Buffer stdout and stderr during test runs\n"
USAGE_AS_MAIN = """\
Usage: %(progName)s [options] [tests]
Options:
-h, --help Show this message
-v, --verbose Verbose output
-q, --quiet Minimal output
%(failfast)s%(catchbreak)s%(buffer)s
Examples:
%(progName)s test_module - run tests from test_module
%(progName)s test_module.TestClass - run tests from
test_module.TestClass
%(progName)s test_module.TestClass.test_method - run specified test method
[tests] can be a list of any number of test modules, classes and test
methods.
Alternative Usage: %(progName)s discover [options]
Options:
-v, --verbose Verbose output
%(failfast)s%(catchbreak)s%(buffer)s -s directory Directory to start discovery ('.' default)
-p pattern Pattern to match test files ('test*.py' default)
-t directory Top level directory of project (default to
start directory)
For test discovery all test modules must be importable from the top
level directory of the project.
"""
USAGE_FROM_MODULE = """\
Usage: %(progName)s [options] [test] [...]
Options:
-h, --help Show this message
-v, --verbose Verbose output
-q, --quiet Minimal output
%(failfast)s%(catchbreak)s%(buffer)s
Examples:
%(progName)s - run default set of tests
%(progName)s MyTestSuite - run suite 'MyTestSuite'
%(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
%(progName)s MyTestCase - run all 'test*' test methods
in MyTestCase
"""
class TestProgram(object):
"""A command-line program that runs a set of tests; this is primarily
for making test modules conveniently executable.
"""
USAGE = USAGE_FROM_MODULE
# defaults for testing
failfast = catchbreak = buffer = progName = None
def __init__(self, module='__main__', defaultTest=None,
argv=None, testRunner=None,
testLoader=loader.defaultTestLoader, exit=True,
verbosity=1, failfast=None, catchbreak=None, buffer=None):
if isinstance(module, basestring):
self.module = __import__(module)
for part in module.split('.')[1:]:
self.module = getattr(self.module, part)
else:
self.module = module
if argv is None:
argv = sys.argv
self.exit = exit
self.verbosity = verbosity
self.failfast = failfast
self.catchbreak = catchbreak
self.buffer = buffer
self.defaultTest = defaultTest
self.testRunner = testRunner
self.testLoader = testLoader
self.progName = os.path.basename(argv[0])
self.parseArgs(argv)
self.runTests()
def usageExit(self, msg=None):
if msg:
print msg
usage = {'progName': self.progName, 'catchbreak': '', 'failfast': '',
'buffer': ''}
if self.failfast != False:
usage['failfast'] = FAILFAST
if self.catchbreak != False and installHandler is not None:
usage['catchbreak'] = CATCHBREAK
if self.buffer != False:
usage['buffer'] = BUFFEROUTPUT
print self.USAGE % usage
sys.exit(2)
def parseArgs(self, argv):
if len(argv) > 1 and argv[1].lower() == 'discover':
self._do_discovery(argv[2:])
return
import getopt
long_opts = ['help', 'verbose', 'quiet', 'failfast', 'catch', 'buffer']
try:
options, args = getopt.getopt(argv[1:], 'hHvqfcb', long_opts)
for opt, value in options:
if opt in ('-h','-H','--help'):
self.usageExit()
if opt in ('-q','--quiet'):
self.verbosity = 0
if opt in ('-v','--verbose'):
self.verbosity = 2
if opt in ('-f','--failfast'):
if self.failfast is None:
self.failfast = True
# Should this raise an exception if -f is not valid?
if opt in ('-c','--catch'):
if self.catchbreak is None and installHandler is not None:
self.catchbreak = True
# Should this raise an exception if -c is not valid?
if opt in ('-b','--buffer'):
if self.buffer is None:
self.buffer = True
# Should this raise an exception if -b is not valid?
if len(args) == 0 and self.defaultTest is None:
# createTests will load tests from self.module
self.testNames = None
elif len(args) > 0:
self.testNames = args
if __name__ == '__main__':
# to support python -m unittest ...
self.module = None
else:
self.testNames = (self.defaultTest,)
self.createTests()
except getopt.error, msg:
self.usageExit(msg)
def createTests(self):
if self.testNames is None:
self.test = self.testLoader.loadTestsFromModule(self.module)
else:
self.test = self.testLoader.loadTestsFromNames(self.testNames,
self.module)
def _do_discovery(self, argv, Loader=loader.TestLoader):
# handle command line args for test discovery
self.progName = '%s discover' % self.progName
import optparse
parser = optparse.OptionParser()
parser.prog = self.progName
parser.add_option('-v', '--verbose', dest='verbose', default=False,
help='Verbose output', action='store_true')
if self.failfast != False:
parser.add_option('-f', '--failfast', dest='failfast', default=False,
help='Stop on first fail or error',
action='store_true')
if self.catchbreak != False and installHandler is not None:
parser.add_option('-c', '--catch', dest='catchbreak', default=False,
help='Catch ctrl-C and display results so far',
action='store_true')
if self.buffer != False:
parser.add_option('-b', '--buffer', dest='buffer', default=False,
help='Buffer stdout and stderr during tests',
action='store_true')
parser.add_option('-s', '--start-directory', dest='start', default='.',
help="Directory to start discovery ('.' default)")
parser.add_option('-p', '--pattern', dest='pattern', default='test*.py',
help="Pattern to match tests ('test*.py' default)")
parser.add_option('-t', '--top-level-directory', dest='top', default=None,
help='Top level directory of project (defaults to start directory)')
options, args = parser.parse_args(argv)
if len(args) > 3:
self.usageExit()
for name, value in zip(('start', 'pattern', 'top'), args):
setattr(options, name, value)
# only set options from the parsing here
# if they weren't set explicitly in the constructor
if self.failfast is None:
self.failfast = options.failfast
if self.catchbreak is None and installHandler is not None:
self.catchbreak = options.catchbreak
if self.buffer is None:
self.buffer = options.buffer
if options.verbose:
self.verbosity = 2
start_dir = options.start
pattern = options.pattern
top_level_dir = options.top
loader = Loader()
self.test = loader.discover(start_dir, pattern, top_level_dir)
def runTests(self):
if self.catchbreak:
installHandler()
if self.testRunner is None:
self.testRunner = runner.TextTestRunner
if isinstance(self.testRunner, (type, types.ClassType)):
try:
testRunner = self.testRunner(verbosity=self.verbosity,
failfast=self.failfast,
buffer=self.buffer)
except TypeError:
# didn't accept the verbosity, buffer or failfast arguments
testRunner = self.testRunner()
else:
# it is assumed to be a TestRunner instance
testRunner = self.testRunner
self.result = testRunner.run(self.test)
if self.exit:
sys.exit(not self.result.wasSuccessful())
main = TestProgram
def main_():
TestProgram.USAGE = USAGE_AS_MAIN
main(module=None)

View File

@ -0,0 +1,183 @@
"""Test result object"""
import sys
import traceback
import unittest
from StringIO import StringIO
from django.utils.unittest import util
from django.utils.unittest.compatibility import wraps
__unittest = True
def failfast(method):
@wraps(method)
def inner(self, *args, **kw):
if getattr(self, 'failfast', False):
self.stop()
return method(self, *args, **kw)
return inner
STDOUT_LINE = '\nStdout:\n%s'
STDERR_LINE = '\nStderr:\n%s'
class TestResult(unittest.TestResult):
"""Holder for test result information.
Test results are automatically managed by the TestCase and TestSuite
classes, and do not need to be explicitly manipulated by writers of tests.
Each instance holds the total number of tests run, and collections of
failures and errors that occurred among those test runs. The collections
contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
formatted traceback of the error that occurred.
"""
_previousTestClass = None
_moduleSetUpFailed = False
def __init__(self):
self.failfast = False
self.failures = []
self.errors = []
self.testsRun = 0
self.skipped = []
self.expectedFailures = []
self.unexpectedSuccesses = []
self.shouldStop = False
self.buffer = False
self._stdout_buffer = None
self._stderr_buffer = None
self._original_stdout = sys.stdout
self._original_stderr = sys.stderr
self._mirrorOutput = False
def startTest(self, test):
"Called when the given test is about to be run"
self.testsRun += 1
self._mirrorOutput = False
if self.buffer:
if self._stderr_buffer is None:
self._stderr_buffer = StringIO()
self._stdout_buffer = StringIO()
sys.stdout = self._stdout_buffer
sys.stderr = self._stderr_buffer
def startTestRun(self):
"""Called once before any tests are executed.
See startTest for a method called before each test.
"""
def stopTest(self, test):
"""Called when the given test has been run"""
if self.buffer:
if self._mirrorOutput:
output = sys.stdout.getvalue()
error = sys.stderr.getvalue()
if output:
if not output.endswith('\n'):
output += '\n'
self._original_stdout.write(STDOUT_LINE % output)
if error:
if not error.endswith('\n'):
error += '\n'
self._original_stderr.write(STDERR_LINE % error)
sys.stdout = self._original_stdout
sys.stderr = self._original_stderr
self._stdout_buffer.seek(0)
self._stdout_buffer.truncate()
self._stderr_buffer.seek(0)
self._stderr_buffer.truncate()
self._mirrorOutput = False
def stopTestRun(self):
"""Called once after all tests are executed.
See stopTest for a method called after each test.
"""
@failfast
def addError(self, test, err):
"""Called when an error has occurred. 'err' is a tuple of values as
returned by sys.exc_info().
"""
self.errors.append((test, self._exc_info_to_string(err, test)))
self._mirrorOutput = True
@failfast
def addFailure(self, test, err):
"""Called when an error has occurred. 'err' is a tuple of values as
returned by sys.exc_info()."""
self.failures.append((test, self._exc_info_to_string(err, test)))
self._mirrorOutput = True
def addSuccess(self, test):
"Called when a test has completed successfully"
pass
def addSkip(self, test, reason):
"""Called when a test is skipped."""
self.skipped.append((test, reason))
def addExpectedFailure(self, test, err):
"""Called when an expected failure/error occured."""
self.expectedFailures.append(
(test, self._exc_info_to_string(err, test)))
@failfast
def addUnexpectedSuccess(self, test):
"""Called when a test was expected to fail, but succeed."""
self.unexpectedSuccesses.append(test)
def wasSuccessful(self):
"Tells whether or not this result was a success"
return (len(self.failures) + len(self.errors) == 0)
def stop(self):
"Indicates that the tests should be aborted"
self.shouldStop = True
def _exc_info_to_string(self, err, test):
"""Converts a sys.exc_info()-style tuple of values into a string."""
exctype, value, tb = err
# Skip test runner traceback levels
while tb and self._is_relevant_tb_level(tb):
tb = tb.tb_next
if exctype is test.failureException:
# Skip assert*() traceback levels
length = self._count_relevant_tb_levels(tb)
msgLines = traceback.format_exception(exctype, value, tb, length)
else:
msgLines = traceback.format_exception(exctype, value, tb)
if self.buffer:
output = sys.stdout.getvalue()
error = sys.stderr.getvalue()
if output:
if not output.endswith('\n'):
output += '\n'
msgLines.append(STDOUT_LINE % output)
if error:
if not error.endswith('\n'):
error += '\n'
msgLines.append(STDERR_LINE % error)
return ''.join(msgLines)
def _is_relevant_tb_level(self, tb):
return '__unittest' in tb.tb_frame.f_globals
def _count_relevant_tb_levels(self, tb):
length = 0
while tb and not self._is_relevant_tb_level(tb):
length += 1
tb = tb.tb_next
return length
def __repr__(self):
return "<%s run=%i errors=%i failures=%i>" % \
(util.strclass(self.__class__), self.testsRun, len(self.errors),
len(self.failures))

View File

@ -0,0 +1,206 @@
"""Running tests"""
import sys
import time
import unittest
from django.utils.unittest import result
try:
from django.utils.unittest.signals import registerResult
except ImportError:
def registerResult(_):
pass
__unittest = True
class _WritelnDecorator(object):
"""Used to decorate file-like objects with a handy 'writeln' method"""
def __init__(self,stream):
self.stream = stream
def __getattr__(self, attr):
if attr in ('stream', '__getstate__'):
raise AttributeError(attr)
return getattr(self.stream,attr)
def writeln(self, arg=None):
if arg:
self.write(arg)
self.write('\n') # text-mode streams translate to \r\n if needed
class TextTestResult(result.TestResult):
"""A test result class that can print formatted text results to a stream.
Used by TextTestRunner.
"""
separator1 = '=' * 70
separator2 = '-' * 70
def __init__(self, stream, descriptions, verbosity):
super(TextTestResult, self).__init__()
self.stream = stream
self.showAll = verbosity > 1
self.dots = verbosity == 1
self.descriptions = descriptions
def getDescription(self, test):
doc_first_line = test.shortDescription()
if self.descriptions and doc_first_line:
return '\n'.join((str(test), doc_first_line))
else:
return str(test)
def startTest(self, test):
super(TextTestResult, self).startTest(test)
if self.showAll:
self.stream.write(self.getDescription(test))
self.stream.write(" ... ")
self.stream.flush()
def addSuccess(self, test):
super(TextTestResult, self).addSuccess(test)
if self.showAll:
self.stream.writeln("ok")
elif self.dots:
self.stream.write('.')
self.stream.flush()
def addError(self, test, err):
super(TextTestResult, self).addError(test, err)
if self.showAll:
self.stream.writeln("ERROR")
elif self.dots:
self.stream.write('E')
self.stream.flush()
def addFailure(self, test, err):
super(TextTestResult, self).addFailure(test, err)
if self.showAll:
self.stream.writeln("FAIL")
elif self.dots:
self.stream.write('F')
self.stream.flush()
def addSkip(self, test, reason):
super(TextTestResult, self).addSkip(test, reason)
if self.showAll:
self.stream.writeln("skipped %r" % (reason,))
elif self.dots:
self.stream.write("s")
self.stream.flush()
def addExpectedFailure(self, test, err):
super(TextTestResult, self).addExpectedFailure(test, err)
if self.showAll:
self.stream.writeln("expected failure")
elif self.dots:
self.stream.write("x")
self.stream.flush()
def addUnexpectedSuccess(self, test):
super(TextTestResult, self).addUnexpectedSuccess(test)
if self.showAll:
self.stream.writeln("unexpected success")
elif self.dots:
self.stream.write("u")
self.stream.flush()
def printErrors(self):
if self.dots or self.showAll:
self.stream.writeln()
self.printErrorList('ERROR', self.errors)
self.printErrorList('FAIL', self.failures)
def printErrorList(self, flavour, errors):
for test, err in errors:
self.stream.writeln(self.separator1)
self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
self.stream.writeln(self.separator2)
self.stream.writeln("%s" % err)
def stopTestRun(self):
super(TextTestResult, self).stopTestRun()
self.printErrors()
class TextTestRunner(unittest.TextTestRunner):
"""A test runner class that displays results in textual form.
It prints out the names of tests as they are run, errors as they
occur, and a summary of the results at the end of the test run.
"""
resultclass = TextTestResult
def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1,
failfast=False, buffer=False, resultclass=None):
self.stream = _WritelnDecorator(stream)
self.descriptions = descriptions
self.verbosity = verbosity
self.failfast = failfast
self.buffer = buffer
if resultclass is not None:
self.resultclass = resultclass
def _makeResult(self):
return self.resultclass(self.stream, self.descriptions, self.verbosity)
def run(self, test):
"Run the given test case or test suite."
result = self._makeResult()
result.failfast = self.failfast
result.buffer = self.buffer
registerResult(result)
startTime = time.time()
startTestRun = getattr(result, 'startTestRun', None)
if startTestRun is not None:
startTestRun()
try:
test(result)
finally:
stopTestRun = getattr(result, 'stopTestRun', None)
if stopTestRun is not None:
stopTestRun()
else:
result.printErrors()
stopTime = time.time()
timeTaken = stopTime - startTime
if hasattr(result, 'separator2'):
self.stream.writeln(result.separator2)
run = result.testsRun
self.stream.writeln("Ran %d test%s in %.3fs" %
(run, run != 1 and "s" or "", timeTaken))
self.stream.writeln()
expectedFails = unexpectedSuccesses = skipped = 0
try:
results = map(len, (result.expectedFailures,
result.unexpectedSuccesses,
result.skipped))
expectedFails, unexpectedSuccesses, skipped = results
except AttributeError:
pass
infos = []
if not result.wasSuccessful():
self.stream.write("FAILED")
failed, errored = map(len, (result.failures, result.errors))
if failed:
infos.append("failures=%d" % failed)
if errored:
infos.append("errors=%d" % errored)
else:
self.stream.write("OK")
if skipped:
infos.append("skipped=%d" % skipped)
if expectedFails:
infos.append("expected failures=%d" % expectedFails)
if unexpectedSuccesses:
infos.append("unexpected successes=%d" % unexpectedSuccesses)
if infos:
self.stream.writeln(" (%s)" % (", ".join(infos),))
else:
self.stream.write("\n")
return result

View File

@ -0,0 +1,57 @@
import signal
import weakref
from django.utils.unittest.compatibility import wraps
__unittest = True
class _InterruptHandler(object):
def __init__(self, default_handler):
self.called = False
self.default_handler = default_handler
def __call__(self, signum, frame):
installed_handler = signal.getsignal(signal.SIGINT)
if installed_handler is not self:
# if we aren't the installed handler, then delegate immediately
# to the default handler
self.default_handler(signum, frame)
if self.called:
self.default_handler(signum, frame)
self.called = True
for result in _results.keys():
result.stop()
_results = weakref.WeakKeyDictionary()
def registerResult(result):
_results[result] = 1
def removeResult(result):
return bool(_results.pop(result, None))
_interrupt_handler = None
def installHandler():
global _interrupt_handler
if _interrupt_handler is None:
default_handler = signal.getsignal(signal.SIGINT)
_interrupt_handler = _InterruptHandler(default_handler)
signal.signal(signal.SIGINT, _interrupt_handler)
def removeHandler(method=None):
if method is not None:
@wraps(method)
def inner(*args, **kwargs):
initial = signal.getsignal(signal.SIGINT)
removeHandler()
try:
return method(*args, **kwargs)
finally:
signal.signal(signal.SIGINT, initial)
return inner
global _interrupt_handler
if _interrupt_handler is not None:
signal.signal(signal.SIGINT, _interrupt_handler.default_handler)

View File

@ -0,0 +1,287 @@
"""TestSuite"""
import sys
import unittest
from django.utils.unittest import case, util
__unittest = True
class BaseTestSuite(unittest.TestSuite):
"""A simple test suite that doesn't provide class or module shared fixtures.
"""
def __init__(self, tests=()):
self._tests = []
self.addTests(tests)
def __repr__(self):
return "<%s tests=%s>" % (util.strclass(self.__class__), list(self))
def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return list(self) == list(other)
def __ne__(self, other):
return not self == other
# Can't guarantee hash invariant, so flag as unhashable
__hash__ = None
def __iter__(self):
return iter(self._tests)
def countTestCases(self):
cases = 0
for test in self:
cases += test.countTestCases()
return cases
def addTest(self, test):
# sanity checks
if not hasattr(test, '__call__'):
raise TypeError("%r is not callable" % (repr(test),))
if isinstance(test, type) and issubclass(test,
(case.TestCase, TestSuite)):
raise TypeError("TestCases and TestSuites must be instantiated "
"before passing them to addTest()")
self._tests.append(test)
def addTests(self, tests):
if isinstance(tests, basestring):
raise TypeError("tests must be an iterable of tests, not a string")
for test in tests:
self.addTest(test)
def run(self, result):
for test in self:
if result.shouldStop:
break
test(result)
return result
def __call__(self, *args, **kwds):
return self.run(*args, **kwds)
def debug(self):
"""Run the tests without collecting errors in a TestResult"""
for test in self:
test.debug()
class TestSuite(BaseTestSuite):
"""A test suite is a composite test consisting of a number of TestCases.
For use, create an instance of TestSuite, then add test case instances.
When all tests have been added, the suite can be passed to a test
runner, such as TextTestRunner. It will run the individual test cases
in the order in which they were added, aggregating the results. When
subclassing, do not forget to call the base class constructor.
"""
def run(self, result):
self._wrapped_run(result)
self._tearDownPreviousClass(None, result)
self._handleModuleTearDown(result)
return result
def debug(self):
"""Run the tests without collecting errors in a TestResult"""
debug = _DebugResult()
self._wrapped_run(debug, True)
self._tearDownPreviousClass(None, debug)
self._handleModuleTearDown(debug)
################################
# private methods
def _wrapped_run(self, result, debug=False):
for test in self:
if result.shouldStop:
break
if _isnotsuite(test):
self._tearDownPreviousClass(test, result)
self._handleModuleFixture(test, result)
self._handleClassSetUp(test, result)
result._previousTestClass = test.__class__
if (getattr(test.__class__, '_classSetupFailed', False) or
getattr(result, '_moduleSetUpFailed', False)):
continue
if hasattr(test, '_wrapped_run'):
test._wrapped_run(result, debug)
elif not debug:
test(result)
else:
test.debug()
def _handleClassSetUp(self, test, result):
previousClass = getattr(result, '_previousTestClass', None)
currentClass = test.__class__
if currentClass == previousClass:
return
if result._moduleSetUpFailed:
return
if getattr(currentClass, "__unittest_skip__", False):
return
try:
currentClass._classSetupFailed = False
except TypeError:
# test may actually be a function
# so its class will be a builtin-type
pass
setUpClass = getattr(currentClass, 'setUpClass', None)
if setUpClass is not None:
try:
setUpClass()
except Exception, e:
if isinstance(result, _DebugResult):
raise
currentClass._classSetupFailed = True
className = util.strclass(currentClass)
errorName = 'setUpClass (%s)' % className
self._addClassOrModuleLevelException(result, e, errorName)
def _get_previous_module(self, result):
previousModule = None
previousClass = getattr(result, '_previousTestClass', None)
if previousClass is not None:
previousModule = previousClass.__module__
return previousModule
def _handleModuleFixture(self, test, result):
previousModule = self._get_previous_module(result)
currentModule = test.__class__.__module__
if currentModule == previousModule:
return
self._handleModuleTearDown(result)
result._moduleSetUpFailed = False
try:
module = sys.modules[currentModule]
except KeyError:
return
setUpModule = getattr(module, 'setUpModule', None)
if setUpModule is not None:
try:
setUpModule()
except Exception, e:
if isinstance(result, _DebugResult):
raise
result._moduleSetUpFailed = True
errorName = 'setUpModule (%s)' % currentModule
self._addClassOrModuleLevelException(result, e, errorName)
def _addClassOrModuleLevelException(self, result, exception, errorName):
error = _ErrorHolder(errorName)
addSkip = getattr(result, 'addSkip', None)
if addSkip is not None and isinstance(exception, case.SkipTest):
addSkip(error, str(exception))
else:
result.addError(error, sys.exc_info())
def _handleModuleTearDown(self, result):
previousModule = self._get_previous_module(result)
if previousModule is None:
return
if result._moduleSetUpFailed:
return
try:
module = sys.modules[previousModule]
except KeyError:
return
tearDownModule = getattr(module, 'tearDownModule', None)
if tearDownModule is not None:
try:
tearDownModule()
except Exception, e:
if isinstance(result, _DebugResult):
raise
errorName = 'tearDownModule (%s)' % previousModule
self._addClassOrModuleLevelException(result, e, errorName)
def _tearDownPreviousClass(self, test, result):
previousClass = getattr(result, '_previousTestClass', None)
currentClass = test.__class__
if currentClass == previousClass:
return
if getattr(previousClass, '_classSetupFailed', False):
return
if getattr(result, '_moduleSetUpFailed', False):
return
if getattr(previousClass, "__unittest_skip__", False):
return
tearDownClass = getattr(previousClass, 'tearDownClass', None)
if tearDownClass is not None:
try:
tearDownClass()
except Exception, e:
if isinstance(result, _DebugResult):
raise
className = util.strclass(previousClass)
errorName = 'tearDownClass (%s)' % className
self._addClassOrModuleLevelException(result, e, errorName)
class _ErrorHolder(object):
"""
Placeholder for a TestCase inside a result. As far as a TestResult
is concerned, this looks exactly like a unit test. Used to insert
arbitrary errors into a test suite run.
"""
# Inspired by the ErrorHolder from Twisted:
# http://twistedmatrix.com/trac/browser/trunk/twisted/trial/runner.py
# attribute used by TestResult._exc_info_to_string
failureException = None
def __init__(self, description):
self.description = description
def id(self):
return self.description
def shortDescription(self):
return None
def __repr__(self):
return "<ErrorHolder description=%r>" % (self.description,)
def __str__(self):
return self.id()
def run(self, result):
# could call result.addError(...) - but this test-like object
# shouldn't be run anyway
pass
def __call__(self, result):
return self.run(result)
def countTestCases(self):
return 0
def _isnotsuite(test):
"A crude way to tell apart testcases and suites with duck-typing"
try:
iter(test)
except TypeError:
return True
return False
class _DebugResult(object):
"Used by the TestSuite to hold previous class when running in debug."
_previousTestClass = None
_moduleSetUpFailed = False
shouldStop = False

View File

@ -0,0 +1,99 @@
"""Various utility functions."""
__unittest = True
_MAX_LENGTH = 80
def safe_repr(obj, short=False):
try:
result = repr(obj)
except Exception:
result = object.__repr__(obj)
if not short or len(result) < _MAX_LENGTH:
return result
return result[:_MAX_LENGTH] + ' [truncated]...'
def safe_str(obj):
try:
return str(obj)
except Exception:
return object.__str__(obj)
def strclass(cls):
return "%s.%s" % (cls.__module__, cls.__name__)
def sorted_list_difference(expected, actual):
"""Finds elements in only one or the other of two, sorted input lists.
Returns a two-element tuple of lists. The first list contains those
elements in the "expected" list but not in the "actual" list, and the
second contains those elements in the "actual" list but not in the
"expected" list. Duplicate elements in either input list are ignored.
"""
i = j = 0
missing = []
unexpected = []
while True:
try:
e = expected[i]
a = actual[j]
if e < a:
missing.append(e)
i += 1
while expected[i] == e:
i += 1
elif e > a:
unexpected.append(a)
j += 1
while actual[j] == a:
j += 1
else:
i += 1
try:
while expected[i] == e:
i += 1
finally:
j += 1
while actual[j] == a:
j += 1
except IndexError:
missing.extend(expected[i:])
unexpected.extend(actual[j:])
break
return missing, unexpected
def unorderable_list_difference(expected, actual, ignore_duplicate=False):
"""Same behavior as sorted_list_difference but
for lists of unorderable items (like dicts).
As it does a linear search per item (remove) it
has O(n*n) performance.
"""
missing = []
unexpected = []
while expected:
item = expected.pop()
try:
actual.remove(item)
except ValueError:
missing.append(item)
if ignore_duplicate:
for lst in expected, actual:
try:
while True:
lst.remove(item)
except ValueError:
pass
if ignore_duplicate:
while actual:
item = actual.pop()
unexpected.append(item)
try:
while True:
actual.remove(item)
except ValueError:
pass
return missing, unexpected
# anything left in actual is unexpected
return missing, actual

View File

@ -136,3 +136,31 @@ have been added to Django's own code as well -- most notably, the
error emails sent on a HTTP 500 server error are now handled as a
logging activity. See :doc:`the documentation on Django's logging
interface </topics/logging>` for more details.
``unittest2`` support
~~~~~~~~~~~~~~~~~~~~~
Python 2.7 introduced some major changes to the unittest library,
adding some extremely useful features. To ensure that every Django
project can benefit from these new features, Django ships with a
copy of unittest2_, a copy of the Python 2.7 unittest library,
backported for Python 2.4 compatibility.
To access this library, Django provides the
``django.utils.unittest`` module alias. If you are using Python
2.7, or you have installed unittest2 locally, Django will mapt the
alias to the installed version of the unittest library Otherwise,
Django will use it's own bundled version of unittest2.
To use this alias, simply use::
from django.utils import unittest
wherever you would historically used::
import unittest
If you want to continue to use the base unittest libary, you can --
you just won't get any of the nice new unittest2 features.
.. _unittest2: http://pypi.python.org/pypi/unittest2

View File

@ -57,8 +57,8 @@ frameworks are:
class MyFuncTestCase(unittest.TestCase):
def testBasic(self):
a = ['larry', 'curly', 'moe']
self.assertEquals(my_func(a, 0), 'larry')
self.assertEquals(my_func(a, 1), 'curly')
self.assertEqual(my_func(a, 0), 'larry')
self.assertEqual(my_func(a, 1), 'curly')
You can choose the test framework you like, depending on which syntax you
prefer, or you can mix and match, using one framework for some of your code and
@ -151,9 +151,38 @@ documentation for doctest`_.
Writing unit tests
------------------
Like doctests, Django's unit tests use a standard library module: unittest_.
This module uses a different way of defining tests, taking a class-based
approach.
Like doctests, Django's unit tests use a Python standard library
module: unittest_. This module uses a different way of defining tests,
taking a class-based approach.
.. admonition:: unittest2
.. versionchanged:: 1.3
Python 2.7 introduced some major changes to the unittest library,
adding some extremely useful features. To ensure that every Django
project can benefit from these new features, Django ships with a
copy of unittest2_, a copy of the Python 2.7 unittest library,
backported for Python 2.4 compatibility.
To access this library, Django provides the
``django.utils.unittest`` module alias. If you are using Python
2.7, or you have installed unittest2 locally, Django will mapt the
alias to the installed version of the unittest library Otherwise,
Django will use it's own bundled version of unittest2.
To use this alias, simply use::
from django.utils import unittest
wherever you would historically used::
import unittest
If you want to continue to use the base unittest libary, you can --
you just won't get any of the nice new unittest2 features.
.. _unittest2: http://pypi.python.org/pypi/unittest2
As with doctests, for a given Django application, the test runner looks for
unit tests in two places:
@ -168,7 +197,7 @@ unit tests in two places:
This example ``unittest.TestCase`` subclass is equivalent to the example given
in the doctest section above::
import unittest
from django.utils import unittest
from myapp.models import Animal
class AnimalTestCase(unittest.TestCase):
@ -177,8 +206,8 @@ in the doctest section above::
self.cat = Animal.objects.create(name="cat", sound="meow")
def testSpeaking(self):
self.assertEquals(self.lion.speak(), 'The lion says "roar"')
self.assertEquals(self.cat.speak(), 'The cat says "meow"')
self.assertEqual(self.lion.speak(), 'The lion says "roar"')
self.assertEqual(self.cat.speak(), 'The cat says "meow"')
When you :ref:`run your tests <running-tests>`, the default behavior of the
test utility is to find all the test cases (that is, subclasses of
@ -199,6 +228,7 @@ documentation`_.
.. _standard library unittest documentation: unittest_
.. _suggested organization: http://docs.python.org/library/unittest.html#organizing-tests
Which should I use?
-------------------
@ -231,6 +261,8 @@ you:
routines, which give you a high level of control over the environment
in which your test cases are run.
* If you're writing tests for Django itself, you should use ``unittest``.
Again, remember that you can use both systems side-by-side (even in the same
app). In the end, most projects will eventually end up using both. Each shines
in different circumstances.
@ -964,7 +996,7 @@ Example
The following is a simple unit test using the test client::
import unittest
from django.utils import unittest
from django.test.client import Client
class SimpleTest(unittest.TestCase):
@ -977,10 +1009,10 @@ The following is a simple unit test using the test client::
response = self.client.get('/customer/details/')
# Check that the response is 200 OK.
self.failUnlessEqual(response.status_code, 200)
self.assertEqual(response.status_code, 200)
# Check that the rendered context contains 5 customers.
self.failUnlessEqual(len(response.context['customers']), 5)
self.assertEqual(len(response.context['customers']), 5)
TestCase
--------
@ -1061,19 +1093,19 @@ worry about state (such as cookies) carrying over from one test to another.
This means, instead of instantiating a ``Client`` in each test::
import unittest
from django.utils import unittest
from django.test.client import Client
class SimpleTest(unittest.TestCase):
def test_details(self):
client = Client()
response = client.get('/customer/details/')
self.failUnlessEqual(response.status_code, 200)
self.assertEqual(response.status_code, 200)
def test_index(self):
client = Client()
response = client.get('/customer/index/')
self.failUnlessEqual(response.status_code, 200)
self.assertEqual(response.status_code, 200)
...you can just refer to ``self.client``, like so::
@ -1082,11 +1114,11 @@ This means, instead of instantiating a ``Client`` in each test::
class SimpleTest(TestCase):
def test_details(self):
response = self.client.get('/customer/details/')
self.failUnlessEqual(response.status_code, 200)
self.assertEqual(response.status_code, 200)
def test_index(self):
response = self.client.get('/customer/index/')
self.failUnlessEqual(response.status_code, 200)
self.assertEqual(response.status_code, 200)
Customizing the test client
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -1265,7 +1297,7 @@ Assertions
Addded ``msg_prefix`` argument.
As Python's normal ``unittest.TestCase`` class implements assertion methods
such as ``assertTrue`` and ``assertEquals``, Django's custom ``TestCase`` class
such as ``assertTrue`` and ``assertEqual``, Django's custom ``TestCase`` class
provides a number of custom assertion methods that are useful for testing Web
applications:
@ -1385,10 +1417,10 @@ and contents::
fail_silently=False)
# Test that one message has been sent.
self.assertEquals(len(mail.outbox), 1)
self.assertEqual(len(mail.outbox), 1)
# Verify that the subject of the first message is correct.
self.assertEquals(mail.outbox[0].subject, 'Subject here')
self.assertEqual(mail.outbox[0].subject, 'Subject here')
As noted :ref:`previously <emptying-test-outbox>`, the test outbox is emptied
at the start of every test in a Django ``TestCase``. To empty the outbox

View File

@ -4,7 +4,7 @@
This is a basic model with only two non-primary-key fields.
"""
from django.db import models, DEFAULT_DB_ALIAS
from django.db import models, DEFAULT_DB_ALIAS, connection
class Article(models.Model):
headline = models.CharField(max_length=100, default='Default headline')
@ -359,9 +359,7 @@ AttributeError: Manager isn't accessible via Article instances
from django.conf import settings
building_docs = getattr(settings, 'BUILDING_DOCS', False)
if building_docs or settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.postgresql':
if connection.features.supports_microsecond_precision:
__test__['API_TESTS'] += """
# In PostgreSQL, microsecond-level precision is available.
>>> a9 = Article(headline='Article 9', pub_date=datetime(2005, 7, 31, 12, 30, 45, 180))
@ -369,8 +367,7 @@ if building_docs or settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db
>>> Article.objects.get(id__exact=9).pub_date
datetime.datetime(2005, 7, 31, 12, 30, 45, 180)
"""
if building_docs or settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.mysql':
else:
__test__['API_TESTS'] += """
# In MySQL, microsecond-level precision isn't available. You'll lose
# microsecond-level precision once the data is saved.

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from django.db import DEFAULT_DB_ALIAS, transaction, IntegrityError
from django.test import TestCase
from django.test import TestCase, skipIfDBFeature
from models import Employee, Business, Bar, Foo
@ -168,16 +168,15 @@ class CustomPKTests(TestCase):
self.assertEqual(f, new_foo),
self.assertEqual(f.bar, new_bar)
# SQLite lets objects be saved with an empty primary key, even though an
# integer is expected. So we can't check for an error being raised in that
# case for SQLite. Remove it from the suite for this next bit.
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.sqlite3':
def test_required_pk(self):
# The primary key must be specified, so an error is raised if you
# try to create an object without it.
sid = transaction.savepoint()
self.assertRaises(IntegrityError,
Employee.objects.create, first_name="Tom", last_name="Smith"
)
transaction.savepoint_rollback(sid)
@skipIfDBFeature('supports_unspecified_pk')
def test_required_pk(self):
# The primary key must be specified, so an error is raised if you
# try to create an object without it.
sid = transaction.savepoint()
self.assertRaises(IntegrityError,
Employee.objects.create, first_name="Tom", last_name="Smith"
)
transaction.savepoint_rollback(sid)

View File

@ -1,13 +1,14 @@
import StringIO
import sys
from django.test import TestCase, TransactionTestCase
from django.conf import settings
from django.core import management
from django.db import DEFAULT_DB_ALIAS
from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature
from models import Article, Blog, Book, Category, Person, Spy, Tag, Visa
class TestCaseFixtureLoadingTests(TestCase):
fixtures = ['fixture1.json', 'fixture2.json']
@ -291,46 +292,46 @@ class FixtureLoadingTests(TestCase):
self._dumpdata_assert(['fixtures'], """<?xml version="1.0" encoding="utf-8"?>
<django-objects version="1.0"><object pk="1" model="fixtures.category"><field type="CharField" name="title">News Stories</field><field type="TextField" name="description">Latest news stories</field></object><object pk="3" model="fixtures.article"><field type="CharField" name="headline">Time to reform copyright</field><field type="DateTimeField" name="pub_date">2006-06-16 13:00:00</field></object><object pk="2" model="fixtures.article"><field type="CharField" name="headline">Poker has no place on ESPN</field><field type="DateTimeField" name="pub_date">2006-06-16 12:00:00</field></object><object pk="1" model="fixtures.article"><field type="CharField" name="headline">Python program becomes self aware</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.tag"><field type="CharField" name="name">copyright</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="2" model="fixtures.tag"><field type="CharField" name="name">law</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="1" model="fixtures.person"><field type="CharField" name="name">Django Reinhardt</field></object><object pk="3" model="fixtures.person"><field type="CharField" name="name">Prince</field></object><object pk="2" model="fixtures.person"><field type="CharField" name="name">Stephane Grappelli</field></object></django-objects>""", format='xml', natural_keys=True)
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.mysql':
class FixtureTransactionTests(TransactionTestCase):
def _dumpdata_assert(self, args, output, format='json'):
new_io = StringIO.StringIO()
management.call_command('dumpdata', *args, **{'format':format, 'stdout':new_io})
command_output = new_io.getvalue().strip()
self.assertEqual(command_output, output)
class FixtureTransactionTests(TransactionTestCase):
def _dumpdata_assert(self, args, output, format='json'):
new_io = StringIO.StringIO()
management.call_command('dumpdata', *args, **{'format':format, 'stdout':new_io})
command_output = new_io.getvalue().strip()
self.assertEqual(command_output, output)
def test_format_discovery(self):
# Load fixture 1 again, using format discovery
management.call_command('loaddata', 'fixture1', verbosity=0, commit=False)
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: Time to reform copyright>',
'<Article: Poker has no place on ESPN>',
'<Article: Python program becomes self aware>'
])
@skipUnlessDBFeature('supports_forward_references')
def test_format_discovery(self):
# Load fixture 1 again, using format discovery
management.call_command('loaddata', 'fixture1', verbosity=0, commit=False)
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: Time to reform copyright>',
'<Article: Poker has no place on ESPN>',
'<Article: Python program becomes self aware>'
])
# Try to load fixture 2 using format discovery; this will fail
# because there are two fixture2's in the fixtures directory
new_io = StringIO.StringIO()
management.call_command('loaddata', 'fixture2', verbosity=0, stderr=new_io)
output = new_io.getvalue().strip().split('\n')
self.assertEqual(len(output), 1)
self.assertTrue(output[0].startswith("Multiple fixtures named 'fixture2'"))
# Try to load fixture 2 using format discovery; this will fail
# because there are two fixture2's in the fixtures directory
new_io = StringIO.StringIO()
management.call_command('loaddata', 'fixture2', verbosity=0, stderr=new_io)
output = new_io.getvalue().strip().split('\n')
self.assertEqual(len(output), 1)
self.assertTrue(output[0].startswith("Multiple fixtures named 'fixture2'"))
# object list is unaffected
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: Time to reform copyright>',
'<Article: Poker has no place on ESPN>',
'<Article: Python program becomes self aware>'
])
# object list is unaffected
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: Time to reform copyright>',
'<Article: Poker has no place on ESPN>',
'<Article: Python program becomes self aware>'
])
# Dump the current contents of the database as a JSON fixture
self._dumpdata_assert(['fixtures'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]')
# Dump the current contents of the database as a JSON fixture
self._dumpdata_assert(['fixtures'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]')
# Load fixture 4 (compressed), using format discovery
management.call_command('loaddata', 'fixture4', verbosity=0, commit=False)
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: Django pets kitten>',
'<Article: Time to reform copyright>',
'<Article: Poker has no place on ESPN>',
'<Article: Python program becomes self aware>'
])
# Load fixture 4 (compressed), using format discovery
management.call_command('loaddata', 'fixture4', verbosity=0, commit=False)
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: Django pets kitten>',
'<Article: Time to reform copyright>',
'<Article: Poker has no place on ESPN>',
'<Article: Python program becomes self aware>'
])

View File

@ -4,7 +4,7 @@
This demonstrates features of the database API.
"""
from django.db import models, DEFAULT_DB_ALIAS
from django.db import models, DEFAULT_DB_ALIAS, connection
from django.conf import settings
class Article(models.Model):
@ -41,15 +41,16 @@ False
# There should be some now!
>>> Article.objects.exists()
True
"""}
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] in (
'django.db.backends.postgresql',
'django.db.backends.postgresql_pysycopg2'):
__test__['API_TESTS'] += r"""
# text matching tests for PostgreSQL 8.3
# Integer value can be queried using string
>>> Article.objects.filter(id__iexact='1')
[<Article: Article 1>]
"""}
if connection.features.supports_date_lookup_using_string:
__test__['API_TESTS'] += r"""
# A date lookup can be performed using a string search
>>> Article.objects.filter(pub_date__startswith='2005')
[<Article: Article 5>, <Article: Article 6>, <Article: Article 4>, <Article: Article 2>, <Article: Article 3>, <Article: Article 7>, <Article: Article 1>]
"""
@ -409,7 +410,7 @@ FieldError: Join on field 'headline' not permitted. Did you misspell 'starts' fo
"""
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.mysql':
if connection.features.supports_regex_backreferencing:
__test__['API_TESTS'] += r"""
# grouping and backreferences
>>> Article.objects.filter(headline__regex=r'b(.).*b\1')

View File

@ -1,6 +1,6 @@
# Validate that you can override the default test suite
import unittest
from django.utils import unittest
def suite():
"""

View File

@ -1,155 +1,159 @@
from django.test import TransactionTestCase
from django.db import connection, transaction, IntegrityError, DEFAULT_DB_ALIAS
from django.conf import settings
from django.test import TransactionTestCase, skipUnlessDBFeature
from models import Reporter
PGSQL = 'psycopg2' in settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE']
MYSQL = 'mysql' in settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE']
class TransactionTests(TransactionTestCase):
def create_a_reporter_then_fail(self, first, last):
a = Reporter(first_name=first, last_name=last)
a.save()
raise Exception("I meant to do that")
if not MYSQL:
def remove_a_reporter(self, first_name):
r = Reporter.objects.get(first_name="Alice")
r.delete()
def create_a_reporter_then_fail(self, first, last):
a = Reporter(first_name=first, last_name=last)
a.save()
raise Exception("I meant to do that")
def manually_managed(self):
r = Reporter(first_name="Dirk", last_name="Gently")
r.save()
transaction.commit()
def remove_a_reporter(self, first_name):
r = Reporter.objects.get(first_name="Alice")
r.delete()
def manually_managed_mistake(self):
r = Reporter(first_name="Edward", last_name="Woodward")
r.save()
# Oops, I forgot to commit/rollback!
def manually_managed(self):
r = Reporter(first_name="Dirk", last_name="Gently")
r.save()
transaction.commit()
@skipUnlessDBFeature('supports_transactions')
def test_autocommit(self):
"""
The default behavior is to autocommit after each save() action.
"""
self.assertRaises(Exception,
self.create_a_reporter_then_fail,
"Alice", "Smith"
)
def manually_managed_mistake(self):
r = Reporter(first_name="Edward", last_name="Woodward")
r.save()
# Oops, I forgot to commit/rollback!
# The object created before the exception still exists
self.assertEqual(Reporter.objects.count(), 1)
def execute_bad_sql(self):
cursor = connection.cursor()
cursor.execute("INSERT INTO transactions_reporter (first_name, last_name) VALUES ('Douglas', 'Adams');")
transaction.set_dirty()
@skipUnlessDBFeature('supports_transactions')
def test_autocommit_decorator(self):
"""
The autocommit decorator works exactly the same as the default behavior.
"""
autocomitted_create_then_fail = transaction.autocommit(
self.create_a_reporter_then_fail
)
self.assertRaises(Exception,
autocomitted_create_then_fail,
"Alice", "Smith"
)
# Again, the object created before the exception still exists
self.assertEqual(Reporter.objects.count(), 1)
def test_autocommit(self):
"""
The default behavior is to autocommit after each save() action.
"""
self.assertRaises(Exception,
self.create_a_reporter_then_fail,
"Alice", "Smith"
)
@skipUnlessDBFeature('supports_transactions')
def test_autocommit_decorator_with_using(self):
"""
The autocommit decorator also works with a using argument.
"""
autocomitted_create_then_fail = transaction.autocommit(using='default')(
self.create_a_reporter_then_fail
)
self.assertRaises(Exception,
autocomitted_create_then_fail,
"Alice", "Smith"
)
# Again, the object created before the exception still exists
self.assertEqual(Reporter.objects.count(), 1)
# The object created before the exception still exists
self.assertEqual(Reporter.objects.count(), 1)
@skipUnlessDBFeature('supports_transactions')
def test_commit_on_success(self):
"""
With the commit_on_success decorator, the transaction is only committed
if the function doesn't throw an exception.
"""
committed_on_success = transaction.commit_on_success(
self.create_a_reporter_then_fail)
self.assertRaises(Exception, committed_on_success, "Dirk", "Gently")
# This time the object never got saved
self.assertEqual(Reporter.objects.count(), 0)
def test_autocommit_decorator(self):
"""
The autocommit decorator works exactly the same as the default behavior.
"""
autocomitted_create_then_fail = transaction.autocommit(
self.create_a_reporter_then_fail
)
self.assertRaises(Exception,
autocomitted_create_then_fail,
"Alice", "Smith"
)
# Again, the object created before the exception still exists
self.assertEqual(Reporter.objects.count(), 1)
@skipUnlessDBFeature('supports_transactions')
def test_commit_on_success_with_using(self):
"""
The commit_on_success decorator also works with a using argument.
"""
using_committed_on_success = transaction.commit_on_success(using='default')(
self.create_a_reporter_then_fail
)
self.assertRaises(Exception,
using_committed_on_success,
"Dirk", "Gently"
)
# This time the object never got saved
self.assertEqual(Reporter.objects.count(), 0)
def test_autocommit_decorator_with_using(self):
"""
The autocommit decorator also works with a using argument.
"""
autocomitted_create_then_fail = transaction.autocommit(using='default')(
self.create_a_reporter_then_fail
)
self.assertRaises(Exception,
autocomitted_create_then_fail,
"Alice", "Smith"
)
# Again, the object created before the exception still exists
self.assertEqual(Reporter.objects.count(), 1)
@skipUnlessDBFeature('supports_transactions')
def test_commit_on_success_succeed(self):
"""
If there aren't any exceptions, the data will get saved.
"""
Reporter.objects.create(first_name="Alice", last_name="Smith")
remove_comitted_on_success = transaction.commit_on_success(
self.remove_a_reporter
)
remove_comitted_on_success("Alice")
self.assertEqual(list(Reporter.objects.all()), [])
def test_commit_on_success(self):
"""
With the commit_on_success decorator, the transaction is only committed
if the function doesn't throw an exception.
"""
committed_on_success = transaction.commit_on_success(
self.create_a_reporter_then_fail)
self.assertRaises(Exception, committed_on_success, "Dirk", "Gently")
# This time the object never got saved
self.assertEqual(Reporter.objects.count(), 0)
@skipUnlessDBFeature('supports_transactions')
def test_manually_managed(self):
"""
You can manually manage transactions if you really want to, but you
have to remember to commit/rollback.
"""
manually_managed = transaction.commit_manually(self.manually_managed)
manually_managed()
self.assertEqual(Reporter.objects.count(), 1)
def test_commit_on_success_with_using(self):
"""
The commit_on_success decorator also works with a using argument.
"""
using_committed_on_success = transaction.commit_on_success(using='default')(
self.create_a_reporter_then_fail
)
self.assertRaises(Exception,
using_committed_on_success,
"Dirk", "Gently"
)
# This time the object never got saved
self.assertEqual(Reporter.objects.count(), 0)
@skipUnlessDBFeature('supports_transactions')
def test_manually_managed_mistake(self):
"""
If you forget, you'll get bad errors.
"""
manually_managed_mistake = transaction.commit_manually(
self.manually_managed_mistake
)
self.assertRaises(transaction.TransactionManagementError,
manually_managed_mistake)
def test_commit_on_success_succeed(self):
"""
If there aren't any exceptions, the data will get saved.
"""
Reporter.objects.create(first_name="Alice", last_name="Smith")
remove_comitted_on_success = transaction.commit_on_success(
self.remove_a_reporter
)
remove_comitted_on_success("Alice")
self.assertEqual(list(Reporter.objects.all()), [])
@skipUnlessDBFeature('supports_transactions')
def test_manually_managed_with_using(self):
"""
The commit_manually function also works with a using argument.
"""
using_manually_managed_mistake = transaction.commit_manually(using='default')(
self.manually_managed_mistake
)
self.assertRaises(transaction.TransactionManagementError,
using_manually_managed_mistake
)
def test_manually_managed(self):
"""
You can manually manage transactions if you really want to, but you
have to remember to commit/rollback.
"""
manually_managed = transaction.commit_manually(self.manually_managed)
manually_managed()
self.assertEqual(Reporter.objects.count(), 1)
class TransactionRollbackTests(TransactionTestCase):
def execute_bad_sql(self):
cursor = connection.cursor()
cursor.execute("INSERT INTO transactions_reporter (first_name, last_name) VALUES ('Douglas', 'Adams');")
transaction.set_dirty()
def test_manually_managed_mistake(self):
"""
If you forget, you'll get bad errors.
"""
manually_managed_mistake = transaction.commit_manually(
self.manually_managed_mistake
)
self.assertRaises(transaction.TransactionManagementError,
manually_managed_mistake)
def test_manually_managed_with_using(self):
"""
The commit_manually function also works with a using argument.
"""
using_manually_managed_mistake = transaction.commit_manually(using='default')(
self.manually_managed_mistake
)
self.assertRaises(transaction.TransactionManagementError,
using_manually_managed_mistake
)
if PGSQL:
def test_bad_sql(self):
"""
Regression for #11900: If a function wrapped by commit_on_success
writes a transaction that can't be committed, that transaction should
be rolled back. The bug is only visible using the psycopg2 backend,
though the fix is generally a good idea.
"""
execute_bad_sql = transaction.commit_on_success(self.execute_bad_sql)
self.assertRaises(IntegrityError, execute_bad_sql)
transaction.rollback()
@skipUnlessDBFeature('requires_rollback_on_dirty_transaction')
def test_bad_sql(self):
"""
Regression for #11900: If a function wrapped by commit_on_success
writes a transaction that can't be committed, that transaction should
be rolled back. The bug is only visible using the psycopg2 backend,
though the fix is generally a good idea.
"""
execute_bad_sql = transaction.commit_on_success(self.execute_bad_sql)
self.assertRaises(IntegrityError, execute_bad_sql)
transaction.rollback()

View File

@ -1,4 +1,4 @@
import unittest
from django.utils import unittest
from django.core.exceptions import ValidationError

View File

@ -1,7 +1,9 @@
import unittest
import datetime
from django.conf import settings
from django.db import connection
from django.utils import unittest
from models import CustomPKModel, UniqueTogetherModel, UniqueFieldsModel, UniqueForDateModel, ModelToValidate

View File

@ -1,4 +1,5 @@
from unittest import TestCase
from django.utils.unittest import TestCase
from modeltests.validation import ValidationTestCase
from models import *

View File

@ -1,10 +1,12 @@
# -*- coding: utf-8 -*-
import re
import types
from unittest import TestCase
from datetime import datetime, timedelta
from django.core.exceptions import ValidationError
from django.core.validators import *
from django.utils.unittest import TestCase
NOW = datetime.now()

View File

@ -4,13 +4,13 @@ advertised - especially with regards to the handling of the DJANGO_SETTINGS_MODU
and default settings.py files.
"""
import os
import unittest
import shutil
import sys
import re
from django import conf, bin, get_version
from django.conf import settings
from django.utils import unittest
class AdminScriptTestCase(unittest.TestCase):
def write_settings(self, filename, apps=None, is_dir=False, sdict=None):

View File

@ -1,16 +1,15 @@
from datetime import datetime
import unittest
from django.conf import settings
from django.db import models
from django.utils.formats import localize
from django.test import TestCase
from django.contrib import admin
from django.contrib.admin.util import display_for_field, label_for_field, lookup_field
from django.contrib.admin.util import NestedObjects
from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
from django.contrib.sites.models import Site
from django.contrib.admin.util import NestedObjects
from django.db import models
from django.test import TestCase
from django.utils import unittest
from django.utils.formats import localize
from models import Article, Count

View File

@ -12,13 +12,14 @@ from django.contrib.admin.sites import LOGIN_FORM_KEY
from django.contrib.admin.util import quote
from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
from django.forms.util import ErrorList
import django.template.context
from django.test import TestCase
from django.utils import formats
from django.utils.cache import get_max_age
from django.utils.encoding import iri_to_uri
from django.utils.html import escape
from django.utils.translation import get_date_formats, activate, deactivate
import django.template.context
from django.utils import unittest
# local test models
from models import Article, BarAccount, CustomArticle, EmptyModel, \
@ -2210,51 +2211,52 @@ class UserAdminTest(TestCase):
self.assertNotEquals(new_user.password, UNUSABLE_PASSWORD)
try:
# If docutils isn't installed, skip the AdminDocs tests.
import docutils
class AdminDocsTest(TestCase):
fixtures = ['admin-views-users.xml']
def setUp(self):
self.client.login(username='super', password='secret')
def tearDown(self):
self.client.logout()
def test_tags(self):
response = self.client.get('/test_admin/admin/doc/tags/')
# The builtin tag group exists
self.assertContains(response, "<h2>Built-in tags</h2>", count=2)
# A builtin tag exists in both the index and detail
self.assertContains(response, '<h3 id="built_in-autoescape">autoescape</h3>')
self.assertContains(response, '<li><a href="#built_in-autoescape">autoescape</a></li>')
# An app tag exists in both the index and detail
self.assertContains(response, '<h3 id="flatpages-get_flatpages">get_flatpages</h3>')
self.assertContains(response, '<li><a href="#flatpages-get_flatpages">get_flatpages</a></li>')
# The admin list tag group exists
self.assertContains(response, "<h2>admin_list</h2>", count=2)
# An admin list tag exists in both the index and detail
self.assertContains(response, '<h3 id="admin_list-admin_actions">admin_actions</h3>')
self.assertContains(response, '<li><a href="#admin_list-admin_actions">admin_actions</a></li>')
def test_filters(self):
response = self.client.get('/test_admin/admin/doc/filters/')
# The builtin filter group exists
self.assertContains(response, "<h2>Built-in filters</h2>", count=2)
# A builtin filter exists in both the index and detail
self.assertContains(response, '<h3 id="built_in-add">add</h3>')
self.assertContains(response, '<li><a href="#built_in-add">add</a></li>')
except ImportError:
pass
docutils = None
#@unittest.skipUnless(docutils, "no docutils installed.")
class AdminDocsTest(TestCase):
fixtures = ['admin-views-users.xml']
def setUp(self):
self.client.login(username='super', password='secret')
def tearDown(self):
self.client.logout()
def test_tags(self):
response = self.client.get('/test_admin/admin/doc/tags/')
# The builtin tag group exists
self.assertContains(response, "<h2>Built-in tags</h2>", count=2)
# A builtin tag exists in both the index and detail
self.assertContains(response, '<h3 id="built_in-autoescape">autoescape</h3>')
self.assertContains(response, '<li><a href="#built_in-autoescape">autoescape</a></li>')
# An app tag exists in both the index and detail
self.assertContains(response, '<h3 id="flatpages-get_flatpages">get_flatpages</h3>')
self.assertContains(response, '<li><a href="#flatpages-get_flatpages">get_flatpages</a></li>')
# The admin list tag group exists
self.assertContains(response, "<h2>admin_list</h2>", count=2)
# An admin list tag exists in both the index and detail
self.assertContains(response, '<h3 id="admin_list-admin_actions">admin_actions</h3>')
self.assertContains(response, '<li><a href="#admin_list-admin_actions">admin_actions</a></li>')
def test_filters(self):
response = self.client.get('/test_admin/admin/doc/filters/')
# The builtin filter group exists
self.assertContains(response, "<h2>Built-in filters</h2>", count=2)
# A builtin filter exists in both the index and detail
self.assertContains(response, '<h3 id="built_in-add">add</h3>')
self.assertContains(response, '<li><a href="#built_in-add">add</a></li>')
AdminDocsTest = unittest.skipUnless(docutils, "no docutils installed.")(AdminDocsTest)
class ValidXHTMLTests(TestCase):
fixtures = ['admin-views-users.xml']

View File

@ -3,9 +3,10 @@
from django import forms
from django.contrib import admin
from django.contrib.admin import widgets
from unittest import TestCase
from django.test import TestCase as DjangoTestCase
from django.db.models import DateField
from django.test import TestCase as DjangoTestCase
from django.utils.unittest import TestCase
import models
class AdminFormfieldForDBFieldTests(TestCase):

View File

@ -3,32 +3,13 @@ from decimal import Decimal
from django.core.exceptions import FieldError
from django.conf import settings
from django.test import TestCase, Approximate
from django.test import TestCase, Approximate, skipUnlessDBFeature
from django.db import DEFAULT_DB_ALIAS
from django.db.models import Count, Max, Avg, Sum, StdDev, Variance, F
from regressiontests.aggregation_regress.models import *
def run_stddev_tests():
"""Check to see if StdDev/Variance tests should be run.
Stddev and Variance are not guaranteed to be available for SQLite, and
are not available for PostgreSQL before 8.2.
"""
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.sqlite3':
return False
class StdDevPop(object):
sql_function = 'STDDEV_POP'
try:
connection.ops.check_aggregate_support(StdDevPop())
except:
return False
return True
class AggregationTests(TestCase):
def assertObjectAttrs(self, obj, **kwargs):
for attr, value in kwargs.iteritems():
@ -75,27 +56,27 @@ class AggregationTests(TestCase):
qs2 = books.filter(id__in=list(qs))
self.assertEqual(list(qs1), list(qs2))
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.oracle':
def test_annotate_with_extra(self):
"""
Regression test for #11916: Extra params + aggregation creates
incorrect SQL.
"""
#oracle doesn't support subqueries in group by clause
shortest_book_sql = """
SELECT name
FROM aggregation_regress_book b
WHERE b.publisher_id = aggregation_regress_publisher.id
ORDER BY b.pages
LIMIT 1
"""
# tests that this query does not raise a DatabaseError due to the full
# subselect being (erroneously) added to the GROUP BY parameters
qs = Publisher.objects.extra(select={
'name_of_shortest_book': shortest_book_sql,
}).annotate(total_books=Count('book'))
# force execution of the query
list(qs)
@skipUnlessDBFeature('supports_subqueries_in_group_by')
def test_annotate_with_extra(self):
"""
Regression test for #11916: Extra params + aggregation creates
incorrect SQL.
"""
#oracle doesn't support subqueries in group by clause
shortest_book_sql = """
SELECT name
FROM aggregation_regress_book b
WHERE b.publisher_id = aggregation_regress_publisher.id
ORDER BY b.pages
LIMIT 1
"""
# tests that this query does not raise a DatabaseError due to the full
# subselect being (erroneously) added to the GROUP BY parameters
qs = Publisher.objects.extra(select={
'name_of_shortest_book': shortest_book_sql,
}).annotate(total_books=Count('book'))
# force execution of the query
list(qs)
def test_aggregate(self):
# Ordering requests are ignored
@ -641,64 +622,64 @@ class AggregationTests(TestCase):
lambda: Book.objects.annotate(mean_age=Avg('authors__age')).annotate(Avg('mean_age'))
)
if run_stddev_tests():
def test_stddev(self):
self.assertEqual(
Book.objects.aggregate(StdDev('pages')),
{'pages__stddev': Approximate(311.46, 1)}
)
@skipUnlessDBFeature('supports_stddev')
def test_stddev(self):
self.assertEqual(
Book.objects.aggregate(StdDev('pages')),
{'pages__stddev': Approximate(311.46, 1)}
)
self.assertEqual(
Book.objects.aggregate(StdDev('rating')),
{'rating__stddev': Approximate(0.60, 1)}
)
self.assertEqual(
Book.objects.aggregate(StdDev('rating')),
{'rating__stddev': Approximate(0.60, 1)}
)
self.assertEqual(
Book.objects.aggregate(StdDev('price')),
{'price__stddev': Approximate(24.16, 2)}
)
self.assertEqual(
Book.objects.aggregate(StdDev('price')),
{'price__stddev': Approximate(24.16, 2)}
)
self.assertEqual(
Book.objects.aggregate(StdDev('pages', sample=True)),
{'pages__stddev': Approximate(341.19, 2)}
)
self.assertEqual(
Book.objects.aggregate(StdDev('pages', sample=True)),
{'pages__stddev': Approximate(341.19, 2)}
)
self.assertEqual(
Book.objects.aggregate(StdDev('rating', sample=True)),
{'rating__stddev': Approximate(0.66, 2)}
)
self.assertEqual(
Book.objects.aggregate(StdDev('rating', sample=True)),
{'rating__stddev': Approximate(0.66, 2)}
)
self.assertEqual(
Book.objects.aggregate(StdDev('price', sample=True)),
{'price__stddev': Approximate(26.46, 1)}
)
self.assertEqual(
Book.objects.aggregate(StdDev('price', sample=True)),
{'price__stddev': Approximate(26.46, 1)}
)
self.assertEqual(
Book.objects.aggregate(Variance('pages')),
{'pages__variance': Approximate(97010.80, 1)}
)
self.assertEqual(
Book.objects.aggregate(Variance('pages')),
{'pages__variance': Approximate(97010.80, 1)}
)
self.assertEqual(
Book.objects.aggregate(Variance('rating')),
{'rating__variance': Approximate(0.36, 1)}
)
self.assertEqual(
Book.objects.aggregate(Variance('rating')),
{'rating__variance': Approximate(0.36, 1)}
)
self.assertEqual(
Book.objects.aggregate(Variance('price')),
{'price__variance': Approximate(583.77, 1)}
)
self.assertEqual(
Book.objects.aggregate(Variance('price')),
{'price__variance': Approximate(583.77, 1)}
)
self.assertEqual(
Book.objects.aggregate(Variance('pages', sample=True)),
{'pages__variance': Approximate(116412.96, 1)}
)
self.assertEqual(
Book.objects.aggregate(Variance('pages', sample=True)),
{'pages__variance': Approximate(116412.96, 1)}
)
self.assertEqual(
Book.objects.aggregate(Variance('rating', sample=True)),
{'rating__variance': Approximate(0.44, 2)}
)
self.assertEqual(
Book.objects.aggregate(Variance('rating', sample=True)),
{'rating__variance': Approximate(0.44, 2)}
)
self.assertEqual(
Book.objects.aggregate(Variance('price', sample=True)),
{'price__variance': Approximate(700.53, 2)}
)
self.assertEqual(
Book.objects.aggregate(Variance('price', sample=True)),
{'price__variance': Approximate(700.53, 2)}
)

View File

@ -2,10 +2,10 @@ import copy
import os
import sys
import time
from unittest import TestCase
from django.conf import Settings
from django.db.models.loading import cache, load_app
from django.utils.unittest import TestCase
__test__ = {"API_TESTS": """
Test the globbing of INSTALLED_APPS.

View File

@ -28,7 +28,7 @@ class SchoolClass(models.Model):
# Unfortunately, the following model breaks MySQL hard.
# Until #13711 is fixed, this test can't be run under MySQL.
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.mysql':
if connection.features.supports_long_model_names:
class VeryLongModelNameZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ(models.Model):
class Meta:
# We need to use a short actual table name or

View File

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
# Unit and doctests for specific database backends.
import datetime
import unittest
from django.conf import settings
from django.core import management
@ -9,48 +8,46 @@ from django.core.management.color import no_style
from django.db import backend, connection, connections, DEFAULT_DB_ALIAS
from django.db.backends.signals import connection_created
from django.db.backends.postgresql import version as pg_version
from django.test import TestCase
from django.test import TestCase, skipUnlessDBFeature
from django.utils import unittest
from regressiontests.backends import models
class Callproc(unittest.TestCase):
class OracleChecks(unittest.TestCase):
@unittest.skipUnless(connection.vendor == 'oracle',
"No need to check Oracle cursor semantics")
def test_dbms_session(self):
# If the backend is Oracle, test that we can call a standard
# stored procedure through our cursor wrapper.
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle':
convert_unicode = backend.convert_unicode
cursor = connection.cursor()
cursor.callproc(convert_unicode('DBMS_SESSION.SET_IDENTIFIER'),
[convert_unicode('_django_testing!'),])
return True
else:
return True
convert_unicode = backend.convert_unicode
cursor = connection.cursor()
cursor.callproc(convert_unicode('DBMS_SESSION.SET_IDENTIFIER'),
[convert_unicode('_django_testing!'),])
@unittest.skipUnless(connection.vendor == 'oracle',
"No need to check Oracle cursor semantics")
def test_cursor_var(self):
# If the backend is Oracle, test that we can pass cursor variables
# as query parameters.
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle':
cursor = connection.cursor()
var = cursor.var(backend.Database.STRING)
cursor.execute("BEGIN %s := 'X'; END; ", [var])
self.assertEqual(var.getvalue(), 'X')
class LongString(unittest.TestCase):
cursor = connection.cursor()
var = cursor.var(backend.Database.STRING)
cursor.execute("BEGIN %s := 'X'; END; ", [var])
self.assertEqual(var.getvalue(), 'X')
@unittest.skipUnless(connection.vendor == 'oracle',
"No need to check Oracle cursor semantics")
def test_long_string(self):
# If the backend is Oracle, test that we can save a text longer
# than 4000 chars and read it properly
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle':
c = connection.cursor()
c.execute('CREATE TABLE ltext ("TEXT" NCLOB)')
long_str = ''.join([unicode(x) for x in xrange(4000)])
c.execute('INSERT INTO ltext VALUES (%s)',[long_str])
c.execute('SELECT text FROM ltext')
row = c.fetchone()
self.assertEquals(long_str, row[0].read())
c.execute('DROP TABLE ltext')
c = connection.cursor()
c.execute('CREATE TABLE ltext ("TEXT" NCLOB)')
long_str = ''.join([unicode(x) for x in xrange(4000)])
c.execute('INSERT INTO ltext VALUES (%s)',[long_str])
c.execute('SELECT text FROM ltext')
row = c.fetchone()
self.assertEqual(long_str, row[0].read())
c.execute('DROP TABLE ltext')
class DateQuotingTest(TestCase):
@ -97,46 +94,48 @@ class ParameterHandlingTest(TestCase):
# Unfortunately, the following tests would be a good test to run on all
# backends, but it breaks MySQL hard. Until #13711 is fixed, it can't be run
# everywhere (although it would be an effective test of #13711).
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.mysql':
class LongNameTest(TestCase):
"""Long primary keys and model names can result in a sequence name
that exceeds the database limits, which will result in truncation
on certain databases (e.g., Postgres). The backend needs to use
the correct sequence name in last_insert_id and other places, so
check it is. Refs #8901.
"""
class LongNameTest(TestCase):
"""Long primary keys and model names can result in a sequence name
that exceeds the database limits, which will result in truncation
on certain databases (e.g., Postgres). The backend needs to use
the correct sequence name in last_insert_id and other places, so
check it is. Refs #8901.
"""
def test_sequence_name_length_limits_create(self):
"""Test creation of model with long name and long pk name doesn't error. Ref #8901"""
models.VeryLongModelNameZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ.objects.create()
@skipUnlessDBFeature('supports_long_model_names')
def test_sequence_name_length_limits_create(self):
"""Test creation of model with long name and long pk name doesn't error. Ref #8901"""
models.VeryLongModelNameZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ.objects.create()
def test_sequence_name_length_limits_m2m(self):
"""Test an m2m save of a model with a long name and a long m2m field name doesn't error as on Django >=1.2 this now uses object saves. Ref #8901"""
obj = models.VeryLongModelNameZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ.objects.create()
rel_obj = models.Person.objects.create(first_name='Django', last_name='Reinhardt')
obj.m2m_also_quite_long_zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz.add(rel_obj)
@skipUnlessDBFeature('supports_long_model_names')
def test_sequence_name_length_limits_m2m(self):
"""Test an m2m save of a model with a long name and a long m2m field name doesn't error as on Django >=1.2 this now uses object saves. Ref #8901"""
obj = models.VeryLongModelNameZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ.objects.create()
rel_obj = models.Person.objects.create(first_name='Django', last_name='Reinhardt')
obj.m2m_also_quite_long_zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz.add(rel_obj)
def test_sequence_name_length_limits_flush(self):
"""Test that sequence resetting as part of a flush with model with long name and long pk name doesn't error. Ref #8901"""
# A full flush is expensive to the full test, so we dig into the
# internals to generate the likely offending SQL and run it manually
@skipUnlessDBFeature('supports_long_model_names')
def test_sequence_name_length_limits_flush(self):
"""Test that sequence resetting as part of a flush with model with long name and long pk name doesn't error. Ref #8901"""
# A full flush is expensive to the full test, so we dig into the
# internals to generate the likely offending SQL and run it manually
# Some convenience aliases
VLM = models.VeryLongModelNameZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
VLM_m2m = VLM.m2m_also_quite_long_zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz.through
tables = [
VLM._meta.db_table,
VLM_m2m._meta.db_table,
]
sequences = [
{
'column': VLM._meta.pk.column,
'table': VLM._meta.db_table
},
]
cursor = connection.cursor()
for statement in connection.ops.sql_flush(no_style(), tables, sequences):
cursor.execute(statement)
# Some convenience aliases
VLM = models.VeryLongModelNameZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
VLM_m2m = VLM.m2m_also_quite_long_zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz.through
tables = [
VLM._meta.db_table,
VLM_m2m._meta.db_table,
]
sequences = [
{
'column': VLM._meta.pk.column,
'table': VLM._meta.db_table
},
]
cursor = connection.cursor()
for statement in connection.ops.sql_flush(no_style(), tables, sequences):
cursor.execute(statement)
class SequenceResetTest(TestCase):
def test_generic_relation(self):
@ -170,22 +169,22 @@ class PostgresVersionTest(TestCase):
# Unfortunately with sqlite3 the in-memory test database cannot be
# closed, and so it cannot be re-opened during testing, and so we
# sadly disable this test for now.
if settings.DATABASES[DEFAULT_DB_ALIAS]["ENGINE"] != "django.db.backends.sqlite3":
class ConnectionCreatedSignalTest(TestCase):
def test_signal(self):
data = {}
def receiver(sender, connection, **kwargs):
data["connection"] = connection
class ConnectionCreatedSignalTest(TestCase):
@skipUnlessDBFeature('test_db_allows_multiple_connections')
def test_signal(self):
data = {}
def receiver(sender, connection, **kwargs):
data["connection"] = connection
connection_created.connect(receiver)
connection.close()
cursor = connection.cursor()
self.assertTrue(data["connection"] is connection)
connection_created.connect(receiver)
connection.close()
cursor = connection.cursor()
self.assertTrue(data["connection"] is connection)
connection_created.disconnect(receiver)
data.clear()
cursor = connection.cursor()
self.assertTrue(data == {})
connection_created.disconnect(receiver)
data.clear()
cursor = connection.cursor()
self.assertTrue(data == {})
class BackendTestCase(TestCase):
@ -225,3 +224,4 @@ class BackendTestCase(TestCase):
self.assertEqual(cursor.fetchone(), (u'Clark', u'Kent'))
self.assertEqual(list(cursor.fetchmany(2)), [(u'Jane', u'Doe'), (u'John', u'Doe')])
self.assertEqual(list(cursor.fetchall()), [(u'Mary', u'Agnelline'), (u'Peter', u'Parker')])

View File

@ -2,12 +2,12 @@
A series of tests to establish that the command-line bash completion works.
"""
import os
import unittest
import sys
import StringIO
from django.conf import settings
from django.core.management import ManagementUtility
from django.utils import unittest
class BashCompletionTests(unittest.TestCase):
"""

View File

@ -6,9 +6,10 @@ ModelForm's save() method causes Model.save() to be called more than once.
import os
import shutil
import unittest
from django.core.files.uploadedfile import SimpleUploadedFile
from django.utils import unittest
from regressiontests.bug639.models import Photo, PhotoForm, temp_storage_dir
class Bug639Test(unittest.TestCase):

View File

@ -1,6 +1,5 @@
from unittest import TestCase
from django.contrib import admin
from django.utils.unittest import TestCase
class Bug8245Test(TestCase):

View File

@ -1,6 +1,7 @@
from unittest import TestCase
from StringIO import StringIO
from django.core.servers.basehttp import ServerHandler
from django.utils.unittest import TestCase
#
# Tests for #9659: wsgi.file_wrapper in the builtin server.

View File

@ -7,7 +7,6 @@ import os
import shutil
import tempfile
import time
import unittest
import warnings
from django.conf import settings
@ -17,6 +16,7 @@ from django.core.cache.backends.base import InvalidCacheBackendError, CacheKeyWa
from django.http import HttpResponse, HttpRequest
from django.middleware.cache import FetchFromCacheMiddleware, UpdateCacheMiddleware
from django.utils import translation
from django.utils import unittest
from django.utils.cache import patch_vary_headers, get_cache_key, learn_cache_key
from django.utils.hashcompat import md5_constructor
from regressiontests.cache.models import Poll, expensive_calculation
@ -393,6 +393,7 @@ class BaseCacheTests(object):
# runner doesn't add any global warning filters (it currently
# does not).
warnings.resetwarnings()
warnings.simplefilter("ignore", PendingDeprecationWarning)
class DBCacheTests(unittest.TestCase, BaseCacheTests):
def setUp(self):

View File

@ -1,10 +1,11 @@
import datetime
from django.conf import settings
from django.db import DEFAULT_DB_ALIAS
from django.test import TestCase
from django.test import TestCase, skipIfDBFeature
from django.utils import tzinfo
from models import Donut, RumBaba
from django.conf import settings
class DataTypesTestCase(TestCase):
@ -73,14 +74,14 @@ class DataTypesTestCase(TestCase):
newd = Donut.objects.get(id=d.id)
self.assert_(isinstance(newd.review, unicode))
def test_tz_awareness_mysql(self):
@skipIfDBFeature('supports_timezones')
def test_error_on_timezone(self):
"""Regression test for #8354: the MySQL backend should raise an error
if given a timezone-aware datetime object."""
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.mysql':
dt = datetime.datetime(2008, 8, 31, 16, 20, tzinfo=tzinfo.FixedOffset(0))
d = Donut(name='Bear claw', consumed_at=dt)
self.assertRaises(ValueError, d.save)
# ValueError: MySQL backend does not support timezone-aware datetimes.
dt = datetime.datetime(2008, 8, 31, 16, 20, tzinfo=tzinfo.FixedOffset(0))
d = Donut(name='Bear claw', consumed_at=dt)
self.assertRaises(ValueError, d.save)
# ValueError: MySQL backend does not support timezone-aware datetimes.
def test_datefield_auto_now_add(self):
"""Regression test for #10970, auto_now_add for DateField should store

View File

@ -1,18 +1,19 @@
from unittest import TestCase
from sys import version_info
try:
from functools import wraps
except ImportError:
from django.utils.functional import wraps # Python 2.4 fallback.
from django.contrib.auth.decorators import login_required, permission_required, user_passes_test
from django.contrib.admin.views.decorators import staff_member_required
from django.http import HttpResponse, HttpRequest
from django.utils.decorators import method_decorator
from django.utils.functional import allow_lazy, lazy, memoize
from django.utils.unittest import TestCase
from django.views.decorators.http import require_http_methods, require_GET, require_POST
from django.views.decorators.vary import vary_on_headers, vary_on_cookie
from django.views.decorators.cache import cache_page, never_cache, cache_control
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required, permission_required, user_passes_test
from django.contrib.admin.views.decorators import staff_member_required
def fully_decorated(request):
"""Expected __doc__"""
@ -70,25 +71,25 @@ class DecoratorsTest(TestCase):
def test1(user):
user.decorators_applied.append('test1')
return True
def test2(user):
user.decorators_applied.append('test2')
return True
def callback(request):
return request.user.decorators_applied
callback = user_passes_test(test1)(callback)
callback = user_passes_test(test2)(callback)
class DummyUser(object): pass
class DummyRequest(object): pass
request = DummyRequest()
request.user = DummyUser()
request.user.decorators_applied = []
response = callback(request)
self.assertEqual(response, ['test2', 'test1'])
def test_cache_page_new_style(self):

View File

@ -2,64 +2,65 @@ import datetime
from django.conf import settings
from django.db import backend, connection, transaction, DEFAULT_DB_ALIAS
from django.test import TestCase, TransactionTestCase
from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature
from models import Book, Award, AwardNote, Person, Child, Toy, PlayedWith, PlayedWithNote
# Can't run this test under SQLite, because you can't
# get two connections to an in-memory database.
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.sqlite3':
class DeleteLockingTest(TransactionTestCase):
def setUp(self):
# Create a second connection to the default database
conn_settings = settings.DATABASES[DEFAULT_DB_ALIAS]
self.conn2 = backend.DatabaseWrapper({
'HOST': conn_settings['HOST'],
'NAME': conn_settings['NAME'],
'OPTIONS': conn_settings['OPTIONS'],
'PASSWORD': conn_settings['PASSWORD'],
'PORT': conn_settings['PORT'],
'USER': conn_settings['USER'],
'TIME_ZONE': settings.TIME_ZONE,
})
class DeleteLockingTest(TransactionTestCase):
def setUp(self):
# Create a second connection to the default database
conn_settings = settings.DATABASES[DEFAULT_DB_ALIAS]
self.conn2 = backend.DatabaseWrapper({
'HOST': conn_settings['HOST'],
'NAME': conn_settings['NAME'],
'OPTIONS': conn_settings['OPTIONS'],
'PASSWORD': conn_settings['PASSWORD'],
'PORT': conn_settings['PORT'],
'USER': conn_settings['USER'],
'TIME_ZONE': settings.TIME_ZONE,
})
# Put both DB connections into managed transaction mode
transaction.enter_transaction_management()
transaction.managed(True)
self.conn2._enter_transaction_management(True)
# Put both DB connections into managed transaction mode
transaction.enter_transaction_management()
transaction.managed(True)
self.conn2._enter_transaction_management(True)
def tearDown(self):
# Close down the second connection.
transaction.leave_transaction_management()
self.conn2.close()
def tearDown(self):
# Close down the second connection.
transaction.leave_transaction_management()
self.conn2.close()
def test_concurrent_delete(self):
"Deletes on concurrent transactions don't collide and lock the database. Regression for #9479"
@skipUnlessDBFeature('test_db_allows_multiple_connections')
def test_concurrent_delete(self):
"Deletes on concurrent transactions don't collide and lock the database. Regression for #9479"
# Create some dummy data
b1 = Book(id=1, pagecount=100)
b2 = Book(id=2, pagecount=200)
b3 = Book(id=3, pagecount=300)
b1.save()
b2.save()
b3.save()
# Create some dummy data
b1 = Book(id=1, pagecount=100)
b2 = Book(id=2, pagecount=200)
b3 = Book(id=3, pagecount=300)
b1.save()
b2.save()
b3.save()
transaction.commit()
transaction.commit()
self.assertEquals(3, Book.objects.count())
self.assertEqual(3, Book.objects.count())
# Delete something using connection 2.
cursor2 = self.conn2.cursor()
cursor2.execute('DELETE from delete_regress_book WHERE id=1')
self.conn2._commit();
# Delete something using connection 2.
cursor2 = self.conn2.cursor()
cursor2.execute('DELETE from delete_regress_book WHERE id=1')
self.conn2._commit();
# Now perform a queryset delete that covers the object
# deleted in connection 2. This causes an infinite loop
# under MySQL InnoDB unless we keep track of already
# deleted objects.
Book.objects.filter(pagecount__lt=250).delete()
transaction.commit()
self.assertEquals(1, Book.objects.count())
# Now perform a queryset delete that covers the object
# deleted in connection 2. This causes an infinite loop
# under MySQL InnoDB unless we keep track of already
# deleted objects.
Book.objects.filter(pagecount__lt=250).delete()
transaction.commit()
self.assertEqual(1, Book.objects.count())
class DeleteCascadeTests(TestCase):
def test_generic_relation_cascade(self):

View File

@ -1,7 +1,8 @@
from django.dispatch import Signal
import unittest
import sys
import gc
import sys
from django.dispatch import Signal
from django.utils import unittest
import django.utils.copycompat as copy
if sys.platform.startswith('java'):
@ -20,7 +21,7 @@ def receiver_1_arg(val, **kwargs):
class Callable(object):
def __call__(self, val, **kwargs):
return val
def a(self, val, **kwargs):
return val
@ -35,7 +36,7 @@ class DispatcherTests(unittest.TestCase):
# force cleanup just in case
signal.receivers = []
def testExact(self):
a_signal.connect(receiver_1_arg, sender=self)
expected = [(receiver_1_arg,"test")]
@ -51,7 +52,7 @@ class DispatcherTests(unittest.TestCase):
self.assertEqual(result, expected)
a_signal.disconnect(receiver_1_arg)
self._testIsClean(a_signal)
def testGarbageCollected(self):
a = Callable()
a_signal.connect(a.a, sender=self)
@ -61,7 +62,7 @@ class DispatcherTests(unittest.TestCase):
result = a_signal.send(sender=self, val="test")
self.assertEqual(result, expected)
self._testIsClean(a_signal)
def testMultipleRegistration(self):
a = Callable()
a_signal.connect(a)
@ -90,7 +91,7 @@ class DispatcherTests(unittest.TestCase):
self.assertEqual(len(a_signal.receivers), 1)
a_signal.disconnect(dispatch_uid = "uid")
self._testIsClean(a_signal)
def testRobust(self):
"""Test the sendRobust function"""
def fails(val, **kwargs):

View File

@ -1,6 +1,6 @@
from django.dispatch.saferef import *
import unittest
from django.utils import unittest
class Test1(object):
def x(self):

View File

@ -1,14 +1,14 @@
"""
Spanning tests for all the operations that F() expressions can perform.
"""
from django.test import TestCase, Approximate
from django.conf import settings
from django.db import models, DEFAULT_DB_ALIAS
from django.db.models import F
from django.test import TestCase, Approximate, skipUnlessDBFeature
from regressiontests.expressions_regress.models import Number
class ExpressionsRegressTests(TestCase):
def setUp(self):
@ -130,13 +130,13 @@ class ExpressionOperatorTests(TestCase):
self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 40)
self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.oracle':
def test_lefthand_bitwise_or(self):
# LH Bitwise or on integers
Number.objects.filter(pk=self.n.pk).update(integer=F('integer') | 48)
@skipUnlessDBFeature('supports_bitwise_or')
def test_lefthand_bitwise_or(self):
# LH Bitwise or on integers
Number.objects.filter(pk=self.n.pk).update(integer=F('integer') | 48)
self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 58)
self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 58)
self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
def test_right_hand_addition(self):
# Right hand operators
@ -185,11 +185,11 @@ class ExpressionOperatorTests(TestCase):
self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 10)
self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.oracle':
def test_right_hand_bitwise_or(self):
# RH Bitwise or on integers
Number.objects.filter(pk=self.n.pk).update(integer=15 | F('integer'))
@skipUnlessDBFeature('supports_bitwise_or')
def test_right_hand_bitwise_or(self):
# RH Bitwise or on integers
Number.objects.filter(pk=self.n.pk).update(integer=15 | F('integer'))
self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 47)
self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 47)
self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))

View File

@ -4,7 +4,6 @@ import shutil
import sys
import tempfile
import time
import unittest
from cStringIO import StringIO
from datetime import datetime, timedelta
from django.conf import settings
@ -14,7 +13,8 @@ from django.core.files.images import get_image_dimensions
from django.core.files.storage import FileSystemStorage, get_storage_class
from django.core.files.uploadedfile import UploadedFile
from django.core.exceptions import ImproperlyConfigured
from unittest import TestCase
from django.utils import unittest
try:
import threading
except ImportError:
@ -294,7 +294,7 @@ class SlowFile(ContentFile):
time.sleep(1)
return super(ContentFile, self).chunks()
class FileSaveRaceConditionTest(TestCase):
class FileSaveRaceConditionTest(unittest.TestCase):
def setUp(self):
self.storage_dir = tempfile.mkdtemp()
self.storage = FileSystemStorage(self.storage_dir)
@ -315,7 +315,7 @@ class FileSaveRaceConditionTest(TestCase):
self.storage.delete('conflict')
self.storage.delete('conflict_1')
class FileStoragePermissions(TestCase):
class FileStoragePermissions(unittest.TestCase):
def setUp(self):
self.old_perms = settings.FILE_UPLOAD_PERMISSIONS
settings.FILE_UPLOAD_PERMISSIONS = 0666
@ -332,7 +332,7 @@ class FileStoragePermissions(TestCase):
self.assertEqual(actual_mode, 0666)
class FileStoragePathParsing(TestCase):
class FileStoragePathParsing(unittest.TestCase):
def setUp(self):
self.storage_dir = tempfile.mkdtemp()
self.storage = FileSystemStorage(self.storage_dir)
@ -370,64 +370,67 @@ class FileStoragePathParsing(TestCase):
else:
self.assert_(os.path.exists(os.path.join(self.storage_dir, 'dotted.path/.test_1')))
if Image is not None:
class DimensionClosingBug(TestCase):
class DimensionClosingBug(unittest.TestCase):
"""
Test that get_image_dimensions() properly closes files (#8817)
"""
@unittest.skipUnless(Image, "PIL not installed")
def test_not_closing_of_files(self):
"""
Test that get_image_dimensions() properly closes files (#8817)
Open files passed into get_image_dimensions() should stay opened.
"""
def test_not_closing_of_files(self):
"""
Open files passed into get_image_dimensions() should stay opened.
"""
empty_io = StringIO()
try:
get_image_dimensions(empty_io)
finally:
self.assert_(not empty_io.closed)
empty_io = StringIO()
try:
get_image_dimensions(empty_io)
finally:
self.assert_(not empty_io.closed)
def test_closing_of_filenames(self):
"""
get_image_dimensions() called with a filename should closed the file.
"""
# We need to inject a modified open() builtin into the images module
# that checks if the file was closed properly if the function is
# called with a filename instead of an file object.
# get_image_dimensions will call our catching_open instead of the
# regular builtin one.
class FileWrapper(object):
_closed = []
def __init__(self, f):
self.f = f
def __getattr__(self, name):
return getattr(self.f, name)
def close(self):
self._closed.append(True)
self.f.close()
def catching_open(*args):
return FileWrapper(open(*args))
from django.core.files import images
images.open = catching_open
try:
get_image_dimensions(os.path.join(os.path.dirname(__file__), "test1.png"))
finally:
del images.open
self.assert_(FileWrapper._closed)
class InconsistentGetImageDimensionsBug(TestCase):
@unittest.skipUnless(Image, "PIL not installed")
def test_closing_of_filenames(self):
"""
Test that get_image_dimensions() works properly after various calls using a file handler (#11158)
get_image_dimensions() called with a filename should closed the file.
"""
def test_multiple_calls(self):
"""
Multiple calls of get_image_dimensions() should return the same size.
"""
from django.core.files.images import ImageFile
img_path = os.path.join(os.path.dirname(__file__), "test.png")
image = ImageFile(open(img_path, 'rb'))
image_pil = Image.open(img_path)
size_1, size_2 = get_image_dimensions(image), get_image_dimensions(image)
self.assertEqual(image_pil.size, size_1)
self.assertEqual(size_1, size_2)
# We need to inject a modified open() builtin into the images module
# that checks if the file was closed properly if the function is
# called with a filename instead of an file object.
# get_image_dimensions will call our catching_open instead of the
# regular builtin one.
class FileWrapper(object):
_closed = []
def __init__(self, f):
self.f = f
def __getattr__(self, name):
return getattr(self.f, name)
def close(self):
self._closed.append(True)
self.f.close()
def catching_open(*args):
return FileWrapper(open(*args))
from django.core.files import images
images.open = catching_open
try:
get_image_dimensions(os.path.join(os.path.dirname(__file__), "test1.png"))
finally:
del images.open
self.assert_(FileWrapper._closed)
class InconsistentGetImageDimensionsBug(unittest.TestCase):
"""
Test that get_image_dimensions() works properly after various calls
using a file handler (#11158)
"""
@unittest.skipUnless(Image, "PIL not installed")
def test_multiple_calls(self):
"""
Multiple calls of get_image_dimensions() should return the same size.
"""
from django.core.files.images import ImageFile
img_path = os.path.join(os.path.dirname(__file__), "test.png")
image = ImageFile(open(img_path, 'rb'))
image_pil = Image.open(img_path)
size_1, size_2 = get_image_dimensions(image), get_image_dimensions(image)
self.assertEqual(image_pil.size, size_1)
self.assertEqual(size_1, size_2)

View File

@ -2,15 +2,15 @@
import os
import errno
import shutil
import unittest
from StringIO import StringIO
from django.core.files import temp as tempfile
from django.core.files.uploadedfile import SimpleUploadedFile
from django.http.multipartparser import MultiPartParser
from django.test import TestCase, client
from django.utils import simplejson
from django.utils import unittest
from django.utils.hashcompat import sha_constructor
from django.http.multipartparser import MultiPartParser
from models import FileModel, temp_storage, UPLOAD_TO
import uploadhandler
@ -223,7 +223,7 @@ class FileUploadTests(TestCase):
ret = super(POSTAccessingHandler, self).handle_uncaught_exception(request, resolver, exc_info)
p = request.POST
return ret
post_data = {
'name': 'Ringo',
'file_field': open(__file__),
@ -244,7 +244,7 @@ class FileUploadTests(TestCase):
response = self.client.post('/file_uploads/upload_errors/', post_data)
except reference_error.__class__, err:
self.failIf(
str(err) == str(reference_error),
str(err) == str(reference_error),
"Caught a repeated exception that'll cause an infinite loop in file uploads."
)
except Exception, err:

View File

@ -1,4 +1,4 @@
from django.db import models, DEFAULT_DB_ALIAS
from django.db import models, DEFAULT_DB_ALIAS, connection
from django.contrib.auth.models import User
from django.conf import settings
@ -31,7 +31,7 @@ class Stuff(models.Model):
# Oracle doesn't distinguish between None and the empty string.
# This hack makes the test case pass using Oracle.
name = self.name
if (settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle'
if (connection.features.interprets_empty_strings_as_nulls
and name == u''):
name = None
return unicode(name) + u' is owned by ' + unicode(self.owner)

View File

@ -30,11 +30,10 @@ import re
import os
from decimal import Decimal
from unittest import TestCase
from django.core.files.uploadedfile import SimpleUploadedFile
from django.forms import *
from django.forms.widgets import RadioFieldRenderer
from django.utils.unittest import TestCase
def fix_os_paths(x):

View File

@ -1,9 +1,9 @@
from datetime import time, date, datetime
from unittest import TestCase
from django import forms
from django.conf import settings
from django.utils.translation import activate, deactivate
from django.utils.unittest import TestCase
class LocalizedTimeTests(TestCase):

View File

@ -1,8 +1,7 @@
from unittest import TestCase
from django import forms
from django.core import validators
from django.core.exceptions import ValidationError
from django.utils.unittest import TestCase
class TestFieldWithValidators(TestCase):

View File

@ -1265,10 +1265,9 @@ u'<input type="hidden" name="date_0" value="17.09.2007" /><input type="hidden" n
"""
from django.utils import copycompat as copy
from unittest import TestCase
from django import forms
from django.utils import copycompat as copy
from django.utils.unittest import TestCase
from django.core.files.uploadedfile import SimpleUploadedFile

View File

@ -1,7 +1,8 @@
import copy
import pickle
import unittest
from django.http import QueryDict, HttpResponse, CompatCookie, BadHeaderError
from django.utils import unittest
class QueryDictTests(unittest.TestCase):
def test_missing_key(self):
@ -17,7 +18,7 @@ class QueryDictTests(unittest.TestCase):
self.assertRaises(AttributeError, q.pop, 'foo')
self.assertRaises(AttributeError, q.popitem)
self.assertRaises(AttributeError, q.clear)
def test_immutable_get_with_default(self):
q = QueryDict('')
self.assertEqual(q.get('foo', 'default'), 'default')
@ -34,7 +35,7 @@ class QueryDictTests(unittest.TestCase):
self.assertEqual(q.values(), [])
self.assertEqual(len(q), 0)
self.assertEqual(q.urlencode(), '')
def test_single_key_value(self):
"""Test QueryDict with one key/value pair"""
@ -47,7 +48,7 @@ class QueryDictTests(unittest.TestCase):
self.assertEqual(q.get('bar', 'default'), 'default')
self.assertEqual(q.getlist('foo'), ['bar'])
self.assertEqual(q.getlist('bar'), [])
self.assertRaises(AttributeError, q.setlist, 'foo', ['bar'])
self.assertRaises(AttributeError, q.appendlist, 'foo', ['bar'])
@ -67,16 +68,16 @@ class QueryDictTests(unittest.TestCase):
self.assertRaises(AttributeError, q.popitem)
self.assertRaises(AttributeError, q.clear)
self.assertRaises(AttributeError, q.setdefault, 'foo', 'bar')
self.assertEqual(q.urlencode(), 'foo=bar')
def test_mutable_copy(self):
"""A copy of a QueryDict is mutable."""
q = QueryDict('').copy()
self.assertRaises(KeyError, q.__getitem__, "foo")
q['name'] = 'john'
self.assertEqual(q['name'], 'john')
def test_mutable_delete(self):
q = QueryDict('').copy()
q['name'] = 'john'
@ -126,20 +127,20 @@ class QueryDictTests(unittest.TestCase):
"""Test QueryDict with two key/value pairs with same keys."""
q = QueryDict('vote=yes&vote=no')
self.assertEqual(q['vote'], u'no')
self.assertRaises(AttributeError, q.__setitem__, 'something', 'bar')
self.assertEqual(q.get('vote', 'default'), u'no')
self.assertEqual(q.get('foo', 'default'), 'default')
self.assertEqual(q.getlist('vote'), [u'yes', u'no'])
self.assertEqual(q.getlist('foo'), [])
self.assertRaises(AttributeError, q.setlist, 'foo', ['bar', 'baz'])
self.assertRaises(AttributeError, q.setlist, 'foo', ['bar', 'baz'])
self.assertRaises(AttributeError, q.appendlist, 'foo', ['bar'])
self.assertEqual(q.has_key('vote'), True)
self.assertEqual(q.has_key('vote'), True)
self.assertEqual('vote' in q, True)
self.assertEqual(q.has_key('foo'), False)
self.assertEqual('foo' in q, False)
@ -148,23 +149,23 @@ class QueryDictTests(unittest.TestCase):
self.assertEqual(q.keys(), [u'vote'])
self.assertEqual(q.values(), [u'no'])
self.assertEqual(len(q), 1)
self.assertRaises(AttributeError, q.update, {'foo': 'bar'})
self.assertRaises(AttributeError, q.pop, 'foo')
self.assertRaises(AttributeError, q.popitem)
self.assertRaises(AttributeError, q.clear)
self.assertRaises(AttributeError, q.setdefault, 'foo', 'bar')
self.assertRaises(AttributeError, q.__delitem__, 'vote')
def test_invalid_input_encoding(self):
"""
QueryDicts must be able to handle invalid input encoding (in this
case, bad UTF-8 encoding).
"""
q = QueryDict('foo=bar&foo=\xff')
self.assertEqual(q['foo'], u'\ufffd')
self.assertEqual(q['foo'], u'\ufffd')
self.assertEqual(q.getlist('foo'), [u'bar', u'\ufffd'])
def test_pickle(self):
q = QueryDict('')
q1 = pickle.loads(pickle.dumps(q, 2))
@ -172,7 +173,7 @@ class QueryDictTests(unittest.TestCase):
q = QueryDict('a=b&c=d')
q1 = pickle.loads(pickle.dumps(q, 2))
self.assertEqual(q == q1, True)
q = QueryDict('a=b&c=d&a=1')
q = QueryDict('a=b&c=d&a=1')
q1 = pickle.loads(pickle.dumps(q, 2))
self.assertEqual(q == q1 , True)
@ -181,21 +182,21 @@ class QueryDictTests(unittest.TestCase):
x = QueryDict("a=1&a=2", mutable=True)
y = QueryDict("a=3&a=4")
x.update(y)
self.assertEqual(x.getlist('a'), [u'1', u'2', u'3', u'4'])
self.assertEqual(x.getlist('a'), [u'1', u'2', u'3', u'4'])
def test_non_default_encoding(self):
"""#13572 - QueryDict with a non-default encoding"""
q = QueryDict('sbb=one', encoding='rot_13')
q = QueryDict('sbb=one', encoding='rot_13')
self.assertEqual(q.encoding , 'rot_13' )
self.assertEqual(q.items() , [(u'foo', u'bar')] )
self.assertEqual(q.urlencode() , 'sbb=one' )
q = q.copy()
q = q.copy()
self.assertEqual(q.encoding , 'rot_13' )
self.assertEqual(q.items() , [(u'foo', u'bar')] )
self.assertEqual(q.urlencode() , 'sbb=one' )
self.assertEqual(copy.copy(q).encoding , 'rot_13' )
self.assertEqual(copy.deepcopy(q).encoding , 'rot_13')
class HttpResponseTests(unittest.TestCase):
def test_unicode_headers(self):
r = HttpResponse()
@ -203,10 +204,10 @@ class HttpResponseTests(unittest.TestCase):
# If we insert a unicode value it will be converted to an ascii
r['value'] = u'test value'
self.failUnless(isinstance(r['value'], str))
# An error is raised ~hen a unicode object with non-ascii is assigned.
self.assertRaises(UnicodeEncodeError, r.__setitem__, 'value', u't\xebst value')
# An error is raised when a unicode object with non-ASCII format is
# passed as initial mimetype or content_type.
self.assertRaises(UnicodeEncodeError, HttpResponse,
@ -216,12 +217,12 @@ class HttpResponseTests(unittest.TestCase):
self.assertRaises(UnicodeEncodeError, HttpResponse,
content_type=u't\xebst value')
# The response also converts unicode keys to strings.)
# The response also converts unicode keys to strings.)
r[u'test'] = 'testing key'
l = list(r.items())
l.sort()
self.assertEqual(l[1], ('test', 'testing key'))
# It will also raise errors for keys with non-ascii data.
self.assertRaises(UnicodeEncodeError, r.__setitem__, u't\xebst key', 'value')

View File

@ -1,6 +1,7 @@
import unittest
from datetime import timedelta, date
from django.template import Template, Context, add_to_builtins
from django.utils import unittest
from django.utils.dateformat import DateFormat
from django.utils.translation import ugettext as _
from django.utils.html import escape

View File

@ -1,6 +1,6 @@
from django.conf import settings
from django.db import connection, DEFAULT_DB_ALIAS
from django.test import TestCase
from django.test import TestCase, skipUnlessDBFeature
from django.utils import functional
from models import Reporter, Article
@ -77,13 +77,13 @@ class IntrospectionTests(TestCase):
)
# Regression test for #9991 - 'real' types in postgres
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'].startswith('django.db.backends.postgresql'):
def test_postgresql_real_type(self):
cursor = connection.cursor()
cursor.execute("CREATE TABLE django_ixn_real_test_table (number REAL);")
desc = connection.introspection.get_table_description(cursor, 'django_ixn_real_test_table')
cursor.execute('DROP TABLE django_ixn_real_test_table;')
self.assertEqual(datatype(desc[0][1], desc[0]), 'FloatField')
@skipUnlessDBFeature('has_real_datatype')
def test_postgresql_real_type(self):
cursor = connection.cursor()
cursor.execute("CREATE TABLE django_ixn_real_test_table (number REAL);")
desc = connection.introspection.get_table_description(cursor, 'django_ixn_real_test_table')
cursor.execute('DROP TABLE django_ixn_real_test_table;')
self.assertEqual(datatype(desc[0][1], desc[0]), 'FloatField')
def test_get_relations(self):
cursor = connection.cursor()

View File

@ -1,5 +1,5 @@
import unittest
from django.test import TestCase
from django.utils import unittest
# just import your tests here
from us.tests import *

View File

@ -1,12 +1,12 @@
from unittest import TestCase
from django.db import DatabaseError
from django.utils import unittest
from regressiontests.max_lengths.models import PersonWithDefaultMaxLengths, PersonWithCustomMaxLengths
class MaxLengthArgumentsTests(TestCase):
class MaxLengthArgumentsTests(unittest.TestCase):
def verify_max_length(self, model,field,length):
self.assertEquals(model._meta.get_field(field).max_length,length)
def test_default_max_lengths(self):
self.verify_max_length(PersonWithDefaultMaxLengths, 'email', 75)
self.verify_max_length(PersonWithDefaultMaxLengths, 'vcard', 100)
@ -19,7 +19,7 @@ class MaxLengthArgumentsTests(TestCase):
self.verify_max_length(PersonWithCustomMaxLengths, 'homepage', 250)
self.verify_max_length(PersonWithCustomMaxLengths, 'avatar', 250)
class MaxLengthORMTests(TestCase):
class MaxLengthORMTests(unittest.TestCase):
def test_custom_max_lengths(self):
args = {

View File

@ -1,12 +1,12 @@
import datetime
import unittest
from decimal import Decimal
import django.test
from django import test
from django import forms
from django.db import models
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models.fields.files import FieldFile
from django.utils import unittest
from models import Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post, NullBooleanModel, BooleanModel, Document
@ -22,7 +22,7 @@ if Image:
TwoImageFieldTests
class BasicFieldTests(django.test.TestCase):
class BasicFieldTests(test.TestCase):
def test_show_hidden_initial(self):
"""
Regression test for #12913. Make sure fields with choices respect
@ -48,7 +48,7 @@ class BasicFieldTests(django.test.TestCase):
except ValidationError, e:
self.fail("NullBooleanField failed validation with value of None: %s" % e.messages)
class DecimalFieldTests(django.test.TestCase):
class DecimalFieldTests(test.TestCase):
def test_to_python(self):
f = models.DecimalField(max_digits=4, decimal_places=2)
self.assertEqual(f.to_python(3), Decimal("3"))
@ -95,7 +95,7 @@ class DecimalFieldTests(django.test.TestCase):
# This should not crash. That counts as a win for our purposes.
Foo.objects.filter(d__gte=100000000000)
class ForeignKeyTests(django.test.TestCase):
class ForeignKeyTests(test.TestCase):
def test_callable_default(self):
"""Test the use of a lazy callable for ForeignKey.default"""
a = Foo.objects.create(id=1, a='abc', d=Decimal("12.34"))
@ -194,7 +194,7 @@ class BooleanFieldTests(unittest.TestCase):
select={'string_length': 'LENGTH(string)'})[0]
self.assertFalse(isinstance(b5.pk, bool))
class ChoicesTests(django.test.TestCase):
class ChoicesTests(test.TestCase):
def test_choices_and_field_display(self):
"""
Check that get_choices and get_flatchoices interact with
@ -206,7 +206,7 @@ class ChoicesTests(django.test.TestCase):
self.assertEqual(Whiz(c=None).get_c_display(), None) # Blank value
self.assertEqual(Whiz(c='').get_c_display(), '') # Empty value
class SlugFieldTests(django.test.TestCase):
class SlugFieldTests(test.TestCase):
def test_slugfield_max_length(self):
"""
Make sure SlugField honors max_length (#9706)
@ -216,7 +216,7 @@ class SlugFieldTests(django.test.TestCase):
self.assertEqual(bs.s, 'slug'*50)
class ValidationTest(django.test.TestCase):
class ValidationTest(test.TestCase):
def test_charfield_raises_error_on_empty_string(self):
f = models.CharField()
self.assertRaises(ValidationError, f.clean, "", None)
@ -271,7 +271,7 @@ class ValidationTest(django.test.TestCase):
self.assertRaises(ValidationError, f.clean, None, None)
class BigIntegerFieldTests(django.test.TestCase):
class BigIntegerFieldTests(test.TestCase):
def test_limits(self):
# Ensure that values that are right at the limits can be saved
# and then retrieved without corruption.
@ -299,7 +299,7 @@ class BigIntegerFieldTests(django.test.TestCase):
b = BigInt.objects.get(value = '10')
self.assertEqual(b.value, 10)
class TypeCoercionTests(django.test.TestCase):
class TypeCoercionTests(test.TestCase):
"""
Test that database lookups can accept the wrong types and convert
them with no error: especially on Postgres 8.3+ which does not do

View File

@ -2,7 +2,7 @@
import datetime
from django.conf import settings
from django.db import models, DEFAULT_DB_ALIAS
from django.db import models, DEFAULT_DB_ALIAS, connection
from django.utils import tzinfo
CHOICES = (
@ -149,9 +149,7 @@ datetime.datetime(2000, 1, 1, 6, 1, 1)
"""}
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] not in (
"django.db.backends.mysql",
"django.db.backends.oracle"):
if connection.features.supports_timezones:
__test__["timezone-tests"] = """
# Saving an updating with timezone-aware datetime Python objects. Regression
# test for #10443.

View File

@ -1,6 +1,5 @@
from unittest import TestCase
from django.core.paginator import Paginator, EmptyPage
from django.utils.unittest import TestCase
class PaginatorTests(TestCase):
"""

View File

@ -8,7 +8,7 @@ import sys
import threading
from django.conf import settings
from django.db import models, DEFAULT_DB_ALIAS
from django.db import models, DEFAULT_DB_ALIAS, connection
from django.db.models import Count
from django.db.models.query import Q, ITER_CHUNK_SIZE, EmptyQuerySet
@ -1307,13 +1307,13 @@ FieldError: Infinite loop caused by ordering.
# In Oracle, we expect a null CharField to return u'' instead of None.
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == "django.db.backends.oracle":
if connection.features.interprets_empty_strings_as_nulls:
__test__["API_TESTS"] = __test__["API_TESTS"].replace("<NONE_OR_EMPTY_UNICODE>", "u''")
else:
__test__["API_TESTS"] = __test__["API_TESTS"].replace("<NONE_OR_EMPTY_UNICODE>", "None")
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == "django.db.backends.mysql":
if connection.features.requires_explicit_null_ordering_when_grouping:
__test__["API_TESTS"] += """
When grouping without specifying ordering, we add an explicit "ORDER BY NULL"
portion in MySQL to prevent unnecessary sorting.
@ -1342,7 +1342,7 @@ Using an empty generator expression as the rvalue for an "__in" lookup is legal
# Sqlite 3 does not support passing in more than 1000 parameters except by
# changing a parameter at compilation time.
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != "django.db.backends.sqlite3":
if connection.features.supports_1000_query_paramters:
__test__["API_TESTS"] += """
Bug #14244: Test that the "in" lookup works with lists of 1000 items or more.
>>> Number.objects.all().delete()

View File

@ -1,8 +1,7 @@
import unittest
from django.db import DatabaseError, connections, DEFAULT_DB_ALIAS
from django.db.models import Count
from django.test import TestCase
from django.utils import unittest
from models import Tag, Annotation, DumbCategory, Note, ExtraInfo, Number

View File

@ -17,7 +17,7 @@ except ImportError:
from django.conf import settings
from django.core import serializers, management
from django.db import transaction, DEFAULT_DB_ALIAS
from django.db import transaction, DEFAULT_DB_ALIAS, connection
from django.test import TestCase
from django.utils.functional import curry
@ -335,7 +335,7 @@ The end."""),
# Because Oracle treats the empty string as NULL, Oracle is expected to fail
# when field.empty_strings_allowed is True and the value is None; skip these
# tests.
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle':
if connection.features.interprets_empty_strings_as_nulls:
test_data = [data for data in test_data
if not (data[0] == data_obj and
data[2]._meta.get_field('data').empty_strings_allowed and
@ -344,7 +344,7 @@ if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle'
# Regression test for #8651 -- a FK to an object iwth PK of 0
# This won't work on MySQL since it won't let you create an object
# with a primary key of 0,
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.mysql':
if connection.features.allows_primary_key_0:
test_data.extend([
(data_obj, 0, Anchor, "Anchor 0"),
(fk_obj, 465, FKData, 0),

View File

@ -1,5 +1,5 @@
import unittest
from django.conf import settings
from django.utils import unittest
class SettingsTests(unittest.TestCase):

View File

@ -9,7 +9,6 @@ from django.conf import settings
if __name__ == '__main__':
settings.configure()
import unittest
import sys
import pkg_resources
import imp
@ -21,6 +20,8 @@ from django.template import TemplateDoesNotExist, Context
from django.template.loaders.eggs import load_template_source as lts_egg
from django.template.loaders.eggs import Loader as EggLoader
from django.template import loader
from django.utils import unittest
# Mock classes and objects for pkg_resources functions.
class MockProvider(pkg_resources.NullProvider):
@ -73,6 +74,7 @@ class DeprecatedEggLoaderTest(unittest.TestCase):
def tearDown(self):
settings.INSTALLED_APPS = self._old_installed_apps
warnings.resetwarnings()
warnings.simplefilter("ignore", PendingDeprecationWarning)
def test_existing(self):
"A template can be loaded from an egg"
@ -80,8 +82,6 @@ class DeprecatedEggLoaderTest(unittest.TestCase):
contents, template_name = lts_egg("y.html")
self.assertEqual(contents, "y")
self.assertEqual(template_name, "egg:egg_1:templates/y.html")
warnings.resetwarnings()
warnings.simplefilter("ignore", PendingDeprecationWarning)
class EggLoaderTest(unittest.TestCase):

View File

@ -1,6 +1,6 @@
from unittest import TestCase
from django.template.loader import get_template_from_string
from django.template import VariableNode
from django.utils.unittest import TestCase
class NodelistTest(TestCase):

View File

@ -1,5 +1,5 @@
import unittest
from django.template.smartif import IfParser, Literal
from django.utils import unittest
class SmartIfTests(unittest.TestCase):

View File

@ -11,12 +11,12 @@ import time
import os
import sys
import traceback
import unittest
from django import template
from django.core import urlresolvers
from django.template import loader
from django.template.loaders import app_directories, filesystem, cached
from django.utils import unittest
from django.utils.translation import activate, deactivate, ugettext as _
from django.utils.safestring import mark_safe
from django.utils.tzinfo import LocalTimezone
@ -506,16 +506,16 @@ class Templates(unittest.TestCase):
'basic-syntax28': ("{{ a.b }}", {'a': SilentGetItemClass()}, ('', 'INVALID')),
'basic-syntax29': ("{{ a.b }}", {'a': SilentAttrClass()}, ('', 'INVALID')),
# Something that starts like a number but has an extra lookup works as a lookup.
'basic-syntax30': ("{{ 1.2.3 }}", {"1": {"2": {"3": "d"}}}, "d"),
'basic-syntax31': ("{{ 1.2.3 }}", {"1": {"2": ("a", "b", "c", "d")}}, "d"),
'basic-syntax32': ("{{ 1.2.3 }}", {"1": (("x", "x", "x", "x"), ("y", "y", "y", "y"), ("a", "b", "c", "d"))}, "d"),
'basic-syntax33': ("{{ 1.2.3 }}", {"1": ("xxxx", "yyyy", "abcd")}, "d"),
'basic-syntax34': ("{{ 1.2.3 }}", {"1": ({"x": "x"}, {"y": "y"}, {"z": "z", "3": "d"})}, "d"),
# Numbers are numbers even if their digits are in the context.
'basic-syntax35': ("{{ 1 }}", {"1": "abc"}, "1"),
'basic-syntax36': ("{{ 1.2 }}", {"1": "abc"}, "1.2"),
# Something that starts like a number but has an extra lookup works as a lookup.
'basic-syntax30': ("{{ 1.2.3 }}", {"1": {"2": {"3": "d"}}}, "d"),
'basic-syntax31': ("{{ 1.2.3 }}", {"1": {"2": ("a", "b", "c", "d")}}, "d"),
'basic-syntax32': ("{{ 1.2.3 }}", {"1": (("x", "x", "x", "x"), ("y", "y", "y", "y"), ("a", "b", "c", "d"))}, "d"),
'basic-syntax33': ("{{ 1.2.3 }}", {"1": ("xxxx", "yyyy", "abcd")}, "d"),
'basic-syntax34': ("{{ 1.2.3 }}", {"1": ({"x": "x"}, {"y": "y"}, {"z": "z", "3": "d"})}, "d"),
# Numbers are numbers even if their digits are in the context.
'basic-syntax35': ("{{ 1 }}", {"1": "abc"}, "1"),
'basic-syntax36': ("{{ 1.2 }}", {"1": "abc"}, "1.2"),
# List-index syntax allows a template to access a certain item of a subscriptable object.
'list-index01': ("{{ var.1 }}", {"var": ["first item", "second item"]}, "second item"),
@ -603,7 +603,7 @@ class Templates(unittest.TestCase):
#filters should accept empty string constants
'filter-syntax20': ('{{ ""|default_if_none:"was none" }}', {}, ""),
### COMMENT SYNTAX ########################################################
'comment-syntax01': ("{# this is hidden #}hello", {}, "hello"),
'comment-syntax02': ("{# this is hidden #}hello{# foo #}", {}, "hello"),
@ -1300,8 +1300,8 @@ class Templates(unittest.TestCase):
# Regression test for #11270.
'cache17': ('{% load cache %}{% cache 10 long_cache_key poem %}Some Content{% endcache %}', {'poem': 'Oh freddled gruntbuggly/Thy micturations are to me/As plurdled gabbleblotchits/On a lurgid bee/That mordiously hath bitled out/Its earted jurtles/Into a rancid festering/Or else I shall rend thee in the gobberwarts with my blurglecruncheon/See if I dont.'}, 'Some Content'),
### AUTOESCAPE TAG ##############################################
'autoescape-tag01': ("{% autoescape off %}hello{% endautoescape %}", {}, "hello"),
'autoescape-tag02': ("{% autoescape off %}{{ first }}{% endautoescape %}", {"first": "<b>hello</b>"}, "<b>hello</b>"),
@ -1330,23 +1330,23 @@ class Templates(unittest.TestCase):
# implementation details (fortunately, the (no)autoescape block
# tags can be used in those cases)
'autoescape-filtertag01': ("{{ first }}{% filter safe %}{{ first }} x<y{% endfilter %}", {"first": "<a>"}, template.TemplateSyntaxError),
# ifqeual compares unescaped vales.
'autoescape-ifequal01': ('{% ifequal var "this & that" %}yes{% endifequal %}', { "var": "this & that" }, "yes" ),
# Arguments to filters are 'safe' and manipulate their input unescaped.
'autoescape-filters01': ('{{ var|cut:"&" }}', { "var": "this & that" }, "this that" ),
'autoescape-filters02': ('{{ var|join:" & \" }}', { "var": ("Tom", "Dick", "Harry") }, "Tom & Dick & Harry" ),
# Literal strings are safe.
'autoescape-literals01': ('{{ "this & that" }}',{}, "this & that" ),
# Iterating over strings outputs safe characters.
'autoescape-stringiterations01': ('{% for l in var %}{{ l }},{% endfor %}', {'var': 'K&R'}, "K,&amp;,R," ),
# Escape requirement survives lookup.
'autoescape-lookup01': ('{{ var.key }}', { "var": {"key": "this & that" }}, "this &amp; that" ),
'autoescape-ifequal01': ('{% ifequal var "this & that" %}yes{% endifequal %}', { "var": "this & that" }, "yes" ),
# Arguments to filters are 'safe' and manipulate their input unescaped.
'autoescape-filters01': ('{{ var|cut:"&" }}', { "var": "this & that" }, "this that" ),
'autoescape-filters02': ('{{ var|join:" & \" }}', { "var": ("Tom", "Dick", "Harry") }, "Tom & Dick & Harry" ),
# Literal strings are safe.
'autoescape-literals01': ('{{ "this & that" }}',{}, "this & that" ),
# Iterating over strings outputs safe characters.
'autoescape-stringiterations01': ('{% for l in var %}{{ l }},{% endfor %}', {'var': 'K&R'}, "K,&amp;,R," ),
# Escape requirement survives lookup.
'autoescape-lookup01': ('{{ var.key }}', { "var": {"key": "this & that" }}, "this &amp; that" ),
}

View File

@ -35,83 +35,83 @@ class AssertContainsTests(TestCase):
try:
self.assertContains(response, 'text', status_code=999)
except AssertionError, e:
self.assertEquals(str(e), "Couldn't retrieve content: Response code was 200 (expected 999)")
self.assertIn("Couldn't retrieve content: Response code was 200 (expected 999)", str(e))
try:
self.assertContains(response, 'text', status_code=999, msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Couldn't retrieve content: Response code was 200 (expected 999)")
self.assertIn("abc: Couldn't retrieve content: Response code was 200 (expected 999)", str(e))
try:
self.assertNotContains(response, 'text', status_code=999)
except AssertionError, e:
self.assertEquals(str(e), "Couldn't retrieve content: Response code was 200 (expected 999)")
self.assertIn("Couldn't retrieve content: Response code was 200 (expected 999)", str(e))
try:
self.assertNotContains(response, 'text', status_code=999, msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Couldn't retrieve content: Response code was 200 (expected 999)")
self.assertIn("abc: Couldn't retrieve content: Response code was 200 (expected 999)", str(e))
try:
self.assertNotContains(response, 'once')
except AssertionError, e:
self.assertEquals(str(e), "Response should not contain 'once'")
self.assertIn("Response should not contain 'once'", str(e))
try:
self.assertNotContains(response, 'once', msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Response should not contain 'once'")
self.assertIn("abc: Response should not contain 'once'", str(e))
try:
self.assertContains(response, 'never', 1)
except AssertionError, e:
self.assertEquals(str(e), "Found 0 instances of 'never' in response (expected 1)")
self.assertIn("Found 0 instances of 'never' in response (expected 1)", str(e))
try:
self.assertContains(response, 'never', 1, msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Found 0 instances of 'never' in response (expected 1)")
self.assertIn("abc: Found 0 instances of 'never' in response (expected 1)", str(e))
try:
self.assertContains(response, 'once', 0)
except AssertionError, e:
self.assertEquals(str(e), "Found 1 instances of 'once' in response (expected 0)")
self.assertIn("Found 1 instances of 'once' in response (expected 0)", str(e))
try:
self.assertContains(response, 'once', 0, msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Found 1 instances of 'once' in response (expected 0)")
self.assertIn("abc: Found 1 instances of 'once' in response (expected 0)", str(e))
try:
self.assertContains(response, 'once', 2)
except AssertionError, e:
self.assertEquals(str(e), "Found 1 instances of 'once' in response (expected 2)")
self.assertIn("Found 1 instances of 'once' in response (expected 2)", str(e))
try:
self.assertContains(response, 'once', 2, msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Found 1 instances of 'once' in response (expected 2)")
self.assertIn("abc: Found 1 instances of 'once' in response (expected 2)", str(e))
try:
self.assertContains(response, 'twice', 1)
except AssertionError, e:
self.assertEquals(str(e), "Found 2 instances of 'twice' in response (expected 1)")
self.assertIn("Found 2 instances of 'twice' in response (expected 1)", str(e))
try:
self.assertContains(response, 'twice', 1, msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Found 2 instances of 'twice' in response (expected 1)")
self.assertIn("abc: Found 2 instances of 'twice' in response (expected 1)", str(e))
try:
self.assertContains(response, 'thrice')
except AssertionError, e:
self.assertEquals(str(e), "Couldn't find 'thrice' in response")
self.assertIn("Couldn't find 'thrice' in response", str(e))
try:
self.assertContains(response, 'thrice', msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Couldn't find 'thrice' in response")
self.assertIn("abc: Couldn't find 'thrice' in response", str(e))
try:
self.assertContains(response, 'thrice', 3)
except AssertionError, e:
self.assertEquals(str(e), "Found 0 instances of 'thrice' in response (expected 3)")
self.assertIn("Found 0 instances of 'thrice' in response (expected 3)", str(e))
try:
self.assertContains(response, 'thrice', 3, msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Found 0 instances of 'thrice' in response (expected 3)")
self.assertIn("abc: Found 0 instances of 'thrice' in response (expected 3)", str(e))
def test_unicode_contains(self):
"Unicode characters can be found in template context"
@ -141,12 +141,12 @@ class AssertTemplateUsedTests(TestCase):
try:
self.assertTemplateUsed(response, 'GET Template')
except AssertionError, e:
self.assertEquals(str(e), "No templates used to render the response")
self.assertIn("No templates used to render the response", str(e))
try:
self.assertTemplateUsed(response, 'GET Template', msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: No templates used to render the response")
self.assertIn("abc: No templates used to render the response", str(e))
def test_single_context(self):
"Template assertions work when there is a single context"
@ -155,22 +155,22 @@ class AssertTemplateUsedTests(TestCase):
try:
self.assertTemplateNotUsed(response, 'Empty GET Template')
except AssertionError, e:
self.assertEquals(str(e), "Template 'Empty GET Template' was used unexpectedly in rendering the response")
self.assertIn("Template 'Empty GET Template' was used unexpectedly in rendering the response", str(e))
try:
self.assertTemplateNotUsed(response, 'Empty GET Template', msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Template 'Empty GET Template' was used unexpectedly in rendering the response")
self.assertIn("abc: Template 'Empty GET Template' was used unexpectedly in rendering the response", str(e))
try:
self.assertTemplateUsed(response, 'Empty POST Template')
except AssertionError, e:
self.assertEquals(str(e), "Template 'Empty POST Template' was not a template used to render the response. Actual template(s) used: Empty GET Template")
self.assertIn("Template 'Empty POST Template' was not a template used to render the response. Actual template(s) used: Empty GET Template", str(e))
try:
self.assertTemplateUsed(response, 'Empty POST Template', msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Template 'Empty POST Template' was not a template used to render the response. Actual template(s) used: Empty GET Template")
self.assertIn("abc: Template 'Empty POST Template' was not a template used to render the response. Actual template(s) used: Empty GET Template", str(e))
def test_multiple_context(self):
"Template assertions work when there are multiple contexts"
@ -186,17 +186,17 @@ class AssertTemplateUsedTests(TestCase):
try:
self.assertTemplateNotUsed(response, "form_view.html")
except AssertionError, e:
self.assertEquals(str(e), "Template 'form_view.html' was used unexpectedly in rendering the response")
self.assertIn("Template 'form_view.html' was used unexpectedly in rendering the response", str(e))
try:
self.assertTemplateNotUsed(response, 'base.html')
except AssertionError, e:
self.assertEquals(str(e), "Template 'base.html' was used unexpectedly in rendering the response")
self.assertIn("Template 'base.html' was used unexpectedly in rendering the response", str(e))
try:
self.assertTemplateUsed(response, "Valid POST Template")
except AssertionError, e:
self.assertEquals(str(e), "Template 'Valid POST Template' was not a template used to render the response. Actual template(s) used: form_view.html, base.html")
self.assertIn("Template 'Valid POST Template' was not a template used to render the response. Actual template(s) used: form_view.html, base.html", str(e))
class AssertRedirectsTests(TestCase):
def test_redirect_page(self):
@ -206,12 +206,12 @@ class AssertRedirectsTests(TestCase):
try:
self.assertRedirects(response, '/test_client/get_view/')
except AssertionError, e:
self.assertEquals(str(e), "Response didn't redirect as expected: Response code was 301 (expected 302)")
self.assertIn("Response didn't redirect as expected: Response code was 301 (expected 302)", str(e))
try:
self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Response didn't redirect as expected: Response code was 301 (expected 302)")
self.assertIn("abc: Response didn't redirect as expected: Response code was 301 (expected 302)", str(e))
def test_lost_query(self):
"An assertion is raised if the redirect location doesn't preserve GET parameters"
@ -219,12 +219,12 @@ class AssertRedirectsTests(TestCase):
try:
self.assertRedirects(response, '/test_client/get_view/')
except AssertionError, e:
self.assertEquals(str(e), "Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'")
self.assertIn("Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'", str(e))
try:
self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'")
self.assertIn("abc: Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'", str(e))
def test_incorrect_target(self):
"An assertion is raised if the response redirects to another target"
@ -233,7 +233,7 @@ class AssertRedirectsTests(TestCase):
# Should redirect to get_view
self.assertRedirects(response, '/test_client/some_view/')
except AssertionError, e:
self.assertEquals(str(e), "Response didn't redirect as expected: Response code was 301 (expected 302)")
self.assertIn("Response didn't redirect as expected: Response code was 301 (expected 302)", str(e))
def test_target_page(self):
"An assertion is raised if the response redirect target cannot be retrieved as expected"
@ -242,13 +242,13 @@ class AssertRedirectsTests(TestCase):
# The redirect target responds with a 301 code, not 200
self.assertRedirects(response, 'http://testserver/test_client/permanent_redirect_view/')
except AssertionError, e:
self.assertEquals(str(e), "Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)")
self.assertIn("Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)", str(e))
try:
# The redirect target responds with a 301 code, not 200
self.assertRedirects(response, 'http://testserver/test_client/permanent_redirect_view/', msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)")
self.assertIn("abc: Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)", str(e))
def test_redirect_chain(self):
"You can follow a redirect chain of multiple redirects"
@ -339,12 +339,12 @@ class AssertRedirectsTests(TestCase):
try:
self.assertRedirects(response, '/test_client/get_view/')
except AssertionError, e:
self.assertEquals(str(e), "Response didn't redirect as expected: Response code was 200 (expected 302)")
self.assertIn("Response didn't redirect as expected: Response code was 200 (expected 302)", str(e))
try:
self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Response didn't redirect as expected: Response code was 200 (expected 302)")
self.assertIn("abc: Response didn't redirect as expected: Response code was 200 (expected 302)", str(e))
def test_redirect_on_non_redirect_page(self):
"An assertion is raised if the original page couldn't be retrieved as expected"
@ -353,12 +353,12 @@ class AssertRedirectsTests(TestCase):
try:
self.assertRedirects(response, '/test_client/get_view/')
except AssertionError, e:
self.assertEquals(str(e), "Response didn't redirect as expected: Response code was 200 (expected 302)")
self.assertIn("Response didn't redirect as expected: Response code was 200 (expected 302)", str(e))
try:
self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc')
except AssertionError, e:
self.assertEquals(str(e), "abc: Response didn't redirect as expected: Response code was 200 (expected 302)")
self.assertIn("abc: Response didn't redirect as expected: Response code was 200 (expected 302)", str(e))
class AssertFormErrorTests(TestCase):
@ -378,11 +378,11 @@ class AssertFormErrorTests(TestCase):
try:
self.assertFormError(response, 'wrong_form', 'some_field', 'Some error.')
except AssertionError, e:
self.assertEqual(str(e), "The form 'wrong_form' was not used to render the response")
self.assertIn("The form 'wrong_form' was not used to render the response", str(e))
try:
self.assertFormError(response, 'wrong_form', 'some_field', 'Some error.', msg_prefix='abc')
except AssertionError, e:
self.assertEqual(str(e), "abc: The form 'wrong_form' was not used to render the response")
self.assertIn("abc: The form 'wrong_form' was not used to render the response", str(e))
def test_unknown_field(self):
"An assertion is raised if the field name is unknown"
@ -400,11 +400,11 @@ class AssertFormErrorTests(TestCase):
try:
self.assertFormError(response, 'form', 'some_field', 'Some error.')
except AssertionError, e:
self.assertEqual(str(e), "The form 'form' in context 0 does not contain the field 'some_field'")
self.assertIn("The form 'form' in context 0 does not contain the field 'some_field'", str(e))
try:
self.assertFormError(response, 'form', 'some_field', 'Some error.', msg_prefix='abc')
except AssertionError, e:
self.assertEqual(str(e), "abc: The form 'form' in context 0 does not contain the field 'some_field'")
self.assertIn("abc: The form 'form' in context 0 does not contain the field 'some_field'", str(e))
def test_noerror_field(self):
"An assertion is raised if the field doesn't have any errors"
@ -422,11 +422,11 @@ class AssertFormErrorTests(TestCase):
try:
self.assertFormError(response, 'form', 'value', 'Some error.')
except AssertionError, e:
self.assertEqual(str(e), "The field 'value' on form 'form' in context 0 contains no errors")
self.assertIn("The field 'value' on form 'form' in context 0 contains no errors", str(e))
try:
self.assertFormError(response, 'form', 'value', 'Some error.', msg_prefix='abc')
except AssertionError, e:
self.assertEqual(str(e), "abc: The field 'value' on form 'form' in context 0 contains no errors")
self.assertIn("abc: The field 'value' on form 'form' in context 0 contains no errors", str(e))
def test_unknown_error(self):
"An assertion is raised if the field doesn't contain the provided error"
@ -444,11 +444,11 @@ class AssertFormErrorTests(TestCase):
try:
self.assertFormError(response, 'form', 'email', 'Some error.')
except AssertionError, e:
self.assertEqual(str(e), "The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [u'Enter a valid e-mail address.'])")
self.assertIn("The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [u'Enter a valid e-mail address.'])", str(e))
try:
self.assertFormError(response, 'form', 'email', 'Some error.', msg_prefix='abc')
except AssertionError, e:
self.assertEqual(str(e), "abc: The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [u'Enter a valid e-mail address.'])")
self.assertIn("abc: The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [u'Enter a valid e-mail address.'])", str(e))
def test_unknown_nonfield_error(self):
"""
@ -469,11 +469,11 @@ class AssertFormErrorTests(TestCase):
try:
self.assertFormError(response, 'form', None, 'Some error.')
except AssertionError, e:
self.assertEqual(str(e), "The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )")
self.assertIn("The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )", str(e))
try:
self.assertFormError(response, 'form', None, 'Some error.', msg_prefix='abc')
except AssertionError, e:
self.assertEqual(str(e), "abc: The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )")
self.assertIn("abc: The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )", str(e))
class LoginTests(TestCase):
fixtures = ['testdata']

View File

@ -2,9 +2,9 @@
Tests for django test runner
"""
import StringIO
import unittest
import django
from django.test import simple
from django.utils import unittest
class DjangoTestRunnerTests(unittest.TestCase):

View File

@ -1,8 +1,6 @@
"""
Unit tests for reverse URL lookups.
"""
import unittest
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import reverse, resolve, NoReverseMatch,\
@ -11,6 +9,7 @@ from django.core.urlresolvers import reverse, resolve, NoReverseMatch,\
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
from django.shortcuts import redirect
from django.test import TestCase
from django.utils import unittest
import urlconf_outer
import urlconf_inner

Some files were not shown because too many files have changed in this diff Show More