1
# Copyright (C) 2005 by Canonical Ltd
1
# Copyright (C) 2005, 2006, 2007 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
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
11
# GNU General Public License for more details.
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
from cStringIO import StringIO
20
from bzrlib.branch import Branch
21
from bzrlib.diff import internal_diff
22
from bzrlib.inventory import Inventory, ROOT_ID
23
import bzrlib.inventory as inventory
24
from bzrlib.osutils import has_symlinks
25
from bzrlib.selftest import TestCase, TestCaseInTempDir
28
class TestInventory(TestCase):
30
def test_is_within(self):
31
from bzrlib.osutils import is_inside_any
33
SRC_FOO_C = os.path.join('src', 'foo.c')
34
for dirs, fn in [(['src', 'doc'], SRC_FOO_C),
38
self.assert_(is_inside_any(dirs, fn))
40
for dirs, fn in [(['src'], 'srccontrol'),
41
(['src'], 'srccontrol/foo')]:
42
self.assertFalse(is_inside_any(dirs, fn))
45
"""Test detection of files within selected directories."""
48
for args in [('src', 'directory', 'src-id'),
49
('doc', 'directory', 'doc-id'),
50
('src/hello.c', 'file'),
51
('src/bye.c', 'file', 'bye-id'),
52
('Makefile', 'file')]:
55
self.assertEqual(inv.path2id('src'), 'src-id')
56
self.assertEqual(inv.path2id('src/bye.c'), 'bye-id')
58
self.assert_('src-id' in inv)
61
def test_version(self):
62
"""Inventory remembers the text's version."""
64
ie = inv.add_path('foo.txt', 'file')
68
class TestInventoryEntry(TestCaseInTempDir):
18
from bzrlib import errors, inventory, osutils
19
from bzrlib.inventory import (Inventory, ROOT_ID, InventoryFile,
20
InventoryDirectory, InventoryEntry, TreeReference)
21
from bzrlib.tests import TestCase
24
class TestInventoryEntry(TestCase):
70
26
def test_file_kind_character(self):
71
27
file = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
130
86
link = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
131
87
self.failIf(link.has_text())
134
class TestEntryDiffing(TestCaseInTempDir):
137
super(TestEntryDiffing, self).setUp()
138
self.branch = Branch.initialize('.')
139
print >> open('file', 'wb'), 'foo'
140
self.branch.add(['file'], ['fileid'])
142
os.symlink('target1', 'symlink')
143
self.branch.add(['symlink'], ['linkid'])
144
self.branch.commit('message_1', rev_id = '1')
145
print >> open('file', 'wb'), 'bar'
148
os.symlink('target2', 'symlink')
149
self.tree_1 = self.branch.revision_tree('1')
150
self.inv_1 = self.branch.get_inventory('1')
151
self.file_1 = self.inv_1['fileid']
152
self.tree_2 = self.branch.working_tree()
153
self.inv_2 = self.branch.inventory
154
self.file_2 = self.inv_2['fileid']
156
self.link_1 = self.inv_1['linkid']
157
self.link_2 = self.inv_2['linkid']
159
def test_file_diff_deleted(self):
161
self.file_1.diff(internal_diff,
162
"old_label", self.tree_1,
163
"/dev/null", None, None,
165
self.assertEqual(output.getvalue(), "--- old_label\n"
171
def test_file_diff_added(self):
173
self.file_1.diff(internal_diff,
174
"new_label", self.tree_1,
175
"/dev/null", None, None,
176
output, reverse=True)
177
self.assertEqual(output.getvalue(), "--- /dev/null\n"
183
def test_file_diff_changed(self):
185
self.file_1.diff(internal_diff,
186
"/dev/null", self.tree_1,
187
"new_label", self.file_2, self.tree_2,
189
self.assertEqual(output.getvalue(), "--- /dev/null\n"
196
def test_link_diff_deleted(self):
198
self.link_1.diff(internal_diff,
199
"old_label", self.tree_1,
200
"/dev/null", None, None,
202
self.assertEqual(output.getvalue(),
203
"=== target was 'target1'\n")
205
def test_link_diff_added(self):
207
self.link_1.diff(internal_diff,
208
"new_label", self.tree_1,
209
"/dev/null", None, None,
210
output, reverse=True)
211
self.assertEqual(output.getvalue(),
212
"=== target is 'target1'\n")
214
def test_link_diff_changed(self):
216
self.link_1.diff(internal_diff,
217
"/dev/null", self.tree_1,
218
"new_label", self.link_2, self.tree_2,
220
self.assertEqual(output.getvalue(),
221
"=== target changed 'target1' => 'target2'\n")
89
def test_make_entry(self):
90
self.assertIsInstance(inventory.make_entry("file", "name", ROOT_ID),
91
inventory.InventoryFile)
92
self.assertIsInstance(inventory.make_entry("symlink", "name", ROOT_ID),
93
inventory.InventoryLink)
94
self.assertIsInstance(inventory.make_entry("directory", "name", ROOT_ID),
95
inventory.InventoryDirectory)
97
def test_make_entry_non_normalized(self):
98
orig_normalized_filename = osutils.normalized_filename
101
osutils.normalized_filename = osutils._accessible_normalized_filename
102
entry = inventory.make_entry("file", u'a\u030a', ROOT_ID)
103
self.assertEqual(u'\xe5', entry.name)
104
self.assertIsInstance(entry, inventory.InventoryFile)
106
osutils.normalized_filename = osutils._inaccessible_normalized_filename
107
self.assertRaises(errors.InvalidNormalization,
108
inventory.make_entry, 'file', u'a\u030a', ROOT_ID)
110
osutils.normalized_filename = orig_normalized_filename
113
class TestDescribeChanges(TestCase):
115
def test_describe_change(self):
116
# we need to test the following change combinations:
122
# renamed/reparented and modified
123
# change kind (perhaps can't be done yet?)
124
# also, merged in combination with all of these?
125
old_a = InventoryFile('a-id', 'a_file', ROOT_ID)
126
old_a.text_sha1 = '123132'
128
new_a = InventoryFile('a-id', 'a_file', ROOT_ID)
129
new_a.text_sha1 = '123132'
132
self.assertChangeDescription('unchanged', old_a, new_a)
135
new_a.text_sha1 = 'abcabc'
136
self.assertChangeDescription('modified', old_a, new_a)
138
self.assertChangeDescription('added', None, new_a)
139
self.assertChangeDescription('removed', old_a, None)
140
# perhaps a bit questionable but seems like the most reasonable thing...
141
self.assertChangeDescription('unchanged', None, None)
143
# in this case it's both renamed and modified; show a rename and
145
new_a.name = 'newfilename'
146
self.assertChangeDescription('modified and renamed', old_a, new_a)
148
# reparenting is 'renaming'
149
new_a.name = old_a.name
150
new_a.parent_id = 'somedir-id'
151
self.assertChangeDescription('modified and renamed', old_a, new_a)
153
# reset the content values so its not modified
154
new_a.text_size = old_a.text_size
155
new_a.text_sha1 = old_a.text_sha1
156
new_a.name = old_a.name
158
new_a.name = 'newfilename'
159
self.assertChangeDescription('renamed', old_a, new_a)
161
# reparenting is 'renaming'
162
new_a.name = old_a.name
163
new_a.parent_id = 'somedir-id'
164
self.assertChangeDescription('renamed', old_a, new_a)
166
def assertChangeDescription(self, expected_change, old_ie, new_ie):
167
change = InventoryEntry.describe_change(old_ie, new_ie)
168
self.assertEqual(expected_change, change)