# 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 test_support
if not os.path.supports_unicode_filenames:
    raise test_support.TestSkipped, "test works only on NT+"

filenames = [
    'abc',
    u'ascii',
    u'Gr\xfc\xdf-Gott',
    u'\u0393\u03b5\u03b9\u03ac-\u03c3\u03b1\u03c2',
    u'\u0417\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435',
    u'\u306b\u307d\u3093',
    u'\u05d4\u05e9\u05e7\u05e6\u05e5\u05e1',
    u'\u66e8\u66e9\u66eb',
    u'\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(unicode(dirname)):
            os.unlink(os.path.join(dirname, fname))
        os.rmdir(dirname)

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

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

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

    def _apply_failure(self, fn, filename, expected_exception,
                       check_fn_in_exception = True):
        try:
            fn(filename)
            raise test_support.TestFailed("Expected to fail calling '%s(%r)'"
                             % (fn.__name__, filename))
        except expected_exception, details:
            if check_fn_in_exception and details.filename != filename:
                raise test_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, 'w')
            f.write((name+'\n').encode("utf-8"))
            f.close()
            os.stat(name)

    def test_listdir(self):
        f1 = os.listdir(test_support.TESTFN)
        # Printing f1 is not appropriate, as specific filenames
        # returned depend on the local encoding
        f2 = os.listdir(unicode(test_support.TESTFN,
                                sys.getfilesystemencoding()))
        f2.sort()
        print f2

    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(test_support.TESTFN,u'Gr\xfc\xdf-\u66e8\u66e9\u66eb')
        filename = u'\xdf-\u66e8\u66e9\u66eb'
        oldwd = os.getcwd()
        os.mkdir(dirname)
        os.chdir(dirname)
        f = open(filename, 'w')
        f.write((filename + '\n').encode("utf-8"))
        f.close()
        print repr(filename)
        os.access(filename,os.R_OK)
        os.remove(filename)
        os.chdir(oldwd)
        os.rmdir(dirname)

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

if __name__ == "__main__":
    test_main()
