8000 rfctr: bulk test-layout updates · python-openxml/python-docx@5cd150e · GitHub
[go: up one dir, main page]

Skip to content

Commit 5cd150e

Browse files
committed
rfctr: bulk test-layout updates
Back in the day I thought it better to extract a test-specific fixture for each test. That had the benefit of making parameterized tests fold cleanly without the parameters in the decorator. The downside was you had to look in two places to understand the test so I dropped that practice. Fix some of these I need to change or add to later.
1 parent 1c5bb28 commit 5cd150e

File tree

6 files changed

+86
-83
lines changed

6 files changed

+86
-83
lines changed

src/docx/oxml/text/run.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Custom element classes related to text runs (CT_R)."""
22

3+
from __future__ import annotations
4+
35
from docx.ox 8000 ml.ns import qn
46
from docx.oxml.simpletypes import ST_BrClear, ST_BrType
57
from docx.oxml.xmlchemy import BaseOxmlElement, OptionalAttribute, ZeroOrMore, ZeroOrOne
@@ -18,7 +20,7 @@ class CT_R(BaseOxmlElement):
1820
tab = ZeroOrMore("w:tab")
1921
drawing = ZeroOrMore("w:drawing")
2022

21-
def add_t(self, text):
23+
def add_t(self, text: str) -> CT_Text:
2224
"""Return a newly added `<w:t>` element containing `text`."""
2325
t = self._add_t(text=text)
2426
if len(text.strip()) < len(text):

src/docx/text/run.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,18 +128,19 @@ def style(self, style_or_name):
128128
self._r.style = style_id
129129

130130
@property
131-
def text(self):
132-
"""String formed by concatenating the text equivalent of each run content child
133-
element into a Python string. Each ``<w:t>`` element adds the text characters it
134-
contains. A ``<w:tab/>`` element adds a ``\\t`` character. A ``<w:cr/>`` or
135-
``<w:br>`` element each add a ``\\n`` character. Note that a ``<w:br>`` element
136-
can indicate a page break or column break as well as a line break. All
137-
``<w:br>`` elements translate to a single ``\\n`` character regardless of their
138-
type. All other content child elements, such as ``<w:drawing>``, are ignored.
139-
140-
Assigning text to this property has the reverse effect, translating each ``\\t``
141-
character to a ``<w:tab/>`` element and each ``\\n`` or ``\\r`` character to a
142-
``<w:cr/>`` element. Any existing run content is replaced. Run formatting is
131+
def text(self) -> str:
132+
"""String formed by concatenating the text equivalent of each run.
133+
134+
Each `<w:t>` element adds the text characters it contains. A `<w:tab/>` element
135+
adds a `\\t` character. A `<w:cr/>` or `<w:br>` element each add a `\\n`
136+
character. Note that a `<w:br>` element can indicate a page break or column
137+
break as well as a line break. Only line-break `<w:br>` elements translate to
138+
a `\\n` character. Others are ignored. All other content child elements, such as
139+
`<w:drawing>`, are ignored.
140+
141+
Assigning text to this property has the reverse effect, translating each `\\t`
142+
character to a `<w:tab/>` element and each `\\n` or `\\r` character to a
143+
`<w:cr/>` element. Any existing run content is replaced. Run formatting is
143144
preserved.
144145
"""
145146
return self._r.text

tests/oxml/text/test_run.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,35 @@
11
"""Test suite for the docx.oxml.text.run module."""
22

3+
from typing import cast
4+
35
import pytest
46

5-
from ...unitutil.cxml import element, xml
7+
from docx.oxml.text.run import CT_R
68

9+
from ...unitutil.cxml import element, xml
710

8-
class DescribeCT_R(object):
9-
def it_can_add_a_t_preserving_edge_whitespace(self, add_t_fixture):
10-
r, text, expected_xml = add_t_fixture
11-
r.add_t(text)
12-
assert r.xml == expected_xml
1311

14-
# fixtures -------------------------------------------------------
12+
class DescribeCT_R:
13+
"""Unit-test suite for the CT_R (run, <w:r>) element."""
1514

