# coding: utf-8
#
# Copyright 2018 The Oppia Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# For details on how to write such tests, please refer to
# https://github.com/oppia/oppia/wiki/Writing-Tests-For-Pylint

"""Unit tests for scripts/pylint_extensions."""

from __future__ import annotations

import tempfile
import unittest

from core import utils

from . import pylint_extensions

import astroid  # isort:skip
from pylint import interfaces  # isort:skip
from pylint import testutils  # isort:skip
from pylint import utils as pylint_utils  # isort:skip


class HangingIndentCheckerTests(unittest.TestCase):

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.HangingIndentChecker)
        self.checker_test_object.setup_method()

    def test_no_break_after_hanging_indentation(self) -> None:
        node_break_after_hanging_indent = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name
        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""self.post_json('/ml/\\trainedclassifierhandler',
                self.payload, expect_errors=True, expected_status_int=401)
                if (a > 1 and
                        b > 2):
                """)
        node_break_after_hanging_indent.file = filename
        node_break_after_hanging_indent.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_break_after_hanging_indent))

        message = testutils.MessageTest(
            msg_id='no-break-after-hanging-indent', line=1)

        with self.checker_test_object.assertAddsMessages(message):
            temp_file.close()

    def test_no_break_after_hanging_indentation_with_comment(self) -> None:
        node_break_after_hanging_indent = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name
        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""self.post_json('/ml/\\trainedclassifierhandler',
                self.payload, expect_errors=True, expected_status_int=401)

                if (a > 1 and
                        b > 2):  # pylint: disable=invalid-name
                """)
        node_break_after_hanging_indent.file = filename
        node_break_after_hanging_indent.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_break_after_hanging_indent))

        message = testutils.MessageTest(
            msg_id='no-break-after-hanging-indent', line=1)

        with self.checker_test_object.assertAddsMessages(message):
            temp_file.close()

    def test_break_after_hanging_indentation(self) -> None:
        node_with_no_error_message = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')

        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name
        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""\"\"\"Some multiline
                docstring.
                \"\"\"
                # Load JSON.
                master_translation_dict = json.loads(
               pylint_utils.get_file_contents(os.path.join(
                os.getcwd(), 'assets', 'i18n', 'en.json')))
                """)
        node_with_no_error_message.file = filename
        node_with_no_error_message.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_with_no_error_message))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_hanging_indentation_with_a_comment_after_bracket(self) -> None:
        node_with_no_error_message = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')

        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name
        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""self.post_json(  # Random comment
                '(',
                self.payload, expect_errors=True, expected_status_int=401)""")
        node_with_no_error_message.file = filename
        node_with_no_error_message.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_with_no_error_message))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_hanging_indentation_with_a_comment_after_two_or_more_bracket(
        self
    ) -> None:
        node_with_no_error_message = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')

        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name
        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""self.post_json(func(  # Random comment
                '(',
                self.payload, expect_errors=True, expected_status_int=401))""")
        node_with_no_error_message.file = filename
        node_with_no_error_message.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_with_no_error_message))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_hanging_indentation_with_a_comment_after_square_bracket(
        self
    ) -> None:
        node_with_no_error_message = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')

        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name
        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""self.post_json([  # Random comment
                '(',
                '', '', ''])""")
        node_with_no_error_message.file = filename
        node_with_no_error_message.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_with_no_error_message))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_hanging_indentation_with_a_if_statement_before(self) -> None:
        node_with_no_error_message = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')

        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name
        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                if 5 > 7:
                    self.post_json([
                    '(',
                    '', '', ''])

                def func(arg1,
                    arg2, arg3):
                    a = 2 / 2""")
        node_with_no_error_message.file = filename
        node_with_no_error_message.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_with_no_error_message))

        message = testutils.MessageTest(
            msg_id='no-break-after-hanging-indent',
            line=7)

        with self.checker_test_object.assertAddsMessages(message):
            temp_file.close()


class DocstringParameterCheckerTests(unittest.TestCase):

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.DocstringParameterChecker)
        self.checker_test_object.setup_method()

    def test_no_newline_below_class_docstring(self) -> None:
        node_no_newline_below_class_docstring = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    class ClassName(dummy_class):
                        \"\"\"This is a docstring.\"\"\"
                        a = 1 + 2
                """)
        node_no_newline_below_class_docstring.file = filename
        node_no_newline_below_class_docstring.path = filename

        self.checker_test_object.checker.visit_classdef(
            node_no_newline_below_class_docstring)

        message = testutils.MessageTest(
            msg_id='newline-below-class-docstring',
            node=node_no_newline_below_class_docstring)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            temp_file.close()

    def test_excessive_newline_below_class_docstring(self) -> None:
        node_excessive_newline_below_class_docstring = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'))
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    class ClassName(dummy_class):
                        \"\"\"This is a docstring.\"\"\"


                        a = 1 + 2
                """)
        node_excessive_newline_below_class_docstring.file = filename
        node_excessive_newline_below_class_docstring.path = filename

        self.checker_test_object.checker.visit_classdef(
            node_excessive_newline_below_class_docstring)

        message = testutils.MessageTest(
            msg_id='newline-below-class-docstring',
            node=node_excessive_newline_below_class_docstring)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            temp_file.close()

    def test_inline_comment_after_class_docstring(self) -> None:
        node_inline_comment_after_class_docstring = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'))
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    class ClassName(dummy_class):
                        \"\"\"This is a docstring.\"\"\"
                        # This is a comment.
                        def func():
                            a = 1 + 2
                """)
        node_inline_comment_after_class_docstring.file = filename
        node_inline_comment_after_class_docstring.path = filename

        self.checker_test_object.checker.visit_classdef(
            node_inline_comment_after_class_docstring)

        message = testutils.MessageTest(
            msg_id='newline-below-class-docstring',
            node=node_inline_comment_after_class_docstring)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            temp_file.close()

    def test_multiline_class_argument_with_incorrect_style(self) -> None:
        node_multiline_class_argument_with_incorrect_style = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'))
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    class ClassName(
                            dummy_class):
                        \"\"\"This is a docstring.\"\"\"
                        a = 1 + 2
                """)
        node_multiline_class_argument_with_incorrect_style.file = filename
        node_multiline_class_argument_with_incorrect_style.path = filename

        self.checker_test_object.checker.visit_classdef(
            node_multiline_class_argument_with_incorrect_style)

        message = testutils.MessageTest(
            msg_id='newline-below-class-docstring',
            node=node_multiline_class_argument_with_incorrect_style)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            temp_file.close()

    def test_multiline_class_argument_with_correct_style(self) -> None:
        node_multiline_class_argument_with_correct_style = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'))
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    class ClassName(
                            dummy_class):
                        \"\"\"This is a docstring.\"\"\"

                        a = 1 + 2
                """)
        node_multiline_class_argument_with_correct_style.file = filename
        node_multiline_class_argument_with_correct_style.path = filename

        self.checker_test_object.checker.visit_classdef(
            node_multiline_class_argument_with_correct_style)

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_single_newline_below_class_docstring(self) -> None:
        node_with_no_error_message = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    class ClassName(dummy_class):
                        \"\"\"This is a multiline docstring.\"\"\"

                        a = 1 + 2
                """)
        node_with_no_error_message.file = filename
        node_with_no_error_message.path = filename

        self.checker_test_object.checker.visit_classdef(
            node_with_no_error_message)

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_class_with_no_docstring(self) -> None:
        node_class_with_no_docstring = astroid.scoped_nodes.Module(
            name='test',
            doc=None)
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    class ClassName(dummy_class):
                        a = 1 + 2
                """)
        node_class_with_no_docstring.file = filename
        node_class_with_no_docstring.path = filename

        self.checker_test_object.checker.visit_classdef(
            node_class_with_no_docstring)

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_newline_before_docstring_with_correct_style(self) -> None:
        node_newline_before_docstring_with_correct_style = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'))
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    class ClassName(dummy_class):

                        \"\"\"This is a multiline docstring.\"\"\"

                        a = 1 + 2
                """)
        node_newline_before_docstring_with_correct_style.file = filename
        node_newline_before_docstring_with_correct_style.path = filename

        self.checker_test_object.checker.visit_classdef(
            node_newline_before_docstring_with_correct_style)

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_newline_before_docstring_with_incorrect_style(self) -> None:
        node_newline_before_docstring_with_incorrect_style = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'))
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    class ClassName(dummy_class):

                        \"\"\"This is a multiline docstring.\"\"\"
                        a = 1 + 2
                """)
        node_newline_before_docstring_with_incorrect_style.file = filename
        node_newline_before_docstring_with_incorrect_style.path = filename

        self.checker_test_object.checker.visit_classdef(
            node_newline_before_docstring_with_incorrect_style)

        message = testutils.MessageTest(
            msg_id='newline-below-class-docstring',
            node=node_newline_before_docstring_with_incorrect_style)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            temp_file.close()

    def test_malformed_args_section(self) -> None:
        node_malformed_args_section = astroid.extract_node(
            u"""def func(arg): #@
                \"\"\"Does nothing.

                Args:
                    arg: Argument description.
                \"\"\"
                a = True
        """)

        message = testutils.MessageTest(
            msg_id='malformed-args-section',
            node=node_malformed_args_section
        )

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_malformed_args_section)

    def test_malformed_returns_section(self) -> None:
        node_malformed_returns_section = astroid.extract_node(
            u"""def func(): #@
                \"\"\"Return True.

                Returns:
                    arg: Argument description.
                \"\"\"
                return True
        """)

        message = testutils.MessageTest(
            msg_id='malformed-returns-section',
            node=node_malformed_returns_section
        )

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_malformed_returns_section)

    def test_malformed_yields_section(self) -> None:
        node_malformed_yields_section = astroid.extract_node(
            u"""def func(): #@
                \"\"\"Yield true.

                Yields:
                    yields: Argument description.
                \"\"\"
                yield True
        """)

        message = testutils.MessageTest(
            msg_id='malformed-yields-section',
            node=node_malformed_yields_section
        )

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_malformed_yields_section)

    def test_malformed_raises_section(self) -> None:
        node_malformed_raises_section = astroid.extract_node(
            u"""def func(): #@
                \"\"\"Raise an exception.

                Raises:
                    Exception: Argument description.
                \"\"\"
                raise Exception()
        """)

        message = testutils.MessageTest(
            msg_id='malformed-raises-section',
            node=node_malformed_raises_section
        )

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_malformed_raises_section)

    def test_malformed_args_argument(self) -> None:
        node_malformed_args_argument = astroid.extract_node(
            u"""def func(*args): #@
                \"\"\"Does nothing.

                Args:
                    *args: int. Argument description.
                \"\"\"
                a = True
        """)

        message = testutils.MessageTest(
            msg_id='malformed-args-argument',
            node=node_malformed_args_argument
        )

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_malformed_args_argument)

    def test_well_formated_args_argument(self) -> None:
        node_with_no_error_message = astroid.extract_node(
            u"""def func(*args): #@
                \"\"\"Does nothing.

                Args:
                    *args: list(*). Description.
                \"\"\"
                a = True
        """)

        with self.checker_test_object.assertAddsMessages():
            self.checker_test_object.checker.visit_functiondef(
                node_with_no_error_message)

    def test_well_formated_args_section(self) -> None:
        node_with_no_error_message = astroid.extract_node(
            u"""def func(arg): #@
                \"\"\"Does nothing.

                Args:
                    arg: argument. Description.
                \"\"\"
                a = True
        """)

        with self.checker_test_object.assertAddsMessages():
            self.checker_test_object.checker.visit_functiondef(
                node_with_no_error_message)

    def test_well_formated_returns_section(self) -> None:
        node_with_no_error_message = astroid.extract_node(
            u"""def func(): #@
                \"\"\"Does nothing.

                Returns:
                    int. Argument escription.
                \"\"\"
                return args
        """)

        with self.checker_test_object.assertAddsMessages():
            self.checker_test_object.checker.visit_functiondef(
                node_with_no_error_message)

    def test_well_formated_yields_section(self) -> None:
        node_with_no_error_message = astroid.extract_node(
            u"""def func(): #@
                \"\"\"Does nothing.

                Yields:
                    arg. Argument description.
                \"\"\"
                yield args
        """)

        with self.checker_test_object.assertAddsMessages():
            self.checker_test_object.checker.visit_functiondef(
                node_with_no_error_message)

    def test_space_after_docstring(self) -> None:
        node_space_after_docstring = astroid.extract_node(
            u"""def func():
                    \"\"\" Hello world.\"\"\"
                    Something
        """)

        message = testutils.MessageTest(
            msg_id='space-after-triple-quote',
            node=node_space_after_docstring)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_space_after_docstring)

    def test_two_lines_empty_docstring_raise_correct_message(self) -> None:
        node_with_docstring = astroid.extract_node(
            u"""def func():
                    \"\"\"
                    \"\"\"
                    pass
        """)
        message = testutils.MessageTest(
            msg_id='single-line-docstring-span-two-lines',
            node=node_with_docstring)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_with_docstring)

    def test_single_line_docstring_span_two_lines(self) -> None:
        node_single_line_docstring_span_two_lines = astroid.extract_node(
            u"""def func(): #@
                    \"\"\"This is a docstring.
                    \"\"\"
                    Something
        """)

        message = testutils.MessageTest(
            msg_id='single-line-docstring-span-two-lines',
            node=node_single_line_docstring_span_two_lines)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_single_line_docstring_span_two_lines)

    def test_no_period_at_end(self) -> None:
        node_no_period_at_end = astroid.extract_node(
            u"""def func(): #@
                    \"\"\"This is a docstring\"\"\"
                    Something
        """)

        message = testutils.MessageTest(
            msg_id='no-period-used',
            node=node_no_period_at_end)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_no_period_at_end)

    def test_empty_line_before_end_of_docstring(self) -> None:
        node_empty_line_before_end = astroid.extract_node(
            u"""def func(): #@
                    \"\"\"This is a docstring.

                    \"\"\"
                    Something
        """)

        message = testutils.MessageTest(
            msg_id='empty-line-before-end', node=node_empty_line_before_end)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_empty_line_before_end)

    def test_no_period_at_end_of_a_multiline_docstring(self) -> None:
        node_no_period_at_end = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"This is a docstring.

                        Args:
                            arg: variable. Desciption
                    \"\"\"
                    Something
        """)

        no_period_at_end_message = testutils.MessageTest(
            msg_id='no-period-used', node=node_no_period_at_end)
        malformed_args_message = testutils.MessageTest(
            msg_id='malformed-args-section', node=node_no_period_at_end)

        with self.checker_test_object.assertAddsMessages(
            no_period_at_end_message, malformed_args_message,
            ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_no_period_at_end)

    def test_no_newline_at_end_of_multi_line_docstring(self) -> None:
        node_no_newline_at_end = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"This is a docstring.

                        Args:
                            arg: variable. Description.\"\"\"
                    Something
        """)

        message = testutils.MessageTest(
            msg_id='no-newline-used-at-end', node=node_no_newline_at_end)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_no_newline_at_end)

    def test_no_newline_above_args(self) -> None:
        node_single_newline_above_args = astroid.extract_node(
            u"""def func(arg): #@
                \"\"\"Do something.
                Args:
                    arg: argument. Description.
                \"\"\"
        """)

        message = testutils.MessageTest(
            msg_id='single-space-above-args',
            node=node_single_newline_above_args)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_single_newline_above_args)

    def test_no_newline_above_raises(self) -> None:
        node_single_newline_above_raises = astroid.extract_node(
            u"""def func(): #@
                    \"\"\"Raises exception.
                    Raises:
                        raises_exception. Description.
                    \"\"\"
                    raise exception
        """)

        message = testutils.MessageTest(
            msg_id='single-space-above-raises',
            node=node_single_newline_above_raises
        )

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_single_newline_above_raises)

    def test_no_newline_above_return(self) -> None:
        node_with_no_space_above_return = astroid.extract_node(
            u"""def func(): #@
                \"\"\"Returns something.
                Returns:
                    returns_something. Description.
                \"\"\"
                return something
        """)

        message = testutils.MessageTest(
            msg_id='single-space-above-returns',
            node=node_with_no_space_above_return
        )

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_with_no_space_above_return)

    def test_varying_combination_of_newline_above_args(self) -> None:
        node_newline_above_args_raises = astroid.extract_node(
            u"""def func(arg): #@
                \"\"\"Raises exception.

                Args:
                    arg: argument. Description.
                Raises:
                    raises_something. Description.
                \"\"\"
                raise exception
        """)

        message = testutils.MessageTest(
            msg_id='single-space-above-raises',
            node=node_newline_above_args_raises
        )

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_newline_above_args_raises)

        node_newline_above_args_returns = astroid.extract_node(
            u"""def func(arg): #@
                \"\"\"Returns Something.

                Args:
                    arg: argument. Description.
                Returns:
                    returns_something. Description.
                \"\"\"
                return something
        """)

        message = testutils.MessageTest(
            msg_id='single-space-above-returns',
            node=node_newline_above_args_returns
        )

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_newline_above_args_returns)

        node_newline_above_returns_raises = astroid.extract_node(
            u"""def func(): #@
                \"\"\"Do something.



                Raises:
                    raises_exception. Description.

                Returns:
                    returns_something. Description.
                \"\"\"
                raise something
                return something
        """)

        message = testutils.MessageTest(
            msg_id='single-space-above-raises',
            node=node_newline_above_returns_raises
        )

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_newline_above_returns_raises)

    def test_excessive_newline_above_args(self) -> None:
        node_with_two_newline = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"Returns something.


                    Args:
                        arg: argument. This is  description.


                    Returns:
                        int. Returns something.


                    Yields:
                        yield_something. Description.
                    \"\"\"
                    return True
                    yield something
        """)

        single_space_above_args_message = testutils.MessageTest(
            msg_id='single-space-above-args',
            node=node_with_two_newline
        )

        single_space_above_returns_message = testutils.MessageTest(
            msg_id='single-space-above-returns',
            node=node_with_two_newline
        )

        single_space_above_yields_message = testutils.MessageTest(
            msg_id='single-space-above-yield',
            node=node_with_two_newline
        )

        with self.checker_test_object.assertAddsMessages(
            single_space_above_args_message, single_space_above_returns_message,
            single_space_above_yields_message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                node_with_two_newline)

    def test_return_in_comment(self) -> None:
        node_with_return_in_comment = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"Returns something.

                    Args:
                        arg: argument. Description.

                    Returns:
                        returns_something. Description.
                    \"\"\"
                    "Returns: something"
                    return something
        """)

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(
                node_with_return_in_comment)

    def test_function_with_no_args(self) -> None:
        node_with_no_args = astroid.extract_node(
            u"""def func():
                \"\"\"Do something.\"\"\"

                a = 1 + 2
        """)

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(
                node_with_no_args)

    def test_well_placed_newline(self) -> None:
        node_with_no_error_message = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"Returns something.

                    Args:
                        arg: argument. This is description.

                    Returns:
                        returns_something. This is description.

                    Raises:
                        raises. Something.

                    Yields:
                        yield_something. This is description.
                    \"\"\"
                    raise something
                    yield something
                    return something
        """)

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(
                node_with_no_error_message)

    def test_invalid_parameter_indentation_in_docstring(self) -> None:
        raises_invalid_indentation_node = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"This is a docstring.

                        Raises:
                        NoVariableException. Variable.
                    \"\"\"
                    Something
        """)

        message = testutils.MessageTest(
            msg_id='4-space-indentation-in-docstring',
            node=raises_invalid_indentation_node)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                raises_invalid_indentation_node)

        return_invalid_indentation_node = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"This is a docstring.

                        Returns:
                        str. If :true,
                            individual key=value pairs.
                    \"\"\"
                    Something
        """)
        message = testutils.MessageTest(
            msg_id='4-space-indentation-in-docstring',
            node=return_invalid_indentation_node)
        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                return_invalid_indentation_node)

    def test_invalid_description_indentation_docstring(self) -> None:
        invalid_raises_description_indentation_node = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"This is a docstring.

                        Raises:
                            AssertionError. If the
                            schema is not valid.
                    \"\"\"
                    Something
        """)

        incorrect_indentation_message = testutils.MessageTest(
            msg_id='8-space-indentation-in-docstring',
            node=invalid_raises_description_indentation_node)
        malformed_raises_message = testutils.MessageTest(
            msg_id='malformed-raises-section',
            node=invalid_raises_description_indentation_node)

        with self.checker_test_object.assertAddsMessages(
            incorrect_indentation_message, malformed_raises_message,
            malformed_raises_message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                invalid_raises_description_indentation_node)

        invalid_return_description_indentation_node = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"This is a docstring.

                        Returns:
                            str. If :true,
                                individual key=value pairs.
                    \"\"\"
                    return Something
        """)
        message = testutils.MessageTest(
            msg_id='4-space-indentation-in-docstring',
            node=invalid_return_description_indentation_node)
        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                invalid_return_description_indentation_node)

        invalid_yield_description_indentation_node = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"This is a docstring.

                        Yields:
                            str. If :true,
                                incorrent indentation line.
                    \"\"\"
                    yield Something
        """)
        message = testutils.MessageTest(
            msg_id='4-space-indentation-in-docstring',
            node=invalid_yield_description_indentation_node)
        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                invalid_yield_description_indentation_node)

    def test_malformed_parameter_docstring(self) -> None:
        invalid_parameter_name = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"This is a docstring.

                        Raises:
                            Incorrect-Exception. If the
                            schema is not valid.
                    \"\"\"
                    Something
        """)

        malformed_raises_message = testutils.MessageTest(
            msg_id='malformed-raises-section',
            node=invalid_parameter_name)

        with self.checker_test_object.assertAddsMessages(
            malformed_raises_message, malformed_raises_message,
            ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(
                invalid_parameter_name)

    def test_well_formed_single_line_docstring(self) -> None:
        node_with_no_error_message = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"This is a docstring.\"\"\"
                    Something
        """)

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(
                node_with_no_error_message)

    def test_well_formed_multi_line_docstring(self) -> None:
        node_with_no_error_message = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"This is a docstring.

                        Args:
                            arg: variable. Description.
                    \"\"\"
                    Something
        """)

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(
                node_with_no_error_message)

    def test_well_formed_multi_line_description_docstring(self) -> None:
        node_with_no_error_message = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"This is a docstring.

                        Args:
                            arg: bool. If true, individual key=value
                                pairs separated by '&' are
                                generated for each element of the value
                                sequence for the key.
                    \"\"\"
                    Something
        """)

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(
                node_with_no_error_message)

        node_with_no_error_message = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"This is a docstring.

                        Raises:
                            doseq. If true, individual
                                key=value pairs separated by '&' are
                                generated for each element of
                                the value sequence for the key
                                temp temp temp temp.
                            query. The query to be encoded.
                    \"\"\"
                    Something
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(
                node_with_no_error_message)

        node_with_no_error_message = astroid.extract_node(
            u"""def func(arg):
                    \"\"\"This is a docstring.

                        Returns:
                            str. The string parsed using
                            Jinja templating. Returns an error
                            string in case of error in parsing.

                        Yields:
                            tuple. For ExplorationStatsModel,
                            a 2-tuple of the form (exp_id, value)
                            where value is of the form.
                    \"\"\"
                    if True:
                        return Something
                    else:
                        yield something
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(
                node_with_no_error_message)

        node_with_no_error_message = astroid.extract_node(
            u"""def func(arg): #@
                    \"\"\"This is a docstring.

                        Returns:
                            str. From this item there
                            is things:
                                Jinja templating. Returns an error
                            string in case of error in parsing.

                        Yields:
                            tuple. For ExplorationStatsModel:
                                {key
                                    (sym)
                                }.
                    \"\"\"
                    if True:
                        return Something
                    else:
                        yield (a, b)
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(
                node_with_no_error_message)

    def test_checks_args_formatting_docstring(self) -> None:
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.DocstringParameterChecker)
        self.checker_test_object.setup_method()
        invalid_args_description_node = astroid.extract_node(
            """
        def func(test_var_one, test_var_two): #@
            \"\"\"Function to test docstring parameters.

            Args:
                test_var_one: int. First test variable.
                test_var_two: str. Second test variable.
                Incorrect description indentation

            Returns:
                int. The test result.
            \"\"\"
            result = test_var_one + test_var_two
            return result
        """)
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='8-space-indentation-for-arg-in-descriptions-doc',
                node=invalid_args_description_node,
                args='Incorrect'
            ),
            testutils.MessageTest(
                msg_id='malformed-args-section',
                node=invalid_args_description_node,
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_functiondef(
                invalid_args_description_node)

        invalid_param_indentation_node = astroid.extract_node(
            """
        def func(test_var_one): #@
            \"\"\"Function to test docstring parameters.

            Args:
                 test_var_one: int. First test variable.

            Returns:
                int. The test result.
            \"\"\"
            result = test_var_one + test_var_two
            return result
        """)
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='4-space-indentation-for-arg-parameters-doc',
                node=invalid_param_indentation_node,
                args='test_var_one:'
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_functiondef(
                invalid_param_indentation_node)

        invalid_header_indentation_node = astroid.extract_node(
            """
        def func(test_var_one): #@
            \"\"\"Function to test docstring parameters.

             Args:
                 test_var_one: int. First test variable.

            Returns:
                int. The test result.
            \"\"\"
            result = test_var_one + test_var_two
            return result
        """)
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='incorrect-indentation-for-arg-header-doc',
                node=invalid_header_indentation_node,
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_functiondef(
                invalid_header_indentation_node)

    def test_correct_args_formatting_docstring(self) -> None:
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.DocstringParameterChecker)
        self.checker_test_object.setup_method()
        valid_free_form_node = astroid.extract_node(
            """
        def func(test_var_one, test_var_two): #@
            \"\"\"Function to test docstring parameters.

            Args:
                test_var_one: int. First test variable.
                test_var_two: str. Second test variable:
                    Incorrect description indentation
                        {
                            key:
                        }.

            Returns:
                int. The test result.
            \"\"\"
            result = test_var_one + test_var_two
            return result
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(
                valid_free_form_node)

        valid_indentation_node = astroid.extract_node(
            """
        def func(test_var_one, test_var_two): #@
            \"\"\"Function to test docstring parameters.

            Args:
                test_var_one: int. First test variable.
                test_var_two: str. Second test variable:
                    Correct indentaion.

            Returns:
                int. The test result.
            \"\"\"
            result = test_var_one + test_var_two
            return result
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(
                valid_indentation_node)

        valid_indentation_with_kw_args_node = astroid.extract_node(
        """
        def func( #@
            test_var_one,
            *,
            test_var_two
        ):
            \"\"\"Function to test docstring parameters.

            Args:
                test_var_one: int. First test variable.
                test_var_two: str. Second test variable.

            Returns:
                int. The test result.
            \"\"\"
            result = test_var_one + test_var_two
            return result
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(
                valid_indentation_with_kw_args_node)

    def test_finds_docstring_parameter(self) -> None:
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.DocstringParameterChecker)
        self.checker_test_object.setup_method()
        valid_func_node, valid_return_node = astroid.extract_node(
            """
        def test(test_var_one, test_var_two): #@
            \"\"\"Function to test docstring parameters.

            Args:
                test_var_one: int. First test variable.
                test_var_two: str. Second test variable.

            Returns:
                int. The test result.
            \"\"\"
            result = test_var_one + test_var_two
            return result #@
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(valid_func_node)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_return(valid_return_node)

        valid_func_node, valid_yield_node = astroid.extract_node(
            """
        def test(test_var_one, test_var_two): #@
            \"\"\"Function to test docstring parameters.\"\"\"
            result = test_var_one + test_var_two
            yield result #@
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(valid_func_node)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_yield(valid_yield_node)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_return(valid_yield_node)

        (
            missing_yield_type_func_node,
            missing_yield_type_yield_node) = astroid.extract_node(
                """
        class Test:
            def __init__(self, test_var_one, test_var_two): #@
                \"\"\"Function to test docstring parameters.

                Args:
                    test_var_one: int. First test variable.
                    test_var_two: str. Second test variable.

                Returns:
                    int. The test result.
                \"\"\"
                result = test_var_one + test_var_two
                yield result #@
        """)
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='redundant-returns-doc',
                node=missing_yield_type_func_node
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_functiondef(
                missing_yield_type_func_node)
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='missing-yield-doc',
                node=missing_yield_type_func_node
            ), testutils.MessageTest(
                msg_id='missing-yield-type-doc',
                node=missing_yield_type_func_node
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_yieldfrom(
                missing_yield_type_yield_node)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_return(
                missing_yield_type_yield_node)

        (
            missing_return_type_func_node,
            missing_return_type_return_node) = astroid.extract_node(
                """
        class Test:
            def __init__(self, test_var_one, test_var_two): #@
                \"\"\"Function to test docstring parameters.

                Args:
                    test_var_one: int. First test variable.
                    test_var_two: str. Second test variable.

                Yields:
                    int. The test result.
                \"\"\"
                result = test_var_one + test_var_two
                return result #@
        """)
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='redundant-yields-doc',
                node=missing_return_type_func_node
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_functiondef(
                missing_return_type_func_node)
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='missing-return-doc',
                node=missing_return_type_func_node
            ), testutils.MessageTest(
                msg_id='missing-return-type-doc',
                node=missing_return_type_func_node
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_return(
                missing_return_type_return_node)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_yield(
                missing_return_type_return_node)

        valid_raise_node = astroid.extract_node(
            """
        def func(test_var_one, test_var_two):
            \"\"\"Function to test docstring parameters.

            Args:
                test_var_one: int. First test variable.
                test_var_two: str. Second test variable.

            Raises:
                Exception. An exception.
            \"\"\"
            raise Exception #@
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_raise(valid_raise_node)

        (
            missing_raise_type_func_node,
            missing_raise_type_raise_node) = astroid.extract_node(
                """
        def func(test_var_one, test_var_two): #@
            \"\"\"Function to test raising exceptions.

            Args:
                test_var_one: int. First test variable.
                test_var_two: str. Second test variable.
            \"\"\"
            raise Exception #@
        """)
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='missing-raises-doc',
                args=('Exception',),
                node=missing_raise_type_func_node
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_raise(
                missing_raise_type_raise_node)

        valid_raise_node = astroid.extract_node(
            """
        class Test:
            raise Exception #@
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_raise(valid_raise_node)

        valid_raise_node = astroid.extract_node(
            """
        class Test():
            @property
            def decorator_func(self):
                pass

            @decorator_func.setter
            @property
            def func(self):
                raise Exception #@
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_raise(valid_raise_node)

        valid_raise_node = astroid.extract_node(
            """
        class Test():
            def func(self):
                raise Exception #@
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_raise(valid_raise_node)

        valid_raise_node = astroid.extract_node(
            """
        def func():
            try:
                raise Exception #@
            except Exception:
                pass
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_raise(valid_raise_node)

        valid_raise_node = astroid.extract_node(
            """
        def func():
            \"\"\"Function to test raising exceptions.\"\"\"
            raise Exception #@
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_raise(valid_raise_node)

        valid_raise_node = astroid.extract_node(
            """
        def my_func(self):
            \"\"\"This is a docstring.
            :raises NameError: Never.
            \"\"\"
            def ex_func(val):
                return RuntimeError(val)
            raise ex_func('hi') #@
            raise NameError('hi')
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_raise(valid_raise_node)

        valid_raise_node = astroid.extract_node(
            """
        from unknown import Unknown
        def my_func(self):
            \"\"\"This is a docstring.
            :raises NameError: Never.
            \"\"\"
            raise Unknown('hi') #@
            raise NameError('hi')
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_raise(valid_raise_node)

        valid_raise_node = astroid.extract_node(
            """
        def my_func(self):
            \"\"\"This is a docstring.
            :raises NameError: Never.
            \"\"\"
            def ex_func(val):
                def inner_func(value):
                    return OSError(value)
                return RuntimeError(val)
            raise ex_func('hi') #@
            raise NameError('hi')
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_raise(valid_raise_node)

        valid_return_node = astroid.extract_node(
            """
        def func():
            \"\"\"Function to test return values.\"\"\"
            return None #@
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_return(valid_return_node)

        valid_return_node = astroid.extract_node(
            """
        def func():
            \"\"\"Function to test return values.\"\"\"
            return #@
        """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_return(valid_return_node)

        missing_param_func_node = astroid.extract_node(
            """
        def func(test_var_one, test_var_two, *args, **kwargs): #@
            \"\"\"Function to test docstring parameters.

            Args:
                test_var_one: int. First test variable.
                test_var_two: str. Second test variable.

            Returns:
                int. The test result.
            \"\"\"
            result = test_var_one + test_var_two
            return result
        """)
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='missing-param-doc',
                node=missing_param_func_node,
                args=('args, kwargs',),
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_functiondef(
                missing_param_func_node)

        missing_param_func_node = astroid.extract_node(
            """
        def func(test_var_one, test_var_two): #@
            \"\"\"Function to test docstring parameters.

            Args:
                test_var_one: int. First test variable.
                invalid_var_name: str. Second test variable.

            Returns:
                int. The test result.
            \"\"\"
            result = test_var_one + test_var_two
            return result
        """)
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='missing-param-doc',
                node=missing_param_func_node,
                args=('test_var_two',),
            ), testutils.MessageTest(
                msg_id='missing-type-doc',
                node=missing_param_func_node,
                args=('test_var_two',),
            ), testutils.MessageTest(
                msg_id='differing-param-doc',
                node=missing_param_func_node,
                args=('invalid_var_name',),
            ), testutils.MessageTest(
                msg_id='differing-type-doc',
                node=missing_param_func_node,
                args=('invalid_var_name',),
            ),
            testutils.MessageTest(
                msg_id='8-space-indentation-for-arg-in-descriptions-doc',
                node=missing_param_func_node,
                args='invalid_var_name:'
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_functiondef(
                missing_param_func_node)

        class_node, multiple_constructor_func_node = astroid.extract_node(
            """
        class Test(): #@
            \"\"\"Function to test docstring parameters.

            Args:
                test_var_one: int. First test variable.
                test_var_two: str. Second test variable.

            Returns:
                int. The test result.
            \"\"\"

            def __init__(self, test_var_one, test_var_two): #@
                \"\"\"Function to test docstring parameters.

                Args:
                    test_var_one: int. First test variable.
                    test_var_two: str. Second test variable.

                Returns:
                    int. The test result.
                \"\"\"
                result = test_var_one + test_var_two
                return result
        """)
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='multiple-constructor-doc',
                node=class_node,
                args=(class_node.name,),
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_functiondef(
                multiple_constructor_func_node)

    def test_visit_raise_warns_unknown_style(self) -> None:
        self.checker_test_object.checker.config.accept_no_raise_doc = False
        node = astroid.extract_node(
            """
        def my_func(self):
            \"\"\"This is a docstring.\"\"\"
            raise RuntimeError('hi')
        """)
        raise_node = node.body[0]
        func_node = raise_node.frame()
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='missing-raises-doc',
                args=('RuntimeError',),
                node=func_node
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_raise(raise_node)


class ImportOnlyModulesCheckerTests(unittest.TestCase):

    def test_finds_import_from(self) -> None:
        checker_test_object = testutils.CheckerTestCase()
        checker_test_object.CHECKER_CLASS = (
            pylint_extensions.ImportOnlyModulesChecker)
        checker_test_object.setup_method()
        importfrom_node1 = astroid.extract_node(
            """
            from os import path #@
            import sys
        """)
        with checker_test_object.assertNoMessages():
            checker_test_object.checker.visit_importfrom(importfrom_node1)

        importfrom_node2 = astroid.extract_node(
            """
            from os import error #@
            import sys
        """)
        with checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='import-only-modules',
                node=importfrom_node2,
                args=('error', 'os')
            ),
            ignore_position=True,
        ):
            checker_test_object.checker.visit_importfrom(
                importfrom_node2)

        importfrom_node3 = astroid.extract_node(
            """
            from invalid_module import invalid_module #@
        """)
        with checker_test_object.assertNoMessages():
            checker_test_object.checker.visit_importfrom(importfrom_node3)

        importfrom_node4 = astroid.extract_node(
            """
            from constants import constants #@
        """)
        with checker_test_object.assertNoMessages():
            checker_test_object.checker.visit_importfrom(importfrom_node4)

        importfrom_node5 = astroid.extract_node(
            """
            from os import invalid_module #@
        """)
        with checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='import-only-modules',
                node=importfrom_node5,
                args=('invalid_module', 'os')
            ),
            ignore_position=True,
        ):
            checker_test_object.checker.visit_importfrom(importfrom_node5)

        importfrom_node6 = astroid.extract_node(
            """
            from .constants import constants #@
        """, module_name='.constants')
        with checker_test_object.assertNoMessages():
            checker_test_object.checker.visit_importfrom(importfrom_node6)

    def test_importing_internals_from_allowed_modules_does_not_raise_message(
        self
    ) -> None:
        checker_test_object = testutils.CheckerTestCase()
        checker_test_object.CHECKER_CLASS = (
            pylint_extensions.ImportOnlyModulesChecker)
        checker_test_object.setup_method()
        importfrom_node = astroid.extract_node(
            """
            from __future__ import invalid_module #@
        """)
        with checker_test_object.assertNoMessages():
            checker_test_object.checker.visit_importfrom(importfrom_node)


class BackslashContinuationCheckerTests(unittest.TestCase):

    def test_finds_backslash_continuation(self) -> None:
        checker_test_object = testutils.CheckerTestCase()
        checker_test_object.CHECKER_CLASS = (
            pylint_extensions.BackslashContinuationChecker)
        checker_test_object.setup_method()
        node = astroid.scoped_nodes.Module(name='test', doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""message1 = 'abc'\\\n""" # pylint: disable=backslash-continuation
                """'cde'\\\n"""             # pylint: disable=backslash-continuation
                """'xyz'
                message2 = 'abc\\\\'
                message3 = (
                    'abc\\\\'
                    'xyz\\\\'
                )
                """)

        node.file = filename
        node.path = filename

        checker_test_object.checker.process_module(node)

        with checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='backslash-continuation',
                line=1
            ),
            testutils.MessageTest(
                msg_id='backslash-continuation',
                line=2
            ),
        ):
            temp_file.close()


class FunctionArgsOrderCheckerTests(unittest.TestCase):

    def test_finds_function_def(self) -> None:
        checker_test_object = testutils.CheckerTestCase()
        checker_test_object.CHECKER_CLASS = (
            pylint_extensions.FunctionArgsOrderChecker)
        checker_test_object.setup_method()
        functiondef_node1 = astroid.extract_node(
            """
        def test(self,test_var_one, test_var_two): #@
            result = test_var_one + test_var_two
            return result
        """)
        with checker_test_object.assertNoMessages():
            checker_test_object.checker.visit_functiondef(functiondef_node1)

        functiondef_node2 = astroid.extract_node(
            """
        def test(test_var_one, test_var_two, self): #@
            result = test_var_one + test_var_two
            return result
        """)
        with checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='function-args-order-self',
                node=functiondef_node2
            ),
            ignore_position=True,
        ):
            checker_test_object.checker.visit_functiondef(functiondef_node2)

        functiondef_node3 = astroid.extract_node(
            """
        def test(test_var_one, test_var_two, cls): #@
            result = test_var_one + test_var_two
            return result
        """)
        with checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='function-args-order-cls',
                node=functiondef_node3
            ),
            ignore_position=True,
        ):
            checker_test_object.checker.visit_functiondef(functiondef_node3)


class RestrictedImportCheckerTests(unittest.TestCase):

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.RestrictedImportChecker)
        self.checker_test_object.setup_method()
        # The spaces are included on purpose so that we properly test
        # the input sanitization.
        self.checker_test_object.checker.config.forbidden_imports = (
            (
                '*core.controllers*:\n'
                '    import core.platform*   |  \n'
                '    import core.storage*\n'
            ),
            (
                '*core.domain*:import core.controllers*'
            ),
            (
                '   *core.storage*:import    core.domain*   '
            ),
            (
                '*core.domain.*_domain:\n'
                '    from core.domain    import    *_service*   |\n'
                '    from   core.domain import *_cleaner|\n'
                '      from core.domain import *_registry |\n'
                '    from core.domain import *_fetchers  |\n'
                '    from core.domain import *_manager |\n'
                '       from core.platform import   models'
            )
        )
        self.checker_test_object.checker.open()

    def test_forbid_domain_import_in_storage_module(self) -> None:
        node_err_import = astroid.extract_node(
            """
            import core.domain.activity_domain #@
            """
        )
        node_err_import.root().name = 'oppia.core.storage.topic'
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='invalid-import',
                node=node_err_import,
                args=('core.domain*', '*core.storage*'),
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_import(node_err_import)

    def test_allow_platform_import_in_storage_module(self) -> None:
        node_no_err_import = astroid.extract_node(
            """
            import core.platform.email.mailgun_email_services #@
        """)
        node_no_err_import.root().name = 'oppia.core.storage.topic'
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_import(node_no_err_import)

    def test_forbid_domain_from_import_in_storage_module(self) -> None:
        node_err_importfrom = astroid.extract_node(
            """
            from core.domain import activity_domain #@
        """)
        node_err_importfrom.root().name = 'oppia.core.storage.topic'
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='invalid-import',
                node=node_err_importfrom,
                args=('core.domain*', '*core.storage*'),
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_importfrom(
                node_err_importfrom)

    def test_allow_platform_from_import_in_storage_module(self) -> None:
        node_no_err_importfrom = astroid.extract_node(
            """
            from core.platform.email import mailgun_email_services #@
        """)
        node_no_err_importfrom.root().name = 'oppia.core.storage.topicl'
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_importfrom(
                node_no_err_importfrom)

    def test_forbid_controllers_import_in_domain_module(self) -> None:
        node_err_import = astroid.extract_node(
            """
            import core.controllers.acl_decorators #@
        """)
        node_err_import.root().name = 'oppia.core.domain'
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='invalid-import',
                node=node_err_import,
                args=('core.controllers*', '*core.domain*'),
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_import(node_err_import)

    def test_allow_platform_import_in_domain_module(self) -> None:
        node_no_err_import = astroid.extract_node(
            """
            import core.platform.email.mailgun_email_services_test #@
        """)
        node_no_err_import.root().name = 'oppia.core.domain'
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_import(node_no_err_import)

    def test_forbid_controllers_from_import_in_domain_module(self) -> None:
        node_err_importfrom = astroid.extract_node(
            """
            from core.controllers import acl_decorators #@
            """
        )
        node_err_importfrom.root().name = 'oppia.core.domain'
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='invalid-import',
                node=node_err_importfrom,
                args=('core.controllers*', '*core.domain*'),
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_importfrom(
                node_err_importfrom)

    def test_allow_platform_from_import_in_domain_module(self) -> None:
        node_no_err_importfrom = astroid.extract_node(
            """
            from core.platform.email import mailgun_email_services_test #@
        """)
        node_no_err_importfrom.root().name = 'oppia.core.domain'
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_importfrom(
                node_no_err_importfrom)

    def test_forbid_service_import_in_domain_file(self) -> None:
        node_err_import = astroid.extract_node(
            """
            import core.domain.exp_services #@
            """
        )
        node_err_import.root().name = 'oppia.core.domain.exp_domain'
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='invalid-import-from',
                node=node_err_import,
                args=('*_service*', 'core.domain', '*core.domain.*_domain'),
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_import(node_err_import)

    def test_allow_domain_file_import_in_domain_file(self) -> None:
        node_no_err_import = astroid.extract_node(
            """
            import core.domain.collection_domain #@
            """
        )
        node_no_err_import.root().name = 'oppia.core.domain.topic_domain'
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_import(node_no_err_import)

    def test_forbid_cleaner_from_import_in_domain_file(self) -> None:
        node_err_importfrom = astroid.extract_node(
            """
            from core.domain import html_cleaner #@
            """
        )
        node_err_importfrom.root().name = 'oppia.core.domain.collection_domain'
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='invalid-import-from',
                node=node_err_importfrom,
                args=('*_cleaner', 'core.domain', '*core.domain.*_domain'),
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_importfrom(
                node_err_importfrom)

    def test_allow_domain_file_from_import_in_domain_file(self) -> None:
        node_no_err_importfrom = astroid.extract_node(
            """
            from core.domain import exp_domain #@
            """
        )
        node_no_err_importfrom.root().name = 'oppia.core.domain.story_domain'
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_importfrom(
                node_no_err_importfrom)

    def test_forbid_platform_import_in_controllers_module(self) -> None:
        node_err_import = astroid.extract_node(
            """
            import core.platform #@
        """)
        node_err_import.root().name = 'oppia.core.controllers.controller'
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='invalid-import',
                node=node_err_import,
                args=('core.platform*', '*core.controllers*'),
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_import(node_err_import)

    def test_forbid_storage_import_in_controllers_module(self) -> None:
        node_err_import = astroid.extract_node(
            """
            import core.storage #@
        """)
        node_err_import.root().name = 'oppia.core.controllers.controller'
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='invalid-import',
                node=node_err_import,
                args=('core.storage*', '*core.controllers*'),
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_import(node_err_import)

    def test_allow_domain_import_in_controllers_module(self) -> None:
        node_no_err_import = astroid.extract_node(
            """
            import core.domain #@
        """)
        node_no_err_import.root().name = 'oppia.core.controllers.controller'
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_import(node_no_err_import)

    def test_forbid_platform_from_import_in_controllers_module(self) -> None:
        node_no_err_importfrom = astroid.extract_node(
            """
            from core.platform import models #@
        """)
        node_no_err_importfrom.root().name = 'oppia.core.controllers.controller'
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='invalid-import',
                node=node_no_err_importfrom,
                args=('core.platform*', '*core.controllers*'),
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_importfrom(
                node_no_err_importfrom)

    def test_forbid_storage_from_import_in_controllers_module(self) -> None:
        node_no_err_importfrom = astroid.extract_node(
            """
            from core.storage.user import gae_models as user_models #@
        """)
        node_no_err_importfrom.root().name = 'oppia.core.controllers.controller'
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='invalid-import',
                node=node_no_err_importfrom,
                args=('core.storage*', '*core.controllers*'),
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_importfrom(
                node_no_err_importfrom)

    def test_allow_domain_from_import_in_controllers_module(self) -> None:
        node_no_err_importfrom = astroid.extract_node(
            """
            from core.domain import user_services #@
        """)
        node_no_err_importfrom.root().name = 'oppia.core.controllers.controller'
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_importfrom(
                node_no_err_importfrom)


