/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "charttest.hxx" #include #include #include #include #include #include #include #include #include #include using uno::Reference; using beans::XPropertySet; class Chart2ExportTest : public ChartTest { public: Chart2ExportTest() : ChartTest() {} void test(); void testErrorBarXLSX(); void testTrendline(); void testStockChart(); void testBarChart(); void testCrosses(); void testScatterChart(); void testChartDataTable(); void testChartExternalData(); void testEmbeddingsGrabBag(); void testAreaChartLoad(); void testUpDownBars(); void testDoughnutChart(); void testDisplayUnits(); // void testFdo74115WallGradientFill(); void testFdo74115WallBitmapFill(); void testBarChartRotation(); void testShapeFollowedByChart(); void testPieChartDataLabels(); void testSeriesIdxOrder(); void testErrorBarDataRangeODS(); void testChartCrash(); void testPieChartRotation(); void testEmbeddingsOleObjectGrabBag(); void testGapWidthXLSX(); void testSmoothedLines(); void testLabelStringODS(); CPPUNIT_TEST_SUITE(Chart2ExportTest); CPPUNIT_TEST(test); CPPUNIT_TEST(testErrorBarXLSX); CPPUNIT_TEST(testTrendline); CPPUNIT_TEST(testStockChart); CPPUNIT_TEST(testBarChart); CPPUNIT_TEST(testCrosses); CPPUNIT_TEST(testScatterChart); CPPUNIT_TEST(testChartDataTable); CPPUNIT_TEST(testChartExternalData); CPPUNIT_TEST(testEmbeddingsGrabBag); CPPUNIT_TEST(testAreaChartLoad); CPPUNIT_TEST(testUpDownBars); CPPUNIT_TEST(testDoughnutChart); CPPUNIT_TEST(testDisplayUnits); // CPPUNIT_TEST(testFdo74115WallGradientFill); CPPUNIT_TEST(testFdo74115WallBitmapFill); CPPUNIT_TEST(testBarChartRotation); CPPUNIT_TEST(testShapeFollowedByChart); CPPUNIT_TEST(testPieChartDataLabels); CPPUNIT_TEST(testSeriesIdxOrder); CPPUNIT_TEST(testErrorBarDataRangeODS); CPPUNIT_TEST(testChartCrash); CPPUNIT_TEST(testPieChartRotation); CPPUNIT_TEST(testEmbeddingsOleObjectGrabBag); CPPUNIT_TEST(testGapWidthXLSX); CPPUNIT_TEST(testSmoothedLines); CPPUNIT_TEST(testLabelStringODS); CPPUNIT_TEST_SUITE_END(); protected: /** * Given that some problem doesn't affect the result in the importer, we * test the resulting file directly, by opening the zip file, parsing an * xml stream, and asserting an XPath expression. This method returns the * xml stream, so that you can do the asserting. */ xmlDocPtr parseExport(const OUString& rDir, const OUString& rFilterFormat); /** * Helper method to return nodes represented by rXPath. */ xmlNodeSetPtr getXPathNode(xmlDocPtr pXmlDoc, const OString& rXPath); /** * Assert that rXPath exists, and returns exactly one node. * In case rAttribute is provided, the rXPath's attribute's value must * equal to the rExpected value. */ void assertXPath(xmlDocPtr pXmlDoc, const OString& rXPath, const OString& rAttribute = OString(), const OUString& rExpectedValue = OUString()); /** * Assert that rXPath exists, and returns exactly nNumberOfNodes nodes. * Useful for checking that we do _not_ export some node (nNumberOfNodes == 0). */ void assertXPath(xmlDocPtr pXmlDoc, const OString& rXPath, int nNumberOfNodes); /** * Same as the assertXPath(), but don't assert: return the string instead. */ OUString getXPath(xmlDocPtr pXmlDoc, const OString& rXPath, const OString& rAttribute); /** Assert that rXPath exists, and its content equals rContent. */ void assertXPathContent(xmlDocPtr pXmlDoc, const OString& rXPath, const OUString& rContent); /** Same as the assertXPathContent(), but don't assert: return the string instead. */ OUString getXPathContent(xmlDocPtr pXmlDoc, const OString& rXPath); private: }; void Chart2ExportTest::test() { load("/chart2/qa/extras/data/ods/", "simple_export_chart.ods"); reload("Calc Office Open XML"); } struct CheckForChartName { private: OUString aDir; public: CheckForChartName( const OUString& rDir ): aDir(rDir) {} bool operator()(const OUString& rName) { if(!rName.startsWith(aDir)) return false; if(!rName.endsWith(".xml")) return false; return true; } }; OUString findChartFile(const OUString& rDir, uno::Reference< container::XNameAccess > xNames ) { uno::Sequence rNames = xNames->getElementNames(); OUString* pElement = std::find_if(rNames.begin(), rNames.end(), CheckForChartName(rDir)); CPPUNIT_ASSERT(pElement); CPPUNIT_ASSERT(pElement != rNames.end()); return *pElement; } xmlDocPtr Chart2ExportTest::parseExport(const OUString& rDir, const OUString& rFilterFormat) { boost::shared_ptr pTempFile = reload(rFilterFormat); // Read the XML stream we're interested in. uno::Reference xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), pTempFile->GetURL()); uno::Reference xInputStream(xNameAccess->getByName(findChartFile(rDir, xNameAccess)), uno::UNO_QUERY); CPPUNIT_ASSERT(xInputStream.is()); boost::shared_ptr pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true)); sal_uInt64 const nSize = pStream->remainingSize(); OStringBuffer aDocument(nSize); char ch; for (sal_Size i = 0; i < nSize; ++i) { pStream->ReadChar( ch ); aDocument.append(ch); } // Parse the XML. return xmlParseMemory((const char*)aDocument.getStr(), aDocument.getLength()); } xmlNodeSetPtr Chart2ExportTest::getXPathNode(xmlDocPtr pXmlDoc, const OString& rXPath) { xmlXPathContextPtr pXmlXpathCtx = xmlXPathNewContext(pXmlDoc); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("w"), BAD_CAST("http://schemas.openxmlformats.org/wordprocessingml/2006/main")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("v"), BAD_CAST("urn:schemas-microsoft-com:vml")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("c"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/chart")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("a"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/main")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("mc"), BAD_CAST("http://schemas.openxmlformats.org/markup-compatibility/2006")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("wps"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingShape")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("wpg"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingGroup")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("wp"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing")); xmlXPathObjectPtr pXmlXpathObj = xmlXPathEvalExpression(BAD_CAST(rXPath.getStr()), pXmlXpathCtx); return pXmlXpathObj->nodesetval; } void Chart2ExportTest::assertXPath(xmlDocPtr pXmlDoc, const OString& rXPath, const OString& rAttribute, const OUString& rExpectedValue) { OUString aValue = getXPath(pXmlDoc, rXPath, rAttribute); CPPUNIT_ASSERT_EQUAL_MESSAGE( OString("Attribute '" + rAttribute + "' of '" + rXPath + "' incorrect value.").getStr(), rExpectedValue, aValue); } void Chart2ExportTest::assertXPath(xmlDocPtr pXmlDoc, const OString& rXPath, int nNumberOfNodes) { xmlNodeSetPtr pXmlNodes = getXPathNode(pXmlDoc, rXPath); CPPUNIT_ASSERT_EQUAL_MESSAGE( OString("XPath '" + rXPath + "' number of nodes is incorrect").getStr(), nNumberOfNodes, xmlXPathNodeSetGetLength(pXmlNodes)); } void Chart2ExportTest::assertXPathContent(xmlDocPtr pXmlDoc, const OString& rXPath, const OUString& rContent) { CPPUNIT_ASSERT_EQUAL_MESSAGE("XPath contents of child does not match", rContent, getXPathContent(pXmlDoc, rXPath)); } OUString Chart2ExportTest::getXPathContent(xmlDocPtr pXmlDoc, const OString& rXPath) { xmlNodeSetPtr pXmlNodes = getXPathNode(pXmlDoc, rXPath); CPPUNIT_ASSERT_MESSAGE(OString("XPath '" + rXPath + "' not found").getStr(), xmlXPathNodeSetGetLength(pXmlNodes) > 0); xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0]; _xmlNode *pNode = &(pXmlNode->children[0]); return pNode ? OUString::createFromAscii((const char*)((pXmlNode->children[0]).content)) : OUString(); } OUString Chart2ExportTest::getXPath(xmlDocPtr pXmlDoc, const OString& rXPath, const OString& rAttribute) { xmlNodeSetPtr pXmlNodes = getXPathNode(pXmlDoc, rXPath); CPPUNIT_ASSERT_EQUAL_MESSAGE( OString("XPath '" + rXPath + "' number of nodes is incorrect").getStr(), 1, xmlXPathNodeSetGetLength(pXmlNodes)); if (rAttribute.isEmpty()) return OUString(); xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0]; return OUString::createFromAscii((const char*)xmlGetProp(pXmlNode, BAD_CAST(rAttribute.getStr()))); } namespace { void testErrorBar( Reference< XPropertySet > xErrorBar ) { sal_Int32 nErrorBarStyle; CPPUNIT_ASSERT( xErrorBar->getPropertyValue("ErrorBarStyle") >>= nErrorBarStyle); CPPUNIT_ASSERT_EQUAL(nErrorBarStyle, chart::ErrorBarStyle::RELATIVE); bool bShowPositive = bool(), bShowNegative = bool(); CPPUNIT_ASSERT( xErrorBar->getPropertyValue("ShowPositiveError") >>= bShowPositive); CPPUNIT_ASSERT(bShowPositive); CPPUNIT_ASSERT( xErrorBar->getPropertyValue("ShowNegativeError") >>= bShowNegative); CPPUNIT_ASSERT(bShowNegative); double nVal = 0.0; CPPUNIT_ASSERT(xErrorBar->getPropertyValue("PositiveError") >>= nVal); CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal, 10.0, 1e-10); } void checkCommonTrendline( Reference xCurve, double aExpectedExtrapolateForward, double aExpectedExtrapolateBackward, sal_Bool aExpectedForceIntercept, double aExpectedInterceptValue, sal_Bool aExpectedShowEquation, sal_Bool aExpectedR2) { Reference xProperties( xCurve , uno::UNO_QUERY ); CPPUNIT_ASSERT(xProperties.is()); double aExtrapolateForward = 0.0; CPPUNIT_ASSERT(xProperties->getPropertyValue("ExtrapolateForward") >>= aExtrapolateForward); CPPUNIT_ASSERT_EQUAL(aExpectedExtrapolateForward, aExtrapolateForward); double aExtrapolateBackward = 0.0; CPPUNIT_ASSERT(xProperties->getPropertyValue("ExtrapolateBackward") >>= aExtrapolateBackward); CPPUNIT_ASSERT_EQUAL(aExpectedExtrapolateBackward, aExtrapolateBackward); sal_Bool aForceIntercept = false; CPPUNIT_ASSERT(xProperties->getPropertyValue("ForceIntercept") >>= aForceIntercept); CPPUNIT_ASSERT_EQUAL(aExpectedForceIntercept, aForceIntercept); if (aForceIntercept) { double aInterceptValue = 0.0; CPPUNIT_ASSERT(xProperties->getPropertyValue("InterceptValue") >>= aInterceptValue); CPPUNIT_ASSERT_EQUAL(aExpectedInterceptValue, aInterceptValue); } Reference< XPropertySet > xEquationProperties( xCurve->getEquationProperties() ); CPPUNIT_ASSERT(xEquationProperties.is()); sal_Bool aShowEquation = false; CPPUNIT_ASSERT(xEquationProperties->getPropertyValue("ShowEquation") >>= aShowEquation); CPPUNIT_ASSERT_EQUAL(aExpectedShowEquation, aShowEquation); sal_Bool aShowCorrelationCoefficient = false; CPPUNIT_ASSERT(xEquationProperties->getPropertyValue("ShowCorrelationCoefficient") >>= aShowCorrelationCoefficient); CPPUNIT_ASSERT_EQUAL(aExpectedR2, aShowCorrelationCoefficient); } void checkNameAndType(Reference xProperties, const OUString& aExpectedName, const OUString& aExpectedServiceName) { Reference< lang::XServiceName > xServiceName( xProperties, UNO_QUERY ); CPPUNIT_ASSERT(xServiceName.is()); OUString aServiceName = xServiceName->getServiceName(); CPPUNIT_ASSERT_EQUAL(aExpectedServiceName, aServiceName); OUString aCurveName; CPPUNIT_ASSERT(xProperties->getPropertyValue("CurveName") >>= aCurveName); CPPUNIT_ASSERT_EQUAL(aExpectedName, aCurveName); } void checkLinearTrendline( Reference xCurve, const OUString& aExpectedName, double aExpectedExtrapolateForward, double aExpectedExtrapolateBackward, sal_Bool aExpectedForceIntercept, double aExpectedInterceptValue, sal_Bool aExpectedShowEquation, sal_Bool aExpectedR2) { Reference xProperties( xCurve , uno::UNO_QUERY ); CPPUNIT_ASSERT(xProperties.is()); checkNameAndType(xProperties, aExpectedName, "com.sun.star.chart2.LinearRegressionCurve"); checkCommonTrendline( xCurve, aExpectedExtrapolateForward, aExpectedExtrapolateBackward, aExpectedForceIntercept, aExpectedInterceptValue, aExpectedShowEquation, aExpectedR2); } void checkPolynomialTrendline( Reference xCurve, const OUString& aExpectedName, sal_Int32 aExpectedDegree, double aExpectedExtrapolateForward, double aExpectedExtrapolateBackward, sal_Bool aExpectedForceIntercept, double aExpectedInterceptValue, sal_Bool aExpectedShowEquation, sal_Bool aExpectedR2) { Reference xProperties( xCurve , uno::UNO_QUERY ); CPPUNIT_ASSERT(xProperties.is()); checkNameAndType(xProperties, aExpectedName, "com.sun.star.chart2.PolynomialRegressionCurve"); sal_Int32 aDegree = 2; CPPUNIT_ASSERT(xProperties->getPropertyValue("PolynomialDegree") >>= aDegree); CPPUNIT_ASSERT_EQUAL(aExpectedDegree, aDegree); checkCommonTrendline( xCurve, aExpectedExtrapolateForward, aExpectedExtrapolateBackward, aExpectedForceIntercept, aExpectedInterceptValue, aExpectedShowEquation, aExpectedR2); } void checkMovingAverageTrendline( Reference xCurve, const OUString& aExpectedName, sal_Int32 aExpectedPeriod) { Reference xProperties( xCurve , uno::UNO_QUERY ); CPPUNIT_ASSERT(xProperties.is()); checkNameAndType(xProperties, aExpectedName, "com.sun.star.chart2.MovingAverageRegressionCurve"); sal_Int32 aPeriod = 2; CPPUNIT_ASSERT(xProperties->getPropertyValue("MovingAveragePeriod") >>= aPeriod); CPPUNIT_ASSERT_EQUAL(aExpectedPeriod, aPeriod); } void checkTrendlinesInChart(uno::Reference< chart2::XChartDocument > xChartDoc) { CPPUNIT_ASSERT(xChartDoc.is()); Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( xChartDoc, 0 ); CPPUNIT_ASSERT( xDataSeries.is() ); Reference< chart2::XRegressionCurveContainer > xRegressionCurveContainer( xDataSeries, UNO_QUERY ); CPPUNIT_ASSERT( xRegressionCurveContainer.is() ); Sequence< Reference< chart2::XRegressionCurve > > xRegressionCurveSequence = xRegressionCurveContainer->getRegressionCurves(); CPPUNIT_ASSERT_EQUAL((sal_Int32) 3, xRegressionCurveSequence.getLength()); Reference xCurve; xCurve = xRegressionCurveSequence[0]; CPPUNIT_ASSERT(xCurve.is()); checkPolynomialTrendline(xCurve, "col2_poly", 3, 0.1, -0.1, true, -1.0, true, true); xCurve = xRegressionCurveSequence[1]; CPPUNIT_ASSERT(xCurve.is()); checkLinearTrendline(xCurve, "col2_linear", -0.5, -0.5, false, 0.0, true, false); xCurve = xRegressionCurveSequence[2]; CPPUNIT_ASSERT(xCurve.is()); checkMovingAverageTrendline(xCurve, "col2_moving_avg", 3); } } // improve the test void Chart2ExportTest::testErrorBarXLSX() { load("/chart2/qa/extras/data/ods/", "error_bar.ods"); { // make sure the ODS import was successful uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0, mxComponent ); CPPUNIT_ASSERT(xChartDoc.is()); Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( xChartDoc, 0 ); CPPUNIT_ASSERT( xDataSeries.is() ); Reference< beans::XPropertySet > xPropSet( xDataSeries, UNO_QUERY_THROW ); CPPUNIT_ASSERT( xPropSet.is() ); // test that y error bars are there Reference< beans::XPropertySet > xErrorBarYProps; xPropSet->getPropertyValue("ErrorBarY") >>= xErrorBarYProps; testErrorBar(xErrorBarYProps); } reload("Calc Office Open XML"); { uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0, mxComponent ); CPPUNIT_ASSERT(xChartDoc.is()); Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( xChartDoc, 0 ); CPPUNIT_ASSERT( xDataSeries.is() ); Reference< beans::XPropertySet > xPropSet( xDataSeries, UNO_QUERY_THROW ); CPPUNIT_ASSERT( xPropSet.is() ); // test that y error bars are there Reference< beans::XPropertySet > xErrorBarYProps; xPropSet->getPropertyValue("ErrorBarY") >>= xErrorBarYProps; testErrorBar(xErrorBarYProps); } } // This method tests the preservation of properties for trendlines / regression curves // in an export -> import cycle using different file formats - ODS, XLS and XLSX. void Chart2ExportTest::testTrendline() { mbSkipValidation = true; load("/chart2/qa/extras/data/ods/", "trendline.ods"); checkTrendlinesInChart(getChartDocFromSheet( 0, mxComponent)); reload("calc8"); checkTrendlinesInChart(getChartDocFromSheet( 0, mxComponent)); load("/chart2/qa/extras/data/ods/", "trendline.ods"); checkTrendlinesInChart(getChartDocFromSheet( 0, mxComponent)); reload("Calc Office Open XML"); checkTrendlinesInChart(getChartDocFromSheet( 0, mxComponent)); load("/chart2/qa/extras/data/ods/", "trendline.ods"); checkTrendlinesInChart(getChartDocFromSheet( 0, mxComponent)); reload("MS Excel 97"); checkTrendlinesInChart(getChartDocFromSheet( 0, mxComponent)); } void Chart2ExportTest::testStockChart() { /* For attached file Stock_Chart.docx, in chart1.xml, * , there are four types of series as * Open,Low,High and Close. * For Open series, in * an attribute val of index should start from 1 and not from 0. * Which was problem area. */ load("/chart2/qa/extras/data/docx/", "testStockChart.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); if (!pXmlDoc) return; assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:stockChart/c:ser[1]/c:idx", "val", "1"); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:stockChart/c:ser[1]/c:order", "val", "1"); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:stockChart/c:ser[1]/c:tx/c:strRef/c:strCache/c:pt/c:v", "Open"); } void Chart2ExportTest::testBarChart() { load("/chart2/qa/extras/data/docx/", "testBarChart.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); if (!pXmlDoc) return; assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:barDir", "val", "col"); } void Chart2ExportTest::testCrosses() { load("/chart2/qa/extras/data/docx/", "Bar_horizontal_cone.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:catAx/c:crosses", "val", "autoZero"); } void Chart2ExportTest::testScatterChart() { load("/chart2/qa/extras/data/docx/", "fdo77216.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); if (!pXmlDoc) return; assertXPathContent(pXmlDoc, "//c:scatterChart/c:ser[1]/c:xVal[1]/c:numRef[1]/c:numCache[1]/c:pt[1]/c:v[1]", "1"); } void Chart2ExportTest::testChartDataTable() { load("/chart2/qa/extras/data/docx/", "testChartDataTable.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); CPPUNIT_ASSERT(pXmlDoc); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:dTable/c:showHorzBorder", "val", "1"); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:dTable/c:showVertBorder", "val", "1"); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:dTable/c:showOutline", "val", "1"); } void Chart2ExportTest::testChartExternalData() { load("/chart2/qa/extras/data/docx/", "testMultipleChart.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); CPPUNIT_ASSERT(pXmlDoc); xmlNodeSetPtr pXmlNodes = getXPathNode(pXmlDoc, "/c:chartSpace/c:externalData"); CPPUNIT_ASSERT(pXmlNodes); } void Chart2ExportTest::testEmbeddingsGrabBag() { // The problem was that .xlsx files were missing from docx file from embeddings folder // after saving file. // This test case tests whether embeddings files grabbagged properly in correct object. load("/chart2/qa/extras/data/docx/", "testMultiplechartembeddings.docx" ); uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); uno::Reference xTextDocumentPropertySet(xTextDocument, uno::UNO_QUERY); uno::Sequence aGrabBag(0); xTextDocumentPropertySet->getPropertyValue(OUString("InteropGrabBag")) >>= aGrabBag; CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty bool bEmbeddings = false; const char* testEmbeddedFileNames[3] = {"word/embeddings/Microsoft_Excel_Worksheet3.xlsx", "word/embeddings/Microsoft_Excel_Worksheet2.xlsx", "word/embeddings/Microsoft_Excel_Worksheet1.xlsx"}; for(int i = 0; i < aGrabBag.getLength(); ++i) { if (aGrabBag[i].Name == "OOXEmbeddings") { bEmbeddings = true; uno::Sequence aEmbeddingsList(0); uno::Reference aEmbeddingXlsxStream; OUString aEmbeddedfileName; CPPUNIT_ASSERT(aGrabBag[i].Value >>= aEmbeddingsList); // PropertyValue of proper type sal_Int32 length = aEmbeddingsList.getLength(); CPPUNIT_ASSERT_EQUAL(sal_Int32(3), length); for(int j = 0; j < length; ++j) { aEmbeddingsList[j].Value >>= aEmbeddingXlsxStream; aEmbeddedfileName = aEmbeddingsList[j].Name; CPPUNIT_ASSERT(aEmbeddingXlsxStream.get()); // Reference not empty CPPUNIT_ASSERT_EQUAL(OUString::createFromAscii(testEmbeddedFileNames[j]),aEmbeddedfileName); } } } CPPUNIT_ASSERT(bEmbeddings); // Grab Bag has all the expected elements } void Chart2ExportTest::testAreaChartLoad() { load ("/chart2/qa/extras/data/docx/", "testAreaChartLoad.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart","Office Open XML Text"); CPPUNIT_ASSERT(pXmlDoc); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:areaChart/c:ser/c:dLbls/c:showVal", "val", "1"); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:areaChart/c:ser/c:dLbls/c:dLbl", 0); } void Chart2ExportTest::testUpDownBars() { load("/chart2/qa/extras/data/docx/", "UpDownBars.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); CPPUNIT_ASSERT(pXmlDoc); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:lineChart/c:upDownBars"); } void Chart2ExportTest::testDoughnutChart() { load("/chart2/qa/extras/data/docx/", "doughnutChart.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); CPPUNIT_ASSERT(pXmlDoc); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:doughnutChart", "1"); } void Chart2ExportTest::testDisplayUnits() { load("/chart2/qa/extras/data/docx/", "DisplayUnits.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); CPPUNIT_ASSERT(pXmlDoc); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:valAx/c:dispUnits/c:builtInUnit", "val", "billions"); } // void Chart2ExportTest::testFdo74115WallGradientFill() // { // load("/chart2/qa/extras/data/docx/", "fdo74115_WallGradientFill.docx"); // xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); // CPPUNIT_ASSERT(pXmlDoc); // // assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:spPr/a:gradFill"); // } void Chart2ExportTest::testFdo74115WallBitmapFill() { load("/chart2/qa/extras/data/docx/", "fdo74115_WallBitmapFill.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); CPPUNIT_ASSERT(pXmlDoc); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:spPr/a:blipFill"); } void Chart2ExportTest::testBarChartRotation() { load ("/chart2/qa/extras/data/docx/", "barChartRotation.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart","Office Open XML Text"); CPPUNIT_ASSERT(pXmlDoc); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:view3D/c:rotX", "val", "30"); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:view3D/c:rotY", "val", "50"); } void Chart2ExportTest::testShapeFollowedByChart() { /* If there is a scenario where a chart is followed by a shape which is being exported as an alternate content then, the docPr Id is being repeated, ECMA 20.4.2.5 says that the docPr Id should be unique, ensuring the same here. */ load("/chart2/qa/extras/data/docx/", "FDO74430.docx"); xmlDocPtr pXmlDoc = parseExport("word/document", "Office Open XML Text" ); CPPUNIT_ASSERT(pXmlDoc); OUString aValueOfFirstDocPR = getXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r[1]/w:drawing[1]/wp:inline[1]/wp:docPr[1]", "id"); OUString aValueOfSecondDocPR = getXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r[2]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/wp:docPr[1]", "id"); CPPUNIT_ASSERT( aValueOfFirstDocPR != aValueOfSecondDocPR ); } void Chart2ExportTest::testPieChartDataLabels() { load("/chart2/qa/extras/data/docx/", "PieChartDataLabels.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); CPPUNIT_ASSERT(pXmlDoc); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:pie3DChart/c:ser[1]/c:dLbls/c:dLbl[1]/c:dLblPos", "val", "bestFit"); } void Chart2ExportTest::testSeriesIdxOrder() { load("/chart2/qa/extras/data/docx/", "testSeriesIdxOrder.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); CPPUNIT_ASSERT(pXmlDoc); assertXPath(pXmlDoc, "/c:chartSpace[1]/c:chart[1]/c:plotArea[1]/c:lineChart[1]/c:ser[1]/c:idx[1]", "val", "1"); assertXPath(pXmlDoc, "/c:chartSpace[1]/c:chart[1]/c:plotArea[1]/c:lineChart[1]/c:ser[1]/c:order[1]", "val", "1"); } void Chart2ExportTest::testErrorBarDataRangeODS() { load("/chart2/qa/extras/data/ods/", "ErrorBarRange.ods"); reload("calc8"); uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0, mxComponent ); CPPUNIT_ASSERT(xChartDoc.is()); Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( xChartDoc, 0 ); CPPUNIT_ASSERT( xDataSeries.is() ); Reference< beans::XPropertySet > xPropSet( xDataSeries, UNO_QUERY_THROW ); CPPUNIT_ASSERT( xPropSet.is() ); // test that y error bars are there Reference< beans::XPropertySet > xErrorBarYProps; xPropSet->getPropertyValue("ErrorBarY") >>= xErrorBarYProps; uno::Any aAny = xErrorBarYProps->getPropertyValue("ErrorBarRangePositive"); CPPUNIT_ASSERT(aAny.hasValue()); OUString aPosRange; aAny >>= aPosRange; CPPUNIT_ASSERT_EQUAL(OUString("$Sheet1.$B$1:$B$3"), aPosRange); aAny = xErrorBarYProps->getPropertyValue("ErrorBarRangeNegative"); CPPUNIT_ASSERT(aAny.hasValue()); OUString aNegRange; aAny >>= aNegRange; CPPUNIT_ASSERT_EQUAL(OUString("$Sheet1.$C$1:$C$3"), aNegRange); } void Chart2ExportTest::testChartCrash() { load("/chart2/qa/extras/data/docx/", "FDO75975.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); CPPUNIT_ASSERT(pXmlDoc); } void Chart2ExportTest::testPieChartRotation() { load ("/chart2/qa/extras/data/docx/", "pieChartRotation.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart","Office Open XML Text"); CPPUNIT_ASSERT(pXmlDoc); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:view3D/c:rotX", "val", "40"); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:view3D/c:rotY", "val", "30"); } void Chart2ExportTest::testEmbeddingsOleObjectGrabBag() { // The problem was that .bin files were missing from docx file from embeddings folder // after saving file. // This test case tests whether embeddings files grabbagged properly in correct object. load("/chart2/qa/extras/data/docx/", "testchartoleobjectembeddings.docx" ); uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); uno::Reference xTextDocumentPropertySet(xTextDocument, uno::UNO_QUERY); uno::Sequence aGrabBag(0); xTextDocumentPropertySet->getPropertyValue(OUString("InteropGrabBag")) >>= aGrabBag; CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty bool bEmbeddings = false; const char* testEmbeddedFileNames[1] = {"word/embeddings/oleObject1.bin"}; for(int i = 0; i < aGrabBag.getLength(); ++i) { if (aGrabBag[i].Name == "OOXEmbeddings") { bEmbeddings = true; uno::Sequence aEmbeddingsList(0); uno::Reference aEmbeddingXlsxStream; OUString aEmbeddedfileName; CPPUNIT_ASSERT(aGrabBag[i].Value >>= aEmbeddingsList); // PropertyValue of proper type sal_Int32 length = aEmbeddingsList.getLength(); CPPUNIT_ASSERT_EQUAL(sal_Int32(1), length); for(int j = 0; j < length; ++j) { aEmbeddingsList[j].Value >>= aEmbeddingXlsxStream; aEmbeddedfileName = aEmbeddingsList[j].Name; CPPUNIT_ASSERT(aEmbeddingXlsxStream.get()); // Reference not empty CPPUNIT_ASSERT_EQUAL(OUString::createFromAscii(testEmbeddedFileNames[j]),aEmbeddedfileName); } } } CPPUNIT_ASSERT(bEmbeddings); // Grab Bag has all the expected elements } namespace { void checkGapWidth(Reference xPropSet, sal_Int32 nValue) { uno::Any aAny = xPropSet->getPropertyValue("GapwidthSequence"); CPPUNIT_ASSERT(aAny.hasValue()); uno::Sequence< sal_Int32 > aSequence; aAny >>= aSequence; CPPUNIT_ASSERT(aSequence.getLength()); CPPUNIT_ASSERT_EQUAL(nValue, aSequence[0]); } void checkOverlap(Reference xPropSet, sal_Int32 nValue) { uno::Any aAny = xPropSet->getPropertyValue("OverlapSequence"); CPPUNIT_ASSERT(aAny.hasValue()); uno::Sequence< sal_Int32 > aSequence; aAny >>= aSequence; CPPUNIT_ASSERT(aSequence.getLength()); CPPUNIT_ASSERT_EQUAL(nValue, aSequence[0]); } void checkSheetForGapWidthAndOverlap(uno::Reference< chart2::XChartDocument > xChartDoc, sal_Int32 nExpectedGapWidth, sal_Int32 nExpectedOverlap) { CPPUNIT_ASSERT(xChartDoc.is()); Reference< chart2::XChartType > xChartType = getChartTypeFromDoc( xChartDoc, 0, 0 ); CPPUNIT_ASSERT(xChartType.is()); Reference< beans::XPropertySet > xPropSet( xChartType, uno::UNO_QUERY_THROW ); checkGapWidth(xPropSet, nExpectedGapWidth); checkOverlap(xPropSet, nExpectedOverlap); } } void Chart2ExportTest::testGapWidthXLSX() { load("/chart2/qa/extras/data/xlsx/", "gapWidth.xlsx"); uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0, mxComponent ); checkSheetForGapWidthAndOverlap(xChartDoc, 120, -60); xChartDoc = getChartDocFromSheet( 1, mxComponent ); checkSheetForGapWidthAndOverlap(xChartDoc, 50, 30); reload("Calc Office Open XML"); xChartDoc = getChartDocFromSheet( 0, mxComponent ); checkSheetForGapWidthAndOverlap(xChartDoc, 120, -60); xChartDoc = getChartDocFromSheet( 1, mxComponent ); checkSheetForGapWidthAndOverlap(xChartDoc, 50, 30); } void Chart2ExportTest::testSmoothedLines() { load("/chart2/qa/extras/data/ods/", "smoothedLines.ods"); xmlDocPtr pXmlDoc = parseExport("xl/charts/chart", "Calc Office Open XML"); CPPUNIT_ASSERT(pXmlDoc); assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser[1]/c:smooth", "val", "0"); } void Chart2ExportTest::testLabelStringODS() { load("/chart2/qa/extras/data/ods/", "labelString.ods"); uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0, mxComponent ); Reference< chart2::data::XDataSequence > xLabelSeq = getLabelDataSequenceFromDoc(xChartDoc); CPPUNIT_ASSERT(xLabelSeq.is()); OUString aLabelString = xLabelSeq->getSourceRangeRepresentation(); CPPUNIT_ASSERT_EQUAL(OUString("\"LabelName\""), aLabelString); reload("calc8"); xChartDoc = getChartDocFromSheet( 0, mxComponent ); xLabelSeq = getLabelDataSequenceFromDoc(xChartDoc); CPPUNIT_ASSERT(xLabelSeq.is()); aLabelString = xLabelSeq->getSourceRangeRepresentation(); CPPUNIT_ASSERT_EQUAL(OUString("\"LabelName\""), aLabelString); } CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ExportTest); CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */