# -------------------------------------------------------------------------
#
#  Part of the CodeChecker project, under the Apache License v2.0 with
#  LLVM Exceptions. See LICENSE for license information.
#  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------

"""
This module tests the correctness of the OutputParser and PListConverter, which
used in sequence transform a Clang Tidy output file to a plist file.
"""


import os
import plistlib
import shutil
import tempfile
import unittest

from codechecker_report_converter.output_parser import Message, Event
from codechecker_report_converter.clang_tidy.output_parser import \
    ClangTidyParser
from codechecker_report_converter.clang_tidy.analyzer_result import \
    ClangTidyAnalyzerResult

OLD_PWD = None


def setup_module():
    """Setup the test tidy reprs for the test classes in the module."""
    global OLD_PWD
    OLD_PWD = os.getcwd()
    os.chdir(os.path.join(os.path.dirname(__file__), 'tidy_output_test_files'))


def teardown_module():
    """Restore environment after tests have ran."""
    global OLD_PWD
    os.chdir(OLD_PWD)


class ClangTidyOutputParserTestCase(unittest.TestCase):
    """
    Tests the output of the OutputParser, which converts a Clang Tidy output
    file to zero or more tidy_output_converter.Message.
    """

    def setUp(self):
        """Setup the OutputParser."""
        self.parser = ClangTidyParser()

        # tidy1.out Message/Note representation
        self.tidy1_repr = [
            Message(
                os.path.abspath('files/test.cpp'),
                8, 12,
                'Division by zero',
                'clang-analyzer-core.DivideZero',
                [Event(
                    os.path.abspath('files/test.cpp'),
                    8, 12,
                    'Division by zero')]),
            Message(
                os.path.abspath('files/test.cpp'),
                8, 12,
                'remainder by zero is undefined',
                'clang-diagnostic-division-by-zero')
        ]

        # tidy2.out Message/Note representation
        self.tidy2_repr = [
            Message(
                os.path.abspath('files/test2.cpp'),
                5, 7,
                "unused variable 'y'",
                'clang-diagnostic-unused-variable'),
            Message(
                os.path.abspath('files/test2.cpp'),
                13, 12,
                'Division by zero',
                'clang-analyzer-core.DivideZero',
                [
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        9, 7,
                        "Left side of '||' is false"),
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        9, 3,
                        'Taking false branch'),
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        13, 12,
                        'Division by zero')
                ]),
            Message(
                os.path.abspath('files/test2.cpp'),
                13, 12,
                'remainder by zero is undefined',
                'clang-diagnostic-division-by-zero'),
        ]

        # tidy2_v6.out Message/Note representation
        self.tidy2_v6_repr = [
            Message(
                os.path.abspath('files/test2.cpp'),
                13, 12,
                'Division by zero',
                'clang-analyzer-core.DivideZero',
                [
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        9, 7,
                        "Left side of '||' is false"),
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        9, 16,
                        "Assuming 'x' is 0"),
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        9, 3,
                        'Taking false branch'),
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        13, 12,
                        'Division by zero')
                ]),
            Message(
                os.path.abspath('files/test2.cpp'),
                13, 12,
                'remainder by zero is undefined',
                'clang-diagnostic-division-by-zero'),
        ]

        # tidy3.out Message/Note representation
        self.tidy3_repr = [
            Message(
                os.path.abspath('files/test3.cpp'),
                4, 12,
                'use nullptr',
                'modernize-use-nullptr',
                None,
                None,
                [Event(
                    os.path.abspath('files/test3.cpp'),
                    4, 12,
                    'nullptr')]),
            Message(
                os.path.abspath('files/test3.hh'),
                6, 6,
                "Dereference of null pointer (loaded from variable 'x')",
                'clang-analyzer-core.NullDereference',
                [
                    Event(
                        os.path.abspath('files/test3.cpp'),
                        4, 3,
                        "'x' initialized to a null pointer value"),
                    Event(
                        os.path.abspath('files/test3.cpp'),
                        6, 11,
                        "Assuming 'argc' is > 3"),
                    Event(
                        os.path.abspath('files/test3.cpp'),
                        6, 3,
                        'Taking true branch'),
                    Event(
                        os.path.abspath('files/test3.cpp'),
                        7, 9,
                        "Passing null pointer value via 1st parameter 'x'"),
                    Event(
                        os.path.abspath('files/test3.cpp'),
                        7, 5,
                        "Calling 'bar'"),
                    Event(
                        os.path.abspath('files/test3.hh'),
                        6, 6,
                        "Dereference of null pointer (loaded from variable "
                        "'x')")
                ])
        ]

        # tidy5.out Message/Note representation
        self.tidy5_repr = [
            Message(
                os.path.abspath('files/test4.cpp'),
                3, 26,
                'identifier after literal will be treated '
                'as a reserved user-defined literal suffix in C++11',
                'clang-diagnostic-c++11-compat-reserved-user-defined-literal'),
            Message(
                os.path.abspath('files/test4.cpp'),
                10, 12,
                'Division by zero',
                'clang-analyzer-core.DivideZero',
                [Event(
                    os.path.abspath('files/test4.cpp'),
                    10, 12,
                    'Division by zero')]),
            Message(
                os.path.abspath('files/test4.cpp'),
                10, 12,
                'remainder by zero is undefined',
                'clang-diagnostic-division-by-zero')
        ]

        # tidy5_v6.out Message/Note representation
        self.tidy5_v6_repr = [
            Message(
                os.path.abspath('files/test4.cpp'),
                3, 26,
                'invalid suffix on literal; C++11 requires a space '
                'between literal and identifier',
                'clang-diagnostic-reserved-user-defined-literal'),
            Message(
                os.path.abspath('files/test4.cpp'),
                10, 12,
                'remainder by zero is undefined',
                'clang-diagnostic-division-by-zero')
        ]

        # tidy6.out Message/Note representation
        self.tidy6_repr = [
            Message(
                os.path.abspath('files/test5.cpp'),
                10, 9,
                'no matching function for call to \'get_type\'',
                'clang-diagnostic-error',
                [
                    Event(
                        os.path.abspath('files/test5.cpp'),
                        2, 18,
                        'candidate template ignored: substitution failure '
                        '[with T = int *]: type \'int *\' cannot be used '
                        'prior to \'::\' because it has no members'),
                    Event(
                        os.path.abspath('files/test5.cpp'),
                        5, 6,
                        'candidate template ignored: substitution failure '
                        '[with T = int]: array size is negative'),
                ]
            )]

    def test_absolute_path(self):
        """Test for absolute paths in Messages."""
        for tfile in ['abs.out', 'tidy1.out']:
            messages = self.parser.parse_messages_from_file(tfile)
            self.assertNotEqual(len(messages), 0)
            for message in messages:
                self.assertTrue(os.path.isabs(message.path))

    def test_empty1(self):
        """Test an empty ClangTidy output file."""
        messages = self.parser.parse_messages_from_file('empty1.out')
        self.assertEqual(messages, [])

    def test_empty2(self):
        """Test a ClangTidy output file that only contains empty lines."""
        messages = self.parser.parse_messages_from_file('empty2.out')
        self.assertEqual(messages, [])

    def test_tidy1(self):
        """Test the generated Messages of tidy1.out ClangTidy output file."""
        messages = self.parser.parse_messages_from_file('tidy1.out')
        self.assertEqual(len(messages), len(self.tidy1_repr))
        for message in messages:
            self.assertIn(message, self.tidy1_repr)

    def test_tidy1_v6(self):
        """Test the generated Messages of tidy1.out ClangTidy v6 output
        file."""
        messages = self.parser.parse_messages_from_file('tidy1_v6.out')
        self.assertEqual(len(messages), len(self.tidy1_repr))
        for message in messages:
            self.assertIn(message, self.tidy1_repr)

    def test_tidy2(self):
        """Test the generated Messages of tidy2.out ClangTidy output file."""
        messages = self.parser.parse_messages_from_file('tidy2.out')
        self.assertEqual(len(messages), len(self.tidy2_repr))
        for message in messages:
            self.assertIn(message, self.tidy2_repr)

    def test_tidy2_v6(self):
        """Test the generated Messages of tidy2.out ClangTidy v6 output
        file."""
        messages = self.parser.parse_messages_from_file('tidy2_v6.out')
        self.assertEqual(len(messages), len(self.tidy2_v6_repr))
        for message in messages:
            self.assertIn(message, self.tidy2_v6_repr)

    def test_tidy3(self):
        """Test the generated Messages of tidy3.out ClangTidy output file."""
        messages = self.parser.parse_messages_from_file('tidy3.out')
        self.assertEqual(len(messages), len(self.tidy3_repr))
        for message in messages:
            self.assertIn(message, self.tidy3_repr)

    def test_tidy4(self):
        """
        Test the generated Messages of tidy4.out ClangTidy output file.
        This is an uncomplete file which is equal with tidy1.out except it's
        missing the last two lines.
        """
        messages = self.parser.parse_messages_from_file('tidy4.out')
        self.assertEqual(len(messages), len(self.tidy1_repr))
        for message in messages:
            self.assertIn(message, self.tidy1_repr)

    def test_tidy5(self):
        """
        Test the grenerated Messages of tidy5.out ClangTidy output file.
        This is an uncomplete file which is equal with tidy1.out except it's
        missing the last two lines.
        """
        messages = self.parser.parse_messages_from_file('tidy5.out')
        for message in messages:
            self.assertIn(message, self.tidy5_repr)

    def test_tidy5_v6(self):
        """
        Test the grenerated Messages of tidy5_v6.out ClangTidy output file.
        This is an uncomplete file which is equal with tidy1.out except it's
        missing the last two lines.
        """
        messages = self.parser.parse_messages_from_file('tidy5_v6.out')
        for message in messages:
            self.assertIn(message, self.tidy5_v6_repr)

    def test_tidy6(self):
        """
        Test the generated Messages of tidy6.out ClangTidy output file.
        """
        messages = self.parser.parse_messages_from_file('tidy6.out')
        for message in messages:
            self.assertIn(message, self.tidy6_repr)


