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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
|
# -*- coding: utf-8 -*-
"""
Test suite for the util module
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2006-2017 by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import re
import unittest
from pygments import util, console
class FakeLexer(object):
def analyse(text):
return text
analyse = util.make_analysator(analyse)
class UtilTest(unittest.TestCase):
def test_getoptions(self):
raises = self.assertRaises
equals = self.assertEqual
equals(util.get_bool_opt({}, 'a', True), True)
equals(util.get_bool_opt({}, 'a', 1), True)
equals(util.get_bool_opt({}, 'a', 'true'), True)
equals(util.get_bool_opt({}, 'a', 'no'), False)
raises(util.OptionError, util.get_bool_opt, {}, 'a', [])
raises(util.OptionError, util.get_bool_opt, {}, 'a', 'foo')
equals(util.get_int_opt({}, 'a', 1), 1)
raises(util.OptionError, util.get_int_opt, {}, 'a', [])
raises(util.OptionError, util.get_int_opt, {}, 'a', 'bar')
equals(util.get_list_opt({}, 'a', [1]), [1])
equals(util.get_list_opt({}, 'a', '1 2'), ['1', '2'])
raises(util.OptionError, util.get_list_opt, {}, 'a', 1)
equals(util.get_choice_opt({}, 'a', ['foo', 'bar'], 'bar'), 'bar')
equals(util.get_choice_opt({}, 'a', ['foo', 'bar'], 'Bar', True), 'bar')
raises(util.OptionError, util.get_choice_opt, {}, 'a',
['foo', 'bar'], 'baz')
def test_docstring_headline(self):
def f1():
"""
docstring headline
other text
"""
def f2():
"""
docstring
headline
other text
"""
def f3():
pass
self.assertEqual(util.docstring_headline(f1), 'docstring headline')
self.assertEqual(util.docstring_headline(f2), 'docstring headline')
self.assertEqual(util.docstring_headline(f3), '')
def test_analysator_returns_float(self):
# If an analysator wrapped by make_analysator returns a floating point
# number, then that number will be returned by the wrapper.
self.assertEqual(FakeLexer.analyse('0.5'), 0.5)
def test_analysator_returns_boolean(self):
# If an analysator wrapped by make_analysator returns a boolean value,
# then the wrapper will return 1.0 if the boolean was True or 0.0 if
# it was False.
self.assertEqual(FakeLexer.analyse(True), 1.0)
self.assertEqual(FakeLexer.analyse(False), 0.0)
def test_analysator_raises_exception(self):
# If an analysator wrapped by make_analysator raises an exception,
# then the wrapper will return 0.0.
class ErrorLexer(object):
def analyse(text):
raise RuntimeError('something bad happened')
analyse = util.make_analysator(analyse)
self.assertEqual(ErrorLexer.analyse(''), 0.0)
def test_analysator_value_error(self):
# When converting the analysator's return value to a float a
# ValueError may occur. If that happens 0.0 is returned instead.
self.assertEqual(FakeLexer.analyse('bad input'), 0.0)
def test_analysator_type_error(self):
# When converting the analysator's return value to a float a
# TypeError may occur. If that happens 0.0 is returned instead.
self.assertEqual(FakeLexer.analyse('xxx'), 0.0)
def test_shebang_matches(self):
self.assertTrue(util.shebang_matches('#!/usr/bin/env python\n', r'python(2\.\d)?'))
self.assertTrue(util.shebang_matches('#!/usr/bin/python2.4', r'python(2\.\d)?'))
self.assertTrue(util.shebang_matches('#!/usr/bin/startsomethingwith python',
r'python(2\.\d)?'))
self.assertTrue(util.shebang_matches('#!C:\\Python2.4\\Python.exe',
r'python(2\.\d)?'))
self.assertFalse(util.shebang_matches('#!/usr/bin/python-ruby',
r'python(2\.\d)?'))
self.assertFalse(util.shebang_matches('#!/usr/bin/python/ruby',
r'python(2\.\d)?'))
self.assertFalse(util.shebang_matches('#!', r'python'))
def test_doctype_matches(self):
self.assertTrue(util.doctype_matches(
'<!DOCTYPE html> <html>', 'html.*'))
self.assertFalse(util.doctype_matches(
'<?xml ?> <DOCTYPE html PUBLIC "a"> <html>', 'html.*'))
self.assertTrue(util.html_doctype_matches(
'<?xml ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">'))
def test_xml(self):
self.assertTrue(util.looks_like_xml(
'<?xml ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">'))
self.assertTrue(util.looks_like_xml('<html xmlns>abc</html>'))
self.assertFalse(util.looks_like_xml('<html>'))
def test_unirange(self):
first_non_bmp = u'\U00010000'
r = re.compile(util.unirange(0x10000, 0x20000))
m = r.match(first_non_bmp)
self.assertTrue(m)
self.assertEqual(m.end(), len(first_non_bmp))
self.assertFalse(r.match(u'\uffff'))
self.assertFalse(r.match(u'xxx'))
# Tests that end is inclusive
r = re.compile(util.unirange(0x10000, 0x10000) + '+')
# Tests that the plus works for the entire unicode point, if narrow
# build
m = r.match(first_non_bmp * 2)
self.assertTrue(m)
self.assertEqual(m.end(), len(first_non_bmp) * 2)
def test_format_lines(self):
lst = ['cat', 'dog']
output = util.format_lines('var', lst)
d = {}
exec(output, d)
self.assertTrue(isinstance(d['var'], tuple))
self.assertEqual(('cat', 'dog'), d['var'])
def test_duplicates_removed_seq_types(self):
# tuple
x = util.duplicates_removed(('a', 'a', 'b'))
self.assertEqual(['a', 'b'], x)
# list
x = util.duplicates_removed(['a', 'a', 'b'])
self.assertEqual(['a', 'b'], x)
# iterator
x = util.duplicates_removed(iter(('a', 'a', 'b')))
self.assertEqual(['a', 'b'], x)
def test_duplicates_removed_nonconsecutive(self):
# keeps first
x = util.duplicates_removed(('a', 'b', 'a'))
self.assertEqual(['a', 'b'], x)
def test_guess_decode(self):
# UTF-8 should be decoded as UTF-8
s = util.guess_decode(u'\xff'.encode('utf-8'))
self.assertEqual(s, (u'\xff', 'utf-8'))
# otherwise, it could be latin1 or the locale encoding...
import locale
s = util.guess_decode(b'\xff')
self.assertTrue(s[1] in ('latin1', locale.getpreferredencoding()))
def test_guess_decode_from_terminal(self):
class Term:
encoding = 'utf-7'
s = util.guess_decode_from_terminal(u'\xff'.encode('utf-7'), Term)
self.assertEqual(s, (u'\xff', 'utf-7'))
s = util.guess_decode_from_terminal(u'\xff'.encode('utf-8'), Term)
self.assertEqual(s, (u'\xff', 'utf-8'))
def test_add_metaclass(self):
class Meta(type):
pass
@util.add_metaclass(Meta)
class Cls:
pass
self.assertEqual(type(Cls), Meta)
class ConsoleTest(unittest.TestCase):
def test_ansiformat(self):
f = console.ansiformat
c = console.codes
all_attrs = f('+*_blue_*+', 'text')
self.assertTrue(c['blue'] in all_attrs and c['blink'] in all_attrs
and c['bold'] in all_attrs and c['underline'] in all_attrs
and c['reset'] in all_attrs)
self.assertRaises(KeyError, f, '*mauve*', 'text')
def test_functions(self):
self.assertEqual(console.reset_color(), console.codes['reset'])
self.assertEqual(console.colorize('blue', 'text'),
console.codes['blue'] + 'text' + console.codes['reset'])
|