Commit 5c2dd6b7 authored by cjerdonek@webkit.org's avatar cjerdonek@webkit.org

2010-02-02 Chris Jerdonek <cjerdonek@webkit.org>

        Reviewed by Shinichiro Hamaji.

        Moved filter-related check-webkit-style code into a separate
        filter module.

        https://bugs.webkit.org/show_bug.cgi?id=34408

        This is preparatory refactoring for Bug 33684, which will allow
        file and folder-specific filter rules.

        * Scripts/webkitpy/style/checker.py:
          - Removed CategoryFilter class (moved to filter.py).

        * Scripts/webkitpy/style/checker_unittest.py:
          - Removed CategoryFilter unit tests (moved to filter_unittest.py).

        * Scripts/webkitpy/style/filter.py: Added.
          - Added CategoryFilter class (moved from checker.py).

        * Scripts/webkitpy/style/filter_unittest.py: Added.
          - Added CategoryFilter unit tests (moved from checker_unittest.py).

        * Scripts/webkitpy/style/unittests.py:
          - Added reference to filter_unittest.py.

git-svn-id: svn://svn.chromium.org/blink/trunk@54234 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 3f80cd9f
2010-02-02 Chris Jerdonek <cjerdonek@webkit.org>
Reviewed by Shinichiro Hamaji.
Moved filter-related check-webkit-style code into a separate
filter module.
https://bugs.webkit.org/show_bug.cgi?id=34408
This is preparatory refactoring for Bug 33684, which will allow
file and folder-specific filter rules.
* Scripts/webkitpy/style/checker.py:
- Removed CategoryFilter class (moved to filter.py).
* Scripts/webkitpy/style/checker_unittest.py:
- Removed CategoryFilter unit tests (moved to filter_unittest.py).
* Scripts/webkitpy/style/filter.py: Added.
- Added CategoryFilter class (moved from checker.py).
* Scripts/webkitpy/style/filter_unittest.py: Added.
- Added CategoryFilter unit tests (moved from checker_unittest.py).
* Scripts/webkitpy/style/unittests.py:
- Added reference to filter_unittest.py.
2010-02-01 Chris Jerdonek <cjerdonek@webkit.org>
Reviewed by Shinichiro Hamaji.
......
......@@ -37,6 +37,7 @@ import sys
from .. style_references import parse_patch
from error_handlers import DefaultStyleErrorHandler
from error_handlers import PatchStyleErrorHandler
from filter import CategoryFilter
from processors.common import check_no_carriage_return
from processors.common import categories as CommonCategories
from processors.cpp import CppProcessor
......@@ -108,8 +109,6 @@ SKIPPED_FILES_WITHOUT_WARNING = [
]
# FIXME: Check that the keys are in _style_categories().
#
# The maximum number of errors to report per file, per category.
# If a category is not a key, then it has no maximum.
MAX_REPORTS_PER_CATEGORY = {
......@@ -202,79 +201,6 @@ Syntax: %(program_name)s [--verbose=#] [--git-commit=<SingleCommit>] [--output=v
return usage
class CategoryFilter(object):
"""Filters whether to check style categories."""
def __init__(self, filter_rules=None):
"""Create a category filter.
This method performs argument validation but does not strip
leading or trailing white space.
Args:
filter_rules: A list of strings that are filter rules, which
are strings beginning with the plus or minus
symbol (+/-). The list should include any
default filter rules at the beginning.
Defaults to the empty list.
Raises:
ValueError: Invalid filter rule if a rule does not start with
plus ("+") or minus ("-").
"""
if filter_rules is None:
filter_rules = []
for rule in filter_rules:
if not (rule.startswith('+') or rule.startswith('-')):
raise ValueError('Invalid filter rule "%s": every rule '
'rule in the --filter flag must start '
'with + or -.' % rule)
self._filter_rules = filter_rules
self._should_check_category = {} # Cached dictionary of category to True/False
def __str__(self):
return ",".join(self._filter_rules)
# Useful for unit testing.
def __eq__(self, other):
"""Return whether this CategoryFilter instance is equal to another."""
return self._filter_rules == other._filter_rules
# Useful for unit testing.
def __ne__(self, other):
# Python does not automatically deduce from __eq__().
return not (self == other)
def should_check(self, category):
"""Return whether the category should be checked.
The rules for determining whether a category should be checked
are as follows. By default all categories should be checked.
Then apply the filter rules in order from first to last, with
later flags taking precedence.
A filter rule applies to a category if the string after the
leading plus/minus (+/-) matches the beginning of the category
name. A plus (+) means the category should be checked, while a
minus (-) means the category should not be checked.
"""
if category in self._should_check_category:
return self._should_check_category[category]
should_check = True # All categories checked by default.
for rule in self._filter_rules:
if not category.startswith(rule[1:]):
continue
should_check = rule.startswith('+')
self._should_check_category[category] = should_check # Update cache.
return should_check
# This class should not have knowledge of the flag key names.
class ProcessorOptions(object):
......
......@@ -37,67 +37,13 @@
import unittest
import checker as style
from checker import CategoryFilter
from checker import ProcessorDispatcher
from checker import ProcessorOptions
from checker import StyleChecker
from filter import CategoryFilter
from processors.cpp import CppProcessor
from processors.text import TextProcessor
class CategoryFilterTest(unittest.TestCase):
"""Tests CategoryFilter class."""
def test_init(self):
"""Test __init__ constructor."""
self.assertRaises(ValueError, CategoryFilter, ["no_prefix"])
CategoryFilter() # No ValueError: works
CategoryFilter(["+"]) # No ValueError: works
CategoryFilter(["-"]) # No ValueError: works
def test_str(self):
"""Test __str__ "to string" operator."""
filter = CategoryFilter(["+a", "-b"])
self.assertEquals(str(filter), "+a,-b")
def test_eq(self):
"""Test __eq__ equality function."""
filter1 = CategoryFilter(["+a", "+b"])
filter2 = CategoryFilter(["+a", "+b"])
filter3 = CategoryFilter(["+b", "+a"])
# == calls __eq__.
self.assertTrue(filter1 == filter2)
self.assertFalse(filter1 == filter3) # Cannot test with assertNotEqual.
def test_ne(self):
"""Test __ne__ inequality function."""
# != calls __ne__.
# By default, __ne__ always returns true on different objects.
# Thus, just check the distinguishing case to verify that the
# code defines __ne__.
self.assertFalse(CategoryFilter() != CategoryFilter())
def test_should_check(self):
"""Test should_check() method."""
filter = CategoryFilter()
self.assertTrue(filter.should_check("everything"))
# Check a second time to exercise cache.
self.assertTrue(filter.should_check("everything"))
filter = CategoryFilter(["-"])
self.assertFalse(filter.should_check("anything"))
# Check a second time to exercise cache.
self.assertFalse(filter.should_check("anything"))
filter = CategoryFilter(["-", "+ab"])
self.assertTrue(filter.should_check("abc"))
self.assertFalse(filter.should_check("a"))
filter = CategoryFilter(["+", "-ab"])
self.assertFalse(filter.should_check("abc"))
self.assertTrue(filter.should_check("a"))
class ProcessorOptionsTest(unittest.TestCase):
......
# 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:
# 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.
"""Contains filter-related code."""
class CategoryFilter(object):
"""Filters whether to check style categories."""
def __init__(self, filter_rules=None):
"""Create a category filter.
This method performs argument validation but does not strip
leading or trailing white space.
Args:
filter_rules: A list of strings that are filter rules, which
are strings beginning with the plus or minus
symbol (+/-). The list should include any
default filter rules at the beginning.
Defaults to the empty list.
Raises:
ValueError: Invalid filter rule if a rule does not start with
plus ("+") or minus ("-").
"""
if filter_rules is None:
filter_rules = []
for rule in filter_rules:
if not (rule.startswith('+') or rule.startswith('-')):
raise ValueError('Invalid filter rule "%s": every rule '
'rule in the --filter flag must start '
'with + or -.' % rule)
self._filter_rules = filter_rules
self._should_check_category = {} # Cached dictionary of category to True/False
def __str__(self):
return ",".join(self._filter_rules)
# Useful for unit testing.
def __eq__(self, other):
"""Return whether this CategoryFilter instance is equal to another."""
return self._filter_rules == other._filter_rules
# Useful for unit testing.
def __ne__(self, other):
# Python does not automatically deduce from __eq__().
return not (self == other)
def should_check(self, category):
"""Return whether the category should be checked.
The rules for determining whether a category should be checked
are as follows. By default all categories should be checked.
Then apply the filter rules in order from first to last, with
later flags taking precedence.
A filter rule applies to a category if the string after the
leading plus/minus (+/-) matches the beginning of the category
name. A plus (+) means the category should be checked, while a
minus (-) means the category should not be checked.
"""
if category in self._should_check_category:
return self._should_check_category[category]
should_check = True # All categories checked by default.
for rule in self._filter_rules:
if not category.startswith(rule[1:]):
continue
should_check = rule.startswith('+')
self._should_check_category[category] = should_check # Update cache.
return should_check
# 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:
# 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 filter.py."""
import unittest
from filter import CategoryFilter
class CategoryFilterTest(unittest.TestCase):
"""Tests CategoryFilter class."""
def test_init(self):
"""Test __init__ constructor."""
self.assertRaises(ValueError, CategoryFilter, ["no_prefix"])
CategoryFilter() # No ValueError: works
CategoryFilter(["+"]) # No ValueError: works
CategoryFilter(["-"]) # No ValueError: works
def test_str(self):
"""Test __str__ "to string" operator."""
filter = CategoryFilter(["+a", "-b"])
self.assertEquals(str(filter), "+a,-b")
def test_eq(self):
"""Test __eq__ equality function."""
filter1 = CategoryFilter(["+a", "+b"])
filter2 = CategoryFilter(["+a", "+b"])
filter3 = CategoryFilter(["+b", "+a"])
# == calls __eq__.
self.assertTrue(filter1 == filter2)
self.assertFalse(filter1 == filter3) # Cannot test with assertNotEqual.
def test_ne(self):
"""Test __ne__ inequality function."""
# != calls __ne__.
# By default, __ne__ always returns true on different objects.
# Thus, just check the distinguishing case to verify that the
# code defines __ne__.
self.assertFalse(CategoryFilter() != CategoryFilter())
def test_should_check(self):
"""Test should_check() method."""
filter = CategoryFilter()
self.assertTrue(filter.should_check("everything"))
# Check a second time to exercise cache.
self.assertTrue(filter.should_check("everything"))
filter = CategoryFilter(["-"])
self.assertFalse(filter.should_check("anything"))
# Check a second time to exercise cache.
self.assertFalse(filter.should_check("anything"))
filter = CategoryFilter(["-", "+ab"])
self.assertTrue(filter.should_check("abc"))
self.assertFalse(filter.should_check("a"))
filter = CategoryFilter(["+", "-ab"])
self.assertFalse(filter.should_check("abc"))
self.assertTrue(filter.should_check("a"))
......@@ -37,6 +37,7 @@ import unittest
from checker_unittest import *
from error_handlers_unittest import *
from filter_unittest import *
from processors.common_unittest import *
from processors.cpp_unittest import *
from processors.text_unittest import *
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment