# -*- coding: utf-8; -*-
#
# Copyright (C) 2009 Google Inc. All rights reserved.
# Copyright (C) 2009 Torch Mobile Inc.
# Copyright (C) 2009 Apple Inc. All rights reserved.
# Copyright (C) 2010 Chris Jerdonek (chris.jerdonek@gmail.com)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#    * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#    * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#    * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Unit tests for style.py."""

import logging
import os
import unittest2 as unittest

import checker as style
from webkitpy.common.system.logtesting import LogTesting, TestLogStream
from checker import _BASE_FILTER_RULES
from checker import _MAX_REPORTS_PER_CATEGORY
from checker import _PATH_RULES_SPECIFIER as PATH_RULES_SPECIFIER
from checker import _all_categories
from checker import check_webkit_style_configuration
from checker import check_webkit_style_parser
from checker import configure_logging
from checker import CheckerDispatcher
from checker import ProcessorBase
from checker import StyleProcessor
from checker import StyleProcessorConfiguration
from checkers.changelog import ChangeLogChecker
from checkers.cpp import CppChecker
from checkers.jsonchecker import JSONChecker
from checkers.python import PythonChecker
from checkers.text import TextChecker
from checkers.xml import XMLChecker
from error_handlers import DefaultStyleErrorHandler
from filter import validate_filter_rules
from filter import FilterConfiguration
from optparser import ArgumentParser
from optparser import CommandOptionValues
from webkitpy.common.system.logtesting import LoggingTestCase
from webkitpy.style.filereader import TextFileReader


class ConfigureLoggingTestBase(unittest.TestCase):

    """Base class for testing configure_logging().

    Sub-classes should implement:

      is_verbose: The is_verbose value to pass to configure_logging().

    """

    def setUp(self):
        is_verbose = self.is_verbose

        log_stream = TestLogStream(self)

        # Use a logger other than the root logger or one prefixed with
        # webkit so as not to conflict with test-webkitpy logging.
        logger = logging.getLogger("unittest")

        # Configure the test logger not to pass messages along to the
        # root logger.  This prevents test messages from being
        # propagated to loggers used by test-webkitpy logging (e.g.
        # the root logger).
        logger.propagate = False

        self._handlers = configure_logging(stream=log_stream, logger=logger,
                                           is_verbose=is_verbose)
        self._log = logger
        self._log_stream = log_stream

    def tearDown(self):
        """Reset logging to its original state.

        This method ensures that the logging configuration set up
        for a unit test does not affect logging in other unit tests.

        """
        logger = self._log
        for handler in self._handlers:
            logger.removeHandler(handler)

    def assert_log_messages(self, messages):
        """Assert that the logged messages equal the given messages."""
        self._log_stream.assertMessages(messages)


class ConfigureLoggingTest(ConfigureLoggingTestBase):

    """Tests the configure_logging() function."""

    is_verbose = False

    def test_warning_message(self):
        self._log.warn("test message")
        self.assert_log_messages(["WARNING: test message\n"])

    def test_below_warning_message(self):
        # We test the boundary case of a logging level equal to 29.
        # In practice, we will probably only be calling log.info(),
        # which corresponds to a logging level of 20.
        level = logging.WARNING - 1  # Equals 29.
        self._log.log(level, "test message")
        self.assert_log_messages(["test message\n"])

    def test_debug_message(self):
        self._log.debug("test message")
        self.assert_log_messages([])

    def test_two_messages(self):
        self._log.info("message1")
        self._log.info("message2")
        self.assert_log_messages(["message1\n", "message2\n"])


class ConfigureLoggingVerboseTest(ConfigureLoggingTestBase):

    """Tests the configure_logging() function with is_verbose True."""

    is_verbose = True

    def test_debug_message(self):
        self._log.debug("test message")
        self.assert_log_messages(["unittest: DEBUG    test message\n"])


