Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

unittest_utils.py 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. # -*- coding: utf-8 -*-
  2. # Copyright (c) 2013-2014 Google, Inc.
  3. # Copyright (c) 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
  4. # Copyright (c) 2014 Arun Persaud <arun@nubati.net>
  5. # Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com>
  6. # Copyright (c) 2015 Aru Sahni <arusahni@gmail.com>
  7. # Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro>
  8. # Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com>
  9. # Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net>
  10. # Copyright (c) 2017 ttenhoeve-aa <ttenhoeve@appannie.com>
  11. # Copyright (c) 2017 Anthony Sottile <asottile@umich.edu>
  12. # Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com>
  13. # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  14. # For details: https://github.com/PyCQA/pylint/blob/master/COPYING
  15. import io
  16. import re
  17. import warnings
  18. import astroid
  19. from pylint import utils
  20. from pylint.checkers.utils import check_messages, get_node_last_lineno
  21. from pylint.exceptions import InvalidMessageError
  22. import pytest
  23. class TestPyLintASTWalker(object):
  24. class MockLinter(object):
  25. def __init__(self, msgs):
  26. self._msgs = msgs
  27. def is_message_enabled(self, msgid):
  28. return self._msgs.get(msgid, True)
  29. class Checker(object):
  30. def __init__(self):
  31. self.called = set()
  32. @check_messages('first-message')
  33. def visit_module(self, module):
  34. self.called.add('module')
  35. @check_messages('second-message')
  36. def visit_call(self, module):
  37. raise NotImplementedError
  38. @check_messages('second-message', 'third-message')
  39. def visit_assignname(self, module):
  40. self.called.add('assignname')
  41. @check_messages('second-message')
  42. def leave_assignname(self, module):
  43. raise NotImplementedError
  44. def test_check_messages(self):
  45. linter = self.MockLinter({'first-message': True,
  46. 'second-message': False,
  47. 'third-message': True})
  48. walker = utils.PyLintASTWalker(linter)
  49. checker = self.Checker()
  50. walker.add_checker(checker)
  51. walker.walk(astroid.parse("x = func()"))
  52. assert {'module', 'assignname'} == checker.called
  53. def test_deprecated_methods(self):
  54. class Checker(object):
  55. def __init__(self):
  56. self.called = False
  57. @check_messages('first-message')
  58. def visit_assname(self, node):
  59. self.called = True
  60. linter = self.MockLinter({'first-message': True})
  61. walker = utils.PyLintASTWalker(linter)
  62. checker = Checker()
  63. walker.add_checker(checker)
  64. with warnings.catch_warnings(record=True):
  65. warnings.simplefilter('always')
  66. walker.walk(astroid.parse("x = 1"))
  67. assert not checker.called
  68. def test__basename_in_blacklist_re_match():
  69. patterns = [re.compile(".*enchilada.*"), re.compile("unittest_.*")]
  70. assert utils._basename_in_blacklist_re("unittest_utils.py", patterns)
  71. assert utils._basename_in_blacklist_re("cheese_enchiladas.xml", patterns)
  72. def test__basename_in_blacklist_re_nomatch():
  73. patterns = [re.compile(".*enchilada.*"), re.compile("unittest_.*")]
  74. assert not utils._basename_in_blacklist_re("test_utils.py", patterns)
  75. assert not utils._basename_in_blacklist_re("enchilad.py", patterns)
  76. @pytest.fixture
  77. def store():
  78. return utils.MessagesStore()
  79. @pytest.mark.parametrize("messages,expected", [
  80. ({'W1234': ('message one', 'msg-symbol-one', 'msg description'),
  81. 'W4321': ('message two', 'msg-symbol-two', 'msg description')},
  82. r"Inconsistent checker part in message id 'W4321' (expected 'x12xx')"),
  83. ({'W1233': ('message two', 'msg-symbol-two', 'msg description',
  84. {'old_names': [('W1234', 'old-symbol')]}),
  85. 'W1234': ('message one', 'msg-symbol-one', 'msg description')},
  86. "Message id 'W1234' is already defined"),
  87. ({'W1234': ('message one', 'msg-symbol-one', 'msg description'),
  88. 'W1235': ('message two', 'msg-symbol-two', 'msg description',
  89. {'old_names': [('W1234', 'old-symbol')]})},
  90. "Message id 'W1234' is already defined"),
  91. ({'W1234': ('message one', 'msg-symbol-one', 'msg description',
  92. {'old_names': [('W1201', 'old-symbol-one')]}),
  93. 'W1235': ('message two', 'msg-symbol-two', 'msg description',
  94. {'old_names': [('W1201', 'old-symbol-two')]})},
  95. "Message id 'W1201' is already defined"),
  96. ({'W1234': ('message one', 'msg-symbol', 'msg description'),
  97. 'W1235': ('message two', 'msg-symbol', 'msg description')},
  98. "Message symbol 'msg-symbol' is already defined"),
  99. ({'W1233': ('message two', 'msg-symbol-two', 'msg description',
  100. {'old_names': [('W1230', 'msg-symbol-one')]}),
  101. 'W1234': ('message one', 'msg-symbol-one', 'msg description')},
  102. "Message symbol 'msg-symbol-one' is already defined"),
  103. ({'W1234': ('message one', 'msg-symbol-one', 'msg description'),
  104. 'W1235': ('message two', 'msg-symbol-two', 'msg description',
  105. {'old_names': [('W1230', 'msg-symbol-one')]})},
  106. "Message symbol 'msg-symbol-one' is already defined"),
  107. ({'W1234': ('message one', 'msg-symbol-one', 'msg description',
  108. {'old_names': [('W1230', 'old-symbol-one')]}),
  109. 'W1235': ('message two', 'msg-symbol-two', 'msg description',
  110. {'old_names': [('W1231', 'old-symbol-one')]})},
  111. "Message alternate name 'old-symbol-one' is already defined"),
  112. ])
  113. def test_register_error(store, messages, expected):
  114. class Checker(object):
  115. name = 'checker'
  116. msgs = messages
  117. with pytest.raises(InvalidMessageError) as cm:
  118. store.register_messages(Checker())
  119. assert str(cm.value) == expected
  120. def test_register_error_new_id_duplicate_of_new(store):
  121. class CheckerOne(object):
  122. name = 'checker_one'
  123. msgs = {
  124. 'W1234': ('message one', 'msg-symbol-one', 'msg description.'),
  125. }
  126. class CheckerTwo(object):
  127. name = 'checker_two'
  128. msgs = {
  129. 'W1234': ('message two', 'msg-symbol-two', 'another msg description.'),
  130. }
  131. store.register_messages(CheckerOne())
  132. test_register_error(store,
  133. {'W1234': ('message two', 'msg-symbol-two', 'another msg description.')},
  134. "Message id 'W1234' is already defined")
  135. @pytest.mark.parametrize("msgid,expected", [
  136. ("Q1234", "Bad message type Q in 'Q1234'"),
  137. ("W12345", "Invalid message id 'W12345'"),
  138. ])
  139. def test_create_invalid_message_type(msgid, expected):
  140. with pytest.raises(InvalidMessageError) as cm:
  141. utils.MessageDefinition('checker', msgid,
  142. 'msg', 'descr', 'symbol', 'scope')
  143. assert str(cm.value) == expected
  144. def test__decoding_readline():
  145. """_decoding_readline should yield line at a time even if the binary
  146. representation of the text is not splittable line-by-line.
  147. For convenience this test uses a codec that is easy to understand, though
  148. this *specific* codec is unlikely to be seen in the wild for files.
  149. """
  150. binary_io = io.BytesIO(b'foo\\nbaz\\n')
  151. readline = utils._decoding_readline(binary_io, 'unicode_escape')
  152. ret = []
  153. s = readline()
  154. while s != '':
  155. ret.append(s)
  156. s = readline()
  157. assert ret == ['foo\n', 'baz\n']
  158. def test_decoding_stream_unknown_encoding():
  159. """decoding_stream should fall back to *some* decoding when given an
  160. unknown encoding.
  161. """
  162. binary_io = io.BytesIO(b'foo\nbar')
  163. stream = utils.decoding_stream(binary_io, 'garbage-encoding')
  164. # should still act like a StreamReader
  165. ret = stream.readlines()
  166. assert ret == ['foo\n', 'bar']
  167. def test_decoding_stream_known_encoding():
  168. binary_io = io.BytesIO(u'€'.encode('cp1252'))
  169. stream = utils.decoding_stream(binary_io, 'cp1252')
  170. assert stream.read() == u'€'
  171. class TestGetNodeLastLineno:
  172. def test_get_node_last_lineno_simple(self):
  173. node = astroid.extract_node("""
  174. pass
  175. """)
  176. assert get_node_last_lineno(node) == 2
  177. def test_get_node_last_lineno_if_simple(self):
  178. node = astroid.extract_node("""
  179. if True:
  180. print(1)
  181. pass
  182. """)
  183. assert get_node_last_lineno(node) == 4
  184. def test_get_node_last_lineno_if_elseif_else(self):
  185. node = astroid.extract_node("""
  186. if True:
  187. print(1)
  188. elif False:
  189. print(2)
  190. else:
  191. print(3)
  192. """)
  193. assert get_node_last_lineno(node) == 7
  194. def test_get_node_last_lineno_while(self):
  195. node = astroid.extract_node("""
  196. while True:
  197. print(1)
  198. """)
  199. assert get_node_last_lineno(node) == 3
  200. def test_get_node_last_lineno_while_else(self):
  201. node = astroid.extract_node("""
  202. while True:
  203. print(1)
  204. else:
  205. print(2)
  206. """)
  207. assert get_node_last_lineno(node) == 5
  208. def test_get_node_last_lineno_for(self):
  209. node = astroid.extract_node("""
  210. for x in range(0, 5):
  211. print(1)
  212. """)
  213. assert get_node_last_lineno(node) == 3
  214. def test_get_node_last_lineno_for_else(self):
  215. node = astroid.extract_node("""
  216. for x in range(0, 5):
  217. print(1)
  218. else:
  219. print(2)
  220. """)
  221. assert get_node_last_lineno(node) == 5
  222. def test_get_node_last_lineno_try(self):
  223. node = astroid.extract_node("""
  224. try:
  225. print(1)
  226. except ValueError:
  227. print(2)
  228. except Exception:
  229. print(3)
  230. """)
  231. assert get_node_last_lineno(node) == 7
  232. def test_get_node_last_lineno_try_except_else(self):
  233. node = astroid.extract_node("""
  234. try:
  235. print(1)
  236. except Exception:
  237. print(2)
  238. print(3)
  239. else:
  240. print(4)
  241. """)
  242. assert get_node_last_lineno(node) == 8
  243. def test_get_node_last_lineno_try_except_finally(self):
  244. node = astroid.extract_node("""
  245. try:
  246. print(1)
  247. except Exception:
  248. print(2)
  249. finally:
  250. print(4)
  251. """)
  252. assert get_node_last_lineno(node) == 7
  253. def test_get_node_last_lineno_try_except_else_finally(self):
  254. node = astroid.extract_node("""
  255. try:
  256. print(1)
  257. except Exception:
  258. print(2)
  259. else:
  260. print(3)
  261. finally:
  262. print(4)
  263. """)
  264. assert get_node_last_lineno(node) == 9
  265. def test_get_node_last_lineno_with(self):
  266. node = astroid.extract_node("""
  267. with x as y:
  268. print(1)
  269. pass
  270. """)
  271. assert get_node_last_lineno(node) == 4
  272. def test_get_node_last_lineno_method(self):
  273. node = astroid.extract_node("""
  274. def x(a, b):
  275. print(a, b)
  276. pass
  277. """)
  278. assert get_node_last_lineno(node) == 4
  279. def test_get_node_last_lineno_decorator(self):
  280. node = astroid.extract_node("""
  281. @decor()
  282. def x(a, b):
  283. print(a, b)
  284. pass
  285. """)
  286. assert get_node_last_lineno(node) == 5
  287. def test_get_node_last_lineno_class(self):
  288. node = astroid.extract_node("""
  289. class C(object):
  290. CONST = True
  291. def x(self, b):
  292. print(b)
  293. def y(self):
  294. pass
  295. pass
  296. """)
  297. assert get_node_last_lineno(node) == 10
  298. def test_get_node_last_lineno_combined(self):
  299. node = astroid.extract_node("""
  300. class C(object):
  301. CONST = True
  302. def y(self):
  303. try:
  304. pass
  305. except:
  306. pass
  307. finally:
  308. pass
  309. """)
  310. assert get_node_last_lineno(node) == 11