summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoritz Sichert <moritz.sichert@googlemail.com>2015-06-10 22:57:51 +0200
committerTim Graham <timograham@gmail.com>2015-06-12 17:44:54 -0400
commit296919e7a58c21ff0325de8c747dc2dc8960104e (patch)
tree085278b68130a6127b7f02200ebb3c742d05317a
parente93e0c03b28137e26f9249e0b7c458b0d667a74e (diff)
Fixed #24965 -- Made LiveServerTestCase.live_server_url accessible from class
-rw-r--r--django/utils/decorators.py12
-rw-r--r--docs/topics/testing/tools.txt6
-rw-r--r--tests/servers/tests.py11
-rw-r--r--tests/utils_tests/test_decorators.py40
4 files changed, 64 insertions, 5 deletions
diff --git a/django/utils/decorators.py b/django/utils/decorators.py
index 10ad1ce506..1ea12b32d2 100644
--- a/django/utils/decorators.py
+++ b/django/utils/decorators.py
@@ -144,3 +144,15 @@ if ContextDecorator is None:
with self:
return func(*args, **kwargs)
return inner
+
+
+class classproperty(object):
+ def __init__(self, method=None):
+ self.fget = method
+
+ def __get__(self, instance, owner):
+ return self.fget(owner)
+
+ def getter(self, method):
+ self.fget = method
+ return self
diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt
index e2ad15d5b5..7aaeff97af 100644
--- a/docs/topics/testing/tools.txt
+++ b/docs/topics/testing/tools.txt
@@ -789,6 +789,12 @@ via the :djadminopt:`--liveserver` option, for example:
$ ./manage.py test --liveserver=localhost:8082
+.. versionchanged:: 1.9
+
+ In older versions ``live_server_url`` could only be accessed from an
+ instance. It now is a class property and can be accessed from class methods
+ like ``setUpClass()``.
+
Another way of changing the default server address is by setting the
`DJANGO_LIVE_TEST_SERVER_ADDRESS` environment variable somewhere in your
code (for example, in a :ref:`custom test runner<topics-testing-test_runner>`)::
diff --git a/tests/servers/tests.py b/tests/servers/tests.py
index e84b8788c0..3ba80cc23d 100644
--- a/tests/servers/tests.py
+++ b/tests/servers/tests.py
@@ -11,6 +11,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.test import LiveServerTestCase, override_settings
from django.utils._os import upath
from django.utils.http import urlencode
+from django.utils.six import text_type
from django.utils.six.moves.urllib.error import HTTPError
from django.utils.six.moves.urllib.request import urlopen
@@ -71,6 +72,9 @@ class LiveServerAddress(LiveServerBase):
else:
del os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS']
+ # put it in a list to prevent descriptor lookups in test
+ cls.live_server_url_test = [cls.live_server_url]
+
@classmethod
def tearDownClass(cls):
# skip it, as setUpClass doesn't call its parent either
@@ -87,10 +91,9 @@ class LiveServerAddress(LiveServerBase):
finally:
super(LiveServerAddress, cls).tearDownClass()
- def test_test_test(self):
- # Intentionally empty method so that the test is picked up by the
- # test runner and the overridden setUpClass() method is executed.
- pass
+ def test_live_server_url_is_class_property(self):
+ self.assertIsInstance(self.live_server_url_test[0], text_type)
+ self.assertEqual(self.live_server_url_test[0], self.live_server_url)
class LiveServerViews(LiveServerBase):
diff --git a/tests/utils_tests/test_decorators.py b/tests/utils_tests/test_decorators.py
index 10531937ad..6135eb1994 100644
--- a/tests/utils_tests/test_decorators.py
+++ b/tests/utils_tests/test_decorators.py
@@ -2,7 +2,7 @@ from django.http import HttpResponse
from django.template import engines
from django.template.response import TemplateResponse
from django.test import RequestFactory, SimpleTestCase
-from django.utils.decorators import decorator_from_middleware
+from django.utils.decorators import classproperty, decorator_from_middleware
class ProcessViewMiddleware(object):
@@ -107,3 +107,41 @@ class DecoratorFromMiddlewareTests(SimpleTestCase):
self.assertTrue(getattr(request, 'process_response_reached', False))
# Check that process_response saw the rendered content
self.assertEqual(request.process_response_content, b"Hello world")
+
+
+class ClassPropertyTest(SimpleTestCase):
+ def test_getter(self):
+ class Foo(object):
+ foo_attr = 123
+
+ def __init__(self):
+ self.foo_attr = 456
+
+ @classproperty
+ def foo(cls):
+ return cls.foo_attr
+
+ class Bar(object):
+ bar = classproperty()
+
+ @bar.getter
+ def bar(cls):
+ return 123
+
+ self.assertEqual(Foo.foo, 123)
+ self.assertEqual(Foo().foo, 123)
+ self.assertEqual(Bar.bar, 123)
+ self.assertEqual(Bar().bar, 123)
+
+ def test_override_getter(self):
+ class Foo(object):
+ @classproperty
+ def foo(cls):
+ return 123
+
+ @foo.getter
+ def foo(cls):
+ return 456
+
+ self.assertEqual(Foo.foo, 456)
+ self.assertEqual(Foo().foo, 456)