LCOV - code coverage report
Current view: top level - sc/qa/unit/helper - qahelper.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 302 390 77.4 %
Date: 2014-11-03 Functions: 29 35 82.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include "qahelper.hxx"
      11             : #include "csv_handler.hxx"
      12             : #include "drwlayer.hxx"
      13             : #include "compiler.hxx"
      14             : #include "conditio.hxx"
      15             : #include "stlsheet.hxx"
      16             : #include "formulacell.hxx"
      17             : #include <svx/svdpage.hxx>
      18             : #include <svx/svdoole2.hxx>
      19             : #include <editeng/brushitem.hxx>
      20             : #include <editeng/justifyitem.hxx>
      21             : 
      22             : #include <config_orcus.h>
      23             : 
      24             : #if ENABLE_ORCUS
      25             : #if defined WNT
      26             : #define __ORCUS_STATIC_LIB
      27             : #endif
      28             : #include <orcus/csv_parser.hpp>
      29             : #endif
      30             : 
      31             : #include <fstream>
      32             : 
      33             : #include <com/sun/star/frame/XModel.hpp>
      34             : #include <com/sun/star/text/textfield/Type.hpp>
      35             : #include <com/sun/star/chart2/XChartDocument.hpp>
      36             : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
      37             : 
      38             : using namespace com::sun::star;
      39             : using namespace ::com::sun::star::uno;
      40             : 
      41             : // calc data structure pretty printer
      42           0 : std::ostream& operator<<(std::ostream& rStrm, const ScAddress& rAddr)
      43             : {
      44           0 :     rStrm << "Col: " << rAddr.Col() << " Row: " << rAddr.Row() << " Tab: " << rAddr.Tab() << "\n";
      45           0 :     return rStrm;
      46             : }
      47             : 
      48           0 : std::ostream& operator<<(std::ostream& rStrm, const ScRange& rRange)
      49             : {
      50           0 :     rStrm << "ScRange: " << rRange.aStart << rRange.aEnd << "\n";
      51           0 :     return rStrm;
      52             : }
      53             : 
      54           0 : std::ostream& operator<<(std::ostream& rStrm, const ScRangeList& rList)
      55             : {
      56           0 :     rStrm << "ScRangeList: \n";
      57           0 :     for(size_t i = 0; i < rList.size(); ++i)
      58           0 :         rStrm << *rList[i];
      59           0 :     return rStrm;
      60             : }
      61             : 
      62           0 : std::ostream& operator<<(std::ostream& rStrm, const Color& rColor)
      63             : {
      64           0 :     rStrm << "Color: R:" << rColor.GetRed() << " G:" << rColor.GetGreen() << " B: << rColor.GetBlue()";
      65           0 :     return rStrm;
      66             : }
      67             : 
      68             : FileFormat aFileFormats[] = {
      69             :     { "ods" , "calc8", "", ODS_FORMAT_TYPE },
      70             :     { "xls" , "MS Excel 97", "calc_MS_EXCEL_97", XLS_FORMAT_TYPE },
      71             :     { "xlsx", "Calc Office Open XML" , "Office Open XML Spreadsheet", XLSX_FORMAT_TYPE },
      72             :     { "xlsm", "Calc Office Open XML" , "Office Open XML Spreadsheet", XLSX_FORMAT_TYPE },
      73             :     { "csv" , "Text - txt - csv (StarCalc)", "generic_Text", CSV_FORMAT_TYPE },
      74             :     { "html" , "calc_HTML_WebQuery", "generic_HTML", HTML_FORMAT_TYPE },
      75             :     { "123" , "Lotus", "calc_Lotus", LOTUS123_FORMAT_TYPE },
      76             :     { "dif", "DIF", "calc_DIF", DIF_FORMAT_TYPE },
      77             :     { "xml", "MS Excel 2003 XML", "calc_MS_Excel_2003_XML", XLS_XML_FORMAT_TYPE }
      78             : };
      79             : 
      80          52 : bool testEqualsWithTolerance( long nVal1, long nVal2, long nTol )
      81             : {
      82          52 :     return ( labs( nVal1 - nVal2 ) <= nTol );
      83             : }
      84             : 
      85          84 : void loadFile(const OUString& aFileName, std::string& aContent)
      86             : {
      87          84 :     OString aOFileName = OUStringToOString(aFileName, RTL_TEXTENCODING_UTF8);
      88             : 
      89             : #ifdef ANDROID
      90             :     size_t size;
      91             :     if (strncmp(aOFileName.getStr(), "/assets/", sizeof("/assets/")-1) == 0) {
      92             :         const char *contents = (const char *) lo_apkentry(aOFileName.getStr(), &size);
      93             :         if (contents != 0) {
      94             :             aContent = std::string(contents, size);
      95             :             return;
      96             :         }
      97             :     }
      98             : #endif
      99             : 
     100         168 :     std::ifstream aFile(aOFileName.getStr());
     101             : 
     102         168 :     OStringBuffer aErrorMsg("Could not open csv file: ");
     103          84 :     aErrorMsg.append(aOFileName);
     104          84 :     CPPUNIT_ASSERT_MESSAGE(aErrorMsg.getStr(), aFile);
     105         168 :     std::ostringstream aOStream;
     106          84 :     aOStream << aFile.rdbuf();
     107          84 :     aFile.close();
     108         168 :     aContent = aOStream.str();
     109          84 : }
     110             : 
     111             : #if ENABLE_ORCUS
     112             : 
     113          70 : void testFile(OUString& aFileName, ScDocument& rDoc, SCTAB nTab, StringType aStringFormat)
     114             : {
     115          70 :     csv_handler aHandler(&rDoc, nTab, aStringFormat);
     116          70 :     orcus::csv::parser_config aConfig;
     117          70 :     aConfig.delimiters.push_back(',');
     118          70 :     aConfig.delimiters.push_back(';');
     119          70 :     aConfig.text_qualifier = '"';
     120          70 :     aConfig.trim_cell_value = false;
     121             : 
     122         140 :     std::string aContent;
     123          70 :     loadFile(aFileName, aContent);
     124         140 :     orcus::csv_parser<csv_handler> parser ( &aContent[0], aContent.size() , aHandler, aConfig);
     125             :     try
     126             :     {
     127          70 :         parser.parse();
     128             :     }
     129           0 :     catch (const orcus::csv::parse_error& e)
     130             :     {
     131           0 :         std::cout << "reading csv content file failed: " << e.what() << std::endl;
     132           0 :         OStringBuffer aErrorMsg("csv parser error: ");
     133           0 :         aErrorMsg.append(e.what());
     134           0 :         CPPUNIT_ASSERT_MESSAGE(aErrorMsg.getStr(), false);
     135          70 :     }
     136          70 : }
     137             : 
     138          14 : void testCondFile(OUString& aFileName, ScDocument* pDoc, SCTAB nTab)
     139             : {
     140          14 :     conditional_format_handler aHandler(pDoc, nTab);
     141          14 :     orcus::csv::parser_config aConfig;
     142          14 :     aConfig.delimiters.push_back(',');
     143          14 :     aConfig.delimiters.push_back(';');
     144          14 :     aConfig.text_qualifier = '"';
     145          28 :     std::string aContent;
     146          14 :     loadFile(aFileName, aContent);
     147          28 :     orcus::csv_parser<conditional_format_handler> parser ( &aContent[0], aContent.size() , aHandler, aConfig);
     148             :     try
     149             :     {
     150          14 :         parser.parse();
     151             :     }
     152           0 :     catch (const orcus::csv::parse_error& e)
     153             :     {
     154           0 :         std::cout << "reading csv content file failed: " << e.what() << std::endl;
     155           0 :         OStringBuffer aErrorMsg("csv parser error: ");
     156           0 :         aErrorMsg.append(e.what());
     157           0 :         CPPUNIT_ASSERT_MESSAGE(aErrorMsg.getStr(), false);
     158          14 :     }
     159          14 : }
     160             : 
     161             : #else
     162             : 
     163             : void testFile(OUString&, ScDocument&, SCTAB, StringType) {}
     164             : void testCondFile(OUString&, ScDocument*, SCTAB) {}
     165             : 
     166             : #endif
     167             : 
     168           4 : void testFormats(ScBootstrapFixture* pTest, ScDocument* pDoc, sal_Int32 nFormat)
     169             : {
     170             :     //test Sheet1 with csv file
     171           4 :     OUString aCSVFileName;
     172           4 :     pTest->createCSVPath(OUString("numberFormat."), aCSVFileName);
     173           4 :     testFile(aCSVFileName, *pDoc, 0, PureString);
     174             :     //need to test the color of B3
     175             :     //it's not a font color!
     176             :     //formatting for B5: # ??/100 gets lost during import
     177             : 
     178             :     //test Sheet2
     179           4 :     const ScPatternAttr* pPattern = NULL;
     180           4 :     pPattern = pDoc->GetPattern(0,0,1);
     181           8 :     vcl::Font aFont;
     182           4 :     pPattern->GetFont(aFont,SC_AUTOCOL_RAW);
     183           4 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("font size should be 10", 200l, aFont.GetSize().getHeight());
     184           4 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("font color should be black", COL_AUTO, aFont.GetColor().GetColor());
     185           4 :     pPattern = pDoc->GetPattern(0,1,1);
     186           4 :     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     187           4 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("font size should be 12", 240l, aFont.GetSize().getHeight());
     188           4 :     pPattern = pDoc->GetPattern(0,2,1);
     189           4 :     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     190           4 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be italic", ITALIC_NORMAL, aFont.GetItalic());
     191           4 :     pPattern = pDoc->GetPattern(0,4,1);
     192           4 :     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     193           4 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be bold", WEIGHT_BOLD, aFont.GetWeight());
     194           4 :     pPattern = pDoc->GetPattern(1,0,1);
     195           4 :     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     196           4 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be blue", COL_BLUE, aFont.GetColor().GetColor());
     197           4 :     pPattern = pDoc->GetPattern(1,1,1);
     198           4 :     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     199           4 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be striked out with a single line", STRIKEOUT_SINGLE, aFont.GetStrikeout());
     200             :     //some tests on sheet2 only for ods
     201           4 :     if (nFormat == ODS)
     202             :     {
     203           4 :         pPattern = pDoc->GetPattern(1,2,1);
     204           4 :         pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     205           4 :         CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be striked out with a double line", STRIKEOUT_DOUBLE, aFont.GetStrikeout());
     206           4 :         pPattern = pDoc->GetPattern(1,3,1);
     207           4 :         pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     208           4 :         CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be underlined with a dotted line", UNDERLINE_DOTTED, aFont.GetUnderline());
     209             :         //check row height import
     210             :         //disable for now until we figure out cause of win tinderboxes test failures
     211             :         //CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(256), pDoc->GetRowHeight(0,1) ); //0.178in
     212             :         //CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(304), pDoc->GetRowHeight(1,1) ); //0.211in
     213             :         //CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(477), pDoc->GetRowHeight(5,1) ); //0.3311in
     214             :         //check column width import
     215           4 :         CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(555), pDoc->GetColWidth(4,1) );  //0.3854in
     216           4 :         CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(1280), pDoc->GetColWidth(5,1) ); //0.889in
     217           4 :         CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(4153), pDoc->GetColWidth(6,1) ); //2.8839in
     218             :         //test case for i53253 where a cell has text with different styles and space between the text.
     219           4 :         OUString aTestStr = pDoc->GetString(3,0,1);
     220           8 :         OUString aKnownGoodStr("text14 space");
     221           4 :         CPPUNIT_ASSERT_EQUAL( aKnownGoodStr, aTestStr );
     222             :         //test case for cell text with line breaks.
     223           4 :         aTestStr = pDoc->GetString(3,5,1);
     224           4 :         aKnownGoodStr = "Hello,\nCalc!";
     225           8 :         CPPUNIT_ASSERT_EQUAL( aKnownGoodStr, aTestStr );
     226             :     }
     227           4 :     pPattern = pDoc->GetPattern(1,4,1);
     228           4 :     Color aColor = static_cast<const SvxBrushItem&>(pPattern->GetItem(ATTR_BACKGROUND)).GetColor();
     229           4 :     CPPUNIT_ASSERT_MESSAGE("background color should be green", aColor == COL_LIGHTGREEN);
     230           4 :     pPattern = pDoc->GetPattern(2,0,1);
     231           4 :     SvxCellHorJustify eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
     232           4 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
     233             :     //test alignment
     234           4 :     pPattern = pDoc->GetPattern(2,1,1);
     235           4 :     eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
     236           4 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned right horizontally", SVX_HOR_JUSTIFY_RIGHT, eHorJustify);
     237           4 :     pPattern = pDoc->GetPattern(2,2,1);
     238           4 :     eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
     239           4 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned block horizontally", SVX_HOR_JUSTIFY_BLOCK, eHorJustify);
     240             : 
     241             :     //test Sheet3 only for ods and xlsx
     242           4 :     if ( nFormat == ODS || nFormat == XLSX )
     243             :     {
     244           4 :         pTest->createCSVPath(OUString("conditionalFormatting."), aCSVFileName);
     245           4 :         testCondFile(aCSVFileName, pDoc, 2);
     246             :         // test parent cell style import ( fdo#55198 )
     247           4 :         if ( nFormat == XLSX )
     248             :         {
     249           0 :             pPattern = pDoc->GetPattern(1,1,3);
     250           0 :             ScStyleSheet* pStyleSheet = (ScStyleSheet*)pPattern->GetStyleSheet();
     251             :             // check parent style name
     252           0 :             OUString sExpected("Excel Built-in Date");
     253           0 :             OUString sResult = pStyleSheet->GetName();
     254           0 :             CPPUNIT_ASSERT_EQUAL_MESSAGE("parent style for Sheet4.B2 is 'Excel Built-in Date'", sExpected, sResult);
     255             :             // check  align of style
     256           0 :             SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
     257           0 :             eHorJustify = static_cast<SvxCellHorJustify>(static_cast< const SvxHorJustifyItem& >(rItemSet.Get( ATTR_HOR_JUSTIFY ) ).GetValue() );
     258           0 :             CPPUNIT_ASSERT_EQUAL_MESSAGE("'Excel Built-in Date' style should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
     259             :             // check date format ( should be just month e.g. 29 )
     260           0 :             sResult =pDoc->GetString( 1,1,3 );
     261           0 :             sExpected = "29";
     262           0 :             CPPUNIT_ASSERT_EQUAL_MESSAGE("'Excel Built-in Date' style should just display month", sExpected, sResult );
     263             : 
     264             :             // check actual align applied to cell, should be the same as
     265             :             // the style
     266           0 :             eHorJustify = static_cast<SvxCellHorJustify>(static_cast< const SvxHorJustifyItem& >(pPattern->GetItem( ATTR_HOR_JUSTIFY ) ).GetValue() );
     267           0 :             CPPUNIT_ASSERT_EQUAL_MESSAGE("cell with 'Excel Built-in Date' style should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
     268             :         }
     269             :     }
     270             : 
     271           4 :     ScConditionalFormat* pCondFormat = pDoc->GetCondFormat(0,0,2);
     272           4 :     const ScRangeList& rRange = pCondFormat->GetRange();
     273           4 :     CPPUNIT_ASSERT(rRange == ScRange(0,0,2,3,0,2));
     274             : 
     275           4 :     pCondFormat = pDoc->GetCondFormat(0,1,2);
     276           4 :     const ScRangeList& rRange2 = pCondFormat->GetRange();
     277           4 :     CPPUNIT_ASSERT(rRange2 == ScRange(0,1,2,0,1,2));
     278             : 
     279           4 :     pCondFormat = pDoc->GetCondFormat(1,1,2);
     280           4 :     const ScRangeList& rRange3 = pCondFormat->GetRange();
     281           8 :     CPPUNIT_ASSERT(rRange3 == ScRange(1,1,2,3,1,2));
     282           4 : }
     283             : 
     284           4 : const SdrOle2Obj* getSingleChartObject(ScDocument& rDoc, sal_uInt16 nPage)
     285             : {
     286             :     // Retrieve the chart object instance from the 2nd page (for the 2nd sheet).
     287           4 :     ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
     288           4 :     if (!pDrawLayer)
     289             :     {
     290           0 :         cout << "Failed to retrieve the drawing layer object." << endl;
     291           0 :         return NULL;
     292             :     }
     293             : 
     294           4 :     const SdrPage* pPage = pDrawLayer->GetPage(nPage);
     295           4 :     if (!pPage)
     296             :     {
     297           0 :         cout << "Failed to retrieve the page object." << endl;
     298           0 :         return NULL;
     299             :     }
     300             : 
     301           4 :     if (pPage->GetObjCount() != 1)
     302             :     {
     303           0 :         cout << "This page should contain one drawing object." << endl;
     304           0 :         return NULL;
     305             :     }
     306             : 
     307           4 :     const SdrObject* pObj = pPage->GetObj(0);
     308           4 :     if (!pObj)
     309             :     {
     310           0 :         cout << "Failed to retrieve the drawing object." << endl;
     311           0 :         return NULL;
     312             :     }
     313             : 
     314           4 :     if (pObj->GetObjIdentifier() != OBJ_OLE2)
     315             :     {
     316           0 :         cout << "This is not an OLE2 object." << endl;
     317           0 :         return NULL;
     318             :     }
     319             : 
     320           4 :     const SdrOle2Obj& rOleObj = static_cast<const SdrOle2Obj&>(*pObj);
     321           4 :     if (!rOleObj.IsChart())
     322             :     {
     323           0 :         cout << "This should be a chart object." << endl;
     324           0 :         return NULL;
     325             :     }
     326             : 
     327           4 :     return &rOleObj;
     328             : }
     329             : 
     330           4 : std::vector<OUString> getChartRangeRepresentations(const SdrOle2Obj& rChartObj)
     331             : {
     332           4 :     std::vector<OUString> aRangeReps;
     333             : 
     334             :     // Make sure the chart object has correct range references.
     335           8 :     Reference<frame::XModel> xModel = rChartObj.getXModel();
     336           4 :     if (!xModel.is())
     337             :     {
     338           0 :         cout << "Failed to get the embedded object interface." << endl;
     339           0 :         return aRangeReps;
     340             :     }
     341             : 
     342           8 :     Reference<chart2::XChartDocument> xChartDoc(xModel, UNO_QUERY);
     343           4 :     if (!xChartDoc.is())
     344             :     {
     345           0 :         cout << "Failed to get the chart document interface." << endl;
     346           0 :         return aRangeReps;
     347             :     }
     348             : 
     349           8 :     Reference<chart2::data::XDataSource> xDataSource(xChartDoc, UNO_QUERY);
     350           4 :     if (!xDataSource.is())
     351             :     {
     352           0 :         cout << "Failed to get the data source interface." << endl;
     353           0 :         return aRangeReps;
     354             :     }
     355             : 
     356           8 :     Sequence<Reference<chart2::data::XLabeledDataSequence> > xDataSeqs = xDataSource->getDataSequences();
     357           4 :     if (!xDataSeqs.getLength())
     358             :     {
     359           0 :         cout << "There should be at least one data sequences." << endl;
     360           0 :         return aRangeReps;
     361             :     }
     362             : 
     363           8 :     Reference<chart2::data::XDataReceiver> xDataRec(xChartDoc, UNO_QUERY);
     364           4 :     if (!xDataRec.is())
     365             :     {
     366           0 :         cout << "Failed to get the data receiver interface." << endl;
     367           0 :         return aRangeReps;
     368             :     }
     369             : 
     370           8 :     Sequence<OUString> aRangeRepSeqs = xDataRec->getUsedRangeRepresentations();
     371          16 :     for (sal_Int32 i = 0, n = aRangeRepSeqs.getLength(); i < n; ++i)
     372          12 :         aRangeReps.push_back(aRangeRepSeqs[i]);
     373             : 
     374           4 :     return aRangeReps;
     375             : }
     376             : 
     377           4 : ScRangeList getChartRanges(ScDocument& rDoc, const SdrOle2Obj& rChartObj)
     378             : {
     379           4 :     std::vector<OUString> aRangeReps = getChartRangeRepresentations(rChartObj);
     380           4 :     ScRangeList aRanges;
     381          16 :     for (size_t i = 0, n = aRangeReps.size(); i < n; ++i)
     382             :     {
     383          12 :         ScRange aRange;
     384          12 :         sal_uInt16 nRes = aRange.Parse(aRangeReps[i], &rDoc, rDoc.GetAddressConvention());
     385          12 :         if (nRes & SCA_VALID)
     386             :             // This is a range address.
     387           8 :             aRanges.Append(aRange);
     388             :         else
     389             :         {
     390             :             // Parse it as a single cell address.
     391           4 :             ScAddress aAddr;
     392           4 :             nRes = aAddr.Parse(aRangeReps[i], &rDoc, rDoc.GetAddressConvention());
     393           4 :             CPPUNIT_ASSERT_MESSAGE("Failed to parse a range representation.", (nRes & SCA_VALID));
     394           4 :             aRanges.Append(aAddr);
     395             :         }
     396             :     }
     397             : 
     398           4 :     return aRanges;
     399             : }
     400             : 
     401             : namespace {
     402             : 
     403         758 : ScTokenArray* getTokens(ScDocument& rDoc, const ScAddress& rPos)
     404             : {
     405         758 :     ScFormulaCell* pCell = rDoc.GetFormulaCell(rPos);
     406         758 :     if (!pCell)
     407             :     {
     408           0 :         OUString aStr = rPos.Format(SCA_VALID);
     409           0 :         cerr << aStr << " is not a formula cell." << endl;
     410           0 :         return NULL;
     411             :     }
     412             : 
     413         758 :     return pCell->GetCode();
     414             : }
     415             : 
     416             : }
     417             : 
     418         758 : bool checkFormula(ScDocument& rDoc, const ScAddress& rPos, const char* pExpected)
     419             : {
     420         758 :     ScTokenArray* pCode = getTokens(rDoc, rPos);
     421         758 :     if (!pCode)
     422             :     {
     423           0 :         cerr << "Empty token array." << endl;
     424           0 :         return false;
     425             :     }
     426             : 
     427         758 :     OUString aFormula = toString(rDoc, rPos, *pCode, rDoc.GetGrammar());
     428         758 :     if (aFormula != OUString::createFromAscii(pExpected))
     429             :     {
     430           0 :         cerr << "Formula '" << pExpected << "' expected, but '" << aFormula << "' found" << endl;
     431           0 :         return false;
     432             :     }
     433             : 
     434         758 :     return true;
     435             : }
     436             : 
     437          12 : bool checkFormulaPosition(ScDocument& rDoc, const ScAddress& rPos)
     438             : {
     439          12 :     OUString aStr(rPos.Format(SCA_VALID));
     440          12 :     const ScFormulaCell* pFC = rDoc.GetFormulaCell(rPos);
     441          12 :     if (!pFC)
     442             :     {
     443           0 :         cerr << "Formula cell expected at " << aStr << " but not found." << endl;
     444           0 :         return false;
     445             :     }
     446             : 
     447          12 :     if (pFC->aPos != rPos)
     448             :     {
     449           0 :         OUString aStr2(pFC->aPos.Format(SCA_VALID));
     450           0 :         cerr << "Formula cell at " << aStr << " has incorrect position of " << aStr2 << endl;
     451           0 :         return false;
     452             :     }
     453             : 
     454          12 :     return true;
     455             : }
     456             : 
     457           4 : bool checkFormulaPositions(
     458             :     ScDocument& rDoc, SCTAB nTab, SCCOL nCol, const SCROW* pRows, size_t nRowCount)
     459             : {
     460           4 :     ScAddress aPos(nCol, 0, nTab);
     461          16 :     for (size_t i = 0; i < nRowCount; ++i)
     462             :     {
     463          12 :         SCROW nRow = pRows[i];
     464          12 :         aPos.SetRow(nRow);
     465             : 
     466          12 :         if (!checkFormulaPosition(rDoc, aPos))
     467             :         {
     468           0 :             OUString aStr(aPos.Format(SCA_VALID));
     469           0 :             cerr << "Formula cell position failed at " << aStr << "." << endl;
     470           0 :             return false;
     471             :         }
     472             :     }
     473           4 :     return true;
     474             : }
     475             : 
     476          10 : ScTokenArray* compileFormula(
     477             :     ScDocument* pDoc, const OUString& rFormula, const ScAddress* pPos,
     478             :     formula::FormulaGrammar::Grammar eGram )
     479             : {
     480          10 :     ScAddress aPos(0,0,0);
     481          10 :     if (pPos)
     482           0 :         aPos = *pPos;
     483          10 :     ScCompiler aComp(pDoc, aPos);
     484          10 :     aComp.SetGrammar(eGram);
     485          10 :     return aComp.CompileString(rFormula);
     486             : }
     487             : 
     488           0 : void clearFormulaCellChangedFlag( ScDocument& rDoc, const ScRange& rRange )
     489             : {
     490           0 :     const ScAddress& s = rRange.aStart;
     491           0 :     const ScAddress& e = rRange.aEnd;
     492           0 :     for (SCTAB nTab = s.Tab(); nTab <= e.Tab(); ++nTab)
     493             :     {
     494           0 :         for (SCCOL nCol = s.Col(); nCol <= e.Col(); ++nCol)
     495             :         {
     496           0 :             for (SCROW nRow = s.Row(); nRow <= e.Row(); ++nRow)
     497             :             {
     498           0 :                 ScAddress aPos(nCol, nRow, nTab);
     499           0 :                 ScFormulaCell* pFC = rDoc.GetFormulaCell(aPos);
     500           0 :                 if (pFC)
     501           0 :                     pFC->SetChanged(false);
     502             :             }
     503             :         }
     504             :     }
     505           0 : }
     506             : 
     507         456 : bool isFormulaWithoutError(ScDocument& rDoc, const ScAddress& rPos)
     508             : {
     509         456 :     ScFormulaCell* pFC = rDoc.GetFormulaCell(rPos);
     510         456 :     if (!pFC)
     511           0 :         return false;
     512             : 
     513         456 :     return pFC->GetErrCode() == 0;
     514             : }
     515             : 
     516         766 : OUString toString(
     517             :     ScDocument& rDoc, const ScAddress& rPos, ScTokenArray& rArray, formula::FormulaGrammar::Grammar eGram)
     518             : {
     519         766 :     ScCompiler aComp(&rDoc, rPos, rArray);
     520         766 :     aComp.SetGrammar(eGram);
     521        1532 :     OUStringBuffer aBuf;
     522         766 :     aComp.CreateStringFromTokenArray(aBuf);
     523        1532 :     return aBuf.makeStringAndClear();
     524             : }
     525             : 
     526         374 : ScDocShellRef ScBootstrapFixture::load( bool bReadWrite,
     527             :     const OUString& rURL, const OUString& rFilter, const OUString &rUserData,
     528             :     const OUString& rTypeName, unsigned int nFilterFlags, unsigned int nClipboardID,
     529             :     sal_uIntPtr nFilterVersion, const OUString* pPassword )
     530             : {
     531             :     SfxFilter* pFilter = new SfxFilter(
     532             :         rFilter,
     533             :         OUString(), nFilterFlags, nClipboardID, rTypeName, 0, OUString(),
     534         374 :         rUserData, OUString("private:factory/scalc*"));
     535         374 :     pFilter->SetVersion(nFilterVersion);
     536             : 
     537         374 :     ScDocShellRef xDocShRef = new ScDocShell;
     538         374 :     xDocShRef->GetDocument().EnableUserInteraction(false);
     539         374 :     SfxMedium* pSrcMed = new SfxMedium(rURL, bReadWrite ? STREAM_STD_READWRITE : STREAM_STD_READ );
     540         374 :     pSrcMed->SetFilter(pFilter);
     541         374 :     pSrcMed->UseInteractionHandler(false);
     542         374 :     if (pPassword)
     543             :     {
     544           2 :         SfxItemSet* pSet = pSrcMed->GetItemSet();
     545           2 :         pSet->Put(SfxStringItem(SID_PASSWORD, *pPassword));
     546             :     }
     547             :     SAL_INFO( "sc.qa", "about to load " << rURL );
     548         374 :     if (!xDocShRef->DoLoad(pSrcMed))
     549             :     {
     550           8 :         xDocShRef->DoClose();
     551             :         // load failed.
     552           8 :         xDocShRef.Clear();
     553             :     }
     554             : 
     555         374 :     return xDocShRef;
     556             : }
     557             : 
     558         136 : ScDocShellRef ScBootstrapFixture::load(
     559             :     const OUString& rURL, const OUString& rFilter, const OUString &rUserData,
     560             :     const OUString& rTypeName, unsigned int nFilterFlags, unsigned int nClipboardID,
     561             :     sal_uIntPtr nFilterVersion, const OUString* pPassword )
     562             : {
     563         136 :     return load( false, rURL, rFilter, rUserData, rTypeName, nFilterFlags, nClipboardID,  nFilterVersion, pPassword );
     564             : }
     565             : 
     566         238 : ScDocShellRef ScBootstrapFixture::loadDoc(
     567             :     const OUString& rFileName, sal_Int32 nFormat, bool bReadWrite )
     568             : {
     569         238 :     OUString aFileExtension(aFileFormats[nFormat].pName, strlen(aFileFormats[nFormat].pName), RTL_TEXTENCODING_UTF8 );
     570         476 :     OUString aFilterName(aFileFormats[nFormat].pFilterName, strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
     571         476 :     OUString aFileName;
     572         238 :     createFileURL( rFileName, aFileExtension, aFileName );
     573         476 :     OUString aFilterType(aFileFormats[nFormat].pTypeName, strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
     574         238 :     unsigned int nFormatType = aFileFormats[nFormat].nFormatType;
     575         238 :     unsigned int nClipboardId = nFormatType ? SFX_FILTER_IMPORT | SFX_FILTER_USESOPTIONS : 0;
     576             : 
     577         476 :     return load(bReadWrite, aFileName, aFilterName, OUString(), aFilterType, nFormatType, nClipboardId, nFormatType);
     578             : }
     579             : 
     580          84 : const FileFormat* ScBootstrapFixture::getFileFormats()
     581             : {
     582          84 :     return aFileFormats;
     583             : }
     584             : 
     585         680 : ScBootstrapFixture::ScBootstrapFixture( const OUString& rsBaseString ) : m_aBaseString( rsBaseString ) {}
     586         680 : ScBootstrapFixture::~ScBootstrapFixture() {}
     587             : 
     588         248 : void ScBootstrapFixture::createFileURL(
     589             :     const OUString& aFileBase, const OUString& aFileExtension, OUString& rFilePath)
     590             : {
     591         248 :     OUString aSep("/");
     592         496 :     OUStringBuffer aBuffer( getSrcRootURL() );
     593         248 :     aBuffer.append(m_aBaseString).append(aSep).append(aFileExtension);
     594         248 :     aBuffer.append(aSep).append(aFileBase).append(aFileExtension);
     595         496 :     rFilePath = aBuffer.makeStringAndClear();
     596         248 : }
     597             : 
     598          84 : void ScBootstrapFixture::createCSVPath(const OUString& aFileBase, OUString& rCSVPath)
     599             : {
     600          84 :     OUStringBuffer aBuffer( getSrcRootPath());
     601          84 :     aBuffer.append(m_aBaseString).append("/contentCSV/");
     602          84 :     aBuffer.append(aFileBase).append("csv");
     603          84 :     rCSVPath = aBuffer.makeStringAndClear();
     604          84 : }
     605             : 
     606          80 : ScDocShellRef ScBootstrapFixture::saveAndReload(
     607             :     ScDocShell* pShell, const OUString &rFilter,
     608             :     const OUString &rUserData, const OUString& rTypeName, sal_uLong nFormatType)
     609             : {
     610             : 
     611          80 :     utl::TempFile aTempFile;
     612         160 :     SfxMedium aStoreMedium( aTempFile.GetURL(), STREAM_STD_WRITE );
     613          80 :     sal_uInt32 nExportFormat = 0;
     614          80 :     if (nFormatType == ODS_FORMAT_TYPE)
     615          30 :         nExportFormat = SFX_FILTER_EXPORT | SFX_FILTER_USESOPTIONS;
     616             :     SfxFilter* pExportFilter = new SfxFilter(
     617             :         rFilter,
     618             :         OUString(), nFormatType, nExportFormat, rTypeName, 0, OUString(),
     619          80 :         rUserData, OUString("private:factory/scalc*") );
     620          80 :     pExportFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
     621          80 :     aStoreMedium.SetFilter(pExportFilter);
     622          80 :     pShell->DoSaveAs( aStoreMedium );
     623          80 :     pShell->DoClose();
     624             : 
     625             :     //std::cout << "File: " << aTempFile.GetURL() << std::endl;
     626             : 
     627          80 :     sal_uInt32 nFormat = 0;
     628          80 :     if (nFormatType == ODS_FORMAT_TYPE)
     629          30 :         nFormat = SFX_FILTER_IMPORT | SFX_FILTER_USESOPTIONS;
     630             : 
     631          80 :     ScDocShellRef xDocSh = load(aTempFile.GetURL(), rFilter, rUserData, rTypeName, nFormatType, nFormat );
     632          80 :     if(nFormatType == XLSX_FORMAT_TYPE)
     633          28 :         validate(aTempFile.GetFileName(), test::OOXML);
     634          52 :     else if (nFormatType == ODS_FORMAT_TYPE)
     635          30 :         validate(aTempFile.GetFileName(), test::ODF);
     636          80 :     aTempFile.EnableKillingFile();
     637         160 :     return xDocSh;
     638             : }
     639             : 
     640          80 : ScDocShellRef ScBootstrapFixture::saveAndReload( ScDocShell* pShell, sal_Int32 nFormat )
     641             : {
     642          80 :     OUString aFilterName(aFileFormats[nFormat].pFilterName, strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
     643         160 :     OUString aFilterType(aFileFormats[nFormat].pTypeName, strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
     644          80 :     ScDocShellRef xDocSh = saveAndReload(pShell, aFilterName, OUString(), aFilterType, aFileFormats[nFormat].nFormatType);
     645             : 
     646          80 :     CPPUNIT_ASSERT(xDocSh.Is());
     647         160 :     return xDocSh;
     648             : }
     649             : 
     650           2 : boost::shared_ptr<utl::TempFile> ScBootstrapFixture::exportTo( ScDocShell* pShell, sal_Int32 nFormat )
     651             : {
     652           2 :     OUString aFilterName(aFileFormats[nFormat].pFilterName, strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
     653           4 :     OUString aFilterType(aFileFormats[nFormat].pTypeName, strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
     654             : 
     655           2 :     boost::shared_ptr<utl::TempFile> pTempFile(new utl::TempFile());
     656           2 :     pTempFile->EnableKillingFile();
     657           4 :     SfxMedium aStoreMedium( pTempFile->GetURL(), STREAM_STD_WRITE );
     658           2 :     sal_uInt32 nExportFormat = 0;
     659           2 :     sal_Int32 nFormatType = aFileFormats[nFormat].nFormatType;
     660           2 :     if (nFormatType == ODS_FORMAT_TYPE)
     661           2 :         nExportFormat = SFX_FILTER_EXPORT | SFX_FILTER_USESOPTIONS;
     662             :     SfxFilter* pExportFilter = new SfxFilter(
     663             :         aFilterName,
     664             :         OUString(), nFormatType, nExportFormat, aFilterType, 0, OUString(),
     665           2 :         OUString(), OUString("private:factory/scalc*") );
     666           2 :     pExportFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
     667           2 :     aStoreMedium.SetFilter(pExportFilter);
     668           2 :     pShell->DoSaveAs( aStoreMedium );
     669           2 :     pShell->DoClose();
     670             : 
     671           2 :     if(nFormatType == XLSX_FORMAT_TYPE)
     672           0 :         validate(pTempFile->GetFileName(), test::OOXML);
     673           2 :     else if (nFormatType == ODS_FORMAT_TYPE)
     674           2 :         validate(pTempFile->GetFileName(), test::ODF);
     675             : 
     676           4 :     return pTempFile;
     677             : }
     678             : 
     679           4 : void ScBootstrapFixture::miscRowHeightsTest( TestParam* aTestValues, unsigned int numElems )
     680             : {
     681          16 :     for ( unsigned int index=0; index<numElems; ++index )
     682             :     {
     683          12 :         OUString sFileName = OUString::createFromAscii( aTestValues[ index ].sTestDoc );
     684             :         SAL_INFO( "sc.qa", "aTestValues[" << index << "] " << sFileName );
     685          12 :         int nImportType =  aTestValues[ index ].nImportType;
     686          12 :         int nExportType =  aTestValues[ index ].nExportType;
     687          24 :         ScDocShellRef xShell = loadDoc( sFileName, nImportType );
     688          12 :         CPPUNIT_ASSERT(xShell.Is());
     689             : 
     690          12 :         if ( nExportType != -1 )
     691           8 :             xShell = saveAndReload(&(*xShell), nExportType );
     692             : 
     693          12 :         CPPUNIT_ASSERT(xShell.Is());
     694             : 
     695          12 :         ScDocument& rDoc = xShell->GetDocument();
     696             : 
     697          48 :         for (int i=0; i<aTestValues[ index ].nRowData; ++i)
     698             :         {
     699          36 :             SCROW nRow = aTestValues[ index ].pData[ i].nStartRow;
     700          36 :             SCROW nEndRow = aTestValues[ index ].pData[ i ].nEndRow;
     701          36 :             SCTAB nTab = aTestValues[ index ].pData[ i ].nTab;
     702          36 :             int nExpectedHeight = aTestValues[ index ].pData[ i ].nExpectedHeight;
     703          36 :             if ( nExpectedHeight == -1 )
     704           4 :                 nExpectedHeight =  sc::TwipsToHMM( ScGlobal::GetStandardRowHeight() );
     705          36 :             bool bCheckOpt = ( ( aTestValues[ index ].pData[ i ].nCheck & CHECK_OPTIMAL ) == CHECK_OPTIMAL );
     706         184 :             for ( ; nRow <= nEndRow; ++nRow )
     707             :             {
     708             :                 SAL_INFO( "sc.qa", " checking row " << nRow << " for height " << nExpectedHeight );
     709         148 :                 int nHeight = sc::TwipsToHMM( rDoc.GetRowHeight(nRow, nTab, false) );
     710         148 :                 if ( bCheckOpt )
     711             :                 {
     712           4 :                     bool bOpt = !(rDoc.GetRowFlags( nRow, nTab ) & CR_MANUALSIZE);
     713           4 :                     CPPUNIT_ASSERT_EQUAL(aTestValues[ index ].pData[ i ].bOptimal, bOpt);
     714             :                 }
     715         148 :                 CPPUNIT_ASSERT_EQUAL(nExpectedHeight, nHeight);
     716             :             }
     717             :         }
     718          12 :         xShell->DoClose();
     719          12 :     }
     720          46 : }
     721             : 
     722             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10