# Test the Unicode versions of normal file functions
# open, os.open, os.stat. os.listdir, os.rename, os.remove, os.mkdir, os.chdir, os.rmdir
import sys, os, unittest
from test import support
if not os.path.supports_unicode_filenames:
    raise unittest.SkipTest("test works only on NT+")

filenames = [
    'abc',
    'ascii',
    'Gr\xfc\xdf-Gott',
    '\u0393\u03b5\u03b9\u03ac-\u03c3\u03b1\u03c2',
    '\u0417\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435',
    '\u306b\u307d\u3093',
    '\u05d4\u05e9\u05e7\u05e6\u05e5\u05e1',
    '\u66e8\u66e9\u66eb',
    '\u66e8\u05e9\u3093\u0434\u0393\xdf',
    ]

# Destroy directory dirname and all files under it, to one level.
def deltree(dirname):
    # Don't hide legitimate errors:  if one of these suckers exists, it's
    # an error if we can't remove it.
    if os.path.exists(dirname):
        # must pass unicode to os.listdir() so we get back unicode results.
        for fname in os.listdir(str(dirname)):
            os.unlink(os.path.join(dirname, fname))
        os.rmdir(dirname)

class UnicodeFileTests(unittest.TestCase):
    files = [os.path.join(support.TESTFN, f) for f in filenames]

    def setUp(self):
        try:
            os.mkdir(support.TESTFN)
        except OSError:
            pass
        for name in self.files:
            f = open(name, 'wb')
            f.write((name+'\n').encode("utf-8"))
            f.close()
            os.stat(name)

    def tearDown(self):
        deltree(support.TESTFN)

    def _apply_failure(self, fn, filename, expected_exception,
                       check_fn_in_exception = True):
        try:
            fn(filename)
            raise support.TestFailed("Expected to fail calling '%s(%r)'"
                             % (fn.__name__, filename))
        except expected_exception as details:
            if check_fn_in_exception and details.filename != filename:
                raise support.TestFailed("Function '%s(%r) failed with "
                                 "bad filename in the exception: %r"
                                 % (fn.__name__, filename,
                                    details.filename))

    def test_failures(self):
        # Pass non-existing Unicode filenames all over the place.
        for name in self.files:
            name = "not_" + name
            self._apply_failure(open, name, IOError)
            self._apply_failure(os.stat, name, OSError)
            self._apply_failure(os.chdir, name, OSError)
            self._apply_failure(os.rmdir, name, OSError)
            self._apply_failure(os.remove, name, OSError)
            # listdir may append a wildcard to the filename, so dont check
            self._apply_failure(os.listdir, name, OSError, False)

    def test_open(self):
        for name in self.files:
            f = open(name, 'wb')
            f.write((name+'\n').encode("utf-8"))
            f.close()
            os.stat(name)

    def test_listdir(self):
        f1 = os.listdir(support.TESTFN)
        f2 = os.listdir(str(support.TESTFN.encode("utf-8"),
                                sys.getfilesystemencoding()))
        sf2 = set("\\".join((str(support.TESTFN), f))
                  for f in f2)
        self.assertEqual(len(f1), len(self.files))
        self.assertEqual(sf2, set(self.files))

    def test_rename(self):
        for name in self.files:
            os.rename(name,"tmp")
            os.rename("tmp",name)

    def test_directory(self):
        dirname = os.path.join(support.TESTFN,'Gr\xfc\xdf-\u66e8\u66e9\u66eb')
        filename = '\xdf-\u66e8\u66e9\u66eb'
        oldwd = os.getcwd()
        os.mkdir(dirname)
        os.chdir(dirname)
        f = open(filename, 'wb')
        f.write((filename + '\n').encode("utf-8"))
        f.close()
        os.access(filename,os.R_OK)
        os.remove(filename)
        os.chdir(oldwd)
        os.rmdir(dirname)

def test_main():
    try:
        support.run_unittest(UnicodeFileTests)
    finally:
        deltree(support.TESTFN)

if __name__ == "__main__":
    test_main()
