File indexing completed on 2023-09-24 07:54:05
0001 /*************************************************************************** 0002 File : ProjectImportTest.cpp 0003 Project : LabPlot 0004 Description : Tests for project imports 0005 -------------------------------------------------------------------- 0006 Copyright : (C) 2018 Alexander Semke (alexander.semke@web.de) 0007 ***************************************************************************/ 0008 0009 /*************************************************************************** 0010 * * 0011 * This program is free software; you can redistribute it and/or modify * 0012 * it under the terms of the GNU General Public License as published by * 0013 * the Free Software Foundation; either version 2 of the License, or * 0014 * (at your option) any later version. * 0015 * * 0016 * This program is distributed in the hope that it will be useful, * 0017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0019 * GNU General Public License for more details. * 0020 * * 0021 * You should have received a copy of the GNU General Public License * 0022 * along with this program; if not, write to the Free Software * 0023 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0024 * Boston, MA 02110-1301 USA * 0025 * * 0026 ***************************************************************************/ 0027 0028 #include "ProjectImportTest.h" 0029 #ifdef HAVE_LIBORIGIN 0030 #include "backend/datasources/projects/OriginProjectParser.h" 0031 #endif 0032 #include "backend/core/Project.h" 0033 #include "backend/core/Workbook.h" 0034 #include "backend/matrix/Matrix.h" 0035 #include "backend/worksheet/Worksheet.h" 0036 #include "backend/worksheet/plots/cartesian/CartesianPlot.h" 0037 #include "backend/spreadsheet/Spreadsheet.h" 0038 0039 void ProjectImportTest::initTestCase() { 0040 // needed in order to have the signals triggered by SignallingUndoCommand, see LabPlot.cpp 0041 //TODO: redesign/remove this 0042 qRegisterMetaType<const AbstractAspect*>("const AbstractAspect*"); 0043 qRegisterMetaType<const AbstractColumn*>("const AbstractColumn*"); 0044 } 0045 0046 //############################################################################## 0047 //##################### import of LabPlot projects ############################ 0048 //############################################################################## 0049 0050 0051 #ifdef HAVE_LIBORIGIN 0052 //############################################################################## 0053 //###################### import of Origin projects ############################ 0054 //############################################################################## 0055 //project tree of the file "origin8_test_tree_import.opj" 0056 /* 0057 test_tree_import\ 0058 \Book3 0059 \Folder 0060 \Book2 0061 \Sheet1 0062 \Sheet2 0063 \MBook2 0064 \MSheet1 0065 \MSheet2 0066 \Folder1 0067 \MBook1 0068 \Sheet1 0069 \Book1 0070 \Sheet1 0071 \Book4 0072 \MSheet1 0073 \Graph2 0074 \Excel1 0075 */ 0076 0077 void ProjectImportTest::testOrigin01() { 0078 0079 //import the opj file into LabPlot's project object 0080 OriginProjectParser parser; 0081 parser.setProjectFileName(QFINDTESTDATA(QLatin1String("data/origin8_test_tree_import.opj"))); 0082 Project project; 0083 parser.importTo(&project, QStringList()); 0084 0085 //check the project tree for the imported project 0086 0087 //first child of the root folder, spreadsheet "Book3" 0088 auto* aspect = project.child<AbstractAspect>(0); 0089 QCOMPARE(aspect != nullptr, true); 0090 if (aspect != nullptr) 0091 QCOMPARE(aspect->name(), QLatin1String("Book3")); 0092 QCOMPARE(dynamic_cast<Spreadsheet*>(aspect) != nullptr, true); 0093 0094 0095 //first child of the root folder, folder "Folder" -> import into a Folder 0096 aspect = project.child<AbstractAspect>(1); 0097 QCOMPARE(aspect != nullptr, true); 0098 if (aspect != nullptr) 0099 QCOMPARE(aspect->name(), QLatin1String("Folder")); 0100 QCOMPARE(dynamic_cast<Folder*>(aspect) != nullptr, true); 0101 0102 //first child of "Folder", workbook "Book2" with two sheets -> import into a Workbook with two Spreadsheets 0103 aspect = project.child<AbstractAspect>(1)->child<AbstractAspect>(0); 0104 QCOMPARE(aspect != nullptr, true); 0105 if (aspect != nullptr) 0106 QCOMPARE(aspect->name(), QLatin1String("Book2")); 0107 QCOMPARE(dynamic_cast<Workbook*>(aspect) != nullptr, true); 0108 0109 aspect = project.child<AbstractAspect>(1)->child<AbstractAspect>(0)->child<AbstractAspect>(0); 0110 QCOMPARE(aspect != nullptr, true); 0111 if (aspect != nullptr) 0112 QCOMPARE(aspect->name(), QLatin1String("Sheet1")); 0113 QCOMPARE(dynamic_cast<Spreadsheet*>(aspect) != nullptr, true); 0114 0115 aspect = project.child<AbstractAspect>(1)->child<AbstractAspect>(0)->child<AbstractAspect>(1); 0116 QCOMPARE(aspect != nullptr, true); 0117 if (aspect != nullptr) 0118 QCOMPARE(aspect->name(), QLatin1String("Sheet2")); 0119 QCOMPARE(dynamic_cast<Spreadsheet*>(aspect) != nullptr, true); 0120 0121 //second child of "Folder", matrixbook "MBook" with two matrix sheets -> import into a Workbook with two Matrices 0122 aspect = project.child<AbstractAspect>(1)->child<AbstractAspect>(1); 0123 QCOMPARE(aspect != nullptr, true); 0124 if (aspect != nullptr) 0125 QCOMPARE(aspect->name(), QLatin1String("MBook2")); 0126 QCOMPARE(dynamic_cast<Workbook*>(aspect) != nullptr, true); 0127 0128 aspect = project.child<AbstractAspect>(1)->child<AbstractAspect>(1)->child<AbstractAspect>(0); 0129 QCOMPARE(aspect != nullptr, true); 0130 if (aspect != nullptr) 0131 QCOMPARE(aspect->name(), QLatin1String("MSheet1")); 0132 QCOMPARE(dynamic_cast<Matrix*>(aspect) != nullptr, true); 0133 0134 aspect = project.child<AbstractAspect>(1)->child<AbstractAspect>(1)->child<AbstractAspect>(1); 0135 QCOMPARE(aspect != nullptr, true); 0136 if (aspect != nullptr) 0137 QCOMPARE(aspect->name(), QLatin1String("MSheet2")); 0138 QCOMPARE(dynamic_cast<Matrix*>(aspect) != nullptr, true); 0139 0140 0141 //second child of the root folder, folder "Folder1" -> import into a Folder 0142 aspect = project.child<AbstractAspect>(2); 0143 QCOMPARE(aspect != nullptr, true); 0144 if (aspect != nullptr) 0145 QCOMPARE(aspect->name(), QLatin1String("Folder1")); 0146 QCOMPARE(dynamic_cast<Folder*>(aspect) != nullptr, true); 0147 0148 //first child of "Folder1", matrix "MBook1" 0149 aspect = project.child<AbstractAspect>(2)->child<AbstractAspect>(0); 0150 QCOMPARE(aspect != nullptr, true); 0151 if (aspect != nullptr) 0152 QCOMPARE(aspect->name(), QLatin1String("MBook1")); 0153 QCOMPARE(dynamic_cast<Matrix*>(aspect) != nullptr, true); 0154 0155 //second child of "Folder1", workbook "Book1" with on sheet -> import into a Spreadsheet 0156 aspect = project.child<AbstractAspect>(2)->child<AbstractAspect>(1); 0157 QCOMPARE(aspect != nullptr, true); 0158 if (aspect != nullptr) 0159 QCOMPARE(aspect->name(), QLatin1String("Book1")); 0160 QCOMPARE(dynamic_cast<Spreadsheet*>(aspect) != nullptr, true); 0161 0162 //second child of "Folder1", workbook "Book4" with on sheet -> import into a Spreadsheet 0163 aspect = project.child<AbstractAspect>(2)->child<AbstractAspect>(2); 0164 QCOMPARE(aspect != nullptr, true); 0165 if (aspect != nullptr) 0166 QCOMPARE(aspect->name(), QLatin1String("Book4")); 0167 QCOMPARE(dynamic_cast<Spreadsheet*>(aspect) != nullptr, true); 0168 0169 //third child of "Folder1", graph "Graph"-> import into a Worksheet 0170 aspect = project.child<AbstractAspect>(2)->child<AbstractAspect>(3); 0171 QCOMPARE(aspect != nullptr, true); 0172 if (aspect != nullptr) 0173 QCOMPARE(aspect->name(), QLatin1String("Graph2")); 0174 QCOMPARE(dynamic_cast<Worksheet*>(aspect) != nullptr, true); 0175 //TODO: check the created plot in the worksheet 0176 0177 // TODO: loose window: spreadsheet "Excel1" 0178 //aspect = project.child<AbstractAspect>(3); 0179 //QCOMPARE(aspect != nullptr, true); 0180 //QCOMPARE(aspect->name(), QLatin1String("Excel1")); 0181 //QCOMPARE(dynamic_cast<Spreadsheet*>(aspect) != nullptr, true); 0182 } 0183 0184 /* 0185 * import one single folder child 0186 */ 0187 void ProjectImportTest::testOrigin02() { 0188 //import one single object 0189 OriginProjectParser parser; 0190 parser.setProjectFileName(QFINDTESTDATA(QLatin1String("data/origin8_test_tree_import.opj"))); 0191 Project project; 0192 QStringList selectedPathes = {QLatin1String("test_tree_import/Folder1/Book1"), QLatin1String("test_tree_import/Folder1"), QLatin1String("test_tree_import")}; 0193 parser.importTo(&project, selectedPathes); 0194 0195 //check the project tree for the imported project 0196 0197 //first child of the root folder, folder "Folder1" -> import into a Folder 0198 auto* aspect = project.child<AbstractAspect>(0); 0199 QCOMPARE(aspect != nullptr, true); 0200 if (aspect != nullptr) 0201 QCOMPARE(aspect->name(), QLatin1String("Folder1")); 0202 QCOMPARE(dynamic_cast<Folder*>(aspect) != nullptr, true); 0203 if (aspect != nullptr) 0204 QCOMPARE(aspect->childCount<AbstractAspect>(), 1); 0205 0206 //first child of "Folder", workbook "Book" with one sheet -> import into a Spreadsheet 0207 aspect = project.child<AbstractAspect>(0)->child<AbstractAspect>(0); 0208 QCOMPARE(aspect != nullptr, true); 0209 if (aspect != nullptr) 0210 QCOMPARE(aspect->name(), QLatin1String("Book1")); 0211 QCOMPARE(dynamic_cast<Spreadsheet*>(aspect) != nullptr, true); 0212 } 0213 0214 /* 0215 * 1. import one single folder child 0216 * 2. import another folder child 0217 * 3. check that both children are available after the second import 0218 */ 0219 void ProjectImportTest::testOrigin03() { 0220 //import one single object 0221 OriginProjectParser parser; 0222 parser.setProjectFileName(QFINDTESTDATA(QLatin1String("data/origin8_test_tree_import.opj"))); 0223 Project project; 0224 0225 //import one single child in "Folder1" 0226 QStringList selectedPathes = {QLatin1String("test_tree_import/Folder1/Book1"), QLatin1String("test_tree_import/Folder1"), QLatin1String("test_tree_import")}; 0227 parser.importTo(&project, selectedPathes); 0228 0229 //first child of the root folder, folder "Folder1" -> import into a Folder 0230 auto* aspect = project.child<AbstractAspect>(0); 0231 QCOMPARE(aspect != nullptr, true); 0232 if (aspect != nullptr) 0233 QCOMPARE(aspect->name(), QLatin1String("Folder1")); 0234 QCOMPARE(dynamic_cast<Folder*>(aspect) != nullptr, true); 0235 if (aspect != nullptr) 0236 QCOMPARE(aspect->childCount<AbstractAspect>(), 1); 0237 0238 //first child of "Folder", workbook "Book1" with one sheet -> import into a Spreadsheet 0239 aspect = project.child<AbstractAspect>(0)->child<AbstractAspect>(0); 0240 QCOMPARE(aspect != nullptr, true); 0241 if (aspect != nullptr) 0242 QCOMPARE(aspect->name(), QLatin1String("Book1")); 0243 QCOMPARE(dynamic_cast<Spreadsheet*>(aspect) != nullptr, true); 0244 0245 0246 //import another child in "Folder1" 0247 selectedPathes.clear(); 0248 selectedPathes << QLatin1String("test_tree_import/Folder1/Book4") << QLatin1String("test_tree_import/Folder1") << QLatin1String("test_tree_import"); 0249 parser.importTo(&project, selectedPathes); 0250 0251 //the first child should still be available in the project -> check it 0252 aspect = project.child<AbstractAspect>(0); 0253 QCOMPARE(aspect != nullptr, true); 0254 if (aspect != nullptr) 0255 QCOMPARE(aspect->name(), QLatin1String("Folder1")); 0256 QCOMPARE(dynamic_cast<Folder*>(aspect) != nullptr, true); 0257 0258 aspect = project.child<AbstractAspect>(0)->child<AbstractAspect>(0); 0259 QCOMPARE(aspect != nullptr, true); 0260 if (aspect != nullptr) 0261 QCOMPARE(aspect->name(), QLatin1String("Book1")); 0262 QCOMPARE(dynamic_cast<Spreadsheet*>(aspect) != nullptr, true); 0263 0264 //check the second child, workbook "Book4" with one sheet -> import into a Spreadsheet 0265 aspect = project.child<AbstractAspect>(0)->child<AbstractAspect>(1); 0266 QCOMPARE(aspect != nullptr, true); 0267 if (aspect != nullptr) 0268 QCOMPARE(aspect->name(), QLatin1String("Book4")); 0269 QCOMPARE(dynamic_cast<Spreadsheet*>(aspect) != nullptr, true); 0270 0271 if (aspect != nullptr) 0272 QCOMPARE(aspect->childCount<AbstractAspect>(), 2); 0273 } 0274 0275 /* 0276 * 1. import a spreadsheet 0277 * 2. modify a cell in it 0278 * 3. import the same spreadsheet once more 0279 * 4. check that the changes were really over-written 0280 */ 0281 void ProjectImportTest::testOrigin04() { 0282 OriginProjectParser parser; 0283 parser.setProjectFileName(QFINDTESTDATA(QLatin1String("data/origin8_test_tree_import.opj"))); 0284 Project project; 0285 0286 //import "Book1" 0287 QStringList selectedPathes = {QLatin1String("test_tree_import/Folder1/Book1"), QLatin1String("test_tree_import/Folder1"), QLatin1String("test_tree_import")}; 0288 parser.importTo(&project, selectedPathes); 0289 0290 //first child of folder "Folder1", workbook "Book1" with one sheet -> import into a spreadsheet 0291 auto* aspect = project.child<AbstractAspect>(0); 0292 QCOMPARE(aspect != nullptr, true); 0293 if (aspect != nullptr) 0294 QCOMPARE(aspect->name(), QLatin1String("Folder1")); 0295 aspect = project.child<AbstractAspect>(0)->child<AbstractAspect>(0); 0296 QCOMPARE(aspect != nullptr, true); 0297 if (aspect != nullptr) 0298 QCOMPARE(aspect->name(), QLatin1String("Book1")); 0299 auto* spreadsheet = dynamic_cast<Spreadsheet*>(aspect); 0300 QCOMPARE(spreadsheet != nullptr, true); 0301 0302 //the (0,0)-cell has the value 1.0 0303 if (spreadsheet != nullptr) { 0304 QCOMPARE(spreadsheet->column(0)->valueAt(0), 1.0); 0305 0306 //set the value to 5.0 0307 spreadsheet->column(0)->setValueAt(0, 5.0); 0308 QCOMPARE(spreadsheet->column(0)->valueAt(0), 5.0); 0309 } 0310 0311 //re-import 0312 parser.importTo(&project, selectedPathes); 0313 0314 //check the folder structure and the value of the (0,0)-cell again 0315 aspect = project.child<AbstractAspect>(0)->child<AbstractAspect>(0); 0316 QCOMPARE(aspect != nullptr, true); 0317 if (aspect != nullptr) 0318 QCOMPARE(aspect->name(), QLatin1String("Book1")); 0319 spreadsheet = dynamic_cast<Spreadsheet*>(aspect); 0320 QCOMPARE(spreadsheet != nullptr, true); 0321 if (spreadsheet != nullptr) 0322 QCOMPARE(spreadsheet->column(0)->valueAt(0), 1.0); 0323 } 0324 0325 void ProjectImportTest::testOriginTextNumericColumns() { 0326 OriginProjectParser parser; 0327 parser.setProjectFileName(QFINDTESTDATA(QLatin1String("data/origin8_test_workbook.opj"))); 0328 Project project; 0329 0330 //import "Book1" 0331 QStringList selectedPathes = {QLatin1String("origin8_test_workbook/Folder1/Book1"), QLatin1String("origin8_test_workbook/Folder1"), QLatin1String("origin8_test_workbook")}; 0332 parser.importTo(&project, selectedPathes); 0333 0334 //first child of folder "Folder1", workbook "Book1" with one sheet -> import into a spreadsheet 0335 auto* aspect = project.child<AbstractAspect>(0); 0336 QCOMPARE(aspect != nullptr, true); 0337 if (aspect != nullptr) 0338 QCOMPARE(aspect->name(), QLatin1String("Folder1")); 0339 aspect = project.child<AbstractAspect>(0)->child<AbstractAspect>(0); 0340 QCOMPARE(aspect != nullptr, true); 0341 if (aspect != nullptr) 0342 QCOMPARE(aspect->name(), QLatin1String("Book1")); 0343 auto* spreadsheet = dynamic_cast<Spreadsheet*>(aspect); 0344 QCOMPARE(spreadsheet != nullptr, true); 0345 0346 //additional pointer check for static code analysis tools like Coverity that are not aware of QCOMPARE above 0347 if (!spreadsheet) 0348 return; 0349 0350 //check the values in the imported columns 0351 QCOMPARE(spreadsheet->columnCount(), 6); 0352 0353 //1st column, Origin::TextNumeric: 0354 //first non-empty value is numerical, column is set to Numeric, empty or text values in the column a set to NAN 0355 Column* column = spreadsheet->column(0); 0356 QCOMPARE(column->columnMode(), AbstractColumn::ColumnMode::Numeric); 0357 QCOMPARE(!std::isnan(column->valueAt(0)), false); 0358 QCOMPARE(column->valueAt(1), 1.1); 0359 QCOMPARE(column->valueAt(2), 2.2); 0360 QCOMPARE(!std::isnan(column->valueAt(3)), false); 0361 QCOMPARE(!std::isnan(column->valueAt(4)), false); 0362 0363 //2nd column, Origin::TextNumeric: 0364 //first non-empty value is string, the column is set to Text, numerical values are converted to strings 0365 column = spreadsheet->column(1); 0366 QCOMPARE(column->columnMode(), AbstractColumn::ColumnMode::Text); 0367 QCOMPARE(column->textAt(0).isEmpty(), true); 0368 QCOMPARE(column->textAt(1), QLatin1String("a")); 0369 QCOMPARE(column->textAt(2), QLatin1String("b")); 0370 QCOMPARE(column->textAt(3), QLatin1String("1.1")); 0371 QCOMPARE(column->textAt(4), QLatin1String("2.2")); 0372 0373 //3rd column, Origin::TextNumeric: 0374 //first is numerical, column is set to Numeric, empty or text values in the column a set to NAN 0375 column = spreadsheet->column(2); 0376 QCOMPARE(column->columnMode(), AbstractColumn::ColumnMode::Numeric); 0377 QCOMPARE(column->valueAt(0), 1.1); 0378 QCOMPARE(column->valueAt(1), 2.2); 0379 QCOMPARE(!std::isnan(column->valueAt(2)), false); 0380 QCOMPARE(!std::isnan(column->valueAt(3)), false); 0381 QCOMPARE(column->valueAt(4), 3.3); 0382 0383 //4th column, Origin::TextNumeric: 0384 //first value is string, the column is set to Text, numerical values are converted to strings 0385 column = spreadsheet->column(3); 0386 QCOMPARE(column->columnMode(), AbstractColumn::ColumnMode::Text); 0387 QCOMPARE(column->textAt(0), QLatin1String("a")); 0388 QCOMPARE(column->textAt(1), QLatin1String("b")); 0389 QCOMPARE(column->textAt(2), QLatin1String("1.1")); 0390 QCOMPARE(column->textAt(3), QLatin1String("2.2")); 0391 QCOMPARE(column->textAt(4), QLatin1String("c")); 0392 0393 //5th column, Origin::Numeric 0394 //column is set to Numeric, empty values in the column a set to NAN 0395 column = spreadsheet->column(4); 0396 QCOMPARE(column->columnMode(), AbstractColumn::ColumnMode::Numeric); 0397 QCOMPARE(!std::isnan(column->valueAt(0)), false); 0398 QCOMPARE(column->valueAt(1), 1.1); 0399 QCOMPARE(column->valueAt(2), 2.2); 0400 QCOMPARE(column->valueAt(3), 3.3); 0401 QCOMPARE(!std::isnan(column->valueAt(4)), false); 0402 0403 //6th column, Origin::Numeric 0404 //column is set to Numeric, empty values in the column a set to NAN 0405 column = spreadsheet->column(5); 0406 QCOMPARE(column->columnMode(), AbstractColumn::ColumnMode::Numeric); 0407 QCOMPARE(column->valueAt(0), 1.1); 0408 QCOMPARE(column->valueAt(1), 2.2); 0409 QCOMPARE(column->valueAt(2), 3.3); 0410 QCOMPARE(!std::isnan(column->valueAt(3)), false); 0411 QCOMPARE(!std::isnan(column->valueAt(4)), false); 0412 } 0413 0414 void ProjectImportTest::testParseOriginTags_data() { 0415 QTest::addColumn<QString>("originTag"); 0416 QTest::addColumn<QString>("labPlotHTML"); 0417 0418 QTest::newRow("bold") << "\\b(bold)" << "<b>bold</b>"; 0419 0420 QTest::newRow("italic") << "\\i(italic)" << "<i>italic</i>"; 0421 0422 QTest::newRow("strike through") << "\\s(strike through)" << "<s>strike through</s>"; 0423 0424 QTest::newRow("underlined") << "\\u(underlined)" << "<u>underlined</u>"; 0425 0426 QTest::newRow("greek char") << "\\g(a)" << "<font face=Symbol>a</font>"; 0427 0428 QTest::newRow("sub-script") << "a\\-(b)" << "a<sub>b</sub>"; 0429 0430 QTest::newRow("super-script") << "a\\+(b)" << "a<sup>b</sup>"; 0431 0432 QTest::newRow("set-font") << "\\f:dejavu sans(text)" << "<font face=\"dejavu sans\">text</font>"; 0433 0434 QTest::newRow("font-size") << "some \\p200(big) text" 0435 << "some <span style=\"font-size: 200%\">big</span> text"; 0436 0437 QTest::newRow("color") << "some \\c15(colored) text" 0438 << "some <span style=\"color: #8000ff\">colored</span> text"; 0439 0440 QTest::newRow("nested-non-tag-parenthesis") 0441 << "\\b(text (c) and (fh) and a(t) and empty ())" 0442 << "<b>text (c) and (fh) and a(t) and empty ()</b>"; 0443 0444 QTest::newRow("nested-tags") 0445 << "\\b(bold text with some \\i(italic) bits and some \\c15(color)) " 0446 "then a change of \\f:dejavu sans(font)" 0447 << "<b>bold text with some <i>italic</i> bits and some " 0448 "<span style=\"color: #8000ff\">color</span></b> " 0449 "then a change of <font face=\"dejavu sans\">font</font>"; 0450 0451 QTest::newRow("nested-tags-with-extra-spaces") 0452 << "\\ b (bold text with some \\ i(italic) bits and some \\c 15 (color)) " 0453 "then a change of \\ f:dejavu sans( font)" 0454 << "<b>bold text with some <i>italic</i> bits and some " 0455 "<span style=\"color: #8000ff\">color</span></b> " 0456 "then a change of <font face=\"dejavu sans\"> font</font>"; 0457 } 0458 0459 void ProjectImportTest::testParseOriginTags() { 0460 QFETCH(QString, originTag); 0461 QFETCH(QString, labPlotHTML); 0462 0463 OriginProjectParser parser; 0464 QCOMPARE(parser.parseOriginTags(originTag), labPlotHTML); 0465 } 0466 0467 #endif 0468 0469 QTEST_MAIN(ProjectImportTest)