Refactored check-webkit-style's ProcessorOptions class into two
authorcjerdonek@webkit.org <cjerdonek@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 18 Feb 2010 07:29:12 +0000 (07:29 +0000)
committercjerdonek@webkit.org <cjerdonek@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 18 Feb 2010 07:29:12 +0000 (07:29 +0000)
classes. This revision contains no new functionality.

Reviewed by Shinichiro Hamaji.

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

Divided the ProcessorOptions class into a CommandOptionValues
class (the result of parsing the command-line options) and
a StyleCheckerConfiguration class (which configures the main
StyleChecker).

* Scripts/check-webkit-style:
  - Updated main() to convert the parsed command option values
    to a StyleCheckConfiguration instance prior to constructing
    a StyleChecker.

* Scripts/webkitpy/style/checker.py:
  - Added check_webkit_style_configuration() to convert a
    CommandOptionValues instance into a StyleCheckerConfiguration
    instance.
  - Renamed the ProcessorOptions class to CommandOptionValues.
  - In the CommandOptionValues class--
    - Replaced the filter_configuration attribute with the
      simpler filter_rules attribute.
    - Removed the max_reports_per_error attribute.
    - Moved the is_reportable() method to the new
      StyleCheckerConfiguration class.
  - Removed the base_filter_rules attribute from the
    DefaultCommandOptionValues class.
  - In the ArgumentParser class--
    - Added base_filter_rules to the constructor.
    - Changed the parse() method to return a CommandOptionValues
      instance instead of a ProcessorOptions instance.
  - Created a StyleCheckerConfiguration class.
    - Added the data attributes max_reports_per_category,
      stderr_write, and verbosity.
    - Added is_reportable() (moved from the ProcessorOptions
      class) and write_style_error() (moved from the
      DefaultStyleErrorHandler class).
  - In the StyleChecker class--
    - Replaced the ProcessorOptions options attribute with the
      StyleCheckerConfiguration _configuration attribute.
    - Removed the _stderr_write attribute.

* Scripts/webkitpy/style/checker_unittest.py:
  - Updated the existing unit test classes as necessary.
  - Added a StyleCheckerConfigurationTest class.

* Scripts/webkitpy/style/error_handlers.py:
  - Updated the DefaultStyleErrorHandler class to accept a
    StyleCheckerConfiguration instance instead of a ProcessorOptions
    instance and an stderr_write method.

* Scripts/webkitpy/style/error_handlers_unittest.py:
  - Updated the unit test classes as necessary.

* Scripts/webkitpy/style/filter.py:
  - Addressed the FIXME in the FilterConfiguration class to change
    the user_rules attribute to _user_rules (since it is now
    accessed only internally).

* Scripts/webkitpy/style/filter_unittest.py:
  - Updated to reflect the change from user_rules to _user_rules.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@54934 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKitTools/ChangeLog
WebKitTools/Scripts/check-webkit-style
WebKitTools/Scripts/webkitpy/style/checker.py
WebKitTools/Scripts/webkitpy/style/checker_unittest.py
WebKitTools/Scripts/webkitpy/style/error_handlers.py
WebKitTools/Scripts/webkitpy/style/error_handlers_unittest.py
WebKitTools/Scripts/webkitpy/style/filter.py
WebKitTools/Scripts/webkitpy/style/filter_unittest.py

index 32d935314cd7885bbcc5e61d91f763204a507b3c..54be5abde0093cd6f9b1ed37e77c82ee0e0097a8 100644 (file)
@@ -1,3 +1,70 @@
+2010-02-16  Chris Jerdonek  <cjerdonek@webkit.org>
+
+        Reviewed by Shinichiro Hamaji.
+
+        Refactored check-webkit-style's ProcessorOptions class into two
+        classes. This revision contains no new functionality.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34674
+
+        Divided the ProcessorOptions class into a CommandOptionValues
+        class (the result of parsing the command-line options) and
+        a StyleCheckerConfiguration class (which configures the main
+        StyleChecker).
+
+        * Scripts/check-webkit-style:
+          - Updated main() to convert the parsed command option values
+            to a StyleCheckConfiguration instance prior to constructing
+            a StyleChecker.
+
+        * Scripts/webkitpy/style/checker.py:
+          - Added check_webkit_style_configuration() to convert a
+            CommandOptionValues instance into a StyleCheckerConfiguration
+            instance.
+          - Renamed the ProcessorOptions class to CommandOptionValues.
+          - In the CommandOptionValues class--
+            - Replaced the filter_configuration attribute with the
+              simpler filter_rules attribute.
+            - Removed the max_reports_per_error attribute.
+            - Moved the is_reportable() method to the new
+              StyleCheckerConfiguration class.
+          - Removed the base_filter_rules attribute from the
+            DefaultCommandOptionValues class.
+          - In the ArgumentParser class--
+            - Added base_filter_rules to the constructor.
+            - Changed the parse() method to return a CommandOptionValues
+              instance instead of a ProcessorOptions instance.
+          - Created a StyleCheckerConfiguration class.
+            - Added the data attributes max_reports_per_category,
+              stderr_write, and verbosity.
+            - Added is_reportable() (moved from the ProcessorOptions
+              class) and write_style_error() (moved from the
+              DefaultStyleErrorHandler class).
+          - In the StyleChecker class--
+            - Replaced the ProcessorOptions options attribute with the
+              StyleCheckerConfiguration _configuration attribute.
+            - Removed the _stderr_write attribute.
+
+        * Scripts/webkitpy/style/checker_unittest.py:
+          - Updated the existing unit test classes as necessary.
+          - Added a StyleCheckerConfigurationTest class.
+
+        * Scripts/webkitpy/style/error_handlers.py:
+          - Updated the DefaultStyleErrorHandler class to accept a
+            StyleCheckerConfiguration instance instead of a ProcessorOptions
+            instance and an stderr_write method.
+
+        * Scripts/webkitpy/style/error_handlers_unittest.py:
+          - Updated the unit test classes as necessary.
+
+        * Scripts/webkitpy/style/filter.py:
+          - Addressed the FIXME in the FilterConfiguration class to change
+            the user_rules attribute to _user_rules (since it is now
+            accessed only internally).
+
+        * Scripts/webkitpy/style/filter_unittest.py:
+          - Updated to reflect the change from user_rules to _user_rules.
+
 2010-02-17  Shinichiro Hamaji  <hamaji@chromium.org>
 
         Reviewed by Eric Seidel.
