Skip to content

Commit 677694b

Browse files
author
Steve Canny
committed
style: add StylesPart
1 parent f1ca7b4 commit 677694b

File tree

4 files changed

+143
-0
lines changed

4 files changed

+143
-0
lines changed

docx/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from docx.parts.document import DocumentPart
1414
from docx.parts.image import ImagePart
1515
from docx.parts.numbering import NumberingPart
16+
from docx.parts.styles import StylesPart
1617

1718

1819
def part_class_selector(content_type, reltype):
@@ -24,5 +25,6 @@ def part_class_selector(content_type, reltype):
2425
PartFactory.part_class_selector = part_class_selector
2526
PartFactory.part_type_for[CT.WML_DOCUMENT_MAIN] = DocumentPart
2627
PartFactory.part_type_for[CT.WML_NUMBERING] = NumberingPart
28+
PartFactory.part_type_for[CT.WML_STYLES] = StylesPart
2729

2830
del CT, DocumentPart, PartFactory, part_class_selector

docx/oxml/parts/styles.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# encoding: utf-8
2+
3+
"""
4+
Custom element classes related to the styles part
5+
"""
6+
7+
from docx.oxml.shared import OxmlBaseElement
8+
9+
10+
class CT_Styles(OxmlBaseElement):
11+
"""
12+
``<w:styles>`` element, the root element of a styles part, i.e.
13+
styles.xml
14+
"""

docx/parts/styles.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,29 @@
99
)
1010

1111
from ..opc.package import Part
12+
from ..oxml.shared import oxml_fromstring
1213

1314

1415
class StylesPart(Part):
1516
"""
1617
Proxy for the styles.xml part containing style definitions for a document
1718
or glossary.
1819
"""
20+
def __init__(self, partname, content_type, element, package):
21+
super(StylesPart, self).__init__(
22+
partname, content_type, element=element, package=package
23+
)
24+
25+
@classmethod
26+
def load(cls, partname, content_type, blob, package):
27+
"""
28+
Provides PartFactory interface for loading a styles part from a WML
29+
package.
30+
"""
31+
styles_elm = oxml_fromstring(blob)
32+
styles_part = cls(partname, content_type, styles_elm, package)
33+
return styles_part
34+
1935
@classmethod
2036
def new(cls):
2137
"""

tests/parts/test_styles.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# encoding: utf-8
2+
3+
"""
4+
Test suite for the docx.parts.styles module
5+
"""
6+
7+
from __future__ import absolute_import, print_function, unicode_literals
8+
9+
import pytest
10+
11+
from docx.opc.constants import CONTENT_TYPE as CT, RELATIONSHIP_TYPE as RT
12+
from docx.opc.package import PartFactory
13+
from docx.opc.packuri import PackURI
14+
from docx.oxml.parts.styles import CT_Styles
15+
from docx.package import Package
16+
from docx.parts.styles import StylesPart
17+
18+
from ..unitutil import (
19+
function_mock, initializer_mock, instance_mock, method_mock
20+
)
21+
22+
23+
class DescribeStylesPart(object):
24+
25+
def it_is_used_by_PartFactory_to_construct_styles_part(
26+
self, load_fixture):
27+
# fixture ----------------------
28+
styles_part_load_, partname_, blob_, package_, styles_part_ = (
29+
load_fixture
30+
)
31+
content_type, reltype = CT.WML_STYLES, RT.STYLES
32+
# exercise ---------------------
33+
part = PartFactory(partname_, content_type, reltype, blob_, package_)
34+
# verify -----------------------
35+
styles_part_load_.assert_called_once_with(
36+
partname_, content_type, blob_, package_
37+
)
38+
assert part is styles_part_
39+
40+
def it_can_be_constructed_by_opc_part_factory(self, construct_fixture):
41+
(partname_, content_type_, blob_, package_, oxml_fromstring_,
42+
init__, styles_elm_) = construct_fixture
43+
# exercise ---------------------
44+
styles_part = StylesPart.load(
45+
partname_, content_type_, blob_, package_
46+
)
47+
# verify -----------------------
48+
oxml_fromstring_.assert_called_once_with(blob_)
49+
init__.assert_called_once_with(
50+
partname_, content_type_, styles_elm_, package_
51+
)
52+
assert isinstance(styles_part, StylesPart)
53+
54+
# fixtures -------------------------------------------------------
55+
56+
@pytest.fixture
57+
def blob_(self, request):
58+
return instance_mock(request, bytes)
59+
60+
@pytest.fixture
61+
def construct_fixture(
62+
self, partname_, content_type_, blob_, package_,
63+
oxml_fromstring_, init__, styles_elm_):
64+
return (
65+
partname_, content_type_, blob_, package_, oxml_fromstring_,
66+
init__, styles_elm_
67+
)
68+
69+
@pytest.fixture
70+
def content_type_(self, request):
71+
return instance_mock(request, str)
72+
73+
@pytest.fixture
74+
def init__(self, request):
75+
return initializer_mock(request, StylesPart)
76+
77+
@pytest.fixture
78+
def load_fixture(
79+
self, styles_part_load_, partname_, blob_, package_,
80+
styles_part_):
81+
styles_part_load_.return_value = styles_part_
82+
return (
83+
styles_part_load_, partname_, blob_, package_, styles_part_
84+
)
85+
86+
@pytest.fixture
87+
def oxml_fromstring_(self, request, styles_elm_):
88+
return function_mock(
89+
request, 'docx.parts.styles.oxml_fromstring',
90+
return_value=styles_elm_
91+
)
92+
93+
@pytest.fixture
94+
def package_(self, request):
95+
return instance_mock(request, Package)
96+
97+
@pytest.fixture
98+
def partname_(self, request):
99+
return instance_mock(request, PackURI)
100+
101+
@pytest.fixture
102+
def styles_elm_(self, request):
103+
return instance_mock(request, CT_Styles)
104+
105+
@pytest.fixture
106+
def styles_part_(self, request):
107+
return instance_mock(request, StylesPart)
108+
109+
@pytest.fixture
110+
def styles_part_load_(self, request):
111+
return method_mock(request, StylesPart, 'load')

0 commit comments

Comments
 (0)