PageRenderTime 22ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/scandir/test/test_scandir.py

https://gitlab.com/Smileyt/KomodoEdit
Python | 279 lines | 207 code | 59 blank | 13 comment | 44 complexity | d6553dacfd818a82e9eeddf67daeef72 MD5 | raw file
  1. """Tests for scandir.scandir()."""
  2. import os
  3. import shutil
  4. import sys
  5. import time
  6. import unittest
  7. try:
  8. import scandir
  9. has_scandir = True
  10. except ImportError:
  11. has_scandir = False
  12. FILE_ATTRIBUTE_DIRECTORY = 16
  13. TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), 'testdir'))
  14. IS_PY3 = sys.version_info >= (3, 0)
  15. if IS_PY3:
  16. int_types = int
  17. else:
  18. int_types = (int, long)
  19. str = unicode
  20. if hasattr(os, 'symlink'):
  21. try:
  22. link_name = os.path.join(os.path.dirname(__file__), '_testlink')
  23. os.symlink(__file__, link_name)
  24. os.remove(link_name)
  25. symlinks_supported = True
  26. except NotImplementedError:
  27. # Windows versions before Vista don't support symbolic links
  28. symlinks_supported = False
  29. else:
  30. symlinks_supported = False
  31. def create_file(path, contents='1234'):
  32. with open(path, 'w') as f:
  33. f.write(contents)
  34. def setup_main():
  35. join = os.path.join
  36. try:
  37. os.mkdir(TEST_PATH)
  38. except Exception as e:
  39. print(repr(e), e.filename)
  40. import time
  41. time.sleep(500)
  42. raise
  43. os.mkdir(join(TEST_PATH, 'subdir'))
  44. create_file(join(TEST_PATH, 'file1.txt'))
  45. create_file(join(TEST_PATH, 'file2.txt'), contents='12345678')
  46. os.mkdir(join(TEST_PATH, 'subdir', u'unidir\u018F'))
  47. create_file(join(TEST_PATH, 'subdir', 'file1.txt'))
  48. create_file(join(TEST_PATH, 'subdir', u'unicod\u018F.txt'))
  49. create_file(join(TEST_PATH, 'subdir', u'unidir\u018F', 'file1.txt'))
  50. os.mkdir(join(TEST_PATH, 'linkdir'))
  51. def setup_symlinks():
  52. join = os.path.join
  53. os.mkdir(join(TEST_PATH, 'linkdir', 'linksubdir'))
  54. create_file(join(TEST_PATH, 'linkdir', 'file1.txt'))
  55. os.symlink(os.path.abspath(join(TEST_PATH, 'linkdir', 'file1.txt')),
  56. join(TEST_PATH, 'linkdir', 'link_to_file'))
  57. dir_name = os.path.abspath(join(TEST_PATH, 'linkdir', 'linksubdir'))
  58. dir_link = join(TEST_PATH, 'linkdir', 'link_to_dir')
  59. if sys.version_info >= (3, 3):
  60. # "target_is_directory" was only added in Python 3.3
  61. os.symlink(dir_name, dir_link, target_is_directory=True)
  62. else:
  63. os.symlink(dir_name, dir_link)
  64. def teardown():
  65. try:
  66. shutil.rmtree(TEST_PATH)
  67. except OSError:
  68. # why does the above fail sometimes?
  69. time.sleep(0.1)
  70. shutil.rmtree(TEST_PATH)
  71. class TestMixin(object):
  72. def setUp(self):
  73. if not os.path.exists(TEST_PATH):
  74. setup_main()
  75. if symlinks_supported and not os.path.exists(
  76. os.path.join(TEST_PATH, 'linkdir', 'linksubdir')):
  77. setup_symlinks()
  78. if not hasattr(unittest.TestCase, 'skipTest'):
  79. def skipTest(self, reason):
  80. sys.stdout.write('skipped {0!r} '.format(reason))
  81. def test_basic(self):
  82. entries = sorted(self.scandir_func(TEST_PATH), key=lambda e: e.name)
  83. self.assertEqual([(e.name, e.is_dir()) for e in entries],
  84. [('file1.txt', False), ('file2.txt', False),
  85. ('linkdir', True), ('subdir', True)])
  86. self.assertEqual([e.path for e in entries],
  87. [os.path.join(TEST_PATH, e.name) for e in entries])
  88. def test_dir_entry(self):
  89. entries = dict((e.name, e) for e in self.scandir_func(TEST_PATH))
  90. e = entries['file1.txt']
  91. self.assertEqual([e.is_dir(), e.is_file(), e.is_symlink()], [False, True, False])
  92. e = entries['file2.txt']
  93. self.assertEqual([e.is_dir(), e.is_file(), e.is_symlink()], [False, True, False])
  94. e = entries['subdir']
  95. self.assertEqual([e.is_dir(), e.is_file(), e.is_symlink()], [True, False, False])
  96. self.assertEqual(entries['file1.txt'].stat().st_size, 4)
  97. self.assertEqual(entries['file2.txt'].stat().st_size, 8)
  98. def test_stat(self):
  99. entries = list(self.scandir_func(TEST_PATH))
  100. for entry in entries:
  101. os_stat = os.stat(os.path.join(TEST_PATH, entry.name))
  102. scandir_stat = entry.stat()
  103. self.assertEqual(os_stat.st_mode, scandir_stat.st_mode)
  104. self.assertEqual(int(os_stat.st_mtime), int(scandir_stat.st_mtime))
  105. self.assertEqual(int(os_stat.st_ctime), int(scandir_stat.st_ctime))
  106. if entry.is_file():
  107. self.assertEqual(os_stat.st_size, scandir_stat.st_size)
  108. def test_returns_iter(self):
  109. it = self.scandir_func(TEST_PATH)
  110. entry = next(it)
  111. assert hasattr(entry, 'name')
  112. def check_file_attributes(self, result):
  113. self.assertTrue(hasattr(result, 'st_file_attributes'))
  114. self.assertTrue(isinstance(result.st_file_attributes, int_types))
  115. self.assertTrue(0 <= result.st_file_attributes <= 0xFFFFFFFF)
  116. def test_file_attributes(self):
  117. if sys.platform != 'win32' or not self.has_file_attributes:
  118. # st_file_attributes is Win32 specific (but can't use
  119. # unittest.skipUnless on Python 2.6)
  120. return self.skipTest('st_file_attributes not supported')
  121. entries = dict((e.name, e) for e in self.scandir_func(TEST_PATH))
  122. # test st_file_attributes on a file (FILE_ATTRIBUTE_DIRECTORY not set)
  123. result = entries['file1.txt'].stat()
  124. self.check_file_attributes(result)
  125. self.assertEqual(result.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY, 0)
  126. # test st_file_attributes on a directory (FILE_ATTRIBUTE_DIRECTORY set)
  127. result = entries['subdir'].stat()
  128. self.check_file_attributes(result)
  129. self.assertEqual(result.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY,
  130. FILE_ATTRIBUTE_DIRECTORY)
  131. def test_path(self):
  132. entries = sorted(self.scandir_func(TEST_PATH), key=lambda e: e.name)
  133. self.assertEqual([os.path.basename(e.name) for e in entries],
  134. ['file1.txt', 'file2.txt', 'linkdir', 'subdir'])
  135. self.assertEqual([os.path.normpath(os.path.join(TEST_PATH, e.name)) for e in entries],
  136. [os.path.normpath(e.path) for e in entries])
  137. def test_symlink(self):
  138. if not symlinks_supported:
  139. return self.skipTest('symbolic links not supported')
  140. entries = sorted(self.scandir_func(os.path.join(TEST_PATH, 'linkdir')),
  141. key=lambda e: e.name)
  142. self.assertEqual([(e.name, e.is_symlink()) for e in entries],
  143. [('file1.txt', False),
  144. ('link_to_dir', True),
  145. ('link_to_file', True),
  146. ('linksubdir', False)])
  147. self.assertEqual([(e.name, e.is_file(), e.is_file(follow_symlinks=False))
  148. for e in entries],
  149. [('file1.txt', True, True),
  150. ('link_to_dir', False, False),
  151. ('link_to_file', True, False),
  152. ('linksubdir', False, False)])
  153. self.assertEqual([(e.name, e.is_dir(), e.is_dir(follow_symlinks=False))
  154. for e in entries],
  155. [('file1.txt', False, False),
  156. ('link_to_dir', True, False),
  157. ('link_to_file', False, False),
  158. ('linksubdir', True, True)])
  159. def test_bytes(self):
  160. # Check that unicode filenames are returned correctly as bytes in output
  161. path = os.path.join(TEST_PATH, 'subdir').encode(sys.getfilesystemencoding(), 'replace')
  162. self.assertTrue(isinstance(path, bytes))
  163. entries = [e for e in self.scandir_func(path) if e.name.startswith(b'unicod')]
  164. self.assertEqual(len(entries), 1)
  165. entry = entries[0]
  166. self.assertTrue(isinstance(entry.name, bytes))
  167. self.assertTrue(isinstance(entry.path, bytes))
  168. # b'unicod?.txt' on Windows, b'unicod\xc6\x8f.txt' (UTF-8) or similar on POSIX
  169. entry_name = u'unicod\u018f.txt'.encode(sys.getfilesystemencoding(), 'replace')
  170. self.assertEqual(entry.name, entry_name)
  171. self.assertEqual(entry.path, os.path.join(path, entry_name))
  172. def test_unicode(self):
  173. # Check that unicode filenames are returned correctly as (unicode) str in output
  174. path = os.path.join(TEST_PATH, 'subdir')
  175. if not IS_PY3:
  176. path = path.decode(sys.getfilesystemencoding(), 'replace')
  177. self.assertTrue(isinstance(path, str))
  178. entries = [e for e in self.scandir_func(path) if e.name.startswith('unicod')]
  179. self.assertEqual(len(entries), 1)
  180. entry = entries[0]
  181. self.assertTrue(isinstance(entry.name, str))
  182. self.assertTrue(isinstance(entry.path, str))
  183. entry_name = u'unicod\u018f.txt'
  184. self.assertEqual(entry.name, entry_name)
  185. self.assertEqual(entry.path, os.path.join(path, u'unicod\u018f.txt'))
  186. # Check that it handles unicode input properly
  187. path = os.path.join(TEST_PATH, 'subdir', u'unidir\u018f')
  188. self.assertTrue(isinstance(path, str))
  189. entries = list(self.scandir_func(path))
  190. self.assertEqual(len(entries), 1)
  191. entry = entries[0]
  192. self.assertTrue(isinstance(entry.name, str))
  193. self.assertTrue(isinstance(entry.path, str))
  194. self.assertEqual(entry.name, 'file1.txt')
  195. self.assertEqual(entry.path, os.path.join(path, 'file1.txt'))
  196. # TODO ben: add tests for file not found is_dir/is_file/stat
  197. if has_scandir:
  198. class TestScandirGeneric(TestMixin, unittest.TestCase):
  199. def setUp(self):
  200. self.scandir_func = scandir.scandir_generic
  201. self.has_file_attributes = False
  202. TestMixin.setUp(self)
  203. if hasattr(scandir, 'scandir_python'):
  204. class TestScandirPython(TestMixin, unittest.TestCase):
  205. def setUp(self):
  206. self.scandir_func = scandir.scandir_python
  207. self.has_file_attributes = True
  208. TestMixin.setUp(self)
  209. if hasattr(scandir, 'scandir_c'):
  210. class TestScandirC(TestMixin, unittest.TestCase):
  211. def setUp(self):
  212. self.scandir_func = scandir.scandir_c
  213. self.has_file_attributes = True
  214. TestMixin.setUp(self)
  215. if hasattr(os, 'scandir'):
  216. class TestScandirOS(TestMixin, unittest.TestCase):
  217. def setUp(self):
  218. self.scandir_func = os.scandir
  219. self.has_file_attributes = True
  220. TestMixin.setUp(self)