class GlobalVariablesTest(unittest.TestCase):

    """Tests validity of the global variables."""

    def _all_categories(self):
        return _all_categories()

    def defaults(self):
        return style._check_webkit_style_defaults()

    def test_webkit_base_filter_rules(self):
        base_filter_rules = _BASE_FILTER_RULES
        defaults = self.defaults()
        already_seen = []
        validate_filter_rules(base_filter_rules, self._all_categories())
        # Also do some additional checks.
        for rule in base_filter_rules:
            # Check no leading or trailing white space.
            self.assertEqual(rule, rule.strip())
            # All categories are on by default, so defaults should
            # begin with -.
            self.assertTrue(rule.startswith('-'))
            # Check no rule occurs twice.
            self.assertNotIn(rule, already_seen)
            already_seen.append(rule)

    def test_defaults(self):
        """Check that default arguments are valid."""
        default_options = self.defaults()

        # FIXME: We should not need to call parse() to determine
        #        whether the default arguments are valid.
        parser = ArgumentParser(all_categories=self._all_categories(),
                                base_filter_rules=[],
                                default_options=default_options)
        # No need to test the return value here since we test parse()
        # on valid arguments elsewhere.
        #
        # The default options are valid: no error or SystemExit.
        parser.parse(args=[])

    def test_path_rules_specifier(self):
        all_categories = self._all_categories()
        for (sub_paths, path_rules) in PATH_RULES_SPECIFIER:
            validate_filter_rules(path_rules, self._all_categories())

        config = FilterConfiguration(path_specific=PATH_RULES_SPECIFIER)

        def assertCheck(path, category):
            """Assert that the given category should be checked."""
            message = ('Should check category "%s" for path "%s".'
                       % (category, path))
            self.assertTrue(config.should_check(category, path))

        def assertNoCheck(path, category):
            """Assert that the given category should not be checked."""
            message = ('Should not check category "%s" for path "%s".'
                       % (category, path))
            self.assertFalse(config.should_check(category, path), message)

        assertCheck("random_path.cpp",
                    "build/include")
        assertNoCheck("Tools/WebKitAPITest/main.cpp",
                      "build/include")
        assertCheck("random_path.cpp",
                    "readability/naming")
        assertNoCheck("Source/WebKit/gtk/webkit/webkit.h",
                      "readability/naming")
        assertNoCheck("Tools/DumpRenderTree/gtk/DumpRenderTree.cpp",
                      "readability/null")
        assertNoCheck("Source/WebKit/efl/ewk/ewk_view.h",
                      "readability/naming")
        assertNoCheck("Source/WebCore/css/CSSParser.cpp",
                      "readability/naming")

        # Test if Qt exceptions are indeed working
        assertCheck("Source/WebKit/qt/WidgetApi/qwebpage.cpp",
                    "readability/braces")
        assertCheck("Source/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp",
                    "readability/braces")
        assertCheck("Source/WebKit/qt/declarative/platformplugin/WebPlugin.cpp",
                    "readability/braces")
        assertCheck("Source/WebKit/qt/examples/platformplugin/WebPlugin.cpp",
                    "readability/braces")
        assertNoCheck("Source/WebKit/qt/WidgetApi/qwebpage.cpp",
                      "readability/naming")
        assertNoCheck("Source/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp",
                      "readability/naming")
        assertNoCheck("Source/WebKit/qt/declarative/platformplugin/WebPlugin.cpp",
                      "readability/naming")
        assertNoCheck("Source/WebKit/qt/examples/platformplugin/WebPlugin.cpp",
                      "readability/naming")

        assertNoCheck("Tools/MiniBrowser/qt/UrlLoader.cpp",
                    "build/include")

        assertNoCheck("Source/WebKit2/UIProcess/API/qt",
                    "readability/parameter_name")

        assertNoCheck("Source/WebCore/ForwardingHeaders/debugger/Debugger.h",
                      "build/header_guard")

        assertNoCheck("Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp",
                      "readability/naming")

        # Third-party Python code: webkitpy/thirdparty
        path = "Tools/Scripts/webkitpy/thirdparty/mock.py"
        assertNoCheck(path, "build/include")
        assertNoCheck(path, "pep8/E401")  # A random pep8 category.
        assertCheck(path, "pep8/W191")
        assertCheck(path, "pep8/W291")
        assertCheck(path, "whitespace/carriage_return")

        # Test if the exception for GDBInterface.cpp is in place.
        assertNoCheck("Source/JavaScriptCore/jit/GDBInterface.cpp",
                      "readability/naming")

        # Javascript keywords.
        assertCheck("Source/JavaScriptCore/parser/Keywords.table", "whitespace/carriage_return")

    def test_max_reports_per_category(self):
        """Check that _MAX_REPORTS_PER_CATEGORY is valid."""
        all_categories = self._all_categories()
        for category in _MAX_REPORTS_PER_CATEGORY.iterkeys():
            self.assertIn(category, all_categories,
                          'Key "%s" is not a category' % category)


