99import pytest
1010
1111from docx .compat import BytesIO
12+ from docx .image .constants import TAG
1213from docx .image .exceptions import InvalidImageStreamError
1314from docx .image .helpers import BIG_ENDIAN , StreamReader
1415from docx .image .png import Png
@@ -33,24 +34,33 @@ def it_can_construct_from_a_png_stream(self, from_stream_fixture):
3334 assert isinstance (png , Png )
3435
3536 def it_parses_PNG_headers_to_access_attrs (self , parse_png_fixture ):
36- (stream_ , _parse_chunk_offsets_ , _parse_chunks_ , chunk_offsets_ ,
37+ (stream_ , _parse_chunk_offsets_ , _parse_chunks_ , chunk_offsets ,
3738 attrs_ ) = parse_png_fixture
3839 attrs = Png ._parse_png_headers (stream_ )
3940 _parse_chunk_offsets_ .assert_called_once_with (stream_ )
40- _parse_chunks_ .assert_called_once_with (stream_ , chunk_offsets_ )
41+ _parse_chunks_ .assert_called_once_with (stream_ , chunk_offsets )
4142 assert attrs == attrs_
4243
43- def it_raises_on_png_having_no_IHDR_chunk (self , no_IHDR_fixture ):
44- stream_ = no_IHDR_fixture
45- with pytest .raises (InvalidImageStreamError ):
46- Png ._parse_png_headers (stream_ )
47-
4844 def it_parses_chunk_offsets_to_help_chunk_parser (
4945 self , chunk_offset_fixture ):
5046 stream , expected_chunk_offsets = chunk_offset_fixture
5147 chunk_offsets = Png ._parse_chunk_offsets (stream )
5248 assert chunk_offsets == expected_chunk_offsets
5349
50+ def it_parses_chunks_to_extract_fields (self , parse_chunks_fixture ):
51+ (stream_ , chunk_offsets , _parse_IHDR_ , ihdr_offset , _parse_pHYs_ ,
52+ phys_offset , expected_attrs ) = parse_chunks_fixture
53+ attrs = Png ._parse_chunks (stream_ , chunk_offsets )
54+ _parse_IHDR_ .assert_called_once_with (stream_ , ihdr_offset )
55+ if phys_offset is not None :
56+ _parse_pHYs_ .assert_called_once_with (stream_ , phys_offset )
57+ assert attrs == expected_attrs
58+
59+ def it_raises_on_png_having_no_IHDR_chunk (self , no_IHDR_fixture ):
60+ stream_ , chunk_offsets = no_IHDR_fixture
61+ with pytest .raises (InvalidImageStreamError ):
62+ Png ._parse_chunks (stream_ , chunk_offsets )
63+
5464 # fixtures -------------------------------------------------------
5565
5666 @pytest .fixture
@@ -82,7 +92,7 @@ def chunk_offset_fixture(self, request):
8292 return stream_rdr , expected_chunk_offsets
8393
8494 @pytest .fixture
85- def chunk_offsets_ (self , request ):
95+ def chunk_offsets (self , request ):
8696 return dict ()
8797
8898 @pytest .fixture
@@ -101,24 +111,37 @@ def from_stream_fixture(
101111 )
102112
103113 @pytest .fixture
104- def no_IHDR_fixture (
105- self , stream_ , _parse_chunk_offsets_ , _parse_chunks_ ):
106- return stream_
114+ def no_IHDR_fixture (self , stream_ , chunk_offsets ):
115+ return stream_ , chunk_offsets
116+
117+ @pytest .fixture (params = [(42 , 24 ), (42 , None )])
118+ def parse_chunks_fixture (
119+ self , request , stream_rdr_ , _parse_IHDR_ , _parse_pHYs_ ):
120+ ihdr_offset , phys_offset = request .param
121+ chunk_offsets = {'IHDR' : ihdr_offset }
122+ expected_attrs = dict (_parse_IHDR_ .return_value )
123+ if phys_offset is not None :
124+ chunk_offsets ['pHYs' ] = phys_offset
125+ expected_attrs .update (_parse_pHYs_ .return_value )
126+ return (
127+ stream_rdr_ , chunk_offsets , _parse_IHDR_ , ihdr_offset ,
128+ _parse_pHYs_ , phys_offset , expected_attrs
129+ )
107130
108131 @pytest .fixture
109132 def parse_png_fixture (
110133 self , stream_rdr_ , _parse_chunk_offsets_ , _parse_chunks_ ,
111- chunk_offsets_ , attrs_ ):
112- chunk_offsets_ ['IHDR' ] = 666
134+ chunk_offsets , attrs_ ):
135+ chunk_offsets ['IHDR' ] = 666
113136 return (
114137 stream_rdr_ , _parse_chunk_offsets_ , _parse_chunks_ ,
115- chunk_offsets_ , attrs_
138+ chunk_offsets , attrs_
116139 )
117140
118141 @pytest .fixture
119- def _parse_chunk_offsets_ (self , request , chunk_offsets_ ):
142+ def _parse_chunk_offsets_ (self , request , chunk_offsets ):
120143 return method_mock (
121- request , Png , '_parse_chunk_offsets' , return_value = chunk_offsets_
144+ request , Png , '_parse_chunk_offsets' , return_value = chunk_offsets
122145 )
123146
124147 @pytest .fixture
@@ -127,6 +150,23 @@ def _parse_chunks_(self, request, attrs_):
127150 request , Png , '_parse_chunks' , return_value = attrs_
128151 )
129152
153+ @pytest .fixture
154+ def _parse_IHDR_ (self , request ):
155+ return method_mock (
156+ request , Png , '_parse_IHDR' , return_value = {
157+ TAG .PX_WIDTH : 12 , TAG .PX_HEIGHT : 34
158+ }
159+ )
160+
161+ @pytest .fixture
162+ def _parse_pHYs_ (self , request ):
163+ return method_mock (
164+ request , Png , '_parse_pHYs' , return_value = {
165+ TAG .HORZ_PX_PER_UNIT : 56 , TAG .VERT_PX_PER_UNIT : 78 ,
166+ TAG .UNITS_SPECIFIER : 1
167+ }
168+ )
169+
130170 @pytest .fixture
131171 def _parse_png_headers_ (self , request , attrs ):
132172 return method_mock (
0 commit comments