16-
@pytest.fixture(
17-
params=[
15+
@pytest.mark.parametrize(
16+
("initial_cxml", "text", "expected_cxml"),
17+
[
1818
("w:r", "foobar", 'w:r/w:t"foobar"'),
1919
("w:r", "foobar ", 'w:r/w:t{xml:space=preserve}"foobar "'),
2020
(
2121
"w:r/(w:rPr/w:rStyle{w:val=emphasis}, w:cr)",
2222
"foobar",
2323
'w:r/(w:rPr/w:rStyle{w:val=emphasis}, w:cr, w:t"foobar")',
2424
),
25-
]
25+
],
2626
)
27-
def add_t_fixture(self, request):
28-
initial_cxml, text, expected_cxml = request.param
29-
r = element(initial_cxml)
27+
def it_can_add_a_t_preserving_edge_whitespace(
28+
self, initial_cxml: str, text: str, expected_cxml: str
29+
):
30+
r = cast(CT_R, element(initial_cxml))
3031
expected_xml = xml(expected_cxml)
31-
return r, text, expected_xml
32+
33+
r.add_t(text)
34+
35+
assert r.xml == expected_xml

tests/text/test_paragraph.py

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,23 @@ def it_can_change_its_paragraph_style(self, style_set_fixture):
3434
)
3535
assert paragraph._p.xml == expected_xml
3636

37-
def it_knows_the_text_it_contains(self, text_get_fixture):
38-
paragraph, expected_text = text_get_fixture
39-
assert paragraph.text == expected_text
37+
@pytest.mark.parametrize(
38+
("p_cxml", "expected_value"),
39+
[
40+
("w:p", ""),
41+
("w:p/w:r", ""),
42+
("w:p/w:r/w:t", ""),
43+
('w:p/w:r/w:t"foo"', "foo"),
44+
('w:p/w:r/(w:t"foo", w:t"bar")', "foobar"),
45+
('w:p/w:r/(w:t"fo ", w:t"bar")', "fo bar"),
46+
('w:p/w:r/(w:t"foo", w:tab, w:t"bar")', "foo\tbar"),
47+
('w:p/w:r/(w:t"foo", w:br, w:t"bar")', "foo\nbar"),
48+
('w:p/w:r/(w:t"foo", w:cr, w:t"bar")', "foo\nbar"),
49+
],
50+
)
51+
def it_knows_the_text_it_contains(self, p_cxml: str, expected_value: str):
52+
paragraph = Paragraph(element(p_cxml), None)
53+
assert paragraph.text == expected_value
4054

4155
def it_can_replace_the_text_it_contains(self, text_set_fixture):
4256
paragraph, text, expected_text = text_set_fixture
@@ -223,24 +237,6 @@ def style_set_fixture(self, request, part_prop_):
223237
expected_xml = xml(expected_cxml)
224238
return paragraph, value, expected_xml
225239

226-
@pytest.fixture(
227-
params=[
228-
("w:p", ""),
229-
("w:p/w:r", ""),
230-
("w:p/w:r/w:t", ""),
231-
('w:p/w:r/w:t"foo"', "foo"),
232-
('w:p/w:r/(w:t"foo", w:t"bar")', "foobar"),
233-
('w:p/w:r/(w:t"fo ", w:t"bar")', "fo bar"),
234-
('w:p/w:r/(w:t"foo", w:tab, w:t"bar")', "foo\tbar"),
235-
('w:p/w:r/(w:t"foo", w:br, w:t"bar")', "foo\nbar"),
236-
('w:p/w:r/(w:t"foo", w:cr, w:t"bar")', "foo\nbar"),
237-
]
238-
)
239-
def text_get_fixture(self, request):
240-
p_cxml, expected_text_value = request.param
241-
paragraph = Paragraph(element(p_cxml), None)
242-
return paragraph, expected_text_value
243-
244240
@pytest.fixture
245241
def text_set_fixture(self):
246242
paragraph = Paragraph(element("w:p"), None)

tests/text/test_run.py

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
"""Test suite for the docx.text.run module."""
22

3+
from __future__ import annotations
4+
5+
from typing import cast
6+
37
import pytest
48

59
from docx.enum.style import WD_STYLE_TYPE
610
from docx.enum.text import WD_BREAK, WD_UNDERLINE
11+
from docx.oxml.text.run import CT_R
712
from docx.parts.document import DocumentPart
813
from docx.shape import InlineShape
914
from docx.text.font import Font
@@ -64,9 +69,23 @@ def it_can_add_text(self, add_text_fixture, Text_):
6469
assert run._r.xml == expected_xml
6570
assert _text is Text_.return_value
6671