class SingleCharAndNewlineAtEOFCheckerTests(unittest.TestCase):

    def test_checks_single_char_and_newline_eof(self) -> None:
        checker_test_object = testutils.CheckerTestCase()
        checker_test_object.CHECKER_CLASS = (
            pylint_extensions.SingleCharAndNewlineAtEOFChecker)
        checker_test_object.setup_method()
        node_missing_newline_at_eof = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""c = 'something dummy'
                """)
        node_missing_newline_at_eof.file = filename
        node_missing_newline_at_eof.path = filename

        checker_test_object.checker.process_module(node_missing_newline_at_eof)

        with checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='newline-at-eof',
                line=2
            ),
        ):
            temp_file.close()

        node_single_char_file = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')

        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name
        with utils.open_file(filename, 'w') as tmp:
            tmp.write(u"""1""")
        node_single_char_file.file = filename
        node_single_char_file.path = filename

        checker_test_object.checker.process_module(node_single_char_file)

        with checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='only-one-character',
                line=1
            ),
        ):
            temp_file.close()

        node_with_no_error_message = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')

        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name
        with utils.open_file(filename, 'w') as tmp:
            tmp.write(u"""x = 'something dummy'""")
        node_with_no_error_message.file = filename
        node_with_no_error_message.path = filename

        checker_test_object.checker.process_module(node_with_no_error_message)

        with checker_test_object.assertNoMessages():
            temp_file.close()


class TypeIgnoreCommentCheckerTests(unittest.TestCase):

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.TypeIgnoreCommentChecker)
        self.checker_test_object.setup_method()
        self.checker_test_object.checker.config.allowed_type_ignore_error_codes = [  # pylint: disable=line-too-long
            'attr-defined',
            'union-attr',
            'arg-type',
            'call-overload',
            'override',
            'return',
            'assignment',
            'list-item',
            'dict-item',
            'typeddict-item',
            'func-returns-value',
            'misc',
            'type-arg',
            'no-untyped-def',
            'no-untyped-call',
            'no-any-return'
        ]

    def test_type_ignore_used_without_comment_raises_error(self) -> None:
        node_function_with_type_ignore_only = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                suggestion.change.new_value = (  # type: ignore[attr-defined]
                    new_content
                ) #@
                """
            )
        node_function_with_type_ignore_only.file = filename

        message = testutils.MessageTest(
            msg_id='mypy-ignore-used',
            line=2,
            node=node_function_with_type_ignore_only
        )
        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(
                node_function_with_type_ignore_only
            )
        temp_file.close()

    def test_raises_error_if_prohibited_error_code_is_used(self) -> None:
        node_with_prohibited_error_code = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                suggestion.change.new_value = (  # type: ignore[some-new-ignore]
                    new_content
                ) #@
                """
            )
        node_with_prohibited_error_code.file = filename

        message = testutils.MessageTest(
            msg_id='prohibited-type-ignore-used',
            line=2,
            node=node_with_prohibited_error_code,
            args=('some-new-ignore',)
        )

        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(
                node_with_prohibited_error_code
            )
        temp_file.close()

        node_with_prohibited_type_ignore_error_code = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'
            )
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # Here we use MyPy ignore because ...
                suggestion.change.new_value = (  # type: ignore[attr-defined]
                    new_content
                )

                suggestion.change.new_value = (  # type: ignore[truthy-bool]
                    new_content
                )

                # Here we use MyPy ignore because ...
                func_only_accept_str('hi')  # type: ignore[attr-defined]

                #@
                """
            )
        node_with_prohibited_type_ignore_error_code.file = filename

        message = testutils.MessageTest(
            msg_id='prohibited-type-ignore-used',
            line=7,
            node=node_with_prohibited_type_ignore_error_code,
            args=('truthy-bool',)
        )
        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(
                node_with_prohibited_type_ignore_error_code
            )
        temp_file.close()

    def test_raises_error_if_prohibited_error_code_is_used_in_combined_form(
        self
    ) -> None:
        node_with_prohibited_error_code_in_combined_form = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'
            )
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                suggestion.change.new_value = (  # type: ignore[arg-type, no-untyped-call, truthy-bool] pylint: disable=line-too-long
                    new_content
                ) #@
                """
            )
        node_with_prohibited_error_code_in_combined_form.file = filename

        message = testutils.MessageTest(
            msg_id='prohibited-type-ignore-used',
            line=2,
            node=node_with_prohibited_error_code_in_combined_form,
            args=('truthy-bool',)
        )

        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(
                node_with_prohibited_error_code_in_combined_form
            )
        temp_file.close()

        node_with_multiple_prohibited_error_code_in_combined_form = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'
            )
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                suggestion.change.new_value = (  # type: ignore[return-none, no-untyped-call, truthy-bool] pylint: disable=line-too-long
                    new_content
                ) #@
                """
            )
        node_with_multiple_prohibited_error_code_in_combined_form.file = (
            filename)

        message = testutils.MessageTest(
            msg_id='prohibited-type-ignore-used',
            line=2,
            node=node_with_multiple_prohibited_error_code_in_combined_form,
            args=('return-none', 'truthy-bool')
        )

        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(
                node_with_multiple_prohibited_error_code_in_combined_form
            )
        temp_file.close()

    def test_extra_type_ignore_comment_used_in_a_module_raises_error(
        self
    ) -> None:
        node_function_with_extra_comment = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # Here we use MyPy ignore because ...
                suggestion.change.new_value = (   # type: ignore[attr-defined]
                    new_content
                )

                # Here we use MyPy ignore because ...
                suggestion.change.new_value = (
                    new_content
                )

                # Here we use MyPy ignore because ...
                func_only_accept_str('hi')   # type: ignore[attr-defined]

                # Here we use MyPy ignore because ...
                suggestion.change.new_value = (
                    new_content
                )
                #@
                """
            )
        node_function_with_extra_comment.file = filename

        message1 = testutils.MessageTest(
            msg_id='redundant-type-comment',
            line=7,
            node=node_function_with_extra_comment
        )
        message2 = testutils.MessageTest(
            msg_id='redundant-type-comment',
            line=15,
            node=node_function_with_extra_comment
        )
        with self.checker_test_object.assertAddsMessages(
            message1, message2
        ):
            self.checker_test_object.checker.visit_module(
                node_function_with_extra_comment
            )
        temp_file.close()

        node_function_with_extra_comment2 = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # Here we use MyPy ignore because ...
                suggestion.change.new_value = (   # type: ignore[attr-defined]
                    new_content
                )

                # Here we use MyPy ignore because ...
                suggestion.change.new_value = (
                    new_content
                )

                # Here we use MyPy ignore because ...
                func_only_accept_str('hi')   # type: ignore[attr-defined]
                #@
                """
            )
        node_function_with_extra_comment2.file = filename

        message = testutils.MessageTest(
            msg_id='redundant-type-comment',
            line=7,
            node=node_function_with_extra_comment2
        )
        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(
                node_function_with_extra_comment2
            )
        temp_file.close()

    def test_raises_error_if_type_ignore_is_in_second_place(self) -> None:
        node_with_type_ignore = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                suggestion.change.new_value = (  # pylint: disable=line-too-long type: ignore[attr-defined]
                    new_content
                )
                #@
                """
            )
        node_with_type_ignore.file = filename

        message = testutils.MessageTest(
            msg_id='mypy-ignore-used',
            line=2,
            node=node_with_type_ignore
        )
        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(
                node_with_type_ignore
            )
        temp_file.close()

    def test_type_ignores_with_comments_should_not_raises_error(self) -> None:
        node_with_type_ignore_in_single_form = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # Here we use MyPy ignore because attributes on BaseChange
                # class are defined dynamically.
                suggestion.change.new_value = (  # type: ignore[attr-defined]
                    new_content
                )

                # Here we use MyPy ignore because this function is can only
                # str values but here we are providing integer which causes
                # MyPy to throw an error. Thus to avoid the error, we used
                # ignore here.
                func_only_accept_str(1234)  # type: ignore[arg-type] #@
                """
            )
        node_with_type_ignore_in_single_form.file = filename

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_module(
                node_with_type_ignore_in_single_form
            )
        temp_file.close()

        node_with_type_ignore_in_combined_form = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # Here we use MyPy ignore because ...
                suggestion.change.new_value = (  # type: ignore[attr-defined, list-item]
                    new_content
                )

                # Here we use MyPy ignore because ...
                func_only_accept_str(1234)  # type: ignore[arg-type]
                #@
                """
            )
        node_with_type_ignore_in_combined_form.file = filename

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_module(
                node_with_type_ignore_in_combined_form
            )
        temp_file.close()

    def test_untyped_call_type_ignores_should_not_raise_error(self) -> None:
        node_function = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # Here we use MyPy ignore because attributes on BaseChange
                # class are defined dynamically.
                suggestion.change.new_value = (  # type: ignore[attr-defined]
                    new_content
                )

                func_only_accept_str(1234)  # type: ignore[no-untyped-call] #@
                """
            )
        node_function.file = filename

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_module(node_function)
        temp_file.close()

    def test_raises_error_if_gap_in_ignore_and_comment_is_more_than_fifteen(
        self
    ) -> None:
        node_with_ignore_and_more_than_fifteen_gap = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'
            )
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # Here we use MyPy ignore because stubs of protobuf are not
                # available yet.

                variable_one: str = '123'
                variable_two: str = '1234'
                # Some other content of module one.

                # Line 1 content.
                # Line 2 content.
                # Line 3 content.
                # Line 4 content.

                # Some other content of module two.

                def test_foo(arg: str) -> str:

                def foo(exp_id: str) -> str:  # type: ignore[arg-type]
                    return 'hi' #@
                """
            )
        node_with_ignore_and_more_than_fifteen_gap.file = filename

        message1 = testutils.MessageTest(
            msg_id='mypy-ignore-used',
            line=18,
            node=node_with_ignore_and_more_than_fifteen_gap
        )
        message2 = testutils.MessageTest(
            msg_id='redundant-type-comment',
            line=2,
            node=node_with_ignore_and_more_than_fifteen_gap
        )
        with self.checker_test_object.assertAddsMessages(
            message1, message2
        ):
            self.checker_test_object.checker.visit_module(
                node_with_ignore_and_more_than_fifteen_gap
            )
        temp_file.close()

    def test_generic_type_ignore_raises_pylint_error(self) -> None:
        node_with_generic_type_ignore = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # TODO(#sll): Here we use MyPy ignore because stubs of protobuf
                # are not available yet.

                def foo(exp_id: str) -> str:  # type: ignore
                    return 'hi' #@
                """
            )
        node_with_generic_type_ignore.file = filename

        message1 = testutils.MessageTest(
            msg_id='generic-mypy-ignore-used',
            line=5,
            node=node_with_generic_type_ignore
        )
        message2 = testutils.MessageTest(
            msg_id='redundant-type-comment',
            line=2,
            node=node_with_generic_type_ignore
        )

        with self.checker_test_object.assertAddsMessages(
            message1, message2
        ):
            self.checker_test_object.checker.visit_module(
                node_with_generic_type_ignore
            )
        temp_file.close()

        node_with_both_generic_and_non_generic_type_ignores = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'
            )
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # TODO(#sll): Here we use MyPy ignore because stubs of protobuf
                # are not available yet.
                def foo(exp_id: str) -> str:  # type: ignore[arg-type]
                    return 'hi' #@

                def foo(exp_id: str) -> str:  # type: ignore
                    return 'hi' #@

                # TODO(#sll): Here we use MyPy ignore because stubs of protobuf
                # are not available yet.
                def foo(exp_id: str) -> str:  # type: ignore[misc]
                    return 'hi' #@
                """
            )
        node_with_both_generic_and_non_generic_type_ignores.file = filename

        message1 = testutils.MessageTest(
            msg_id='generic-mypy-ignore-used',
            line=7,
            node=node_with_both_generic_and_non_generic_type_ignores
        )

        with self.checker_test_object.assertAddsMessages(message1):
            self.checker_test_object.checker.visit_module(
                node_with_both_generic_and_non_generic_type_ignores
            )
        temp_file.close()

    def test_raises_no_error_if_todo_is_present_initially(self) -> None:
        node_with_ignore_having_todo = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # TODO(#sll): Here we use MyPy ignore because stubs of protobuf
                # are not available yet.

                def foo(exp_id: str) -> str:  # type: ignore[arg-type]
                    return 'hi' #@
                """
            )
        node_with_ignore_having_todo.file = filename

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_module(
                node_with_ignore_having_todo
            )
        temp_file.close()


