Skip to content

Commit c16e55e

Browse files
committed
hdr: add _BaseHeaderFooter.is_linked_to_p.. setter
1 parent eb48298 commit c16e55e

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

docx/section.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,25 @@ def is_linked_to_previous(self):
232232
# ---absence of a header/footer part indicates "linked" behavior---
233233
return not self._has_definition
234234

235+
@is_linked_to_previous.setter
236+
def is_linked_to_previous(self, value):
237+
new_state = bool(value)
238+
# ---do nothing when value is not being changed---
239+
if new_state == self.is_linked_to_previous:
240+
return
241+
if new_state is True:
242+
self._drop_definition()
243+
else:
244+
self._add_definition()
245+
246+
def _add_definition(self):
247+
"""Return newly-added header/footer part."""
248+
raise NotImplementedError("must be implemented by each subclass")
249+
250+
def _drop_definition(self):
251+
"""Remove header/footer part containing the definition of this header/footer."""
252+
raise NotImplementedError("must be implemented by each subclass")
253+
235254
@property
236255
def _has_definition(self):
237256
"""True if this header/footer has a related part containing its definition."""

tests/test_section.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ def header_(self, request):
360360

361361
class Describe_BaseHeaderFooter(object):
362362

363-
def it_knows_when_its_linked_to_the_previous_header(
363+
def it_knows_when_its_linked_to_the_previous_header_or_footer(
364364
self, is_linked_get_fixture, _has_definition_prop_
365365
):
366366
has_definition, expected_value = is_linked_get_fixture
@@ -371,15 +371,51 @@ def it_knows_when_its_linked_to_the_previous_header(
371371

372372
assert is_linked is expected_value
373373

374+
def it_can_change_whether_it_is_linked_to_previous_header_or_footer(
375+
self,
376+
is_linked_set_fixture,
377+
_has_definition_prop_,
378+
_drop_definition_,
379+
_add_definition_,
380+
):
381+
has_definition, new_value, drop_calls, add_calls = is_linked_set_fixture
382+
_has_definition_prop_.return_value = has_definition
383+
header = _BaseHeaderFooter(None, None)
384+
385+
header.is_linked_to_previous = new_value
386+
387+
assert _drop_definition_.call_args_list == [call(header)] * drop_calls
388+
assert _add_definition_.call_args_list == [call(header)] * add_calls
389+
374390
# fixtures -------------------------------------------------------
375391

376392
@pytest.fixture(params=[(False, True), (True, False)])
377393
def is_linked_get_fixture(self, request):
378394
has_definition, expected_value = request.param
379395
return has_definition, expected_value
380396

397+
@pytest.fixture(
398+
params=[
399+
(False, True, 0, 0),
400+
(True, False, 0, 0),
401+
(True, True, 1, 0),
402+
(False, False, 0, 1),
403+
]
404+
)
405+
def is_linked_set_fixture(self, request):
406+
has_definition, new_value, drop_calls, add_calls = request.param
407+
return has_definition, new_value, drop_calls, add_calls
408+
381409
# fixture components ---------------------------------------------
382410

411+
@pytest.fixture
412+
def _add_definition_(self, request):
413+
return method_mock(request, _BaseHeaderFooter, "_add_definition")
414+
415+
@pytest.fixture
416+
def _drop_definition_(self, request):
417+
return method_mock(request, _BaseHeaderFooter, "_drop_definition")
418+
383419
@pytest.fixture
384420
def _has_definition_prop_(self, request):
385421
return property_mock(request, _BaseHeaderFooter, "_has_definition")

0 commit comments

Comments
 (0)