class ClangTidyAnalyzerResultTestCase(unittest.TestCase):
    """ Test the output of the ClangTidyAnalyzerResult. """

    def setUp(self):
        """ Setup the test. """
        self.analyzer_result = ClangTidyAnalyzerResult()
        self.cc_result_dir = tempfile.mkdtemp()

    def tearDown(self):
        """ Clean temporary directory. """
        shutil.rmtree(self.cc_result_dir)

    def __check_analyzer_result(self, analyzer_result, analyzer_result_plist,
                                source_files, expected_plist):
        """ Check the result of the analyzer transformation. """

        self.analyzer_result.transform(analyzer_result, self.cc_result_dir)

        plist_file = os.path.join(self.cc_result_dir, analyzer_result_plist)
        with open(plist_file, mode='rb') as pfile:
            res = plistlib.load(pfile)

            # Use relative path for this test.
            res['files'] = source_files

        with open(expected_plist, mode='rb') as pfile:
            exp = plistlib.load(pfile)

            self.assertTrue(res['metadata']['generated_by']['version'])
            res['metadata']['generated_by']['version'] = "x.y.z"

        self.assertEqual(res, exp)

    def test_empty1(self):
        """ Test for empty Messages. """
        ret = self.analyzer_result.transform('empty1.out', self.cc_result_dir)
        self.assertFalse(ret)

    def test_empty2(self):
        """ Test for empty Messages with multiple line. """
        ret = self.analyzer_result.transform('empty2.out', self.cc_result_dir)
        self.assertFalse(ret)

    def test_tidy1(self):
        """ Test for the tidy1.plist file. """
        self.__check_analyzer_result('tidy1.out', 'test.cpp_clang-tidy.plist',
                                     ['files/test.cpp'], 'tidy1.plist')

    def test_tidy2(self):
        """ Test for the tidy2.plist file. """
        self.__check_analyzer_result('tidy2.out', 'test2.cpp_clang-tidy.plist',
                                     ['files/test2.cpp'], 'tidy2.plist')

    def test_tidy3(self):
        """ Test for the tidy3.plist file. """
        self.__check_analyzer_result('tidy3.out', 'test3.cpp_clang-tidy.plist',
                                     ['files/test3.cpp'],
                                     'tidy3_cpp.plist')

        self.__check_analyzer_result('tidy3.out', 'test3.hh_clang-tidy.plist',
                                     ['files/test3.hh', 'files/test3.cpp'],
                                     'tidy3_hh.plist')