index 4b9efe5aa200393d3400e908eddaa4817208724d..74ddc01b3c2e41911f116899ca91e11dca0bae8e 100755 (executable)
@@ -61,7 +61,8 @@ def main():
     parser = checker.ArgumentParser()
     (files, options) = parser.parse(sys.argv[1:])
 
-    style_checker = checker.StyleChecker(options)
+    configuration = checker.check_webkit_style_configuration(options)
+    style_checker = checker.StyleChecker(configuration)
 
     if files:
         for filename in files:
index 2fff84c4540058e915dd1b454c11d53a5e1f7368..bd99d0bfd3538b559a0d381c659a57c3d52cc26c 100644 (file)
@@ -159,11 +159,28 @@ def _all_categories():
 
 def _check_webkit_style_defaults():
     """Return the default command-line options for check-webkit-style."""
-    return DefaultCommandOptionValues(base_filter_rules=_BASE_FILTER_RULES,
-                                      output_format=_DEFAULT_OUTPUT_FORMAT,
+    return DefaultCommandOptionValues(output_format=_DEFAULT_OUTPUT_FORMAT,
                                       verbosity=_DEFAULT_VERBOSITY)
 
 
+def check_webkit_style_configuration(options):
+    """Return a StyleCheckerConfiguration instance for check-webkit-style.
+
+    Args:
+      options: A CommandOptionValues instance.
+
+    """
+    filter_configuration = FilterConfiguration(
+                               base_rules=_BASE_FILTER_RULES,
+                               path_specific=_PATH_RULES_SPECIFIER,
+                               user_rules=options.filter_rules)
+
+    return StyleCheckerConfiguration(filter_configuration=filter_configuration,
+               max_reports_per_category=_MAX_REPORTS_PER_CATEGORY,
+               output_format=options.output_format,
+               stderr_write=sys.stderr.write,
+               verbosity=options.verbosity)
+
 
 def _create_usage(default_options):
     """Return the usage string to display for command help.
@@ -239,16 +256,8 @@ Syntax: %(program_name)s [--verbose=#] [--git-commit=<SingleCommit>] [--output=v
 
 # FIXME: Eliminate support for "extra_flag_values".
 #
-# FIXME: Remove everything from ProcessorOptions except for the
-#        information that can be passed via the command line, and
-#        rename to something like CheckWebKitStyleOptions.  This
-#        includes, but is not limited to, removing the
-#        max_reports_per_error attribute and the is_reportable()
-#        method.  See also the FIXME below to create a new class
-#        called something like CheckerConfiguration.
-#
 # This class should not have knowledge of the flag key names.
-class ProcessorOptions(object):
+class CommandOptionValues(object):
 
     """Stores the option values passed by the user via the command line.
 
@@ -257,16 +266,14 @@ class ProcessorOptions(object):
                          pairs that are not otherwise represented by this
                          class.  The default is the empty dictionary.
 
-      filter_configuration: A FilterConfiguration instance.  The default
-                            is the "empty" filter configuration, which
-                            means that all errors should be checked.
+      filter_rules: The list of filter rules provided by the user.
+                    These rules are appended to the base rules and
+                    path-specific rules and so take precedence over
+                    the base filter rules, etc.
 
       git_commit: A string representing the git commit to check.
                   The default is None.
 
-      max_reports_per_error: The maximum number of errors to report
-                             per file, per category.
-
       output_format: A string that is the output format.  The supported
                      output formats are "emacs" which emacs can parse
                      and "vs7" which Microsoft Visual Studio 7 can parse.
@@ -278,17 +285,14 @@ class ProcessorOptions(object):
     """
     def __init__(self,
                  extra_flag_values=None,
-                 filter_configuration = None,
+                 filter_rules=None,
                  git_commit=None,
-                 max_reports_per_category=None,
                  output_format="emacs",
                  verbosity=1):
         if extra_flag_values is None:
             extra_flag_values = {}
-        if filter_configuration is None:
-            filter_configuration = FilterConfiguration()
-        if max_reports_per_category is None:
-            max_reports_per_category = {}
+        if filter_rules is None:
+            filter_rules = []
 
         if output_format not in ("emacs", "vs7"):
             raise ValueError('Invalid "output_format" parameter: '
@@ -301,23 +305,20 @@ class ProcessorOptions(object):
                              'Value given: "%s".' % verbosity)
 
         self.extra_flag_values = extra_flag_values
-        self.filter_configuration = filter_configuration
+        self.filter_rules = filter_rules
         self.git_commit = git_commit
-        self.max_reports_per_category = max_reports_per_category
         self.output_format = output_format
         self.verbosity = verbosity
 
     # Useful for unit testing.
     def __eq__(self, other):
-        """Return whether this ProcessorOptions instance is equal to another."""
+        """Return whether this instance is equal to another."""
         if self.extra_flag_values != other.extra_flag_values:
             return False
-        if self.filter_configuration != other.filter_configuration:
+        if self.filter_rules != other.filter_rules:
             return False
         if self.git_commit != other.git_commit:
             return False
-        if self.max_reports_per_category != other.max_reports_per_category:
-            return False
         if self.output_format != other.output_format:
             return False
         if self.verbosity != other.verbosity:
@@ -330,28 +331,6 @@ class ProcessorOptions(object):
         # Python does not automatically deduce this from __eq__().
         return not self.__eq__(other)
 
-    def is_reportable(self, category, confidence_in_error, path):
-        """Return whether an error is reportable.
-
-        An error is reportable if the confidence in the error
-        is at least the current verbosity level, and if the current
-        filter says that the category should be checked for the
-        given path.
-
-        Args:
-          category: A string that is a style category.
-          confidence_in_error: An integer between 1 and 5, inclusive, that
-                               represents the application's confidence in
-                               the error. A higher number signifies greater
-                               confidence.
-          path: The path of the file being checked
-
-        """
-        if confidence_in_error < self.verbosity:
-            return False
-
-        return self.filter_configuration.should_check(category, path)
-
 
 # This class should not have knowledge of the flag key names.
 class DefaultCommandOptionValues(object):
@@ -359,15 +338,12 @@ class DefaultCommandOptionValues(object):
     """Stores the default check-webkit-style command-line options.
 
     Attributes:
-      base_filter_rules: A list of boolean filter rule strings that begin
-                         the list of filter rules used to check style.
       output_format: A string that is the default output format.
       verbosity: An integer that is the default verbosity level.
 
     """
 
-    def __init__(self, base_filter_rules, output_format, verbosity):
-        self.base_filter_rules = base_filter_rules
+    def __init__(self, output_format, verbosity):
         self.output_format = output_format
         self.verbosity = verbosity
 
@@ -380,12 +356,12 @@ class ArgumentPrinter(object):
         return '--%(key)s=%(val)s' % {'key': flag_key, 'val': flag_value }
 
     def to_flag_string(self, options):
-        """Return a flag string yielding the given ProcessorOptions instance.
+        """Return a flag string of the given CommandOptionValues instance.
 
         This method orders the flag values alphabetically by the flag key.
 
         Args:
-          options: A ProcessorOptions instance.
+          options: A CommandOptionValues instance.
 
         """
         flags = options.extra_flag_values.copy()
@@ -393,9 +369,9 @@ class ArgumentPrinter(object):
         flags['output'] = options.output_format
         flags['verbose'] = options.verbosity
         # Only include the filter flag if user-provided rules are present.
-        user_rules = options.filter_configuration.user_rules
-        if user_rules:
-            flags['filter'] = ",".join(user_rules)
+        filter_rules = options.filter_rules
+        if filter_rules:
+            flags['filter'] = ",".join(filter_rules)
         if options.git_commit:
             flags['git-commit'] = options.git_commit
 
@@ -410,6 +386,8 @@ class ArgumentPrinter(object):
 # FIXME: Replace the use of getopt.getopt() with optparse.OptionParser.
 class ArgumentParser(object):
 
+    # FIXME: Move the documentation of the attributes to the __init__
+    #        docstring after making the attributes internal.
     """Supports the parsing of check-webkit-style command arguments.
 
     Attributes:
@@ -427,9 +405,30 @@ class ArgumentParser(object):
     """
 
     def __init__(self,
+                 base_filter_rules=None,
                  create_usage=None,
                  default_options=None,
                  stderr_write=None):
+        """Create an ArgumentParser instance.
+
+        Args:
+          base_filter_rules: The list of filter rules at the beginning of
+                             the list of rules used to check style.  This
+                             list has the least precedence when checking
+                             style and precedes any user-provided rules.
+                             The class uses this parameter only for display
+                             purposes to the user.  Defaults to the base
+                             filter rules for check-webkit-style.
+          create_usage: See the documentation of the corresponding
+                        attribute in the class docstring.
+          default_options: See the documentation of the corresponding
+                           attribute in the class docstring.
+          stderr_write: See the documentation of the corresponding
+                        attribute in the class docstring.
+
+        """
+        if base_filter_rules is None:
+            base_filter_rules = _BASE_FILTER_RULES
         if create_usage is None:
             create_usage = _create_usage
         if default_options is None:
@@ -437,6 +436,7 @@ class ArgumentParser(object):
         if stderr_write is None:
             stderr_write = sys.stderr.write
 
+        self._base_filter_rules = base_filter_rules
         # FIXME: Rename these to reflect that they are internal.
         self.create_usage = create_usage
         self.default_options = default_options
@@ -464,7 +464,7 @@ class ArgumentParser(object):
             self.stderr_write('    ' + category + '\n')
 
         self.stderr_write('\nDefault filter rules**:\n')
-        for filter_rule in sorted(self.default_options.base_filter_rules):
+        for filter_rule in sorted(self._base_filter_rules):
             self.stderr_write('    ' + filter_rule + '\n')
         self.stderr_write('\n**The command always evaluates the above rules, '
                           'and before any --filter flag.\n\n')
@@ -493,7 +493,7 @@ class ArgumentParser(object):
         Args:
           args: A list of command-line arguments as returned by sys.argv[1:].
           extra_flags: A list of flags whose values we want to extract, but
-                       are not supported by the ProcessorOptions class.
+                       are not supported by the CommandOptionValues class.
                        An example flag "new_flag=". This defaults to the
                        empty list.
 
@@ -501,7 +501,7 @@ class ArgumentParser(object):
           A tuple of (filenames, options)
 
           filenames: The list of filenames to check.
-          options: A ProcessorOptions instance.
+          options: A CommandOptionValues instance.
 
         """
         if extra_flags is None:
@@ -509,9 +509,8 @@ class ArgumentParser(object):
 
         output_format = self.default_options.output_format
         verbosity = self.default_options.verbosity
-        base_rules = self.default_options.base_filter_rules
 
-        # The flags already supported by the ProcessorOptions class.
+        # The flags already supported by the CommandOptionValues class.
         flags = ['help', 'output=', 'verbose=', 'filter=', 'git-commit=']
 
         for extra_flag in extra_flags:
@@ -532,7 +531,7 @@ class ArgumentParser(object):
 
         extra_flag_values = {}
         git_commit = None
-        user_rules = []
+        filter_rules = []
 
         for (opt, val) in opts:
             if opt == '--help':
@@ -546,8 +545,7 @@ class ArgumentParser(object):
             elif opt == '--filter':
                 if not val:
                     self._exit_with_categories()
-                # Prepend the defaults.
-                user_rules = self._parse_filter_flag(val)
+                filter_rules = self._parse_filter_flag(val)
             else:
                 extra_flag_values[opt] = val
 
@@ -562,23 +560,18 @@ class ArgumentParser(object):
                              output_format)
 
         all_categories = _all_categories()
-        validate_filter_rules(user_rules, all_categories)
+        validate_filter_rules(filter_rules, all_categories)
 
         verbosity = int(verbosity)
         if (verbosity < 1) or (verbosity > 5):
             raise ValueError('Invalid --verbose value %s: value must '
                              'be between 1-5.' % verbosity)
 
-        filter_configuration = FilterConfiguration(base_rules=base_rules,
-                                   path_specific=_PATH_RULES_SPECIFIER,
-                                   user_rules=user_rules)
-
-        options = ProcessorOptions(extra_flag_values=extra_flag_values,
-                      filter_configuration=filter_configuration,
-                      git_commit=git_commit,
-                      max_reports_per_category=_MAX_REPORTS_PER_CATEGORY,
-                      output_format=output_format,
-                      verbosity=verbosity)
+        options = CommandOptionValues(extra_flag_values=extra_flag_values,
+                                 filter_rules=filter_rules,
+                                 git_commit=git_commit,
+                                 output_format=output_format,
+                                 verbosity=verbosity)
 
         return (filenames, options)
 
@@ -681,16 +674,95 @@ class ProcessorDispatcher(object):
         return processor
 
 
-# FIXME: When creating the new CheckWebKitStyleOptions class as
-#        described in a FIXME above, add a new class here called
-#        something like CheckerConfiguration.  The class should contain
-#        attributes for options needed to process a file.  This includes
-#        a subset of the CheckWebKitStyleOptions attributes, a
-#        FilterConfiguration attribute, an stderr_write attribute, a
-#        max_reports_per_category attribute, etc.  It can also include
-#        the is_reportable() method.  The StyleChecker should accept
-#        an instance of this class rather than a ProcessorOptions
-#        instance.
+class StyleCheckerConfiguration(object):
+
+    """Stores configuration values for the StyleChecker class.
+
+    Attributes:
+      max_reports_per_category: The maximum number of errors to report
+                                per category, per file.
+
+      stderr_write: A function that takes a string as a parameter and
+                    serves as stderr.write.
+
+      verbosity: An integer between 1-5 inclusive that restricts output
+                 to errors with a confidence score at or above this value.
+
+    """
+
+    def __init__(self,
+                 filter_configuration,
+                 max_reports_per_category,
+                 output_format,
+                 stderr_write,
+                 verbosity):
+        """Create a StyleCheckerConfiguration instance.
+
+        Args:
+          filter_configuration: A FilterConfiguration instance.  The default
+                                is the "empty" filter configuration, which
+                                means that all errors should be checked.
+
+          max_reports_per_category: The maximum number of errors to report
+                                    per category, per file.
+
+          output_format: A string that is the output format.  The supported
+                         output formats are "emacs" which emacs can parse
+                         and "vs7" which Microsoft Visual Studio 7 can parse.
+
+          stderr_write: A function that takes a string as a parameter and
+                        serves as stderr.write.
+
+          verbosity: An integer between 1-5 inclusive that restricts output
+                     to errors with a confidence score at or above this value.
+                     The default is 1, which reports all errors.
+
+        """
+        self._filter_configuration = filter_configuration
+        self._output_format = output_format
+
+        self.max_reports_per_category = max_reports_per_category
+        self.stderr_write = stderr_write
+        self.verbosity = verbosity
+
+    def is_reportable(self, category, confidence_in_error, file_path):
+        """Return whether an error is reportable.
+
+        An error is reportable if both the confidence in the error is
+        at least the current verbosity level and the current filter
+        says the category should be checked for the given path.
+
+        Args:
+          category: A string that is a style category.
+          confidence_in_error: An integer between 1 and 5, inclusive, that
+                               represents the application's confidence in
+                               the error.  A higher number signifies greater
+                               confidence.
+          file_path: The path of the file being checked
+
+        """
+        if confidence_in_error < self.verbosity:
+            return False
+
+        return self._filter_configuration.should_check(category, file_path)
+
+    def write_style_error(self,
+                          category,
+                          confidence,
+                          file_path,
+                          line_number,
+                          message):
+        """Write a style error to the configured stderr."""
+        if self._output_format == 'vs7':
+            format_string = "%s(%s):  %s  [%s] [%d]\n"
+        else:
+            format_string = "%s:%s:  %s  [%s] [%d]\n"
+
+        self.stderr_write(format_string % (file_path,
+                                           line_number,
+                                           message,
+                                           category,
+                                           confidence))
 
 
 class StyleChecker(object):
@@ -701,33 +773,27 @@ class StyleChecker(object):
          error_count: An integer that is the total number of reported
                       errors for the lifetime of this StyleChecker
                       instance.
-         options: A ProcessorOptions instance that controls the behavior
-                  of style checking.
          file_count: An integer that is the total number of processed
                      files.  Note that the number of skipped files is
                      included in this value.
 
     """
 
-    def __init__(self, options, stderr_write=None):
+    def __init__(self, configuration):
         """Create a StyleChecker instance.
 
         Args:
-          options: See options attribute.
-          stderr_write: A function that takes a string as a parameter
-                        and that is called when a style error occurs.
-                        Defaults to sys.stderr.write. This should be
-                        used only for unit tests.
+          configuration: A StyleCheckerConfiguration instance that controls
+                         the behavior of style checking.
 
         """
-        if stderr_write is None:
-            stderr_write = sys.stderr.write
-
-        self._stderr_write = stderr_write
+        self._configuration = configuration
         self.error_count = 0
-        self.options = options
         self.file_count = 0
 
+    def _stderr_write(self, message):
+        self._configuration.stderr_write(message)
+
     def _increment_error_count(self):
         """Increment the total count of reported errors."""
         self.error_count += 1
@@ -791,11 +857,11 @@ class StyleChecker(object):
 
         """
         if handle_style_error is None:
-            handle_style_error = DefaultStyleErrorHandler(file_path=file_path,
-                                     options=self.options,
+            handle_style_error = DefaultStyleErrorHandler(
+                                     configuration=self._configuration,
+                                     file_path=file_path,
                                      increment_error_count=
-                                         self._increment_error_count,
-                                     stderr_write=self._stderr_write)
+                                         self._increment_error_count)
         if process_file is None:
             process_file = self._process_file
 
@@ -810,7 +876,7 @@ class StyleChecker(object):
                                "style guide.\n" % file_path)
             return
 
-        verbosity = self.options.verbosity
+        verbosity = self._configuration.verbosity
         processor = dispatcher.dispatch_processor(file_path,
                                                   handle_style_error,
                                                   verbosity)
@@ -830,8 +896,7 @@ class StyleChecker(object):
         for file_path, diff in patch_files.iteritems():
             style_error_handler = PatchStyleErrorHandler(diff,
                                       file_path,
-                                      self.options,
-                                      self._increment_error_count,
-                                      self._stderr_write)
+                                      self._configuration,
+                                      self._increment_error_count)
 
             self.check_file(file_path, style_error_handler)
index 29c1b6ceafacf1e30fad776cb8d301d47c54b6db..ba1bb4d79d278888327754241e1a8b591e9cd56d 100755 (executable)
@@ -41,10 +41,11 @@ 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 CommandOptionValues as ProcessorOptions
 from checker import DefaultCommandOptionValues
 from checker import ProcessorDispatcher
-from checker import ProcessorOptions
 from checker import StyleChecker
+from checker import StyleCheckerConfiguration
 from filter import validate_filter_rules
 from filter import FilterConfiguration
 from processors.cpp import CppProcessor
@@ -60,9 +61,8 @@ class ProcessorOptionsTest(unittest.TestCase):
         # Check default parameters.
         options = ProcessorOptions()
         self.assertEquals(options.extra_flag_values, {})
-        self.assertEquals(options.filter_configuration, FilterConfiguration())
+        self.assertEquals(options.filter_rules, [])
         self.assertEquals(options.git_commit, None)
-        self.assertEquals(options.max_reports_per_category, {})
         self.assertEquals(options.output_format, "emacs")
         self.assertEquals(options.verbosity, 1)
 
@@ -76,17 +76,14 @@ class ProcessorOptionsTest(unittest.TestCase):
         ProcessorOptions(verbosity=5) # works
 
         # Check attributes.
-        filter_configuration = FilterConfiguration(base_rules=["+"])
         options = ProcessorOptions(extra_flag_values={"extra_value" : 2},
-                                   filter_configuration=filter_configuration,
+                                   filter_rules=["+"],
                                    git_commit="commit",
-                                   max_reports_per_category={"category": 3},
                                    output_format="vs7",
                                    verbosity=3)
         self.assertEquals(options.extra_flag_values, {"extra_value" : 2})
-        self.assertEquals(options.filter_configuration, filter_configuration)
+        self.assertEquals(options.filter_rules, ["+"])
         self.assertEquals(options.git_commit, "commit")
-        self.assertEquals(options.max_reports_per_category, {"category": 3})
         self.assertEquals(options.output_format, "vs7")
         self.assertEquals(options.verbosity, 3)
 
@@ -96,20 +93,15 @@ class ProcessorOptionsTest(unittest.TestCase):
         self.assertTrue(ProcessorOptions() == ProcessorOptions())
 
         # Verify that a difference in any argument causes equality to fail.
-        filter_configuration = FilterConfiguration(base_rules=["+"])
         options = ProcessorOptions(extra_flag_values={"extra_value" : 1},
-                                   filter_configuration=filter_configuration,
+                                   filter_rules=["+"],
                                    git_commit="commit",
-                                   max_reports_per_category={"category": 3},
                                    output_format="vs7",
                                    verbosity=1)
-        self.assertFalse(options == ProcessorOptions(extra_flag_values={"extra_value" : 2}))
-        new_config = FilterConfiguration(base_rules=["-"])
-        self.assertFalse(options ==
-                         ProcessorOptions(filter_configuration=new_config))
+        self.assertFalse(options == ProcessorOptions(extra_flag_values=
+                                                     {"extra_value" : 2}))
+        self.assertFalse(options == ProcessorOptions(filter_rules=["-"]))
         self.assertFalse(options == ProcessorOptions(git_commit="commit2"))
-        self.assertFalse(options == ProcessorOptions(max_reports_per_category=
-                                                     {"category": 2}))
         self.assertFalse(options == ProcessorOptions(output_format="emacs"))
         self.assertFalse(options == ProcessorOptions(verbosity=2))
 
@@ -121,20 +113,6 @@ class ProcessorOptionsTest(unittest.TestCase):
         # code defines __ne__.
         self.assertFalse(ProcessorOptions() != ProcessorOptions())
 
-    def test_is_reportable(self):
-        """Test is_reportable()."""
-        filter_configuration = FilterConfiguration(base_rules=["-xyz"])
-        options = ProcessorOptions(filter_configuration=filter_configuration,
-                                   verbosity=3)
-
-        # Test verbosity
-        self.assertTrue(options.is_reportable("abc", 3, "foo.h"))
-        self.assertFalse(options.is_reportable("abc", 2, "foo.h"))
-
-        # Test filter
-        self.assertTrue(options.is_reportable("xy", 3, "foo.h"))
-        self.assertFalse(options.is_reportable("xyz", 3, "foo.h"))
-
 
 class GlobalVariablesTest(unittest.TestCase):
 
@@ -231,15 +209,14 @@ class ArgumentPrinterTest(unittest.TestCase):
     def _create_options(self,
                         output_format='emacs',
                         verbosity=3,
-                        user_rules=[],
+                        filter_rules=[],
                         git_commit=None,
                         extra_flag_values={}):
-        filter_configuration = FilterConfiguration(user_rules=user_rules)
-        return style.ProcessorOptions(extra_flag_values=extra_flag_values,
-                                      filter_configuration=filter_configuration,
-                                      git_commit=git_commit,
-                                      output_format=output_format,
-                                      verbosity=verbosity)
+        return ProcessorOptions(extra_flag_values=extra_flag_values,
+                                filter_rules=filter_rules,
+                                git_commit=git_commit,
+                                output_format=output_format,
+                                verbosity=verbosity)
 
     def test_to_flag_string(self):
         options = self._create_options('vs7', 5, ['+foo', '-bar'], 'git',
@@ -266,8 +243,7 @@ class ArgumentParserTest(unittest.TestCase):
     def _create_defaults(self):
         """Return a DefaultCommandOptionValues instance for testing."""
         base_filter_rules = ["-", "+whitespace"]
-        return DefaultCommandOptionValues(base_filter_rules=base_filter_rules,
-                                          output_format="vs7",
+        return DefaultCommandOptionValues(output_format="vs7",
                                           verbosity=3)
 
     def _create_parser(self):
@@ -336,9 +312,7 @@ class ArgumentParserTest(unittest.TestCase):
 
         self.assertEquals(options.output_format, 'vs7')
         self.assertEquals(options.verbosity, 3)
-        self.assertEquals(options.filter_configuration,
-                          FilterConfiguration(base_rules=["-", "+whitespace"],
-                              path_specific=PATH_RULES_SPECIFIER))
+        self.assertEquals(options.filter_rules, [])
         self.assertEquals(options.git_commit, None)
 
     def test_parse_explicit_arguments(self):
@@ -354,18 +328,13 @@ class ArgumentParserTest(unittest.TestCase):
 
         # Pass user_rules.
         (files, options) = parse(['--filter=+build,-whitespace'])
-        config = options.filter_configuration
-        self.assertEquals(options.filter_configuration,
-                          FilterConfiguration(base_rules=["-", "+whitespace"],
-                              path_specific=PATH_RULES_SPECIFIER,
-                              user_rules=["+build", "-whitespace"]))
+        self.assertEquals(options.filter_rules,
+                          ["+build", "-whitespace"])
 
         # Pass spurious white space in user rules.
         (files, options) = parse(['--filter=+build, -whitespace'])
-        self.assertEquals(options.filter_configuration,
-                          FilterConfiguration(base_rules=["-", "+whitespace"],
-                              path_specific=PATH_RULES_SPECIFIER,
-                              user_rules=["+build", "-whitespace"]))
+        self.assertEquals(options.filter_rules,
+                          ["+build", "-whitespace"])
 
         # Pass extra flag values.
         (files, options) = parse(['--extra'], ['extra'])
@@ -545,30 +514,95 @@ class ProcessorDispatcherDispatchTest(unittest.TestCase):
             self.assert_processor_none(path)
 
 
-class StyleCheckerTest(unittest.TestCase):
+class StyleCheckerConfigurationTest(unittest.TestCase):
 
-    """Test the StyleChecker class.
+    """Tests the StyleCheckerConfiguration class."""
 
-    Attributes:
-      error_messages: A string containing all of the warning messages
-                      written to the mock_stderr_write method of
-                      this 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 StyleCheckerConfiguration instance for testing."""
+        base_rules = ["-whitespace", "+whitespace/tab"]
+        filter_configuration = FilterConfiguration(base_rules=base_rules)
+
+        return StyleCheckerConfiguration(
+                   filter_configuration=filter_configuration,
+                   max_reports_per_category={"whitespace/newline": 1},
+                   output_format=output_format,
+                   stderr_write=self._mock_stderr_write,
+                   verbosity=3)
+
+    def test_init(self):
+        """Test the __init__() method."""
+        configuration = self._style_checker_configuration()
+
+        # Check that __init__ sets the "public" data attributes correctly.
+        self.assertEquals(configuration.max_reports_per_category,
+                          {"whitespace/newline": 1})
+        self.assertEquals(configuration.stderr_write, self._mock_stderr_write)
+        self.assertEquals(configuration.verbosity, 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=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.assertEquals(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.assertEquals(self._error_messages,
+                          ["foo.h(100):  message  [whitespace/tab] [5]\n"])
+
+
+class StyleCheckerTest(unittest.TestCase):
+
+    """Test the StyleChecker class."""
 
     def _mock_stderr_write(self, message):
         pass
 
-    def _style_checker(self, options):
-        return StyleChecker(options, self._mock_stderr_write)
+    def _style_checker(self, configuration):
+        return StyleChecker(configuration)
 
     def test_init(self):
         """Test __init__ constructor."""
-        options = ProcessorOptions()
-        style_checker = self._style_checker(options)
+        configuration = StyleCheckerConfiguration(
+                            filter_configuration=FilterConfiguration(),
+                            max_reports_per_category={},
+                            output_format="vs7",
+                            stderr_write=self._mock_stderr_write,
+                            verbosity=3)
+
+        style_checker = self._style_checker(configuration)
 
+        self.assertEquals(style_checker._configuration, configuration)
         self.assertEquals(style_checker.error_count, 0)
-        self.assertEquals(style_checker.options, options)
         self.assertEquals(style_checker.file_count, 0)
 
 
@@ -636,15 +670,14 @@ class StyleCheckerCheckFileTest(unittest.TestCase):
         # Confirm that the attributes are reset.
         self.assert_attributes(None, None, None, "")
 
-        # Create a test StyleChecker instance.
-        #
-        # The verbosity attribute is the only ProcessorOptions
-        # attribute that needs to be checked in this test.
-        # This is because it is the only option is directly
-        # passed to the constructor of a style processor.
-        options = ProcessorOptions(verbosity=3)
+        configuration = StyleCheckerConfiguration(
+                            filter_configuration=FilterConfiguration(),
+                            max_reports_per_category={"whitespace/newline": 1},
+                            output_format="vs7",
+                            stderr_write=self.mock_stderr_write,
+                            verbosity=3)
 
-        style_checker = StyleChecker(options, self.mock_stderr_write)
+        style_checker = StyleChecker(configuration)
 
         style_checker.check_file(file_path,
                                  self.mock_handle_style_error,
index d87df716277ef2dcf5fd765de6e74c96a68515ea..6bc3f15e7fed0282e4fcbc7e66436b3054548d56 100644 (file)
@@ -56,30 +56,21 @@ class DefaultStyleErrorHandler(object):
 
     """The default style error handler."""
 
-    def __init__(self, file_path, options, increment_error_count,
-                 stderr_write=None):
+    def __init__(self, file_path, configuration, increment_error_count):
         """Create a default style error handler.
 
         Args:
           file_path: The path to the file containing the error. This
                      is used for reporting to the user.
-          options: A ProcessorOptions instance.
+          configuration: A StyleCheckerConfiguration instance.
           increment_error_count: A function that takes no arguments and
                                  increments the total count of reportable
                                  errors.
-          stderr_write: A function that takes a string as a parameter
-                        and that is called when a style error occurs.
-                        Defaults to sys.stderr.write. This should be
-                        used only for unit tests.
 
         """
-        if stderr_write is None:
-            stderr_write = sys.stderr.write
-
         self._file_path = file_path
+        self._configuration = configuration
         self._increment_error_count = increment_error_count
-        self._options = options
-        self._stderr_write = stderr_write
 
         # A string to integer dictionary cache of the number of reportable
         # errors per category passed to this instance.
@@ -99,9 +90,9 @@ class DefaultStyleErrorHandler(object):
 
     def _max_reports(self, category):
         """Return the maximum number of errors to report."""
-        if not category in self._options.max_reports_per_category:
+        if not category in self._configuration.max_reports_per_category:
             return None
-        return self._options.max_reports_per_category[category]
+        return self._configuration.max_reports_per_category[category]
 
     def __call__(self, line_number, category, confidence, message):
         """Handle the occurrence of a style error.
@@ -109,9 +100,9 @@ class DefaultStyleErrorHandler(object):
         See the docstring of this module for more information.
 
         """
-        if not self._options.is_reportable(category,
-                                           confidence,
-                                           self._file_path):
+        if not self._configuration.is_reportable(category=category,
+                                                 confidence_in_error=confidence,
+                                                 file_path=self._file_path):
             return
 
         category_total = self._add_reportable_error(category)
@@ -122,28 +113,22 @@ class DefaultStyleErrorHandler(object):
             # Then suppress displaying the error.
             return
 
-        if self._options.output_format == 'vs7':
-            format_string = "%s(%s):  %s  [%s] [%d]\n"
-        else:
-            format_string = "%s:%s:  %s  [%s] [%d]\n"
+        self._configuration.write_style_error(category=category,
+                                              confidence=confidence,
+                                              file_path=self._file_path,
+                                              line_number=line_number,
+                                              message=message)
 
         if category_total == max_reports:
-            format_string += ("Suppressing further [%s] reports for this "
-                              "file.\n" % category)
-
-        self._stderr_write(format_string % (self._file_path,
-                                            line_number,
-                                            message,
-                                            category,
-                                            confidence))
+            self._configuration.stderr_write("Suppressing further [%s] reports "
+                                             "for this file.\n" % category)
 
 
 class PatchStyleErrorHandler(object):
 
     """The style error function for patch files."""
 
-    def __init__(self, diff, file_path, options, increment_error_count,
-                 stderr_write):
+    def __init__(self, diff, file_path, configuration, increment_error_count):
         """Create a patch style error handler for the given path.
 
         Args:
@@ -155,11 +140,10 @@ class PatchStyleErrorHandler(object):
         self._diff = diff
 
         self._default_error_handler = DefaultStyleErrorHandler(
+                                          configuration=configuration,
                                           file_path=file_path,
                                           increment_error_count=
-                                              increment_error_count,
-                                          options=options,
-                                          stderr_write=stderr_write)
+                                              increment_error_count)
 
         # The line numbers of the modified lines. This is set lazily.
         self._line_numbers = set()
