summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lord <davidism@gmail.com>2018-05-02 14:54:35 -0700
committerDavid Lord <davidism@gmail.com>2018-05-02 14:54:35 -0700
commit4d4fa0dd1ae28599c1dde5658cb3dcd7b8f75c71 (patch)
tree0d70bb86caad5b08d7e10357bf11ec5c9ea33fdb
parent0e8bdc2cc40e13565a2510fa9639df25c1aba5e0 (diff)
downloadmarkupsafe-pytest.tar.gz
stop using unittestpytest
-rw-r--r--MANIFEST.in3
-rw-r--r--setup.cfg2
-rw-r--r--tests.py216
-rw-r--r--tests/test_leak.py29
-rw-r--r--tests/test_markupsafe.py191
5 files changed, 223 insertions, 218 deletions
diff --git a/MANIFEST.in b/MANIFEST.in
index 52fdb6f..7e6029d 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,2 +1,3 @@
-include AUTHORS CHANGES.rst LICENSE tests.py
+include AUTHORS.rst CHANGES.rst LICENSE.rst tox.ini
recursive-include markupsafe *.c
+graft tests
diff --git a/setup.cfg b/setup.cfg
index 6ae8437..3c5e533 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -8,7 +8,7 @@ tag_build = dev
release = egg_info -Db ''
[tool:pytest]
-testpaths = tests.py
+testpaths = tests
[coverage:run]
branch = True
diff --git a/tests.py b/tests.py
deleted file mode 100644
index ba5d30c..0000000
--- a/tests.py
+++ /dev/null
@@ -1,216 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-import gc
-import sys
-import unittest
-from markupsafe import Markup, escape, escape_silent
-from markupsafe._compat import text_type, PY2
-
-
-class MarkupTestCase(unittest.TestCase):
-
- def test_adding(self):
- # adding two strings should escape the unsafe one
- unsafe = '<script type="application/x-some-script">alert("foo");</script>'
- safe = Markup('<em>username</em>')
- assert unsafe + safe == text_type(escape(unsafe)) + text_type(safe)
-
- def test_string_interpolation(self):
- # string interpolations are safe to use too
- assert Markup('<em>%s</em>') % '<bad user>' == \
- '<em>&lt;bad user&gt;</em>'
- assert Markup('<em>%(username)s</em>') % {
- 'username': '<bad user>'
- } == '<em>&lt;bad user&gt;</em>'
-
- assert Markup('%i') % 3.14 == '3'
- assert Markup('%.2f') % 3.14 == '3.14'
-
- def test_type_behavior(self):
- # an escaped object is markup too
- assert type(Markup('foo') + 'bar') is Markup
-
- # and it implements __html__ by returning itself
- x = Markup("foo")
- assert x.__html__() is x
-
- def test_html_interop(self):
- # it also knows how to treat __html__ objects
- class Foo(object):
- def __html__(self):
- return '<em>awesome</em>'
- def __unicode__(self):
- return 'awesome'
- __str__ = __unicode__
- assert Markup(Foo()) == '<em>awesome</em>'
- assert Markup('<strong>%s</strong>') % Foo() == \
- '<strong><em>awesome</em></strong>'
-
- def test_tuple_interpol(self):
- self.assertEqual(Markup('<em>%s:%s</em>') % (
- '<foo>',
- '<bar>',
- ), Markup(u'<em>&lt;foo&gt;:&lt;bar&gt;</em>'))
-
- def test_dict_interpol(self):
- self.assertEqual(Markup('<em>%(foo)s</em>') % {
- 'foo': '<foo>',
- }, Markup(u'<em>&lt;foo&gt;</em>'))
- self.assertEqual(Markup('<em>%(foo)s:%(bar)s</em>') % {
- 'foo': '<foo>',
- 'bar': '<bar>',
- }, Markup(u'<em>&lt;foo&gt;:&lt;bar&gt;</em>'))
-
- def test_escaping(self):
- # escaping
- assert escape('"<>&\'') == '&#34;&lt;&gt;&amp;&#39;'
- assert Markup("<em>Foo &amp; Bar</em>").striptags() == "Foo & Bar"
-
- def test_unescape(self):
- assert Markup("&lt;test&gt;").unescape() == "<test>"
- assert "jack & tavi are cooler than mike & russ" == \
- Markup("jack & tavi are cooler than mike &amp; russ").unescape(), \
- Markup("jack & tavi are cooler than mike &amp; russ").unescape()
-
- # Test that unescape is idempotent
- original = '&foo&#x3b;'
- once = Markup(original).unescape()
- twice = Markup(once).unescape()
- expected = "&foo;"
- assert expected == once == twice, (once, twice)
-
- def test_formatting(self):
- for actual, expected in (
- (Markup('%i') % 3.14, '3'),
- (Markup('%.2f') % 3.14159, '3.14'),
- (Markup('%s %s %s') % ('<', 123, '>'), '&lt; 123 &gt;'),
- (Markup('<em>{awesome}</em>').format(awesome='<awesome>'),
- '<em>&lt;awesome&gt;</em>'),
- (Markup('{0[1][bar]}').format([0, {'bar': '<bar/>'}]),
- '&lt;bar/&gt;'),
- (Markup('{0[1][bar]}').format([0, {'bar': Markup('<bar/>')}]),
- '<bar/>')):
- assert actual == expected, "%r should be %r!" % (actual, expected)
-
- # This is new in 2.7
- if sys.version_info >= (2, 7):
- def test_formatting_empty(self):
- formatted = Markup('{}').format(0)
- assert formatted == Markup('0')
-
- def test_custom_formatting(self):
- class HasHTMLOnly(object):
- def __html__(self):
- return Markup('<foo>')
-
- class HasHTMLAndFormat(object):
- def __html__(self):
- return Markup('<foo>')
- def __html_format__(self, spec):
- return Markup('<FORMAT>')
-
- assert Markup('{0}').format(HasHTMLOnly()) == Markup('<foo>')
- assert Markup('{0}').format(HasHTMLAndFormat()) == Markup('<FORMAT>')
-
- def test_complex_custom_formatting(self):
- class User(object):
- def __init__(self, id, username):
- self.id = id
- self.username = username
- def __html_format__(self, format_spec):
- if format_spec == 'link':
- return Markup('<a href="/user/{0}">{1}</a>').format(
- self.id,
- self.__html__(),
- )
- elif format_spec:
- raise ValueError('Invalid format spec')
- return self.__html__()
- def __html__(self):
- return Markup('<span class=user>{0}</span>').format(self.username)
-
- user = User(1, 'foo')
- assert Markup('<p>User: {0:link}').format(user) == \
- Markup('<p>User: <a href="/user/1"><span class=user>foo</span></a>')
-
- def test_formatting_with_objects(self):
- class Stringable(object):
- def __unicode__(self):
- return u'строка'
- if PY2:
- def __str__(self):
- return 'some other value'
- else:
- __str__ = __unicode__
-
- assert Markup('{s}').format(s=Stringable()) == \
- Markup(u'строка')
-
- def test_all_set(self):
- import markupsafe as markup
- for item in markup.__all__:
- getattr(markup, item)
-
- def test_escape_silent(self):
- assert escape_silent(None) == Markup()
- assert escape(None) == Markup(None)
- assert escape_silent('<foo>') == Markup(u'&lt;foo&gt;')
-
- def test_splitting(self):
- self.assertEqual(Markup('a b').split(), [
- Markup('a'),
- Markup('b')
- ])
- self.assertEqual(Markup('a b').rsplit(), [
- Markup('a'),
- Markup('b')
- ])
- self.assertEqual(Markup('a\nb').splitlines(), [
- Markup('a'),
- Markup('b')
- ])
-
- def test_mul(self):
- self.assertEqual(Markup('a') * 3, Markup('aaa'))
-
- def test_escape_return_type(self):
- self.assertTrue(isinstance(escape('a'), Markup))
- self.assertTrue(isinstance(escape(Markup('a')), Markup))
- class Foo:
- def __html__(self):
- return '<strong>Foo</strong>'
- self.assertTrue(isinstance(escape(Foo()), Markup))
-
-
-class MarkupLeakTestCase(unittest.TestCase):
-
- def test_markup_leaks(self):
- counts = set()
- for count in range(20):
- for item in range(1000):
- escape("foo")
- escape("<foo>")
- escape(u"foo")
- escape(u"<foo>")
- if hasattr(sys, 'pypy_version_info'):
- gc.collect()
- counts.add(len(gc.get_objects()))
- assert len(counts) == 1, 'ouch, c extension seems to ' \
- 'leak objects, got: ' + str(len(counts))
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(MarkupTestCase))
-
- # this test only tests the c extension
- if not hasattr(escape, 'func_code'):
- suite.addTest(unittest.makeSuite(MarkupLeakTestCase))
-
- return suite
-
-
-if __name__ == '__main__':
- unittest.main(defaultTest='suite')
-
-# vim:sts=4:sw=4:et:
diff --git a/tests/test_leak.py b/tests/test_leak.py
new file mode 100644
index 0000000..964341a
--- /dev/null
+++ b/tests/test_leak.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+import gc
+import sys
+
+import pytest
+
+from markupsafe import escape
+
+
+@pytest.mark.skipif(
+ hasattr(escape, 'func_code'),
+ reason='only test memory leak with speedups'
+)
+def test_markup_leaks():
+ counts = set()
+
+ for count in range(20):
+ for item in range(1000):
+ escape("foo")
+ escape("<foo>")
+ escape(u"foo")
+ escape(u"<foo>")
+
+ if hasattr(sys, 'pypy_version_info'):
+ gc.collect()
+
+ counts.add(len(gc.get_objects()))
+
+ assert len(counts) == 1
diff --git a/tests/test_markupsafe.py b/tests/test_markupsafe.py
new file mode 100644
index 0000000..ffbf8a3
--- /dev/null
+++ b/tests/test_markupsafe.py
@@ -0,0 +1,191 @@
+# -*- coding: utf-8 -*-
+import pytest
+
+from markupsafe import Markup, escape, escape_silent
+from markupsafe._compat import PY2, text_type
+
+
+def test_adding():
+ unsafe = '<script type="application/x-some-script">alert("foo");</script>'
+ safe = Markup('<em>username</em>')
+ assert unsafe + safe == text_type(escape(unsafe)) + text_type(safe)
+
+
+@pytest.mark.parametrize(('template', 'data', 'expect'), (
+ ('<em>%s</em>', '<bad user>', '<em>&lt;bad user&gt;</em>'),
+ (
+ '<em>%(username)s</em>',
+ {'username': '<bad user>'},
+ '<em>&lt;bad user&gt;</em>'
+ ),
+ ('%i', 3.14, '3'),
+ ('%.2f', 3.14, '3.14'),
+))
+def test_string_interpolation(template, data, expect):
+ assert Markup(template) % data == expect
+
+
+def test_type_behavior():
+ assert type(Markup('foo') + 'bar') is Markup
+ x = Markup("foo")
+ assert x.__html__() is x
+
+
+def test_html_interop():
+ class Foo(object):
+ def __html__(self):
+ return '<em>awesome</em>'
+
+ def __unicode__(self):
+ return 'awesome'
+
+ __str__ = __unicode__
+
+ assert Markup(Foo()) == '<em>awesome</em>'
+ result = Markup('<strong>%s</strong>') % Foo()
+ assert result == '<strong><em>awesome</em></strong>'
+
+
+def test_tuple_interpol():
+ result = Markup('<em>%s:%s</em>') % ('<foo>', '<bar>')
+ expect = Markup(u'<em>&lt;foo&gt;:&lt;bar&gt;</em>')
+ assert result == expect
+
+
+def test_dict_interpol():
+ result = Markup('<em>%(foo)s</em>') % {'foo': '<foo>'}
+ expect = Markup(u'<em>&lt;foo&gt;</em>')
+ assert result == expect
+
+ result = Markup('<em>%(foo)s:%(bar)s</em>') % {
+ 'foo': '<foo>',
+ 'bar': '<bar>',
+ }
+ expect = Markup(u'<em>&lt;foo&gt;:&lt;bar&gt;</em>')
+ assert result == expect
+
+
+def test_escaping():
+ assert escape('"<>&\'') == '&#34;&lt;&gt;&amp;&#39;'
+ assert Markup("<em>Foo &amp; Bar</em>").striptags() == "Foo & Bar"
+
+
+def test_unescape():
+ assert Markup("&lt;test&gt;").unescape() == "<test>"
+
+ result = Markup("jack & tavi are cooler than mike &amp; russ").unescape()
+ expect = "jack & tavi are cooler than mike & russ"
+ assert result == expect
+
+ original = '&foo&#x3b;'
+ once = Markup(original).unescape()
+ twice = Markup(once).unescape()
+ expect = "&foo;"
+ assert once == expect
+ assert twice == expect
+
+
+def test_format():
+ result = Markup('<em>{awesome}</em>').format(awesome='<awesome>')
+ assert result == '<em>&lt;awesome&gt;</em>'
+
+ result = Markup('{0[1][bar]}').format([0, {'bar': '<bar/>'}])
+ assert result == '&lt;bar/&gt;'
+
+ result = Markup('{0[1][bar]}').format([0, {'bar': Markup('<bar/>')}])
+ assert result == '<bar/>'
+
+
+def test_formatting_empty():
+ formatted = Markup('{}').format(0)
+ assert formatted == Markup('0')
+
+
+def test_custom_formatting():
+ class HasHTMLOnly(object):
+ def __html__(self):
+ return Markup('<foo>')
+
+ class HasHTMLAndFormat(object):
+ def __html__(self):
+ return Markup('<foo>')
+
+ def __html_format__(self, spec):
+ return Markup('<FORMAT>')
+
+ assert Markup('{0}').format(HasHTMLOnly()) == Markup('<foo>')
+ assert Markup('{0}').format(HasHTMLAndFormat()) == Markup('<FORMAT>')
+
+
+def test_complex_custom_formatting():
+ class User(object):
+ def __init__(self, id, username):
+ self.id = id
+ self.username = username
+
+ def __html_format__(self, format_spec):
+ if format_spec == 'link':
+ return Markup('<a href="/user/{0}">{1}</a>').format(
+ self.id, self.__html__())
+ elif format_spec:
+ raise ValueError('Invalid format spec')
+
+ return self.__html__()
+
+ def __html__(self):
+ return Markup('<span class=user>{0}</span>').format(self.username)
+
+ user = User(1, 'foo')
+ result = Markup('<p>User: {0:link}').format(user)
+ expect = Markup(
+ '<p>User: <a href="/user/1"><span class=user>foo</span></a>')
+ assert result == expect
+
+
+def test_formatting_with_objects():
+ class Stringable(object):
+ def __unicode__(self):
+ return u'строка'
+
+ if PY2:
+ def __str__(self):
+ return 'some other value'
+ else:
+ __str__ = __unicode__
+
+ assert Markup('{s}').format(s=Stringable()) == Markup(u'строка')
+
+
+def test_all_set():
+ import markupsafe as markup
+
+ for item in markup.__all__:
+ getattr(markup, item)
+
+
+def test_escape_silent():
+ assert escape_silent(None) == Markup()
+ assert escape(None) == Markup(None)
+ assert escape_silent('<foo>') == Markup(u'&lt;foo&gt;')
+
+
+def test_splitting():
+ expect = [Markup('a'), Markup('b')]
+ assert Markup('a b').split() == expect
+ assert Markup('a b').rsplit() == expect
+ assert Markup('a\nb').splitlines() == expect
+
+
+def test_mul():
+ assert Markup('a') * 3 == Markup('aaa')
+
+
+def test_escape_return_type():
+ assert isinstance(escape('a'), Markup)
+ assert isinstance(escape(Markup('a')), Markup)
+
+ class Foo:
+ def __html__(self):
+ return '<strong>Foo</strong>'
+
+ assert isinstance(escape(Foo()), Markup)