Repository URL to install this package:
|
Version:
0.8.10 ▾
|
# encoding: utf-8
"""
Test suite for the docx.styles.style module
"""
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import pytest
from docx.enum.style import WD_STYLE_TYPE
from docx.styles.style import (
BaseStyle, _CharacterStyle, _ParagraphStyle, _NumberingStyle,
StyleFactory, _TableStyle
)
from docx.text.font import Font
from docx.text.parfmt import ParagraphFormat
from ..unitutil.cxml import element, xml
from ..unitutil.mock import call, class_mock, function_mock, instance_mock
class DescribeStyleFactory(object):
def it_constructs_the_right_type_of_style(self, factory_fixture):
style_elm, StyleCls_, style_ = factory_fixture
style = StyleFactory(style_elm)
StyleCls_.assert_called_once_with(style_elm)
assert style is style_
# fixtures -------------------------------------------------------
@pytest.fixture(params=['paragraph', 'character', 'table', 'numbering'])
def factory_fixture(
self, request, paragraph_style_, _ParagraphStyle_,
character_style_, _CharacterStyle_, table_style_, _TableStyle_,
numbering_style_, _NumberingStyle_):
type_attr_val = request.param
StyleCls_, style_mock = {
'paragraph': (_ParagraphStyle_, paragraph_style_),
'character': (_CharacterStyle_, character_style_),
'table': (_TableStyle_, table_style_),
'numbering': (_NumberingStyle_, numbering_style_),
}[request.param]
style_cxml = 'w:style{w:type=%s}' % type_attr_val
style_elm = element(style_cxml)
return style_elm, StyleCls_, style_mock
# fixture components -----------------------------------
@pytest.fixture
def _ParagraphStyle_(self, request, paragraph_style_):
return class_mock(
request, 'docx.styles.style._ParagraphStyle',
return_value=paragraph_style_
)
@pytest.fixture
def paragraph_style_(self, request):
return instance_mock(request, _ParagraphStyle)
@pytest.fixture
def _CharacterStyle_(self, request, character_style_):
return class_mock(
request, 'docx.styles.style._CharacterStyle',
return_value=character_style_
)
@pytest.fixture
def character_style_(self, request):
return instance_mock(request, _CharacterStyle)
@pytest.fixture
def _TableStyle_(self, request, table_style_):
return class_mock(
request, 'docx.styles.style._TableStyle',
return_value=table_style_
)
@pytest.fixture
def table_style_(self, request):
return instance_mock(request, _TableStyle)
@pytest.fixture
def _NumberingStyle_(self, request, numbering_style_):
return class_mock(
request, 'docx.styles.style._NumberingStyle',
return_value=numbering_style_
)
@pytest.fixture
def numbering_style_(self, request):
return instance_mock(request, _NumberingStyle)
class DescribeBaseStyle(object):
def it_knows_its_style_id(self, id_get_fixture):
style, expected_value = id_get_fixture
assert style.style_id == expected_value
def it_can_change_its_style_id(self, id_set_fixture):
style, new_value, expected_xml = id_set_fixture
style.style_id = new_value
assert style._element.xml == expected_xml
def it_knows_its_type(self, type_get_fixture):
style, expected_value = type_get_fixture
assert style.type == expected_value
def it_knows_its_name(self, name_get_fixture):
style, expected_value = name_get_fixture
assert style.name == expected_value
def it_can_change_its_name(self, name_set_fixture):
style, new_value, expected_xml = name_set_fixture
style.name = new_value
assert style._element.xml == expected_xml
def it_knows_whether_its_a_builtin_style(self, builtin_get_fixture):
style, expected_value = builtin_get_fixture
assert style.builtin is expected_value
def it_knows_whether_its_hidden(self, hidden_get_fixture):
style, expected_value = hidden_get_fixture
assert style.hidden == expected_value
def it_can_change_whether_its_hidden(self, hidden_set_fixture):
style, value, expected_xml = hidden_set_fixture
style.hidden = value
assert style._element.xml == expected_xml
def it_knows_its_sort_order(self, priority_get_fixture):
style, expected_value = priority_get_fixture
assert style.priority == expected_value
def it_can_change_its_sort_order(self, priority_set_fixture):
style, value, expected_xml = priority_set_fixture
style.priority = value
assert style._element.xml == expected_xml
def it_knows_whether_its_unhide_when_used(self, unhide_get_fixture):
style, expected_value = unhide_get_fixture
assert style.unhide_when_used == expected_value
def it_can_change_its_unhide_when_used_value(self, unhide_set_fixture):
style, value, expected_xml = unhide_set_fixture
style.unhide_when_used = value
assert style._element.xml == expected_xml
def it_knows_its_quick_style_setting(self, quick_get_fixture):
style, expected_value = quick_get_fixture
assert style.quick_style == expected_value
def it_can_change_its_quick_style_setting(self, quick_set_fixture):
style, new_value, expected_xml = quick_set_fixture
style.quick_style = new_value
assert style._element.xml == expected_xml
def it_knows_whether_its_locked(self, locked_get_fixture):
style, expected_value = locked_get_fixture
assert style.locked == expected_value
def it_can_change_whether_its_locked(self, locked_set_fixture):
style, value, expected_xml = locked_set_fixture
style.locked = value
assert style._element.xml == expected_xml
def it_can_delete_itself_from_the_document(self, delete_fixture):
style, styles, expected_xml = delete_fixture
style.delete()
assert styles.xml == expected_xml
assert style._element is None
# fixture --------------------------------------------------------
@pytest.fixture(params=[
('w:style', True),
('w:style{w:customStyle=0}', True),
('w:style{w:customStyle=1}', False),
])
def builtin_get_fixture(self, request):
style_cxml, expected_value = request.param
style = BaseStyle(element(style_cxml))
return style, expected_value
@pytest.fixture
def delete_fixture(self):
styles = element('w:styles/w:style')
style = BaseStyle(styles[0])
expected_xml = xml('w:styles')
return style, styles, expected_xml
@pytest.fixture(params=[
('w:style', False),
('w:style/w:semiHidden', True),
('w:style/w:semiHidden{w:val=0}', False),
('w:style/w:semiHidden{w:val=1}', True),
])
def hidden_get_fixture(self, request):
style_cxml, expected_value = request.param
style = BaseStyle(element(style_cxml))
return style, expected_value
@pytest.fixture(params=[
('w:style', True, 'w:style/w:semiHidden'),
('w:style/w:semiHidden{w:val=0}', True, 'w:style/w:semiHidden'),
('w:style/w:semiHidden{w:val=1}', True, 'w:style/w:semiHidden'),
('w:style', False, 'w:style'),
('w:style/w:semiHidden', False, 'w:style'),
('w:style/w:semiHidden{w:val=1}', False, 'w:style'),
])
def hidden_set_fixture(self, request):
style_cxml, value, expected_cxml = request.param
style = BaseStyle(element(style_cxml))
expected_xml = xml(expected_cxml)
return style, value, expected_xml
@pytest.fixture(params=[
('w:style', None),
('w:style{w:styleId=Foobar}', 'Foobar'),
])
def id_get_fixture(self, request):
style_cxml, expected_value = request.param
style = BaseStyle(element(style_cxml))
return style, expected_value
@pytest.fixture(params=[
('w:style', 'Foo', 'w:style{w:styleId=Foo}'),
('w:style{w:styleId=Foo}', 'Bar', 'w:style{w:styleId=Bar}'),
('w:style{w:styleId=Bar}', None, 'w:style'),
('w:style', None, 'w:style'),
])
def id_set_fixture(self, request):
style_cxml, new_value, expected_style_cxml = request.param
style = BaseStyle(element(style_cxml))
expected_xml = xml(expected_style_cxml)
return style, new_value, expected_xml
@pytest.fixture(params=[
('w:style', False),
('w:style/w:locked', True),
('w:style/w:locked{w:val=0}', False),
('w:style/w:locked{w:val=1}', True),
])
def locked_get_fixture(self, request):
style_cxml, expected_value = request.param
style = BaseStyle(element(style_cxml))
return style, expected_value
@pytest.fixture(params=[
('w:style', True, 'w:style/w:locked'),
('w:style/w:locked{w:val=0}', True, 'w:style/w:locked'),
('w:style/w:locked{w:val=1}', True, 'w:style/w:locked'),
('w:style', False, 'w:style'),
('w:style/w:locked', False, 'w:style'),
('w:style/w:locked{w:val=1}', False, 'w:style'),
])
def locked_set_fixture(self, request):
style_cxml, value, expected_cxml = request.param
style = BaseStyle(element(style_cxml))
expected_xml = xml(expected_cxml)
return style, value, expected_xml
@pytest.fixture(params=[
('w:style{w:type=table}', None),
('w:style{w:type=table}/w:name{w:val=Boofar}', 'Boofar'),
('w:style{w:type=table}/w:name{w:val=heading 1}', 'Heading 1'),
])
def name_get_fixture(self, request):
style_cxml, expected_value = request.param
style = BaseStyle(element(style_cxml))
return style, expected_value
@pytest.fixture(params=[
('w:style', 'Foo', 'w:style/w:name{w:val=Foo}'),
('w:style/w:name{w:val=Foo}', 'Bar', 'w:style/w:name{w:val=Bar}'),
('w:style/w:name{w:val=Bar}', None, 'w:style'),
])
def name_set_fixture(self, request):
style_cxml, new_value, expected_style_cxml = request.param
style = BaseStyle(element(style_cxml))
expected_xml = xml(expected_style_cxml)
return style, new_value, expected_xml
@pytest.fixture(params=[
('w:style', None),
('w:style/w:uiPriority{w:val=42}', 42),
])
def priority_get_fixture(self, request):
style_cxml, expected_value = request.param
style = BaseStyle(element(style_cxml))
return style, expected_value
@pytest.fixture(params=[
('w:style', 42,
'w:style/w:uiPriority{w:val=42}'),
('w:style/w:uiPriority{w:val=42}', 24,
'w:style/w:uiPriority{w:val=24}'),
('w:style/w:uiPriority{w:val=24}', None,
'w:style'),
])
def priority_set_fixture(self, request):
style_cxml, value, expected_cxml = request.param
style = BaseStyle(element(style_cxml))
expected_xml = xml(expected_cxml)
return style, value, expected_xml
@pytest.fixture(params=[
('w:style', False),
('w:style/w:qFormat', True),
('w:style/w:qFormat{w:val=0}', False),
('w:style/w:qFormat{w:val=on}', True),
])
def quick_get_fixture(self, request):
style_cxml, expected_value = request.param
style = BaseStyle(element(style_cxml))
return style, expected_value
@pytest.fixture(params=[
('w:style', True, 'w:style/w:qFormat'),
('w:style/w:qFormat', False, 'w:style'),
('w:style/w:qFormat', True, 'w:style/w:qFormat'),
('w:style/w:qFormat{w:val=0}', False, 'w:style'),
('w:style/w:qFormat{w:val=on}', True, 'w:style/w:qFormat'),
])
def quick_set_fixture(self, request):
style_cxml, new_value, expected_style_cxml = request.param
style = BaseStyle(element(style_cxml))
expected_xml = xml(expected_style_cxml)
return style, new_value, expected_xml
@pytest.fixture(params=[
('w:style', WD_STYLE_TYPE.PARAGRAPH),
('w:style{w:type=paragraph}', WD_STYLE_TYPE.PARAGRAPH),
('w:style{w:type=character}', WD_STYLE_TYPE.CHARACTER),
('w:style{w:type=numbering}', WD_STYLE_TYPE.LIST),
])
def type_get_fixture(self, request):
style_cxml, expected_value = request.param
style = BaseStyle(element(style_cxml))
return style, expected_value
@pytest.fixture(params=[
('w:style', False),
('w:style/w:unhideWhenUsed', True),
('w:style/w:unhideWhenUsed{w:val=0}', False),
('w:style/w:unhideWhenUsed{w:val=1}', True),
])
def unhide_get_fixture(self, request):
style_cxml, expected_value = request.param
style = BaseStyle(element(style_cxml))
return style, expected_value
@pytest.fixture(params=[
('w:style', True,
'w:style/w:unhideWhenUsed'),
('w:style/w:unhideWhenUsed', False,
'w:style'),
('w:style/w:unhideWhenUsed{w:val=0}', True,
'w:style/w:unhideWhenUsed'),
('w:style/w:unhideWhenUsed{w:val=1}', True,
'w:style/w:unhideWhenUsed'),
('w:style/w:unhideWhenUsed{w:val=1}', False,
'w:style'),
('w:style', False,
'w:style'),
])
def unhide_set_fixture(self, request):
style_cxml, value, expected_cxml = request.param
style = BaseStyle(element(style_cxml))
expected_xml = xml(expected_cxml)
return style, value, expected_xml
class Describe_CharacterStyle(object):
def it_knows_which_style_it_is_based_on(self, base_get_fixture):
style, StyleFactory_, StyleFactory_calls, base_style_ = (
base_get_fixture
)
base_style = style.base_style
assert StyleFactory_.call_args_list == StyleFactory_calls
assert base_style == base_style_
def it_can_change_its_base_style(self, base_set_fixture):
style, value, expected_xml = base_set_fixture
style.base_style = value
assert style._element.xml == expected_xml
def it_provides_access_to_its_font(self, font_fixture):
style, Font_, font_ = font_fixture
font = style.font
Font_.assert_called_once_with(style._element)
assert font is font_
# fixture --------------------------------------------------------
@pytest.fixture(params=[
('w:styles/(w:style{w:styleId=Foo},w:style/w:basedOn{w:val=Foo})',
1, 0),
('w:styles/(w:style{w:styleId=Foo},w:style/w:basedOn{w:val=Bar})',
1, -1),
('w:styles/w:style',
0, -1),
])
def base_get_fixture(self, request, StyleFactory_):
styles_cxml, style_idx, base_style_idx = request.param
styles = element(styles_cxml)
style = _CharacterStyle(styles[style_idx])
if base_style_idx >= 0:
base_style = styles[base_style_idx]
StyleFactory_calls = [call(base_style)]
expected_value = StyleFactory_.return_value
else:
StyleFactory_calls = []
expected_value = None
return style, StyleFactory_, StyleFactory_calls, expected_value
@pytest.fixture(params=[
('w:style', 'Foo',
'w:style/w:basedOn{w:val=Foo}'),
('w:style/w:basedOn{w:val=Foo}', 'Bar',
'w:style/w:basedOn{w:val=Bar}'),
('w:style/w:basedOn{w:val=Bar}', None,
'w:style'),
])
def base_set_fixture(self, request, style_):
style_cxml, base_style_id, expected_style_cxml = request.param
style = _CharacterStyle(element(style_cxml))
style_.style_id = base_style_id
base_style = style_ if base_style_id is not None else None
expected_xml = xml(expected_style_cxml)
return style, base_style, expected_xml
@pytest.fixture
def font_fixture(self, Font_, font_):
style = _CharacterStyle(element('w:style'))
return style, Font_, font_
# fixture components ---------------------------------------------
@pytest.fixture
def Font_(self, request, font_):
return class_mock(
request, 'docx.styles.style.Font', return_value=font_
)
@pytest.fixture
def font_(self, request):
return instance_mock(request, Font)
@pytest.fixture
def style_(self, request):
return instance_mock(request, BaseStyle)
@pytest.fixture
def StyleFactory_(self, request):
return function_mock(request, 'docx.styles.style.StyleFactory')
class Describe_ParagraphStyle(object):
def it_knows_its_next_paragraph_style(self, next_get_fixture):
style, expected_value = next_get_fixture
assert style.next_paragraph_style == expected_value
def it_can_change_its_next_paragraph_style(self, next_set_fixture):
style, next_style, expected_xml = next_set_fixture
style.next_paragraph_style = next_style
assert style.element.xml == expected_xml
def it_provides_access_to_its_paragraph_format(self, parfmt_fixture):
style, ParagraphFormat_, paragraph_format_ = parfmt_fixture
paragraph_format = style.paragraph_format
ParagraphFormat_.assert_called_once_with(style._element)
assert paragraph_format is paragraph_format_
# fixtures -------------------------------------------------------
@pytest.fixture(params=[
('H1', 'Body'),
('H2', 'H2'),
('Body', 'Body'),
('Foo', 'Foo'),
])
def next_get_fixture(self, request):
style_name, next_style_name = request.param
styles = element(
'w:styles/('
'w:style{w:type=paragraph,w:styleId=H1}/w:next{w:val=Body},'
'w:style{w:type=paragraph,w:styleId=H2}/w:next{w:val=Char},'
'w:style{w:type=paragraph,w:styleId=Body},'
'w:style{w:type=paragraph,w:styleId=Foo}/w:next{w:val=Bar},'
'w:style{w:type=character,w:styleId=Char})'
)
style_names = ['H1', 'H2', 'Body', 'Foo', 'Char']
style_elm = styles[style_names.index(style_name)]
next_style_elm = styles[style_names.index(next_style_name)]
style = _ParagraphStyle(style_elm)
if style_name == 'H1':
next_style = _ParagraphStyle(next_style_elm)
else:
next_style = style
return style, next_style
@pytest.fixture(params=[
('H', 'B', 'w:style{w:type=paragraph,w:styleId=H}/w:next{w:val=B}'),
('H', None, 'w:style{w:type=paragraph,w:styleId=H}'),
('H', 'H', 'w:style{w:type=paragraph,w:styleId=H}'),
])
def next_set_fixture(self, request):
style_name, next_style_name, style_cxml = request.param
styles = element(
'w:styles/('
'w:style{w:type=paragraph,w:styleId=H},'
'w:style{w:type=paragraph,w:styleId=B})'
)
style_elms = {'H': styles[0], 'B': styles[1]}
style = _ParagraphStyle(style_elms[style_name])
next_style = (
None if next_style_name is None else
_ParagraphStyle(style_elms[next_style_name])
)
expected_xml = xml(style_cxml)
return style, next_style, expected_xml
@pytest.fixture
def parfmt_fixture(self, ParagraphFormat_, paragraph_format_):
style = _ParagraphStyle(element('w:style'))
return style, ParagraphFormat_, paragraph_format_
# fixture components ---------------------------------------------
@pytest.fixture
def ParagraphFormat_(self, request, paragraph_format_):
return class_mock(
request, 'docx.styles.style.ParagraphFormat',
return_value=paragraph_format_
)
@pytest.fixture
def paragraph_format_(self, request):
return instance_mock(request, ParagraphFormat)