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_checker_spelling.py 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. # -*- coding: utf-8 -*-
  2. # Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com>
  3. # Copyright (c) 2014 Michal Nowikowski <godfryd@gmail.com>
  4. # Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro>
  5. # Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com>
  6. # Copyright (c) 2017 Pedro Algarvio <pedro@algarvio.me>
  7. # Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com>
  8. # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  9. # For details: https://github.com/PyCQA/pylint/blob/master/COPYING
  10. """Unittest for the spelling checker."""
  11. import pytest
  12. import astroid
  13. from pylint.checkers import spelling
  14. from pylint.testutils import CheckerTestCase, Message, set_config, _tokenize_str
  15. # try to create enchant dictionary
  16. try:
  17. import enchant
  18. except ImportError:
  19. enchant = None
  20. spell_dict = None
  21. if enchant is not None:
  22. try:
  23. enchant.Dict("en_US")
  24. spell_dict = "en_US"
  25. except enchant.DictNotFoundError:
  26. pass
  27. class TestSpellingChecker(CheckerTestCase):
  28. CHECKER_CLASS = spelling.SpellingChecker
  29. skip_on_missing_package_or_dict = pytest.mark.skipif(
  30. spell_dict is None,
  31. reason="missing python-enchant package or missing spelling dictionaries")
  32. def _get_msg_suggestions(self, word, count=4):
  33. return "'{0}'".format("' or '".join(self.checker.spelling_dict.suggest(word)[:count]))
  34. @skip_on_missing_package_or_dict
  35. @set_config(spelling_dict=spell_dict)
  36. def test_check_bad_coment(self):
  37. with self.assertAddsMessages(
  38. Message('wrong-spelling-in-comment', line=1,
  39. args=('coment', '# bad coment',
  40. ' ^^^^^^',
  41. self._get_msg_suggestions('coment')))):
  42. self.checker.process_tokens(_tokenize_str("# bad coment"))
  43. @skip_on_missing_package_or_dict
  44. @set_config(spelling_dict=spell_dict)
  45. @set_config(max_spelling_suggestions=2)
  46. def test_check_bad_coment_custom_suggestion_count(self):
  47. with self.assertAddsMessages(
  48. Message('wrong-spelling-in-comment', line=1,
  49. args=('coment', '# bad coment',
  50. ' ^^^^^^',
  51. self._get_msg_suggestions('coment', count=2)))):
  52. self.checker.process_tokens(_tokenize_str("# bad coment"))
  53. @skip_on_missing_package_or_dict
  54. @set_config(spelling_dict=spell_dict)
  55. def test_check_bad_docstring(self):
  56. stmt = astroid.extract_node(
  57. 'def fff():\n """bad coment"""\n pass')
  58. with self.assertAddsMessages(
  59. Message('wrong-spelling-in-docstring', line=2,
  60. args=('coment', 'bad coment',
  61. ' ^^^^^^',
  62. self._get_msg_suggestions('coment')))):
  63. self.checker.visit_functiondef(stmt)
  64. stmt = astroid.extract_node(
  65. 'class Abc(object):\n """bad coment"""\n pass')
  66. with self.assertAddsMessages(
  67. Message('wrong-spelling-in-docstring', line=2,
  68. args=('coment', 'bad coment',
  69. ' ^^^^^^',
  70. self._get_msg_suggestions('coment')))):
  71. self.checker.visit_classdef(stmt)
  72. @pytest.mark.skipif(True, reason='pyenchant\'s tokenizer strips these')
  73. @skip_on_missing_package_or_dict
  74. @set_config(spelling_dict=spell_dict)
  75. def test_invalid_docstring_characters(self):
  76. stmt = astroid.extract_node(
  77. 'def fff():\n """test\\x00"""\n pass')
  78. with self.assertAddsMessages(
  79. Message('invalid-characters-in-docstring', line=2,
  80. args=('test\x00',))):
  81. self.checker.visit_functiondef(stmt)
  82. @skip_on_missing_package_or_dict
  83. @set_config(spelling_dict=spell_dict)
  84. def test_skip_shebangs(self):
  85. self.checker.process_tokens(_tokenize_str('#!/usr/bin/env python'))
  86. assert self.linter.release_messages() == []
  87. @skip_on_missing_package_or_dict
  88. @set_config(spelling_dict=spell_dict)
  89. def test_skip_python_coding_comments(self):
  90. self.checker.process_tokens(_tokenize_str(
  91. '# -*- coding: utf-8 -*-'))
  92. assert self.linter.release_messages() == []
  93. self.checker.process_tokens(_tokenize_str(
  94. '# coding=utf-8'))
  95. assert self.linter.release_messages() == []
  96. self.checker.process_tokens(_tokenize_str(
  97. '# vim: set fileencoding=utf-8 :'))
  98. assert self.linter.release_messages() == []
  99. # Now with a shebang first
  100. self.checker.process_tokens(_tokenize_str(
  101. '#!/usr/bin/env python\n# -*- coding: utf-8 -*-'))
  102. assert self.linter.release_messages() == []
  103. self.checker.process_tokens(_tokenize_str(
  104. '#!/usr/bin/env python\n# coding=utf-8'))
  105. assert self.linter.release_messages() == []
  106. self.checker.process_tokens(_tokenize_str(
  107. '#!/usr/bin/env python\n# vim: set fileencoding=utf-8 :'))
  108. assert self.linter.release_messages() == []
  109. @skip_on_missing_package_or_dict
  110. @set_config(spelling_dict=spell_dict)
  111. def test_skip_top_level_pylint_enable_disable_comments(self):
  112. self.checker.process_tokens(_tokenize_str('# Line 1\n Line 2\n# pylint: disable=ungrouped-imports'))
  113. assert self.linter.release_messages() == []
  114. @skip_on_missing_package_or_dict
  115. @set_config(spelling_dict=spell_dict)
  116. def test_skip_words_with_numbers(self):
  117. self.checker.process_tokens(_tokenize_str('\n# 0ne\n# Thr33\n# Sh3ll'))
  118. assert self.linter.release_messages() == []
  119. @skip_on_missing_package_or_dict
  120. @set_config(spelling_dict=spell_dict)
  121. def test_skip_wiki_words(self):
  122. stmt = astroid.extract_node(
  123. 'class ComentAbc(object):\n """ComentAbc with a bad coment"""\n pass')
  124. with self.assertAddsMessages(
  125. Message('wrong-spelling-in-docstring', line=2,
  126. args=('coment', 'ComentAbc with a bad coment',
  127. ' ^^^^^^',
  128. self._get_msg_suggestions('coment')))):
  129. self.checker.visit_classdef(stmt)
  130. @skip_on_missing_package_or_dict
  131. @set_config(spelling_dict=spell_dict)
  132. def test_skip_camel_cased_words(self):
  133. stmt = astroid.extract_node(
  134. 'class ComentAbc(object):\n """comentAbc with a bad coment"""\n pass')
  135. with self.assertAddsMessages(
  136. Message('wrong-spelling-in-docstring', line=2,
  137. args=('coment', 'comentAbc with a bad coment',
  138. ' ^^^^^^',
  139. self._get_msg_suggestions('coment')))):
  140. self.checker.visit_classdef(stmt)
  141. # With just a single upper case letter in the end
  142. stmt = astroid.extract_node(
  143. 'class ComentAbc(object):\n """argumentN with a bad coment"""\n pass')
  144. with self.assertAddsMessages(
  145. Message('wrong-spelling-in-docstring', line=2,
  146. args=('coment', 'argumentN with a bad coment',
  147. ' ^^^^^^',
  148. self._get_msg_suggestions('coment')))):
  149. self.checker.visit_classdef(stmt)
  150. for ccn in ('xmlHttpRequest', 'newCustomer', 'newCustomerId',
  151. 'innerStopwatch', 'supportsIpv6OnIos', 'affine3D'):
  152. stmt = astroid.extract_node(
  153. 'class TestClass(object):\n """{0} comment"""\n pass'.format(ccn))
  154. self.checker.visit_classdef(stmt)
  155. assert self.linter.release_messages() == []
  156. @skip_on_missing_package_or_dict
  157. @set_config(spelling_dict=spell_dict)
  158. def test_skip_words_with_underscores(self):
  159. stmt = astroid.extract_node(
  160. 'def fff(param_name):\n """test param_name"""\n pass')
  161. self.checker.visit_functiondef(stmt)
  162. assert self.linter.release_messages() == []
  163. @skip_on_missing_package_or_dict
  164. @set_config(spelling_dict=spell_dict)
  165. def test_skip_email_address(self):
  166. self.checker.process_tokens(_tokenize_str('# uname@domain.tld'))
  167. assert self.linter.release_messages() == []
  168. @skip_on_missing_package_or_dict
  169. @set_config(spelling_dict=spell_dict)
  170. def test_skip_urls(self):
  171. self.checker.process_tokens(_tokenize_str('# https://github.com/rfk/pyenchant'))
  172. assert self.linter.release_messages() == []
  173. @skip_on_missing_package_or_dict
  174. @set_config(spelling_dict=spell_dict)
  175. def test_skip_sphinx_directives(self):
  176. stmt = astroid.extract_node(
  177. 'class ComentAbc(object):\n """This is :class:`ComentAbc` with a bad coment"""\n pass')
  178. with self.assertAddsMessages(
  179. Message('wrong-spelling-in-docstring', line=2,
  180. args=('coment', 'This is :class:`ComentAbc` with a bad coment',
  181. ' ^^^^^^',
  182. self._get_msg_suggestions('coment')))):
  183. self.checker.visit_classdef(stmt)
  184. @skip_on_missing_package_or_dict
  185. @set_config(spelling_dict=spell_dict)
  186. def test_handle_words_joined_by_forward_slash(self):
  187. stmt = astroid.extract_node('''
  188. class ComentAbc(object):
  189. """This is Comment/Abcz with a bad comment"""
  190. pass
  191. ''')
  192. with self.assertAddsMessages(
  193. Message('wrong-spelling-in-docstring', line=3,
  194. args=('Abcz', 'This is Comment/Abcz with a bad comment',
  195. ' ^^^^',
  196. self._get_msg_suggestions('Abcz')))):
  197. self.checker.visit_classdef(stmt)