forked from python-openxml/python-docx
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_enum.py
More file actions
189 lines (132 loc) · 6.56 KB
/
test_enum.py
File metadata and controls
189 lines (132 loc) · 6.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
"""Test suite for docx.enum module, focused on base classes.
Configured a little differently because of the meta-programming, the two enumeration
classes at the top constitute the entire fixture and the tests themselves just make
assertions on those.
"""
import enum
import pytest
from docx.enum.base import BaseXmlEnum
class SomeXmlAttr(BaseXmlEnum):
"""SomeXmlAttr docstring."""
FOO = (1, "foo", "Do foo instead of bar.")
"""Do foo instead of bar."""
BAR = (2, "bar", "Do bar instead of foo.")
"""Do bar instead of foo."""
BAZ = (3, None, "Maps to the value assumed when the attribute is omitted.")
"""Maps to the value assumed when the attribute is omitted."""
class DescribeBaseXmlEnum:
"""Unit-test suite for `docx.enum.base.BaseXmlEnum`."""
def it_is_an_instance_of_EnumMeta_just_like_a_regular_Enum(self):
assert type(SomeXmlAttr) is enum.EnumMeta
def it_has_the_same_repr_as_a_regular_Enum(self):
assert repr(SomeXmlAttr) == "<enum 'SomeXmlAttr'>"
def it_has_an_MRO_that_goes_through_the_base_class_int_and_Enum(self):
assert SomeXmlAttr.__mro__ == (
SomeXmlAttr,
BaseXmlEnum,
int,
enum.Enum,
object,
), f"got: {SomeXmlAttr.__mro__}"
def it_knows_the_XML_value_for_each_member_by_the_member_instance(self):
assert SomeXmlAttr.to_xml(SomeXmlAttr.FOO) == "foo"
def it_knows_the_XML_value_for_each_member_by_the_member_value(self):
assert SomeXmlAttr.to_xml(2) == "bar"
def but_it_raises_when_there_is_no_such_member(self):
with pytest.raises(ValueError, match="42 is not a valid SomeXmlAttr"):
SomeXmlAttr.to_xml(42)
def it_can_find_the_member_from_the_XML_attr_value(self):
assert SomeXmlAttr.from_xml("bar") == SomeXmlAttr.BAR
def and_it_can_find_the_member_from_None_when_a_member_maps_that(self):
assert SomeXmlAttr.from_xml(None) == SomeXmlAttr.BAZ
def but_it_raises_when_there_is_no_such_mapped_XML_value(self):
with pytest.raises(ValueError, match="SomeXmlAttr has no XML mapping for 'baz'"):
SomeXmlAttr.from_xml("baz")
class DescribeBaseXmlEnumMembers:
"""Unit-test suite for `docx.enum.base.BaseXmlEnum`."""
def it_is_an_instance_of_its_XmlEnum_subtype_class(self):
assert type(SomeXmlAttr.FOO) is SomeXmlAttr
def it_has_the_default_Enum_repr(self):
assert repr(SomeXmlAttr.BAR) == "<SomeXmlAttr.BAR: 2>"
def but_its_str_value_is_customized(self):
assert str(SomeXmlAttr.FOO) == "FOO (1)"
def its_value_is_the_same_int_as_its_corresponding_MS_API_enum_member(self):
assert SomeXmlAttr.FOO.value == 1
def its_name_is_its_member_name_the_same_as_a_regular_Enum(self):
assert SomeXmlAttr.FOO.name == "FOO"
def it_has_an_individual_member_specific_docstring(self):
assert SomeXmlAttr.FOO.__doc__ == "Do foo instead of bar."
def it_is_equivalent_to_its_int_value(self):
assert SomeXmlAttr.FOO == 1
assert SomeXmlAttr.FOO != 2
assert SomeXmlAttr.BAR == 2
assert SomeXmlAttr.BAR != 1
class DescribeDashOOSafety:
"""`python -OO` strips class/function `__doc__` attributes to `None`.
upstream-PR#337: reading docstrings anywhere in the import or enum-
construction path must not crash when those `__doc__` attributes are
missing.
"""
def it_tolerates_None_docstring_in_BaseEnum_new(self):
# -- simulate -OO by passing docstr=None to BaseEnum.__new__ --
from docx.enum.base import BaseEnum
class SomeEnum(BaseEnum):
ALPHA = (1, None) # type: ignore[arg-type]
BETA = (2, None) # type: ignore[arg-type]
assert SomeEnum.ALPHA.__doc__ == ""
assert SomeEnum.BETA.__doc__ == ""
def it_tolerates_None_docstring_in_BaseXmlEnum_new(self):
# -- simulate -OO by passing docstr=None to BaseXmlEnum.__new__ --
class SomeXml(BaseXmlEnum):
ONE = (1, "one", None) # type: ignore[arg-type]
assert SomeXml.ONE.__doc__ == ""
assert SomeXml.ONE.xml_value == "one"
def it_tolerates_None_docstring_in_DocsPageFormatter_member_def(self):
# -- even if an enum member's __doc__ is None, the RST formatter
# -- must not blow up --
from docx.enum.base import BaseEnum, DocsPageFormatter
class SomeEnum(BaseEnum):
ALPHA = (1, None) # type: ignore[arg-type]
clsdict = dict(SomeEnum.__dict__)
clsdict["__ms_name__"] = "SomeEnum"
clsdict["__members__"] = list(SomeEnum.__members__.values())
formatter = DocsPageFormatter("SomeEnum", clsdict)
# -- does not raise --
assert "ALPHA" in formatter.page_str
def it_runs_Document_under_minus_OO(self):
# -- end-to-end smoke test: launch a subprocess with -OO and ensure
# -- `Document()` (which pulls the default template, constructs enums,
# -- and reads docstrings for built-in style lookups) works.
import os
import subprocess
import sys
env = os.environ.copy()
# -- forward the current interpreter's sys.path so the subprocess
# -- resolves this worktree's `docx` package rather than a site-
# -- packages copy --
env["PYTHONPATH"] = os.pathsep.join(sys.path)
result = subprocess.run(
[sys.executable, "-OO", "-c", "import docx; docx.Document()"],
capture_output=True,
text=True,
env=env,
)
assert result.returncode == 0, f"stderr: {result.stderr}"
class DescribeWDParagraphAlignmentStartEnd:
"""`WD_PARAGRAPH_ALIGNMENT.START` / `.END` alias LEFT / RIGHT (upstream #1473)."""
def it_exposes_START_as_an_alias_of_LEFT(self):
from docx.enum.text import WD_ALIGN_PARAGRAPH
assert WD_ALIGN_PARAGRAPH.START is WD_ALIGN_PARAGRAPH.LEFT
def it_exposes_END_as_an_alias_of_RIGHT(self):
from docx.enum.text import WD_ALIGN_PARAGRAPH
assert WD_ALIGN_PARAGRAPH.END is WD_ALIGN_PARAGRAPH.RIGHT
def it_maps_start_from_xml_to_LEFT(self):
from docx.enum.text import WD_ALIGN_PARAGRAPH
assert WD_ALIGN_PARAGRAPH.from_xml("start") is WD_ALIGN_PARAGRAPH.LEFT
def it_maps_end_from_xml_to_RIGHT(self):
from docx.enum.text import WD_ALIGN_PARAGRAPH
assert WD_ALIGN_PARAGRAPH.from_xml("end") is WD_ALIGN_PARAGRAPH.RIGHT
def it_remains_equal_to_LEFT_for_legacy_comparisons(self):
from docx.enum.text import WD_ALIGN_PARAGRAPH
alignment = WD_ALIGN_PARAGRAPH.START
assert alignment == WD_ALIGN_PARAGRAPH.LEFT