xref: /aosp_15_r20/external/yapf/yapftests/yapf_test_helper.py (revision 7249d1a64f4850ccf838e62a46276f891f72998e)
1*7249d1a6SKrzysztof Kosiński# Copyright 2016 Google Inc. All Rights Reserved.
2*7249d1a6SKrzysztof Kosiński#
3*7249d1a6SKrzysztof Kosiński# Licensed under the Apache License, Version 2.0 (the "License");
4*7249d1a6SKrzysztof Kosiński# you may not use this file except in compliance with the License.
5*7249d1a6SKrzysztof Kosiński# You may obtain a copy of the License at
6*7249d1a6SKrzysztof Kosiński#
7*7249d1a6SKrzysztof Kosiński#     http://www.apache.org/licenses/LICENSE-2.0
8*7249d1a6SKrzysztof Kosiński#
9*7249d1a6SKrzysztof Kosiński# Unless required by applicable law or agreed to in writing, software
10*7249d1a6SKrzysztof Kosiński# distributed under the License is distributed on an "AS IS" BASIS,
11*7249d1a6SKrzysztof Kosiński# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*7249d1a6SKrzysztof Kosiński# See the License for the specific language governing permissions and
13*7249d1a6SKrzysztof Kosiński# limitations under the License.
14*7249d1a6SKrzysztof Kosiński"""Support module for tests for yapf."""
15*7249d1a6SKrzysztof Kosiński
16*7249d1a6SKrzysztof Kosińskiimport difflib
17*7249d1a6SKrzysztof Kosińskiimport sys
18*7249d1a6SKrzysztof Kosińskiimport unittest
19*7249d1a6SKrzysztof Kosiński
20*7249d1a6SKrzysztof Kosińskifrom yapf.yapflib import blank_line_calculator
21*7249d1a6SKrzysztof Kosińskifrom yapf.yapflib import comment_splicer
22*7249d1a6SKrzysztof Kosińskifrom yapf.yapflib import continuation_splicer
23*7249d1a6SKrzysztof Kosińskifrom yapf.yapflib import identify_container
24*7249d1a6SKrzysztof Kosińskifrom yapf.yapflib import py3compat
25*7249d1a6SKrzysztof Kosińskifrom yapf.yapflib import pytree_unwrapper
26*7249d1a6SKrzysztof Kosińskifrom yapf.yapflib import pytree_utils
27*7249d1a6SKrzysztof Kosińskifrom yapf.yapflib import pytree_visitor
28*7249d1a6SKrzysztof Kosińskifrom yapf.yapflib import split_penalty
29*7249d1a6SKrzysztof Kosińskifrom yapf.yapflib import style
30*7249d1a6SKrzysztof Kosińskifrom yapf.yapflib import subtype_assigner
31*7249d1a6SKrzysztof Kosiński
32*7249d1a6SKrzysztof Kosiński
33*7249d1a6SKrzysztof Kosińskiclass YAPFTest(unittest.TestCase):
34*7249d1a6SKrzysztof Kosiński
35*7249d1a6SKrzysztof Kosiński  def __init__(self, *args):
36*7249d1a6SKrzysztof Kosiński    super(YAPFTest, self).__init__(*args)
37*7249d1a6SKrzysztof Kosiński    if not py3compat.PY3:
38*7249d1a6SKrzysztof Kosiński      self.assertRaisesRegex = self.assertRaisesRegexp
39*7249d1a6SKrzysztof Kosiński
40*7249d1a6SKrzysztof Kosiński  def assertCodeEqual(self, expected_code, code):
41*7249d1a6SKrzysztof Kosiński    if code != expected_code:
42*7249d1a6SKrzysztof Kosiński      msg = ['Code format mismatch:', 'Expected:']
43*7249d1a6SKrzysztof Kosiński      linelen = style.Get('COLUMN_LIMIT')
44*7249d1a6SKrzysztof Kosiński      for line in expected_code.splitlines():
45*7249d1a6SKrzysztof Kosiński        if len(line) > linelen:
46*7249d1a6SKrzysztof Kosiński          msg.append('!> %s' % line)
47*7249d1a6SKrzysztof Kosiński        else:
48*7249d1a6SKrzysztof Kosiński          msg.append(' > %s' % line)
49*7249d1a6SKrzysztof Kosiński      msg.append('Actual:')
50*7249d1a6SKrzysztof Kosiński      for line in code.splitlines():
51*7249d1a6SKrzysztof Kosiński        if len(line) > linelen:
52*7249d1a6SKrzysztof Kosiński          msg.append('!> %s' % line)
53*7249d1a6SKrzysztof Kosiński        else:
54*7249d1a6SKrzysztof Kosiński          msg.append(' > %s' % line)
55*7249d1a6SKrzysztof Kosiński      msg.append('Diff:')
56*7249d1a6SKrzysztof Kosiński      msg.extend(
57*7249d1a6SKrzysztof Kosiński          difflib.unified_diff(
58*7249d1a6SKrzysztof Kosiński              code.splitlines(),
59*7249d1a6SKrzysztof Kosiński              expected_code.splitlines(),
60*7249d1a6SKrzysztof Kosiński              fromfile='actual',
61*7249d1a6SKrzysztof Kosiński              tofile='expected',
62*7249d1a6SKrzysztof Kosiński              lineterm=''))
63*7249d1a6SKrzysztof Kosiński      self.fail('\n'.join(msg))
64*7249d1a6SKrzysztof Kosiński
65*7249d1a6SKrzysztof Kosiński
66*7249d1a6SKrzysztof Kosińskidef ParseAndUnwrap(code, dumptree=False):
67*7249d1a6SKrzysztof Kosiński  """Produces logical lines from the given code.
68*7249d1a6SKrzysztof Kosiński
69*7249d1a6SKrzysztof Kosiński  Parses the code into a tree, performs comment splicing and runs the
70*7249d1a6SKrzysztof Kosiński  unwrapper.
71*7249d1a6SKrzysztof Kosiński
72*7249d1a6SKrzysztof Kosiński  Arguments:
73*7249d1a6SKrzysztof Kosiński    code: code to parse as a string
74*7249d1a6SKrzysztof Kosiński    dumptree: if True, the parsed pytree (after comment splicing) is dumped
75*7249d1a6SKrzysztof Kosiński              to stderr. Useful for debugging.
76*7249d1a6SKrzysztof Kosiński
77*7249d1a6SKrzysztof Kosiński  Returns:
78*7249d1a6SKrzysztof Kosiński    List of logical lines.
79*7249d1a6SKrzysztof Kosiński  """
80*7249d1a6SKrzysztof Kosiński  tree = pytree_utils.ParseCodeToTree(code)
81*7249d1a6SKrzysztof Kosiński  comment_splicer.SpliceComments(tree)
82*7249d1a6SKrzysztof Kosiński  continuation_splicer.SpliceContinuations(tree)
83*7249d1a6SKrzysztof Kosiński  subtype_assigner.AssignSubtypes(tree)
84*7249d1a6SKrzysztof Kosiński  identify_container.IdentifyContainers(tree)
85*7249d1a6SKrzysztof Kosiński  split_penalty.ComputeSplitPenalties(tree)
86*7249d1a6SKrzysztof Kosiński  blank_line_calculator.CalculateBlankLines(tree)
87*7249d1a6SKrzysztof Kosiński
88*7249d1a6SKrzysztof Kosiński  if dumptree:
89*7249d1a6SKrzysztof Kosiński    pytree_visitor.DumpPyTree(tree, target_stream=sys.stderr)
90*7249d1a6SKrzysztof Kosiński
91*7249d1a6SKrzysztof Kosiński  llines = pytree_unwrapper.UnwrapPyTree(tree)
92*7249d1a6SKrzysztof Kosiński  for lline in llines:
93*7249d1a6SKrzysztof Kosiński    lline.CalculateFormattingInformation()
94*7249d1a6SKrzysztof Kosiński
95*7249d1a6SKrzysztof Kosiński  return llines
96