1import pytest 2 3from markupsafe import Markup 4 5 6def test_adding(escape): 7 unsafe = '<script type="application/x-some-script">alert("foo");</script>' 8 safe = Markup("<em>username</em>") 9 assert unsafe + safe == str(escape(unsafe)) + str(safe) 10 11 12@pytest.mark.parametrize( 13 ("template", "data", "expect"), 14 ( 15 ("<em>%s</em>", "<bad user>", "<em><bad user></em>"), 16 ( 17 "<em>%(username)s</em>", 18 {"username": "<bad user>"}, 19 "<em><bad user></em>", 20 ), 21 ("%i", 3.14, "3"), 22 ("%.2f", 3.14, "3.14"), 23 ), 24) 25def test_string_interpolation(template, data, expect): 26 assert Markup(template) % data == expect 27 28 29def test_type_behavior(): 30 assert type(Markup("foo") + "bar") is Markup 31 x = Markup("foo") 32 assert x.__html__() is x 33 34 35def test_html_interop(): 36 class Foo: 37 def __html__(self): 38 return "<em>awesome</em>" 39 40 def __str__(self): 41 return "awesome" 42 43 assert Markup(Foo()) == "<em>awesome</em>" 44 result = Markup("<strong>%s</strong>") % Foo() 45 assert result == "<strong><em>awesome</em></strong>" 46 47 48def test_tuple_interpol(): 49 result = Markup("<em>%s:%s</em>") % ("<foo>", "<bar>") 50 expect = Markup("<em><foo>:<bar></em>") 51 assert result == expect 52 53 54def test_dict_interpol(): 55 result = Markup("<em>%(foo)s</em>") % {"foo": "<foo>"} 56 expect = Markup("<em><foo></em>") 57 assert result == expect 58 59 result = Markup("<em>%(foo)s:%(bar)s</em>") % {"foo": "<foo>", "bar": "<bar>"} 60 expect = Markup("<em><foo>:<bar></em>") 61 assert result == expect 62 63 64def test_escaping(escape): 65 assert escape("\"<>&'") == ""<>&'" 66 assert Markup("<em>Foo & Bar</em>").striptags() == "Foo & Bar" 67 68 69def test_unescape(): 70 assert Markup("<test>").unescape() == "<test>" 71 72 result = Markup("jack & tavi are cooler than mike & russ").unescape() 73 expect = "jack & tavi are cooler than mike & russ" 74 assert result == expect 75 76 original = "&foo;" 77 once = Markup(original).unescape() 78 twice = Markup(once).unescape() 79 expect = "&foo;" 80 assert once == expect 81 assert twice == expect 82 83 84def test_format(): 85 result = Markup("<em>{awesome}</em>").format(awesome="<awesome>") 86 assert result == "<em><awesome></em>" 87 88 result = Markup("{0[1][bar]}").format([0, {"bar": "<bar/>"}]) 89 assert result == "<bar/>" 90 91 result = Markup("{0[1][bar]}").format([0, {"bar": Markup("<bar/>")}]) 92 assert result == "<bar/>" 93 94 95def test_formatting_empty(): 96 formatted = Markup("{}").format(0) 97 assert formatted == Markup("0") 98 99 100def test_custom_formatting(): 101 class HasHTMLOnly: 102 def __html__(self): 103 return Markup("<foo>") 104 105 class HasHTMLAndFormat: 106 def __html__(self): 107 return Markup("<foo>") 108 109 def __html_format__(self, spec): 110 return Markup("<FORMAT>") 111 112 assert Markup("{0}").format(HasHTMLOnly()) == Markup("<foo>") 113 assert Markup("{0}").format(HasHTMLAndFormat()) == Markup("<FORMAT>") 114 115 116def test_complex_custom_formatting(): 117 class User: 118 def __init__(self, id, username): 119 self.id = id 120 self.username = username 121 122 def __html_format__(self, format_spec): 123 if format_spec == "link": 124 return Markup('<a href="/user/{0}">{1}</a>').format( 125 self.id, self.__html__() 126 ) 127 elif format_spec: 128 raise ValueError("Invalid format spec") 129 130 return self.__html__() 131 132 def __html__(self): 133 return Markup("<span class=user>{0}</span>").format(self.username) 134 135 user = User(1, "foo") 136 result = Markup("<p>User: {0:link}").format(user) 137 expect = Markup('<p>User: <a href="/user/1"><span class=user>foo</span></a>') 138 assert result == expect 139 140 141def test_formatting_with_objects(): 142 class Stringable: 143 def __str__(self): 144 return "строка" 145 146 assert Markup("{s}").format(s=Stringable()) == Markup("строка") 147 148 149def test_escape_silent(escape, escape_silent): 150 assert escape_silent(None) == Markup() 151 assert escape(None) == Markup(None) 152 assert escape_silent("<foo>") == Markup("<foo>") 153 154 155def test_splitting(): 156 expect = [Markup("a"), Markup("b")] 157 assert Markup("a b").split() == expect 158 assert Markup("a b").rsplit() == expect 159 assert Markup("a\nb").splitlines() == expect 160 161 162def test_mul(): 163 assert Markup("a") * 3 == Markup("aaa") 164 165 166def test_escape_return_type(escape): 167 assert isinstance(escape("a"), Markup) 168 assert isinstance(escape(Markup("a")), Markup) 169 170 class Foo: 171 def __html__(self): 172 return "<strong>Foo</strong>" 173 174 assert isinstance(escape(Foo()), Markup) 175 176 177def test_soft_str(soft_str): 178 assert type(soft_str("")) is str 179 assert type(soft_str(Markup())) is Markup 180 assert type(soft_str(15)) is str 181 182 183def test_soft_unicode_deprecated(soft_unicode): 184 with pytest.warns(DeprecationWarning): 185 assert type(soft_unicode(Markup())) is Markup 186