1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
# pyright: reportPrivateUsage=false
"""Test suite for the docx.shape module."""
from __future__ import annotations
from typing import cast
import pytest
from docx.document import Document
from docx.enum.shape import WD_INLINE_SHAPE
from docx.oxml.document import CT_Body
from docx.oxml.ns import nsmap
from docx.oxml.shape import CT_Inline
from docx.shape import InlineShape, InlineShapes
from docx.shared import Emu, Length
from .unitutil.cxml import element, xml
from .unitutil.mock import FixtureRequest, Mock, instance_mock
class DescribeInlineShapes:
"""Unit-test suite for `docx.shape.InlineShapes` objects."""
def it_knows_how_many_inline_shapes_it_contains(self, body: CT_Body, document_: Mock):
inline_shapes = InlineShapes(body, document_)
assert len(inline_shapes) == 2
def it_can_iterate_over_its_InlineShape_instances(self, body: CT_Body, document_: Mock):
inline_shapes = InlineShapes(body, document_)
assert all(isinstance(s, InlineShape) for s in inline_shapes)
assert len(list(inline_shapes)) == 2
def it_provides_indexed_access_to_inline_shapes(self, body: CT_Body, document_: Mock):
inline_shapes = InlineShapes(body, document_)
for idx in range(-2, 2):
assert isinstance(inline_shapes[idx], InlineShape)
def it_raises_on_indexed_access_out_of_range(self, body: CT_Body, document_: Mock):
inline_shapes = InlineShapes(body, document_)
with pytest.raises(IndexError, match=r"inline shape index \[-3\] out of range"):
inline_shapes[-3]
with pytest.raises(IndexError, match=r"inline shape index \[2\] out of range"):
inline_shapes[2]
def it_knows_the_part_it_belongs_to(self, body: CT_Body, document_: Mock):
inline_shapes = InlineShapes(body, document_)
assert inline_shapes.part is document_.part
# -- fixtures --------------------------------------------------------------------------------
@pytest.fixture
def body(self) -> CT_Body:
return cast(
CT_Body, element("w:body/w:p/(w:r/w:drawing/wp:inline, w:r/w:drawing/wp:inline)")
)
@pytest.fixture
def document_(self, request: FixtureRequest):
return instance_mock(request, Document)
class DescribeInlineShape:
"""Unit-test suite for `docx.shape.InlineShape` objects."""
@pytest.mark.parametrize(
("uri", "content_cxml", "expected_value"),
[
# -- embedded picture --
(nsmap["pic"], "/pic:pic/pic:blipFill/a:blip{r:embed=rId1}", WD_INLINE_SHAPE.PICTURE),
# -- linked picture --
(
nsmap["pic"],
"/pic:pic/pic:blipFill/a:blip{r:link=rId2}",
WD_INLINE_SHAPE.LINKED_PICTURE,
),
# -- linked and embedded picture (not expected) --
(
nsmap["pic"],
"/pic:pic/pic:blipFill/a:blip{r:embed=rId1,r:link=rId2}",
WD_INLINE_SHAPE.LINKED_PICTURE,
),
# -- chart --
(nsmap["c"], "", WD_INLINE_SHAPE.CHART),
# -- SmartArt --
(nsmap["dgm"], "", WD_INLINE_SHAPE.SMART_ART),
# -- something else we don't know about --
("foobar", "", WD_INLINE_SHAPE.NOT_IMPLEMENTED),
],
)
def it_knows_what_type_of_shape_it_is(
self, uri: str, content_cxml: str, expected_value: WD_INLINE_SHAPE
):
cxml = "wp:inline/a:graphic/a:graphicData{uri=%s}%s" % (uri, content_cxml)
inline = cast(CT_Inline, element(cxml))
inline_shape = InlineShape(inline)
assert inline_shape.type == expected_value
def it_knows_its_display_dimensions(self):
inline = cast(CT_Inline, element("wp:inline/wp:extent{cx=333, cy=666}"))
inline_shape = InlineShape(inline)
width, height = inline_shape.width, inline_shape.height
assert isinstance(width, Length)
assert width == 333
assert isinstance(height, Length)
assert height == 666
def it_can_change_its_display_dimensions(self):
inline_shape = InlineShape(
cast(
CT_Inline,
element(
"wp:inline/(wp:extent{cx=333,cy=666},a:graphic/a:graphicData/pic:pic/"
"pic:spPr/a:xfrm/a:ext{cx=333,cy=666})"
),
)
)
inline_shape.width = Emu(444)
inline_shape.height = Emu(888)
assert inline_shape._inline.xml == xml(
"wp:inline/(wp:extent{cx=444,cy=888},a:graphic/a:graphicData/pic:pic/pic:spPr/"
"a:xfrm/a:ext{cx=444,cy=888})"
)
|