~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_versionedfile.py

  • Committer: Robert Collins
  • Date: 2007-04-30 05:13:58 UTC
  • mfrom: (2470 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2471.
  • Revision ID: robertc@robertcollins.net-20070430051358-8cp7kvp1q0tqhxx0
Merge Johns fix for bug 110399.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
 
1
# Copyright (C) 2005 Canonical Ltd
2
2
#
3
3
# Authors:
4
4
#   Johan Rydberg <jrydberg@gnu.org>
7
7
# it under the terms of the GNU General Public License as published by
8
8
# the Free Software Foundation; either version 2 of the License, or
9
9
# (at your option) any later version.
10
 
 
 
10
#
11
11
# This program is distributed in the hope that it will be useful,
12
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
14
# GNU General Public License for more details.
15
 
 
 
15
#
16
16
# You should have received a copy of the GNU General Public License
17
17
# along with this program; if not, write to the Free Software
18
18
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
24
from StringIO import StringIO
25
25
 
26
26
import bzrlib
27
 
import bzrlib.errors as errors
 
27
from bzrlib import (
 
28
    errors,
 
29
    osutils,
 
30
    progress,
 
31
    )
28
32
from bzrlib.errors import (
29
33
                           RevisionNotPresent, 
30
34
                           RevisionAlreadyPresent,
137
141
        except NotImplementedError:
138
142
            pass
139
143
 
 
144
    def test_add_reserved(self):
 
145
        vf = self.get_file()
 
146
        self.assertRaises(errors.ReservedId,
 
147
            vf.add_lines, 'a:', [], ['a\n', 'b\n', 'c\n'])
 
148
 
 
149
        self.assertRaises(errors.ReservedId,
 
150
            vf.add_delta, 'a:', [], None, 'sha1', False, ((0, 0, 0, []),))
 
151
 
 
152
    def test_get_reserved(self):
 
153
        vf = self.get_file()
 
154
        self.assertRaises(errors.ReservedId, vf.get_delta, 'b:')
 
155
        self.assertRaises(errors.ReservedId, vf.get_texts, ['b:'])
 
156
        self.assertRaises(errors.ReservedId, vf.get_lines, 'b:')
 
157
        self.assertRaises(errors.ReservedId, vf.get_text, 'b:')
 
158
 
140
159
    def test_get_delta(self):
141
160
        f = self.get_file()
142
161
        sha1s = self._setup_for_deltas(f)
195
214
        self.assertEqual(expected_delta, deltas['noeol'])
196
215
        # smoke tests for eol support - two noeol in a row same content
197
216
        expected_deltas = (('noeol', '3ad7ee82dbd8f29ecba073f96e43e414b3f70a4d', True, 
198
 
                          [(0, 1, 2, [(u'noeolsecond', 'line\n'), (u'noeolsecond', 'line\n')])]),
 
217
                          [(0, 1, 2, [('noeolsecond', 'line\n'), ('noeolsecond', 'line\n')])]),
199
218
                          ('noeol', '3ad7ee82dbd8f29ecba073f96e43e414b3f70a4d', True, 
200
219
                           [(0, 0, 1, [('noeolsecond', 'line\n')]), (1, 1, 0, [])]))
201
220
        self.assertEqual(['line\n', 'line'], f.get_lines('noeolsecond'))
202
221
        self.assertTrue(deltas['noeolsecond'] in expected_deltas)
203
222
        # two no-eol in a row, different content
204
223
        expected_delta = ('noeolsecond', '8bb553a84e019ef1149db082d65f3133b195223b', True, 
205
 
                          [(1, 2, 1, [(u'noeolnotshared', 'phone\n')])])
 
224
                          [(1, 2, 1, [('noeolnotshared', 'phone\n')])])
206
225
        self.assertEqual(['line\n', 'phone'], f.get_lines('noeolnotshared'))
207
226
        self.assertEqual(expected_delta, deltas['noeolnotshared'])
208
227
        # eol folling a no-eol with content change
209
228
        expected_delta = ('noeol', 'a61f6fb6cfc4596e8d88c34a308d1e724caf8977', False, 
210
 
                          [(0, 1, 1, [(u'eol', 'phone\n')])])
 
229
                          [(0, 1, 1, [('eol', 'phone\n')])])
211
230
        self.assertEqual(['phone\n'], f.get_lines('eol'))
212
231
        self.assertEqual(expected_delta, deltas['eol'])
213
232
        # eol folling a no-eol with content change
214
233
        expected_delta = ('noeol', '6bfa09d82ce3e898ad4641ae13dd4fdb9cf0d76b', False, 
215
 
                          [(0, 1, 1, [(u'eolline', 'line\n')])])
 
234
                          [(0, 1, 1, [('eolline', 'line\n')])])
216
235
        self.assertEqual(['line\n'], f.get_lines('eolline'))
217
236
        self.assertEqual(expected_delta, deltas['eolline'])
218
237
        # eol with no parents