class CheckWebKitStyleFunctionTest(unittest.TestCase):

    """Tests the functions with names of the form check_webkit_style_*."""

    def test_check_webkit_style_configuration(self):
        # Exercise the code path to make sure the function does not error out.
        option_values = CommandOptionValues()
        configuration = check_webkit_style_configuration(option_values)

    def test_check_webkit_style_parser(self):
        # Exercise the code path to make sure the function does not error out.
        parser = check_webkit_style_parser()


class CheckerDispatcherSkipTest(unittest.TestCase):

    """Tests the "should skip" methods of the CheckerDispatcher class."""

    def setUp(self):
        self._dispatcher = CheckerDispatcher()

    def test_should_skip_with_warning(self):
        """Test should_skip_with_warning()."""
        # Check skipped files.
        paths_to_skip = [
           "Source/WebKit/gtk/tests/testatk.c",
           "Source/WebKit2/UIProcess/API/gtk/webkit2.h",
           "Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h",
           "Source/WebKit2/UIProcess/API/gtk/WebKitLoader.h",
            ]

        for path in paths_to_skip:
            self.assertTrue(self._dispatcher.should_skip_with_warning(path),
                            "Checking: " + path)

        # Verify that some files are not skipped.
        paths_not_to_skip = [
           "foo.txt",
           "Source/WebKit2/UIProcess/API/gtk/HelperClass.cpp",
           "Source/WebKit2/UIProcess/API/gtk/HelperClass.h",
           "Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp",
           "Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h",
           "Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp",
           "Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h",
            ]

        for path in paths_not_to_skip:
            self.assertFalse(self._dispatcher.should_skip_with_warning(path))

    def _assert_should_skip_without_warning(self, path, is_checker_none,
                                            expected):
        # Check the file type before asserting the return value.
        checker = self._dispatcher.dispatch(file_path=path,
                                            handle_style_error=None,
                                            min_confidence=3)
        message = 'while checking: %s' % path
        self.assertEqual(checker is None, is_checker_none, message)
        self.assertEqual(self._dispatcher.should_skip_without_warning(path),
                          expected, message)

    def test_should_skip_without_warning__true(self):
        """Test should_skip_without_warning() for True return values."""
        # Check a file with NONE file type.
        path = 'foo.asdf'  # Non-sensical file extension.
        self._assert_should_skip_without_warning(path,
                                                 is_checker_none=True,
                                                 expected=True)

        # Check files with non-NONE file type.  These examples must be
        # drawn from the _SKIPPED_FILES_WITHOUT_WARNING configuration
        # variable.
        path = os.path.join('LayoutTests', 'foo.txt')
        self._assert_should_skip_without_warning(path,
                                                 is_checker_none=False,
                                                 expected=True)

    def test_should_skip_without_warning__false(self):
        """Test should_skip_without_warning() for False return values."""
        paths = ['foo.txt',
                 os.path.join('LayoutTests', 'ChangeLog'),
        ]

        for path in paths:
            self._assert_should_skip_without_warning(path,
                                                     is_checker_none=False,
                                                     expected=False)


class CheckerDispatcherCarriageReturnTest(unittest.TestCase):
    def test_should_check_and_strip_carriage_returns(self):
        files = {
            'foo.txt': True,
            'foo.cpp': True,
            'foo.vcproj': False,
            'foo.vsprops': False,
        }

        dispatcher = CheckerDispatcher()
        for file_path, expected_result in files.items():
            self.assertEqual(dispatcher.should_check_and_strip_carriage_returns(file_path), expected_result, 'Checking: %s' % file_path)