index 43a11fe5bf4be94a491f26404e7456a5d670c01d..a39ba2a5891f7e81d8b0de17cd7cbe3d07b6fcae 100644 (file)
 import unittest
 
 from .. style_references import parse_patch
-from checker import ProcessorOptions
+from checker import StyleCheckerConfiguration
 from error_handlers import DefaultStyleErrorHandler
 from error_handlers import PatchStyleErrorHandler
-
+from filter import FilterConfiguration
 
 class StyleErrorHandlerTestBase(unittest.TestCase):
 
@@ -43,6 +43,18 @@ class StyleErrorHandlerTestBase(unittest.TestCase):
     def _mock_stderr_write(self, message):
         self._error_messages.append(message)
 
+    def _style_checker_configuration(self):
+        """Return a StyleCheckerConfiguration instance for testing."""
+        base_rules = ["-whitespace", "+whitespace/tab"]
+        filter_configuration = FilterConfiguration(base_rules=base_rules)
+
+        return StyleCheckerConfiguration(
+                   filter_configuration=filter_configuration,
+                   max_reports_per_category={"whitespace/tab": 2},
+                   output_format="vs7",
+                   stderr_write=self._mock_stderr_write,
+                   verbosity=3)
+
 
 class DefaultStyleErrorHandlerTest(StyleErrorHandlerTestBase):
 
