blob: 138853ceb9372ffdbb4a02110e625189839ea42f [file] [log] [blame]
Sam Clegg08c45352015-04-06 11:02:51 -07001# -*- coding: utf-8 -*-
Bill Wendling92290f12018-01-14 16:49:35 -08002# Copyright 2015 Google Inc. All Rights Reserved.
Sam Clegg08c45352015-04-06 11:02:51 -07003#
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 Haydenc1b85ac2015-04-19 12:21:48 -070017from contextlib import contextmanager
18import sys
Sam Clegg08c45352015-04-06 11:02:51 -070019import unittest
20import yapf
21
Bill Wendlingcec6b192016-10-16 00:30:02 -050022from yapf.yapflib import py3compat
23
24
25class 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 Wendlingcfcdd982017-01-30 23:17:16 -080035 self.string_io = py3compat.StringIO()
Bill Wendlingcec6b192016-10-16 00:30:02 -050036
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 Haydenc1b85ac2015-04-19 12:21:48 -070054
55@contextmanager
Andy Hayden58e1b042015-04-20 12:34:49 -070056def captured_output():
Bill Wendlingcec6b192016-10-16 00:30:02 -050057 new_out, new_err = IO(), IO()
Andy Hayden58e1b042015-04-20 12:34:49 -070058 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
67def patched_input(code):
Bill Wendlingcfcdd982017-01-30 23:17:16 -080068 """Monkey patch code as though it were coming from stdin."""
Andy Hayden58e1b042015-04-20 12:34:49 -070069
Andy Haydenc1b85ac2015-04-19 12:21:48 -070070 def lines():
71 for line in code.splitlines():
72 yield line
73 raise EOFError()
Andy Hayden58e1b042015-04-20 12:34:49 -070074
Andy Haydenc1b85ac2015-04-19 12:21:48 -070075 def patch_raw_input(lines=lines()):
76 return next(lines)
Andy Hayden58e1b042015-04-20 12:34:49 -070077
Andy Haydenc1b85ac2015-04-19 12:21:48 -070078 try:
Bill Wendlingcfcdd982017-01-30 23:17:16 -080079 orig_raw_import = yapf.py3compat.raw_input
Andy Haydenc1b85ac2015-04-19 12:21:48 -070080 yapf.py3compat.raw_input = patch_raw_input
81 yield
82 finally:
Bill Wendlingcfcdd982017-01-30 23:17:16 -080083 yapf.py3compat.raw_input = orig_raw_import
Andy Haydenc1b85ac2015-04-19 12:21:48 -070084
Sam Clegg08c45352015-04-06 11:02:51 -070085
Sam Clegg4f6c1952015-04-27 12:26:22 -070086class RunMainTest(unittest.TestCase):
87
88 def testShouldHandleYapfError(self):
Bill Wendlingcfcdd982017-01-30 23:17:16 -080089 """run_main should handle YapfError and sys.exit(1)."""
Sam Clegg4f6c1952015-04-27 12:26:22 -070090 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):
neube63fb6702016-07-07 12:16:41 +020094 yapf.run_main()
Sam Clegg4f6c1952015-04-27 12:26:22 -070095 self.assertEqual(out.getvalue(), '')
96 self.assertEqual(err.getvalue(), expected_message)
97
98
Sam Clegg08c45352015-04-06 11:02:51 -070099class MainTest(unittest.TestCase):
100
101 def testNoPythonFilesMatched(self):
Sam Clegg4f6c1952015-04-27 12:26:22 -0700102 with self.assertRaisesRegexp(yapf.errors.YapfError,
Sam Clegg08c45352015-04-06 11:02:51 -0700103 'did not match any python files'):
104 yapf.main(['yapf', 'foo.c'])
Andy Haydenc1b85ac2015-04-19 12:21:48 -0700105
106 def testEchoInput(self):
Bill Wendlingcfcdd982017-01-30 23:17:16 -0800107 code = 'a = 1\nb = 2\n'
Andy Hayden58e1b042015-04-20 12:34:49 -0700108 with patched_input(code):
Bill Wendlingcfcdd982017-01-30 23:17:16 -0800109 with captured_output() as (out, _):
Andy Haydenc1b85ac2015-04-19 12:21:48 -0700110 ret = yapf.main([])
111 self.assertEqual(ret, 0)
112 self.assertEqual(out.getvalue(), code)
113
114 def testEchoInputWithStyle(self):
Bill Wendlingcfcdd982017-01-30 23:17:16 -0800115 code = 'def f(a = 1):\n return 2*a\n'
116 chromium_code = 'def f(a=1):\n return 2 * a\n'
Andy Hayden58e1b042015-04-20 12:34:49 -0700117 with patched_input(code):
Bill Wendlingcfcdd982017-01-30 23:17:16 -0800118 with captured_output() as (out, _):
Andy Haydenc1b85ac2015-04-19 12:21:48 -0700119 ret = yapf.main(['-', '--style=chromium'])
Reece Hart6ac26c92016-07-27 21:41:59 -0700120 self.assertEqual(ret, 0)
Andy Haydenc1b85ac2015-04-19 12:21:48 -0700121 self.assertEqual(out.getvalue(), chromium_code)
122
Andy Haydenc1b85ac2015-04-19 12:21:48 -0700123 def testEchoBadInput(self):
Bill Wendlingcfcdd982017-01-30 23:17:16 -0800124 bad_syntax = ' a = 1\n'
Andy Hayden58e1b042015-04-20 12:34:49 -0700125 with patched_input(bad_syntax):
Bill Wendlingd543e202017-10-05 16:11:44 -0700126 with captured_output() as (_, _):
Bill Wendlingcfcdd982017-01-30 23:17:16 -0800127 with self.assertRaisesRegexp(SyntaxError, 'unexpected indent'):
neube63fb6702016-07-07 12:16:41 +0200128 yapf.main([])
Andy Haydenc1b85ac2015-04-19 12:21:48 -0700129
130 def testHelp(self):
Bill Wendlingcfcdd982017-01-30 23:17:16 -0800131 with captured_output() as (out, _):
Andy Haydenc1b85ac2015-04-19 12:21:48 -0700132 ret = yapf.main(['-', '--style-help', '--style=pep8'])
133 self.assertEqual(ret, 0)
134 help_message = out.getvalue()
Bill Wendlingcfcdd982017-01-30 23:17:16 -0800135 self.assertIn('indent_width=4', help_message)
136 self.assertIn('The number of spaces required before a trailing comment.',
Andy Haydenc1b85ac2015-04-19 12:21:48 -0700137 help_message)
138
139 def testVersion(self):
Bill Wendlingcfcdd982017-01-30 23:17:16 -0800140 with captured_output() as (out, _):
Andy Haydenc1b85ac2015-04-19 12:21:48 -0700141 ret = yapf.main(['-', '--version'])
142 self.assertEqual(ret, 0)
143 version = 'yapf {}\n'.format(yapf.__version__)
144 self.assertEqual(version, out.getvalue())