# -------------------------------------------------------------------------
#
#  Part of the CodeChecker project, under the Apache License v2.0 with
#  LLVM Exceptions. See LICENSE for license information.
#  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------

"""
This module tests the correctness of the OutputParser and PListConverter, which
used in sequence transform a Clang Tidy output file to a plist file.
"""


import os
import plistlib
import shutil
import tempfile
import unittest

from codechecker_report_converter.output_parser import Message, Event
from codechecker_report_converter.clang_tidy.output_parser import \
    ClangTidyParser
from codechecker_report_converter.clang_tidy.analyzer_result import \
    ClangTidyAnalyzerResult

OLD_PWD = None


def setup_module():
    """Setup the test tidy reprs for the test classes in the module."""
    global OLD_PWD
    OLD_PWD = os.getcwd()
    os.chdir(os.path.join(os.path.dirname(__file__), 'tidy_output_test_files'))


def teardown_module():
    """Restore environment after tests have ran."""
    global OLD_PWD
    os.chdir(OLD_PWD)


class ClangTidyOutputParserTestCase(unittest.TestCase):
    """
    Tests the output of the OutputParser, which converts a Clang Tidy output
    file to zero or more tidy_output_converter.Message.
    """

    def setUp(self):
        """Setup the OutputParser."""
        self.parser = ClangTidyParser()

        # tidy1.out Message/Note representation
        self.tidy1_repr = [
            Message(
                os.path.abspath('files/test.cpp'),
                8, 12,
                'Division by zero',
                'clang-analyzer-core.DivideZero',
                [Event(
                    os.path.abspath('files/test.cpp'),
                    8, 12,
                    'Division by zero')]),
            Message(
                os.path.abspath('files/test.cpp'),
                8, 12,
                'remainder by zero is undefined',
                'clang-diagnostic-division-by-zero')
        ]

        # tidy2.out Message/Note representation
        self.tidy2_repr = [
            Message(
                os.path.abspath('files/test2.cpp'),
                5, 7,
                "unused variable 'y'",
                'clang-diagnostic-unused-variable'),
            Message(
                os.path.abspath('files/test2.cpp'),
                13, 12,
                'Division by zero',
                'clang-analyzer-core.DivideZero',
                [
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        9, 7,
                        "Left side of '||' is false"),
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        9, 3,
                        'Taking false branch'),
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        13, 12,
                        'Division by zero')
                ]),
            Message(
                os.path.abspath('files/test2.cpp'),
                13, 12,
                'remainder by zero is undefined',
                'clang-diagnostic-division-by-zero'),
        ]

        # tidy2_v6.out Message/Note representation
        self.tidy2_v6_repr = [
            Message(
                os.path.abspath('files/test2.cpp'),
                13, 12,
                'Division by zero',
                'clang-analyzer-core.DivideZero',
                [
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        9, 7,
                        "Left side of '||' is false"),
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        9, 16,
                        "Assuming 'x' is 0"),
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        9, 3,
                        'Taking false branch'),
                    Event(
                        os.path.abspath('files/test2.cpp'),
                        13, 12,
                        'Division by zero')
                ]),
            Message(
                os.path.abspath('files/test2.cpp'),
                13, 12,
                'remainder by zero is undefined',
                'clang-diagnostic-division-by-zero'),
        ]

        # tidy3.out Message/Note representation
        self.tidy3_repr = [
            Message(
                os.path.abspath('files/test3.cpp'),
                4, 12,
                'use nullptr',
                'modernize-use-nullptr',
                None,
                None,
                [Event(
                    os.path.abspath('files/test3.cpp'),
                    4, 12,
                    'nullptr')]),
            Message(
                os.path.abspath('files/test3.hh'),
                6, 6,
                "Dereference of null pointer (loaded from variable 'x')",
                'clang-analyzer-core.NullDereference',
                [
                    Event(
                        os.path.abspath('files/test3.cpp'),
                        4, 3,
                        "'x' initialized to a null pointer value"),
                    Event(
                        os.path.abspath('files/test3.cpp'),
                        6, 11,
                        "Assuming 'argc' is > 3"),
                    Event(
                        os.path.abspath('files/test3.cpp'),
                        6, 3,
                        'Taking true branch'),
                    Event(
                        os.path.abspath('files/test3.cpp'),
                        7, 9,
                        "Passing null pointer value via 1st parameter 'x'"),
                    Event(
                        os.path.abspath('files/test3.cpp'),
                        7, 5,
                        "Calling 'bar'"),
                    Event(
                        os.path.abspath('files/test3.hh'),
                        6, 6,
                        "Dereference of null pointer (loaded from variable "
                        "'x')")
                ])
        ]

        # tidy5.out Message/Note representation
        self.tidy5_repr = [
            Message(
                os.path.abspath('files/test4.cpp'),
                3, 26,
                'identifier after literal will be treated '
                'as a reserved user-defined literal suffix in C++11',
                'clang-diagnostic-c++11-compat-reserved-user-defined-literal'),
            Message(
                os.path.abspath('files/test4.cpp'),
                10, 12,
                'Division by zero',
                'clang-analyzer-core.DivideZero',
                [Event(
                    os.path.abspath('files/test4.cpp'),
                    10, 12,
                    'Division by zero')]),
            Message(
                os.path.abspath('files/test4.cpp'),
                10, 12,
                'remainder by zero is undefined',
                'clang-diagnostic-division-by-zero')
        ]

        # tidy5_v6.out Message/Note representation
        self.tidy5_v6_repr = [
            Message(
                os.path.abspath('files/test4.cpp'),
                3, 26,
                'invalid suffix on literal; C++11 requires a space '
                'between literal and identifier',
                'clang-diagnostic-reserved-user-defined-literal'),
            Message(
                os.path.abspath('files/test4.cpp'),
                10, 12,
                'remainder by zero is undefined',
                'clang-diagnostic-division-by-zero')
        ]

        # tidy6.out Message/Note representation
        self.tidy6_repr = [
            Message(
                os.path.abspath('files/test5.cpp'),
                10, 9,
                'no matching function for call to \'get_type\'',
                'clang-diagnostic-error',
                [
                    Event(
                        os.path.abspath('files/test5.cpp'),
                        2, 18,
                        'candidate template ignored: substitution failure '
                        '[with T = int *]: type \'int *\' cannot be used '
                        'prior to \'::\' because it has no members'),
                    Event(
                        os.path.abspath('files/test5.cpp'),
                        5, 6,
                        'candidate template ignored: substitution failure '
                        '[with T = int]: array size is negative'),
                ]
            )]

    def test_absolute_path(self):
        """Test for absolute paths in Messages."""
        for tfile in ['abs.out', 'tidy1.out']:
            messages = self.parser.parse_messages_from_file(tfile)
            self.assertNotEqual(len(messages), 0)
            for message in messages:
                self.assertTrue(os.path.isabs(message.path))

    def test_empty1(self):
        """Test an empty ClangTidy output file."""
        messages = self.parser.parse_messages_from_file('empty1.out')
        self.assertEqual(messages, [])

    def test_empty2(self):
        """Test a ClangTidy output file that only contains empty lines."""
        messages = self.parser.parse_messages_from_file('empty2.out')
        self.assertEqual(messages, [])

    def test_tidy1(self):
        """Test the generated Messages of tidy1.out ClangTidy output file."""
        messages = self.parser.parse_messages_from_file('tidy1.out')
        self.assertEqual(len(messages), len(self.tidy1_repr))
        for message in messages:
            self.assertIn(message, self.tidy1_repr)

    def test_tidy1_v6(self):
        """Test the generated Messages of tidy1.out ClangTidy v6 output
        file."""
        messages = self.parser.parse_messages_from_file('tidy1_v6.out')
        self.assertEqual(len(messages), len(self.tidy1_repr))
        for message in messages:
            self.assertIn(message, self.tidy1_repr)

    def test_tidy2(self):
        """Test the generated Messages of tidy2.out ClangTidy output file."""
        messages = self.parser.parse_messages_from_file('tidy2.out')
        self.assertEqual(len(messages), len(self.tidy2_repr))
        for message in messages:
            self.assertIn(message, self.tidy2_repr)

    def test_tidy2_v6(self):
        """Test the generated Messages of tidy2.out ClangTidy v6 output
        file."""
        messages = self.parser.parse_messages_from_file('tidy2_v6.out')
        self.assertEqual(len(messages), len(self.tidy2_v6_repr))
        for message in messages:
            self.assertIn(message, self.tidy2_v6_repr)

    def test_tidy3(self):
        """Test the generated Messages of tidy3.out ClangTidy output file."""
        messages = self.parser.parse_messages_from_file('tidy3.out')
        self.assertEqual(len(messages), len(self.tidy3_repr))
        for message in messages:
            self.assertIn(message, self.tidy3_repr)

    def test_tidy4(self):
        """
        Test the generated Messages of tidy4.out ClangTidy output file.
        This is an uncomplete file which is equal with tidy1.out except it's
        missing the last two lines.
        """
        messages = self.parser.parse_messages_from_file('tidy4.out')
        self.assertEqual(len(messages), len(self.tidy1_repr))
        for message in messages:
            self.assertIn(message, self.tidy1_repr)

    def test_tidy5(self):
        """
        Test the grenerated Messages of tidy5.out ClangTidy output file.
        This is an uncomplete file which is equal with tidy1.out except it's
        missing the last two lines.
        """
        messages = self.parser.parse_messages_from_file('tidy5.out')
        for message in messages:
            self.assertIn(message, self.tidy5_repr)

    def test_tidy5_v6(self):
        """
        Test the grenerated Messages of tidy5_v6.out ClangTidy output file.
        This is an uncomplete file which is equal with tidy1.out except it's
        missing the last two lines.
        """
        messages = self.parser.parse_messages_from_file('tidy5_v6.out')
        for message in messages:
            self.assertIn(message, self.tidy5_v6_repr)

    def test_tidy6(self):
        """
        Test the generated Messages of tidy6.out ClangTidy output file.
        """
        messages = self.parser.parse_messages_from_file('tidy6.out')
        for message in messages:
            self.assertIn(message, self.tidy6_repr)