@@ -59,12 +71,10 @@ class DefaultStyleErrorHandlerTest(StyleErrorHandlerTestBase):
         self.assertEquals(0, self._error_count)
         self.assertEquals(0, len(self._error_messages))
 
-    def _error_handler(self, options):
-        return DefaultStyleErrorHandler(file_path=self._file_path,
-                                        increment_error_count=
-                                            self._mock_increment_error_count,
-                                        options=options,
-                                        stderr_write=self._mock_stderr_write)
+    def _error_handler(self, configuration):
+        return DefaultStyleErrorHandler(configuration=configuration,
+                   file_path=self._file_path,
+                   increment_error_count=self._mock_increment_error_count)
 
     def _call_error_handler(self, handle_error, confidence):
         """Call the given error handler with a test error."""
@@ -73,78 +83,54 @@ class DefaultStyleErrorHandlerTest(StyleErrorHandlerTestBase):
                      confidence=confidence,
                      message="message")
 
-    def test_call_non_reportable(self):
-        """Test __call__() method with a non-reportable error."""
-        confidence = 1
-        options = ProcessorOptions(verbosity=3)
+    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(options.is_reportable(self._category,
-                                               confidence,
-                                               self._file_path))
-
-        error_handler = self._error_handler(options)
+        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.assertEquals(0, self._error_count)
         self.assertEquals([], self._error_messages)
 
