Home | History | Annotate | Download | only in checkstyle
      1 #!/usr/bin/python
      2 
      3 #
      4 # Copyright 2015, The Android Open Source Project
      5 #
      6 # Licensed under the Apache License, Version 2.0 (the "License");
      7 # you may not use this file except in compliance with the License.
      8 # You may obtain a copy of the License at
      9 #
     10 #     http://www.apache.org/licenses/LICENSE-2.0
     11 #
     12 # Unless required by applicable law or agreed to in writing, software
     13 # distributed under the License is distributed on an "AS IS" BASIS,
     14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 # See the License for the specific language governing permissions and
     16 # limitations under the License.
     17 #
     18 
     19 """Tests the Checkstyle script used to run style checks on Java files."""
     20 
     21 from StringIO import StringIO
     22 import unittest
     23 import checkstyle
     24 
     25 
     26 TEST_RULE = u'com.puppycrawl.tools.checkstyle.checks.BANANAS'
     27 TEST_SHA = u'0000deadbeef000000deadbeef00deadbeef0000'
     28 TEST_ROOT = u'/usr/local/android/master/framework/support'
     29 TEST_FILE1 = TEST_ROOT + u'/Blarg.java'
     30 TEST_FILE2 = TEST_ROOT + u'/Blarg2.java'
     31 TEST_FILE_NON_JAVA = TEST_ROOT + u'/blarg.cc'
     32 FILE_ADDED = u'A '
     33 FILE_MODIFIED = u'M '
     34 FILE_UNTRACKED = u'??'
     35 
     36 
     37 def mock_repository_root():
     38   return TEST_ROOT
     39 
     40 
     41 def mock_last_commit():
     42   return TEST_SHA
     43 
     44 
     45 def mock_modified_files_good(root, tracked_only=False, commit=None):
     46   if commit:
     47     return {TEST_FILE1: FILE_MODIFIED, TEST_FILE2: FILE_ADDED}
     48   return {}
     49 
     50 
     51 def mock_modified_files_uncommitted(root, tracked_only=False, commit=None):
     52   if tracked_only and not commit:
     53     return {TEST_FILE1: FILE_MODIFIED}
     54   if commit:
     55     return {TEST_FILE1: FILE_MODIFIED, TEST_FILE2: FILE_ADDED}
     56   return {}
     57 
     58 
     59 def mock_modified_files_untracked(root, tracked_only=False, commit=None):
     60   if not tracked_only:
     61     return {TEST_FILE1: FILE_UNTRACKED}
     62   if commit:
     63     return {TEST_FILE2: FILE_ADDED}
     64   return {}
     65 
     66 
     67 def mock_modified_files_non_java(root, tracked_only=False, commit=None):
     68   if commit:
     69     return {TEST_FILE1: FILE_MODIFIED, TEST_FILE_NON_JAVA: FILE_ADDED}
     70   return {}
     71 
     72 
     73 class TestCheckstyle(unittest.TestCase):
     74 
     75   def setUp(self):
     76     checkstyle.git.repository_root = mock_repository_root
     77     checkstyle.git.last_commit = mock_last_commit
     78 
     79   def test_ShouldSkip(self):
     80     # Skip checks for explicit git commit.
     81     self.assertFalse(checkstyle._ShouldSkip(True, None, 1, TEST_RULE))
     82     self.assertTrue(checkstyle._ShouldSkip(True, [], 1, TEST_RULE))
     83     self.assertFalse(checkstyle._ShouldSkip(True, [1], 1, TEST_RULE))
     84     self.assertFalse(checkstyle._ShouldSkip(True, [1, 2, 3], 1, TEST_RULE))
     85     self.assertTrue(checkstyle._ShouldSkip(True, [1, 2, 3], 4, TEST_RULE))
     86     for rule in checkstyle.FORCED_RULES:
     87       self.assertFalse(checkstyle._ShouldSkip(True, [1, 2, 3], 1, rule))
     88       self.assertFalse(checkstyle._ShouldSkip(True, [1, 2, 3], 4, rule))
     89 
     90     # Skip checks for explicitly checked files.
     91     self.assertFalse(checkstyle._ShouldSkip(False, None, 1, TEST_RULE))
     92     self.assertFalse(checkstyle._ShouldSkip(False, [], 1, TEST_RULE))
     93     self.assertFalse(checkstyle._ShouldSkip(False, [1], 1, TEST_RULE))
     94     self.assertFalse(checkstyle._ShouldSkip(False, [1, 2, 3], 1, TEST_RULE))
     95     self.assertFalse(checkstyle._ShouldSkip(False, [1, 2, 3], 4, TEST_RULE))
     96     for rule in checkstyle.FORCED_RULES:
     97       self.assertFalse(checkstyle._ShouldSkip(False, [1, 2, 3], 1, rule))
     98       self.assertFalse(checkstyle._ShouldSkip(False, [1, 2, 3], 4, rule))
     99 
    100     # Skip checks for test classes.
    101     self.assertFalse(checkstyle._ShouldSkip(True, None, 1, TEST_RULE, True))
    102     self.assertTrue(checkstyle._ShouldSkip(True, [], 1, TEST_RULE, True))
    103     self.assertFalse(checkstyle._ShouldSkip(True, [1], 1, TEST_RULE, True))
    104     self.assertFalse(checkstyle._ShouldSkip(True, [1, 2, 3], 1, TEST_RULE, True))
    105     self.assertTrue(checkstyle._ShouldSkip(True, [1, 2, 3], 4, TEST_RULE, True))
    106     for rule in checkstyle.SKIPPED_RULES_FOR_TEST_FILES:
    107       self.assertTrue(checkstyle._ShouldSkip(True, [1, 2, 3], 1, rule, True))
    108       self.assertTrue(checkstyle._ShouldSkip(True, [1, 2, 3], 4, rule, True))
    109 
    110   def test_GetModifiedFiles(self):
    111     checkstyle.git.modified_files = mock_modified_files_good
    112     out = StringIO()
    113     files = checkstyle._GetModifiedFiles(mock_last_commit(), out=out)
    114     output = out.getvalue()
    115     self.assertEqual(output, '')
    116     self.assertEqual(files, {TEST_FILE1: FILE_MODIFIED, TEST_FILE2: FILE_ADDED})
    117 
    118   def test_GetModifiedFilesUncommitted(self):
    119     checkstyle.git.modified_files = mock_modified_files_uncommitted
    120     with self.assertRaises(SystemExit):
    121       out = StringIO()
    122       checkstyle._GetModifiedFiles(mock_last_commit(), out=out)
    123     self.assertEqual(out.getvalue(), checkstyle.ERROR_UNCOMMITTED)
    124 
    125   def test_GetModifiedFilesUncommittedExplicitCommit(self):
    126     checkstyle.git.modified_files = mock_modified_files_uncommitted
    127     out = StringIO()
    128     files = checkstyle._GetModifiedFiles(mock_last_commit(), True, out=out)
    129     output = out.getvalue()
    130     self.assertEqual(output, '')
    131     self.assertEqual(files, {TEST_FILE1: FILE_MODIFIED, TEST_FILE2: FILE_ADDED})
    132 
    133   def test_GetModifiedFilesNonJava(self):
    134     checkstyle.git.modified_files = mock_modified_files_non_java
    135     out = StringIO()
    136     files = checkstyle._GetModifiedFiles(mock_last_commit(), out=out)
    137     output = out.getvalue()
    138     self.assertEqual(output, '')
    139     self.assertEqual(files, {TEST_FILE1: FILE_MODIFIED})
    140 
    141   def test_WarnIfUntrackedFiles(self):
    142     checkstyle.git.modified_files = mock_modified_files_untracked
    143     out = StringIO()
    144     checkstyle._WarnIfUntrackedFiles(out=out)
    145     output = out.getvalue()
    146     self.assertEqual(output, checkstyle.ERROR_UNTRACKED + TEST_FILE1 + '\n\n')
    147 
    148   def test_WarnIfUntrackedFilesNoUntracked(self):
    149     checkstyle.git.modified_files = mock_modified_files_good
    150     out = StringIO()
    151     checkstyle._WarnIfUntrackedFiles(out=out)
    152     output = out.getvalue()
    153     self.assertEqual(output, '')
    154 
    155   def test_FilterFiles(self):
    156     files = {TEST_FILE1: FILE_MODIFIED, TEST_FILE2: FILE_ADDED}
    157     output = checkstyle._FilterFiles(files, None)
    158     self.assertEqual(files, output)
    159     output = checkstyle._FilterFiles(files, ['Blarg2'])
    160     self.assertEqual({TEST_FILE2: FILE_ADDED}, output)
    161     output = checkstyle._FilterFiles(files, ['Blarg'])
    162     self.assertEqual(files, output)
    163     output = checkstyle._FilterFiles(files, ['FunkyTown'])
    164     self.assertEqual({}, output)
    165 
    166 if __name__ == '__main__':
    167   unittest.main()
    168