219
238
        expected_delta = (None, '264f39cab871e4cfd65b3a002f7255888bb5ed97', True, 
220
 
                          [(0, 0, 1, [(u'noeolbase', 'line\n')])])
 
239
                          [(0, 0, 1, [('noeolbase', 'line\n')])])
221
240
        self.assertEqual(['line'], f.get_lines('noeolbase'))
222
241
        self.assertEqual(expected_delta, deltas['noeolbase'])
223
242
        # eol with two parents, in inverse insertion order
224
243
        expected_deltas = (('noeolbase', '264f39cab871e4cfd65b3a002f7255888bb5ed97', True,
225
 
                            [(0, 1, 1, [(u'eolbeforefirstparent', 'line\n')])]),
 
244
                            [(0, 1, 1, [('eolbeforefirstparent', 'line\n')])]),
226
245
                           ('noeolbase', '264f39cab871e4cfd65b3a002f7255888bb5ed97', True,
227
 
                            [(0, 1, 1, [(u'eolbeforefirstparent', 'line\n')])]))
 
246
                            [(0, 1, 1, [('eolbeforefirstparent', 'line\n')])]))
228
247
        self.assertEqual(['line'], f.get_lines('eolbeforefirstparent'))
229
248
        #self.assertTrue(deltas['eolbeforefirstparent'] in expected_deltas)
230
249
 
543
562
        # versions in the weave 
544
563
        # the ordering here is to make a tree so that dumb searches have
545
564
        # more changes to muck up.
 
565
 
 
566
        class InstrumentedProgress(progress.DummyProgress):
 
567
 
 
568
            def __init__(self):
 
569
 
 
570
                progress.DummyProgress.__init__(self)
 
571
                self.updates = []
 
572
 
 
573
            def update(self, msg=None, current=None, total=None):
 
574
                self.updates.append((msg, current, total))
 
575
 
546
576
        vf = self.get_file()
547
577
        # add a base to get included
548
578
        vf.add_lines('base', [], ['base\n'])
556
586
        vf.add_lines('otherchild',
557
587
                     ['lancestor', 'base'],
558
588
                     ['base\n', 'lancestor\n', 'otherchild\n'])
559
 
        def iter_with_versions(versions):
 
589
        def iter_with_versions(versions, expected):
560
590
            # now we need to see what lines are returned, and how often.
561
591
            lines = {'base\n':0,
562
592
                     'lancestor\n':0,
564
594
                     'child\n':0,
565
595
                     'otherchild\n':0,
566
596
                     }
 
597
            progress = InstrumentedProgress()
567
598
            # iterate over the lines
568
 
            for line in vf.iter_lines_added_or_present_in_versions(versions):
 
599
            for line in vf.iter_lines_added_or_present_in_versions(versions, 
 
600
                pb=progress):
569
601
                lines[line] += 1
 
602
            if []!= progress.updates: 
 
603
                self.assertEqual(expected, progress.updates)
570
604
            return lines
571
 
        lines = iter_with_versions(['child', 'otherchild'])
 
605
        lines = iter_with_versions(['child', 'otherchild'],
 
606
                                   [('Walking content.', 0, 2),
 
607
                                    ('Walking content.', 1, 2),
 
608
                                    ('Walking content.', 2, 2)])
572
609
        # we must see child and otherchild
573
610
        self.assertTrue(lines['child\n'] > 0)
574
611
        self.assertTrue(lines['otherchild\n'] > 0)
575
612
        # we dont care if we got more than that.
576
613
        
577
614
        # test all lines
578
 
        lines = iter_with_versions(None)
 
615
        lines = iter_with_versions(None, [('Walking content.', 0, 5),
 
616
                                          ('Walking content.', 1, 5),
 
617
                                          ('Walking content.', 2, 5),
 
618
                                          ('Walking content.', 3, 5),
 
619
                                          ('Walking content.', 4, 5),
 
620
                                          ('Walking content.', 5, 5)])
579
621
        # all lines must be seen at least once
580
622
        self.assertTrue(lines['base\n'] > 0)
581
623
        self.assertTrue(lines['lancestor\n'] > 0)
627
669
        # add_lines_with_ghosts api.
628
670
        vf = self.get_file()
629
671
        # add a revision with ghost parents
 
672
        # The preferred form is utf8, but we should translate when needed
 
673
        parent_id_unicode = u'b\xbfse'
 
674
        parent_id_utf8 = parent_id_unicode.encode('utf8')
630
675
        try:
631
 
            vf.add_lines_with_ghosts(u'notbxbfse', [u'b\xbfse'], [])
 
676
            vf.add_lines_with_ghosts('notbxbfse', [parent_id_utf8], [])
632
677
        except NotImplementedError:
633
678
            # check the other ghost apis are also not implemented
634
679
            self.assertRaises(NotImplementedError, vf.has_ghost, 'foo')
636
681
            self.assertRaises(NotImplementedError, vf.get_parents_with_ghosts, 'foo')
637
682
            self.assertRaises(NotImplementedError, vf.get_graph_with_ghosts)
638
683
            return
 
