diff options
author | Skyler Grey <skyler.grey@collabora.com> | 2023-10-23 09:17:23 +0000 |
---|---|---|
committer | Caolán McNamara <caolan.mcnamara@collabora.com> | 2023-11-02 10:27:52 +0100 |
commit | fd5c75750f5c5448eec840033bce16375774a707 (patch) | |
tree | 752a27e4c7d41f9080b020484c408de1478188ae /sw | |
parent | 419866e851c7ad4a39bd508d607baba3590f3d45 (diff) |
Improve and extend STYLEREF tests
- I7d8f455ffe90cface4f3b1acf6b9bef6a045ed19,
Ib664fec059aa1f7f130acc76c253d5d298fa59f7 and
Iad8e8001807f5ceeaedc9665838672695174a936 added STYLEREF flags. This
commit adds tests for them
- The tests in I35dc36197b62fa53def4745da1d4755ece79ed22 were partly
broken due to the fields occasionally being inserted in the wrong
place (i.e. at the end of the document), this commit makes sure to
move the cursor before inserting a field
- The tests in I35dc36197b62fa53def4745da1d4755ece79ed22 were not
separated into sections which made it difficult to tell what was being
tested. All STYLEREF tests that create documents are now clearly split
into arrange/act/assert steps with comments denoting the sections
- The tests in I35dc36197b62fa53def4745da1d4755ece79ed22 had a lot of
repetition, particularly in creating the document, adding headings,
etc. This has been refactored into some helper functions
- I35dc36197b62fa53def4745da1d4755ece79ed22 was missing an ODF import
test. This commit adds one
Follow-Up-To: I25dd7a6940abee5651a784b9059fe23b32547d6c
Follow-Up-To: I35dc36197b62fa53def4745da1d4755ece79ed22
Follow-Up-To: I7d8f455ffe90cface4f3b1acf6b9bef6a045ed19
Follow-Up-To: Ib664fec059aa1f7f130acc76c253d5d298fa59f7
Follow-Up-To: Iad8e8001807f5ceeaedc9665838672695174a936
Follow-Up-To: Iecd3e83a6bd3f8c2c6adba5c7eba9ee55b773510
Follow-Up-To: Ifaa67fbc2d53b0d4fb85e7305b2dbdf78cf0a1ad
Follow-Up-To: Id991c92b9aeaa054b136f7a3d9c7c8ea0026e514
Change-Id: I941b477c8e860270a400869cb9ea15e5561e402a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158352
Tested-by: Jenkins
Tested-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/core/fields/data/styleref-flags.docx | bin | 0 -> 23218 bytes | |||
-rw-r--r-- | sw/qa/core/fields/data/styleref.odt | bin | 0 -> 40280 bytes | |||
-rw-r--r-- | sw/qa/core/fields/data/suppress-non-numerical.docx | bin | 0 -> 17046 bytes | |||
-rw-r--r-- | sw/qa/core/fields/fields.cxx | 215 |
4 files changed, 169 insertions, 46 deletions
diff --git a/sw/qa/core/fields/data/styleref-flags.docx b/sw/qa/core/fields/data/styleref-flags.docx Binary files differnew file mode 100644 index 000000000000..443624a575e0 --- /dev/null +++ b/sw/qa/core/fields/data/styleref-flags.docx diff --git a/sw/qa/core/fields/data/styleref.odt b/sw/qa/core/fields/data/styleref.odt Binary files differnew file mode 100644 index 000000000000..27af5aae1f06 --- /dev/null +++ b/sw/qa/core/fields/data/styleref.odt diff --git a/sw/qa/core/fields/data/suppress-non-numerical.docx b/sw/qa/core/fields/data/suppress-non-numerical.docx Binary files differnew file mode 100644 index 000000000000..439e048b9f93 --- /dev/null +++ b/sw/qa/core/fields/data/suppress-non-numerical.docx diff --git a/sw/qa/core/fields/fields.cxx b/sw/qa/core/fields/fields.cxx index 9fae9cafef13..8e6a1488fa3a 100644 --- a/sw/qa/core/fields/fields.cxx +++ b/sw/qa/core/fields/fields.cxx @@ -7,8 +7,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <com/sun/star/text/XParagraphCursor.hpp> +#include <reffld.hxx> #include <com/sun/star/beans/PropertyValue.hpp> -#include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/container/XIndexAccess.hpp> #include <com/sun/star/text/ControlCharacter.hpp> @@ -36,7 +37,6 @@ #include <com/sun/star/text/XTextDocument.hpp> #include <com/sun/star/text/XTextFieldsSupplier.hpp> - #include <comphelper/propertyvalue.hxx> #include <authfld.hxx> @@ -182,27 +182,49 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf86790) CPPUNIT_ASSERT_EQUAL(sValue.first, xField->getPresentation(true)); CPPUNIT_ASSERT_EQUAL(sValue.second, xField->getPresentation(false)); } + CPPUNIT_ASSERT(!xFields->hasMoreElements()); +} + +void InsertParagraphBreak(const uno::Reference<text::XTextCursor>& xCursor) +{ + uno::Reference<text::XText> xText = xCursor->getText(); + xText->insertControlCharacter(xCursor, text::ControlCharacter::PARAGRAPH_BREAK, false); +} +void InsertHeading(const uno::Reference<text::XTextCursor>& xCursor, const OUString& content) +{ + uno::Reference<beans::XPropertySet> xCursorPropertySet(xCursor, uno::UNO_QUERY); + uno::Reference<text::XText> xText = xCursor->getText(); + + xCursorPropertySet->setPropertyValue("ParaStyleName", uno::Any(OUString("Heading 1"))); + xText->insertString(xCursor, content, false); + InsertParagraphBreak(xCursor); } /// If there is referenced text both above and below, STYLEREF searches up CPPUNIT_TEST_FIXTURE(Test, testStyleRefSearchUp) { + // Arrange + // Create a document with headings both above and below a cursor createSwDoc(); uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); uno::Reference<text::XText> xText = xTextDocument->getText(); uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor(); - uno::Reference<beans::XPropertySet> xCursorPropertySet(xCursor, uno::UNO_QUERY); - xCursorPropertySet->setPropertyValue("ParaStyleName", uno::Any(OUString("Heading 1"))); - xText->insertString(xCursor, "Heading far above field", false); - xText->insertControlCharacter(xCursor, text::ControlCharacter::PARAGRAPH_BREAK, false); + InsertHeading(xCursor, "Heading far above field"); + InsertHeading(xCursor, "Heading above field"); + InsertParagraphBreak(xCursor); + InsertHeading(xCursor, "Heading below field"); + InsertHeading(xCursor, "Heading far below field"); - xCursorPropertySet->setPropertyValue("ParaStyleName", uno::Any(OUString("Heading 1"))); - xText->insertString(xCursor, "Heading above field", false); - xText->insertControlCharacter(xCursor, text::ControlCharacter::PARAGRAPH_BREAK, false); + uno::Reference<text::XParagraphCursor> xParagraphCursor(xCursor, uno::UNO_QUERY); + xParagraphCursor->gotoPreviousParagraph(false); // Heading far below... + xParagraphCursor->gotoPreviousParagraph(false); // Heading below... + xParagraphCursor->gotoPreviousParagraph(false); // Blank space + // Act + // Insert a STYLEREF field which looks for "Heading 1"s uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); uno::Reference<text::XTextField> xField( xFactory->createInstance("com.sun.star.text.TextField.GetReference"), uno::UNO_QUERY); @@ -214,27 +236,36 @@ CPPUNIT_TEST_FIXTURE(Test, testStyleRefSearchUp) uno::Any(sal_Int16(text::ReferenceFieldPart::TEXT))); xFieldPropertySet->setPropertyValue("SourceName", uno::Any(OUString("Heading 1"))); - uno::Reference<text::XTextCursor> xFieldCursor = xText->createTextCursor(); + xField->attach(xCursor); - xText->insertControlCharacter(xCursor, text::ControlCharacter::PARAGRAPH_BREAK, false); - xCursorPropertySet->setPropertyValue("ParaStyleName", uno::Any(OUString("Heading 1"))); - xText->insertString(xCursor, "Heading below field", false); - - xField->attach(xFieldCursor); + // Assert + // Make sure the field has the right text CPPUNIT_ASSERT_EQUAL(OUString("Heading above field"), xField->getPresentation(false)); } -/// If there is referenced text both above and below, STYLEREF searches down +/// If there is referenced text only below, STYLEREF searches down CPPUNIT_TEST_FIXTURE(Test, testStyleRefSearchDown) { + // Arrange + // Create a document with headings below a cursor createSwDoc(); uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); uno::Reference<text::XText> xText = xTextDocument->getText(); uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor(); - uno::Reference<beans::XPropertySet> xCursorPropertySet(xCursor, uno::UNO_QUERY); + InsertParagraphBreak(xCursor); + InsertHeading(xCursor, "Heading below field"); + InsertHeading(xCursor, "Heading far below field"); + + uno::Reference<text::XParagraphCursor> xParagraphCursor(xCursor, uno::UNO_QUERY); + xParagraphCursor->gotoPreviousParagraph(false); // Heading far below... + xParagraphCursor->gotoPreviousParagraph(false); // Heading below... + xParagraphCursor->gotoPreviousParagraph(false); // Blank space + + // Act + // Insert a STYLEREF field which looks for "Heading 1"s uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); uno::Reference<text::XTextField> xField( xFactory->createInstance("com.sun.star.text.TextField.GetReference"), uno::UNO_QUERY); @@ -246,39 +277,30 @@ CPPUNIT_TEST_FIXTURE(Test, testStyleRefSearchDown) uno::Any(sal_Int16(text::ReferenceFieldPart::TEXT))); xFieldPropertySet->setPropertyValue("SourceName", uno::Any(OUString("Heading 1"))); - uno::Reference<text::XTextCursor> xFieldCursor = xText->createTextCursor(); - - xText->insertControlCharacter(xCursor, text::ControlCharacter::PARAGRAPH_BREAK, false); - xCursorPropertySet->setPropertyValue("ParaStyleName", uno::Any(OUString("Heading 1"))); - xText->insertString(xCursor, "Heading below field", false); + xField->attach(xCursor); - xText->insertControlCharacter(xCursor, text::ControlCharacter::PARAGRAPH_BREAK, false); - xCursorPropertySet->setPropertyValue("ParaStyleName", uno::Any(OUString("Heading 1"))); - xText->insertString(xCursor, "Heading far below field", false); - - xField->attach(xFieldCursor); + // Assert + // Make sure the field has the right text CPPUNIT_ASSERT_EQUAL(OUString("Heading below field"), xField->getPresentation(false)); } /// STYLEREFs in marginals (headers or footers) should search in the page they are on first, regardless if there is anything above them CPPUNIT_TEST_FIXTURE(Test, testMarginalStyleRef) { + // Arrange + // Create a document with 2 headings createSwDoc(); uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); uno::Reference<text::XText> xText = xTextDocument->getText(); uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor(); - uno::Reference<beans::XPropertySet> xCursorPropertySet(xCursor, uno::UNO_QUERY); - xCursorPropertySet->setPropertyValue("ParaStyleName", uno::Any(OUString("Heading 1"))); - xText->insertString(xCursor, "Top heading on page", false); - xText->insertControlCharacter(xCursor, text::ControlCharacter::PARAGRAPH_BREAK, false); - - xCursorPropertySet->setPropertyValue("ParaStyleName", uno::Any(OUString("Heading 1"))); - xText->insertString(xCursor, "Bottom heading on page", false); - xText->insertControlCharacter(xCursor, text::ControlCharacter::PARAGRAPH_BREAK, false); + InsertHeading(xCursor, "Top heading on page"); + InsertHeading(xCursor, "Bottom heading on page"); + // Act + // Insert a STYLEREF field which looks for "Heading 1"s into the footer uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); uno::Reference<text::XTextField> xField( xFactory->createInstance("com.sun.star.text.TextField.GetReference"), uno::UNO_QUERY); @@ -305,28 +327,36 @@ CPPUNIT_TEST_FIXTURE(Test, testMarginalStyleRef) uno::Reference<text::XTextRange> xFooterCursor = xFooterText->createTextCursor(); xField->attach(xFooterCursor); + // Assert + // Make sure the field has the right text CPPUNIT_ASSERT_EQUAL(OUString("Top heading on page"), xField->getPresentation(false)); } /// STYLEREFs in footnotes should search from the point of the reference mark CPPUNIT_TEST_FIXTURE(Test, testFootnoteStyleRef) { + // Arrange + // Create a document with headings both above and below a cursor createSwDoc(); uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); uno::Reference<text::XText> xText = xTextDocument->getText(); uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor(); - uno::Reference<beans::XPropertySet> xCursorPropertySet(xCursor, uno::UNO_QUERY); - xCursorPropertySet->setPropertyValue("ParaStyleName", uno::Any(OUString("Heading 1"))); - xText->insertString(xCursor, "Heading far above reference mark", false); - xText->insertControlCharacter(xCursor, text::ControlCharacter::PARAGRAPH_BREAK, false); + InsertHeading(xCursor, "Heading far above reference mark"); + InsertHeading(xCursor, "Heading above reference mark"); + InsertParagraphBreak(xCursor); + InsertHeading(xCursor, "Heading below reference mark"); + InsertHeading(xCursor, "Heading far below reference mark"); - xCursorPropertySet->setPropertyValue("ParaStyleName", uno::Any(OUString("Heading 1"))); - xText->insertString(xCursor, "Heading above reference mark", false); - xText->insertControlCharacter(xCursor, text::ControlCharacter::PARAGRAPH_BREAK, false); + uno::Reference<text::XParagraphCursor> xParagraphCursor(xCursor, uno::UNO_QUERY); + xParagraphCursor->gotoPreviousParagraph(false); // Heading far below... + xParagraphCursor->gotoPreviousParagraph(false); // Heading below... + xParagraphCursor->gotoPreviousParagraph(false); // Blank space + // Act + // Insert a STYLEREF field which looks for "Heading 1"s into a footnote uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); uno::Reference<text::XFootnote> xFootnote( @@ -334,10 +364,6 @@ CPPUNIT_TEST_FIXTURE(Test, testFootnoteStyleRef) xFootnote->setLabel("Style reference mark"); xText->insertTextContent(xCursor, xFootnote, false); - xText->insertControlCharacter(xCursor, text::ControlCharacter::PARAGRAPH_BREAK, false); - xCursorPropertySet->setPropertyValue("ParaStyleName", uno::Any(OUString("Heading 1"))); - xText->insertString(xCursor, "Heading below reference mark", false); - uno::Reference<text::XTextField> xField( xFactory->createInstance("com.sun.star.text.TextField.GetReference"), uno::UNO_QUERY); @@ -352,8 +378,105 @@ CPPUNIT_TEST_FIXTURE(Test, testFootnoteStyleRef) uno::Reference<text::XTextRange> xFootnoteCursor = xFootnoteText->createTextCursor(); xField->attach(xFootnoteCursor); + // Assert + // Make sure the field has the right text CPPUNIT_ASSERT_EQUAL(OUString("Heading above reference mark"), xField->getPresentation(false)); } + +/// STYLEREFs with the REFFLDFLAG_HIDE_NON_NUMERICAL flag should hide all characters that are not numerical or delimiters +CPPUNIT_TEST_FIXTURE(Test, testNumericalStyleRef) +{ + loadFromURL(u"suppress-non-numerical.docx"); + + uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> xFieldsAccess( + xTextFieldsSupplier->getTextFields()); + uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration()); + + // Similarly to testChapterFieldsFollowedBy, the fields are enumerated with #1 first and everything else in reverse order + std::vector<std::pair<OUString, OUString>> aFieldValues = { + { " Heading 1", "3" }, // #1 + { " Heading 2", ".2\\@123^&~|a....." }, // #4 + { " Heading 2", ".2\\|a....." }, // #3 + { " Heading 1", "Chapter 3.!" }, // #2 + }; + + for (const auto& sValue : aFieldValues) + { + CPPUNIT_ASSERT(xFields->hasMoreElements()); + uno::Reference<text::XTextField> xField(xFields->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sValue.first, xField->getPresentation(true)); + CPPUNIT_ASSERT_EQUAL(sValue.second, xField->getPresentation(false)); + } + CPPUNIT_ASSERT(!xFields->hasMoreElements()); +} + +/// We should be able to import these flags from OOXML documents +/// (Note: in Word, STYLEREF 'search bottom up' flag does nothing unless it's in a marginal, we place no such limitation but +/// this docx only has such stylerefs to avoid confusion) +CPPUNIT_TEST_FIXTURE(Test, testOOXMLStyleRefFlags) +{ + loadFromURL(u"styleref-flags.docx"); + + uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> xFieldsAccess( + xTextFieldsSupplier->getTextFields()); + uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration()); + + // Similarly to testChapterFieldsFollowedBy, the fields are enumerated with #1 first and everything else in reverse order + std::vector<std::pair<OUString, OUString>> aFieldValues = { + { " Heading 2", "2.1" }, // #1 + { " Heading 1", "3" }, // #5 + { " Heading 1", "A top level heading at the top of the page" }, // #4 + { " Heading 1", "The last top level heading" }, // #3 + { " Heading 2", "Heading 2.1" }, // #2 + }; + + for (const auto& sValue : aFieldValues) + { + CPPUNIT_ASSERT(xFields->hasMoreElements()); + uno::Reference<text::XTextField> xField(xFields->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sValue.first, xField->getPresentation(true)); + CPPUNIT_ASSERT_EQUAL(sValue.second, xField->getPresentation(false)); + } + CPPUNIT_ASSERT(!xFields->hasMoreElements()); +} + +/// We should be able to import these flags from OOXML documents +/// (Note: in Word, STYLEREF 'search bottom up' flag does nothing unless it's in a marginal, we place no such limitation but +/// this docx only has such stylerefs to avoid confusion) +CPPUNIT_TEST_FIXTURE(Test, testODFStyleRef) +{ + loadFromURL(u"styleref.odt"); + + uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> xFieldsAccess( + xTextFieldsSupplier->getTextFields()); + uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration()); + + // Similarly to testChapterFieldsFollowedBy, the fields are enumerated with #1 first and everything else in reverse order + std::vector<std::pair<OUString, OUString>> aFieldValues = { + { " Heading 1", "1:" }, // #1 + { " Heading 2", "In footnotes" }, // #10 + { " Heading 2", "In document text" }, // #9 + { " Heading 1", "STYLEREF in different locations" }, // #8 + { " Heading 1", "2:" }, // #7 + { " Heading 1", "With STYLEREF, many things are possible" }, // #6 + { " Heading 1", "1:" }, // #5 + { " Heading 1", "STYLEREF in different locations" }, // #4 + { " Heading 1", "2:" }, // #3 + { " Heading 1", "With STYLEREF, many things are possible" }, // #2 + }; + + for (const auto& sValue : aFieldValues) + { + CPPUNIT_ASSERT(xFields->hasMoreElements()); + uno::Reference<text::XTextField> xField(xFields->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sValue.first, xField->getPresentation(true)); + CPPUNIT_ASSERT_EQUAL(sValue.second, xField->getPresentation(false)); + } + CPPUNIT_ASSERT(!xFields->hasMoreElements()); +} } CPPUNIT_PLUGIN_IMPLEMENT(); |