class ExceptionalTypesCommentCheckerTests(unittest.TestCase):

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.ExceptionalTypesCommentChecker)
        self.checker_test_object.setup_method()

    def test_raises_error_if_exceptional_types_are_used_without_comment(
        self
    ) -> None:
        # Checking for Any type.
        node_with_any_type = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                schema_dict: Dict[str, Any] = {
                    'key': 'value'
                } #@
                """
            )
        node_with_any_type.file = filename

        message = testutils.MessageTest(
            msg_id='any-type-used',
            line=2,
            node=node_with_any_type
        )
        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(node_with_any_type)
        temp_file.close()

        # Checking for object class.
        node_with_object_type = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                func(proto_buff_stuff: object) #@
                """
            )
        node_with_object_type.file = filename

        message = testutils.MessageTest(
            msg_id='object-class-used',
            line=2,
            node=node_with_object_type
        )
        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(node_with_object_type)
        temp_file.close()

        # Checking for cast method.
        node_with_cast_method = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                func(cast(str, change.new_value)) #@
                """
            )
        node_with_cast_method.file = filename

        message = testutils.MessageTest(
            msg_id='cast-func-used',
            line=2,
            node=node_with_cast_method
        )
        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(node_with_cast_method)
        temp_file.close()

    def test_raises_error_if_exceptional_types_are_combined_in_module(
        self
    ) -> None:
        node_with_combined_types = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                schema_dict: Dict[str, Any] = {
                    'key': 'value'
                }

                def func(proto_buff_stuff: object) -> None:
                    pass

                # Some other contents of the module.

                # Here we use object because to test the linters.
                new_object: object = 'strong hi'

                # We are not considering this case.
                var = object()
                new_string = 'hi'

                change_value = cast(str, change.new_value) #@
                """
            )
        node_with_combined_types.file = filename

        message1 = testutils.MessageTest(
            msg_id='any-type-used',
            line=2,
            node=node_with_combined_types
        )
        message2 = testutils.MessageTest(
            msg_id='object-class-used',
            line=6,
            node=node_with_combined_types
        )
        message3 = testutils.MessageTest(
            msg_id='cast-func-used',
            line=18,
            node=node_with_combined_types
        )
        with self.checker_test_object.assertAddsMessages(
            message1, message3, message2
        ):
            self.checker_test_object.checker.visit_module(
                node_with_combined_types
            )
        temp_file.close()

    def test_raises_error_if_any_type_used_in_function_signature(
        self
    ) -> None:
        node_with_any_type_arg = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                def foo(*args: Any) -> None:
                    pass #@
                """
            )
        node_with_any_type_arg.file = filename

        message = testutils.MessageTest(
            msg_id='any-type-used',
            line=2,
            node=node_with_any_type_arg
        )
        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(
                node_with_any_type_arg
            )
        temp_file.close()

        node_with_any_type_return = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                def foo(*args: str) -> Any:
                    pass #@
                """
            )
        node_with_any_type_return.file = filename

        message = testutils.MessageTest(
            msg_id='any-type-used',
            line=2,
            node=node_with_any_type_return
        )
        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(
                node_with_any_type_return
            )
        temp_file.close()

        node_with_any_type_return_and_args = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                def foo(*args: Any) -> Any:
                    pass #@
                """
            )
        node_with_any_type_return_and_args.file = filename

        message = testutils.MessageTest(
            msg_id='any-type-used',
            line=2,
            node=node_with_any_type_return_and_args
        )
        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(
                node_with_any_type_return_and_args
            )
        temp_file.close()

        node_with_multiple_any_type_functions = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                def foo(*args: Any) -> Any:
                    pass

                def foo1(arg1: str) -> int:
                    pass

                def foo2(*args: str) -> Any:
                    pass #@
                """
            )
        node_with_multiple_any_type_functions.file = filename

        message = testutils.MessageTest(
            msg_id='any-type-used',
            line=2,
            node=node_with_multiple_any_type_functions
        )
        message2 = testutils.MessageTest(
            msg_id='any-type-used',
            line=8,
            node=node_with_multiple_any_type_functions
        )
        with self.checker_test_object.assertAddsMessages(
            message, message2
        ):
            self.checker_test_object.checker.visit_module(
                node_with_multiple_any_type_functions
            )
        temp_file.close()

    def test_any_and_cast_will_not_raise_error_in_import(self) -> None:
        node_with_any_and_cast_imported = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                from typing import Any, cast #@
                """
            )
        node_with_any_and_cast_imported.file = filename

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_module(
                node_with_any_and_cast_imported
            )
        temp_file.close()

        node_with_any_and_cast_in_multi_line_import = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'
            )
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                from typing import (
                    Any, Dict, List, Optional, cast
                ) #@
                """
            )
        node_with_any_and_cast_in_multi_line_import.file = filename

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_module(
                node_with_any_and_cast_in_multi_line_import
            )
        temp_file.close()

    def test_exceptional_types_with_comments_should_not_raise_error(
        self
    ) -> None:
        node_with_any_type_and_comment = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                from typing import Any

                # Here we use type Any because, this function can take
                # any argument.
                def foo(arg1: Any) -> None
                    pass

                # Some other contents of the Module.
                new_var: str = 'hi'

                # Here we use type Any because, schema dicts can accept
                # any value.
                schema_dict: Dict[str, Any] = {
                    'key': 'value'
                }

                def foo1(arg2: str) -> None
                    # Here we use type Any because, new_value can accept any
                    # value.
                    new_value: Any = 'hi' #@
                """
            )
        node_with_any_type_and_comment.file = filename

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_module(
                node_with_any_type_and_comment
            )
        temp_file.close()

        node_with_cast_method_and_comment = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                from typing import Any, cast

                # Here we use type Any because, this function can take
                # any argument.
                def foo(arg1: Any) -> None
                    pass

                # Here we use cast because we are narrowing down the object
                # to string object.
                new_var: str = cast(str, object())

                # Here we use type Any because, schema dicts can accept
                # any value.
                schema_dict: Dict[str, Any] = {
                    'key': 'value'
                }

                # Here we use object because stubs of protobuf are not
                # available yet. So, instead of Any we used object here.
                def save_classifier_data(
                    exp_id: str,
                    job_id: str,
                    classifier_data_proto: object
                ) -> None:
                    pass #@
                """
            )
        node_with_cast_method_and_comment.file = filename

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_module(
                node_with_cast_method_and_comment
            )
        temp_file.close()

    def test_no_error_raised_if_objects_are_present_with_comment(
        self
    ) -> None:
        node_with_multiple_objects_in_func = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # Here we use object because stubs of protobuf are not
                # available yet. So, instead of Any we used object here.
                def foo(exp_id: object) -> object:
                    return 'hi' #@
                """
            )
        node_with_multiple_objects_in_func.file = filename

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_module(
                node_with_multiple_objects_in_func
            )
        temp_file.close()

    def test_raises_error_if_gap_between_type_and_comment_is_more_than_fifteen(
        self
    ) -> None:
        node_with_object_and_more_than_expected_gap = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'
            )
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # Here we use object because stubs of protobuf are not
                # available yet. So, instead of Any we used object here.

                variable_one: str = '123'
                variable_two: str = '1234'
                # Some other content of module one.

                # Line 1 content.
                # Line 2 content.
                # Line 3 content.
                # Line 4 content.

                # Some other content of module two.

                def test_foo(arg: str) -> str:

                def foo(exp_id: str) -> object:
                    return 'hi' #@
                """
            )
        node_with_object_and_more_than_expected_gap.file = filename

        message = testutils.MessageTest(
            msg_id='object-class-used',
            line=18,
            node=node_with_object_and_more_than_expected_gap
        )
        with self.checker_test_object.assertAddsMessages(message):
            self.checker_test_object.checker.visit_module(
                node_with_object_and_more_than_expected_gap
            )
        temp_file.close()

        node_with_object_and_less_than_fifteen_gap = (
            astroid.scoped_nodes.Module(
                name='test',
                doc='Custom test'
            )
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # Here we use object because stubs of protobuf are not
                # available yet. So, instead of Any we used object here.

                variable_one: str = '123'
                variable_two: str = '1234'
                # Some other content of module one.

                def test_foo(arg: str) -> str:

                def foo(exp_id: str) -> object:
                    return 'hi' #@
                """
            )
        node_with_object_and_less_than_fifteen_gap.file = filename

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_module(
                node_with_object_and_less_than_fifteen_gap
            )
        temp_file.close()

    def test_no_error_raised_if_objects_are_present_with_todo_comment(
        self
    ) -> None:
        node_with_object_and_todo_comment = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test'
        )
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                # TODO(#sll): Here we use object because stubs of protobuf
                # are not available yet. So, instead of Any we used object
                # here.
                def foo(exp_id: object) -> object:
                    return 'hi' #@
                """
            )
        node_with_object_and_todo_comment.file = filename

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_module(
                node_with_object_and_todo_comment
            )
        temp_file.close()


class SingleLineCommentCheckerTests(unittest.TestCase):

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.SingleLineCommentChecker)
        self.checker_test_object.setup_method()

    def test_invalid_punctuation(self) -> None:
        node_invalid_punctuation = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""# This is a multiline
                # comment/

                # Comment.
                """)
        node_invalid_punctuation.file = filename
        node_invalid_punctuation.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_invalid_punctuation))

        message = testutils.MessageTest(
            msg_id='invalid-punctuation-used',
            line=2)

        with self.checker_test_object.assertAddsMessages(message):
            temp_file.close()

    def test_no_space_at_beginning(self) -> None:
        node_no_space_at_beginning = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""#Something.
                """)
        node_no_space_at_beginning.file = filename
        node_no_space_at_beginning.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_no_space_at_beginning))

        message = testutils.MessageTest(
            msg_id='no-space-at-beginning',
            line=1)

        with self.checker_test_object.assertAddsMessages(message):
            temp_file.close()

    def test_no_capital_letter_at_beginning(self) -> None:
        node_no_capital_letter_at_beginning = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""# coding: utf-8

                    # something.
                """)
        node_no_capital_letter_at_beginning.file = filename
        node_no_capital_letter_at_beginning.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_no_capital_letter_at_beginning))

        message = testutils.MessageTest(
            msg_id='no-capital-letter-at-beginning',
            line=3)

        with self.checker_test_object.assertAddsMessages(message):
            temp_file.close()

    def test_comment_with_excluded_phrase(self) -> None:
        node_comment_with_excluded_phrase = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""# coding: utf-8
                # pylint: disable
                a = 1 + 2  # pylint: disable
                """)
        node_comment_with_excluded_phrase.file = filename
        node_comment_with_excluded_phrase.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_comment_with_excluded_phrase))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_inline_comment_with_allowed_pragma_raises_no_error(self) -> None:
        node_inline_comment_with_allowed_pragma = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""a = 1 + 2  # type: ignore[some-rule]
                """)

        node_inline_comment_with_allowed_pragma.file = filename
        node_inline_comment_with_allowed_pragma.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(
               node_inline_comment_with_allowed_pragma))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_inline_comment_with_multiple_allowed_pragmas_raises_no_error(
        self
    ) -> None:
        node_inline_comment_with_allowed_pragma = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""a = 1 + 2  # isort:skip # pylint: ignore[some-rule]
                """)

        node_inline_comment_with_allowed_pragma.file = filename
        node_inline_comment_with_allowed_pragma.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(
               node_inline_comment_with_allowed_pragma))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_inline_comment_with_invalid_pragma_raises_error(self) -> None:
        node_inline_comment_with_invalid_pragma = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""a = 1 + 2  # not_a_valid_pragma
                """)

        node_inline_comment_with_invalid_pragma.file = filename
        node_inline_comment_with_invalid_pragma.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(
               node_inline_comment_with_invalid_pragma))

        message = testutils.MessageTest(
            msg_id='no-allowed-inline-pragma',
            line=1)

        with self.checker_test_object.assertAddsMessages(message):
            temp_file.close()

    def test_variable_name_in_comment(self) -> None:
        node_variable_name_in_comment = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""# coding: utf-8

                # variable_name is used.
                """)
        node_variable_name_in_comment.file = filename
        node_variable_name_in_comment.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_variable_name_in_comment))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_comment_with_version_info(self) -> None:
        node_comment_with_version_info = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""# coding: utf-8

                # v2 is used.
                """)
        node_comment_with_version_info.file = filename
        node_comment_with_version_info.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_comment_with_version_info))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_data_type_in_comment(self) -> None:
        node_data_type_in_comment = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""# coding: utf-8

                # str. variable is type of str.
                """)
        node_data_type_in_comment.file = filename
        node_data_type_in_comment.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_data_type_in_comment))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_comment_inside_docstring(self) -> None:
        node_comment_inside_docstring = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""# coding: utf-8
                    \"\"\"# str. variable is type of str.\"\"\"
                    \"\"\"# str. variable is type
                    of str.\"\"\"
                """)
        node_comment_inside_docstring.file = filename
        node_comment_inside_docstring.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_comment_inside_docstring))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_well_formed_comment(self) -> None:
        node_with_no_error_message = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""# coding: utf-8

                # Multi
                # line
                # comment.
                """)
        node_with_no_error_message.file = filename
        node_with_no_error_message.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_with_no_error_message))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()