class ClangTidyAnalyzerResultTestCase(unittest.TestCase):
    """ Test the output of the ClangTidyAnalyzerResult. """

    def setUp(self):
        """ Setup the test. """
        self.analyzer_result = ClangTidyAnalyzerResult()
        self.cc_result_dir = tempfile.mkdtemp()

    def tearDown(self):
        """ Clean temporary directory. """
        shutil.rmtree(self.cc_result_dir)

    def __check_analyzer_result(self, analyzer_result, analyzer_result_plist,
                                source_files, expected_plist):
        """ Check the result of the analyzer transformation. """

        self.analyzer_result.transform(analyzer_result, self.cc_result_dir)

        plist_file = os.path.join(self.cc_result_dir, analyzer_result_plist)
        with open(plist_file, mode='rb') as pfile:
            res = plistlib.load(pfile)

            # Use relative path for this test.
            res['files'] = source_files

        with open(expected_plist, mode='rb') as pfile:
            exp = plistlib.load(pfile)

            self.assertTrue(res['metadata']['generated_by']['version'])
            res['metadata']['generated_by']['version'] = "x.y.z"

        self.assertEqual(res, exp)

    def test_empty1(self):
        """ Test for empty Messages. """
        ret = self.analyzer_result.transform('empty1.out', self.cc_result_dir)
        self.assertFalse(ret)

    def test_empty2(self):
        """ Test for empty Messages with multiple line. """
        ret = self.analyzer_result.transform('empty2.out', self.cc_result_dir)
        self.assertFalse(ret)

    def test_tidy1(self):
        """ Test for the tidy1.plist file. """
        self.__check_analyzer_result('tidy1.out', 'test.cpp_clang-tidy.plist',
                                     ['files/test.cpp'], 'tidy1.plist')

    def test_tidy2(self):
        """ Test for the tidy2.plist file. """
        self.__check_analyzer_result('tidy2.out', 'test2.cpp_clang-tidy.plist',
                                     ['files/test2.cpp'], 'tidy2.plist')

    def test_tidy3(self):
        """ Test for the tidy3.plist file. """
        self.__check_analyzer_result('tidy3.out', 'test3.cpp_clang-tidy.plist',
                                     ['files/test3.cpp'],
                                     'tidy3_cpp.plist')

        self.__check_analyzer_result('tidy3.out', 'test3.hh_clang-tidy.plist',
                                     ['files/test3.hh', 'files/test3.cpp'],
                                     'tidy3_hh.plist')

