#!/usr/bin/env python3

#
# Copyright 2015, The Android Open Source Project
#
# 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 the Checkstyle script used to run style checks on Java files."""

try:
  from StringIO import StringIO
except ImportError:
  # python3 use io instead of StringIO
  from io import StringIO
import unittest
import checkstyle


TEST_RULE = u'com.puppycrawl.tools.checkstyle.checks.BANANAS'
TEST_SHA = u'0000deadbeef000000deadbeef00deadbeef0000'
TEST_ROOT = u'/usr/local/android/master/framework/support'
TEST_FILE1 = TEST_ROOT + u'/Blarg.java'
TEST_FILE2 = TEST_ROOT + u'/Blarg2.java'
TEST_FILE_NON_JAVA = TEST_ROOT + u'/blarg.cc'
FILE_ADDED = u'A '
FILE_MODIFIED = u'M '
FILE_UNTRACKED = u'??'


def mock_repository_root():
  return TEST_ROOT


def mock_last_commit():
  return TEST_SHA


def mock_modified_files_good(root, tracked_only=False, commit=None):
  if commit:
    return {TEST_FILE1: FILE_MODIFIED, TEST_FILE2: FILE_ADDED}
  return {}


def mock_modified_files_uncommitted(root, tracked_only=False, commit=None):
  if tracked_only and not commit:
    return {TEST_FILE1: FILE_MODIFIED}
  if commit:
    return {TEST_FILE1: FILE_MODIFIED, TEST_FILE2: FILE_ADDED}
  return {}


def mock_modified_files_untracked(root, tracked_only=False, commit=None):
  if not tracked_only:
    return {TEST_FILE1: FILE_UNTRACKED}
  if commit:
    return {TEST_FILE2: FILE_ADDED}
  return {}


def mock_modified_files_non_java(root, tracked_only=False, commit=None):
  if commit:
    return {TEST_FILE1: FILE_MODIFIED, TEST_FILE_NON_JAVA: FILE_ADDED}
  return {}


class TestCheckstyle(unittest.TestCase):

  def setUp(self):
    checkstyle.git.repository_root = mock_repository_root
    checkstyle.git.last_commit = mock_last_commit

  def test_ShouldSkip(self):
    # Skip checks for explicit git commit.
    self.assertFalse(checkstyle._ShouldSkip(True, None, 1, TEST_RULE))
    self.assertTrue(checkstyle._ShouldSkip(True, [], 1, TEST_RULE))
    self.assertFalse(checkstyle._ShouldSkip(True, [1], 1, TEST_RULE))
    self.assertFalse(checkstyle._ShouldSkip(True, [1, 2, 3], 1, TEST_RULE))
    self.assertTrue(checkstyle._ShouldSkip(True, [1, 2, 3], 4, TEST_RULE))
    for rule in checkstyle.FORCED_RULES:
      self.assertFalse(checkstyle._ShouldSkip(True, [1, 2, 3], 1, rule))
      self.assertFalse(checkstyle._ShouldSkip(True, [1, 2, 3], 4, rule))

    # Skip checks for explicitly checked files.
    self.assertFalse(checkstyle._ShouldSkip(False, None, 1, TEST_RULE))
    self.assertFalse(checkstyle._ShouldSkip(False, [], 1, TEST_RULE))
    self.assertFalse(checkstyle._ShouldSkip(False, [1], 1, TEST_RULE))
    self.assertFalse(checkstyle._ShouldSkip(False, [1, 2, 3], 1, TEST_RULE))
    self.assertFalse(checkstyle._ShouldSkip(False, [1, 2, 3], 4, TEST_RULE))
    for rule in checkstyle.FORCED_RULES:
      self.assertFalse(checkstyle._ShouldSkip(False, [1, 2, 3], 1, rule))
      self.assertFalse(checkstyle._ShouldSkip(False, [1, 2, 3], 4, rule))

    # Skip checks for test classes.
    self.assertFalse(checkstyle._ShouldSkip(True, None, 1, TEST_RULE, True))
    self.assertTrue(checkstyle._ShouldSkip(True, [], 1, TEST_RULE, True))
    self.assertFalse(checkstyle._ShouldSkip(True, [1], 1, TEST_RULE, True))
    self.assertFalse(checkstyle._ShouldSkip(True, [1, 2, 3], 1, TEST_RULE, True))
    self.assertTrue(checkstyle._ShouldSkip(True, [1, 2, 3], 4, TEST_RULE, True))
    for rule in checkstyle.SKIPPED_RULES_FOR_TEST_FILES:
      self.assertTrue(checkstyle._ShouldSkip(True, [1, 2, 3], 1, rule, True))
      self.assertTrue(checkstyle._ShouldSkip(True, [1, 2, 3], 4, rule, True))

  def test_GetModifiedFiles(self):
    checkstyle.git.modified_files = mock_modified_files_good
    out = StringIO()
    files = checkstyle._GetModifiedFiles(mock_last_commit(), out=out)
    output = out.getvalue()
    self.assertEqual(output, '')
    self.assertEqual(files, {TEST_FILE1: FILE_MODIFIED, TEST_FILE2: FILE_ADDED})

  def test_GetModifiedFilesUncommitted(self):
    checkstyle.git.modified_files = mock_modified_files_uncommitted
    with self.assertRaises(SystemExit):
      out = StringIO()
      checkstyle._GetModifiedFiles(mock_last_commit(), out=out)
    self.assertEqual(out.getvalue(), checkstyle.ERROR_UNCOMMITTED)

  def test_GetModifiedFilesUncommittedExplicitCommit(self):
    checkstyle.git.modified_files = mock_modified_files_uncommitted
    out = StringIO()
    files = checkstyle._GetModifiedFiles(mock_last_commit(), True, out=out)
    output = out.getvalue()
    self.assertEqual(output, '')
    self.assertEqual(files, {TEST_FILE1: FILE_MODIFIED, TEST_FILE2: FILE_ADDED})

  def test_GetModifiedFilesNonJava(self):
    checkstyle.git.modified_files = mock_modified_files_non_java
    out = StringIO()
    files = checkstyle._GetModifiedFiles(mock_last_commit(), out=out)
    output = out.getvalue()
    self.assertEqual(output, '')
    self.assertEqual(files, {TEST_FILE1: FILE_MODIFIED})

  def test_WarnIfUntrackedFiles(self):
    checkstyle.git.modified_files = mock_modified_files_untracked
    out = StringIO()
    checkstyle._WarnIfUntrackedFiles(out=out)
    output = out.getvalue()
    self.assertEqual(output, checkstyle.ERROR_UNTRACKED + TEST_FILE1 + '\n\n')

  def test_WarnIfUntrackedFilesNoUntracked(self):
    checkstyle.git.modified_files = mock_modified_files_good
    out = StringIO()
    checkstyle._WarnIfUntrackedFiles(out=out)
    output = out.getvalue()
    self.assertEqual(output, '')

  def test_FilterFiles(self):
    files = {TEST_FILE1: FILE_MODIFIED, TEST_FILE2: FILE_ADDED}
    output = checkstyle._FilterFiles(files, None)
    self.assertEqual(files, output)
    output = checkstyle._FilterFiles(files, ['Blarg2'])
    self.assertEqual({TEST_FILE2: FILE_ADDED}, output)
    output = checkstyle._FilterFiles(files, ['Blarg'])
    self.assertEqual(files, output)
    output = checkstyle._FilterFiles(files, ['FunkyTown'])
    self.assertEqual({}, output)

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