1import ntpath
2import os
3import sys
4import unittest
5import warnings
6from test.support import TestFailed, FakePath
7from test import support, test_genericpath
8from tempfile import TemporaryFile
9
10try:
11    import nt
12except ImportError:
13    # Most tests can complete without the nt module,
14    # but for those that require it we import here.
15    nt = None
16
17def tester(fn, wantResult):
18    fn = fn.replace("\\", "\\\\")
19    gotResult = eval(fn)
20    if wantResult != gotResult:
21        raise TestFailed("%s should return: %s but returned: %s" \
22              %(str(fn), str(wantResult), str(gotResult)))
23
24    # then with bytes
25    fn = fn.replace("('", "(b'")
26    fn = fn.replace('("', '(b"')
27    fn = fn.replace("['", "[b'")
28    fn = fn.replace('["', '[b"')
29    fn = fn.replace(", '", ", b'")
30    fn = fn.replace(', "', ', b"')
31    fn = os.fsencode(fn).decode('latin1')
32    fn = fn.encode('ascii', 'backslashreplace').decode('ascii')
33    with warnings.catch_warnings():
34        warnings.simplefilter("ignore", DeprecationWarning)
35        gotResult = eval(fn)
36    if isinstance(wantResult, str):
37        wantResult = os.fsencode(wantResult)
38    elif isinstance(wantResult, tuple):
39        wantResult = tuple(os.fsencode(r) for r in wantResult)
40
41    gotResult = eval(fn)
42    if wantResult != gotResult:
43        raise TestFailed("%s should return: %s but returned: %s" \
44              %(str(fn), str(wantResult), repr(gotResult)))
45
46
47class TestNtpath(unittest.TestCase):
48    def test_splitext(self):
49        tester('ntpath.splitext("foo.ext")', ('foo', '.ext'))
50        tester('ntpath.splitext("/foo/foo.ext")', ('/foo/foo', '.ext'))
51        tester('ntpath.splitext(".ext")', ('.ext', ''))
52        tester('ntpath.splitext("\\foo.ext\\foo")', ('\\foo.ext\\foo', ''))
53        tester('ntpath.splitext("foo.ext\\")', ('foo.ext\\', ''))
54        tester('ntpath.splitext("")', ('', ''))
55        tester('ntpath.splitext("foo.bar.ext")', ('foo.bar', '.ext'))
56        tester('ntpath.splitext("xx/foo.bar.ext")', ('xx/foo.bar', '.ext'))
57        tester('ntpath.splitext("xx\\foo.bar.ext")', ('xx\\foo.bar', '.ext'))
58        tester('ntpath.splitext("c:a/b\\c.d")', ('c:a/b\\c', '.d'))
59
60    def test_splitdrive(self):
61        tester('ntpath.splitdrive("c:\\foo\\bar")',
62               ('c:', '\\foo\\bar'))
63        tester('ntpath.splitdrive("c:/foo/bar")',
64               ('c:', '/foo/bar'))
65        tester('ntpath.splitdrive("\\\\conky\\mountpoint\\foo\\bar")',
66               ('\\\\conky\\mountpoint', '\\foo\\bar'))
67        tester('ntpath.splitdrive("//conky/mountpoint/foo/bar")',
68               ('//conky/mountpoint', '/foo/bar'))
69        tester('ntpath.splitdrive("\\\\\\conky\\mountpoint\\foo\\bar")',
70            ('', '\\\\\\conky\\mountpoint\\foo\\bar'))
71        tester('ntpath.splitdrive("///conky/mountpoint/foo/bar")',
72            ('', '///conky/mountpoint/foo/bar'))
73        tester('ntpath.splitdrive("\\\\conky\\\\mountpoint\\foo\\bar")',
74               ('', '\\\\conky\\\\mountpoint\\foo\\bar'))
75        tester('ntpath.splitdrive("//conky//mountpoint/foo/bar")',
76               ('', '//conky//mountpoint/foo/bar'))
77        # Issue #19911: UNC part containing U+0130
78        self.assertEqual(ntpath.splitdrive('//conky/MOUNTPOİNT/foo/bar'),
79                         ('//conky/MOUNTPOİNT', '/foo/bar'))
80
81    def test_split(self):
82        tester('ntpath.split("c:\\foo\\bar")', ('c:\\foo', 'bar'))
83        tester('ntpath.split("\\\\conky\\mountpoint\\foo\\bar")',
84               ('\\\\conky\\mountpoint\\foo', 'bar'))
85
86        tester('ntpath.split("c:\\")', ('c:\\', ''))
87        tester('ntpath.split("\\\\conky\\mountpoint\\")',
88               ('\\\\conky\\mountpoint\\', ''))
89
90        tester('ntpath.split("c:/")', ('c:/', ''))
91        tester('ntpath.split("//conky/mountpoint/")', ('//conky/mountpoint/', ''))
92
93    def test_isabs(self):
94        tester('ntpath.isabs("c:\\")', 1)
95        tester('ntpath.isabs("\\\\conky\\mountpoint\\")', 1)
96        tester('ntpath.isabs("\\foo")', 1)
97        tester('ntpath.isabs("\\foo\\bar")', 1)
98
99    def test_commonprefix(self):
100        tester('ntpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])',
101               "/home/swen")
102        tester('ntpath.commonprefix(["\\home\\swen\\spam", "\\home\\swen\\eggs"])',
103               "\\home\\swen\\")
104        tester('ntpath.commonprefix(["/home/swen/spam", "/home/swen/spam"])',
105               "/home/swen/spam")
106
107    def test_join(self):
108        tester('ntpath.join("")', '')
109        tester('ntpath.join("", "", "")', '')
110        tester('ntpath.join("a")', 'a')
111        tester('ntpath.join("/a")', '/a')
112        tester('ntpath.join("\\a")', '\\a')
113        tester('ntpath.join("a:")', 'a:')
114        tester('ntpath.join("a:", "\\b")', 'a:\\b')
115        tester('ntpath.join("a", "\\b")', '\\b')
116        tester('ntpath.join("a", "b", "c")', 'a\\b\\c')
117        tester('ntpath.join("a\\", "b", "c")', 'a\\b\\c')
118        tester('ntpath.join("a", "b\\", "c")', 'a\\b\\c')
119        tester('ntpath.join("a", "b", "\\c")', '\\c')
120        tester('ntpath.join("d:\\", "\\pleep")', 'd:\\pleep')
121        tester('ntpath.join("d:\\", "a", "b")', 'd:\\a\\b')
122
123        tester("ntpath.join('', 'a')", 'a')
124        tester("ntpath.join('', '', '', '', 'a')", 'a')
125        tester("ntpath.join('a', '')", 'a\\')
126        tester("ntpath.join('a', '', '', '', '')", 'a\\')
127        tester("ntpath.join('a\\', '')", 'a\\')
128        tester("ntpath.join('a\\', '', '', '', '')", 'a\\')
129        tester("ntpath.join('a/', '')", 'a/')
130
131        tester("ntpath.join('a/b', 'x/y')", 'a/b\\x/y')
132        tester("ntpath.join('/a/b', 'x/y')", '/a/b\\x/y')
133        tester("ntpath.join('/a/b/', 'x/y')", '/a/b/x/y')
134        tester("ntpath.join('c:', 'x/y')", 'c:x/y')
135        tester("ntpath.join('c:a/b', 'x/y')", 'c:a/b\\x/y')
136        tester("ntpath.join('c:a/b/', 'x/y')", 'c:a/b/x/y')
137        tester("ntpath.join('c:/', 'x/y')", 'c:/x/y')
138        tester("ntpath.join('c:/a/b', 'x/y')", 'c:/a/b\\x/y')
139        tester("ntpath.join('c:/a/b/', 'x/y')", 'c:/a/b/x/y')
140        tester("ntpath.join('//computer/share', 'x/y')", '//computer/share\\x/y')
141        tester("ntpath.join('//computer/share/', 'x/y')", '//computer/share/x/y')
142        tester("ntpath.join('//computer/share/a/b', 'x/y')", '//computer/share/a/b\\x/y')
143
144        tester("ntpath.join('a/b', '/x/y')", '/x/y')
145        tester("ntpath.join('/a/b', '/x/y')", '/x/y')
146        tester("ntpath.join('c:', '/x/y')", 'c:/x/y')
147        tester("ntpath.join('c:a/b', '/x/y')", 'c:/x/y')
148        tester("ntpath.join('c:/', '/x/y')", 'c:/x/y')
149        tester("ntpath.join('c:/a/b', '/x/y')", 'c:/x/y')
150        tester("ntpath.join('//computer/share', '/x/y')", '//computer/share/x/y')
151        tester("ntpath.join('//computer/share/', '/x/y')", '//computer/share/x/y')
152        tester("ntpath.join('//computer/share/a', '/x/y')", '//computer/share/x/y')
153
154        tester("ntpath.join('c:', 'C:x/y')", 'C:x/y')
155        tester("ntpath.join('c:a/b', 'C:x/y')", 'C:a/b\\x/y')
156        tester("ntpath.join('c:/', 'C:x/y')", 'C:/x/y')
157        tester("ntpath.join('c:/a/b', 'C:x/y')", 'C:/a/b\\x/y')
158
159        for x in ('', 'a/b', '/a/b', 'c:', 'c:a/b', 'c:/', 'c:/a/b',
160                  '//computer/share', '//computer/share/', '//computer/share/a/b'):
161            for y in ('d:', 'd:x/y', 'd:/', 'd:/x/y',
162                      '//machine/common', '//machine/common/', '//machine/common/x/y'):
163                tester("ntpath.join(%r, %r)" % (x, y), y)
164
165        tester("ntpath.join('\\\\computer\\share\\', 'a', 'b')", '\\\\computer\\share\\a\\b')
166        tester("ntpath.join('\\\\computer\\share', 'a', 'b')", '\\\\computer\\share\\a\\b')
167        tester("ntpath.join('\\\\computer\\share', 'a\\b')", '\\\\computer\\share\\a\\b')
168        tester("ntpath.join('//computer/share/', 'a', 'b')", '//computer/share/a\\b')
169        tester("ntpath.join('//computer/share', 'a', 'b')", '//computer/share\\a\\b')
170        tester("ntpath.join('//computer/share', 'a/b')", '//computer/share\\a/b')
171
172    def test_normpath(self):
173        tester("ntpath.normpath('A//////././//.//B')", r'A\B')
174        tester("ntpath.normpath('A/./B')", r'A\B')
175        tester("ntpath.normpath('A/foo/../B')", r'A\B')
176        tester("ntpath.normpath('C:A//B')", r'C:A\B')
177        tester("ntpath.normpath('D:A/./B')", r'D:A\B')
178        tester("ntpath.normpath('e:A/foo/../B')", r'e:A\B')
179
180        tester("ntpath.normpath('C:///A//B')", r'C:\A\B')
181        tester("ntpath.normpath('D:///A/./B')", r'D:\A\B')
182        tester("ntpath.normpath('e:///A/foo/../B')", r'e:\A\B')
183
184        tester("ntpath.normpath('..')", r'..')
185        tester("ntpath.normpath('.')", r'.')
186        tester("ntpath.normpath('')", r'.')
187        tester("ntpath.normpath('/')", '\\')
188        tester("ntpath.normpath('c:/')", 'c:\\')
189        tester("ntpath.normpath('/../.././..')", '\\')
190        tester("ntpath.normpath('c:/../../..')", 'c:\\')
191        tester("ntpath.normpath('../.././..')", r'..\..\..')
192        tester("ntpath.normpath('K:../.././..')", r'K:..\..\..')
193        tester("ntpath.normpath('C:////a/b')", r'C:\a\b')
194        tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b')
195
196        tester("ntpath.normpath('\\\\.\\NUL')", r'\\.\NUL')
197        tester("ntpath.normpath('\\\\?\\D:/XY\\Z')", r'\\?\D:/XY\Z')
198
199    def test_expandvars(self):
200        with support.EnvironmentVarGuard() as env:
201            env.clear()
202            env["foo"] = "bar"
203            env["{foo"] = "baz1"
204            env["{foo}"] = "baz2"
205            tester('ntpath.expandvars("foo")', "foo")
206            tester('ntpath.expandvars("$foo bar")', "bar bar")
207            tester('ntpath.expandvars("${foo}bar")', "barbar")
208            tester('ntpath.expandvars("$[foo]bar")', "$[foo]bar")
209            tester('ntpath.expandvars("$bar bar")', "$bar bar")
210            tester('ntpath.expandvars("$?bar")', "$?bar")
211            tester('ntpath.expandvars("$foo}bar")', "bar}bar")
212            tester('ntpath.expandvars("${foo")', "${foo")
213            tester('ntpath.expandvars("${{foo}}")', "baz1}")
214            tester('ntpath.expandvars("$foo$foo")', "barbar")
215            tester('ntpath.expandvars("$bar$bar")', "$bar$bar")
216            tester('ntpath.expandvars("%foo% bar")', "bar bar")
217            tester('ntpath.expandvars("%foo%bar")', "barbar")
218            tester('ntpath.expandvars("%foo%%foo%")', "barbar")
219            tester('ntpath.expandvars("%%foo%%foo%foo%")', "%foo%foobar")
220            tester('ntpath.expandvars("%?bar%")', "%?bar%")
221            tester('ntpath.expandvars("%foo%%bar")', "bar%bar")
222            tester('ntpath.expandvars("\'%foo%\'%bar")', "\'%foo%\'%bar")
223            tester('ntpath.expandvars("bar\'%foo%")', "bar\'%foo%")
224
225    @unittest.skipUnless(support.FS_NONASCII, 'need support.FS_NONASCII')
226    def test_expandvars_nonascii(self):
227        def check(value, expected):
228            tester('ntpath.expandvars(%r)' % value, expected)
229        with support.EnvironmentVarGuard() as env:
230            env.clear()
231            nonascii = support.FS_NONASCII
232            env['spam'] = nonascii
233            env[nonascii] = 'ham' + nonascii
234            check('$spam bar', '%s bar' % nonascii)
235            check('$%s bar' % nonascii, '$%s bar' % nonascii)
236            check('${spam}bar', '%sbar' % nonascii)
237            check('${%s}bar' % nonascii, 'ham%sbar' % nonascii)
238            check('$spam}bar', '%s}bar' % nonascii)
239            check('$%s}bar' % nonascii, '$%s}bar' % nonascii)
240            check('%spam% bar', '%s bar' % nonascii)
241            check('%{}% bar'.format(nonascii), 'ham%s bar' % nonascii)
242            check('%spam%bar', '%sbar' % nonascii)
243            check('%{}%bar'.format(nonascii), 'ham%sbar' % nonascii)
244
245    def test_expanduser(self):
246        tester('ntpath.expanduser("test")', 'test')
247
248        with support.EnvironmentVarGuard() as env:
249            env.clear()
250            tester('ntpath.expanduser("~test")', '~test')
251
252            env['HOMEPATH'] = 'eric\\idle'
253            env['HOMEDRIVE'] = 'C:\\'
254            tester('ntpath.expanduser("~test")', 'C:\\eric\\test')
255            tester('ntpath.expanduser("~")', 'C:\\eric\\idle')
256
257            del env['HOMEDRIVE']
258            tester('ntpath.expanduser("~test")', 'eric\\test')
259            tester('ntpath.expanduser("~")', 'eric\\idle')
260
261            env.clear()
262            env['USERPROFILE'] = 'C:\\eric\\idle'
263            tester('ntpath.expanduser("~test")', 'C:\\eric\\test')
264            tester('ntpath.expanduser("~")', 'C:\\eric\\idle')
265
266            env.clear()
267            env['HOME'] = 'C:\\idle\\eric'
268            tester('ntpath.expanduser("~test")', 'C:\\idle\\test')
269            tester('ntpath.expanduser("~")', 'C:\\idle\\eric')
270
271            tester('ntpath.expanduser("~test\\foo\\bar")',
272                   'C:\\idle\\test\\foo\\bar')
273            tester('ntpath.expanduser("~test/foo/bar")',
274                   'C:\\idle\\test/foo/bar')
275            tester('ntpath.expanduser("~\\foo\\bar")',
276                   'C:\\idle\\eric\\foo\\bar')
277            tester('ntpath.expanduser("~/foo/bar")',
278                   'C:\\idle\\eric/foo/bar')
279
280    @unittest.skipUnless(nt, "abspath requires 'nt' module")
281    def test_abspath(self):
282        tester('ntpath.abspath("C:\\")', "C:\\")
283        with support.temp_cwd(support.TESTFN) as cwd_dir: # bpo-31047
284            tester('ntpath.abspath("")', cwd_dir)
285            tester('ntpath.abspath(" ")', cwd_dir + "\\ ")
286            tester('ntpath.abspath("?")', cwd_dir + "\\?")
287            drive, _ = ntpath.splitdrive(cwd_dir)
288            tester('ntpath.abspath("/abc/")', drive + "\\abc")
289
290    def test_relpath(self):
291        tester('ntpath.relpath("a")', 'a')
292        tester('ntpath.relpath(os.path.abspath("a"))', 'a')
293        tester('ntpath.relpath("a/b")', 'a\\b')
294        tester('ntpath.relpath("../a/b")', '..\\a\\b')
295        with support.temp_cwd(support.TESTFN) as cwd_dir:
296            currentdir = os.path.basename(cwd_dir)
297            tester('ntpath.relpath("a", "../b")', '..\\'+currentdir+'\\a')
298            tester('ntpath.relpath("a/b", "../c")', '..\\'+currentdir+'\\a\\b')
299        tester('ntpath.relpath("a", "b/c")', '..\\..\\a')
300        tester('ntpath.relpath("c:/foo/bar/bat", "c:/x/y")', '..\\..\\foo\\bar\\bat')
301        tester('ntpath.relpath("//conky/mountpoint/a", "//conky/mountpoint/b/c")', '..\\..\\a')
302        tester('ntpath.relpath("a", "a")', '.')
303        tester('ntpath.relpath("/foo/bar/bat", "/x/y/z")', '..\\..\\..\\foo\\bar\\bat')
304        tester('ntpath.relpath("/foo/bar/bat", "/foo/bar")', 'bat')
305        tester('ntpath.relpath("/foo/bar/bat", "/")', 'foo\\bar\\bat')
306        tester('ntpath.relpath("/", "/foo/bar/bat")', '..\\..\\..')
307        tester('ntpath.relpath("/foo/bar/bat", "/x")', '..\\foo\\bar\\bat')
308        tester('ntpath.relpath("/x", "/foo/bar/bat")', '..\\..\\..\\x')
309        tester('ntpath.relpath("/", "/")', '.')
310        tester('ntpath.relpath("/a", "/a")', '.')
311        tester('ntpath.relpath("/a/b", "/a/b")', '.')
312        tester('ntpath.relpath("c:/foo", "C:/FOO")', '.')
313
314    def test_commonpath(self):
315        def check(paths, expected):
316            tester(('ntpath.commonpath(%r)' % paths).replace('\\\\', '\\'),
317                   expected)
318        def check_error(exc, paths):
319            self.assertRaises(exc, ntpath.commonpath, paths)
320            self.assertRaises(exc, ntpath.commonpath,
321                              [os.fsencode(p) for p in paths])
322
323        self.assertRaises(ValueError, ntpath.commonpath, [])
324        check_error(ValueError, ['C:\\Program Files', 'Program Files'])
325        check_error(ValueError, ['C:\\Program Files', 'C:Program Files'])
326        check_error(ValueError, ['\\Program Files', 'Program Files'])
327        check_error(ValueError, ['Program Files', 'C:\\Program Files'])
328        check(['C:\\Program Files'], 'C:\\Program Files')
329        check(['C:\\Program Files', 'C:\\Program Files'], 'C:\\Program Files')
330        check(['C:\\Program Files\\', 'C:\\Program Files'],
331              'C:\\Program Files')
332        check(['C:\\Program Files\\', 'C:\\Program Files\\'],
333              'C:\\Program Files')
334        check(['C:\\\\Program Files', 'C:\\Program Files\\\\'],
335              'C:\\Program Files')
336        check(['C:\\.\\Program Files', 'C:\\Program Files\\.'],
337              'C:\\Program Files')
338        check(['C:\\', 'C:\\bin'], 'C:\\')
339        check(['C:\\Program Files', 'C:\\bin'], 'C:\\')
340        check(['C:\\Program Files', 'C:\\Program Files\\Bar'],
341              'C:\\Program Files')
342        check(['C:\\Program Files\\Foo', 'C:\\Program Files\\Bar'],
343              'C:\\Program Files')
344        check(['C:\\Program Files', 'C:\\Projects'], 'C:\\')
345        check(['C:\\Program Files\\', 'C:\\Projects'], 'C:\\')
346
347        check(['C:\\Program Files\\Foo', 'C:/Program Files/Bar'],
348              'C:\\Program Files')
349        check(['C:\\Program Files\\Foo', 'c:/program files/bar'],
350              'C:\\Program Files')
351        check(['c:/program files/bar', 'C:\\Program Files\\Foo'],
352              'c:\\program files')
353
354        check_error(ValueError, ['C:\\Program Files', 'D:\\Program Files'])
355
356        check(['spam'], 'spam')
357        check(['spam', 'spam'], 'spam')
358        check(['spam', 'alot'], '')
359        check(['and\\jam', 'and\\spam'], 'and')
360        check(['and\\\\jam', 'and\\spam\\\\'], 'and')
361        check(['and\\.\\jam', '.\\and\\spam'], 'and')
362        check(['and\\jam', 'and\\spam', 'alot'], '')
363        check(['and\\jam', 'and\\spam', 'and'], 'and')
364        check(['C:and\\jam', 'C:and\\spam'], 'C:and')
365
366        check([''], '')
367        check(['', 'spam\\alot'], '')
368        check_error(ValueError, ['', '\\spam\\alot'])
369
370        self.assertRaises(TypeError, ntpath.commonpath,
371                          [b'C:\\Program Files', 'C:\\Program Files\\Foo'])
372        self.assertRaises(TypeError, ntpath.commonpath,
373                          [b'C:\\Program Files', 'Program Files\\Foo'])
374        self.assertRaises(TypeError, ntpath.commonpath,
375                          [b'Program Files', 'C:\\Program Files\\Foo'])
376        self.assertRaises(TypeError, ntpath.commonpath,
377                          ['C:\\Program Files', b'C:\\Program Files\\Foo'])
378        self.assertRaises(TypeError, ntpath.commonpath,
379                          ['C:\\Program Files', b'Program Files\\Foo'])
380        self.assertRaises(TypeError, ntpath.commonpath,
381                          ['Program Files', b'C:\\Program Files\\Foo'])
382
383    def test_sameopenfile(self):
384        with TemporaryFile() as tf1, TemporaryFile() as tf2:
385            # Make sure the same file is really the same
386            self.assertTrue(ntpath.sameopenfile(tf1.fileno(), tf1.fileno()))
387            # Make sure different files are really different
388            self.assertFalse(ntpath.sameopenfile(tf1.fileno(), tf2.fileno()))
389            # Make sure invalid values don't cause issues on win32
390            if sys.platform == "win32":
391                with self.assertRaises(OSError):
392                    # Invalid file descriptors shouldn't display assert
393                    # dialogs (#4804)
394                    ntpath.sameopenfile(-1, -1)
395
396    def test_ismount(self):
397        self.assertTrue(ntpath.ismount("c:\\"))
398        self.assertTrue(ntpath.ismount("C:\\"))
399        self.assertTrue(ntpath.ismount("c:/"))
400        self.assertTrue(ntpath.ismount("C:/"))
401        self.assertTrue(ntpath.ismount("\\\\.\\c:\\"))
402        self.assertTrue(ntpath.ismount("\\\\.\\C:\\"))
403
404        self.assertTrue(ntpath.ismount(b"c:\\"))
405        self.assertTrue(ntpath.ismount(b"C:\\"))
406        self.assertTrue(ntpath.ismount(b"c:/"))
407        self.assertTrue(ntpath.ismount(b"C:/"))
408        self.assertTrue(ntpath.ismount(b"\\\\.\\c:\\"))
409        self.assertTrue(ntpath.ismount(b"\\\\.\\C:\\"))
410
411        with support.temp_dir() as d:
412            self.assertFalse(ntpath.ismount(d))
413
414        if sys.platform == "win32":
415            #
416            # Make sure the current folder isn't the root folder
417            # (or any other volume root). The drive-relative
418            # locations below cannot then refer to mount points
419            #
420            drive, path = ntpath.splitdrive(sys.executable)
421            with support.change_cwd(os.path.dirname(sys.executable)):
422                self.assertFalse(ntpath.ismount(drive.lower()))
423                self.assertFalse(ntpath.ismount(drive.upper()))
424
425            self.assertTrue(ntpath.ismount("\\\\localhost\\c$"))
426            self.assertTrue(ntpath.ismount("\\\\localhost\\c$\\"))
427
428            self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$"))
429            self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$\\"))
430
431    @unittest.skipUnless(nt, "OS helpers require 'nt' module")
432    def test_nt_helpers(self):
433        # Trivial validation that the helpers do not break, and support both
434        # unicode and bytes (UTF-8) paths
435
436        drive, path = ntpath.splitdrive(sys.executable)
437        drive = drive.rstrip(ntpath.sep) + ntpath.sep
438        self.assertEqual(drive, nt._getvolumepathname(sys.executable))
439        self.assertEqual(drive.encode(),
440                         nt._getvolumepathname(sys.executable.encode()))
441
442        cap, free = nt._getdiskusage(sys.exec_prefix)
443        self.assertGreater(cap, 0)
444        self.assertGreater(free, 0)
445        b_cap, b_free = nt._getdiskusage(sys.exec_prefix.encode())
446        # Free space may change, so only test the capacity is equal
447        self.assertEqual(b_cap, cap)
448        self.assertGreater(b_free, 0)
449
450        for path in [sys.prefix, sys.executable]:
451            final_path = nt._getfinalpathname(path)
452            self.assertIsInstance(final_path, str)
453            self.assertGreater(len(final_path), 0)
454
455            b_final_path = nt._getfinalpathname(path.encode())
456            self.assertIsInstance(b_final_path, bytes)
457            self.assertGreater(len(b_final_path), 0)
458
459class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase):
460    pathmodule = ntpath
461    attributes = ['relpath']
462
463
464class PathLikeTests(unittest.TestCase):
465
466    path = ntpath
467
468    def setUp(self):
469        self.file_name = support.TESTFN.lower()
470        self.file_path = FakePath(support.TESTFN)
471        self.addCleanup(support.unlink, self.file_name)
472        with open(self.file_name, 'xb', 0) as file:
473            file.write(b"test_ntpath.PathLikeTests")
474
475    def assertPathEqual(self, func):
476        self.assertEqual(func(self.file_path), func(self.file_name))
477
478    def test_path_normcase(self):
479        self.assertPathEqual(self.path.normcase)
480
481    def test_path_isabs(self):
482        self.assertPathEqual(self.path.isabs)
483
484    def test_path_join(self):
485        self.assertEqual(self.path.join('a', FakePath('b'), 'c'),
486                         self.path.join('a', 'b', 'c'))
487
488    def test_path_split(self):
489        self.assertPathEqual(self.path.split)
490
491    def test_path_splitext(self):
492        self.assertPathEqual(self.path.splitext)
493
494    def test_path_splitdrive(self):
495        self.assertPathEqual(self.path.splitdrive)
496
497    def test_path_basename(self):
498        self.assertPathEqual(self.path.basename)
499
500    def test_path_dirname(self):
501        self.assertPathEqual(self.path.dirname)
502
503    def test_path_islink(self):
504        self.assertPathEqual(self.path.islink)
505
506    def test_path_lexists(self):
507        self.assertPathEqual(self.path.lexists)
508
509    def test_path_ismount(self):
510        self.assertPathEqual(self.path.ismount)
511
512    def test_path_expanduser(self):
513        self.assertPathEqual(self.path.expanduser)
514
515    def test_path_expandvars(self):
516        self.assertPathEqual(self.path.expandvars)
517
518    def test_path_normpath(self):
519        self.assertPathEqual(self.path.normpath)
520
521    def test_path_abspath(self):
522        self.assertPathEqual(self.path.abspath)
523
524    def test_path_realpath(self):
525        self.assertPathEqual(self.path.realpath)
526
527    def test_path_relpath(self):
528        self.assertPathEqual(self.path.relpath)
529
530    def test_path_commonpath(self):
531        common_path = self.path.commonpath([self.file_path, self.file_name])
532        self.assertEqual(common_path, self.file_name)
533
534    def test_path_isdir(self):
535        self.assertPathEqual(self.path.isdir)
536
537
538if __name__ == "__main__":
539    unittest.main()
540