# ------------------------------------------------------------------------- # #  Part of the CodeChecker project, under the Apache License v2.0 with #  LLVM Exceptions. See LICENSE for license information. #  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # # ------------------------------------------------------------------------- This module tests the correctness of the OutputParser and PListConverter, which used in sequence transform a Clang Tidy output file to a plist file. Setup the test tidy reprs for the test classes in the module. Restore environment after tests have ran. Tests the output of the OutputParser, which converts a Clang Tidy output     file to zero or more tidy_output_converter.Message. Setup the OutputParser. # tidy1.out Message/Note representation # tidy2.out Message/Note representation # tidy2_v6.out Message/Note representation # tidy3.out Message/Note representation # tidy5.out Message/Note representation # tidy5_v6.out Message/Note representation # tidy6.out Message/Note representation Test for absolute paths in Messages. Test an empty ClangTidy output file. Test a ClangTidy output file that only contains empty lines. Test the generated Messages of tidy1.out ClangTidy output file. Test the generated Messages of tidy1.out ClangTidy v6 output         file. Test the generated Messages of tidy2.out ClangTidy output file. Test the generated Messages of tidy2.out ClangTidy v6 output         file. Test the generated Messages of tidy3.out ClangTidy output file. Test the generated Messages of tidy4.out ClangTidy output file.         This is an uncomplete file which is equal with tidy1.out except it's         missing the last two lines. Test the grenerated Messages of tidy5.out ClangTidy output file.         This is an uncomplete file which is equal with tidy1.out except it's         missing the last two lines. Test the grenerated Messages of tidy5_v6.out ClangTidy output file.         This is an uncomplete file which is equal with tidy1.out except it's         missing the last two lines. Test the generated Messages of tidy6.out ClangTidy output file. Test the output of the ClangTidyAnalyzerResult. Setup the test. Clean temporary directory. Check the result of the analyzer transformation. # Use relative path for this test. Test for empty Messages. Test for empty Messages with multiple line. Test for the tidy1.plist file. Test for the tidy2.plist file. Test for the tidy3.plist file.