| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- # coding: utf-8
- from io import StringIO
- import re
- import sys
- import datetime
- import unittest
- import tornado.escape
- from tornado.escape import utf8
- from tornado.util import (
- raise_exc_info,
- Configurable,
- exec_in,
- ArgReplacer,
- timedelta_to_seconds,
- import_object,
- re_unescape,
- is_finalizing,
- )
- import typing
- from typing import cast
- if typing.TYPE_CHECKING:
- from typing import Dict, Any # noqa: F401
- class RaiseExcInfoTest(unittest.TestCase):
- def test_two_arg_exception(self):
- # This test would fail on python 3 if raise_exc_info were simply
- # a three-argument raise statement, because TwoArgException
- # doesn't have a "copy constructor"
- class TwoArgException(Exception):
- def __init__(self, a, b):
- super(TwoArgException, self).__init__()
- self.a, self.b = a, b
- try:
- raise TwoArgException(1, 2)
- except TwoArgException:
- exc_info = sys.exc_info()
- try:
- raise_exc_info(exc_info)
- self.fail("didn't get expected exception")
- except TwoArgException as e:
- self.assertIs(e, exc_info[1])
- class TestConfigurable(Configurable):
- @classmethod
- def configurable_base(cls):
- return TestConfigurable
- @classmethod
- def configurable_default(cls):
- return TestConfig1
- class TestConfig1(TestConfigurable):
- def initialize(self, pos_arg=None, a=None):
- self.a = a
- self.pos_arg = pos_arg
- class TestConfig2(TestConfigurable):
- def initialize(self, pos_arg=None, b=None):
- self.b = b
- self.pos_arg = pos_arg
- class TestConfig3(TestConfigurable):
- # TestConfig3 is a configuration option that is itself configurable.
- @classmethod
- def configurable_base(cls):
- return TestConfig3
- @classmethod
- def configurable_default(cls):
- return TestConfig3A
- class TestConfig3A(TestConfig3):
- def initialize(self, a=None):
- self.a = a
- class TestConfig3B(TestConfig3):
- def initialize(self, b=None):
- self.b = b
- class ConfigurableTest(unittest.TestCase):
- def setUp(self):
- self.saved = TestConfigurable._save_configuration()
- self.saved3 = TestConfig3._save_configuration()
- def tearDown(self):
- TestConfigurable._restore_configuration(self.saved)
- TestConfig3._restore_configuration(self.saved3)
- def checkSubclasses(self):
- # no matter how the class is configured, it should always be
- # possible to instantiate the subclasses directly
- self.assertIsInstance(TestConfig1(), TestConfig1)
- self.assertIsInstance(TestConfig2(), TestConfig2)
- obj = TestConfig1(a=1)
- self.assertEqual(obj.a, 1)
- obj2 = TestConfig2(b=2)
- self.assertEqual(obj2.b, 2)
- def test_default(self):
- # In these tests we combine a typing.cast to satisfy mypy with
- # a runtime type-assertion. Without the cast, mypy would only
- # let us access attributes of the base class.
- obj = cast(TestConfig1, TestConfigurable())
- self.assertIsInstance(obj, TestConfig1)
- self.assertIs(obj.a, None)
- obj = cast(TestConfig1, TestConfigurable(a=1))
- self.assertIsInstance(obj, TestConfig1)
- self.assertEqual(obj.a, 1)
- self.checkSubclasses()
- def test_config_class(self):
- TestConfigurable.configure(TestConfig2)
- obj = cast(TestConfig2, TestConfigurable())
- self.assertIsInstance(obj, TestConfig2)
- self.assertIs(obj.b, None)
- obj = cast(TestConfig2, TestConfigurable(b=2))
- self.assertIsInstance(obj, TestConfig2)
- self.assertEqual(obj.b, 2)
- self.checkSubclasses()
- def test_config_str(self):
- TestConfigurable.configure("tornado.test.util_test.TestConfig2")
- obj = cast(TestConfig2, TestConfigurable())
- self.assertIsInstance(obj, TestConfig2)
- self.assertIs(obj.b, None)
- obj = cast(TestConfig2, TestConfigurable(b=2))
- self.assertIsInstance(obj, TestConfig2)
- self.assertEqual(obj.b, 2)
- self.checkSubclasses()
- def test_config_args(self):
- TestConfigurable.configure(None, a=3)
- obj = cast(TestConfig1, TestConfigurable())
- self.assertIsInstance(obj, TestConfig1)
- self.assertEqual(obj.a, 3)
- obj = cast(TestConfig1, TestConfigurable(42, a=4))
- self.assertIsInstance(obj, TestConfig1)
- self.assertEqual(obj.a, 4)
- self.assertEqual(obj.pos_arg, 42)
- self.checkSubclasses()
- # args bound in configure don't apply when using the subclass directly
- obj = TestConfig1()
- self.assertIs(obj.a, None)
- def test_config_class_args(self):
- TestConfigurable.configure(TestConfig2, b=5)
- obj = cast(TestConfig2, TestConfigurable())
- self.assertIsInstance(obj, TestConfig2)
- self.assertEqual(obj.b, 5)
- obj = cast(TestConfig2, TestConfigurable(42, b=6))
- self.assertIsInstance(obj, TestConfig2)
- self.assertEqual(obj.b, 6)
- self.assertEqual(obj.pos_arg, 42)
- self.checkSubclasses()
- # args bound in configure don't apply when using the subclass directly
- obj = TestConfig2()
- self.assertIs(obj.b, None)
- def test_config_multi_level(self):
- TestConfigurable.configure(TestConfig3, a=1)
- obj = cast(TestConfig3A, TestConfigurable())
- self.assertIsInstance(obj, TestConfig3A)
- self.assertEqual(obj.a, 1)
- TestConfigurable.configure(TestConfig3)
- TestConfig3.configure(TestConfig3B, b=2)
- obj2 = cast(TestConfig3B, TestConfigurable())
- self.assertIsInstance(obj2, TestConfig3B)
- self.assertEqual(obj2.b, 2)
- def test_config_inner_level(self):
- # The inner level can be used even when the outer level
- # doesn't point to it.
- obj = TestConfig3()
- self.assertIsInstance(obj, TestConfig3A)
- TestConfig3.configure(TestConfig3B)
- obj = TestConfig3()
- self.assertIsInstance(obj, TestConfig3B)
- # Configuring the base doesn't configure the inner.
- obj2 = TestConfigurable()
- self.assertIsInstance(obj2, TestConfig1)
- TestConfigurable.configure(TestConfig2)
- obj3 = TestConfigurable()
- self.assertIsInstance(obj3, TestConfig2)
- obj = TestConfig3()
- self.assertIsInstance(obj, TestConfig3B)
- class UnicodeLiteralTest(unittest.TestCase):
- def test_unicode_escapes(self):
- self.assertEqual(utf8(u"\u00e9"), b"\xc3\xa9")
- class ExecInTest(unittest.TestCase):
- # TODO(bdarnell): make a version of this test for one of the new
- # future imports available in python 3.
- @unittest.skip("no testable future imports")
- def test_no_inherit_future(self):
- # This file has from __future__ import print_function...
- f = StringIO()
- print("hello", file=f)
- # ...but the template doesn't
- exec_in('print >> f, "world"', dict(f=f))
- self.assertEqual(f.getvalue(), "hello\nworld\n")
- class ArgReplacerTest(unittest.TestCase):
- def setUp(self):
- def function(x, y, callback=None, z=None):
- pass
- self.replacer = ArgReplacer(function, "callback")
- def test_omitted(self):
- args = (1, 2)
- kwargs = dict() # type: Dict[str, Any]
- self.assertIs(self.replacer.get_old_value(args, kwargs), None)
- self.assertEqual(
- self.replacer.replace("new", args, kwargs),
- (None, (1, 2), dict(callback="new")),
- )
- def test_position(self):
- args = (1, 2, "old", 3)
- kwargs = dict() # type: Dict[str, Any]
- self.assertEqual(self.replacer.get_old_value(args, kwargs), "old")
- self.assertEqual(
- self.replacer.replace("new", args, kwargs),
- ("old", [1, 2, "new", 3], dict()),
- )
- def test_keyword(self):
- args = (1,)
- kwargs = dict(y=2, callback="old", z=3)
- self.assertEqual(self.replacer.get_old_value(args, kwargs), "old")
- self.assertEqual(
- self.replacer.replace("new", args, kwargs),
- ("old", (1,), dict(y=2, callback="new", z=3)),
- )
- class TimedeltaToSecondsTest(unittest.TestCase):
- def test_timedelta_to_seconds(self):
- time_delta = datetime.timedelta(hours=1)
- self.assertEqual(timedelta_to_seconds(time_delta), 3600.0)
- class ImportObjectTest(unittest.TestCase):
- def test_import_member(self):
- self.assertIs(import_object("tornado.escape.utf8"), utf8)
- def test_import_member_unicode(self):
- self.assertIs(import_object(u"tornado.escape.utf8"), utf8)
- def test_import_module(self):
- self.assertIs(import_object("tornado.escape"), tornado.escape)
- def test_import_module_unicode(self):
- # The internal implementation of __import__ differs depending on
- # whether the thing being imported is a module or not.
- # This variant requires a byte string in python 2.
- self.assertIs(import_object(u"tornado.escape"), tornado.escape)
- class ReUnescapeTest(unittest.TestCase):
- def test_re_unescape(self):
- test_strings = ("/favicon.ico", "index.html", "Hello, World!", "!$@#%;")
- for string in test_strings:
- self.assertEqual(string, re_unescape(re.escape(string)))
- def test_re_unescape_raises_error_on_invalid_input(self):
- with self.assertRaises(ValueError):
- re_unescape("\\d")
- with self.assertRaises(ValueError):
- re_unescape("\\b")
- with self.assertRaises(ValueError):
- re_unescape("\\Z")
- class IsFinalizingTest(unittest.TestCase):
- def test_basic(self):
- self.assertFalse(is_finalizing())
|