| # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org) |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions |
| # are met: |
| # 1. Redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer. |
| # 2. 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. |
| # |
| # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 error_handlers.py.""" |
| |
| |
| import unittest |
| |
| from checker import StyleProcessorConfiguration |
| from error_handlers import DefaultStyleErrorHandler |
| from filter import FilterConfiguration |
| from webkitpy.common.system.logtesting import LoggingTestCase |
| |
| |
| class DefaultStyleErrorHandlerTest(LoggingTestCase): |
| |
| """Tests the DefaultStyleErrorHandler class.""" |
| |
| def setUp(self): |
| super(DefaultStyleErrorHandlerTest, self).setUp() |
| self._error_count = 0 |
| |
| _category = "whitespace/tab" |
| """The category name for the tests in this class.""" |
| |
| _file_path = "foo.h" |
| """The file path for the tests in this class.""" |
| |
| def _mock_increment_error_count(self): |
| self._error_count += 1 |
| |
| def _style_checker_configuration(self): |
| """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/tab": 2}, |
| min_confidence=3, |
| output_format="vs7", |
| commit_queue=False) |
| |
| def _error_handler(self, configuration, line_numbers=None): |
| return DefaultStyleErrorHandler(configuration=configuration, |
| file_path=self._file_path, |
| increment_error_count=self._mock_increment_error_count, |
| line_numbers=line_numbers) |
| |
| def _check_initialized(self): |
| """Check that count and error messages are initialized.""" |
| self.assertEqual(0, self._error_count) |
| |
| def _call_error_handler(self, handle_error, confidence, line_number=100): |
| """Call the given error handler with a test error.""" |
| handle_error(line_number=line_number, |
| category=self._category, |
| confidence=confidence, |
| message="message") |
| |
| def test_eq__true_return_value(self): |
| """Test the __eq__() method for the return value of True.""" |
| handler1 = self._error_handler(configuration=None) |
| handler2 = self._error_handler(configuration=None) |
| |
| self.assertTrue(handler1.__eq__(handler2)) |
| |
| def test_eq__false_return_value(self): |
| """Test the __eq__() method for the return value of False.""" |
| def make_handler(configuration=self._style_checker_configuration(), |
| file_path='foo.txt', increment_error_count=lambda: True, |
| line_numbers=[100]): |
| return DefaultStyleErrorHandler(configuration=configuration, |
| file_path=file_path, |
| increment_error_count=increment_error_count, |
| line_numbers=line_numbers) |
| |
| handler = make_handler() |
| |
| # Establish a baseline for our comparisons below. |
| self.assertTrue(handler.__eq__(make_handler())) |
| |
| # Verify that a difference in any argument causes equality to fail. |
| self.assertFalse(handler.__eq__(make_handler(configuration=None))) |
| self.assertFalse(handler.__eq__(make_handler(file_path='bar.txt'))) |
| self.assertFalse(handler.__eq__(make_handler(increment_error_count=None))) |
| self.assertFalse(handler.__eq__(make_handler(line_numbers=[50]))) |
| |
| def test_ne(self): |
| """Test the __ne__() method.""" |
| # By default, __ne__ always returns true on different objects. |
| # Thus, check just the distinguishing case to verify that the |
| # code defines __ne__. |
| handler1 = self._error_handler(configuration=None) |
| handler2 = self._error_handler(configuration=None) |
| |
| self.assertFalse(handler1.__ne__(handler2)) |
| |
| def test_non_reportable_error(self): |
| """Test __call__() with a non-reportable error.""" |
| self._check_initialized() |
| configuration = self._style_checker_configuration() |
| |
| confidence = 1 |
| # Confirm the error is not reportable. |
| self.assertFalse(configuration.is_reportable(self._category, |
| confidence, |
| self._file_path)) |
| error_handler = self._error_handler(configuration) |
| self._call_error_handler(error_handler, confidence) |
| |
| self.assertEqual(0, self._error_count) |
| |
| # Also serves as a reportable error test. |
| def test_max_reports_per_category(self): |
| """Test error report suppression in __call__() method.""" |
| self._check_initialized() |
| configuration = self._style_checker_configuration() |
| error_handler = self._error_handler(configuration) |
| |
| confidence = 5 |
| |
| # First call: usual reporting. |
| self._call_error_handler(error_handler, confidence) |
| self.assertEqual(1, self._error_count) |
| self.assertLog(["ERROR: foo.h(100): message [whitespace/tab] [5]\n"]) |
| |
| # Second call: suppression message reported. |
| self._call_error_handler(error_handler, confidence) |
| # The "Suppressing further..." message counts as an additional |
| # message (but not as an addition to the error count). |
| self.assertEqual(2, self._error_count) |
| expected_message = ["ERROR: foo.h(100): message [whitespace/tab] [5]\n", |
| "ERROR: Suppressing further [whitespace/tab] reports for this file.\n"] |
| self.assertLog(expected_message) |
| |
| # Third call: no report. |
| self._call_error_handler(error_handler, confidence) |
| self.assertEqual(3, self._error_count) |
| self.assertLog([]) |
| |
| def test_line_numbers(self): |
| """Test the line_numbers parameter.""" |
| self._check_initialized() |
| configuration = self._style_checker_configuration() |
| error_handler = self._error_handler(configuration, |
| line_numbers=[50]) |
| confidence = 5 |
| |
| # Error on non-modified line: no error. |
| self._call_error_handler(error_handler, confidence, line_number=60) |
| self.assertEqual(0, self._error_count) |
| self.assertLog([]) |
| |
| # Error on modified line: error. |
| self._call_error_handler(error_handler, confidence, line_number=50) |
| self.assertEqual(1, self._error_count) |
| self.assertLog(["ERROR: foo.h(50): message [whitespace/tab] [5]\n"]) |
| |
| # Error on non-modified line after turning off line filtering: error. |
| error_handler.turn_off_line_filtering() |
| self._call_error_handler(error_handler, confidence, line_number=60) |
| self.assertEqual(2, self._error_count) |
| self.assertLog(['ERROR: foo.h(60): message [whitespace/tab] [5]\n', |
| 'ERROR: Suppressing further [whitespace/tab] reports for this file.\n']) |