-    def test_call_reportable_emacs(self):
-        """Test __call__() method with a reportable error and emacs format."""
-        confidence = 5
-        options = ProcessorOptions(verbosity=3, output_format="emacs")
-        self._check_initialized()
-
-        error_handler = self._error_handler(options)
-        self._call_error_handler(error_handler, confidence)
-
-        self.assertEquals(1, self._error_count)
-        self.assertEquals(self._error_messages[-1],
-                          "foo.h:100:  message  [whitespace/tab] [5]\n")
-
-    def test_call_reportable_vs7(self):
-        """Test __call__() method with a reportable error and vs7 format."""
-        confidence = 5
-        options = ProcessorOptions(verbosity=3, output_format="vs7")
+    # 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)
 
-        error_handler = self._error_handler(options)
-        self._call_error_handler(error_handler, confidence)
-
-        self.assertEquals(1, self._error_count)
-        self.assertEquals(self._error_messages[-1],
-                          "foo.h(100):  message  [whitespace/tab] [5]\n")
-
-    def test_call_max_reports_per_category(self):
-        """Test error report suppression in __call__() method."""
         confidence = 5
-        options = ProcessorOptions(verbosity=3,
-                                   max_reports_per_category={self._category: 2})
-        error_handler = self._error_handler(options)
-
-        self._check_initialized()
 
         # First call: usual reporting.
         self._call_error_handler(error_handler, confidence)
         self.assertEquals(1, self._error_count)
         self.assertEquals(1, len(self._error_messages))