class BlankLineBelowFileOverviewCheckerTests(unittest.TestCase):

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.BlankLineBelowFileOverviewChecker)
        self.checker_test_object.setup_method()

    def test_no_empty_line_below_fileoverview(self) -> None:
        node_no_empty_line_below_fileoverview = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    \"\"\" this file does something \"\"\"
                    import something
                    import random
                """)
        node_no_empty_line_below_fileoverview.file = filename
        node_no_empty_line_below_fileoverview.path = filename
        node_no_empty_line_below_fileoverview.fromlineno = 2

        self.checker_test_object.checker.visit_module(
            node_no_empty_line_below_fileoverview)

        message = testutils.MessageTest(
            msg_id='no-empty-line-provided-below-fileoverview',
            node=node_no_empty_line_below_fileoverview)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            temp_file.close()

    def test_extra_empty_lines_below_fileoverview(self) -> None:
        node_extra_empty_lines_below_fileoverview = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""

                    \"\"\" this file does something \"\"\"


                    import something
                    from something import random
                """)
        node_extra_empty_lines_below_fileoverview.file = filename
        node_extra_empty_lines_below_fileoverview.path = filename
        node_extra_empty_lines_below_fileoverview.fromlineno = 2

        self.checker_test_object.checker.visit_module(
            node_extra_empty_lines_below_fileoverview)

        message = testutils.MessageTest(
            msg_id='only-a-single-empty-line-should-be-provided',
            node=node_extra_empty_lines_below_fileoverview)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            temp_file.close()

    def test_extra_empty_lines_below_fileoverview_with_unicode_characters(
        self
    ) -> None:
        node_extra_empty_lines_below_fileoverview = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    #this comment has a unicode character \u2713
                    \"\"\" this file does \u2715 something \"\"\"


                    from something import random
                """)
        node_extra_empty_lines_below_fileoverview.file = filename
        node_extra_empty_lines_below_fileoverview.path = filename
        node_extra_empty_lines_below_fileoverview.fromlineno = 3

        self.checker_test_object.checker.visit_module(
            node_extra_empty_lines_below_fileoverview)

        message = testutils.MessageTest(
            msg_id='only-a-single-empty-line-should-be-provided',
            node=node_extra_empty_lines_below_fileoverview)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            temp_file.close()

    def test_no_empty_line_below_fileoverview_with_unicode_characters(
        self
    ) -> None:
        node_no_empty_line_below_fileoverview = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    #this comment has a unicode character \u2713
                    \"\"\" this file does \u2715 something \"\"\"
                    import something
                    import random
                """)
        node_no_empty_line_below_fileoverview.file = filename
        node_no_empty_line_below_fileoverview.path = filename
        node_no_empty_line_below_fileoverview.fromlineno = 3

        self.checker_test_object.checker.visit_module(
            node_no_empty_line_below_fileoverview)

        message = testutils.MessageTest(
            msg_id='no-empty-line-provided-below-fileoverview',
            node=node_no_empty_line_below_fileoverview)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            temp_file.close()

    def test_single_new_line_below_file_overview(self) -> None:
        node_with_no_error_message = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    \"\"\" this file does something \"\"\"

                    import something
                    import random
                """)
        node_with_no_error_message.file = filename
        node_with_no_error_message.path = filename
        node_with_no_error_message.fromlineno = 2

        self.checker_test_object.checker.visit_module(
            node_with_no_error_message)

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_file_with_no_file_overview(self) -> None:
        node_file_with_no_file_overview = astroid.scoped_nodes.Module(
            name='test',
            doc=None)
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    import something
                    import random
                """)
        node_file_with_no_file_overview.file = filename
        node_file_with_no_file_overview.path = filename

        self.checker_test_object.checker.visit_module(
            node_file_with_no_file_overview)

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_file_overview_at_end_of_file(self) -> None:
        node_file_overview_at_end_of_file = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    \"\"\" this file does something \"\"\"   """)
        node_file_overview_at_end_of_file.file = filename
        node_file_overview_at_end_of_file.path = filename
        node_file_overview_at_end_of_file.fromlineno = 2

        self.checker_test_object.checker.visit_module(
            node_file_overview_at_end_of_file)

        message = testutils.MessageTest(
            msg_id='only-a-single-empty-line-should-be-provided',
            node=node_file_overview_at_end_of_file)

        with self.checker_test_object.assertAddsMessages(
            message, ignore_position=True
        ):
            temp_file.close()


