test_filecmp.py 10 KB

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