| # 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 parser.py.""" |
| |
| import unittest |
| |
| from webkitpy.common.system.logtesting import LoggingTestCase |
| from webkitpy.style.optparser import ArgumentParser |
| from webkitpy.style.optparser import ArgumentPrinter |
| from webkitpy.style.optparser import CommandOptionValues as ProcessorOptions |
| from webkitpy.style.optparser import DefaultCommandOptionValues |
| |
| |
| class ArgumentPrinterTest(unittest.TestCase): |
| |
| """Tests the ArgumentPrinter class.""" |
| |
| _printer = ArgumentPrinter() |
| |
| def _create_options(self, |
| output_format='emacs', |
| min_confidence=3, |
| filter_rules=[], |
| git_commit=None): |
| return ProcessorOptions(filter_rules=filter_rules, |
| git_commit=git_commit, |
| min_confidence=min_confidence, |
| output_format=output_format) |
| |
| def test_to_flag_string(self): |
| options = self._create_options('vs7', 5, ['+foo', '-bar'], 'git') |
| self.assertEqual('--filter=+foo,-bar --git-commit=git ' |
| '--min-confidence=5 --output=vs7', |
| self._printer.to_flag_string(options)) |
| |
| # This is to check that --filter and --git-commit do not |
| # show up when not user-specified. |
| options = self._create_options() |
| self.assertEqual('--min-confidence=3 --output=emacs', |
| self._printer.to_flag_string(options)) |
| |
| |
| class ArgumentParserTest(LoggingTestCase): |
| |
| """Test the ArgumentParser class.""" |
| |
| class _MockStdErr(object): |
| |
| def write(self, message): |
| # We do not want the usage string or style categories |
| # to print during unit tests, so print nothing. |
| return |
| |
| def _parse(self, args): |
| """Call a test parser.parse().""" |
| parser = self._create_parser() |
| return parser.parse(args) |
| |
| def _create_defaults(self): |
| """Return a DefaultCommandOptionValues instance for testing.""" |
| base_filter_rules = ["-", "+whitespace"] |
| return DefaultCommandOptionValues(min_confidence=3, |
| output_format="vs7") |
| |
| def _create_parser(self): |
| """Return an ArgumentParser instance for testing.""" |
| default_options = self._create_defaults() |
| |
| all_categories = ["build", "whitespace"] |
| |
| mock_stderr = self._MockStdErr() |
| |
| return ArgumentParser(all_categories=all_categories, |
| base_filter_rules=[], |
| default_options=default_options, |
| mock_stderr=mock_stderr, |
| usage="test usage") |
| |
| def test_parse_documentation(self): |
| parse = self._parse |
| |
| # FIXME: Test both the printing of the usage string and the |
| # filter categories help. |
| |
| # Request the usage string. |
| self.assertRaises(SystemExit, parse, ['--help']) |
| # Request default filter rules and available style categories. |
| self.assertRaises(SystemExit, parse, ['--filter=']) |
| |
| def test_parse_bad_values(self): |
| parse = self._parse |
| |
| # Pass an unsupported argument. |
| self.assertRaises(SystemExit, parse, ['--bad']) |
| self.assertLog(['ERROR: no such option: --bad\n']) |
| |
| self.assertRaises(SystemExit, parse, ['--min-confidence=bad']) |
| self.assertLog(['ERROR: option --min-confidence: ' |
| "invalid integer value: 'bad'\n"]) |
| self.assertRaises(SystemExit, parse, ['--min-confidence=0']) |
| self.assertLog(['ERROR: option --min-confidence: invalid integer: 0: ' |
| 'value must be between 1 and 5\n']) |
| self.assertRaises(SystemExit, parse, ['--min-confidence=6']) |
| self.assertLog(['ERROR: option --min-confidence: invalid integer: 6: ' |
| 'value must be between 1 and 5\n']) |
| parse(['--min-confidence=1']) # works |
| parse(['--min-confidence=5']) # works |
| |
| self.assertRaises(SystemExit, parse, ['--output=bad']) |
| self.assertLog(['ERROR: option --output-format: invalid choice: ' |
| "'bad' (choose from 'emacs', 'vs7')\n"]) |
| parse(['--output=vs7']) # works |
| |
| # Pass a filter rule not beginning with + or -. |
| self.assertRaises(SystemExit, parse, ['--filter=build']) |
| self.assertLog(['ERROR: Invalid filter rule "build": ' |
| 'every rule must start with + or -.\n']) |
| parse(['--filter=+build']) # works |
| |
| def test_parse_default_arguments(self): |
| parse = self._parse |
| |
| (files, options) = parse([]) |
| |
| self.assertEqual(files, []) |
| |
| self.assertEqual(options.filter_rules, []) |
| self.assertIsNone(options.git_commit) |
| self.assertFalse(options.diff_files) |
| self.assertFalse(options.is_verbose) |
| self.assertEqual(options.min_confidence, 3) |
| self.assertEqual(options.output_format, 'vs7') |
| |
| def test_parse_explicit_arguments(self): |
| parse = self._parse |
| |
| # Pass non-default explicit values. |
| (files, options) = parse(['--min-confidence=4']) |
| self.assertEqual(options.min_confidence, 4) |
| (files, options) = parse(['--output=emacs']) |
| self.assertEqual(options.output_format, 'emacs') |
| (files, options) = parse(['-g', 'commit']) |
| self.assertEqual(options.git_commit, 'commit') |
| (files, options) = parse(['--git-commit=commit']) |
| self.assertEqual(options.git_commit, 'commit') |
| (files, options) = parse(['--git-diff=commit']) |
| self.assertEqual(options.git_commit, 'commit') |
| (files, options) = parse(['--verbose']) |
| self.assertTrue(options.is_verbose) |
| (files, options) = parse(['--diff-files', 'file.txt']) |
| self.assertTrue(options.diff_files) |
| |
| # Pass user_rules. |
| (files, options) = parse(['--filter=+build,-whitespace']) |
| self.assertEqual(options.filter_rules, |
| ["+build", "-whitespace"]) |
| |
| # Pass spurious white space in user rules. |
| (files, options) = parse(['--filter=+build, -whitespace']) |
| self.assertEqual(options.filter_rules, |
| ["+build", "-whitespace"]) |
| |
| def test_parse_files(self): |
| parse = self._parse |
| |
| (files, options) = parse(['foo.cpp']) |
| self.assertEqual(files, ['foo.cpp']) |
| |
| # Pass multiple files. |
| (files, options) = parse(['--output=emacs', 'foo.cpp', 'bar.cpp']) |
| self.assertEqual(files, ['foo.cpp', 'bar.cpp']) |
| |
| |
| class CommandOptionValuesTest(unittest.TestCase): |
| |
| """Tests CommandOptionValues class.""" |
| |
| def test_init(self): |
| """Test __init__ constructor.""" |
| # Check default parameters. |
| options = ProcessorOptions() |
| self.assertEqual(options.filter_rules, []) |
| self.assertIsNone(options.git_commit) |
| self.assertFalse(options.is_verbose) |
| self.assertEqual(options.min_confidence, 1) |
| self.assertEqual(options.output_format, "emacs") |
| self.assertFalse(options.git_index) |
| |
| # Check argument validation. |
| self.assertRaises(ValueError, ProcessorOptions, output_format="bad") |
| ProcessorOptions(output_format="emacs") # No ValueError: works |
| ProcessorOptions(output_format="vs7") # works |
| self.assertRaises(ValueError, ProcessorOptions, min_confidence=0) |
| self.assertRaises(ValueError, ProcessorOptions, min_confidence=6) |
| ProcessorOptions(min_confidence=1) # works |
| ProcessorOptions(min_confidence=5) # works |
| |
| # Check attributes. |
| options = ProcessorOptions(filter_rules=["+"], |
| git_commit="commit", |
| is_verbose=True, |
| min_confidence=3, |
| output_format="vs7", |
| git_index=True) |
| self.assertEqual(options.filter_rules, ["+"]) |
| self.assertEqual(options.git_commit, "commit") |
| self.assertTrue(options.is_verbose) |
| self.assertEqual(options.min_confidence, 3) |
| self.assertEqual(options.output_format, "vs7") |
| self.assertTrue(options.git_index) |
| |
| def test_eq(self): |
| """Test __eq__ equality function.""" |
| self.assertTrue(ProcessorOptions().__eq__(ProcessorOptions())) |
| |
| # Also verify that a difference in any argument causes equality to fail. |
| |
| # Explicitly create a ProcessorOptions instance with all default |
| # values. We do this to be sure we are assuming the right default |
| # values in our self.assertFalse() calls below. |
| options = ProcessorOptions(filter_rules=[], |
| git_commit=None, |
| is_verbose=False, |
| min_confidence=1, |
| output_format="emacs", |
| git_index=False) |
| # Verify that we created options correctly. |
| self.assertTrue(options.__eq__(ProcessorOptions())) |
| |
| self.assertFalse(options.__eq__(ProcessorOptions(filter_rules=["+"]))) |
| self.assertFalse(options.__eq__(ProcessorOptions(git_commit="commit"))) |
| self.assertFalse(options.__eq__(ProcessorOptions(is_verbose=True))) |
| self.assertFalse(options.__eq__(ProcessorOptions(min_confidence=2))) |
| self.assertFalse(options.__eq__(ProcessorOptions(output_format="vs7"))) |
| self.assertFalse(options.__eq__(ProcessorOptions(git_index=True))) |
| |
| def test_ne(self): |
| """Test __ne__ inequality function.""" |
| # By default, __ne__ always returns true on different objects. |
| # Thus, just check the distinguishing case to verify that the |
| # code defines __ne__. |
| self.assertFalse(ProcessorOptions().__ne__(ProcessorOptions())) |