Skip to content

Commit 9d753de

Browse files
author
Steve Canny
committed
test: incorporate declarative BaseBuilder
1 parent c5d2223 commit 9d753de

File tree

6 files changed

+208
-261
lines changed

6 files changed

+208
-261
lines changed

tests/oxml/test_parts.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from docx.oxml.text import CT_P
99

1010
from .unitdata.parts import a_body, a_document
11+
from .unitdata.text import a_p, a_sectPr
1112

1213

1314
class DescribeCT_Body(object):
@@ -18,38 +19,44 @@ def it_can_add_a_p_to_itself(self):
1819
existing content.
1920
"""
2021
cases = (
21-
(a_body(), a_body().with_p()),
22-
(a_body().with_sectPr(), a_body().with_p().with_sectPr()),
22+
(a_body().with_nsdecls(),
23+
a_body().with_nsdecls().with_child(a_p())),
24+
(a_body().with_nsdecls().with_child(a_sectPr()),
25+
a_body().with_nsdecls().with_child(a_p()).with_child(a_sectPr())),
2326
)
2427
for before_body_bldr, after_body_bldr in cases:
2528
body = before_body_bldr.element
2629
# exercise -----------------
2730
p = body.add_p()
2831
# verify -------------------
2932
print(body.xml)
30-
assert body.xml == after_body_bldr.xml
33+
assert body.xml == after_body_bldr.xml()
3134
assert isinstance(p, CT_P)
3235

3336
def it_can_clear_all_the_content_it_holds(self):
3437
"""
3538
Remove all content child elements from this <w:body> element.
3639
"""
3740
cases = (
38-
(a_body(), a_body()),
39-
(a_body().with_p(), a_body()),
40-
(a_body().with_sectPr(), a_body().with_sectPr()),
41-
(a_body().with_p().with_sectPr(), a_body().with_sectPr()),
41+
(a_body().with_nsdecls(),
42+
a_body().with_nsdecls()),
43+
(a_body().with_nsdecls().with_child(a_p()),
44+
a_body().with_nsdecls()),
45+
(a_body().with_nsdecls().with_child(a_sectPr()),
46+
a_body().with_nsdecls().with_child(a_sectPr())),
47+
(a_body().with_nsdecls().with_child(a_p()).with_child(a_sectPr()),
48+
a_body().with_nsdecls().with_child(a_sectPr())),
4249
)
4350
for before_body_bldr, after_body_bldr in cases:
4451
body = before_body_bldr.element
4552
# exercise -----------------
4653
body.clear_content()
4754
# verify -------------------
48-
assert body.xml == after_body_bldr.xml
55+
assert body.xml == after_body_bldr.xml()
4956

5057

5158
class DescribeCT_Document(object):
5259

5360
def it_holds_a_body_element(self):
54-
document = a_document().with_body().element
61+
document = a_document().with_nsdecls().with_child(a_body()).element
5562
assert isinstance(document.body, CT_Body)

tests/oxml/test_text.py

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@
66

77
from docx.oxml.text import CT_P, CT_PPr, CT_R, CT_Text
88

9-
from .unitdata.text import a_p, a_pPr, a_t, an_r
9+
from .unitdata.text import a_p, a_pPr, a_pStyle, a_t, an_r
1010

1111

1212
class DescribeCT_P(object):
1313

1414
def it_can_construct_a_new_p_element(self):
1515
p = CT_P.new()
16-
expected_xml = a_p().with_nsdecls().xml
16+
expected_xml = a_p().with_nsdecls().xml()
1717
assert p.xml == expected_xml
1818

1919
def it_has_a_sequence_of_the_runs_it_contains(self):
20-
p = a_p().with_nsdecls().with_r(3).element
21-
assert len(p.r_lst) == 3
20+
p = a_p().with_nsdecls().with_child(an_r()).with_child(an_r()).element
21+
assert len(p.r_lst) == 2
2222
for r in p.r_lst:
2323
assert isinstance(r, CT_R)
2424

@@ -27,37 +27,35 @@ def it_can_add_an_r_to_itself(self):
2727
# exercise -----------------
2828
r = p.add_r()
2929
# verify -------------------
30-
assert p.xml == a_p().with_nsdecls().with_r().xml
30+
assert p.xml == a_p().with_nsdecls().with_child(an_r()).xml()
3131
assert isinstance(r, CT_R)
3232

3333
def it_knows_its_paragraph_style(self):
34-
# effectively an integration test with CT_PPr
35-
pPr = a_pPr().with_style('foobar')
34+
pPr_bldr = a_pPr().with_child(a_pStyle().with_val('foobar'))
3635
cases = (
3736
(a_p(), None),
38-
(a_p().with_pPr(pPr), 'foobar'),
37+
(a_p().with_child(pPr_bldr), 'foobar'),
3938
)
4039
for builder, expected_value in cases:
41-
print builder.with_nsdecls().xml
40+
print builder.with_nsdecls().xml()
4241
p = builder.with_nsdecls().element
4342
assert p.style == expected_value
4443

4544
def it_can_set_its_paragraph_style(self):
46-
# effectively an integration test with CT_PPr
47-
pPr = a_pPr().with_style('foobar')
48-
pPr2 = a_pPr().with_style('barfoo')
45+
pPr = a_pPr().with_child(a_pStyle().with_val('foobar'))
46+
pPr2 = a_pPr().with_child(a_pStyle().with_val('barfoo'))
4947
cases = (
50-
(1, a_p(), None, a_p().with_pPr(a_pPr())),
51-
(2, a_p(), 'foobar', a_p().with_pPr(pPr)),
52-
(3, a_p().with_pPr(pPr), None, a_p().with_pPr(a_pPr())),
53-
(4, a_p().with_pPr(pPr), 'barfoo', a_p().with_pPr(pPr2)),
48+
(1, a_p(), None, a_p().with_child(a_pPr())),
49+
(2, a_p(), 'foobar', a_p().with_child(pPr)),
50+
(3, a_p().with_child(pPr), None, a_p().with_child(a_pPr())),
51+
(4, a_p().with_child(pPr), 'barfoo', a_p().with_child(pPr2)),
5452
)
5553
for case_nmbr, before_bldr, new_style, after_bldr in cases:
56-
print before_bldr.with_nsdecls().xml
54+
print before_bldr.with_nsdecls().xml()
5755
print 'case_nmbr, new_style => %d, %s' % (case_nmbr, new_style)
5856
p = before_bldr.with_nsdecls().element
5957
p.style = new_style
60-
expected_xml = after_bldr.with_nsdecls().xml
58+
expected_xml = after_bldr.with_nsdecls().xml()
6159
print expected_xml
6260
print p.xml
6361
assert p.xml == expected_xml
@@ -67,13 +65,13 @@ class DescribeCT_PPr(object):
6765

6866
def it_can_construct_a_new_pPr_element(self):
6967
pPr = CT_PPr.new()
70-
expected_xml = a_pPr().with_nsdecls().xml
68+
expected_xml = a_pPr().with_nsdecls().xml()
7169
assert pPr.xml == expected_xml
7270

7371
def it_knows_the_paragraph_style(self):
7472
cases = (
7573
(a_pPr(), None),
76-
(a_pPr().with_style('foobar'), 'foobar'),
74+
(a_pPr().with_child(a_pStyle().with_val('foobar')), 'foobar'),
7775
)
7876
for builder, expected_value in cases:
7977
print builder.with_nsdecls().xml
@@ -83,17 +81,19 @@ def it_knows_the_paragraph_style(self):
8381
def it_can_set_the_paragraph_style(self):
8482
cases = (
8583
(1, a_pPr(), None, a_pPr()),
86-
(2, a_pPr(), 'foobar', a_pPr().with_style('foobar')),
87-
(3, a_pPr().with_style('foobar'), None, a_pPr()),
88-
(4, a_pPr().with_style('foobar'), 'barfoo',
89-
a_pPr().with_style('barfoo')),
84+
(2, a_pPr(), 'foobar',
85+
a_pPr().with_child(a_pStyle().with_val('foobar'))),
86+
(3, a_pPr().with_child(a_pStyle().with_val('foobar')), None,
87+
a_pPr()),
88+
(4, a_pPr().with_child(a_pStyle().with_val('foobar')), 'barfoo',
89+
a_pPr().with_child(a_pStyle().with_val('barfoo'))),
9090
)
9191
for case_nmbr, before_bldr, new_style, after_bldr in cases:
9292
print '====\ncase %d: new_style => %s' % (case_nmbr, new_style)
93-
print 'before:\n%s' % before_bldr.with_nsdecls().xml
93+
print 'before:\n%s' % before_bldr.with_nsdecls().xml()
9494
pPr = before_bldr.with_nsdecls().element
9595
pPr.style = new_style
96-
expected_xml = after_bldr.with_nsdecls().xml
96+
expected_xml = after_bldr.with_nsdecls().xml()
9797
print 'expected:\n%s' % expected_xml
9898
print 'actual:\n%s' % pPr.xml
9999
assert pPr.xml == expected_xml
@@ -103,22 +103,28 @@ class DescribeCT_R(object):
103103

104104
def it_can_construct_a_new_r_element(self):
105105
r = CT_R.new()
106-
assert r.xml == an_r().with_nsdecls().xml
106+
assert r.xml == an_r().with_nsdecls().xml()
107107

108108
def it_can_add_a_t_to_itself(self):
109109
text = 'foobar'
110110
r = an_r().with_nsdecls().element
111111
# exercise -----------------
112112
t = r.add_t(text)
113113
# verify -------------------
114-
assert r.xml == an_r().with_nsdecls().with_t(text).xml
114+
assert (
115+
r.xml ==
116+
an_r().with_nsdecls().with_child(a_t().with_text(text)).xml()
117+
)
115118
assert isinstance(t, CT_Text)
116119

117120
def it_has_a_sequence_of_the_t_elms_it_contains(self):
118121
cases = (
119122
(an_r().with_nsdecls(), 0),
120-
(an_r().with_nsdecls().with_t('foo'), 1),
121-
(an_r().with_nsdecls().with_t('foo').with_t('bar'), 2),
123+
(an_r().with_nsdecls().with_child(
124+
a_t().with_text('foo')), 1),
125+
(an_r().with_nsdecls().with_child(
126+
a_t().with_text('foo')).with_child(
127+
a_t().with_text('bar')), 2),
122128
)
123129
for r_bldr, expected_len in cases:
124130
r = r_bldr.element
@@ -132,4 +138,4 @@ class DescribeCT_Text(object):
132138
def it_can_construct_a_new_t_element(self):
133139
text = 'foobar'
134140
t = CT_Text.new(text)
135-
assert t.xml == a_t(text).with_nsdecls().xml
141+
assert t.xml == a_t().with_nsdecls().with_text(text).xml()

tests/oxml/unitdata/parts.py

Lines changed: 7 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4,85 +4,24 @@
44
Test data builders for parts XML.
55
"""
66