-        self.assertEquals(self._error_messages[-1],
-                          "foo.h:100:  message  [whitespace/tab] [5]\n")
+        self.assertEquals(self._error_messages,
+                          ["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.assertEquals(2, self._error_count)
-        self.assertEquals(2, len(self._error_messages))
+        self.assertEquals(3, len(self._error_messages))
+        self.assertEquals(self._error_messages[-2],
+                          "foo.h(100):  message  [whitespace/tab] [5]\n")
         self.assertEquals(self._error_messages[-1],
-                          "foo.h:100:  message  [whitespace/tab] [5]\n"
-                          "Suppressing further [%s] reports for this file.\n"
-                          % self._category)
+                          "Suppressing further [whitespace/tab] reports "
+                          "for this file.\n")
 
         # Third call: no report.
         self._call_error_handler(error_handler, confidence)
         self.assertEquals(3, self._error_count)
-        self.assertEquals(2, len(self._error_messages))
+        self.assertEquals(3, len(self._error_messages))
 
 
 class PatchStyleErrorHandlerTest(StyleErrorHandlerTestBase):
@@ -167,22 +153,22 @@ index ef65bee..e3db70e 100644
         patch_files = parse_patch(self._patch_string)
         diff = patch_files[self._file_path]
 
-        options = ProcessorOptions(verbosity=3)
+        configuration = self._style_checker_configuration()
 
-        handle_error = PatchStyleErrorHandler(diff,
-                                              self._file_path,
-                                              options,
-                                              self._mock_increment_error_count,
-                                              self._mock_stderr_write)
+        handle_error = PatchStyleErrorHandler(diff=diff,
+                                              file_path=self._file_path,
+                                              configuration=configuration,
+                                              increment_error_count=
+                                              self._mock_increment_error_count)
 
         category = "whitespace/tab"
         confidence = 5
         message = "message"
 
         # Confirm error is reportable.
-        self.assertTrue(options.is_reportable(category,
-                                              confidence,
-                                              self._file_path))
+        self.assertTrue(configuration.is_reportable(category,
+                                                    confidence,
+                                                    self._file_path))
 
         # Confirm error count initialized to zero.
         self.assertEquals(0, self._error_count)
index 2bd1ad750397ef0c110709a79672fec683d3fe0c..608a9e60c4f2bf6bd060a238dc2bb4adad3bbd22 100644 (file)
@@ -161,11 +161,7 @@ class FilterConfiguration(object):
         self._path_specific_lower = None
         """The backing store for self._get_path_specific_lower()."""
 
-        # FIXME: Make user rules internal after the FilterConfiguration
-        #        attribute is removed from ProcessorOptions (since at
-        #        that point ArgumentPrinter will no longer need to
-        #        access FilterConfiguration.user_rules).
-        self.user_rules = user_rules
+        self._user_rules = user_rules
 
         self._path_rules_to_filter = {}
         """Cached dictionary of path rules to CategoryFilter instance."""
@@ -184,7 +180,7 @@ class FilterConfiguration(object):
             return False
         if self._path_specific != other._path_specific:
             return False
-        if self.user_rules != other.user_rules:
+        if self._user_rules != other._user_rules:
             return False
 
         return True
@@ -233,7 +229,7 @@ class FilterConfiguration(object):
         if path_rules not in self._path_rules_to_filter:
             rules = list(self._base_rules) # Make a copy
             rules.extend(path_rules)
-            rules.extend(self.user_rules)
+            rules.extend(self._user_rules)
             self._path_rules_to_filter[path_rules] = _CategoryFilter(rules)
 
         return self._path_rules_to_filter[path_rules]
index 76f25db447052e26182db08f314e9285ed1aba3f..7b8a5402a8b23df79b211aaf9853261f7c818110 100644 (file)
@@ -164,7 +164,7 @@ class FilterConfigurationTest(unittest.TestCase):
 
         self.assertEquals(base_rules, config._base_rules)
         self.assertEquals(path_specific, config._path_specific)
-        self.assertEquals(user_rules, config.user_rules)
+        self.assertEquals(user_rules, config._user_rules)
 
     def test_default_arguments(self):
         # Test that the attributes are getting set correctly to the defaults.
@@ -172,7 +172,7 @@ class FilterConfigurationTest(unittest.TestCase):
 
         self.assertEquals([], config._base_rules)
         self.assertEquals([], config._path_specific)
-        self.assertEquals([], config.user_rules)
+        self.assertEquals([], config._user_rules)
 
     def test_eq(self):
         """Test __eq__ method."""