Skip to content

Commit 92938c0

Browse files
author
Steve Canny
committed
opc: add reltype to PackageReader.iter_sparts()
1 parent 71e0a41 commit 92938c0

File tree

4 files changed

+92
-44
lines changed

4 files changed

+92
-44
lines changed

docx/opc/package.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ def _unmarshal_parts(pkg_reader, package, part_factory):
486486
*pkg_reader* is constructed using *part_factory*.
487487
"""
488488
parts = {}
489-
for partname, content_type, blob in pkg_reader.iter_sparts():
489+
for partname, content_type, reltype, blob in pkg_reader.iter_sparts():
490490
parts[partname] = part_factory(
491491
partname, content_type, blob, package
492492
)

docx/opc/pkgreader.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ def from_file(pkg_file):
3838

3939
def iter_sparts(self):
4040
"""
41-
Generate a 3-tuple `(partname, content_type, blob)` for each of the
42-
serialized parts in the package.
41+
Generate a 4-tuple `(partname, content_type, reltype, blob)` for each
42+
of the serialized parts in the package.
4343
"""
44-
for spart in self._sparts:
45-
yield (spart.partname, spart.content_type, spart.blob)
44+
for s in self._sparts:
45+
yield (s.partname, s.content_type, s.reltype, s.blob)
4646

4747
def iter_srels(self):
4848
"""

tests/opc/test_package.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -719,18 +719,26 @@ def pkg_(self, request):
719719
return instance_mock(request, OpcPackage)
720720