7-
from ...unitdata import BaseBuilder, nsdecls
8-
from .text import a_p, a_sectPr
7+
from ...unitdata import BaseBuilder
98

109

1110
class CT_BodyBuilder(BaseBuilder):
12-
"""
13-
Test data builder for CT_Body (<w:body>) XML element that appears in
14-
document.xml files.
15-
"""
16-
def __init__(self):
17-
"""Establish instance variables with default values"""
18-
super(CT_BodyBuilder, self).__init__()
19-
self._p = None
20-
self._sectPr = None
21-
22-
@property
23-
def is_empty(self):
24-
return self._p is None and self._sectPr is None
25-
26-
def with_p(self):
27-
"""Add an empty paragraph element"""
28-
self._p = a_p()
29-
return self
30-
31-
def with_sectPr(self):
32-
"""Add an empty section properties element"""
33-
self._sectPr = a_sectPr()
34-
return self
35-
36-
@property
37-
def xml(self):
38-
"""Return element XML based on attribute settings"""
39-
indent = ' ' * self._indent
40-
if self.is_empty:
41-
xml = '%s<w:body %s/>\n' % (indent, nsdecls('w'))
42-
else:
43-
xml = '%s<w:body %s>\n' % (indent, nsdecls('w'))
44-
if self._p:
45-
xml += self._p.with_indent(self._indent+2).xml
46-
if self._sectPr:
47-
xml += self._sectPr.with_indent(self._indent+2).xml
48-
xml += '%s</w:body>\n' % indent
49-
return xml
11+
__tag__ = 'w:body'
12+
__nspfxs__ = ('w',)
13+
__attrs__ = ()
5014

