Skip to content

Commit 96f1cb4

Browse files
committed
Split tests across several modules.
Fix #426.
1 parent f69f51f commit 96f1cb4

File tree

10 files changed

+433
-382
lines changed

10 files changed

+433
-382
lines changed

tests/base.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from __future__ import unicode_literals
2+
3+
import threading
4+
5+
from django.http import HttpResponse
6+
from django.test import TestCase, RequestFactory
7+
8+
from debug_toolbar.middleware import DebugToolbarMiddleware
9+
from debug_toolbar.toolbar.loader import DebugToolbar
10+
11+
rf = RequestFactory()
12+
13+
14+
class BaseTestCase(TestCase):
15+
16+
def setUp(self):
17+
request = rf.get('/')
18+
response = HttpResponse()
19+
toolbar = DebugToolbar(request)
20+
21+
DebugToolbarMiddleware.debug_toolbars[threading.current_thread().ident] = toolbar
22+
23+
self.request = request
24+
self.response = response
25+
self.toolbar = toolbar
26+
self.toolbar.stats = {}

tests/commands/__init__.py

Whitespace-only changes.

tests/commands/test_debugsqlshell.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from __future__ import unicode_literals
2+
3+
import sys
4+
5+
from django.contrib.auth.models import User
6+
from django.core import management
7+
from django.db.backends import util
8+
from django.test import TestCase
9+
from django.test.utils import override_settings
10+
from django.utils import six
11+
12+
13+
@override_settings(DEBUG=True)
14+
class DebugSQLShellTestCase(TestCase):
15+
16+
def setUp(self):
17+
self.original_cursor_wrapper = util.CursorDebugWrapper
18+
# Since debugsqlshell monkey-patches django.db.backends.util, we can
19+
# test it simply by loading it, without executing it. But we have to
20+
# undo the monkey-patch on exit.
21+
command_name = 'debugsqlshell'
22+
app_name = management.get_commands()[command_name]
23+
management.load_command_class(app_name, command_name)
24+
25+
def tearDown(self):
26+
util.CursorDebugWrapper = self.original_cursor_wrapper
27+
28+
def test_command(self):
29+
original_stdout, sys.stdout = sys.stdout, six.StringIO()
30+
try:
31+
User.objects.count()
32+
self.assertIn("SELECT COUNT(*)", sys.stdout.getvalue())
33+
finally:
34+
sys.stdout = original_stdout

tests/panels/__init__.py

Whitespace-only changes.

tests/panels/test_logger.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from __future__ import unicode_literals
2+
3+
import logging
4+
5+
from debug_toolbar.panels.logger import (
6+
LoggingPanel, MESSAGE_IF_STRING_REPRESENTATION_INVALID)
7+
8+
from ..base import BaseTestCase
9+
10+
11+
class LoggingPanelTestCase(BaseTestCase):
12+
13+
def test_happy_case(self):
14+
logger = logging.getLogger(__name__)
15+
logger.info('Nothing to see here, move along!')
16+
17+
logging_panel = self.toolbar.get_panel(LoggingPanel)
18+
logging_panel.process_response(None, None)
19+
records = logging_panel.get_stats()['records']
20+
21+
self.assertEqual(1, len(records))
22+
self.assertEqual('Nothing to see here, move along!',
23+
records[0]['message'])
24+
25+
def test_formatting(self):
26+
logger = logging.getLogger(__name__)
27+
logger.info('There are %d %s', 5, 'apples')
28+
29+
logging_panel = self.toolbar.get_panel(LoggingPanel)
30+
logging_panel.process_response(None, None)
31+
records = logging_panel.get_stats()['records']
32+
33+
self.assertEqual(1, len(records))
34+
self.assertEqual('There are 5 apples',
35+
records[0]['message'])
36+
37+
def test_failing_formatting(self):
38+
class BadClass(object):
39+
def __str__(self):
40+
raise Exception('Please not stringify me!')
41+
42+
logger = logging.getLogger(__name__)
43+
44+
# should not raise exception, but fail silently
45+
logger.debug('This class is misbehaving: %s', BadClass())
46+
47+
logging_panel = self.toolbar.get_panel(LoggingPanel)
48+
logging_panel.process_response(None, None)
49+
records = logging_panel.get_stats()['records']
50+
51+
self.assertEqual(1, len(records))
52+
self.assertEqual(MESSAGE_IF_STRING_REPRESENTATION_INVALID,
53+
records[0]['message'])

