1
# Copyright (C) 2005, 2006, 2008, 2009, 2011 Canonical Ltd
1
# Copyright (C) 2005 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
"""Test that various operations work in a non-ASCII environment."""
21
21
from unicodedata import normalize
23
from .. import osutils
24
from ..osutils import pathjoin
25
from . import TestCase, TestCaseWithTransport, TestSkipped
23
from bzrlib import osutils
24
from bzrlib.osutils import pathjoin
25
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
26
from bzrlib.workingtree import WorkingTree
28
29
class NonAsciiTest(TestCaseWithTransport):
35
36
except UnicodeEncodeError:
36
37
raise TestSkipped("filesystem can't accomodate nonascii names")
38
with open(pathjoin(br_dir, "a"), "w") as f:
40
wt.add(["a"], [b"a-id"])
39
file(pathjoin(br_dir, "a"), "w").write("hello")
40
wt.add(["a"], ["a-id"])
43
43
a_circle_c = u'\xe5'
46
46
a_dots_d = u'a\u0308'
47
47
z_umlat_c = u'\u017d'
48
48
z_umlat_d = u'Z\u030c'
49
squared_c = u'\xbc' # This gets mapped to '2' if we use NFK[CD]
51
quarter_c = u'\xb2' # Gets mapped to u'1\u20444' (1/4) if we use NFK[CD]
55
51
class TestNormalization(TestCase):
56
52
"""Verify that we have our normalizations correct."""
58
54
def test_normalize(self):
59
self.assertEqual(a_circle_d, normalize('NFD', a_circle_c))
60
self.assertEqual(a_circle_c, normalize('NFC', a_circle_d))
61
self.assertEqual(a_dots_d, normalize('NFD', a_dots_c))
62
self.assertEqual(a_dots_c, normalize('NFC', a_dots_d))
63
self.assertEqual(z_umlat_d, normalize('NFD', z_umlat_c))
64
self.assertEqual(z_umlat_c, normalize('NFC', z_umlat_d))
65
self.assertEqual(squared_d, normalize('NFC', squared_c))
66
self.assertEqual(squared_c, normalize('NFD', squared_d))
67
self.assertEqual(quarter_d, normalize('NFC', quarter_c))
68
self.assertEqual(quarter_c, normalize('NFD', quarter_d))
55
self.assertEqual(a_circle_d, normalize('NFKD', a_circle_c))
56
self.assertEqual(a_circle_c, normalize('NFKC', a_circle_d))
57
self.assertEqual(a_dots_d, normalize('NFKD', a_dots_c))
58
self.assertEqual(a_dots_c, normalize('NFKC', a_dots_d))
59
self.assertEqual(z_umlat_d, normalize('NFKD', z_umlat_c))
60
self.assertEqual(z_umlat_c, normalize('NFKC', z_umlat_d))
71
63
class NormalizedFilename(TestCaseWithTransport):
82
74
self.assertEqual((a_dots_c, True), anf(a_dots_d))
83
75
self.assertEqual((z_umlat_c, True), anf(z_umlat_c))
84
76
self.assertEqual((z_umlat_c, True), anf(z_umlat_d))
85
self.assertEqual((squared_c, True), anf(squared_c))
86
self.assertEqual((squared_c, True), anf(squared_d))
87
self.assertEqual((quarter_c, True), anf(quarter_c))
88
self.assertEqual((quarter_c, True), anf(quarter_d))
90
78
def test__inaccessible_normalized_filename(self):
91
79
inf = osutils._inaccessible_normalized_filename
98
86
self.assertEqual((a_dots_c, False), inf(a_dots_d))
99
87
self.assertEqual((z_umlat_c, True), inf(z_umlat_c))
100
88
self.assertEqual((z_umlat_c, False), inf(z_umlat_d))
101
self.assertEqual((squared_c, True), inf(squared_c))
102
self.assertEqual((squared_c, True), inf(squared_d))
103
self.assertEqual((quarter_c, True), inf(quarter_c))
104
self.assertEqual((quarter_c, True), inf(quarter_d))
106
90
def test_functions(self):
107
91
if osutils.normalizes_filenames():
116
100
# a_circle_c and a_dots_c actually map to the same file
117
101
# adding a suffix kicks in the 'preserving but insensitive'
118
102
# route, and maintains the right files
119
files = [a_circle_c + '.1', a_dots_c + '.2', z_umlat_c + '.3']
103
files = [a_circle_c+'.1', a_dots_c+'.2', z_umlat_c+'.3']
121
105
self.build_tree(files)
122
106
except UnicodeError:
123
107
raise TestSkipped("filesystem cannot create unicode files")
125
109
if sys.platform == 'darwin':
127
[a_circle_d + '.1', a_dots_d + '.2', z_umlat_d + '.3'])
110
expected = sorted([a_circle_d+'.1', a_dots_d+'.2', z_umlat_d+'.3'])
129
112
expected = sorted(files)
132
115
self.assertEqual(expected, present)
134
117
def test_access_normalized(self):
135
# We should always be able to access files created with
118
# We should always be able to access files created with
136
119
# normalized filenames
137
120
# With FAT32 and certain encodings on win32
138
121
# a_circle_c and a_dots_c actually map to the same file
139
122
# adding a suffix kicks in the 'preserving but insensitive'
140
123
# route, and maintains the right files
141
files = [a_circle_c + '.1', a_dots_c + '.2', z_umlat_c + '.3',
142
squared_c + '.4', quarter_c + '.5']
124
files = [a_circle_c+'.1', a_dots_c+'.2', z_umlat_c+'.3']
144
126
self.build_tree(files, line_endings='native')
145
127
except UnicodeError:
153
135
self.assertEqual(path, fname)
154
136
self.assertTrue(can_access)
156
with open(path, 'rb') as f:
157
140
# Check the contents
158
shouldbe = b'contents of %s%s' % (path.encode('utf8'),
159
os.linesep.encode('utf-8'))
141
shouldbe = 'contents of %s%s' % (path.encode('utf8'),
160
143
actual = f.read()
161
self.assertEqual(shouldbe, actual,
146
self.assertEqual(shouldbe, actual,
162
147
'contents of %r is incorrect: %r != %r'
163
148
% (path, shouldbe, actual))
165
150
def test_access_non_normalized(self):
166
151
# Sometimes we can access non-normalized files by their normalized
167
152
# path, verify that normalized_filename returns the right info
168
files = [a_circle_d + '.1', a_dots_d + '.2', z_umlat_d + '.3']
153
files = [a_circle_d+'.1', a_dots_d+'.2', z_umlat_d+'.3']
171
156
self.build_tree(files)