initial import
[vuplus_webkit] / Tools / Scripts / webkitpy / style / optparser_unittest.py
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
140     def test_parse_default_arguments(self):
141         parse = self._parse
142
143         (files, options) = parse([])
144
145         self.assertEquals(files, [])
146
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')
153
154     def test_parse_explicit_arguments(self):
155         parse = self._parse
156
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)
172
173         # Pass user_rules.
174         (files, options) = parse(['--filter=+build,-whitespace'])
175         self.assertEquals(options.filter_rules,
176                           ["+build", "-whitespace"])
177
178         # Pass spurious white space in user rules.
179         (files, options) = parse(['--filter=+build, -whitespace'])
180         self.assertEquals(options.filter_rules,
181                           ["+build", "-whitespace"])
182
183     def test_parse_files(self):
184         parse = self._parse
185
186         (files, options) = parse(['foo.cpp'])
187         self.assertEquals(files, ['foo.cpp'])
188
189         # Pass multiple files.
190         (files, options) = parse(['--output=emacs', 'foo.cpp', 'bar.cpp'])
191         self.assertEquals(files, ['foo.cpp', 'bar.cpp'])
192
193
194 class CommandOptionValuesTest(unittest.TestCase):
195
196     """Tests CommandOptionValues class."""
197
198     def test_init(self):
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")
207
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
216
217         # Check attributes.
218         options = ProcessorOptions(filter_rules=["+"],
219                                    git_commit="commit",
220                                    is_verbose=True,
221                                    min_confidence=3,
222                                    output_format="vs7")
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")
228
229     def test_eq(self):
230         """Test __eq__ equality function."""
231         self.assertTrue(ProcessorOptions().__eq__(ProcessorOptions()))
232
233         # Also verify that a difference in any argument causes equality to fail.
234
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=[],
239                                    git_commit=None,
240                                    is_verbose=False,
241                                    min_confidence=1,
242                                    output_format="emacs")
243         # Verify that we created options correctly.
244         self.assertTrue(options.__eq__(ProcessorOptions()))
245
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")))
251
252     def test_ne(self):
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()))
258