721721
@pytest.fixture
722-
def pkg_reader_(self, request, partnames_, content_types_, blobs_):
722+
def pkg_reader_(
723+
self, request, partnames_, content_types_, reltypes_, blobs_):
723724
partname_, partname_2_ = partnames_
724725
content_type_, content_type_2_ = content_types_
726+
reltype_, reltype_2_ = reltypes_
725727
blob_, blob_2_ = blobs_
726-
spart_return_values = (
727-
(partname_, content_type_, blob_),
728-
(partname_2_, content_type_2_, blob_2_),
728+
iter_spart_items = (
729+
(partname_, content_type_, reltype_, blob_),
730+
(partname_2_, content_type_2_, reltype_2_, blob_2_),
729731
)
730732
pkg_reader_ = instance_mock(request, PackageReader)
731-
pkg_reader_.iter_sparts.return_value = spart_return_values
733+
pkg_reader_.iter_sparts.return_value = iter_spart_items
732734
return pkg_reader_
733735

736+
@pytest.fixture
737+
def reltypes_(self, request):
738+
reltype_ = instance_mock(request, str, name='reltype_')
739+
reltype_2_ = instance_mock(request, str, name='reltype_2')
740+
return reltype_, reltype_2_
741+
734742
@pytest.fixture
735743
def _unmarshal_parts(self, request, parts_dict_):
736744
return method_mock(

tests/opc/test_pkgreader.py

Lines changed: 74 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,17 @@
1616
_SerializedRelationshipCollection
1717
)
1818

19-
from ..unitutil import class_mock, initializer_mock, method_mock
20-
21-
22-
@pytest.fixture
23-
def oxml_fromstring(request):
24-
_patch = patch('docx.opc.pkgreader.oxml_fromstring')
25-
request.addfinalizer(_patch.stop)
26-
return _patch.start()
19+
from ..unitutil import (
20+
initializer_mock, class_mock, function_mock, instance_mock, loose_mock,
21+
method_mock
22+
)
2723

2824

2925
class DescribePackageReader(object):
3026

31-
def it_can_construct_from_pkg_file(self, init, PhysPkgReader_, from_xml,
32-
_srels_for, _load_serialized_parts):
27+
def it_can_construct_from_pkg_file(
28+
self, init, PhysPkgReader_, from_xml, _srels_for,
29+
_load_serialized_parts):
3330
# mockery ----------------------
3431
phys_reader = PhysPkgReader_.return_value
3532
content_types = from_xml.return_value
@@ -48,20 +45,10 @@ def it_can_construct_from_pkg_file(self, init, PhysPkgReader_, from_xml,
4845
init.assert_called_once_with(content_types, pkg_srels, sparts)
4946
assert isinstance(pkg_reader, PackageReader)
5047

51-
def it_can_iterate_over_the_serialized_parts(self):
52-
# mockery ----------------------
53-
partname, content_type, blob = ('part/name.xml', 'app/vnd.type',
54-
'<Part_1/>')
55-
spart = Mock(name='spart', partname=partname,
56-
content_type=content_type, blob=blob)
57-
pkg_reader = PackageReader(None, None, [spart])
58-
iter_count = 0
59-
# exercise ---------------------
60-
for retval in pkg_reader.iter_sparts():
61-
iter_count += 1
62-
# verify -----------------------
63-
assert retval == (partname, content_type, blob)
64-
assert iter_count == 1
48+
def it_can_iterate_over_the_serialized_parts(self, iter_sparts_fixture):
49+
pkg_reader, expected_iter_spart_items = iter_sparts_fixture
50+
iter_spart_items = list(pkg_reader.iter_sparts())
51+
assert iter_spart_items == expected_iter_spart_items
6552

6653
def it_can_iterate_over_all_the_srels(self):
6754
# mockery ----------------------
@@ -182,6 +169,18 @@ def it_can_retrieve_srels_for_a_source_uri(
182169

183170
# fixtures -------------------------------------------------------
184171

172+
@pytest.fixture
173+
def blobs_(self, request):
174+
blob_ = loose_mock(request, spec=str, name='blob_')
175+
blob_2_ = loose_mock(request, spec=str, name='blob_2_')
176+
return blob_, blob_2_
177+
178+
@pytest.fixture
179+
def content_types_(self, request):
180+
content_type_ = loose_mock(request, spec=str, name='content_type_')
181+
content_type_2_ = loose_mock(request, spec=str, name='content_type_2_')
182+
return content_type_, content_type_2_
183+
185184
@pytest.fixture
186185
def from_xml(self, request):
187186
return method_mock(request, _ContentTypeMap, 'from_xml')
@@ -190,10 +189,26 @@ def from_xml(self, request):
190189
def init(self, request):
191190
return initializer_mock(request, PackageReader)
192191

192+
@pytest.fixture
193+
def iter_sparts_fixture(
194+
self, sparts_, partnames_, content_types_, reltypes_, blobs_):
195+
pkg_reader = PackageReader(None, None, sparts_)
196+
expected_iter_spart_items = [
197+
(partnames_[0], content_types_[0], reltypes_[0], blobs_[0]),
198+
(partnames_[1], content_types_[1], reltypes_[1], blobs_[1]),
199+
]
200+
return pkg_reader, expected_iter_spart_items
201+
193202
@pytest.fixture
194203
def _load_serialized_parts(self, request):
195204
return method_mock(request, PackageReader, '_load_serialized_parts')
196205

206+
@pytest.fixture
207+
def partnames_(self, request):
208+
partname_ = loose_mock(request, spec=str, name='partname_')
209+
partname_2_ = loose_mock(request, spec=str, name='partname_2_')
210+
return partname_, partname_2_
211+
197212
@pytest.fixture
198213
def PhysPkgReader_(self, request):
199214
_patch = patch(
@@ -202,6 +217,12 @@ def PhysPkgReader_(self, request):
202217
request.addfinalizer(_patch.stop)
203218
return _patch.start()
204219

220+
@pytest.fixture
221+
def reltypes_(self, request):
222+
reltype_ = instance_mock(request, str, name='reltype_')
223+
reltype_2_ = instance_mock(request, str, name='reltype_2')
224+
return reltype_, reltype_2_
225+
205226
@pytest.fixture
206227
def _SerializedPart_(self, request):
207228
return class_mock(request, 'docx.opc.pkgreader._SerializedPart')
@@ -212,6 +233,20 @@ def _SerializedRelationshipCollection_(self, request):
212233
request, 'docx.opc.pkgreader._SerializedRelationshipCollection'
213234
)
214235

236+
@pytest.fixture
237+
def sparts_(
238+
self, request, partnames_, content_types_, reltypes_, blobs_):
239+
sparts_ = []
240+
for idx in range(2):
241+
name = 'spart_%s' % (('%d_' % (idx+1)) if idx else '')
242+
spart_ = instance_mock(
243+
request, _SerializedPart, name=name,
244+
partname=partnames_[idx], content_type=content_types_[idx],
245+
reltype=reltypes_[idx], blob=blobs_[idx]
246+
)
247+
sparts_.append(spart_)
248+
return sparts_
249+
215250
@pytest.fixture
216251
def _srels_for(self, request):
217252
return method_mock(request, PackageReader, '_srels_for')
@@ -223,7 +258,7 @@ def _walk_phys_parts(self, request):
223258

224259
class Describe_ContentTypeMap(object):
225260

226-
def it_can_construct_from_types_xml(self, oxml_fromstring):
261+
def it_can_construct_from_types_xml(self, oxml_fromstring_):
227262
# test data --------------------
228263
content_types = (
229264
'app/vnd.type1', 'app/vnd.type2', 'app/vnd.type3',
@@ -249,7 +284,7 @@ def it_can_construct_from_types_xml(self, oxml_fromstring):
249284
types_elm = Mock(
250285
name='types_elm', overrides=overrides, defaults=defaults
251286
)
252-
oxml_fromstring.return_value = types_elm
287+
oxml_fromstring_.return_value = types_elm
253288
# exercise ---------------------
254289
ct_map = _ContentTypeMap.from_xml(content_types_xml)
255290
# verify -----------------------
@@ -259,7 +294,7 @@ def it_can_construct_from_types_xml(self, oxml_fromstring):
259294
expected_defaults = {
260295
exts[0]: content_types[2], exts[1]: content_types[3]
261296
}
262-
oxml_fromstring.assert_called_once_with(content_types_xml)
297+
oxml_fromstring_.assert_called_once_with(content_types_xml)
263298
assert ct_map._overrides == expected_overrides
264299
assert ct_map._defaults == expected_defaults
265300

@@ -290,6 +325,12 @@ def it_should_raise_on_key_not_instance_of_PackURI(self):
290325
with pytest.raises(KeyError):
291326
ct_map['/part/name1.xml']
292327

328+
# fixtures ---------------------------------------------
329+
330+
@pytest.fixture
331+
def oxml_fromstring_(self, request):
332+
return function_mock(request, 'docx.opc.pkgreader.oxml_fromstring')
333+
293334

294335
class Describe_SerializedPart(object):
295336

@@ -364,7 +405,8 @@ def it_raises_on_target_partname_when_external(self):
364405

365406
class Describe_SerializedRelationshipCollection(object):
366407

367-
def it_can_load_from_xml(self, oxml_fromstring, _SerializedRelationship_):
408+
def it_can_load_from_xml(
409+
self, oxml_fromstring_, _SerializedRelationship_):
368410
# mockery ----------------------
369411
baseURI, rels_item_xml, rel_elm_1, rel_elm_2 = (
370412
Mock(name='baseURI'), Mock(name='rels_item_xml'),
@@ -373,7 +415,7 @@ def it_can_load_from_xml(self, oxml_fromstring, _SerializedRelationship_):
373415
rels_elm = Mock(
374416
name='rels_elm', Relationship_lst=[rel_elm_1, rel_elm_2]
375417
)
376-
oxml_fromstring.return_value = rels_elm
418+
oxml_fromstring_.return_value = rels_elm
377419
# exercise ---------------------
378420
srels = _SerializedRelationshipCollection.load_from_xml(
379421
baseURI, rels_item_xml)
@@ -382,7 +424,7 @@ def it_can_load_from_xml(self, oxml_fromstring, _SerializedRelationship_):
382424
call(baseURI, rel_elm_1),
383425
call(baseURI, rel_elm_2),
384426
]
385-
oxml_fromstring.assert_called_once_with(rels_item_xml)
427+
oxml_fromstring_.assert_called_once_with(rels_item_xml)
386428
assert _SerializedRelationship_.call_args_list == expected_calls
387429
assert isinstance(srels, _SerializedRelationshipCollection)
388430

@@ -398,10 +440,8 @@ def it_should_be_iterable(self):
398440
# fixtures ---------------------------------------------
399441

400442
@pytest.fixture
401-
def oxml_fromstring(self, request):
402-
_patch = patch('docx.opc.pkgreader.oxml_fromstring')
403-
request.addfinalizer(_patch.stop)
404-
return _patch.start()
443+
def oxml_fromstring_(self, request):
444+
return function_mock(request, 'docx.opc.pkgreader.oxml_fromstring')
405445

406446
@pytest.fixture
407447
def _SerializedRelationship_(self, request):

0 commit comments

Comments
 (0)