class SingleLinePragmaCheckerTests(unittest.TestCase):

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.SingleLinePragmaChecker)
        self.checker_test_object.setup_method()

    def test_pragma_for_multiline(self) -> None:
        node_pragma_for_multiline = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    # pylint: disable=invalid-name
                    def funcName():
                        \"\"\" # pylint: disable=test-purpose\"\"\"
                        pass
                    # pylint: enable=invalid-name
                """)
        node_pragma_for_multiline.file = filename
        node_pragma_for_multiline.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_pragma_for_multiline))

        message1 = testutils.MessageTest(
            msg_id='single-line-pragma',
            line=2)

        message2 = testutils.MessageTest(
            msg_id='single-line-pragma',
            line=6)

        with self.checker_test_object.assertAddsMessages(
            message1, message2):
            temp_file.close()

    def test_enable_single_line_pragma_for_multiline(self) -> None:
        node_enable_single_line_pragma_for_multiline = (
            astroid.scoped_nodes.Module(name='test', doc='Custom test'))
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    # pylint: disable=single-line-pragma
                    def func():
                        \"\"\"
                        # pylint: disable=testing-purpose
                        \"\"\"
                        pass
                    # pylint: enable=single-line-pragma
                """)
        node_enable_single_line_pragma_for_multiline.file = filename
        node_enable_single_line_pragma_for_multiline.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(
               node_enable_single_line_pragma_for_multiline))

        message = testutils.MessageTest(
            msg_id='single-line-pragma',
            line=2)

        with self.checker_test_object.assertAddsMessages(message):
            temp_file.close()

    def test_enable_single_line_pragma_with_invalid_name(self) -> None:
        node_enable_single_line_pragma_with_invalid_name = (
            astroid.scoped_nodes.Module(name='test', doc='Custom test'))
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    # pylint: disable=invalid-name, single-line-pragma
                    def funcName():
                        \"\"\"
                        # pylint: disable=testing-purpose
                        \"\"\"
                        pass
                    # pylint: enable=invalid_name, single-line-pragma
                """)
        node_enable_single_line_pragma_with_invalid_name.file = filename
        node_enable_single_line_pragma_with_invalid_name.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(
                node_enable_single_line_pragma_with_invalid_name))

        message = testutils.MessageTest(
            msg_id='single-line-pragma',
            line=2)

        with self.checker_test_object.assertAddsMessages(message):
            temp_file.close()

    def test_single_line_pylint_pragma(self) -> None:
        node_with_no_error_message = (
            astroid.scoped_nodes.Module(name='test', doc='Custom test'))
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    def funcName():  # pylint: disable=single-line-pragma
                        pass
                """)
        node_with_no_error_message.file = filename
        node_with_no_error_message.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_with_no_error_message))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()

    def test_no_and_extra_space_before_pylint(self) -> None:
        node_no_and_extra_space_before_pylint = (
            astroid.scoped_nodes.Module(name='test', doc='Custom test'))
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                    # pylint:disable=single-line-pragma
                    def func():
                        \"\"\"
                        # pylint: disable=testing-purpose
                        \"\"\"
                        pass
                    # pylint:     enable=single-line-pragma
                """)
        node_no_and_extra_space_before_pylint.file = filename
        node_no_and_extra_space_before_pylint.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_no_and_extra_space_before_pylint))

        message = testutils.MessageTest(
            msg_id='single-line-pragma',
            line=2)

        with self.checker_test_object.assertAddsMessages(message):
            temp_file.close()


class SingleSpaceAfterKeyWordCheckerTests(unittest.TestCase):

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.SingleSpaceAfterKeyWordChecker)
        self.checker_test_object.setup_method()

    def test_no_space_after_keyword(self) -> None:
        node_no_space_after_keyword = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                if(False):
                    pass
                elif(True):
                    pass
                while(True):
                    pass
                yield(1)
                return True if(True) else False
                """)
        node_no_space_after_keyword.file = filename
        node_no_space_after_keyword.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_no_space_after_keyword))

        if_message = testutils.MessageTest(
            msg_id='single-space-after-keyword', args=('if'), line=2)
        elif_message = testutils.MessageTest(
            msg_id='single-space-after-keyword', args=('elif'), line=4)
        while_message = testutils.MessageTest(
            msg_id='single-space-after-keyword', args=('while'), line=6)
        yield_message = testutils.MessageTest(
            msg_id='single-space-after-keyword', args=('yield'), line=8)
        if_exp_message = testutils.MessageTest(
            msg_id='single-space-after-keyword', args=('if'), line=9)

        with self.checker_test_object.assertAddsMessages(
            if_message, elif_message, while_message, yield_message,
            if_exp_message):
            temp_file.close()

    def test_multiple_spaces_after_keyword(self) -> None:
        node_multiple_spaces_after_keyword = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                if  False:
                    pass
                elif  True:
                    pass
                while  True:
                    pass
                yield  1
                return True if  True else False
                """)
        node_multiple_spaces_after_keyword.file = filename
        node_multiple_spaces_after_keyword.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_multiple_spaces_after_keyword))

        if_message = testutils.MessageTest(
            msg_id='single-space-after-keyword', args=('if'), line=2)
        elif_message = testutils.MessageTest(
            msg_id='single-space-after-keyword', args=('elif'), line=4)
        while_message = testutils.MessageTest(
            msg_id='single-space-after-keyword', args=('while'), line=6)
        yield_message = testutils.MessageTest(
            msg_id='single-space-after-keyword', args=('yield'), line=8)
        if_exp_message = testutils.MessageTest(
            msg_id='single-space-after-keyword', args=('if'), line=9)

        with self.checker_test_object.assertAddsMessages(
            if_message, elif_message, while_message, yield_message,
            if_exp_message):
            temp_file.close()

    def test_single_space_after_keyword(self) -> None:
        node_single_space_after_keyword = astroid.scoped_nodes.Module(
            name='test',
            doc='Custom test')
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name

        with utils.open_file(filename, 'w') as tmp:
            tmp.write(
                u"""
                if False:
                    pass
                elif True:
                    pass
                while True:
                    pass
                yield 1
                return True if True else False
                """)
        node_single_space_after_keyword.file = filename
        node_single_space_after_keyword.path = filename

        self.checker_test_object.checker.process_tokens(
           pylint_utils.tokenize_module(node_single_space_after_keyword))

        with self.checker_test_object.assertNoMessages():
            temp_file.close()


class InequalityWithNoneCheckerTests(unittest.TestCase):

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.InequalityWithNoneChecker)
        self.checker_test_object.setup_method()

    def test_inequality_op_on_none_adds_message(self) -> None:
        if_node = astroid.extract_node(
            """
            if x != None: #@
                pass
            """
        )
        compare_node = if_node.test
        not_equal_none_message = testutils.MessageTest(
            msg_id='inequality-with-none', node=compare_node)
        with self.checker_test_object.assertAddsMessages(
            not_equal_none_message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_compare(compare_node)

    def test_inequality_op_on_none_with_wrapped_none_adds_message(
        self
    ) -> None:
        if_node = astroid.extract_node(
            """
            if x != ( #@
                None
            ):
                pass
            """
        )
        compare_node = if_node.test
        not_equal_none_message = testutils.MessageTest(
            msg_id='inequality-with-none', node=compare_node)
        with self.checker_test_object.assertAddsMessages(
            not_equal_none_message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_compare(compare_node)

    def test_usage_of_is_not_on_none_does_not_add_message(self) -> None:
        if_node = astroid.extract_node(
            """
            if x is not None: #@
                pass
            """
        )
        compare_node = if_node.test
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_compare(compare_node)


class DisallowedFunctionsCheckerTests(unittest.TestCase):
    """Unit tests for DisallowedFunctionsChecker"""

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.DisallowedFunctionsChecker)
        self.checker_test_object.setup_method()

    def test_disallowed_removals_str(self) -> None:
        (
            self.checker_test_object
            .checker.config.disallowed_functions_and_replacements_str) = [
                'example_func',
                'a.example_attr',
            ]
        self.checker_test_object.checker.open()

        call1, call2 = astroid.extract_node(
            """
        example_func() #@
        a.example_attr() #@
        """)

        message_remove_example_func = testutils.MessageTest(
            msg_id='remove-disallowed-function-calls',
            node=call1,
            args='example_func',
            confidence=interfaces.UNDEFINED
        )

        message_remove_example_attr = testutils.MessageTest(
            msg_id='remove-disallowed-function-calls',
            node=call2,
            args='a.example_attr',
            confidence=interfaces.UNDEFINED
        )

        with self.checker_test_object.assertAddsMessages(
            message_remove_example_func,
            message_remove_example_attr,
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_call(call1)
            self.checker_test_object.checker.visit_call(call2)

    def test_disallowed_replacements_str(self) -> None:
        (
            self.checker_test_object
            .checker.config.disallowed_functions_and_replacements_str) = [
                'datetime.datetime.now=>datetime.datetime.utcnow',
                'self.assertEquals=>self.assertEqual',
            ]
        self.checker_test_object.checker.open()

        call1, call2, call3 = astroid.extract_node(
        """
            datetime.datetime.now() #@
            self.assertEquals() #@
            b.a.next() #@
        """)

        message_replace_disallowed_datetime = testutils.MessageTest(
            msg_id='replace-disallowed-function-calls',
            node=call1,
            args=('datetime.datetime.now', 'datetime.datetime.utcnow'),
            confidence=interfaces.UNDEFINED
        )

        message_replace_disallowed_assert_equals = testutils.MessageTest(
            msg_id='replace-disallowed-function-calls',
            node=call2,
            args=('self.assertEquals', 'self.assertEqual'),
            confidence=interfaces.UNDEFINED
        )

        with self.checker_test_object.assertAddsMessages(
            message_replace_disallowed_datetime,
            message_replace_disallowed_assert_equals,
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_call(call1)
            self.checker_test_object.checker.visit_call(call2)

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_call(call3)

    def test_disallowed_removals_regex(self) -> None:
        (
            self.checker_test_object
            .checker.config.disallowed_functions_and_replacements_regex) = [
                r'.*example_func',
                r'.*\..*example_attr'
            ]
        self.checker_test_object.checker.open()

        call1, call2 = astroid.extract_node(
            """
        somethingexample_func() #@
        c.someexample_attr() #@
        """)

        message_remove_example_func = testutils.MessageTest(
            msg_id='remove-disallowed-function-calls',
            node=call1,
            args='somethingexample_func',
            confidence=interfaces.UNDEFINED
        )

        message_remove_example_attr = testutils.MessageTest(
            msg_id='remove-disallowed-function-calls',
            node=call2,
            args='c.someexample_attr',
            confidence=interfaces.UNDEFINED
        )

        with self.checker_test_object.assertAddsMessages(
            message_remove_example_func,
            message_remove_example_attr,
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_call(call1)
            self.checker_test_object.checker.visit_call(call2)

    def test_disallowed_replacements_regex(self) -> None:
        (
            self.checker_test_object
            .checker.config.disallowed_functions_and_replacements_regex) = [
                r'.*example_func=>other_func',
                r'.*\.example_attr=>other_attr',
            ]
        self.checker_test_object.checker.open()

        call1, call2, call3, call4 = astroid.extract_node(
            """
        somethingexample_func() #@
        d.example_attr() #@
        d.example_attr() #@
        d.b.example_attr() #@
        """)

        message_replace_example_func = testutils.MessageTest(
            msg_id='replace-disallowed-function-calls',
            node=call1,
            args=('somethingexample_func', 'other_func'),
            confidence=interfaces.UNDEFINED
        )

        message_replace_example_attr1 = testutils.MessageTest(
            msg_id='replace-disallowed-function-calls',
            node=call2,
            args=('d.example_attr', 'other_attr'),
            confidence=interfaces.UNDEFINED
        )

        message_replace_example_attr2 = testutils.MessageTest(
            msg_id='replace-disallowed-function-calls',
            node=call3,
            args=('d.example_attr', 'other_attr'),
            confidence=interfaces.UNDEFINED
        )

        message_replace_example_attr3 = testutils.MessageTest(
            msg_id='replace-disallowed-function-calls',
            node=call4,
            args=('d.b.example_attr', 'other_attr'),
            confidence=interfaces.UNDEFINED
        )

        with self.checker_test_object.assertAddsMessages(
            message_replace_example_func,
            message_replace_example_attr1,
            message_replace_example_attr2,
            message_replace_example_attr3,
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_call(call1)
            self.checker_test_object.checker.visit_call(call2)
            self.checker_test_object.checker.visit_call(call3)
            self.checker_test_object.checker.visit_call(call4)


class NonTestFilesFunctionNameCheckerTests(unittest.TestCase):

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.NonTestFilesFunctionNameChecker)
        self.checker_test_object.setup_method()

    def test_function_def_for_test_file_with_test_only_adds_no_msg(
        self
    ) -> None:
        def_node = astroid.extract_node(
            """
            def test_only_some_random_function(param1, param2):
                pass
            """
        )
        def_node.root().name = 'random_module_test'

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(def_node)

    def test_function_def_for_test_file_without_test_only_adds_no_msg(
        self
    ) -> None:
        def_node = astroid.extract_node(
            """
            def some_random_function(param1, param2):
                pass
            """
        )
        def_node.root().name = 'random_module_test'

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(def_node)

    def test_function_def_for_non_test_file_with_test_only_adds_msg(
        self
    ) -> None:
        def_node = astroid.extract_node(
            """
            def test_only_some_random_function(param1, param2):
                pass
            """
        )
        def_node.root().name = 'random_module_nontest'
        non_test_function_name_message = testutils.MessageTest(
            msg_id='non-test-files-function-name-checker', node=def_node)

        with self.checker_test_object.assertAddsMessages(
            non_test_function_name_message, ignore_position=True
        ):
            self.checker_test_object.checker.visit_functiondef(def_node)

    def test_function_def_for_non_test_file_without_test_only_adds_no_msg(
        self
    ) -> None:
        def_node = astroid.extract_node(
            """
            def some_random_function(param1, param2):
                pass
            """
        )
        def_node.root().name = 'random_module_nontest'

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_functiondef(def_node)


class DisallowHandlerWithoutSchemaTests(unittest.TestCase):

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.DisallowHandlerWithoutSchema)
        self.checker_test_object.setup_method()

    def test_schema_handlers_without_request_args_raise_error(self) -> None:

        schemaless_class_node = astroid.extract_node(
            """
            class BaseHandler():
                HANDLER_ARGS_SCHEMAS = None
                URL_PATH_ARGS_SCHEMAS = None

            class FakeClass(BaseHandler):
                URL_PATH_ARGS_SCHEMAS = {}
            """)
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='no-schema-for-handler-args',
                node=schemaless_class_node,
                args=(schemaless_class_node.name)
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_classdef(
                schemaless_class_node)

    def test_schema_handlers_without_url_path_args_raise_error(self) -> None:

        schemaless_class_node = astroid.extract_node(
            """
            class BaseHandler():
                HANDLER_ARGS_SCHEMAS = None
                URL_PATH_ARGS_SCHEMAS = None

            class FakeClass(BaseHandler):
                HANDLER_ARGS_SCHEMAS = {}
            """)

        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='no-schema-for-url-path-elements',
                node=schemaless_class_node,
                args=(schemaless_class_node.name)
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_classdef(
                schemaless_class_node)

    def test_handlers_with_valid_schema_do_not_raise_error(self) -> None:

        schemaless_class_node = astroid.extract_node(
            """
            class BaseHandler():
                HANDLER_ARGS_SCHEMAS = None
                URL_PATH_ARGS_SCHEMAS = None

            class FakeClass(BaseHandler):
                URL_PATH_ARGS_SCHEMAS = {}
                HANDLER_ARGS_SCHEMAS = {'GET': {}}
            """)

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_classdef(
                schemaless_class_node)

    def test_list_of_non_schema_handlers_do_not_raise_errors(self) -> None:
        """Handler class name in list of
        HANDLER_CLASS_NAMES_WHICH_STILL_NEED_SCHEMAS do not raise error
        for missing schemas.
        """

        schemaless_class_node = astroid.extract_node(
            """
            class BaseHandler():
                HANDLER_ARGS_SCHEMAS = None
                URL_PATH_ARGS_SCHEMAS = None

            class SessionBeginHandler(BaseHandler):
                def get(self):
                    return
            """)

        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_classdef(
                schemaless_class_node)

    def test_schema_handler_with_basehandler_as_an_ancestor_raise_error(
        self
    ) -> None:
        """Handlers which are child classes of BaseHandler must have schema
        defined locally in the class.
        """

        schemaless_class_node = astroid.extract_node(
            """
            class BaseHandler():
                HANDLER_ARGS_SCHEMAS = None
                URL_PATH_ARGS_SCHEMAS = None

            class BaseClass(BaseHandler):
                HANDLER_ARGS_SCHEMAS = {}
                URL_PATH_ARGS_SCHEMAS = {}

            class FakeClass(BaseClass):
                HANDLER_ARGS_SCHEMAS = {}
            """)

        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='no-schema-for-url-path-elements',
                node=schemaless_class_node,
                args=(schemaless_class_node.name)
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_classdef(
                schemaless_class_node)

    def test_wrong_data_type_in_url_path_args_schema_raise_error(self) -> None:
        """Checks whether the schemas in URL_PATH_ARGS_SCHEMAS must be of
        dict type.
        """

        schemaless_class_node = astroid.extract_node(
            """
            class BaseHandler():
                HANDLER_ARGS_SCHEMAS = None
                URL_PATH_ARGS_SCHEMA = None

            class BaseClass(BaseHandler):
                HANDLER_ARGS_SCHEMAS = {}
                URL_PATH_ARGS_SCHEMAS = {}

            class FakeClass(BaseClass):
                URL_PATH_ARGS_SCHEMAS = 5
                HANDLER_ARGS_SCHEMAS = {}
            """)

        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='url-path-args-schemas-must-be-dict',
                node=schemaless_class_node,
                args=(schemaless_class_node.name)
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_classdef(
                schemaless_class_node)

    def test_wrong_data_type_in_handler_args_schema_raise_error(self) -> None:
        """Checks whether the schemas in URL_PATH_ARGS_SCHEMAS must be of
        dict type.
        """

        schemaless_class_node = astroid.extract_node(
            """
            class BaseHandler():
                HANDLER_ARGS_SCHEMAS = None
                URL_PATH_ARGS_SCHEMAS = None

            class BaseClass(BaseHandler):
                HANDLER_ARGS_SCHEMAS = {}
                URL_PATH_ARGS_SCHEMAS = {}

            class FakeClass(BaseClass):
                URL_PATH_ARGS_SCHEMAS = {}
                HANDLER_ARGS_SCHEMAS = 10
            """)

        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='handler-args-schemas-must-be-dict',
                node=schemaless_class_node,
                args=(schemaless_class_node.name)
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_classdef(
                schemaless_class_node)


class DisallowedImportsCheckerTests(unittest.TestCase):

    def setUp(self) -> None:
        super().setUp()
        self.checker_test_object = testutils.CheckerTestCase()
        self.checker_test_object.CHECKER_CLASS = (
            pylint_extensions.DisallowedImportsChecker)
        self.checker_test_object.setup_method()

    def test_importing_text_from_typing_in_single_line_raises_error(
        self
    ) -> None:
        node = astroid.extract_node("""from typing import Any, cast, Text""")
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='disallowed-text-import',
                node=node,
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_importfrom(
                node)

    def test_importing_text_from_typing_in_multi_line_raises_error(
        self
    ) -> None:
        node = astroid.extract_node(
            """
            from typing import (
                Any, Dict, List, Optional, Sequence, Text, TypeVar)
            """)
        with self.checker_test_object.assertAddsMessages(
            testutils.MessageTest(
                msg_id='disallowed-text-import',
                node=node,
            ),
            ignore_position=True,
        ):
            self.checker_test_object.checker.visit_importfrom(
                node)

    def test_non_import_of_text_from_typing_does_not_raise_error(
        self
    ) -> None:
        node = astroid.extract_node(
            """
            from typing import Any, Dict, List, Optional
            """)
        with self.checker_test_object.assertNoMessages():
            self.checker_test_object.checker.visit_importfrom(
                node)
