1
# (C) 2005,2006 Canonical Ltd
2
# Authors: Robert Collins <robert.collins@canonical.com>
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU General Public License for more details.
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
from cStringIO import StringIO
23
from bzrlib.branch import Branch
24
import bzrlib.bzrdir as bzrdir
25
from bzrlib.bzrdir import BzrDir
26
import bzrlib.errors as errors
27
from bzrlib.errors import (NotBranchError, NotVersionedError,
29
from bzrlib.osutils import pathjoin, getcwd, has_symlinks
30
from bzrlib.tests import TestSkipped, TestCase
31
from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
32
from bzrlib.trace import mutter
33
import bzrlib.ui as ui
34
import bzrlib.workingtree as workingtree
35
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
39
class CapturingUIFactory(ui.UIFactory):
40
"""A UI Factory for testing - capture the updates made through it."""
43
super(CapturingUIFactory, self).__init__()
48
"""See progress.ProgressBar.clear()."""
51
"""See progress.ProgressBar.clear_term()."""
54
"""See progress.ProgressBar.finished()."""
57
def note(self, fmt_string, *args, **kwargs):
58
"""See progress.ProgressBar.note()."""
60
def progress_bar(self):
63
def nested_progress_bar(self):
67
def update(self, message, count=None, total=None):
68
"""See progress.ProgressBar.update()."""
70
self._calls.append(("update", count, total))
73
class TestCapturingUI(TestCase):
75
def test_nested_ignore_depth_beyond_one(self):
76
# we only want to capture the first level out progress, not
77
# want sub-components might do. So we have nested bars ignored.
78
factory = CapturingUIFactory()
79
pb1 = factory.nested_progress_bar()
80
pb1.update('foo', 0, 1)
81
pb2 = factory.nested_progress_bar()
82
pb2.update('foo', 0, 1)
85
self.assertEqual([("update", 0, 1)], factory._calls)
88
class TestCommit(TestCaseWithWorkingTree):
90
def test_commit_sets_last_revision(self):
91
tree = self.make_branch_and_tree('tree')
92
tree.commit('foo', rev_id='foo', allow_pointless=True)
93
self.assertEqual('foo', tree.last_revision())
95
def test_commit_local_unbound(self):
96
# using the library api to do a local commit on unbound branches is
98
tree = self.make_branch_and_tree('tree')
99
self.assertRaises(errors.LocalRequiresBoundBranch,
104
def test_local_commit_ignores_master(self):
105
# a --local commit does not require access to the master branch
106
# at all, or even for it to exist.
107
# we test this by setting up a bound branch and then corrupting
109
master = self.make_branch('master')
110
tree = self.make_branch_and_tree('tree')
112
tree.branch.bind(master)
113
except errors.UpgradeRequired:
116
master.bzrdir.transport.put('branch-format', StringIO('garbage'))
118
# check its corrupted.
119
self.assertRaises(errors.UnknownFormatError,
122
tree.commit('foo', rev_id='foo', local=True)
124
def test_local_commit_does_not_push_to_master(self):
125
# a --local commit does not require access to the master branch
126
# at all, or even for it to exist.
127
# we test that even when its available it does not push to it.
128
master = self.make_branch('master')
129
tree = self.make_branch_and_tree('tree')
131
tree.branch.bind(master)
132
except errors.UpgradeRequired:
135
tree.commit('foo', rev_id='foo', local=True)
136
self.failIf(master.repository.has_revision('foo'))
137
self.assertEqual(None, master.last_revision())
140
class TestCommmitProgress(TestCaseWithWorkingTree):
142
def restoreDefaults(self):
143
ui.ui_factory = self.old_ui_factory
145
def test_commit_progress_steps(self):
146
# during commit we one progress update for every entry in the
147
# inventory, and then one for the inventory, and one for the
148
# inventory, and one for the revision insertions.
149
# first we need a test commit to do. Lets setup a branch with
150
# 3 files, and alter one in a selected-file commit. This exercises
151
# a number of cases quickly. We should also test things like
152
# selective commits which excludes newly added files.
153
tree = self.make_branch_and_tree('.')
154
self.build_tree(['a', 'b', 'c'])
155
tree.add(['a', 'b', 'c'])
156
tree.commit('first post')
158
f.write('new content')
160
# set a progress bar that captures the calls so we can see what is
162
self.old_ui_factory = ui.ui_factory
163
self.addCleanup(self.restoreDefaults)
164
factory = CapturingUIFactory()
165
ui.ui_factory = factory
166
# TODO RBC 20060421 it would be nice to merge the reporter output
167
# into the factory for this test - just make the test ui factory
168
# pun as a reporter. Then we can check the ordering is right.
169
tree.commit('second post', specific_files=['b'])
170
# 11 steps: 1 for rev, 1 for inventory, 1 for finishing. 2 for root
171
# and 3 for basis files, and 3 for new inventory files.