67-
def it_can_add_a_break(self, add_break_fixture):
68-
run, break_type, expected_xml = add_break_fixture
72+
@pytest.mark.parametrize(
73+
("break_type", "expected_cxml"),
74+
[
75+
(WD_BREAK.LINE, "w:r/w:br"),
76+
(WD_BREAK.PAGE, "w:r/w:br{w:type=page}"),
77+
(WD_BREAK.COLUMN, "w:r/w:br{w:type=column}"),
78+
(WD_BREAK.LINE_CLEAR_LEFT, "w:r/w:br{w:type=textWrapping, w:clear=left}"),
79+
(WD_BREAK.LINE_CLEAR_RIGHT, "w:r/w:br{w:type=textWrapping, w:clear=right}"),
80+
(WD_BREAK.LINE_CLEAR_ALL, "w:r/w:br{w:type=textWrapping, w:clear=all}"),
81+
],
82+
)
83+
def it_can_add_a_break(self, break_type: WD_BREAK, expected_cxml: str):
84+
run = Run(element("w:r"), None)
85+
expected_xml = xml(expected_cxml)
86+
6987
run.add_break(break_type)
88+
7089
assert run._r.xml == expected_xml
7190

7291
def it_can_add_a_tab(self, add_tab_fixture):
@@ -91,8 +110,18 @@ def it_can_remove_its_content_but_keep_formatting(self, clear_fixture):
91110
assert run._r.xml == expected_xml
92111
assert _run is run
93112

94-
def it_knows_the_text_it_contains(self, text_get_fixture):
95-
run, expected_text = text_get_fixture
113+
@pytest.mark.parametrize(
114+
("r_cxml", "expected_text"),
115+
[
116+
("w:r", ""),
117+
('w:r/w:t"foobar"', "foobar"),
118+
('w:r/(w:t"abc", w:tab, w:t"def", w:cr)', "abc\tdef\n"),
119+
('w:r/(w:br{w:type=page}, w:t"abc", w:t"def", w:tab)', "\nabcdef\t"),
120+
],
121+
)
122+
def it_knows_the_text_it_contains(self, r_cxml: str, expected_text: str):
123+
r = cast(CT_R, element(r_cxml))
124+
run = Run(r, None) # pyright: ignore[reportGeneralTypeIssues]
96125
assert run.text == expected_text
97126

98127
def it_can_replace_the_text_it_contains(self, text_set_fixture):
@@ -102,22 +131,6 @@ def it_can_replace_the_text_it_contains(self, text_set_fixture):
102131

103132
# fixtures -------------------------------------------------------
104133

105-
@pytest.fixture(
106-
params=[
107-
(WD_BREAK.LINE, "w:r/w:br"),
108-
(WD_BREAK.PAGE, "w:r/w:br{w:type=page}"),
109-
(WD_BREAK.COLUMN, "w:r/w:br{w:type=column}"),
110-
(WD_BREAK.LINE_CLEAR_LEFT, "w:r/w:br{w:type=textWrapping, w:clear=left}"),
111-
(WD_BREAK.LINE_CLEAR_RIGHT, "w:r/w:br{w:type=textWrapping, w:clear=right}"),
112-
(WD_BREAK.LINE_CLEAR_ALL, "w:r/w:br{w:type=textWrapping, w:clear=all}"),
113-
]
114-
)
115-
def add_break_fixture(self, request):
116-
break_type, expected_cxml = request.param
117-
run = Run(element("w:r"), None)
118-
expected_xml = xml(expected_cxml)
119-
return run, break_type, expected_xml
120-
121134
@pytest.fixture
122135
def add_picture_fixture(self, part_prop_, document_part_, InlineShape_, picture_):
123136
run = Run(element("w:r/wp:x"), None)
@@ -247,19 +260,6 @@ def style_set_fixture(self, request, part_prop_):
247260
expected_xml = xml(expected_cxml)
248261
return run, value, expected_xml
249262

250-
@pytest.fixture(
251-
params=[
252-
("w:r", ""),
253-
('w:r/w:t"foobar"', "foobar"),
254-
('w:r/(w:t"abc", w:tab, w:t"def", w:cr)', "abc\tdef\n"),
255-
('w:r/(w:br{w:type=page}, w:t"abc", w:t"def", w:tab)', "\nabcdef\t"),
256-
]
257-
)
258-
def text_get_fixture(self, request):
259-
r_cxml, expected_text = request.param
260-
run = Run(element(r_cxml), None)
261-
return run, expected_text
262-
263263
@pytest.fixture(
264264
params=[
265265
("abc def", 'w:r/w:t"abc def"'),

tests/unitutil/cxml.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@
2828
# ====================================================================
2929

3030

31-
def element(cxel_str):
31+
def element(cxel_str: str):
3232
"""Return an oxml element parsed from the XML generated from `cxel_str`."""
3333
_xml = xml(cxel_str)
3434
return parse_xml(_xml)
3535

3636

37-
def xml(cxel_str):
37+
def xml(cxel_str: str) -> str:
3838
"""Return the XML generated from `cxel_str`."""
3939
root_token = root_node.parseString(cxel_str)
4040
xml = root_token.element.xml

0 commit comments

Comments
 (0)
0