class CheckerDispatcherDispatchTest(unittest.TestCase):

    """Tests dispatch() method of CheckerDispatcher class."""

    def dispatch(self, file_path):
        """Call dispatch() with the given file path."""
        dispatcher = CheckerDispatcher()
        self.mock_handle_style_error = DefaultStyleErrorHandler('', None, None, [])
        checker = dispatcher.dispatch(file_path,
                                      self.mock_handle_style_error,
                                      min_confidence=3)
        return checker

    def assert_checker_none(self, file_path):
        """Assert that the dispatched checker is None."""
        checker = self.dispatch(file_path)
        self.assertIsNone(checker, 'Checking: "%s"' % file_path)

    def assert_checker(self, file_path, expected_class):
        """Assert the type of the dispatched checker."""
        checker = self.dispatch(file_path)
        got_class = checker.__class__
        self.assertEqual(got_class, expected_class,
                          'For path "%(file_path)s" got %(got_class)s when '
                          "expecting %(expected_class)s."
                          % {"file_path": file_path,
                             "got_class": got_class,
                             "expected_class": expected_class})

    def assert_checker_changelog(self, file_path):
        """Assert that the dispatched checker is a ChangeLogChecker."""
        self.assert_checker(file_path, ChangeLogChecker)

    def assert_checker_cpp(self, file_path):
        """Assert that the dispatched checker is a CppChecker."""
        self.assert_checker(file_path, CppChecker)

    def assert_checker_json(self, file_path):
        """Assert that the dispatched checker is a JSONChecker."""
        self.assert_checker(file_path, JSONChecker)

    def assert_checker_python(self, file_path):
        """Assert that the dispatched checker is a PythonChecker."""
        self.assert_checker(file_path, PythonChecker)

    def assert_checker_text(self, file_path):
        """Assert that the dispatched checker is a TextChecker."""
        self.assert_checker(file_path, TextChecker)

    def assert_checker_xml(self, file_path):
        """Assert that the dispatched checker is a XMLChecker."""
        self.assert_checker(file_path, XMLChecker)

    def test_changelog_paths(self):
        """Test paths that should be checked as ChangeLog."""
        paths = [
                 "ChangeLog",
                 "ChangeLog-2009-06-16",
                 os.path.join("Source", "WebCore", "ChangeLog"),
                 ]

        for path in paths:
            self.assert_checker_changelog(path)

        # Check checker attributes on a typical input.
        file_path = "ChangeLog"
        self.assert_checker_changelog(file_path)
        checker = self.dispatch(file_path)
        self.assertEqual(checker.file_path, file_path)
        self.assertEqual(checker.handle_style_error,
                          self.mock_handle_style_error)

    def test_cpp_paths(self):
        """Test paths that should be checked as C++."""
        paths = [
            "-",
            "foo.c",
            "foo.cpp",
            "foo.h",
            ]

        for path in paths:
            self.assert_checker_cpp(path)

        # Check checker attributes on a typical input.
        file_base = "foo"
        file_extension = "c"
        file_path = file_base + "." + file_extension
        self.assert_checker_cpp(file_path)
        checker = self.dispatch(file_path)
        self.assertEqual(checker.file_extension, file_extension)
        self.assertEqual(checker.file_path, file_path)
        self.assertEqual(checker.handle_style_error, self.mock_handle_style_error)
        self.assertEqual(checker.min_confidence, 3)
        # Check "-" for good measure.
        file_base = "-"
        file_extension = ""
        file_path = file_base
        self.assert_checker_cpp(file_path)
        checker = self.dispatch(file_path)
        self.assertEqual(checker.file_extension, file_extension)
        self.assertEqual(checker.file_path, file_path)

    def test_json_paths(self):
        """Test paths that should be checked as JSON."""
        paths = [
           "Source/WebCore/inspector/Inspector.json",
           "Tools/BuildSlaveSupport/build.webkit.org-config/config.json",
        ]

        for path in paths:
            self.assert_checker_json(path)

        # Check checker attributes on a typical input.
        file_base = "foo"
        file_extension = "json"
        file_path = file_base + "." + file_extension
        self.assert_checker_json(file_path)
        checker = self.dispatch(file_path)
        self.assertEqual(checker._handle_style_error,
                          self.mock_handle_style_error)

    def test_python_paths(self):
        """Test paths that should be checked as Python."""
        paths = [
           "foo.py",
           "Tools/Scripts/modules/text_style.py",
        ]

        for path in paths:
            self.assert_checker_python(path)

        # Check checker attributes on a typical input.
        file_base = "foo"
        file_extension = "css"
        file_path = file_base + "." + file_extension
        self.assert_checker_text(file_path)
        checker = self.dispatch(file_path)
        self.assertEqual(checker.file_path, file_path)
        self.assertEqual(checker.handle_style_error,
                          self.mock_handle_style_error)

    def test_text_paths(self):
        """Test paths that should be checked as text."""
        paths = [
           "foo.ac",
           "foo.cc",
           "foo.cgi",
           "foo.css",
           "foo.exp",
           "foo.flex",
           "foo.gyp",
           "foo.gypi",
           "foo.html",
           "foo.idl",
           "foo.in",
           "foo.js",
           "foo.mm",
           "foo.php",
           "foo.pl",
           "foo.pm",
           "foo.pri",
           "foo.pro",
           "foo.rb",
           "foo.sh",
           "foo.txt",
           "foo.wm",
           "foo.xhtml",
           "foo.y",
           os.path.join("Source", "WebCore", "inspector", "front-end", "inspector.js"),
           os.path.join("Tools", "Scripts", "check-webkit-style"),
        ]

        for path in paths:
            self.assert_checker_text(path)

        # Check checker attributes on a typical input.
        file_base = "foo"
        file_extension = "css"
        file_path = file_base + "." + file_extension
        self.assert_checker_text(file_path)
        checker = self.dispatch(file_path)
        self.assertEqual(checker.file_path, file_path)
        self.assertEqual(checker.handle_style_error, self.mock_handle_style_error)

    def test_xml_paths(self):
        """Test paths that should be checked as XML."""
        paths = [
           "Source/WebCore/WebCore.vcproj/WebCore.vcproj",
           "WebKitLibraries/win/tools/vsprops/common.vsprops",
        ]

        for path in paths:
            self.assert_checker_xml(path)

        # Check checker attributes on a typical input.
        file_base = "foo"
        file_extension = "vcproj"
        file_path = file_base + "." + file_extension
        self.assert_checker_xml(file_path)
        checker = self.dispatch(file_path)
        self.assertEqual(checker._handle_style_error,
                          self.mock_handle_style_error)

    def test_none_paths(self):
        """Test paths that have no file type.."""
        paths = [
           "Makefile",
           "foo.asdf",  # Non-sensical file extension.
           "foo.exe",
            ]

        for path in paths:
            self.assert_checker_none(path)


