Sam Clegg | 08c4535 | 2015-04-06 11:02:51 -0700 | [diff] [blame] | 1 | # -*- coding: utf-8 -*- |
Bill Wendling | 92290f1 | 2018-01-14 16:49:35 -0800 | [diff] [blame] | 2 | # Copyright 2015 Google Inc. All Rights Reserved. |
Sam Clegg | 08c4535 | 2015-04-06 11:02:51 -0700 | [diff] [blame] | 3 | # |
| 4 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | # you may not use this file except in compliance with the License. |
| 6 | # You may obtain a copy of the License at |
| 7 | # |
| 8 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | # |
| 10 | # Unless required by applicable law or agreed to in writing, software |
| 11 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | # See the License for the specific language governing permissions and |
| 14 | # limitations under the License. |
| 15 | """Tests for yapf.__init__.main.""" |
| 16 | |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 17 | from contextlib import contextmanager |
| 18 | import sys |
Sam Clegg | 08c4535 | 2015-04-06 11:02:51 -0700 | [diff] [blame] | 19 | import unittest |
| 20 | import yapf |
| 21 | |
Bill Wendling | cec6b19 | 2016-10-16 00:30:02 -0500 | [diff] [blame] | 22 | from yapf.yapflib import py3compat |
| 23 | |
| 24 | |
| 25 | class IO(object): |
| 26 | """IO is a thin wrapper around StringIO. |
| 27 | |
| 28 | This is strictly to wrap the Python 3 StringIO object so that it can supply a |
| 29 | "buffer" attribute. |
| 30 | """ |
| 31 | |
| 32 | class Buffer(object): |
| 33 | |
| 34 | def __init__(self): |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 35 | self.string_io = py3compat.StringIO() |
Bill Wendling | cec6b19 | 2016-10-16 00:30:02 -0500 | [diff] [blame] | 36 | |
| 37 | def write(self, s): |
| 38 | if py3compat.PY3 and isinstance(s, bytes): |
| 39 | s = str(s, 'utf-8') |
| 40 | self.string_io.write(s) |
| 41 | |
| 42 | def getvalue(self): |
| 43 | return self.string_io.getvalue() |
| 44 | |
| 45 | def __init__(self): |
| 46 | self.buffer = self.Buffer() |
| 47 | |
| 48 | def write(self, s): |
| 49 | self.buffer.write(s) |
| 50 | |
| 51 | def getvalue(self): |
| 52 | return self.buffer.getvalue() |
| 53 | |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 54 | |
| 55 | @contextmanager |
Andy Hayden | 58e1b04 | 2015-04-20 12:34:49 -0700 | [diff] [blame] | 56 | def captured_output(): |
Bill Wendling | cec6b19 | 2016-10-16 00:30:02 -0500 | [diff] [blame] | 57 | new_out, new_err = IO(), IO() |
Andy Hayden | 58e1b04 | 2015-04-20 12:34:49 -0700 | [diff] [blame] | 58 | old_out, old_err = sys.stdout, sys.stderr |
| 59 | try: |
| 60 | sys.stdout, sys.stderr = new_out, new_err |
| 61 | yield sys.stdout, sys.stderr |
| 62 | finally: |
| 63 | sys.stdout, sys.stderr = old_out, old_err |
| 64 | |
| 65 | |
| 66 | @contextmanager |
| 67 | def patched_input(code): |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 68 | """Monkey patch code as though it were coming from stdin.""" |
Andy Hayden | 58e1b04 | 2015-04-20 12:34:49 -0700 | [diff] [blame] | 69 | |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 70 | def lines(): |
| 71 | for line in code.splitlines(): |
| 72 | yield line |
| 73 | raise EOFError() |
Andy Hayden | 58e1b04 | 2015-04-20 12:34:49 -0700 | [diff] [blame] | 74 | |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 75 | def patch_raw_input(lines=lines()): |
| 76 | return next(lines) |
Andy Hayden | 58e1b04 | 2015-04-20 12:34:49 -0700 | [diff] [blame] | 77 | |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 78 | try: |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 79 | orig_raw_import = yapf.py3compat.raw_input |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 80 | yapf.py3compat.raw_input = patch_raw_input |
| 81 | yield |
| 82 | finally: |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 83 | yapf.py3compat.raw_input = orig_raw_import |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 84 | |
Sam Clegg | 08c4535 | 2015-04-06 11:02:51 -0700 | [diff] [blame] | 85 | |
Sam Clegg | 4f6c195 | 2015-04-27 12:26:22 -0700 | [diff] [blame] | 86 | class RunMainTest(unittest.TestCase): |
| 87 | |
| 88 | def testShouldHandleYapfError(self): |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 89 | """run_main should handle YapfError and sys.exit(1).""" |
Sam Clegg | 4f6c195 | 2015-04-27 12:26:22 -0700 | [diff] [blame] | 90 | expected_message = 'yapf: Input filenames did not match any python files\n' |
| 91 | sys.argv = ['yapf', 'foo.c'] |
| 92 | with captured_output() as (out, err): |
| 93 | with self.assertRaises(SystemExit): |
neube | 63fb670 | 2016-07-07 12:16:41 +0200 | [diff] [blame] | 94 | yapf.run_main() |
Sam Clegg | 4f6c195 | 2015-04-27 12:26:22 -0700 | [diff] [blame] | 95 | self.assertEqual(out.getvalue(), '') |
| 96 | self.assertEqual(err.getvalue(), expected_message) |
| 97 | |
| 98 | |
Sam Clegg | 08c4535 | 2015-04-06 11:02:51 -0700 | [diff] [blame] | 99 | class MainTest(unittest.TestCase): |
| 100 | |
| 101 | def testNoPythonFilesMatched(self): |
Sam Clegg | 4f6c195 | 2015-04-27 12:26:22 -0700 | [diff] [blame] | 102 | with self.assertRaisesRegexp(yapf.errors.YapfError, |
Sam Clegg | 08c4535 | 2015-04-06 11:02:51 -0700 | [diff] [blame] | 103 | 'did not match any python files'): |
| 104 | yapf.main(['yapf', 'foo.c']) |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 105 | |
| 106 | def testEchoInput(self): |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 107 | code = 'a = 1\nb = 2\n' |
Andy Hayden | 58e1b04 | 2015-04-20 12:34:49 -0700 | [diff] [blame] | 108 | with patched_input(code): |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 109 | with captured_output() as (out, _): |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 110 | ret = yapf.main([]) |
| 111 | self.assertEqual(ret, 0) |
| 112 | self.assertEqual(out.getvalue(), code) |
| 113 | |
| 114 | def testEchoInputWithStyle(self): |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 115 | code = 'def f(a = 1):\n return 2*a\n' |
| 116 | chromium_code = 'def f(a=1):\n return 2 * a\n' |
Andy Hayden | 58e1b04 | 2015-04-20 12:34:49 -0700 | [diff] [blame] | 117 | with patched_input(code): |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 118 | with captured_output() as (out, _): |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 119 | ret = yapf.main(['-', '--style=chromium']) |
Reece Hart | 6ac26c9 | 2016-07-27 21:41:59 -0700 | [diff] [blame] | 120 | self.assertEqual(ret, 0) |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 121 | self.assertEqual(out.getvalue(), chromium_code) |
| 122 | |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 123 | def testEchoBadInput(self): |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 124 | bad_syntax = ' a = 1\n' |
Andy Hayden | 58e1b04 | 2015-04-20 12:34:49 -0700 | [diff] [blame] | 125 | with patched_input(bad_syntax): |
Bill Wendling | d543e20 | 2017-10-05 16:11:44 -0700 | [diff] [blame] | 126 | with captured_output() as (_, _): |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 127 | with self.assertRaisesRegexp(SyntaxError, 'unexpected indent'): |
neube | 63fb670 | 2016-07-07 12:16:41 +0200 | [diff] [blame] | 128 | yapf.main([]) |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 129 | |
| 130 | def testHelp(self): |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 131 | with captured_output() as (out, _): |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 132 | ret = yapf.main(['-', '--style-help', '--style=pep8']) |
| 133 | self.assertEqual(ret, 0) |
| 134 | help_message = out.getvalue() |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 135 | self.assertIn('indent_width=4', help_message) |
| 136 | self.assertIn('The number of spaces required before a trailing comment.', |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 137 | help_message) |
| 138 | |
| 139 | def testVersion(self): |
Bill Wendling | cfcdd98 | 2017-01-30 23:17:16 -0800 | [diff] [blame] | 140 | with captured_output() as (out, _): |
Andy Hayden | c1b85ac | 2015-04-19 12:21:48 -0700 | [diff] [blame] | 141 | ret = yapf.main(['-', '--version']) |
| 142 | self.assertEqual(ret, 0) |
| 143 | version = 'yapf {}\n'.format(yapf.__version__) |
| 144 | self.assertEqual(version, out.getvalue()) |