684
        vf = self.reopen_file()
639
685
        # test key graph related apis: getncestry, _graph, get_parents
640
686
        # has_version
641
687
        # - these are ghost unaware and must not be reflect ghosts
642
 
        self.assertEqual([u'notbxbfse'], vf.get_ancestry(u'notbxbfse'))
643
 
        self.assertEqual([], vf.get_parents(u'notbxbfse'))
644
 
        self.assertEqual({u'notbxbfse':[]}, vf.get_graph())
645
 
        self.assertFalse(vf.has_version(u'b\xbfse'))
 
688
        self.assertEqual(['notbxbfse'], vf.get_ancestry('notbxbfse'))
 
689
        self.assertEqual([], vf.get_parents('notbxbfse'))
 
690
        self.assertEqual({'notbxbfse':[]}, vf.get_graph())
 
691
        self.assertFalse(self.callDeprecated([osutils._revision_id_warning],
 
692
                         vf.has_version, parent_id_unicode))
 
693
        self.assertFalse(vf.has_version(parent_id_utf8))
646
694
        # we have _with_ghost apis to give us ghost information.
647
 
        self.assertEqual([u'b\xbfse', u'notbxbfse'], vf.get_ancestry_with_ghosts([u'notbxbfse']))
648
 
        self.assertEqual([u'b\xbfse'], vf.get_parents_with_ghosts(u'notbxbfse'))
649
 
        self.assertEqual({u'notbxbfse':[u'b\xbfse']}, vf.get_graph_with_ghosts())
650
 
        self.assertTrue(vf.has_ghost(u'b\xbfse'))
 
695
        self.assertEqual([parent_id_utf8, 'notbxbfse'], vf.get_ancestry_with_ghosts(['notbxbfse']))
 
696
        self.assertEqual([parent_id_utf8], vf.get_parents_with_ghosts('notbxbfse'))
 
697
        self.assertEqual({'notbxbfse':[parent_id_utf8]}, vf.get_graph_with_ghosts())
 
698
        self.assertTrue(self.callDeprecated([osutils._revision_id_warning],
 
699
                        vf.has_ghost, parent_id_unicode))
 
700
        self.assertTrue(vf.has_ghost(parent_id_utf8))
651
701
        # if we add something that is a ghost of another, it should correct the
652
702
        # results of the prior apis
653
 
        vf.add_lines(u'b\xbfse', [], [])
654
 
        self.assertEqual([u'b\xbfse', u'notbxbfse'], vf.get_ancestry([u'notbxbfse']))
655
 
        self.assertEqual([u'b\xbfse'], vf.get_parents(u'notbxbfse'))
656
 
        self.assertEqual({u'b\xbfse':[],
657
 
                          u'notbxbfse':[u'b\xbfse'],
 
703
        self.callDeprecated([osutils._revision_id_warning],
 
704
                            vf.add_lines, parent_id_unicode, [], [])
 
705
        self.assertEqual([parent_id_utf8, 'notbxbfse'], vf.get_ancestry(['notbxbfse']))
 
706
        self.assertEqual([parent_id_utf8], vf.get_parents('notbxbfse'))
 
707
        self.assertEqual({parent_id_utf8:[],
 
708
                          'notbxbfse':[parent_id_utf8],
658
709
                          },
659
710
                         vf.get_graph())
660
 
        self.assertTrue(vf.has_version(u'b\xbfse'))
 
711
        self.assertTrue(self.callDeprecated([osutils._revision_id_warning],
 
712
                        vf.has_version, parent_id_unicode))
 
713
        self.assertTrue(vf.has_version(parent_id_utf8))
661
714
        # we have _with_ghost apis to give us ghost information.
662
 
        self.assertEqual([u'b\xbfse', u'notbxbfse'], vf.get_ancestry_with_ghosts([u'notbxbfse']))
663
 
        self.assertEqual([u'b\xbfse'], vf.get_parents_with_ghosts(u'notbxbfse'))
664
 
        self.assertEqual({u'b\xbfse':[],
665
 
                          u'notbxbfse':[u'b\xbfse'],
 
715
        self.assertEqual([parent_id_utf8, 'notbxbfse'], vf.get_ancestry_with_ghosts(['notbxbfse']))
 
716
        self.assertEqual([parent_id_utf8], vf.get_parents_with_ghosts('notbxbfse'))
 
717
        self.assertEqual({parent_id_utf8:[],
 
718
                          'notbxbfse':[parent_id_utf8],
666
719
                          },
667
720
                         vf.get_graph_with_ghosts())
668
 
        self.assertFalse(vf.has_ghost(u'b\xbfse'))
 
721
        self.assertFalse(self.callDeprecated([osutils._revision_id_warning],
 
722
                         vf.has_ghost, parent_id_unicode))
 
723
        self.assertFalse(vf.has_ghost(parent_id_utf8))
669
724
 
670
725
    def test_add_lines_with_ghosts_after_normal_revs(self):
671
726
        # some versioned file formats allow lines to be added with parent