~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test__groupcompress_pyx.py

Bring the groupcompress plugin into the brisbane-core branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2008 Canonical Limited.
 
2
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License version 2 as published
 
5
# by the Free Software Foundation.
 
6
 
7
# This program is distributed in the hope that it will be useful,
 
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
# GNU General Public License for more details.
 
11
 
12
# You should have received a copy of the GNU General Public License
 
13
# along with this program; if not, write to the Free Software
 
14
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 
15
 
16
 
 
17
"""Tests for the pyrex extension of groupcompress"""
 
18
 
 
19
from bzrlib import tests
 
20
 
 
21
from bzrlib import groupcompress
 
22
 
 
23
 
 
24
class _CompiledGroupCompress(tests.Feature):
 
25
 
 
26
    def _probe(self):
 
27
        try:
 
28
            import bzrlib._groupcompress_pyx
 
29
        except ImportError:
 
30
            return False
 
31
        else:
 
32
            return True
 
33
 
 
34
    def feature_name(self):
 
35
        return 'bzrlib._groupcompress_pyx'
 
36
 
 
37
CompiledGroupCompress = _CompiledGroupCompress()
 
38
 
 
39
_text1 = """\
 
40
This is a bit
 
41
of source text
 
42
which is meant to be matched
 
43
against other text
 
44
"""
 
45
 
 
46
_text2 = """\
 
47
This is a bit
 
48
of source text
 
49
which is meant to differ from
 
50
against other text
 
51
"""
 
52
 
 
53
_text3 = """\
 
54
This is a bit
 
55
of source text
 
56
which is meant to be matched
 
57
against other text
 
58
except it also
 
59
has a lot more data
 
60
at the end of the file
 
61
"""
 
62
 
 
63
_first_text = """\
 
64
a bit of text, that
 
65
does not have much in
 
66
common with the next text
 
67
"""
 
68
 
 
69
_second_text = """\
 
70
some more bit of text, that
 
71
does not have much in
 
72
common with the previous text
 
73
and has some extra text
 
74
"""
 
75
 
 
76
 
 
77
_third_text = """\
 
78
a bit of text, that
 
79
has some in common with the previous text
 
80
and has some extra text
 
81
and not have much in
 
82
common with the next text
 
83
"""
 
84
 
 
85
 
 
86
class Test_GroupCompress(tests.TestCase):
 
87
    """Direct tests for the compiled extension."""
 
88
 
 
89
    def setUp(self):
 
90
        super(Test_GroupCompress, self).setUp()
 
91
        self.requireFeature(CompiledGroupCompress)
 
92
        from bzrlib import _groupcompress_pyx
 
93
        self._gc_module = _groupcompress_pyx
 
94
 
 
95
 
 
96
class TestMakeAndApplyDelta(Test_GroupCompress):
 
97
 
 
98
    def setUp(self):
 
99
        super(TestMakeAndApplyDelta, self).setUp()
 
100
        self.make_delta = self._gc_module.make_delta
 
101
        self.apply_delta = self._gc_module.apply_delta
 
102
 
 
103
    def test_make_delta_is_typesafe(self):
 
104
        self.make_delta('a string', 'another string')
 
105
        self.assertRaises(TypeError,
 
106
            self.make_delta, 'a string', object())
 
107
        self.assertRaises(TypeError,
 
108
            self.make_delta, 'a string', u'not a string')
 
109
        self.assertRaises(TypeError,
 
110
            self.make_delta, object(), 'a string')
 
111
        self.assertRaises(TypeError,
 
112
            self.make_delta, u'not a string', 'a string')
 
113
 
 
114
    def test_make_noop_delta(self):
 
115
        ident_delta = self.make_delta(_text1, _text1)
 
116
        self.assertEqual('MM\x90M', ident_delta)
 
117
        ident_delta = self.make_delta(_text2, _text2)
 
118
        self.assertEqual('NN\x90N', ident_delta)
 
119
        ident_delta = self.make_delta(_text3, _text3)
 
120
        self.assertEqual('\x87\x01\x87\x01\x90\x87', ident_delta)
 
121
 
 
122
    def test_make_delta(self):
 
123
        delta = self.make_delta(_text1, _text2)
 
124
        self.assertEqual('MN\x90/\x1fdiffer from\nagainst other text\n', delta)
 
125
        delta = self.make_delta(_text2, _text1)
 
126
        self.assertEqual('NM\x90/\x1ebe matched\nagainst other text\n', delta)
 
127
        delta = self.make_delta(_text3, _text1)
 
128
        self.assertEqual('\x87\x01M\x90M', delta)
 
129
        delta = self.make_delta(_text3, _text2)
 
