Skip to content

Commit aaf8da9

Browse files
author
Steve Canny
committed
blkct: extract BlockItemContainer._add_paragraph()
Allows the core of .add_paragraph() to be tested integrated with oxml while using mocks for the remainder.
1 parent 99aeee4 commit aaf8da9

File tree

2 files changed

+56
-17
lines changed

2 files changed

+56
-17
lines changed

docx/blkcntnr.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ def add_paragraph(self, text='', style=None):
3030
paragraph style *style*. If *style* is |None|, no paragraph style is
3131
applied, which has the same effect as applying the 'Normal' style.
3232
"""
33-
p = self._element.add_p()
34-
paragraph = Paragraph(p, self)
33+
paragraph = self._add_paragraph()
3534
if text:
3635
paragraph.add_run(text)
3736
if style is not None:
@@ -68,3 +67,10 @@ def tables(self):
6867
"""
6968
from .table import Table
7069
return [Table(tbl, self) for tbl in self._element.tbl_lst]
70+
71+
def _add_paragraph(self):
72+
"""
73+
Return a paragraph newly added to the end of the content in this
74+
container.
75+
"""
76+
return Paragraph(self._element.add_p(), self)

tests/test_blkcntnr.py

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,21 @@
1313
from docx.text.paragraph import Paragraph
1414

1515
from .unitutil.cxml import element, xml
16+
from .unitutil.mock import call, instance_mock, method_mock
1617

1718

1819
class DescribeBlockItemContainer(object):
1920

2021
def it_can_add_a_paragraph(self, add_paragraph_fixture):
21-
blkcntnr, text, style, expected_xml = add_paragraph_fixture
22-
paragraph = blkcntnr.add_paragraph(text, style)
23-
assert blkcntnr._element.xml == expected_xml
24-
assert isinstance(paragraph, Paragraph)
22+
blkcntnr, text, style, paragraph_, add_run_calls = (
23+
add_paragraph_fixture
24+
)
25+
new_paragraph = blkcntnr.add_paragraph(text, style)
26+
27+
blkcntnr._add_paragraph.assert_called_once_with()
28+
assert new_paragraph.add_run.call_args_list == add_run_calls
29+
assert new_paragraph.style == style
30+
assert new_paragraph is paragraph_
2531

2632
def it_can_add_a_table(self, add_table_fixture):
2733
blkcntnr, rows, cols, expected_xml = add_table_fixture
@@ -54,23 +60,36 @@ def it_provides_access_to_the_tables_it_contains(self, tables_fixture):
5460
count += 1
5561
assert count == expected_count
5662

63+
def it_adds_a_paragraph_to_help(self, _add_paragraph_fixture):
64+
blkcntnr, expected_xml = _add_paragraph_fixture
65+
new_paragraph = blkcntnr._add_paragraph()
66+
assert isinstance(new_paragraph, Paragraph)
67+
assert new_paragraph._parent == blkcntnr
68+
assert blkcntnr._element.xml == expected_xml
69+
5770
# fixtures -------------------------------------------------------
5871

5972
@pytest.fixture(params=[
60-
('w:body', '', None,
61-
'w:body/w:p'),
62-
('w:body', 'foobar', None,
63-
'w:body/w:p/w:r/w:t"foobar"'),
64-
('w:body', '', 'Heading1',
65-
'w:body/w:p/w:pPr/w:pStyle{w:val=Heading1}'),
66-
('w:body', 'barfoo', 'BodyText',
67-
'w:body/w:p/(w:pPr/w:pStyle{w:val=BodyText},w:r/w:t"barfoo")'),
73+
('', None),
74+
('Foo', None),
75+
('', 'Bar'),
76+
('Foo', 'Bar'),
6877
])
69-
def add_paragraph_fixture(self, request):
70-
blkcntnr_cxml, text, style, after_cxml = request.param
78+
def add_paragraph_fixture(self, request, _add_paragraph_, paragraph_,
79+
add_run_):
80+
blkcntnr = BlockItemContainer(None, None)
81+
text, style = request.param
82+
_add_paragraph_.return_value = paragraph_
83+
add_run_calls = [call(text)] if text else []
84+
paragraph_.style = None
85+
return blkcntnr, text, style, paragraph_, add_run_calls
86+
87+
@pytest.fixture
88+
def _add_paragraph_fixture(self, request):
89+
blkcntnr_cxml, after_cxml = 'w:body', 'w:body/w:p'
7190
blkcntnr = BlockItemContainer(element(blkcntnr_cxml), None)
7291
expected_xml = xml(after_cxml)
73-
return blkcntnr, text, style, expected_xml
92+
return blkcntnr, expected_xml
7493

7594
@pytest.fixture(params=[
7695
('w:body', 0, 0, 'w:body/w:tbl/(w:tblPr/w:tblW{w:type=auto,w:w=0},w:'
@@ -111,3 +130,17 @@ def tables_fixture(self, request):
111130
blkcntnr_cxml, expected_count = request.param
112131
blkcntnr = BlockItemContainer(element(blkcntnr_cxml), None)
113132
return blkcntnr, expected_count
133+
134+
# fixture components ---------------------------------------------
135+
136+
@pytest.fixture
137+
def _add_paragraph_(self, request):
138+
return method_mock(request, BlockItemContainer, '_add_paragraph')
139+
140+
@pytest.fixture
141+
def add_run_(self, request):
142+
return method_mock(request, Paragraph, 'add_run')
143+
144+
@pytest.fixture
145+
def paragraph_(self, request):
146+
return instance_mock(request, Paragraph)

0 commit comments

Comments
 (0)