class StyleProcessorConfigurationTest(unittest.TestCase):

    """Tests the StyleProcessorConfiguration class."""

    def setUp(self):
        self._error_messages = []
        """The messages written to _mock_stderr_write() of this class."""

    def _mock_stderr_write(self, message):
        self._error_messages.append(message)

    def _style_checker_configuration(self, output_format="vs7"):
        """Return a StyleProcessorConfiguration instance for testing."""
        base_rules = ["-whitespace", "+whitespace/tab"]
        filter_configuration = FilterConfiguration(base_rules=base_rules)

        return StyleProcessorConfiguration(
                   filter_configuration=filter_configuration,
                   max_reports_per_category={"whitespace/newline": 1},
                   min_confidence=3,
                   output_format=output_format,
                   stderr_write=self._mock_stderr_write)

    def test_init(self):
        """Test the __init__() method."""
        configuration = self._style_checker_configuration()

        # Check that __init__ sets the "public" data attributes correctly.
        self.assertEqual(configuration.max_reports_per_category,
                          {"whitespace/newline": 1})
        self.assertEqual(configuration.stderr_write, self._mock_stderr_write)
        self.assertEqual(configuration.min_confidence, 3)

    def test_is_reportable(self):
        """Test the is_reportable() method."""
        config = self._style_checker_configuration()

        self.assertTrue(config.is_reportable("whitespace/tab", 3, "foo.txt"))

        # Test the confidence check code path by varying the confidence.
        self.assertFalse(config.is_reportable("whitespace/tab", 2, "foo.txt"))

        # Test the category check code path by varying the category.
        self.assertFalse(config.is_reportable("whitespace/line", 4, "foo.txt"))

    def _call_write_style_error(self, output_format):
        config = self._style_checker_configuration(output_format=output_format)
        config.write_style_error(category="whitespace/tab",
                                 confidence_in_error=5,
                                 file_path="foo.h",
                                 line_number=100,
                                 message="message")

    def test_write_style_error_emacs(self):
        """Test the write_style_error() method."""
        self._call_write_style_error("emacs")
        self.assertEqual(self._error_messages,
                          ["foo.h:100:  message  [whitespace/tab] [5]\n"])

    def test_write_style_error_vs7(self):
        """Test the write_style_error() method."""
        self._call_write_style_error("vs7")
        self.assertEqual(self._error_messages,
                          ["foo.h(100):  message  [whitespace/tab] [5]\n"])


