# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Style config tests for yapf.reformatter."""

import textwrap
import unittest

from yapf.yapflib import reformatter
from yapf.yapflib import style

from yapftests import yapf_test_helper


class TestsForStyleConfig(yapf_test_helper.YAPFTest):

  def setUp(self):
    self.current_style = style.DEFAULT_STYLE

  def testSetGlobalStyle(self):
    try:
      style.SetGlobalStyle(style.CreateYapfStyle())
      unformatted_code = textwrap.dedent("""\
          for i in range(5):
           print('bar')
      """)
      expected_formatted_code = textwrap.dedent("""\
          for i in range(5):
            print('bar')
      """)
      llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
      self.assertCodeEqual(expected_formatted_code,
                           reformatter.Reformat(llines))
    finally:
      style.SetGlobalStyle(style.CreatePEP8Style())
      style.DEFAULT_STYLE = self.current_style

    unformatted_code = textwrap.dedent("""\
        for i in range(5):
         print('bar')
    """)
    expected_formatted_code = textwrap.dedent("""\
        for i in range(5):
            print('bar')
    """)
    llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))

  def testOperatorNoSpaceStyle(self):
    try:
      sympy_style = style.CreatePEP8Style()
      sympy_style['NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS'] = \
        style._StringSetConverter('*,/')
      style.SetGlobalStyle(sympy_style)
      unformatted_code = textwrap.dedent("""\
          a = 1+2 * 3 - 4 / 5
          b = '0' * 1
      """)
      expected_formatted_code = textwrap.dedent("""\
          a = 1 + 2*3 - 4/5
          b = '0'*1
      """)

      llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
      self.assertCodeEqual(expected_formatted_code,
                           reformatter.Reformat(llines))
    finally:
      style.SetGlobalStyle(style.CreatePEP8Style())
      style.DEFAULT_STYLE = self.current_style

  def testOperatorPrecedenceStyle(self):
    try:
      pep8_with_precedence = style.CreatePEP8Style()
      pep8_with_precedence['ARITHMETIC_PRECEDENCE_INDICATION'] = True
      style.SetGlobalStyle(pep8_with_precedence)
      unformatted_code = textwrap.dedent("""\
          1+2
          (1 + 2) * (3 - (4 / 5))
          a = 1 * 2 + 3 / 4
          b = 1 / 2 - 3 * 4
          c = (1 + 2) * (3 - 4)
          d = (1 - 2) / (3 + 4)
          e = 1 * 2 - 3
          f = 1 + 2 + 3 + 4
          g = 1 * 2 * 3 * 4
          h = 1 + 2 - 3 + 4
          i = 1 * 2 / 3 * 4
          j = (1 * 2 - 3) + 4
          k = (1 * 2 * 3) + (4 * 5 * 6 * 7 * 8)
      """)
      expected_formatted_code = textwrap.dedent("""\
          1 + 2
          (1+2) * (3 - (4/5))
          a = 1*2 + 3/4
          b = 1/2 - 3*4
          c = (1+2) * (3-4)
          d = (1-2) / (3+4)
          e = 1*2 - 3
          f = 1 + 2 + 3 + 4
          g = 1 * 2 * 3 * 4
          h = 1 + 2 - 3 + 4
          i = 1 * 2 / 3 * 4
          j = (1*2 - 3) + 4
          k = (1*2*3) + (4*5*6*7*8)
      """)

      llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
      self.assertCodeEqual(expected_formatted_code,
                           reformatter.Reformat(llines))
    finally:
      style.SetGlobalStyle(style.CreatePEP8Style())
      style.DEFAULT_STYLE = self.current_style

  def testNoSplitBeforeFirstArgumentStyle1(self):
    try:
      pep8_no_split_before_first = style.CreatePEP8Style()
      pep8_no_split_before_first['SPLIT_BEFORE_FIRST_ARGUMENT'] = False
      pep8_no_split_before_first['SPLIT_BEFORE_NAMED_ASSIGNS'] = False
      style.SetGlobalStyle(pep8_no_split_before_first)
      formatted_code = textwrap.dedent("""\
          # Example from in-code MustSplit comments
          foo = outer_function_call(fitting_inner_function_call(inner_arg1, inner_arg2),
                                    outer_arg1, outer_arg2)

          foo = outer_function_call(
              not_fitting_inner_function_call(inner_arg1, inner_arg2), outer_arg1,
              outer_arg2)

          # Examples Issue#424
          a_super_long_version_of_print(argument1, argument2, argument3, argument4,
                                        argument5, argument6, argument7)

          CREDS_FILE = os.path.join(os.path.expanduser('~'),
                                    'apis/super-secret-admin-creds.json')

          # Examples Issue#556
          i_take_a_lot_of_params(arg1, param1=very_long_expression1(),
                                 param2=very_long_expression2(),
                                 param3=very_long_expression3(),
                                 param4=very_long_expression4())

          # Examples Issue#590
          plt.plot(numpy.linspace(0, 1, 10), numpy.linspace(0, 1, 10), marker="x",
                   color="r")

          plt.plot(veryverylongvariablename, veryverylongvariablename, marker="x",
                   color="r")
      """)  # noqa
      llines = yapf_test_helper.ParseAndUnwrap(formatted_code)
      self.assertCodeEqual(formatted_code, reformatter.Reformat(llines))
    finally:
      style.SetGlobalStyle(style.CreatePEP8Style())
      style.DEFAULT_STYLE = self.current_style

  def testNoSplitBeforeFirstArgumentStyle2(self):
    try:
      pep8_no_split_before_first = style.CreatePEP8Style()
      pep8_no_split_before_first['SPLIT_BEFORE_FIRST_ARGUMENT'] = False
      pep8_no_split_before_first['SPLIT_BEFORE_NAMED_ASSIGNS'] = True
      style.SetGlobalStyle(pep8_no_split_before_first)
      formatted_code = textwrap.dedent("""\
          # Examples Issue#556
          i_take_a_lot_of_params(arg1,
                                 param1=very_long_expression1(),
                                 param2=very_long_expression2(),
                                 param3=very_long_expression3(),
                                 param4=very_long_expression4())

          # Examples Issue#590
          plt.plot(numpy.linspace(0, 1, 10),
                   numpy.linspace(0, 1, 10),
                   marker="x",
                   color="r")

          plt.plot(veryverylongvariablename,
                   veryverylongvariablename,
                   marker="x",
                   color="r")
      """)
      llines = yapf_test_helper.ParseAndUnwrap(formatted_code)
      self.assertCodeEqual(formatted_code, reformatter.Reformat(llines))
    finally:
      style.SetGlobalStyle(style.CreatePEP8Style())
      style.DEFAULT_STYLE = self.current_style


if __name__ == '__main__':
  unittest.main()
