~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_container.py

Start implementing container format reading and writing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2007 Canonical Ltd
 
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 as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Tests for bzrlib.container."""
 
18
 
 
19
 
 
20
from cStringIO import StringIO
 
21
 
 
22
from bzrlib import container, errors
 
23
from bzrlib.tests import TestCase
 
24
 
 
25
 
 
26
class TestContainerWriter(TestCase):
 
27
 
 
28
    def test_construct(self):
 
29
        """Test constructing a ContainerWriter.
 
30
        
 
31
        This uses None as the output stream to show that the constructor doesn't
 
32
        try to use the output stream.
 
33
        """
 
34
        writer = container.ContainerWriter(None)
 
35
 
 
36
    def test_begin(self):
 
37
        """Test the begin() method."""
 
38
        output = StringIO()
 
39
        writer = container.ContainerWriter(output.write)
 
40
        writer.begin()
 
41
        self.assertEqual('bzr pack format 1\n', output.getvalue())
 
42
 
 
43
    def test_end(self):
 
44
        """Test the end() method."""
 
45
        output = StringIO()
 
46
        writer = container.ContainerWriter(output.write)
 
47
        writer.begin()
 
48
        writer.end()
 
49
        self.assertEqual('bzr pack format 1\nE', output.getvalue())
 
50
 
 
51
    def test_add_bytes_record_no_name(self):
 
52
        """Add a bytes record with no name."""
 
53
        output = StringIO()
 
54
        writer = container.ContainerWriter(output.write)
 
55
        writer.begin()
 
56
        writer.add_bytes_record('abc', names=[])
 
57
        self.assertEqual('bzr pack format 1\nB3\n\nabc', output.getvalue())
 
58
 
 
59
    def test_add_bytes_record_one_name(self):
 
60
        """Add a bytes record with one name."""
 
61
        output = StringIO()
 
62
        writer = container.ContainerWriter(output.write)
 
63
        writer.begin()
 
64
        writer.add_bytes_record('abc', names=['name1'])
 
65
        self.assertEqual('bzr pack format 1\nB3\nname1\n\nabc',
 
66
                         output.getvalue())
 
67
 
 
68
    def test_add_bytes_record_two_names(self):
 
69
        """Add a bytes record with two names."""
 
70
        output = StringIO()
 
71
        writer = container.ContainerWriter(output.write)
 
72
        writer.begin()
 
73
        writer.add_bytes_record('abc', names=['name1', 'name2'])
 
74
        self.assertEqual('bzr pack format 1\nB3\nname1\nname2\n\nabc',
 
75
                         output.getvalue())
 
76
 
 
77
 
 
78
class TestContainerReader(TestCase):
 
79
 
 
80
    def test_construct(self):
 
81
        """Test constructing a ContainerReader.
 
82
        
 
83
        This uses None as the output stream to show that the constructor doesn't
 
84
        try to use the input stream.
 
85
        """
 
86
        reader = container.ContainerReader(None)
 
87
 
 
88
    def test_empty_container(self):
 
89
        """Read an empty container."""
 
90
        input = StringIO("bzr pack format 1\nE")
 
91
        reader = container.ContainerReader(input.read)
 
92
        self.assertEqual([], list(reader.iter_records()))
 
93
 
 
94
    def test_unknown_format(self):
 
95
        """Unrecognised container formats raise UnknownContainerFormatError."""
 
96
        input = StringIO("unknown format\n")
 
97
        reader = container.ContainerReader(input.read)
 
98
        self.assertRaises(
 
99
            errors.UnknownContainerFormatError, reader.iter_records)
 
100
 
 
101
    def test_unexpected_end_of_container(self):
 
102
        """Containers that don't end with an End Marker record should cause
 
103
        UnexpectedEndOfContainerError to be raised.
 
104
        """
 
105
        input = StringIO("bzr pack format 1\n")
 
106
        reader = container.ContainerReader(input.read)
 
107
        iterator = reader.iter_records()
 
108
        self.assertRaises(
 
109
            errors.UnexpectedEndOfContainerError, iterator.next)
 
110
 
 
111
    def test_unknown_record_type(self):
 
112
        """Unknown record types cause UnknownRecordTypeError to be raised."""
 
113
        input = StringIO("bzr pack format 1\nX")
 
114
        reader = container.ContainerReader(input.read)
 
115
        iterator = reader.iter_records()
 
116
        self.assertRaises(
 
117
            errors.UnknownRecordTypeError, iterator.next)
 
118
 
 
119
    # XXX: refactor Bytes record parsing into a seperate BytesRecordReader for
 
120
    #      better unit testing.
 
121
    def test_one_unnamed_record(self):
 
122
        """Read a container with one Bytes record."""
 
123
        input = StringIO("bzr pack format 1\nB5\n\naaaaaE")
 
124
        reader = container.ContainerReader(input.read)
 
125
        expected_records = [([], 'aaaaa')]
 
126
        self.assertEqual(expected_records, list(reader.iter_records()))
 
127
 
 
128
    def test_one_named_record(self):
 
129
        """Read a container with one Bytes record with a single name."""
 
130
        input = StringIO("bzr pack format 1\nB5\nname1\n\naaaaaE")
 
131
        reader = container.ContainerReader(input.read)
 
132
        expected_records = [(['name1'], 'aaaaa')]
 
133
        self.assertEqual(expected_records, list(reader.iter_records()))
 
134
 
 
135
 
 
136
    # Other Bytes record parsing cases to test:
 
137
    #  - invalid length value
 
138
    #  - incomplete bytes (i.e. stream ends before $length bytes read)
 
139
    #  - _read_line encountering end of stream (at any time; during length,
 
140
    #    names, end of headers...)
 
141
 
 
142
 
 
143