1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
import cgi
from webob.util import html_escape
from webob.multidict import MultiDict
from nose.tools import eq_ as eq, assert_raises
from webob.compat import (
text_,
PY3
)
def test_html_escape():
if PY3:
EXPECTED_LT = 'expected a '<'.'
else:
EXPECTED_LT = "expected a '<'."
for v, s in [
# unsafe chars
('these chars: < > & "', 'these chars: < > & "'),
(' ', ' '),
('è', '&egrave;'),
# The apostrophe is *not* escaped, which some might consider to be
# a serious bug (see, e.g. http://www.cvedetails.com/cve/CVE-2010-2480/)
(text_('the majestic m\xf8ose'), 'the majestic møose'),
#("'", "'")
# 8-bit strings are passed through
(text_('\xe9'), 'é'),
## (text_(b'the majestic m\xf8ose').encode('utf-8'),
## 'the majestic m\xc3\xb8ose'),
# ``None`` is treated specially, and returns the empty string.
(None, ''),
# Objects that define a ``__html__`` method handle their own escaping
(t_esc_HTML(), '<div>hello</div>'),
# Things that are not strings are converted to strings and then escaped
(42, '42'),
(Exception("expected a '<'."), EXPECTED_LT),
# If an object implements both ``__str__`` and ``__unicode__``, the latter
# is preferred
(t_esc_SuperMoose(), 'møose'),
(t_esc_Unicode(), 'é'),
(t_esc_UnsafeAttrs(), '<UnsafeAttrs>'),
]:
eq(html_escape(v), s)
class t_esc_HTML(object):
def __html__(self):
return '<div>hello</div>'
class t_esc_Unicode(object):
def __unicode__(self):
return text_(b'\xe9')
class t_esc_UnsafeAttrs(object):
attr = 'value'
def __getattr__(self, k):
return self.attr
def __repr__(self):
return '<UnsafeAttrs>'
class t_esc_SuperMoose(object):
def __str__(self):
return text_(b'm\xf8ose').encode('utf-8')
def __unicode__(self):
return text_(b'm\xf8ose')
def test_multidict():
d = MultiDict(a=1, b=2)
eq(d['a'], 1)
eq(d.getall('c'), [])
d.add('a', 2)
eq(d['a'], 2)
eq(d.getall('a'), [1, 2])
d['b'] = 4
eq(d.getall('b'), [4])
eq(list(d.keys()), ['a', 'a', 'b'])
eq(list(d.items()), [('a', 1), ('a', 2), ('b', 4)])
eq(d.mixed(), {'a': [1, 2], 'b': 4})
# test getone
# KeyError: "Multiple values match 'a': [1, 2]"
assert_raises(KeyError, d.getone, 'a')
eq(d.getone('b'), 4)
# KeyError: "Key not found: 'g'"
assert_raises(KeyError, d.getone, 'g')
eq(d.dict_of_lists(), {'a': [1, 2], 'b': [4]})
assert 'b' in d
assert 'e' not in d
d.clear()
assert 'b' not in d
d['a'] = 4
d.add('a', 5)
e = d.copy()
assert 'a' in e
e.clear()
e['f'] = 42
d.update(e)
eq(d, MultiDict([('a', 4), ('a', 5), ('f', 42)]))
f = d.pop('a')
eq(f, 4)
eq(d['a'], 5)
eq(d.pop('g', 42), 42)
assert_raises(KeyError, d.pop, 'n')
# TypeError: pop expected at most 2 arguments, got 3
assert_raises(TypeError, d.pop, 4, 2, 3)
d.setdefault('g', []).append(4)
eq(d, MultiDict([('a', 5), ('f', 42), ('g', [4])]))
def test_multidict_init():
d = MultiDict([('a', 'b')], c=2)
eq(repr(d), "MultiDict([('a', 'b'), ('c', 2)])")
eq(d, MultiDict([('a', 'b')], c=2))
# TypeError: MultiDict can only be called with one positional argument
assert_raises(TypeError, MultiDict, 1, 2, 3)
# TypeError: MultiDict.view_list(obj) takes only actual list objects, not None
assert_raises(TypeError, MultiDict.view_list, None)
|