1# encoding: utf-8
2
3"""
4Step implementations for section-related features
5"""
6
7from __future__ import absolute_import, print_function, unicode_literals
8
9from behave import given, then, when
10
11from docx import Document
12from docx.enum.section import WD_ORIENT, WD_SECTION
13from docx.section import Section
14from docx.shared import Inches
15
16from helpers import test_docx
17
18
19# given ====================================================
20
21@given("a Section object as section")
22def given_a_Section_object_as_section(context):
23    context.section = Document(test_docx("sct-section-props")).sections[-1]
24
25
26@given("a Section object {with_or_without} a distinct first-page header as section")
27def given_a_Section_object_with_or_without_first_page_header(context, with_or_without):
28    section_idx = {"with": 1, "without": 0}[with_or_without]
29    context.section = Document(test_docx("sct-first-page-hdrftr")).sections[section_idx]
30
31
32@given('a section collection containing 3 sections')
33def given_a_section_collection_containing_3_sections(context):
34    document = Document(test_docx('doc-access-sections'))
35    context.sections = document.sections
36
37
38@given('a section having known page dimension')
39def given_a_section_having_known_page_dimension(context):
40    document = Document(test_docx('sct-section-props'))
41    context.section = document.sections[-1]
42
43
44@given('a section having known page margins')
45def given_a_section_having_known_page_margins(context):
46    document = Document(test_docx('sct-section-props'))
47    context.section = document.sections[0]
48
49
50@given('a section having start type {start_type}')
51def given_a_section_having_start_type(context, start_type):
52    section_idx = {
53        'CONTINUOUS': 0,
54        'NEW_PAGE':   1,
55        'ODD_PAGE':   2,
56        'EVEN_PAGE':  3,
57        'NEW_COLUMN': 4,
58    }[start_type]
59    document = Document(test_docx('sct-section-props'))
60    context.section = document.sections[section_idx]
61
62
63@given('a section known to have {orientation} orientation')
64def given_a_section_having_known_orientation(context, orientation):
65    section_idx = {
66        'landscape': 0,
67        'portrait':  1
68    }[orientation]
69    document = Document(test_docx('sct-section-props'))
70    context.section = document.sections[section_idx]
71
72
73# when =====================================================
74
75@when("I assign {bool_val} to section.different_first_page_header_footer")
76def when_I_assign_value_to_section_different_first_page_hdrftr(context, bool_val):
77    context.section.different_first_page_header_footer = eval(bool_val)
78
79
80@when('I set the {margin_side} margin to {inches} inches')
81def when_I_set_the_margin_side_length(context, margin_side, inches):
82    prop_name = {
83        'left':   'left_margin',
84        'right':  'right_margin',
85        'top':    'top_margin',
86        'bottom': 'bottom_margin',
87        'gutter': 'gutter',
88        'header': 'header_distance',
89        'footer': 'footer_distance',
90    }[margin_side]
91    new_value = Inches(float(inches))
92    setattr(context.section, prop_name, new_value)
93
94
95@when('I set the section orientation to {orientation}')
96def when_I_set_the_section_orientation(context, orientation):
97    new_orientation = {
98        'WD_ORIENT.PORTRAIT':  WD_ORIENT.PORTRAIT,
99        'WD_ORIENT.LANDSCAPE': WD_ORIENT.LANDSCAPE,
100        'None':                None,
101    }[orientation]
102    context.section.orientation = new_orientation
103
104
105@when('I set the section page height to {y} inches')
106def when_I_set_the_section_page_height_to_y_inches(context, y):
107    context.section.page_height = Inches(float(y))
108
109
110@when('I set the section page width to {x} inches')
111def when_I_set_the_section_page_width_to_x_inches(context, x):
112    context.section.page_width = Inches(float(x))
113
114
115@when('I set the section start type to {start_type}')
116def when_I_set_the_section_start_type_to_start_type(context, start_type):
117    new_start_type = {
118        'None':       None,
119        'CONTINUOUS': WD_SECTION.CONTINUOUS,
120        'EVEN_PAGE':  WD_SECTION.EVEN_PAGE,
121        'NEW_COLUMN': WD_SECTION.NEW_COLUMN,
122        'NEW_PAGE':   WD_SECTION.NEW_PAGE,
123        'ODD_PAGE':   WD_SECTION.ODD_PAGE,
124    }[start_type]
125    context.section.start_type = new_start_type
126
127
128# then =====================================================
129
130@then('I can access a section by index')
131def then_I_can_access_a_section_by_index(context):
132    sections = context.sections
133    for idx in range(3):
134        section = sections[idx]
135        assert isinstance(section, Section)
136
137
138@then('I can iterate over the sections')
139def then_I_can_iterate_over_the_sections(context):
140    sections = context.sections
141    actual_count = 0
142    for section in sections:
143        actual_count += 1
144        assert isinstance(section, Section)
145    assert actual_count == 3
146
147
148@then('len(sections) is 3')
149def then_len_sections_is_3(context):
150    sections = context.sections
151    assert len(sections) == 3, (
152        'expected len(sections) of 3, got %s' % len(sections)
153    )
154
155
156@then("section.different_first_page_header_footer is {bool_val}")
157def then_section_different_first_page_header_footer_is(context, bool_val):
158    actual = context.section.different_first_page_header_footer
159    expected = eval(bool_val)
160    assert actual == expected, (
161        "section.different_first_page_header_footer is %s" % actual
162    )
163
164
165@then("section.even_page_footer is a _Footer object")
166def then_section_even_page_footer_is_a_Footer_object(context):
167    actual = type(context.section.even_page_footer).__name__
168    expected = "_Footer"
169    assert actual == expected, "section.even_page_footer is a %s object" % actual
170
171
172@then("section.even_page_header is a _Header object")
173def then_section_even_page_header_is_a_Header_object(context):
174    actual = type(context.section.even_page_header).__name__
175    expected = "_Header"
176    assert actual == expected, "section.even_page_header is a %s object" % actual
177
178
179@then("section.first_page_footer is a _Footer object")
180def then_section_first_page_footer_is_a_Footer_object(context):
181    actual = type(context.section.first_page_footer).__name__
182    expected = "_Footer"
183    assert actual == expected, "section.first_page_footer is a %s object" % actual
184
185
186@then("section.first_page_header is a _Header object")
187def then_section_first_page_header_is_a_Header_object(context):
188    actual = type(context.section.first_page_header).__name__
189    expected = "_Header"
190    assert actual == expected, "section.first_page_header is a %s object" % actual
191
192
193@then("section.footer is a _Footer object")
194def then_section_footer_is_a_Footer_object(context):
195    actual = type(context.section.footer).__name__
196    expected = "_Footer"
197    assert actual == expected, "section.footer is a %s object" % actual
198
199
200@then("section.header is a _Header object")
201def then_section_header_is_a_Header_object(context):
202    actual = type(context.section.header).__name__
203    expected = "_Header"
204    assert actual == expected, "section.header is a %s object" % actual
205
206
207@then("section.{propname}.is_linked_to_previous is True")
208def then_section_hdrftr_prop_is_linked_to_previous_is_True(context, propname):
209    actual = getattr(context.section, propname).is_linked_to_previous
210    expected = True
211    assert actual == expected, (
212        "section.%s.is_linked_to_previous is %s" % (propname, actual)
213    )
214
215
216@then('the reported {margin_side} margin is {inches} inches')
217def then_the_reported_margin_is_inches(context, margin_side, inches):
218    prop_name = {
219        'left':   'left_margin',
220        'right':  'right_margin',
221        'top':    'top_margin',
222        'bottom': 'bottom_margin',
223        'gutter': 'gutter',
224        'header': 'header_distance',
225        'footer': 'footer_distance',
226    }[margin_side]
227    expected_value = Inches(float(inches))
228    actual_value = getattr(context.section, prop_name)
229    assert actual_value == expected_value
230
231
232@then('the reported page orientation is {orientation}')
233def then_the_reported_page_orientation_is_orientation(context, orientation):
234    expected_value = {
235        'WD_ORIENT.LANDSCAPE': WD_ORIENT.LANDSCAPE,
236        'WD_ORIENT.PORTRAIT':  WD_ORIENT.PORTRAIT,
237    }[orientation]
238    assert context.section.orientation == expected_value
239
240
241@then('the reported page width is {x} inches')
242def then_the_reported_page_width_is_width(context, x):
243    assert context.section.page_width == Inches(float(x))
244
245
246@then('the reported page height is {y} inches')
247def then_the_reported_page_height_is_11_inches(context, y):
248    assert context.section.page_height == Inches(float(y))
249
250
251@then('the reported section start type is {start_type}')
252def then_the_reported_section_start_type_is_type(context, start_type):
253    expected_start_type = {
254        'CONTINUOUS': WD_SECTION.CONTINUOUS,
255        'EVEN_PAGE':  WD_SECTION.EVEN_PAGE,
256        'NEW_COLUMN': WD_SECTION.NEW_COLUMN,
257        'NEW_PAGE':   WD_SECTION.NEW_PAGE,
258        'ODD_PAGE':   WD_SECTION.ODD_PAGE,
259    }[start_type]
260    assert context.section.start_type == expected_start_type
261