|
| 1 | +"""Step implementations for footnote-related features.""" |
| 2 | + |
| 3 | +from behave import given, when, then |
| 4 | +from behave.runner import Context |
| 5 | + |
| 6 | +from docx import Document |
| 7 | +from docx.footnotes import Footnote |
| 8 | +from docx.text.paragraph import Paragraph |
| 9 | + |
| 10 | +from helpers import test_docx |
| 11 | + |
| 12 | +# given ==================================================== |
| 13 | + |
| 14 | + |
| 15 | +@given("a document with 3 footnotes and 2 default footnotes") |
| 16 | +def given_a_document_with_3_footnotes_and_2_default_footnotes(context: Context): |
| 17 | + document = Document(test_docx("footnotes")) |
| 18 | + context.footnotes = document.footnotes |
| 19 | + |
| 20 | + |
| 21 | +@given("a document with footnotes and with all footnotes properties") |
| 22 | +def given_a_document_with_footnotes_and_with_all_footnotes_properties(context: Context): |
| 23 | + document = Document(test_docx("footnotes")) |
| 24 | + context.section = document.sections[0] |
| 25 | + |
| 26 | + |
| 27 | +@given("a document with footnotes") |
| 28 | +def given_a_document_with_footnotes(context: Context): |
| 29 | + document = Document(test_docx("footnotes")) |
| 30 | + context.footnotes = document.footnotes |
| 31 | + |
| 32 | + |
| 33 | +@given("a document without footnotes") |
| 34 | +def given_a_document_without_footnotes(context: Context): |
| 35 | + document = Document(test_docx("doc-default")) |
| 36 | + context.footnotes = document.footnotes |
| 37 | + context.section = document.sections[0] |
| 38 | + |
| 39 | + |
| 40 | +@given("a paragraph in a document without footnotes") |
| 41 | +def given_a_paragraph_in_a_document_without_footnotes(context: Context): |
| 42 | + document = Document(test_docx("par-known-paragraphs")) |
| 43 | + context.paragraphs = document.paragraphs |
| 44 | + context.footnotes = document.footnotes |
| 45 | + |
| 46 | + |
| 47 | +@given("a document with paragraphs[0] containing one, paragraphs[1] containing none, and paragraphs[2] containing two footnotes") |
| 48 | +def given_a_document_with_3_footnotes(context: Context): |
| 49 | + document = Document(test_docx("footnotes")) |
| 50 | + context.paragraphs = document.paragraphs |
| 51 | + context.footnotes = document.footnotes |
| 52 | + |
| 53 | + |
| 54 | +# when ==================================================== |
| 55 | + |
| 56 | + |
| 57 | +@when("I try to access a footnote with invalid reference id") |
| 58 | +def when_I_try_to_access_a_footnote_with_invalid_reference_id(context: Context): |
| 59 | + context.exc = None |
| 60 | + try: |
| 61 | + context.footnotes[10] |
| 62 | + except IndexError as e: |
| 63 | + context.exc = e |
| 64 | + |
| 65 | + |
| 66 | +@when("I add a footnote to the paragraphs[{parId}] with text '{footnoteText}'") |
| 67 | +def when_I_add_a_footnote_to_the_paragraph_with_text_text(context: Context, parId: str, footnoteText: str): |
| 68 | + par = context.paragraphs[int(parId)] |
| 69 | + new_footnote = par.add_footnote() |
| 70 | + new_footnote.add_paragraph(footnoteText) |
| 71 | + |
| 72 | + |
| 73 | +@when("I change footnote property {propName} to {value}") |
| 74 | +def when_I_change_footnote_property_propName_to_value(context: Context, propName: str, value: str): |
| 75 | + context.section.__setattr__(propName, eval(value)) |
| 76 | + |
| 77 | + |
| 78 | +# then ===================================================== |
| 79 | + |
| 80 | + |
| 81 | +@then("len(footnotes) is {expectedLen}") |
| 82 | +def then_len_footnotes_is_len(context: Context, expectedLen: str): |
| 83 | + footnotes = context.footnotes |
| 84 | + assert len(footnotes) == int(expectedLen), f"expected len(footnotes) of {expectedLen}, got {len(footnotes)}" |
| 85 | + |
| 86 | + |
| 87 | +@then("I can access a footnote by footnote reference id") |
| 88 | +def then_I_can_access_a_footnote_by_footnote_reference_id(context: Context): |
| 89 | + footnotes = context.footnotes |
| 90 | + for refId in range(-1, 3): |
| 91 | + footnote = footnotes[refId] |
| 92 | + assert isinstance(footnote, Footnote) |
| 93 | + |
| 94 | + |
| 95 | +@then("I can access a paragraph in a specific footnote") |
| 96 | +def then_I_can_access_a_paragraph_in_a_specific_footnote(context: Context): |
| 97 | + footnotes = context.footnotes |
| 98 | + for refId in range(1, 3): |
| 99 | + footnote = footnotes[refId] |
| 100 | + assert isinstance(footnote.paragraphs[0], Paragraph) |
| 101 | + |
| 102 | + |
| 103 | +@then("it trows an {exceptionType}") |
| 104 | +def then_it_trows_an_IndexError(context: Context, exceptionType: str): |
| 105 | + exc = context.exc |
| 106 | + assert isinstance(exc, eval(exceptionType)), f"expected IndexError, got {type(exc)}" |
| 107 | + |
| 108 | + |
| 109 | +@then("I can access footnote property {propName} with value {value}") |
| 110 | +def then_I_can_access_footnote_propery_name_with_value_value(context: Context, propName: str, value: str): |
| 111 | + actual_value = context.section.__getattribute__(propName) |
| 112 | + expected = eval(value) |
| 113 | + assert actual_value == expected, f"expected section.{propName} {value}, got {expected}" |
| 114 | + |
| 115 | + |
| 116 | +@then("the document contains a footnote with footnote reference id of {refId} with text '{footnoteText}'") |
| 117 | +def then_the_document_contains_a_footnote_with_footnote_reference_id_of_refId_with_text_text(context: Context, refId: str, footnoteText: str): |
| 118 | + par = context.paragraphs[1] |
| 119 | + f = par.footnotes[0] |
| 120 | + assert f.id == int(refId), f"expected {refId}, got {f.id}" |
| 121 | + assert f.paragraphs[0].text == footnoteText, f"expected {footnoteText}, got {f.paragraphs[0].text}" |
| 122 | + |
| 123 | + |
| 124 | +@then("paragraphs[{parId}] has footnote reference ids of {refIds}, with footnote text {fText}") |
| 125 | +def then_paragraph_has_footnote_reference_ids_of_refIds_with_footnote_text_text(context: Context, parId: str, refIds: str, fText: str): |
| 126 | + par = context.paragraphs[int(parId)] |
| 127 | + refIds = eval(refIds) |
| 128 | + fText = eval(fText) |
| 129 | + if refIds is not None: |
| 130 | + if type(refIds) is list: |
| 131 | + for i in range(len(refIds)): |
| 132 | + f = par.footnotes[i] |
| 133 | + assert isinstance(f, Footnote), f"expected to be instance of Footnote, got {type(f)}" |
| 134 | + assert f.id == refIds[i], f"expected {refIds[i]}, got {f.id}" |
| 135 | + assert f.paragraphs[0].text == fText[i], f"expected '{fText[i]}', got '{f.paragraphs[0].text}'" |
| 136 | + else: |
| 137 | + f = par.footnotes[0] |
| 138 | + assert f.id == int(refIds), f"expected {refIds}, got {f.id}" |
| 139 | + assert f.paragraphs[0].text == fText, f"expected '{fText}', got '{f.paragraphs[0].text}'" |
| 140 | + else: |
| 141 | + assert len(par.footnotes) == 0, f"expected an empty list, got {len(par.footnotes)} elements" |
0 commit comments