class StyleProcessor_EndToEndTest(LoggingTestCase):

    """Test the StyleProcessor class with an emphasis on end-to-end tests."""

    def setUp(self):
        LoggingTestCase.setUp(self)
        self._messages = []

    def _mock_stderr_write(self, message):
        """Save a message so it can later be asserted."""
        self._messages.append(message)

    def test_init(self):
        """Test __init__ constructor."""
        configuration = StyleProcessorConfiguration(
                            filter_configuration=FilterConfiguration(),
                            max_reports_per_category={},
                            min_confidence=3,
                            output_format="vs7",
                            stderr_write=self._mock_stderr_write)
        processor = StyleProcessor(configuration)

        self.assertEqual(processor.error_count, 0)
        self.assertEqual(self._messages, [])

    def test_process(self):
        configuration = StyleProcessorConfiguration(
                            filter_configuration=FilterConfiguration(),
                            max_reports_per_category={},
                            min_confidence=3,
                            output_format="vs7",
                            stderr_write=self._mock_stderr_write)
        processor = StyleProcessor(configuration)

        processor.process(lines=['line1', 'Line with tab:\t'],
                          file_path='foo.txt')
        self.assertEqual(processor.error_count, 1)
        expected_messages = ['foo.txt(2):  Line contains tab character.  '
                             '[whitespace/tab] [5]\n']
        self.assertEqual(self._messages, expected_messages)


class StyleProcessor_CodeCoverageTest(LoggingTestCase):

    """Test the StyleProcessor class with an emphasis on code coverage.

    This class makes heavy use of mock objects.

    """

    class MockDispatchedChecker(object):

        """A mock checker dispatched by the MockDispatcher."""

        def __init__(self, file_path, min_confidence, style_error_handler):
            self.file_path = file_path
            self.min_confidence = min_confidence
            self.style_error_handler = style_error_handler

        def check(self, lines):
            self.lines = lines

    class MockDispatcher(object):

        """A mock CheckerDispatcher class."""

        def __init__(self):
            self.dispatched_checker = None

        def should_skip_with_warning(self, file_path):
            return file_path.endswith('skip_with_warning.txt')

        def should_skip_without_warning(self, file_path):
            return file_path.endswith('skip_without_warning.txt')

        def should_check_and_strip_carriage_returns(self, file_path):
            return not file_path.endswith('carriage_returns_allowed.txt')

        def dispatch(self, file_path, style_error_handler, min_confidence):
            if file_path.endswith('do_not_process.txt'):
                return None

            checker = StyleProcessor_CodeCoverageTest.MockDispatchedChecker(
                          file_path,
                          min_confidence,
                          style_error_handler)

            # Save the dispatched checker so the current test case has a
            # way to access and check it.
            self.dispatched_checker = checker

            return checker

    def setUp(self):
        LoggingTestCase.setUp(self)
        # We can pass an error-message swallower here because error message
        # output is tested instead in the end-to-end test case above.
        configuration = StyleProcessorConfiguration(
                            filter_configuration=FilterConfiguration(),
                            max_reports_per_category={"whitespace/newline": 1},
                            min_confidence=3,
                            output_format="vs7",
                            stderr_write=self._swallow_stderr_message)

        mock_carriage_checker_class = self._create_carriage_checker_class()
        mock_dispatcher = self.MockDispatcher()
        # We do not need to use a real incrementer here because error-count
        # incrementing is tested instead in the end-to-end test case above.
        mock_increment_error_count = self._do_nothing

        processor = StyleProcessor(configuration=configuration,
                        mock_carriage_checker_class=mock_carriage_checker_class,
                        mock_dispatcher=mock_dispatcher,
                        mock_increment_error_count=mock_increment_error_count)

        self._configuration = configuration
        self._mock_dispatcher = mock_dispatcher
        self._processor = processor

    def _do_nothing(self):
        # We provide this function so the caller can pass it to the
        # StyleProcessor constructor.  This lets us assert the equality of
        # the DefaultStyleErrorHandler instance generated by the process()
        # method with an expected instance.
        pass

    def _swallow_stderr_message(self, message):
        """Swallow a message passed to stderr.write()."""
        # This is a mock stderr.write() for passing to the constructor
        # of the StyleProcessorConfiguration class.
        pass

    def _create_carriage_checker_class(self):

        # Create a reference to self with a new name so its name does not
        # conflict with the self introduced below.
        test_case = self

        class MockCarriageChecker(object):

            """A mock carriage-return checker."""

            def __init__(self, style_error_handler):
                self.style_error_handler = style_error_handler

                # This gives the current test case access to the
                # instantiated carriage checker.
                test_case.carriage_checker = self

            def check(self, lines):
                # Save the lines so the current test case has a way to access
                # and check them.
                self.lines = lines

                return lines

        return MockCarriageChecker

    def test_should_process__skip_without_warning(self):
        """Test should_process() for a skip-without-warning file."""
        file_path = "foo/skip_without_warning.txt"

        self.assertFalse(self._processor.should_process(file_path))

    def test_should_process__skip_with_warning(self):
        """Test should_process() for a skip-with-warning file."""
        file_path = "foo/skip_with_warning.txt"

        self.assertFalse(self._processor.should_process(file_path))

        self.assertLog(['WARNING: File exempt from style guide. '
                        'Skipping: "foo/skip_with_warning.txt"\n'])

    def test_should_process__true_result(self):
        """Test should_process() for a file that should be processed."""
        file_path = "foo/skip_process.txt"

        self.assertTrue(self._processor.should_process(file_path))

    def test_process__checker_dispatched(self):
        """Test the process() method for a path with a dispatched checker."""
        file_path = 'foo.txt'
        lines = ['line1', 'line2']
        line_numbers = [100]

        expected_error_handler = DefaultStyleErrorHandler(
            configuration=self._configuration,
            file_path=file_path,
            increment_error_count=self._do_nothing,
            line_numbers=line_numbers)

        self._processor.process(lines=lines,
                                file_path=file_path,
                                line_numbers=line_numbers)

        # Check that the carriage-return checker was instantiated correctly
        # and was passed lines correctly.
        carriage_checker = self.carriage_checker
        self.assertEqual(carriage_checker.style_error_handler,
                          expected_error_handler)
        self.assertEqual(carriage_checker.lines, ['line1', 'line2'])

        # Check that the style checker was dispatched correctly and was
        # passed lines correctly.
        checker = self._mock_dispatcher.dispatched_checker
        self.assertEqual(checker.file_path, 'foo.txt')
        self.assertEqual(checker.min_confidence, 3)
        self.assertEqual(checker.style_error_handler, expected_error_handler)

        self.assertEqual(checker.lines, ['line1', 'line2'])

    def test_process__no_checker_dispatched(self):
        """Test the process() method for a path with no dispatched checker."""
        path = os.path.join('foo', 'do_not_process.txt')
        self.assertRaises(AssertionError, self._processor.process,
                          lines=['line1', 'line2'], file_path=path,
                          line_numbers=[100])

    def test_process__carriage_returns_not_stripped(self):
        """Test that carriage returns aren't stripped from files that are allowed to contain them."""
        file_path = 'carriage_returns_allowed.txt'
        lines = ['line1\r', 'line2\r']
        line_numbers = [100]
        self._processor.process(lines=lines,
                                file_path=file_path,
                                line_numbers=line_numbers)
        # The carriage return checker should never have been invoked, and so
        # should not have saved off any lines.
        self.assertFalse(hasattr(self.carriage_checker, 'lines'))
