WebKitTools/Scripts/webkitpy/style/optparser_unittest.py
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
       
     2 #
       
     3 # Redistribution and use in source and binary forms, with or without
       
     4 # modification, are permitted provided that the following conditions
       
     5 # are met:
       
     6 # 1.  Redistributions of source code must retain the above copyright
       
     7 #     notice, this list of conditions and the following disclaimer.
       
     8 # 2.  Redistributions in binary form must reproduce the above copyright
       
     9 #     notice, this list of conditions and the following disclaimer in the
       
    10 #     documentation and/or other materials provided with the distribution.
       
    11 #
       
    12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
       
    13 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    14 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    15 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
       
    16 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
       
    17 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    18 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
       
    19 # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    20 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
       
    21 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    22 
       
    23 """Unit tests for parser.py."""
       
    24 
       
    25 import unittest
       
    26 
       
    27 from webkitpy.common.system.logtesting import LoggingTestCase
       
    28 from webkitpy.style.optparser import ArgumentParser
       
    29 from webkitpy.style.optparser import ArgumentPrinter
       
    30 from webkitpy.style.optparser import CommandOptionValues as ProcessorOptions
       
    31 from webkitpy.style.optparser import DefaultCommandOptionValues
       
    32 
       
    33 
       
    34 class ArgumentPrinterTest(unittest.TestCase):
       
    35 
       
    36     """Tests the ArgumentPrinter class."""
       
    37 
       
    38     _printer = ArgumentPrinter()
       
    39 
       
    40     def _create_options(self,
       
    41                         output_format='emacs',
       
    42                         min_confidence=3,
       
    43                         filter_rules=[],
       
    44                         git_commit=None):
       
    45         return ProcessorOptions(filter_rules=filter_rules,
       
    46                                 git_commit=git_commit,
       
    47                                 min_confidence=min_confidence,
       
    48                                 output_format=output_format)
       
    49 
       
    50     def test_to_flag_string(self):
       
    51         options = self._create_options('vs7', 5, ['+foo', '-bar'], 'git')
       
    52         self.assertEquals('--filter=+foo,-bar --git-commit=git '
       
    53                           '--min-confidence=5 --output=vs7',
       
    54                           self._printer.to_flag_string(options))
       
    55 
       
    56         # This is to check that --filter and --git-commit do not
       
    57         # show up when not user-specified.
       
    58         options = self._create_options()
       
    59         self.assertEquals('--min-confidence=3 --output=emacs',
       
    60                           self._printer.to_flag_string(options))
       
    61 
       
    62 
       
    63 class ArgumentParserTest(LoggingTestCase):
       
    64 
       
    65     """Test the ArgumentParser class."""
       
    66 
       
    67     class _MockStdErr(object):
       
    68 
       
    69         def write(self, message):
       
    70             # We do not want the usage string or style categories
       
    71             # to print during unit tests, so print nothing.
       
    72             return
       
    73 
       
    74     def _parse(self, args):
       
    75         """Call a test parser.parse()."""
       
    76         parser = self._create_parser()
       
    77         return parser.parse(args)
       
    78 
       
    79     def _create_defaults(self):
       
    80         """Return a DefaultCommandOptionValues instance for testing."""
       
    81         base_filter_rules = ["-", "+whitespace"]
       
    82         return DefaultCommandOptionValues(min_confidence=3,
       
    83                                           output_format="vs7")
       
    84 
       
    85     def _create_parser(self):
       
    86         """Return an ArgumentParser instance for testing."""
       
    87         default_options = self._create_defaults()
       
    88 
       
    89         all_categories = ["build" ,"whitespace"]
       
    90 
       
    91         mock_stderr = self._MockStdErr()
       
    92 
       
    93         return ArgumentParser(all_categories=all_categories,
       
    94                               base_filter_rules=[],
       
    95                               default_options=default_options,
       
    96                               mock_stderr=mock_stderr,
       
    97                               usage="test usage")
       
    98 
       
    99     def test_parse_documentation(self):
       
   100         parse = self._parse
       
   101 
       
   102         # FIXME: Test both the printing of the usage string and the
       
   103         #        filter categories help.
       
   104 
       
   105         # Request the usage string.
       
   106         self.assertRaises(SystemExit, parse, ['--help'])
       
   107         # Request default filter rules and available style categories.
       
   108         self.assertRaises(SystemExit, parse, ['--filter='])
       
   109 
       
   110     def test_parse_bad_values(self):
       
   111         parse = self._parse
       
   112 
       
   113         # Pass an unsupported argument.
       
   114         self.assertRaises(SystemExit, parse, ['--bad'])
       
   115         self.assertLog(['ERROR: no such option: --bad\n'])
       
   116 
       
   117         self.assertRaises(SystemExit, parse, ['--min-confidence=bad'])
       
   118         self.assertLog(['ERROR: option --min-confidence: '
       
   119                         "invalid integer value: 'bad'\n"])
       
   120         self.assertRaises(SystemExit, parse, ['--min-confidence=0'])
       
   121         self.assertLog(['ERROR: option --min-confidence: invalid integer: 0: '
       
   122                         'value must be between 1 and 5\n'])
       
   123         self.assertRaises(SystemExit, parse, ['--min-confidence=6'])
       
   124         self.assertLog(['ERROR: option --min-confidence: invalid integer: 6: '
       
   125                         'value must be between 1 and 5\n'])
       
   126         parse(['--min-confidence=1']) # works
       
   127         parse(['--min-confidence=5']) # works
       
   128 
       
   129         self.assertRaises(SystemExit, parse, ['--output=bad'])
       
   130         self.assertLog(['ERROR: option --output-format: invalid choice: '
       
   131                         "'bad' (choose from 'emacs', 'vs7')\n"])
       
   132         parse(['--output=vs7']) # works
       
   133 
       
   134         # Pass a filter rule not beginning with + or -.
       
   135         self.assertRaises(SystemExit, parse, ['--filter=build'])
       
   136         self.assertLog(['ERROR: Invalid filter rule "build": '
       
   137                         'every rule must start with + or -.\n'])
       
   138         parse(['--filter=+build']) # works
       
   139         # Pass files and git-commit at the same time.
       
   140         self.assertRaises(SystemExit, parse, ['--git-commit=committish',
       
   141                                               'file.txt'])
       
   142         self.assertLog(['ERROR: You cannot provide both paths and '
       
   143                         'a git commit at the same time.\n'])
       
   144 
       
   145     def test_parse_default_arguments(self):
       
   146         parse = self._parse
       
   147 
       
   148         (files, options) = parse([])
       
   149 
       
   150         self.assertEquals(files, [])
       
   151 
       
   152         self.assertEquals(options.filter_rules, [])
       
   153         self.assertEquals(options.git_commit, None)
       
   154         self.assertEquals(options.is_verbose, False)
       
   155         self.assertEquals(options.min_confidence, 3)
       
   156         self.assertEquals(options.output_format, 'vs7')
       
   157 
       
   158     def test_parse_explicit_arguments(self):
       
   159         parse = self._parse
       
   160 
       
   161         # Pass non-default explicit values.
       
   162         (files, options) = parse(['--min-confidence=4'])
       
   163         self.assertEquals(options.min_confidence, 4)
       
   164         (files, options) = parse(['--output=emacs'])
       
   165         self.assertEquals(options.output_format, 'emacs')
       
   166         (files, options) = parse(['-g', 'commit'])
       
   167         self.assertEquals(options.git_commit, 'commit')
       
   168         (files, options) = parse(['--git-commit=commit'])
       
   169         self.assertEquals(options.git_commit, 'commit')
       
   170         (files, options) = parse(['--git-diff=commit'])
       
   171         self.assertEquals(options.git_commit, 'commit')
       
   172         (files, options) = parse(['--verbose'])
       
   173         self.assertEquals(options.is_verbose, True)
       
   174 
       
   175         # Pass user_rules.
       
   176         (files, options) = parse(['--filter=+build,-whitespace'])
       
   177         self.assertEquals(options.filter_rules,
       
   178                           ["+build", "-whitespace"])
       
   179 
       
   180         # Pass spurious white space in user rules.
       
   181         (files, options) = parse(['--filter=+build, -whitespace'])
       
   182         self.assertEquals(options.filter_rules,
       
   183                           ["+build", "-whitespace"])
       
   184 
       
   185     def test_parse_files(self):
       
   186         parse = self._parse
       
   187 
       
   188         (files, options) = parse(['foo.cpp'])
       
   189         self.assertEquals(files, ['foo.cpp'])
       
   190 
       
   191         # Pass multiple files.
       
   192         (files, options) = parse(['--output=emacs', 'foo.cpp', 'bar.cpp'])
       
   193         self.assertEquals(files, ['foo.cpp', 'bar.cpp'])
       
   194 
       
   195 
       
   196 class CommandOptionValuesTest(unittest.TestCase):
       
   197 
       
   198     """Tests CommandOptionValues class."""
       
   199 
       
   200     def test_init(self):
       
   201         """Test __init__ constructor."""
       
   202         # Check default parameters.
       
   203         options = ProcessorOptions()
       
   204         self.assertEquals(options.filter_rules, [])
       
   205         self.assertEquals(options.git_commit, None)
       
   206         self.assertEquals(options.is_verbose, False)
       
   207         self.assertEquals(options.min_confidence, 1)
       
   208         self.assertEquals(options.output_format, "emacs")
       
   209 
       
   210         # Check argument validation.
       
   211         self.assertRaises(ValueError, ProcessorOptions, output_format="bad")
       
   212         ProcessorOptions(output_format="emacs") # No ValueError: works
       
   213         ProcessorOptions(output_format="vs7") # works
       
   214         self.assertRaises(ValueError, ProcessorOptions, min_confidence=0)
       
   215         self.assertRaises(ValueError, ProcessorOptions, min_confidence=6)
       
   216         ProcessorOptions(min_confidence=1) # works
       
   217         ProcessorOptions(min_confidence=5) # works
       
   218 
       
   219         # Check attributes.
       
   220         options = ProcessorOptions(filter_rules=["+"],
       
   221                                    git_commit="commit",
       
   222                                    is_verbose=True,
       
   223                                    min_confidence=3,
       
   224                                    output_format="vs7")
       
   225         self.assertEquals(options.filter_rules, ["+"])
       
   226         self.assertEquals(options.git_commit, "commit")
       
   227         self.assertEquals(options.is_verbose, True)
       
   228         self.assertEquals(options.min_confidence, 3)
       
   229         self.assertEquals(options.output_format, "vs7")
       
   230 
       
   231     def test_eq(self):
       
   232         """Test __eq__ equality function."""
       
   233         self.assertTrue(ProcessorOptions().__eq__(ProcessorOptions()))
       
   234 
       
   235         # Also verify that a difference in any argument causes equality to fail.
       
   236 
       
   237         # Explicitly create a ProcessorOptions instance with all default
       
   238         # values.  We do this to be sure we are assuming the right default
       
   239         # values in our self.assertFalse() calls below.
       
   240         options = ProcessorOptions(filter_rules=[],
       
   241                                    git_commit=None,
       
   242                                    is_verbose=False,
       
   243                                    min_confidence=1,
       
   244                                    output_format="emacs")
       
   245         # Verify that we created options correctly.
       
   246         self.assertTrue(options.__eq__(ProcessorOptions()))
       
   247 
       
   248         self.assertFalse(options.__eq__(ProcessorOptions(filter_rules=["+"])))
       
   249         self.assertFalse(options.__eq__(ProcessorOptions(git_commit="commit")))
       
   250         self.assertFalse(options.__eq__(ProcessorOptions(is_verbose=True)))
       
   251         self.assertFalse(options.__eq__(ProcessorOptions(min_confidence=2)))
       
   252         self.assertFalse(options.__eq__(ProcessorOptions(output_format="vs7")))
       
   253 
       
   254     def test_ne(self):
       
   255         """Test __ne__ inequality function."""
       
   256         # By default, __ne__ always returns true on different objects.
       
   257         # Thus, just check the distinguishing case to verify that the
       
   258         # code defines __ne__.
       
   259         self.assertFalse(ProcessorOptions().__ne__(ProcessorOptions()))
       
   260