1import filecmp 2import os 3import shutil 4import tempfile 5import unittest 6 7from test import support 8 9 10class FileCompareTestCase(unittest.TestCase): 11 def setUp(self): 12 self.name = support.TESTFN 13 self.name_same = support.TESTFN + '-same' 14 self.name_diff = support.TESTFN + '-diff' 15 data = 'Contents of file go here.\n' 16 for name in [self.name, self.name_same, self.name_diff]: 17 with open(name, 'w') as output: 18 output.write(data) 19 20 with open(self.name_diff, 'a+') as output: 21 output.write('An extra line.\n') 22 self.dir = tempfile.gettempdir() 23 24 def tearDown(self): 25 os.unlink(self.name) 26 os.unlink(self.name_same) 27 os.unlink(self.name_diff) 28 29 def test_matching(self): 30 self.assertTrue(filecmp.cmp(self.name, self.name), 31 "Comparing file to itself fails") 32 self.assertTrue(filecmp.cmp(self.name, self.name, shallow=False), 33 "Comparing file to itself fails") 34 self.assertTrue(filecmp.cmp(self.name, self.name_same), 35 "Comparing file to identical file fails") 36 self.assertTrue(filecmp.cmp(self.name, self.name_same, shallow=False), 37 "Comparing file to identical file fails") 38 39 def test_different(self): 40 self.assertFalse(filecmp.cmp(self.name, self.name_diff), 41 "Mismatched files compare as equal") 42 self.assertFalse(filecmp.cmp(self.name, self.dir), 43 "File and directory compare as equal") 44 45 def test_cache_clear(self): 46 first_compare = filecmp.cmp(self.name, self.name_same, shallow=False) 47 second_compare = filecmp.cmp(self.name, self.name_diff, shallow=False) 48 filecmp.clear_cache() 49 self.assertTrue(len(filecmp._cache) == 0, 50 "Cache not cleared after calling clear_cache") 51 52class DirCompareTestCase(unittest.TestCase): 53 def setUp(self): 54 tmpdir = tempfile.gettempdir() 55 self.dir = os.path.join(tmpdir, 'dir') 56 self.dir_same = os.path.join(tmpdir, 'dir-same') 57 self.dir_diff = os.path.join(tmpdir, 'dir-diff') 58 59 # Another dir is created under dir_same, but it has a name from the 60 # ignored list so it should not affect testing results. 61 self.dir_ignored = os.path.join(self.dir_same, '.hg') 62 63 self.caseinsensitive = os.path.normcase('A') == os.path.normcase('a') 64 data = 'Contents of file go here.\n' 65 for dir in (self.dir, self.dir_same, self.dir_diff, self.dir_ignored): 66 shutil.rmtree(dir, True) 67 os.mkdir(dir) 68 if self.caseinsensitive and dir is self.dir_same: 69 fn = 'FiLe' # Verify case-insensitive comparison 70 else: 71 fn = 'file' 72 with open(os.path.join(dir, fn), 'w') as output: 73 output.write(data) 74 75 with open(os.path.join(self.dir_diff, 'file2'), 'w') as output: 76 output.write('An extra file.\n') 77 78 def tearDown(self): 79 for dir in (self.dir, self.dir_same, self.dir_diff): 80 shutil.rmtree(dir) 81 82 def test_default_ignores(self): 83 self.assertIn('.hg', filecmp.DEFAULT_IGNORES) 84 85 def test_cmpfiles(self): 86 self.assertTrue(filecmp.cmpfiles(self.dir, self.dir, ['file']) == 87 (['file'], [], []), 88 "Comparing directory to itself fails") 89 self.assertTrue(filecmp.cmpfiles(self.dir, self.dir_same, ['file']) == 90 (['file'], [], []), 91 "Comparing directory to same fails") 92 93 # Try it with shallow=False 94 self.assertTrue(filecmp.cmpfiles(self.dir, self.dir, ['file'], 95 shallow=False) == 96 (['file'], [], []), 97 "Comparing directory to itself fails") 98 self.assertTrue(filecmp.cmpfiles(self.dir, self.dir_same, ['file'], 99 shallow=False), 100 "Comparing directory to same fails") 101 102 # Add different file2 103 with open(os.path.join(self.dir, 'file2'), 'w') as output: 104 output.write('Different contents.\n') 105 106 self.assertFalse(filecmp.cmpfiles(self.dir, self.dir_same, 107 ['file', 'file2']) == 108 (['file'], ['file2'], []), 109 "Comparing mismatched directories fails") 110 111 112 def test_dircmp(self): 113 # Check attributes for comparison of two identical directories 114 left_dir, right_dir = self.dir, self.dir_same 115 d = filecmp.dircmp(left_dir, right_dir) 116 self.assertEqual(d.left, left_dir) 117 self.assertEqual(d.right, right_dir) 118 if self.caseinsensitive: 119 self.assertEqual([d.left_list, d.right_list],[['file'], ['FiLe']]) 120 else: 121 self.assertEqual([d.left_list, d.right_list],[['file'], ['file']]) 122 self.assertEqual(d.common, ['file']) 123 self.assertEqual(d.left_only, []) 124 self.assertEqual(d.right_only, []) 125 self.assertEqual(d.same_files, ['file']) 126 self.assertEqual(d.diff_files, []) 127 expected_report = [ 128 "diff {} {}".format(self.dir, self.dir_same), 129 "Identical files : ['file']", 130 ] 131 self._assert_report(d.report, expected_report) 132 133 # Check attributes for comparison of two different directories (right) 134 left_dir, right_dir = self.dir, self.dir_diff 135 d = filecmp.dircmp(left_dir, right_dir) 136 self.assertEqual(d.left, left_dir) 137 self.assertEqual(d.right, right_dir) 138 self.assertEqual(d.left_list, ['file']) 139 self.assertEqual(d.right_list, ['file', 'file2']) 140 self.assertEqual(d.common, ['file']) 141 self.assertEqual(d.left_only, []) 142 self.assertEqual(d.right_only, ['file2']) 143 self.assertEqual(d.same_files, ['file']) 144 self.assertEqual(d.diff_files, []) 145 expected_report = [ 146 "diff {} {}".format(self.dir, self.dir_diff), 147 "Only in {} : ['file2']".format(self.dir_diff), 148 "Identical files : ['file']", 149 ] 150 self._assert_report(d.report, expected_report) 151 152 # Check attributes for comparison of two different directories (left) 153 left_dir, right_dir = self.dir, self.dir_diff 154 shutil.move( 155 os.path.join(self.dir_diff, 'file2'), 156 os.path.join(self.dir, 'file2') 157 ) 158 d = filecmp.dircmp(left_dir, right_dir) 159 self.assertEqual(d.left, left_dir) 160 self.assertEqual(d.right, right_dir) 161 self.assertEqual(d.left_list, ['file', 'file2']) 162 self.assertEqual(d.right_list, ['file']) 163 self.assertEqual(d.common, ['file']) 164 self.assertEqual(d.left_only, ['file2']) 165 self.assertEqual(d.right_only, []) 166 self.assertEqual(d.same_files, ['file']) 167 self.assertEqual(d.diff_files, []) 168 expected_report = [ 169 "diff {} {}".format(self.dir, self.dir_diff), 170 "Only in {} : ['file2']".format(self.dir), 171 "Identical files : ['file']", 172 ] 173 self._assert_report(d.report, expected_report) 174 175 # Add different file2 176 with open(os.path.join(self.dir_diff, 'file2'), 'w') as output: 177 output.write('Different contents.\n') 178 d = filecmp.dircmp(self.dir, self.dir_diff) 179 self.assertEqual(d.same_files, ['file']) 180 self.assertEqual(d.diff_files, ['file2']) 181 expected_report = [ 182 "diff {} {}".format(self.dir, self.dir_diff), 183 "Identical files : ['file']", 184 "Differing files : ['file2']", 185 ] 186 self._assert_report(d.report, expected_report) 187 188 def test_report_partial_closure(self): 189 left_dir, right_dir = self.dir, self.dir_same 190 d = filecmp.dircmp(left_dir, right_dir) 191 expected_report = [ 192 "diff {} {}".format(self.dir, self.dir_same), 193 "Identical files : ['file']", 194 ] 195 self._assert_report(d.report_partial_closure, expected_report) 196 197 def test_report_full_closure(self): 198 left_dir, right_dir = self.dir, self.dir_same 199 d = filecmp.dircmp(left_dir, right_dir) 200 expected_report = [ 201 "diff {} {}".format(self.dir, self.dir_same), 202 "Identical files : ['file']", 203 ] 204 self._assert_report(d.report_full_closure, expected_report) 205 206 def _assert_report(self, dircmp_report, expected_report_lines): 207 with support.captured_stdout() as stdout: 208 dircmp_report() 209 report_lines = stdout.getvalue().strip().split('\n') 210 self.assertEqual(report_lines, expected_report_lines) 211 212 213def test_main(): 214 support.run_unittest(FileCompareTestCase, DirCompareTestCase) 215 216if __name__ == "__main__": 217 test_main() 218