summaryrefslogtreecommitdiff
path: root/bzrlib/tests/test_nonascii.py
diff options
context:
space:
mode:
Diffstat (limited to 'bzrlib/tests/test_nonascii.py')
-rw-r--r--bzrlib/tests/test_nonascii.py194
1 files changed, 194 insertions, 0 deletions
diff --git a/bzrlib/tests/test_nonascii.py b/bzrlib/tests/test_nonascii.py
new file mode 100644
index 0000000..992fa77
--- /dev/null
+++ b/bzrlib/tests/test_nonascii.py
@@ -0,0 +1,194 @@
+# Copyright (C) 2005, 2006, 2008, 2009, 2011 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Test that various operations work in a non-ASCII environment."""
+
+import os
+import sys
+from unicodedata import normalize
+
+from bzrlib import osutils
+from bzrlib.osutils import pathjoin
+from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
+
+
+class NonAsciiTest(TestCaseWithTransport):
+
+ def test_add_in_nonascii_branch(self):
+ """Test adding in a non-ASCII branch."""
+ br_dir = u"\u1234"
+ try:
+ wt = self.make_branch_and_tree(br_dir)
+ except UnicodeEncodeError:
+ raise TestSkipped("filesystem can't accomodate nonascii names")
+ return
+ with file(pathjoin(br_dir, "a"), "w") as f: f.write("hello")
+ wt.add(["a"], ["a-id"])
+
+
+a_circle_c = u'\xe5'
+a_circle_d = u'a\u030a'
+a_dots_c = u'\xe4'
+a_dots_d = u'a\u0308'
+z_umlat_c = u'\u017d'
+z_umlat_d = u'Z\u030c'
+squared_c = u'\xbc' # This gets mapped to '2' if we use NFK[CD]
+squared_d = u'\xbc'
+quarter_c = u'\xb2' # Gets mapped to u'1\u20444' (1/4) if we use NFK[CD]
+quarter_d = u'\xb2'
+
+
+class TestNormalization(TestCase):
+ """Verify that we have our normalizations correct."""
+
+ def test_normalize(self):
+ self.assertEqual(a_circle_d, normalize('NFD', a_circle_c))
+ self.assertEqual(a_circle_c, normalize('NFC', a_circle_d))
+ self.assertEqual(a_dots_d, normalize('NFD', a_dots_c))
+ self.assertEqual(a_dots_c, normalize('NFC', a_dots_d))
+ self.assertEqual(z_umlat_d, normalize('NFD', z_umlat_c))
+ self.assertEqual(z_umlat_c, normalize('NFC', z_umlat_d))
+ self.assertEqual(squared_d, normalize('NFC', squared_c))
+ self.assertEqual(squared_c, normalize('NFD', squared_d))
+ self.assertEqual(quarter_d, normalize('NFC', quarter_c))
+ self.assertEqual(quarter_c, normalize('NFD', quarter_d))
+
+
+class NormalizedFilename(TestCaseWithTransport):
+ """Test normalized_filename and associated helpers"""
+
+ def test__accessible_normalized_filename(self):
+ anf = osutils._accessible_normalized_filename
+ # normalized_filename should allow plain ascii strings
+ # not just unicode strings
+ self.assertEqual((u'ascii', True), anf('ascii'))
+ self.assertEqual((a_circle_c, True), anf(a_circle_c))
+ self.assertEqual((a_circle_c, True), anf(a_circle_d))
+ self.assertEqual((a_dots_c, True), anf(a_dots_c))
+ self.assertEqual((a_dots_c, True), anf(a_dots_d))
+ self.assertEqual((z_umlat_c, True), anf(z_umlat_c))
+ self.assertEqual((z_umlat_c, True), anf(z_umlat_d))
+ self.assertEqual((squared_c, True), anf(squared_c))
+ self.assertEqual((squared_c, True), anf(squared_d))
+ self.assertEqual((quarter_c, True), anf(quarter_c))
+ self.assertEqual((quarter_c, True), anf(quarter_d))
+
+ def test__inaccessible_normalized_filename(self):
+ inf = osutils._inaccessible_normalized_filename
+ # normalized_filename should allow plain ascii strings
+ # not just unicode strings
+ self.assertEqual((u'ascii', True), inf('ascii'))
+ self.assertEqual((a_circle_c, True), inf(a_circle_c))
+ self.assertEqual((a_circle_c, False), inf(a_circle_d))
+ self.assertEqual((a_dots_c, True), inf(a_dots_c))
+ self.assertEqual((a_dots_c, False), inf(a_dots_d))
+ self.assertEqual((z_umlat_c, True), inf(z_umlat_c))
+ self.assertEqual((z_umlat_c, False), inf(z_umlat_d))
+ self.assertEqual((squared_c, True), inf(squared_c))
+ self.assertEqual((squared_c, True), inf(squared_d))
+ self.assertEqual((quarter_c, True), inf(quarter_c))
+ self.assertEqual((quarter_c, True), inf(quarter_d))
+
+ def test_functions(self):
+ if osutils.normalizes_filenames():
+ self.assertEqual(osutils.normalized_filename,
+ osutils._accessible_normalized_filename)
+ else:
+ self.assertEqual(osutils.normalized_filename,
+ osutils._inaccessible_normalized_filename)
+
+ def test_platform(self):
+ # With FAT32 and certain encodings on win32
+ # a_circle_c and a_dots_c actually map to the same file
+ # adding a suffix kicks in the 'preserving but insensitive'
+ # route, and maintains the right files
+ files = [a_circle_c+'.1', a_dots_c+'.2', z_umlat_c+'.3']
+ try:
+ self.build_tree(files)
+ except UnicodeError:
+ raise TestSkipped("filesystem cannot create unicode files")
+
+ if sys.platform == 'darwin':
+ expected = sorted([a_circle_d+'.1', a_dots_d+'.2', z_umlat_d+'.3'])
+ else:
+ expected = sorted(files)
+
+ present = sorted(os.listdir(u'.'))
+ self.assertEqual(expected, present)
+
+ def test_access_normalized(self):
+ # We should always be able to access files created with
+ # normalized filenames
+ # With FAT32 and certain encodings on win32
+ # a_circle_c and a_dots_c actually map to the same file
+ # adding a suffix kicks in the 'preserving but insensitive'
+ # route, and maintains the right files
+ files = [a_circle_c+'.1', a_dots_c+'.2', z_umlat_c+'.3',
+ squared_c+'.4', quarter_c+'.5']
+ try:
+ self.build_tree(files, line_endings='native')
+ except UnicodeError:
+ raise TestSkipped("filesystem cannot create unicode files")
+
+ for fname in files:
+ # We should get an exception if we can't open the file at
+ # this location.
+ path, can_access = osutils.normalized_filename(fname)
+
+ self.assertEqual(path, fname)
+ self.assertTrue(can_access)
+
+ f = open(path, 'rb')
+ try:
+ # Check the contents
+ shouldbe = 'contents of %s%s' % (path.encode('utf8'),
+ os.linesep)
+ actual = f.read()
+ finally:
+ f.close()
+ self.assertEqual(shouldbe, actual,
+ 'contents of %r is incorrect: %r != %r'
+ % (path, shouldbe, actual))
+
+ def test_access_non_normalized(self):
+ # Sometimes we can access non-normalized files by their normalized
+ # path, verify that normalized_filename returns the right info
+ files = [a_circle_d+'.1', a_dots_d+'.2', z_umlat_d+'.3']
+
+ try:
+ self.build_tree(files)
+ except UnicodeError:
+ raise TestSkipped("filesystem cannot create unicode files")
+
+ for fname in files:
+ # We should get an exception if we can't open the file at
+ # this location.
+ path, can_access = osutils.normalized_filename(fname)
+
+ self.assertNotEqual(path, fname)
+
+ # We should always be able to access them from the name
+ # they were created with
+ f = open(fname, 'rb')
+ f.close()
+
+ # And normalized_filename sholud tell us correctly if we can
+ # access them by an alternate name
+ if can_access:
+ f = open(path, 'rb')
+ f.close()
+ else:
+ self.assertRaises(IOError, open, path, 'rb')