5115

5216
class CT_DocumentBuilder(BaseBuilder):
53-
"""
54-
XML data builder for CT_Document (<w:document>) element, the root element
55-
in document.xml files.
56-
"""
57-
def __init__(self):
58-
"""Establish instance variables with default values"""
59-
super(CT_DocumentBuilder, self).__init__()
60-
self._body = None
61-
62-
def with_body(self):
63-
"""Add an empty body element"""
64-
self._body = a_body().with_indent(2)
65-
return self
66-
67-
@property
68-
def xml(self):
69-
"""
70-
Return XML string based on settings accumulated via method calls.
71-
"""
72-
if not self._body:
73-
return '<w:document %s/>\n' % nsdecls('w')
74-
75-
xml = '<w:document %s>\n' % nsdecls('w')
76-
xml += self._body.xml
77-
xml += '</w:document>\n'
78-
return xml
17+
__tag__ = 'w:document'
18+
__nspfxs__ = ('w',)
19+
__attrs__ = ()
7920

8021

8122
def a_body():
82-
"""Return a CT_BodyBuilder instance"""
8323
return CT_BodyBuilder()
8424

8525

8626
def a_document():
87-
"""Return a CT_DocumentBuilder instance"""
8827
return CT_DocumentBuilder()

0 commit comments

Comments
 (0)