tests/panels/test_sql.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# coding: utf-8
2+
3+
from __future__ import unicode_literals
4+
5+
from django.contrib.auth.models import User
6+
from django.db import connection
7+
from django.db.utils import DatabaseError
8+
from django.utils import unittest
9+
10+
from debug_toolbar.panels.sql import SQLDebugPanel
11+
12+
from ..base import BaseTestCase
13+
14+
15+
class SQLPanelTestCase(BaseTestCase):
16+
17+
def test_recording(self):
18+
panel = self.toolbar.get_panel(SQLDebugPanel)
19+
self.assertEqual(len(panel._queries), 0)
20+
21+
list(User.objects.all())
22+
23+
# ensure query was logged
24+
self.assertEqual(len(panel._queries), 1)
25+
query = panel._queries[0]
26+
self.assertEqual(query[0], 'default')
27+
self.assertTrue('sql' in query[1])
28+
self.assertTrue('duration' in query[1])
29+
self.assertTrue('stacktrace' in query[1])
30+
31+
# ensure the stacktrace is populated
32+
self.assertTrue(len(query[1]['stacktrace']) > 0)
33+
34+
def test_non_ascii_query(self):
35+
panel = self.toolbar.get_panel(SQLDebugPanel)
36+
self.assertEqual(len(panel._queries), 0)
37+
38+
# non-ASCII query
39+
list(User.objects.extra(where=["username = 'café'"]))
40+
self.assertEqual(len(panel._queries), 1)
41+
42+
# non-ASCII parameters
43+
list(User.objects.filter(username='café'))
44+
self.assertEqual(len(panel._queries), 2)
45+
46+
@unittest.skipUnless(connection.vendor == 'postgresql',
47+
'Test valid only on PostgreSQL')
48+
def test_erroneous_query(self):
49+
"""
50+
Test that an error in the query isn't swallowed by the middleware.
51+
"""
52+
try:
53+
connection.cursor().execute("erroneous query")
54+
except DatabaseError as e:
55+
self.assertTrue('erroneous query' in str(e))
56+
57+
def test_disable_stacktraces(self):
58+
panel = self.toolbar.get_panel(SQLDebugPanel)
59+
self.assertEqual(len(panel._queries), 0)
60+
61+
with self.settings(DEBUG_TOOLBAR_CONFIG={'ENABLE_STACKTRACES': False}):
62+
list(User.objects.all())
63+
64+
# ensure query was logged
65+
self.assertEqual(len(panel._queries), 1)
66+
query = panel._queries[0]
67+
self.assertEqual(query[0], 'default')
68+
self.assertTrue('sql' in query[1])
69+
self.assertTrue('duration' in query[1])
70+
self.assertTrue('stacktrace' in query[1])
71+
72+
# ensure the stacktrace is empty
73+
self.assertEqual([], query[1]['stacktrace'])

tests/panels/test_template.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from __future__ import unicode_literals
2+
3+
import django
4+
from django.contrib.auth.models import User
5+
from django.template import Template, Context
6+
7+
from debug_toolbar.panels.template import TemplateDebugPanel
8+
from debug_toolbar.panels.sql import SQLDebugPanel
9+
10+
from ..base import BaseTestCase
11+
12+
13+
class TemplateDebugPanelTestCase(BaseTestCase):
14+
15+
def test_queryset_hook(self):
16+
template_panel = self.toolbar.get_panel(TemplateDebugPanel)
17+
sql_panel = self.toolbar.get_panel(SQLDebugPanel)
18+
t = Template("No context variables here!")
19+
c = Context({
20+
'queryset': User.objects.all(),
21+
'deep_queryset': {
22+
'queryset': User.objects.all(),
23+
}
24+
})
25+
t.render(c)
26+
# ensure the query was NOT logged
27+
self.assertEqual(len(sql_panel._queries), 0)
28+
base_ctx_idx = 1 if django.VERSION[:2] >= (1, 5) else 0
29+
ctx = template_panel.templates[0]['context'][base_ctx_idx]
30+
self.assertIn('<<queryset of auth.User>>', ctx)
31+
self.assertIn('<<triggers database query>>', ctx)

0 commit comments

Comments
 (0)