Skip to content

Commit 279fb9f

Browse files
author
Steve Canny
committed
img: add _Chunks.from_stream()
1 parent 4edbb14 commit 279fb9f

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

docx/image/png.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,26 @@ def from_stream(cls, stream):
215215
"""
216216
Return a |_Chunks| instance containing the PNG chunks in *stream*.
217217
"""
218+
chunk_parser = _ChunkParser.from_stream(stream)
219+
chunk_lst = [chunk for chunk in chunk_parser.iter_chunks()]
220+
return cls(chunk_lst)
221+
222+
223+
class _ChunkParser(object):
224+
"""
225+
Extracts chunks from a PNG image stream
226+
"""
227+
@classmethod
228+
def from_stream(cls, stream):
229+
"""
230+
Return a |_ChunkParser| instance that can extract the chunks from the
231+
PNG image in *stream*.
232+
"""
233+
raise NotImplementedError
234+
235+
def iter_chunks(self):
236+
"""
237+
Generate a |_Chunk| subclass instance for each chunk in this parser's
238+
PNG stream, in the order encountered in the stream.
239+
"""
218240
raise NotImplementedError

tests/image/test_png.py

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from docx.image.constants import MIME_TYPE, TAG
1313
from docx.image.exceptions import InvalidImageStreamError
1414
from docx.image.helpers import BIG_ENDIAN, StreamReader
15-
from docx.image.png import _Chunks, Png, _PngParser
15+
from docx.image.png import _Chunks, _ChunkParser, Png, _PngParser
1616

1717
from ..unitutil import (
1818
initializer_mock, class_mock, instance_mock, method_mock, test_file
@@ -251,7 +251,7 @@ def stream_rdr_(self, request):
251251
return instance_mock(request, StreamReader)
252252

253253

254-
class DescribePngParser(object):
254+
class Describe_PngParser(object):
255255

256256
def it_can_parse_the_headers_of_a_PNG_stream(self, parse_fixture):
257257
stream_, _Chunks_, _PngParser__init_, chunks_ = parse_fixture
@@ -283,3 +283,45 @@ def _PngParser__init_(self, request):
283283
@pytest.fixture
284284
def stream_(self, request):
285285
return instance_mock(request, BytesIO)
286+
287+
288+
class Describe_Chunks(object):
289+
290+
def it_can_construct_from_a_stream(self, from_stream_fixture):
291+
stream_, _ChunkParser_, chunk_parser_, _Chunks__init_, chunk_lst = (
292+
from_stream_fixture
293+
)
294+
chunks = _Chunks.from_stream(stream_)
295+
_ChunkParser_.from_stream.assert_called_once_with(stream_)
296+
chunk_parser_.iter_chunks.assert_called_once_with()
297+
_Chunks__init_.assert_called_once_with(chunk_lst)
298+
assert isinstance(chunks, _Chunks)
299+
300+
# fixtures -------------------------------------------------------
301+
302+
@pytest.fixture
303+
def from_stream_fixture(
304+
self, stream_, _ChunkParser_, chunk_parser_, _Chunks__init_):
305+
chunk_lst = [1, 2]
306+
chunk_parser_.iter_chunks.return_value = iter(chunk_lst)
307+
return (
308+
stream_, _ChunkParser_, chunk_parser_, _Chunks__init_, chunk_lst
309+
)
310+
311+
@pytest.fixture
312+
def _ChunkParser_(self, request, chunk_parser_):
313+
_ChunkParser_ = class_mock(request, 'docx.image.png._ChunkParser')
314+
_ChunkParser_.from_stream.return_value = chunk_parser_
315+
return _ChunkParser_
316+
317+
@pytest.fixture
318+
def chunk_parser_(self, request):
319+
return instance_mock(request, _ChunkParser)
320+
321+
@pytest.fixture
322+
def _Chunks__init_(self, request):
323+
return initializer_mock(request, _Chunks)
324+
325+
@pytest.fixture
326+
def stream_(self, request):
327+
return instance_mock(request, BytesIO)

0 commit comments

Comments
 (0)