diff options
| -rw-r--r-- | tests/base.py | 26 | ||||
| -rw-r--r-- | tests/commands/__init__.py | 0 | ||||
| -rw-r--r-- | tests/commands/test_debugsqlshell.py | 34 | ||||
| -rw-r--r-- | tests/panels/__init__.py | 0 | ||||
| -rw-r--r-- | tests/panels/test_logger.py | 53 | ||||
| -rw-r--r-- | tests/panels/test_sql.py | 73 | ||||
| -rw-r--r-- | tests/panels/test_template.py | 31 | ||||
| -rw-r--r-- | tests/test_integration.py | 185 | ||||
| -rw-r--r-- | tests/test_utils.py | 24 | ||||
| -rw-r--r-- | tests/tests.py | 389 | 
10 files changed, 433 insertions, 382 deletions
| diff --git a/tests/base.py b/tests/base.py new file mode 100644 index 0000000..e6f6dac --- /dev/null +++ b/tests/base.py @@ -0,0 +1,26 @@ +from __future__ import unicode_literals + +import threading + +from django.http import HttpResponse +from django.test import TestCase, RequestFactory + +from debug_toolbar.middleware import DebugToolbarMiddleware +from debug_toolbar.toolbar.loader import DebugToolbar + +rf = RequestFactory() + + +class BaseTestCase(TestCase): + +    def setUp(self): +        request = rf.get('/') +        response = HttpResponse() +        toolbar = DebugToolbar(request) + +        DebugToolbarMiddleware.debug_toolbars[threading.current_thread().ident] = toolbar + +        self.request = request +        self.response = response +        self.toolbar = toolbar +        self.toolbar.stats = {} diff --git a/tests/commands/__init__.py b/tests/commands/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/commands/__init__.py diff --git a/tests/commands/test_debugsqlshell.py b/tests/commands/test_debugsqlshell.py new file mode 100644 index 0000000..f35ef07 --- /dev/null +++ b/tests/commands/test_debugsqlshell.py @@ -0,0 +1,34 @@ +from __future__ import unicode_literals + +import sys + +from django.contrib.auth.models import User +from django.core import management +from django.db.backends import util +from django.test import TestCase +from django.test.utils import override_settings +from django.utils import six + + +@override_settings(DEBUG=True) +class DebugSQLShellTestCase(TestCase): + +    def setUp(self): +        self.original_cursor_wrapper = util.CursorDebugWrapper +        # Since debugsqlshell monkey-patches django.db.backends.util, we can +        # test it simply by loading it, without executing it. But we have to +        # undo the monkey-patch on exit. +        command_name = 'debugsqlshell' +        app_name = management.get_commands()[command_name] +        management.load_command_class(app_name, command_name) + +    def tearDown(self): +        util.CursorDebugWrapper = self.original_cursor_wrapper + +    def test_command(self): +        original_stdout, sys.stdout = sys.stdout, six.StringIO() +        try: +            User.objects.count() +            self.assertIn("SELECT COUNT(*)", sys.stdout.getvalue()) +        finally: +            sys.stdout = original_stdout diff --git a/tests/panels/__init__.py b/tests/panels/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/panels/__init__.py diff --git a/tests/panels/test_logger.py b/tests/panels/test_logger.py new file mode 100644 index 0000000..477d100 --- /dev/null +++ b/tests/panels/test_logger.py @@ -0,0 +1,53 @@ +from __future__ import unicode_literals + +import logging + +from debug_toolbar.panels.logger import ( +    LoggingPanel, MESSAGE_IF_STRING_REPRESENTATION_INVALID) + +from ..base import BaseTestCase + + +class LoggingPanelTestCase(BaseTestCase): + +    def test_happy_case(self): +        logger = logging.getLogger(__name__) +        logger.info('Nothing to see here, move along!') + +        logging_panel = self.toolbar.get_panel(LoggingPanel) +        logging_panel.process_response(None, None) +        records = logging_panel.get_stats()['records'] + +        self.assertEqual(1, len(records)) +        self.assertEqual('Nothing to see here, move along!', +                         records[0]['message']) + +    def test_formatting(self): +        logger = logging.getLogger(__name__) +        logger.info('There are %d %s', 5, 'apples') + +        logging_panel = self.toolbar.get_panel(LoggingPanel) +        logging_panel.process_response(None, None) +        records = logging_panel.get_stats()['records'] + +        self.assertEqual(1, len(records)) +        self.assertEqual('There are 5 apples', +                         records[0]['message']) + +    def test_failing_formatting(self): +        class BadClass(object): +            def __str__(self): +                raise Exception('Please not stringify me!') + +        logger = logging.getLogger(__name__) + +        # should not raise exception, but fail silently +        logger.debug('This class is misbehaving: %s', BadClass()) + +        logging_panel = self.toolbar.get_panel(LoggingPanel) +        logging_panel.process_response(None, None) +        records = logging_panel.get_stats()['records'] + +        self.assertEqual(1, len(records)) +        self.assertEqual(MESSAGE_IF_STRING_REPRESENTATION_INVALID, +                         records[0]['message']) diff --git a/tests/panels/test_sql.py b/tests/panels/test_sql.py new file mode 100644 index 0000000..10846f5 --- /dev/null +++ b/tests/panels/test_sql.py @@ -0,0 +1,73 @@ +# coding: utf-8 + +from __future__ import unicode_literals + +from django.contrib.auth.models import User +from django.db import connection +from django.db.utils import DatabaseError +from django.utils import unittest + +from debug_toolbar.panels.sql import SQLDebugPanel + +from ..base import BaseTestCase + + +class SQLPanelTestCase(BaseTestCase): + +    def test_recording(self): +        panel = self.toolbar.get_panel(SQLDebugPanel) +        self.assertEqual(len(panel._queries), 0) + +        list(User.objects.all()) + +        # ensure query was logged +        self.assertEqual(len(panel._queries), 1) +        query = panel._queries[0] +        self.assertEqual(query[0], 'default') +        self.assertTrue('sql' in query[1]) +        self.assertTrue('duration' in query[1]) +        self.assertTrue('stacktrace' in query[1]) + +        # ensure the stacktrace is populated +        self.assertTrue(len(query[1]['stacktrace']) > 0) + +    def test_non_ascii_query(self): +        panel = self.toolbar.get_panel(SQLDebugPanel) +        self.assertEqual(len(panel._queries), 0) + +        # non-ASCII query +        list(User.objects.extra(where=["username = 'café'"])) +        self.assertEqual(len(panel._queries), 1) + +        # non-ASCII parameters +        list(User.objects.filter(username='café')) +        self.assertEqual(len(panel._queries), 2) + +    @unittest.skipUnless(connection.vendor == 'postgresql', +                         'Test valid only on PostgreSQL') +    def test_erroneous_query(self): +        """ +        Test that an error in the query isn't swallowed by the middleware. +        """ +        try: +            connection.cursor().execute("erroneous query") +        except DatabaseError as e: +            self.assertTrue('erroneous query' in str(e)) + +    def test_disable_stacktraces(self): +        panel = self.toolbar.get_panel(SQLDebugPanel) +        self.assertEqual(len(panel._queries), 0) + +        with self.settings(DEBUG_TOOLBAR_CONFIG={'ENABLE_STACKTRACES': False}): +            list(User.objects.all()) + +        # ensure query was logged +        self.assertEqual(len(panel._queries), 1) +        query = panel._queries[0] +        self.assertEqual(query[0], 'default') +        self.assertTrue('sql' in query[1]) +        self.assertTrue('duration' in query[1]) +        self.assertTrue('stacktrace' in query[1]) + +        # ensure the stacktrace is empty +        self.assertEqual([], query[1]['stacktrace']) diff --git a/tests/panels/test_template.py b/tests/panels/test_template.py new file mode 100644 index 0000000..4e30a73 --- /dev/null +++ b/tests/panels/test_template.py @@ -0,0 +1,31 @@ +from __future__ import unicode_literals + +import django +from django.contrib.auth.models import User +from django.template import Template, Context + +from debug_toolbar.panels.template import TemplateDebugPanel +from debug_toolbar.panels.sql import SQLDebugPanel + +from ..base import BaseTestCase + + +class TemplateDebugPanelTestCase(BaseTestCase): + +    def test_queryset_hook(self): +        template_panel = self.toolbar.get_panel(TemplateDebugPanel) +        sql_panel = self.toolbar.get_panel(SQLDebugPanel) +        t = Template("No context variables here!") +        c = Context({ +            'queryset': User.objects.all(), +            'deep_queryset': { +                'queryset': User.objects.all(), +            } +        }) +        t.render(c) +        # ensure the query was NOT logged +        self.assertEqual(len(sql_panel._queries), 0) +        base_ctx_idx = 1 if django.VERSION[:2] >= (1, 5) else 0 +        ctx = template_panel.templates[0]['context'][base_ctx_idx] +        self.assertIn('<<queryset of auth.User>>', ctx) +        self.assertIn('<<triggers database query>>', ctx) diff --git a/tests/test_integration.py b/tests/test_integration.py new file mode 100644 index 0000000..41206fc --- /dev/null +++ b/tests/test_integration.py @@ -0,0 +1,185 @@ +# coding: utf-8 + +from __future__ import unicode_literals + +from xml.etree import ElementTree as ET + +from django.contrib.auth.models import User +from django.db import IntegrityError, transaction +from django.test import TestCase, RequestFactory +from django.test.utils import override_settings +from django.utils import six + +from debug_toolbar.middleware import DebugToolbarMiddleware, show_toolbar +from debug_toolbar.panels.request_vars import RequestVarsDebugPanel + +from .base import BaseTestCase + + +rf = RequestFactory() + + +@override_settings(DEBUG=True) +class DebugToolbarTestCase(BaseTestCase): + +    urls = 'tests.urls' + +    def test_show_toolbar(self): +        self.assertTrue(show_toolbar(self.request)) + +    def test_show_toolbar_DEBUG(self): +        with self.settings(DEBUG=False): +            self.assertFalse(show_toolbar(self.request)) + +    def test_show_toolbar_INTERNAL_IPS(self): +        with self.settings(INTERNAL_IPS=[]): +            self.assertFalse(show_toolbar(self.request)) + +    def test_request_urlconf_string(self): +        request = rf.get('/') +        request.urlconf = 'tests.urls' +        middleware = DebugToolbarMiddleware() + +        middleware.process_request(request) + +        self.assertFalse(isinstance(request.urlconf, six.string_types)) + +        patterns = request.urlconf.urlpatterns +        self.assertTrue(hasattr(patterns[1], '_callback_str')) +        self.assertEqual(patterns[-1]._callback_str, 'tests.views.execute_sql') + +    def test_request_urlconf_string_per_request(self): +        request = rf.get('/') +        request.urlconf = 'debug_toolbar.urls' +        middleware = DebugToolbarMiddleware() + +        middleware.process_request(request) +        request.urlconf = 'tests.urls' +        middleware.process_request(request) + +        self.assertFalse(isinstance(request.urlconf, six.string_types)) + +        patterns = request.urlconf.urlpatterns +        self.assertTrue(hasattr(patterns[1], '_callback_str')) +        self.assertEqual(patterns[-1]._callback_str, 'tests.views.execute_sql') + +    def test_request_urlconf_module(self): +        request = rf.get('/') +        request.urlconf = __import__('tests.urls').urls +        middleware = DebugToolbarMiddleware() + +        middleware.process_request(request) + +        self.assertFalse(isinstance(request.urlconf, six.string_types)) + +        patterns = request.urlconf.urlpatterns +        self.assertTrue(hasattr(patterns[1], '_callback_str')) +        self.assertEqual(patterns[-1]._callback_str, 'tests.views.execute_sql') + +    def test_tuple_urlconf(self): +        request = rf.get('/') +        urls = __import__('tests.urls').urls +        urls.urlpatterns = tuple(urls.urlpatterns) +        request.urlconf = urls +        middleware = DebugToolbarMiddleware() + +        middleware.process_request(request) + +        self.assertFalse(isinstance(request.urlconf, six.string_types)) + +    def _resolve_stats(self, path): +        # takes stats from RequestVars panel +        self.request.path = path +        panel = self.toolbar.get_panel(RequestVarsDebugPanel) +        panel.process_request(self.request) +        panel.process_response(self.request, self.response) +        return self.toolbar.stats['requestvars'] + +    def test_url_resolving_positional(self): +        stats = self._resolve_stats('/resolving1/a/b/') +        self.assertEqual(stats['view_urlname'], 'positional-resolving') +        self.assertEqual(stats['view_func'], 'tests.views.resolving_view') +        self.assertEqual(stats['view_args'], ('a', 'b')) +        self.assertEqual(stats['view_kwargs'], {}) + +    def test_url_resolving_named(self): +        stats = self._resolve_stats('/resolving2/a/b/') +        self.assertEqual(stats['view_args'], ()) +        self.assertEqual(stats['view_kwargs'], {'arg1': 'a', 'arg2': 'b'}) + +    def test_url_resolving_mixed(self): +        stats = self._resolve_stats('/resolving3/a/') +        self.assertEqual(stats['view_args'], ('a',)) +        self.assertEqual(stats['view_kwargs'], {'arg2': 'default'}) + +    def test_url_resolving_bad(self): +        stats = self._resolve_stats('/non-existing-url/') +        self.assertEqual(stats['view_urlname'], 'None') +        self.assertEqual(stats['view_args'], 'None') +        self.assertEqual(stats['view_kwargs'], 'None') +        self.assertEqual(stats['view_func'], '<no view>') + + +@override_settings(DEBUG=True) +class DebugToolbarIntegrationTestCase(TestCase): + +    urls = 'tests.urls' + +    def test_middleware(self): +        response = self.client.get('/execute_sql/') +        self.assertEqual(response.status_code, 200) + +    @override_settings(DEFAULT_CHARSET='iso-8859-1') +    def test_non_utf8_charset(self): +        response = self.client.get('/regular/ASCII/') +        self.assertContains(response, 'ASCII')      # template +        self.assertContains(response, 'djDebug')    # toolbar + +        response = self.client.get('/regular/LÀTÍN/') +        self.assertContains(response, 'LÀTÍN')      # template +        self.assertContains(response, 'djDebug')    # toolbar + +    def test_non_ascii_bytes_in_db_params(self): +        response = self.client.get('/non_ascii_bytes_in_db_params/') +        if six.PY3: +            self.assertContains(response, 'djàngó') +        else: +            self.assertContains(response, 'dj\\xe0ng\\xf3') + +    def test_non_ascii_session(self): +        response = self.client.get('/set_session/') +        if six.PY3: +            self.assertContains(response, 'où') +        else: +            self.assertContains(response, 'o\\xf9') +            self.assertContains(response, 'l\\xc3\\xa0') + +    def test_object_with_non_ascii_repr_in_context(self): +        response = self.client.get('/non_ascii_context/') +        self.assertContains(response, 'nôt åscíì') + +    def test_object_with_non_ascii_repr_in_request_vars(self): +        response = self.client.get('/non_ascii_request/') +        self.assertContains(response, 'nôt åscíì') + +    def test_xml_validation(self): +        response = self.client.get('/regular/XML/') +        ET.fromstring(response.content)     # shouldn't raise ParseError + +    def test_view_executed_once(self): +        with self.settings( +                DEBUG_TOOLBAR_PANELS=['debug_toolbar.panels.profiling.ProfilingDebugPanel']): + +            self.assertEqual(User.objects.count(), 0) + +            response = self.client.get('/new_user/') +            self.assertContains(response, 'Profiling') +            self.assertEqual(User.objects.count(), 1) + +            with self.assertRaises(IntegrityError): +                if hasattr(transaction, 'atomic'):      # Django >= 1.6 +                    with transaction.atomic(): +                        response = self.client.get('/new_user/') +                else: +                    response = self.client.get('/new_user/') +            self.assertEqual(User.objects.count(), 1) diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..a930894 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,24 @@ +from __future__ import unicode_literals + +from django.utils.unittest import TestCase + +from debug_toolbar.utils import get_name_from_obj + + +class GetNameFromObjTestCase(TestCase): + +    def test_func(self): +        def x(): +            return 1 +        res = get_name_from_obj(x) +        self.assertEqual(res, 'tests.test_utils.x') + +    def test_lambda(self): +        res = get_name_from_obj(lambda: 1) +        self.assertEqual(res, 'tests.test_utils.<lambda>') + +    def test_class(self): +        class A: +            pass +        res = get_name_from_obj(A) +        self.assertEqual(res, 'tests.test_utils.A') diff --git a/tests/tests.py b/tests/tests.py index 8bbf5b0..10e0a9b 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1,384 +1,9 @@ -# coding: utf-8 - -from __future__ import unicode_literals - -import logging -import sys -import threading -from xml.etree import ElementTree as ET -  import django -from django.contrib.auth.models import User -from django.core import management -from django.db import connection, IntegrityError, transaction -from django.db.backends import util -from django.http import HttpResponse -from django.test import TestCase, RequestFactory -from django.test.utils import override_settings -from django.template import Template, Context -from django.utils import six -from django.utils import unittest - -from debug_toolbar.middleware import DebugToolbarMiddleware, show_toolbar -from debug_toolbar.panels.logger import ( -    LoggingPanel, MESSAGE_IF_STRING_REPRESENTATION_INVALID) -from debug_toolbar.panels.sql import SQLDebugPanel -from debug_toolbar.panels.request_vars import RequestVarsDebugPanel -from debug_toolbar.panels.template import TemplateDebugPanel -from debug_toolbar.toolbar.loader import DebugToolbar -from debug_toolbar.utils import get_name_from_obj - - -rf = RequestFactory() - - -class BaseTestCase(TestCase): - -    def setUp(self): -        request = rf.get('/') -        response = HttpResponse() -        toolbar = DebugToolbar(request) - -        DebugToolbarMiddleware.debug_toolbars[threading.current_thread().ident] = toolbar - -        self.request = request -        self.response = response -        self.toolbar = toolbar -        self.toolbar.stats = {} - - -@override_settings(DEBUG=True) -class DebugToolbarTestCase(BaseTestCase): - -    urls = 'tests.urls' - -    def test_show_toolbar(self): -        self.assertTrue(show_toolbar(self.request)) - -    def test_show_toolbar_DEBUG(self): -        with self.settings(DEBUG=False): -            self.assertFalse(show_toolbar(self.request)) - -    def test_show_toolbar_INTERNAL_IPS(self): -        with self.settings(INTERNAL_IPS=[]): -            self.assertFalse(show_toolbar(self.request)) - -    def test_request_urlconf_string(self): -        request = rf.get('/') -        request.urlconf = 'tests.urls' -        middleware = DebugToolbarMiddleware() - -        middleware.process_request(request) - -        self.assertFalse(isinstance(request.urlconf, six.string_types)) - -        patterns = request.urlconf.urlpatterns -        self.assertTrue(hasattr(patterns[1], '_callback_str')) -        self.assertEqual(patterns[-1]._callback_str, 'tests.views.execute_sql') - -    def test_request_urlconf_string_per_request(self): -        request = rf.get('/') -        request.urlconf = 'debug_toolbar.urls' -        middleware = DebugToolbarMiddleware() - -        middleware.process_request(request) -        request.urlconf = 'tests.urls' -        middleware.process_request(request) - -        self.assertFalse(isinstance(request.urlconf, six.string_types)) - -        patterns = request.urlconf.urlpatterns -        self.assertTrue(hasattr(patterns[1], '_callback_str')) -        self.assertEqual(patterns[-1]._callback_str, 'tests.views.execute_sql') - -    def test_request_urlconf_module(self): -        request = rf.get('/') -        request.urlconf = __import__('tests.urls').urls -        middleware = DebugToolbarMiddleware() - -        middleware.process_request(request) - -        self.assertFalse(isinstance(request.urlconf, six.string_types)) - -        patterns = request.urlconf.urlpatterns -        self.assertTrue(hasattr(patterns[1], '_callback_str')) -        self.assertEqual(patterns[-1]._callback_str, 'tests.views.execute_sql') - -    def test_tuple_urlconf(self): -        request = rf.get('/') -        urls = __import__('tests.urls').urls -        urls.urlpatterns = tuple(urls.urlpatterns) -        request.urlconf = urls -        middleware = DebugToolbarMiddleware() - -        middleware.process_request(request) - -        self.assertFalse(isinstance(request.urlconf, six.string_types)) - -    def _resolve_stats(self, path): -        # takes stats from RequestVars panel -        self.request.path = path -        panel = self.toolbar.get_panel(RequestVarsDebugPanel) -        panel.process_request(self.request) -        panel.process_response(self.request, self.response) -        return self.toolbar.stats['requestvars'] - -    def test_url_resolving_positional(self): -        stats = self._resolve_stats('/resolving1/a/b/') -        self.assertEqual(stats['view_urlname'], 'positional-resolving') -        self.assertEqual(stats['view_func'], 'tests.views.resolving_view') -        self.assertEqual(stats['view_args'], ('a', 'b')) -        self.assertEqual(stats['view_kwargs'], {}) - -    def test_url_resolving_named(self): -        stats = self._resolve_stats('/resolving2/a/b/') -        self.assertEqual(stats['view_args'], ()) -        self.assertEqual(stats['view_kwargs'], {'arg1': 'a', 'arg2': 'b'}) - -    def test_url_resolving_mixed(self): -        stats = self._resolve_stats('/resolving3/a/') -        self.assertEqual(stats['view_args'], ('a',)) -        self.assertEqual(stats['view_kwargs'], {'arg2': 'default'}) - -    def test_url_resolving_bad(self): -        stats = self._resolve_stats('/non-existing-url/') -        self.assertEqual(stats['view_urlname'], 'None') -        self.assertEqual(stats['view_args'], 'None') -        self.assertEqual(stats['view_kwargs'], 'None') -        self.assertEqual(stats['view_func'], '<no view>') - - -@override_settings(DEBUG=True) -class DebugToolbarIntegrationTestCase(TestCase): - -    urls = 'tests.urls' - -    def test_middleware(self): -        response = self.client.get('/execute_sql/') -        self.assertEqual(response.status_code, 200) - -    @override_settings(DEFAULT_CHARSET='iso-8859-1') -    def test_non_utf8_charset(self): -        response = self.client.get('/regular/ASCII/') -        self.assertContains(response, 'ASCII')      # template -        self.assertContains(response, 'djDebug')    # toolbar - -        response = self.client.get('/regular/LÀTÍN/') -        self.assertContains(response, 'LÀTÍN')      # template -        self.assertContains(response, 'djDebug')    # toolbar - -    def test_non_ascii_bytes_in_db_params(self): -        response = self.client.get('/non_ascii_bytes_in_db_params/') -        if six.PY3: -            self.assertContains(response, 'djàngó') -        else: -            self.assertContains(response, 'dj\\xe0ng\\xf3') - -    def test_non_ascii_session(self): -        response = self.client.get('/set_session/') -        if six.PY3: -            self.assertContains(response, 'où') -        else: -            self.assertContains(response, 'o\\xf9') -            self.assertContains(response, 'l\\xc3\\xa0') - -    def test_object_with_non_ascii_repr_in_context(self): -        response = self.client.get('/non_ascii_context/') -        self.assertContains(response, 'nôt åscíì') - -    def test_object_with_non_ascii_repr_in_request_vars(self): -        response = self.client.get('/non_ascii_request/') -        self.assertContains(response, 'nôt åscíì') - -    def test_xml_validation(self): -        response = self.client.get('/regular/XML/') -        ET.fromstring(response.content)     # shouldn't raise ParseError - -    def test_view_executed_once(self): -        with self.settings( -                DEBUG_TOOLBAR_PANELS=['debug_toolbar.panels.profiling.ProfilingDebugPanel']): - -            self.assertEqual(User.objects.count(), 0) - -            response = self.client.get('/new_user/') -            self.assertContains(response, 'Profiling') -            self.assertEqual(User.objects.count(), 1) - -            with self.assertRaises(IntegrityError): -                if hasattr(transaction, 'atomic'):      # Django >= 1.6 -                    with transaction.atomic(): -                        response = self.client.get('/new_user/') -                else: -                    response = self.client.get('/new_user/') -            self.assertEqual(User.objects.count(), 1) - - -class DebugToolbarNameFromObjectTest(BaseTestCase): - -    def test_func(self): -        def x(): -            return 1 -        res = get_name_from_obj(x) -        self.assertEqual(res, 'tests.tests.x') - -    def test_lambda(self): -        res = get_name_from_obj(lambda: 1) -        self.assertEqual(res, 'tests.tests.<lambda>') - -    def test_class(self): -        class A: -            pass -        res = get_name_from_obj(A) -        self.assertEqual(res, 'tests.tests.A') - - -class SQLPanelTestCase(BaseTestCase): - -    def test_recording(self): -        panel = self.toolbar.get_panel(SQLDebugPanel) -        self.assertEqual(len(panel._queries), 0) - -        list(User.objects.all()) - -        # ensure query was logged -        self.assertEqual(len(panel._queries), 1) -        query = panel._queries[0] -        self.assertEqual(query[0], 'default') -        self.assertTrue('sql' in query[1]) -        self.assertTrue('duration' in query[1]) -        self.assertTrue('stacktrace' in query[1]) - -        # ensure the stacktrace is populated -        self.assertTrue(len(query[1]['stacktrace']) > 0) - -    def test_non_ascii_query(self): -        panel = self.toolbar.get_panel(SQLDebugPanel) -        self.assertEqual(len(panel._queries), 0) - -        # non-ASCII query -        list(User.objects.extra(where=["username = 'café'"])) -        self.assertEqual(len(panel._queries), 1) - -        # non-ASCII parameters -        list(User.objects.filter(username='café')) -        self.assertEqual(len(panel._queries), 2) - -    @unittest.skipUnless(connection.vendor == 'postgresql', -                         'Test valid only on PostgreSQL') -    def test_erroneous_query(self): -        """ -        Test that an error in the query isn't swallowed by the middleware. -        """ -        from django.db import connection -        from django.db.utils import DatabaseError -        try: -            connection.cursor().execute("erroneous query") -        except DatabaseError as e: -            self.assertTrue('erroneous query' in str(e)) - -    def test_disable_stacktraces(self): -        panel = self.toolbar.get_panel(SQLDebugPanel) -        self.assertEqual(len(panel._queries), 0) - -        with self.settings(DEBUG_TOOLBAR_CONFIG={'ENABLE_STACKTRACES': False}): -            list(User.objects.all()) - -        # ensure query was logged -        self.assertEqual(len(panel._queries), 1) -        query = panel._queries[0] -        self.assertEqual(query[0], 'default') -        self.assertTrue('sql' in query[1]) -        self.assertTrue('duration' in query[1]) -        self.assertTrue('stacktrace' in query[1]) - -        # ensure the stacktrace is empty -        self.assertEqual([], query[1]['stacktrace']) - - -class TemplatePanelTestCase(BaseTestCase): - -    def test_queryset_hook(self): -        template_panel = self.toolbar.get_panel(TemplateDebugPanel) -        sql_panel = self.toolbar.get_panel(SQLDebugPanel) -        t = Template("No context variables here!") -        c = Context({ -            'queryset': User.objects.all(), -            'deep_queryset': { -                'queryset': User.objects.all(), -            } -        }) -        t.render(c) -        # ensure the query was NOT logged -        self.assertEqual(len(sql_panel._queries), 0) -        base_ctx_idx = 1 if django.VERSION[:2] >= (1, 5) else 0 -        ctx = template_panel.templates[0]['context'][base_ctx_idx] -        self.assertIn('<<queryset of auth.User>>', ctx) -        self.assertIn('<<triggers database query>>', ctx) - - -class LoggingPanelTestCase(BaseTestCase): -    def test_happy_case(self): -        logger = logging.getLogger(__name__) -        logger.info('Nothing to see here, move along!') - -        logging_panel = self.toolbar.get_panel(LoggingPanel) -        logging_panel.process_response(None, None) -        records = logging_panel.get_stats()['records'] - -        self.assertEqual(1, len(records)) -        self.assertEqual('Nothing to see here, move along!', -                         records[0]['message']) - -    def test_formatting(self): -        logger = logging.getLogger(__name__) -        logger.info('There are %d %s', 5, 'apples') - -        logging_panel = self.toolbar.get_panel(LoggingPanel) -        logging_panel.process_response(None, None) -        records = logging_panel.get_stats()['records'] - -        self.assertEqual(1, len(records)) -        self.assertEqual('There are 5 apples', -                         records[0]['message']) - -    def test_failing_formatting(self): -        class BadClass(object): -            def __str__(self): -                raise Exception('Please not stringify me!') - -        logger = logging.getLogger(__name__) - -        # should not raise exception, but fail silently -        logger.debug('This class is misbehaving: %s', BadClass()) - -        logging_panel = self.toolbar.get_panel(LoggingPanel) -        logging_panel.process_response(None, None) -        records = logging_panel.get_stats()['records'] - -        self.assertEqual(1, len(records)) -        self.assertEqual(MESSAGE_IF_STRING_REPRESENTATION_INVALID, -                         records[0]['message']) - - -@override_settings(DEBUG=True) -class DebugSQLShellTestCase(TestCase): - -    def setUp(self): -        self.original_cursor_wrapper = util.CursorDebugWrapper -        # Since debugsqlshell monkey-patches django.db.backends.util, we can -        # test it simply by loading it, without executing it. But we have to -        # undo the monkey-patch on exit. -        command_name = 'debugsqlshell' -        app_name = management.get_commands()[command_name] -        management.load_command_class(app_name, command_name) - -    def tearDown(self): -        util.CursorDebugWrapper = self.original_cursor_wrapper -    def test_command(self): -        original_stdout, sys.stdout = sys.stdout, six.StringIO() -        try: -            User.objects.count() -            self.assertIn("SELECT COUNT(*)", sys.stdout.getvalue()) -        finally: -            sys.stdout = original_stdout +if django.VERSION[:2] < (1, 6):     # unittest-style discovery isn't available +    from .commands.test_debugsqlshell import *                          # noqa +    from .panels.test_logger import *                                   # noqa +    from .panels.test_sql import *                                      # noqa +    from .panels.test_template import *                                 # noqa +    from .test_integration import *                                     # noqa +    from .test_utils import *                                           # noqa | 
