1 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
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.
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.
23 """Unit tests for parser.py."""
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
34 class ArgumentPrinterTest(unittest.TestCase):
36 """Tests the ArgumentPrinter class."""
38 _printer = ArgumentPrinter()
40 def _create_options(self,
41 output_format='emacs',
45 return ProcessorOptions(filter_rules=filter_rules,
46 git_commit=git_commit,
47 min_confidence=min_confidence,
48 output_format=output_format)
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))
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))
63 class ArgumentParserTest(LoggingTestCase):
65 """Test the ArgumentParser class."""
67 class _MockStdErr(object):
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.
74 def _parse(self, args):
75 """Call a test parser.parse()."""
76 parser = self._create_parser()
77 return parser.parse(args)
79 def _create_defaults(self):
80 """Return a DefaultCommandOptionValues instance for testing."""
81 base_filter_rules = ["-", "+whitespace"]
82 return DefaultCommandOptionValues(min_confidence=3,
85 def _create_parser(self):
86 """Return an ArgumentParser instance for testing."""
87 default_options = self._create_defaults()
89 all_categories = ["build" ,"whitespace"]
91 mock_stderr = self._MockStdErr()
93 return ArgumentParser(all_categories=all_categories,
95 default_options=default_options,
96 mock_stderr=mock_stderr,
99 def test_parse_documentation(self):
102 # FIXME: Test both the printing of the usage string and the
103 # filter categories help.
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='])
110 def test_parse_bad_values(self):
113 # Pass an unsupported argument.
114 self.assertRaises(SystemExit, parse, ['--bad'])
115 self.assertLog(['ERROR: no such option: --bad\n'])
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
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
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
140 def test_parse_default_arguments(self):
143 (files, options) = parse([])
145 self.assertEquals(files, [])
147 self.assertEquals(options.filter_rules, [])
148 self.assertEquals(options.git_commit, None)
149 self.assertEquals(options.diff_files, False)
150 self.assertEquals(options.is_verbose, False)
151 self.assertEquals(options.min_confidence, 3)
152 self.assertEquals(options.output_format, 'vs7')
154 def test_parse_explicit_arguments(self):
157 # Pass non-default explicit values.
158 (files, options) = parse(['--min-confidence=4'])
159 self.assertEquals(options.min_confidence, 4)
160 (files, options) = parse(['--output=emacs'])
161 self.assertEquals(options.output_format, 'emacs')
162 (files, options) = parse(['-g', 'commit'])
163 self.assertEquals(options.git_commit, 'commit')
164 (files, options) = parse(['--git-commit=commit'])
165 self.assertEquals(options.git_commit, 'commit')
166 (files, options) = parse(['--git-diff=commit'])
167 self.assertEquals(options.git_commit, 'commit')
168 (files, options) = parse(['--verbose'])
169 self.assertEquals(options.is_verbose, True)
170 (files, options) = parse(['--diff-files', 'file.txt'])
171 self.assertEquals(options.diff_files, True)
174 (files, options) = parse(['--filter=+build,-whitespace'])
175 self.assertEquals(options.filter_rules,
176 ["+build", "-whitespace"])
178 # Pass spurious white space in user rules.
179 (files, options) = parse(['--filter=+build, -whitespace'])
180 self.assertEquals(options.filter_rules,
181 ["+build", "-whitespace"])
183 def test_parse_files(self):
186 (files, options) = parse(['foo.cpp'])
187 self.assertEquals(files, ['foo.cpp'])
189 # Pass multiple files.
190 (files, options) = parse(['--output=emacs', 'foo.cpp', 'bar.cpp'])
191 self.assertEquals(files, ['foo.cpp', 'bar.cpp'])
194 class CommandOptionValuesTest(unittest.TestCase):
196 """Tests CommandOptionValues class."""
199 """Test __init__ constructor."""
200 # Check default parameters.
201 options = ProcessorOptions()
202 self.assertEquals(options.filter_rules, [])
203 self.assertEquals(options.git_commit, None)
204 self.assertEquals(options.is_verbose, False)
205 self.assertEquals(options.min_confidence, 1)
206 self.assertEquals(options.output_format, "emacs")
208 # Check argument validation.
209 self.assertRaises(ValueError, ProcessorOptions, output_format="bad")
210 ProcessorOptions(output_format="emacs") # No ValueError: works
211 ProcessorOptions(output_format="vs7") # works
212 self.assertRaises(ValueError, ProcessorOptions, min_confidence=0)
213 self.assertRaises(ValueError, ProcessorOptions, min_confidence=6)
214 ProcessorOptions(min_confidence=1) # works
215 ProcessorOptions(min_confidence=5) # works
218 options = ProcessorOptions(filter_rules=["+"],
223 self.assertEquals(options.filter_rules, ["+"])
224 self.assertEquals(options.git_commit, "commit")
225 self.assertEquals(options.is_verbose, True)
226 self.assertEquals(options.min_confidence, 3)
227 self.assertEquals(options.output_format, "vs7")
230 """Test __eq__ equality function."""
231 self.assertTrue(ProcessorOptions().__eq__(ProcessorOptions()))
233 # Also verify that a difference in any argument causes equality to fail.
235 # Explicitly create a ProcessorOptions instance with all default
236 # values. We do this to be sure we are assuming the right default
237 # values in our self.assertFalse() calls below.
238 options = ProcessorOptions(filter_rules=[],
242 output_format="emacs")
243 # Verify that we created options correctly.
244 self.assertTrue(options.__eq__(ProcessorOptions()))
246 self.assertFalse(options.__eq__(ProcessorOptions(filter_rules=["+"])))
247 self.assertFalse(options.__eq__(ProcessorOptions(git_commit="commit")))
248 self.assertFalse(options.__eq__(ProcessorOptions(is_verbose=True)))
249 self.assertFalse(options.__eq__(ProcessorOptions(min_confidence=2)))
250 self.assertFalse(options.__eq__(ProcessorOptions(output_format="vs7")))
253 """Test __ne__ inequality function."""
254 # By default, __ne__ always returns true on different objects.
255 # Thus, just check the distinguishing case to verify that the
256 # code defines __ne__.
257 self.assertFalse(ProcessorOptions().__ne__(ProcessorOptions()))