# Copyright 2015 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.
"""Tests for yapf.blank_line_calculator."""

import textwrap
import unittest

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

from yapftests import yapf_test_helper


class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):

  @classmethod
  def setUpClass(cls):
    style.SetGlobalStyle(style.CreateYapfStyle())

  def testDecorators(self):
    unformatted_code = textwrap.dedent("""\
        @bork()

        def foo():
          pass
    """)
    expected_formatted_code = textwrap.dedent("""\
        @bork()
        def foo():
          pass
    """)
    llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))

  def testComplexDecorators(self):
    unformatted_code = textwrap.dedent("""\
        import sys
        @bork()

        def foo():
          pass
        @fork()

        class moo(object):
          @bar()
          @baz()

          def method(self):
            pass
    """)
    expected_formatted_code = textwrap.dedent("""\
        import sys


        @bork()
        def foo():
          pass


        @fork()
        class moo(object):

          @bar()
          @baz()
          def method(self):
            pass
    """)
    llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))

  def testCodeAfterFunctionsAndClasses(self):
    unformatted_code = textwrap.dedent("""\
        def foo():
          pass
        top_level_code = True
        class moo(object):
          def method_1(self):
            pass
          ivar_a = 42
          ivar_b = 13
          def method_2(self):
            pass
        try:
          raise Error
        except Error as error:
          pass
    """)
    expected_formatted_code = textwrap.dedent("""\
        def foo():
          pass


        top_level_code = True


        class moo(object):

          def method_1(self):
            pass

          ivar_a = 42
          ivar_b = 13

          def method_2(self):
            pass


        try:
          raise Error
        except Error as error:
          pass
    """)
    llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))

  def testCommentSpacing(self):
    unformatted_code = textwrap.dedent("""\
        # This is the first comment
        # And it's multiline

        # This is the second comment

        def foo():
          pass

        # multiline before a
        # class definition

        # This is the second comment

        class qux(object):
          pass


        # An attached comment.
        class bar(object):
          '''class docstring'''
          # Comment attached to
          # function
          def foo(self):
            '''Another docstring.'''
            # Another multiline
            # comment
            pass
    """)
    expected_formatted_code = textwrap.dedent("""\
        # This is the first comment
        # And it's multiline

        # This is the second comment


        def foo():
          pass


        # multiline before a
        # class definition

        # This is the second comment


        class qux(object):
          pass


        # An attached comment.
        class bar(object):
          '''class docstring'''

          # Comment attached to
          # function
          def foo(self):
            '''Another docstring.'''
            # Another multiline
            # comment
            pass
    """)
    llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))

  def testCommentBeforeMethod(self):
    code = textwrap.dedent("""\
        class foo(object):

          # pylint: disable=invalid-name
          def f(self):
            pass
    """)
    llines = yapf_test_helper.ParseAndUnwrap(code)
    self.assertCodeEqual(code, reformatter.Reformat(llines))

  def testCommentsBeforeClassDefs(self):
    code = textwrap.dedent('''\
        """Test."""

        # Comment


        class Foo(object):
          pass
    ''')
    llines = yapf_test_helper.ParseAndUnwrap(code)
    self.assertCodeEqual(code, reformatter.Reformat(llines))

  def testCommentsBeforeDecorator(self):
    code = textwrap.dedent("""\
        # The @foo operator adds bork to a().
        @foo()
        def a():
          pass
    """)
    llines = yapf_test_helper.ParseAndUnwrap(code)
    self.assertCodeEqual(code, reformatter.Reformat(llines))

    code = textwrap.dedent("""\
        # Hello world


        @foo()
        def a():
          pass
    """)
    llines = yapf_test_helper.ParseAndUnwrap(code)
    self.assertCodeEqual(code, reformatter.Reformat(llines))

  def testCommentsAfterDecorator(self):
    code = textwrap.dedent("""\
        class _():

          def _():
            pass

          @pytest.mark.xfail(reason="#709 and #710")
          # also
          #@pytest.mark.xfail(setuptools.tests.is_ascii,
          #    reason="https://github.com/pypa/setuptools/issues/706")
          def test_unicode_filename_in_sdist(self, sdist_unicode, tmpdir, monkeypatch):
            pass
    """)  # noqa
    llines = yapf_test_helper.ParseAndUnwrap(code)
    self.assertCodeEqual(code, reformatter.Reformat(llines))

  def testInnerClasses(self):
    unformatted_code = textwrap.dedent("""\
      class DeployAPIClient(object):
          class Error(Exception): pass

          class TaskValidationError(Error): pass

          class DeployAPIHTTPError(Error): pass
    """)
    expected_formatted_code = textwrap.dedent("""\
      class DeployAPIClient(object):

        class Error(Exception):
          pass

        class TaskValidationError(Error):
          pass

        class DeployAPIHTTPError(Error):
          pass
    """)
    llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))

  def testLinesOnRangeBoundary(self):
    unformatted_code = textwrap.dedent("""\
        def A():
          pass

        def B():  # 4
          pass  # 5

        def C():
          pass
        def D():  # 9
          pass  # 10
        def E():
          pass
    """)
    expected_formatted_code = textwrap.dedent("""\
        def A():
          pass


        def B():  # 4
          pass  # 5

        def C():
          pass


        def D():  # 9
          pass  # 10
        def E():
          pass
    """)
    code, changed = yapf_api.FormatCode(
        unformatted_code, lines=[(4, 5), (9, 10)])
    self.assertCodeEqual(expected_formatted_code, code)
    self.assertTrue(changed)

  def testLinesRangeBoundaryNotOutside(self):
    unformatted_code = textwrap.dedent("""\
        def A():
          pass



        def B():  # 6
          pass  # 7



        def C():
          pass
    """)
    expected_formatted_code = textwrap.dedent("""\
        def A():
          pass



        def B():  # 6
          pass  # 7



        def C():
          pass
    """)
    code, changed = yapf_api.FormatCode(unformatted_code, lines=[(6, 7)])
    self.assertCodeEqual(expected_formatted_code, code)
    self.assertFalse(changed)

  def testLinesRangeRemove(self):
    unformatted_code = textwrap.dedent("""\
        def A():
          pass



        def B():  # 6
          pass  # 7




        def C():
          pass
    """)
    expected_formatted_code = textwrap.dedent("""\
        def A():
          pass


        def B():  # 6
          pass  # 7




        def C():
          pass
    """)
    code, changed = yapf_api.FormatCode(unformatted_code, lines=[(5, 9)])
    self.assertCodeEqual(expected_formatted_code, code)
    self.assertTrue(changed)

  def testLinesRangeRemoveSome(self):
    unformatted_code = textwrap.dedent("""\
        def A():
          pass




        def B():  # 7
          pass  # 8




        def C():
          pass
    """)
    expected_formatted_code = textwrap.dedent("""\
        def A():
          pass



        def B():  # 7
          pass  # 8




        def C():
          pass
    """)
    code, changed = yapf_api.FormatCode(unformatted_code, lines=[(6, 9)])
    self.assertCodeEqual(expected_formatted_code, code)
    self.assertTrue(changed)


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