summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorSkyler Grey <skyler.grey@collabora.com>2023-10-23 09:17:23 +0000
committerCaolán McNamara <caolan.mcnamara@collabora.com>2023-11-02 10:27:52 +0100
commitfd5c75750f5c5448eec840033bce16375774a707 (patch)
tree752a27e4c7d41f9080b020484c408de1478188ae /sw
parent419866e851c7ad4a39bd508d607baba3590f3d45 (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.docxbin0 -> 23218 bytes
-rw-r--r--sw/qa/core/fields/data/styleref.odtbin0 -> 40280 bytes
-rw-r--r--sw/qa/core/fields/data/suppress-non-numerical.docxbin0 -> 17046 bytes
-rw-r--r--sw/qa/core/fields/fields.cxx215
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
new file mode 100644
index 000000000000..443624a575e0
--- /dev/null
+++ b/sw/qa/core/fields/data/styleref-flags.docx
Binary files differ
diff --git a/sw/qa/core/fields/data/styleref.odt b/sw/qa/core/fields/data/styleref.odt
new file mode 100644
index 000000000000..27af5aae1f06
--- /dev/null
+++ b/sw/qa/core/fields/data/styleref.odt
Binary files differ
diff --git a/sw/qa/core/fields/data/suppress-non-numerical.docx b/sw/qa/core/fields/data/suppress-non-numerical.docx
new file mode 100644
index 000000000000..439e048b9f93
--- /dev/null
+++ b/sw/qa/core/fields/data/suppress-non-numerical.docx
Binary files differ
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();