130
        self.assertEqual('\x87\x01N\x90/\x1fdiffer from\nagainst other text\n',
 
131
                         delta)
 
132
 
 
133
    def test_apply_delta_is_typesafe(self):
 
134
        self.apply_delta(_text1, 'MM\x90M')
 
135
        self.assertRaises(TypeError,
 
136
            self.apply_delta, object(), 'MM\x90M')
 
137
        self.assertRaises(TypeError,
 
138
            self.apply_delta, unicode(_text1), 'MM\x90M')
 
139
        self.assertRaises(TypeError,
 
140
            self.apply_delta, _text1, u'MM\x90M')
 
141
        self.assertRaises(TypeError,
 
142
            self.apply_delta, _text1, object())
 
143
 
 
144
    def test_apply_delta(self):
 
145
        target = self.apply_delta(_text1,
 
146
                    'MN\x90/\x1fdiffer from\nagainst other text\n')
 
147
        self.assertEqual(_text2, target)
 
148
        target = self.apply_delta(_text2,
 
149
                    'NM\x90/\x1ebe matched\nagainst other text\n')
 
150
        self.assertEqual(_text1, target)
 
151
 
 
152
 
 
153
class TestDeltaIndex(Test_GroupCompress):
 
154
 
 
155
    def test_repr(self):
 
156
        di = self._gc_module.DeltaIndex('test text\n')
 
157
        self.assertEqual('DeltaIndex(1, 10)', repr(di))
 
158
 
 
159
    def test_make_delta(self):
 
160
        di = self._gc_module.DeltaIndex(_text1)
 
161
        delta = di.make_delta(_text2)
 
162
        self.assertEqual('MN\x90/\x1fdiffer from\nagainst other text\n', delta)
 
163
 
 
164
    def test_delta_against_multiple_sources(self):
 
165
        di = self._gc_module.DeltaIndex()
 
166
        di.add_source(_first_text, 0)
 
167
        self.assertEqual(len(_first_text), di._source_offset)
 
168
        di.add_source(_second_text, 0)
 
169
        self.assertEqual(len(_first_text) + len(_second_text), di._source_offset)
 
170
        delta = di.make_delta(_third_text)
 
171
        result = self._gc_module.apply_delta(_first_text + _second_text, delta)
 
172
        self.assertEqualDiff(_third_text, result)
 
173
        self.assertEqual('\xac\x01\x85\x01\x90\x14\x0chas some in '
 
174
                         '\x91v6\x03and\x91d"\x91:\n', delta)
 
175
 
 
176
    def test_delta_with_offsets(self):
 
177
        di = self._gc_module.DeltaIndex()
 
178
        di.add_source(_first_text, 5)
 
179
        self.assertEqual(len(_first_text) + 5, di._source_offset)
 
180
        di.add_source(_second_text, 10)
 
181
        self.assertEqual(len(_first_text) + len(_second_text) + 15,
 
182
                         di._source_offset)
 
183
        delta = di.make_delta(_third_text)
 
184
        self.assertIsNot(None, delta)
 
185
        result = self._gc_module.apply_delta(
 
186
            '12345' + _first_text + '1234567890' + _second_text, delta)
 
187
        self.assertIsNot(None, result)
 
188
        self.assertEqualDiff(_third_text, result)
 
189
        self.assertEqual('\xbb\x01\x85\x01\x91\x05\x14\x0chas some in '
 
190
                         '\x91\x856\x03and\x91s"\x91?\n', delta)
 
191
 
 
192
    def test_delta_with_delta_bytes(self):
 
193
        di = self._gc_module.DeltaIndex()
 
194
        di.add_source(_first_text, 0)
 
195
        self.assertEqual(len(_first_text), di._source_offset)
 
196
        delta = di.make_delta(_second_text)
 
197
        self.assertEqual('Dh\tsome more\x91\x019'
 
198
                         '&previous text\nand has some extra text\n', delta)
 
199
        di.add_delta_source(delta, 0)
 
200
        self.assertEqual(len(_first_text) + len(delta), di._source_offset)
 
201
        third_delta = di.make_delta(_third_text)
 
202
        result = self._gc_module.apply_delta(_first_text + delta, third_delta)
 
203
        self.assertEqualDiff(_third_text, result)
 
204
        # We should be able to match against the 'previous text\nand has some...'
 
205
        # that was part of the delta bytes
 
206
        # Note that we don't match the 'common with the', because it isn't long
 
207
        # enough to match in the original text, and those bytes are not present
 
208
        # in the delta for the second text.
 
209
        self.assertEqual('z\x85\x01\x90\x14\x1chas some in common with the '
 
210
                         '\x91T&\x03and\x91\x18,', third_delta)