Repository URL to install this package:
|
Version:
0.8.9 ▾
|
# encoding: utf-8
"""
Test suite for the docx.text.tabstops module, containing the TabStops and
TabStop objects.
"""
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
from docx.enum.text import WD_TAB_ALIGNMENT, WD_TAB_LEADER
from docx.shared import Twips
from docx.text.tabstops import TabStop, TabStops
import pytest
from ..unitutil.cxml import element, xml
from ..unitutil.mock import call, class_mock, instance_mock
class DescribeTabStop(object):
def it_knows_its_position(self, position_get_fixture):
tab_stop, expected_value = position_get_fixture
assert tab_stop.position == expected_value
def it_can_change_its_position(self, position_set_fixture):
tab_stop, value, tabs, new_idx, expected_xml = position_set_fixture
tab_stop.position = value
assert tab_stop._tab is tabs[new_idx]
assert tabs.xml == expected_xml
def it_knows_its_alignment(self, alignment_get_fixture):
tab_stop, expected_value = alignment_get_fixture
assert tab_stop.alignment == expected_value
def it_can_change_its_alignment(self, alignment_set_fixture):
tab_stop, value, expected_xml = alignment_set_fixture
tab_stop.alignment = value
assert tab_stop._element.xml == expected_xml
def it_knows_its_leader(self, leader_get_fixture):
tab_stop, expected_value = leader_get_fixture
assert tab_stop.leader == expected_value
def it_can_change_its_leader(self, leader_set_fixture):
tab_stop, value, expected_xml = leader_set_fixture
tab_stop.leader = value
assert tab_stop._element.xml == expected_xml
# fixture --------------------------------------------------------
@pytest.fixture(params=[
('w:tab{w:val=left}', 'LEFT'),
('w:tab{w:val=right}', 'RIGHT'),
])
def alignment_get_fixture(self, request):
tab_stop_cxml, member = request.param
tab_stop = TabStop(element(tab_stop_cxml))
expected_value = getattr(WD_TAB_ALIGNMENT, member)
return tab_stop, expected_value
@pytest.fixture(params=[
('w:tab{w:val=left}', 'RIGHT', 'w:tab{w:val=right}'),
('w:tab{w:val=right}', 'LEFT', 'w:tab{w:val=left}'),
])
def alignment_set_fixture(self, request):
tab_stop_cxml, member, expected_cxml = request.param
tab_stop = TabStop(element(tab_stop_cxml))
expected_xml = xml(expected_cxml)
value = getattr(WD_TAB_ALIGNMENT, member)
return tab_stop, value, expected_xml
@pytest.fixture(params=[
('w:tab', 'SPACES'),
('w:tab{w:leader=none}', 'SPACES'),
('w:tab{w:leader=dot}', 'DOTS'),
])
def leader_get_fixture(self, request):
tab_stop_cxml, member = request.param
tab_stop = TabStop(element(tab_stop_cxml))
expected_value = getattr(WD_TAB_LEADER, member)
return tab_stop, expected_value
@pytest.fixture(params=[
('w:tab', 'DOTS', 'w:tab{w:leader=dot}'),
('w:tab{w:leader=dot}', 'DASHES', 'w:tab{w:leader=hyphen}'),
('w:tab{w:leader=hyphen}', 'SPACES', 'w:tab'),
('w:tab{w:leader=hyphen}', None, 'w:tab'),
('w:tab', 'SPACES', 'w:tab'),
('w:tab', None, 'w:tab'),
])
def leader_set_fixture(self, request):
tab_stop_cxml, new_value, expected_cxml = request.param
tab_stop = TabStop(element(tab_stop_cxml))
value = (
None if new_value is None else getattr(WD_TAB_LEADER, new_value)
)
expected_xml = xml(expected_cxml)
return tab_stop, value, expected_xml
@pytest.fixture
def position_get_fixture(self, request):
tab_stop = TabStop(element('w:tab{w:pos=720}'))
return tab_stop, Twips(720)
@pytest.fixture(params=[
('w:tabs/w:tab{w:pos=360,w:val=left}',
Twips(720), 0,
'w:tabs/w:tab{w:pos=720,w:val=left}'),
('w:tabs/(w:tab{w:pos=360,w:val=left},w:tab{w:pos=720,w:val=left})',
Twips(180), 0,
'w:tabs/(w:tab{w:pos=180,w:val=left},w:tab{w:pos=720,w:val=left})'),
('w:tabs/(w:tab{w:pos=360,w:val=left},w:tab{w:pos=720,w:val=left})',
Twips(960), 1,
'w:tabs/(w:tab{w:pos=720,w:val=left},w:tab{w:pos=960,w:val=left})'),
('w:tabs/(w:tab{w:pos=-72,w:val=left},w:tab{w:pos=-36,w:val=left})',
Twips(-48), 0,
'w:tabs/(w:tab{w:pos=-48,w:val=left},w:tab{w:pos=-36,w:val=left})'),
('w:tabs/(w:tab{w:pos=-72,w:val=left},w:tab{w:pos=-36,w:val=left})',
Twips(-16), 1,
'w:tabs/(w:tab{w:pos=-36,w:val=left},w:tab{w:pos=-16,w:val=left})'),
])
def position_set_fixture(self, request):
tabs_cxml, value, new_idx, expected_cxml = request.param
tabs = element(tabs_cxml)
tab = tabs.tab_lst[0]
tab_stop = TabStop(tab)
expected_xml = xml(expected_cxml)
return tab_stop, value, tabs, new_idx, expected_xml
class DescribeTabStops(object):
def it_knows_its_length(self, len_fixture):
tab_stops, expected_value = len_fixture
assert len(tab_stops) == expected_value
def it_can_iterate_over_its_tab_stops(self, iter_fixture):
tab_stops, expected_count, tab_stop_, TabStop_, expected_calls = (
iter_fixture
)
count = 0
for tab_stop in tab_stops:
assert tab_stop is tab_stop_
count += 1
assert count == expected_count
assert TabStop_.call_args_list == expected_calls
def it_can_get_a_tab_stop_by_index(self, index_fixture):
tab_stops, idx, TabStop_, tab, tab_stop_ = index_fixture
tab_stop = tab_stops[idx]
TabStop_.assert_called_once_with(tab)
assert tab_stop is tab_stop_
def it_raises_on_indexed_access_when_empty(self):
tab_stops = TabStops(element('w:pPr'))
with pytest.raises(IndexError):
tab_stops[0]
def it_can_add_a_tab_stop(self, add_tab_fixture):
tab_stops, position, kwargs, expected_xml = add_tab_fixture
tab_stops.add_tab_stop(position, **kwargs)
assert tab_stops._element.xml == expected_xml
def it_can_delete_a_tab_stop(self, del_fixture):
tab_stops, idx, expected_xml = del_fixture
del tab_stops[idx]
assert tab_stops._element.xml == expected_xml
def it_raises_on_del_idx_invalid(self, del_raises_fixture):
tab_stops, idx = del_raises_fixture
with pytest.raises(IndexError) as exc:
del tab_stops[idx]
assert exc.value.args[0] == 'tab index out of range'
def it_can_clear_all_its_tab_stops(self, clear_all_fixture):
tab_stops, expected_xml = clear_all_fixture
tab_stops.clear_all()
assert tab_stops._element.xml == expected_xml
# fixture --------------------------------------------------------
@pytest.fixture(params=[
'w:pPr',
'w:pPr/w:tabs/w:tab{w:pos=42}',
'w:pPr/w:tabs/(w:tab{w:pos=24},w:tab{w:pos=42})',
])
def clear_all_fixture(self, request):
pPr_cxml = request.param
tab_stops = TabStops(element(pPr_cxml))
expected_xml = xml('w:pPr')
return tab_stops, expected_xml
@pytest.fixture(params=[
('w:pPr/w:tabs/w:tab{w:pos=42}', 0,
'w:pPr'),
('w:pPr/w:tabs/(w:tab{w:pos=24},w:tab{w:pos=42})', 0,
'w:pPr/w:tabs/w:tab{w:pos=42}'),
('w:pPr/w:tabs/(w:tab{w:pos=24},w:tab{w:pos=42})', 1,
'w:pPr/w:tabs/w:tab{w:pos=24}'),
])
def del_fixture(self, request):
pPr_cxml, idx, expected_cxml = request.param
tab_stops = TabStops(element(pPr_cxml))
expected_xml = xml(expected_cxml)
return tab_stops, idx, expected_xml
@pytest.fixture(params=[
('w:pPr', 0),
('w:pPr/w:tabs/w:tab{w:pos=42}', 1),
])
def del_raises_fixture(self, request):
tab_stops_cxml, idx = request.param
tab_stops = TabStops(element(tab_stops_cxml))
return tab_stops, idx
@pytest.fixture(params=[
('w:pPr', Twips(42), {},
'w:pPr/w:tabs/w:tab{w:pos=42,w:val=left}'),
('w:pPr', Twips(72), {'alignment': WD_TAB_ALIGNMENT.RIGHT},
'w:pPr/w:tabs/w:tab{w:pos=72,w:val=right}'),
('w:pPr', Twips(24),
{'alignment': WD_TAB_ALIGNMENT.CENTER,
'leader': WD_TAB_LEADER.DOTS},
'w:pPr/w:tabs/w:tab{w:pos=24,w:val=center,w:leader=dot}'),
('w:pPr/w:tabs/w:tab{w:pos=42}', Twips(72), {},
'w:pPr/w:tabs/(w:tab{w:pos=42},w:tab{w:pos=72,w:val=left})'),
('w:pPr/w:tabs/w:tab{w:pos=42}', Twips(24), {},
'w:pPr/w:tabs/(w:tab{w:pos=24,w:val=left},w:tab{w:pos=42})'),
('w:pPr/w:tabs/w:tab{w:pos=42}', Twips(42), {},
'w:pPr/w:tabs/(w:tab{w:pos=42},w:tab{w:pos=42,w:val=left})'),
])
def add_tab_fixture(self, request):
pPr_cxml, position, kwargs, expected_cxml = request.param
tab_stops = TabStops(element(pPr_cxml))
expected_xml = xml(expected_cxml)
return tab_stops, position, kwargs, expected_xml
@pytest.fixture(params=[
('w:pPr/w:tabs/w:tab{w:pos=0}', 0),
('w:pPr/w:tabs/(w:tab{w:pos=1},w:tab{w:pos=2},w:tab{w:pos=3})', 1),
('w:pPr/w:tabs/(w:tab{w:pos=4},w:tab{w:pos=5},w:tab{w:pos=6})', 2),
])
def index_fixture(self, request, TabStop_, tab_stop_):
pPr_cxml, idx = request.param
pPr = element(pPr_cxml)
tab = pPr.xpath('./w:tabs/w:tab')[idx]
tab_stops = TabStops(pPr)
return tab_stops, idx, TabStop_, tab, tab_stop_
@pytest.fixture(params=[
('w:pPr', 0),
('w:pPr/w:tabs/w:tab{w:pos=2880}', 1),
('w:pPr/w:tabs/(w:tab{w:pos=2880},w:tab{w:pos=5760})', 2),
])
def iter_fixture(self, request, TabStop_, tab_stop_):
pPr_cxml, expected_count = request.param
pPr = element(pPr_cxml)
tab_elms = pPr.xpath('//w:tab')
tab_stops = TabStops(pPr)
expected_calls = [call(tab) for tab in tab_elms]
return tab_stops, expected_count, tab_stop_, TabStop_, expected_calls
@pytest.fixture(params=[
('w:pPr', 0),
('w:pPr/w:tabs/w:tab{w:pos=2880}', 1),
])
def len_fixture(self, request):
tab_stops_cxml, expected_value = request.param
tab_stops = TabStops(element(tab_stops_cxml))
return tab_stops, expected_value
# fixture components ---------------------------------------------
@pytest.fixture
def TabStop_(self, request, tab_stop_):
return class_mock(
request, 'docx.text.tabstops.TabStop', return_value=tab_stop_
)
@pytest.fixture
def tab_stop_(self, request):
return instance_mock(request, TabStop)