From 5cc9ab736aa61c7395be0f6960064de36063f677 Mon Sep 17 00:00:00 2001 From: Xisco Fauli Date: Fri, 18 Nov 2022 09:47:04 +0100 Subject: sc: rename these tests to ucalc_* All inherit from the same class, just to be consistent. this is part of a follow-up refactoring Change-Id: I9f69ae16c9363996a95a684183d6c0e981594405 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142907 Tested-by: Jenkins Reviewed-by: Xisco Fauli --- sc/qa/unit/datatransformation_test.cxx | 1005 ------------------------------- sc/qa/unit/parallelism.cxx | 1000 ------------------------------ sc/qa/unit/range.cxx | 189 ------ sc/qa/unit/rangelst_test.cxx | 554 ----------------- sc/qa/unit/ucalc_datatransformation.cxx | 1005 +++++++++++++++++++++++++++++++ sc/qa/unit/ucalc_parallelism.cxx | 1000 ++++++++++++++++++++++++++++++ sc/qa/unit/ucalc_range.cxx | 189 ++++++ sc/qa/unit/ucalc_rangelst.cxx | 554 +++++++++++++++++ 8 files changed, 2748 insertions(+), 2748 deletions(-) delete mode 100644 sc/qa/unit/datatransformation_test.cxx delete mode 100644 sc/qa/unit/parallelism.cxx delete mode 100644 sc/qa/unit/range.cxx delete mode 100644 sc/qa/unit/rangelst_test.cxx create mode 100644 sc/qa/unit/ucalc_datatransformation.cxx create mode 100644 sc/qa/unit/ucalc_parallelism.cxx create mode 100644 sc/qa/unit/ucalc_range.cxx create mode 100644 sc/qa/unit/ucalc_rangelst.cxx (limited to 'sc/qa') diff --git a/sc/qa/unit/datatransformation_test.cxx b/sc/qa/unit/datatransformation_test.cxx deleted file mode 100644 index 7f33aa21548a..000000000000 --- a/sc/qa/unit/datatransformation_test.cxx +++ /dev/null @@ -1,1005 +0,0 @@ -/* -*- 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 - -#include "helper/qahelper.hxx" -#include -#include -#include -#include - -class ScDataTransformationTest : public ScSimpleBootstrapFixture -{ -public: - - virtual void setUp() override; - - void testColumnRemove(); - void testColumnSplit(); - void testColumnMerge(); - void testTextToLower(); - void testTextToUpper(); - void testTextCapitalize(); - void testTextTrim(); - void testAggregateSum(); - void testAggregateAverage(); - void testAggregateMin(); - void testAggregateMax(); - void testNumberRound(); - void testNumberRoundUp(); - void testNumberRoundDown(); - void testNumberAbsolute(); - void testNumberLogE(); - void testNumberLog10(); - void testNumberCube(); - void testNumberSquare(); - void testNumberSquareRoot(); - void testNumberEven(); - void testNumberOdd(); - void testNumberSign(); - void testReplaceNull(); - void testGetDateString(); - void testGetYear(); - void testGetStartOfYear(); - void testGetEndOfYear(); - void testGetMonth(); - void testGetMonthName(); - void testGetStartOfMonth(); - void testGetEndOfMonth(); - void testGetDay(); - void testGetDayOfWeek(); - void testGetDayOfYear(); - void testGetQuarter(); - void testGetStartOfQuarter(); - void testGetEndOfQuarter(); - void testGetTime(); - void testGetHour(); - void testGetMinute(); - void testGetSecond(); - - CPPUNIT_TEST_SUITE(ScDataTransformationTest); - CPPUNIT_TEST(testColumnRemove); - CPPUNIT_TEST(testColumnSplit); - CPPUNIT_TEST(testColumnMerge); - CPPUNIT_TEST(testTextToLower); - CPPUNIT_TEST(testTextToUpper); - CPPUNIT_TEST(testTextCapitalize); - CPPUNIT_TEST(testTextTrim); - CPPUNIT_TEST(testAggregateSum); - CPPUNIT_TEST(testAggregateAverage); - CPPUNIT_TEST(testAggregateMin); - CPPUNIT_TEST(testAggregateMax); - CPPUNIT_TEST(testNumberRound); - CPPUNIT_TEST(testNumberRoundUp); - CPPUNIT_TEST(testNumberRoundDown); - CPPUNIT_TEST(testNumberAbsolute); - CPPUNIT_TEST(testNumberLogE); - CPPUNIT_TEST(testNumberLog10); - CPPUNIT_TEST(testNumberCube); - CPPUNIT_TEST(testNumberSquare); - CPPUNIT_TEST(testNumberSquareRoot); - CPPUNIT_TEST(testNumberEven); - CPPUNIT_TEST(testNumberOdd); - CPPUNIT_TEST(testNumberSign); - CPPUNIT_TEST(testReplaceNull); - CPPUNIT_TEST(testGetDateString); - CPPUNIT_TEST(testGetYear); - CPPUNIT_TEST(testGetStartOfYear); - CPPUNIT_TEST(testGetEndOfYear); - CPPUNIT_TEST(testGetMonth); - CPPUNIT_TEST(testGetMonthName); - CPPUNIT_TEST(testGetStartOfMonth); - CPPUNIT_TEST(testGetEndOfMonth); - CPPUNIT_TEST(testGetDay); - CPPUNIT_TEST(testGetDayOfWeek); - CPPUNIT_TEST(testGetDayOfYear); - CPPUNIT_TEST(testGetQuarter); - CPPUNIT_TEST(testGetStartOfQuarter); - CPPUNIT_TEST(testGetEndOfQuarter); - CPPUNIT_TEST(testGetTime); - CPPUNIT_TEST(testGetHour); - CPPUNIT_TEST(testGetMinute); - CPPUNIT_TEST(testGetSecond); - CPPUNIT_TEST_SUITE_END(); -}; - -void ScDataTransformationTest::testColumnRemove() -{ - for (SCROW nRow = 0; nRow < 10; ++nRow) - { - for (SCCOL nCol = 0; nCol < 10; ++nCol) - { - m_pDoc->SetValue(nCol, nRow, 0, nRow*nCol); - } - } - - sc::ColumnRemoveTransformation aTransformation({5}); - aTransformation.Transform(*m_pDoc); - - for (SCROW nRow = 0; nRow < 10; ++nRow) - { - for (SCCOL nCol = 0; nCol < 9; ++nCol) - { - double nVal = m_pDoc->GetValue(nCol, nRow, 0); - if (nCol < 5) - { - ASSERT_DOUBLES_EQUAL(static_cast(nCol)*nRow, nVal); - } - else - { - ASSERT_DOUBLES_EQUAL(static_cast(nCol+1)*nRow, nVal); - } - } - } -} - -void ScDataTransformationTest::testColumnSplit() -{ - m_pDoc->SetString(2, 0, 0, "Test1,Test2"); - m_pDoc->SetString(2, 1, 0, "Test1,"); - m_pDoc->SetString(2, 2, 0, ",Test1"); - m_pDoc->SetString(2, 3, 0, "Test1,Test2,Test3"); - m_pDoc->SetString(3, 0, 0, "AnotherString"); - - sc::SplitColumnTransformation aTransform(2, ','); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("AnotherString"), m_pDoc->GetString(4, 0, 0)); - - CPPUNIT_ASSERT_EQUAL(OUString("Test1"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Test1"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString(""), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Test1"), m_pDoc->GetString(2, 3, 0)); - - CPPUNIT_ASSERT_EQUAL(OUString("Test2"), m_pDoc->GetString(3, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString(""), m_pDoc->GetString(3, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Test1"), m_pDoc->GetString(3, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Test2,Test3"), m_pDoc->GetString(3, 3, 0)); -} - -void ScDataTransformationTest::testColumnMerge() -{ - m_pDoc->SetString(2, 0, 0, "Berlin"); - m_pDoc->SetString(2, 1, 0, "Brussels"); - m_pDoc->SetString(2, 2, 0, "Paris"); - m_pDoc->SetString(2, 3, 0, "Peking"); - - m_pDoc->SetString(4, 0, 0, "Germany"); - m_pDoc->SetString(4, 1, 0, "Belgium"); - m_pDoc->SetString(4, 2, 0, "France"); - m_pDoc->SetString(4, 3, 0, "China"); - - sc::MergeColumnTransformation aTransform({2, 4}, ", "); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("Berlin, Germany"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Brussels, Belgium"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Paris, France"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Peking, China"), m_pDoc->GetString(2, 3, 0)); - - for (SCROW nRow = 0; nRow <= 3; ++nRow) - { - CPPUNIT_ASSERT(m_pDoc->GetString(4, nRow, 0).isEmpty()); - } -} - -void ScDataTransformationTest::testTextToLower() -{ - m_pDoc->SetString(2, 0, 0, "Berlin"); - m_pDoc->SetString(2, 1, 0, "Brussels"); - m_pDoc->SetString(2, 2, 0, "Paris"); - m_pDoc->SetString(2, 3, 0, "Peking"); - - sc::TextTransformation aTransform({2}, sc::TEXT_TRANSFORM_TYPE::TO_LOWER); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("berlin"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("brussels"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("paris"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("peking"), m_pDoc->GetString(2, 3, 0)); -} - -void ScDataTransformationTest::testTextToUpper() -{ - m_pDoc->SetString(2, 0, 0, "Berlin"); - m_pDoc->SetString(2, 1, 0, "Brussels"); - m_pDoc->SetString(2, 2, 0, "Paris"); - m_pDoc->SetString(2, 3, 0, "Peking"); - - sc::TextTransformation aTransform({2}, sc::TEXT_TRANSFORM_TYPE::TO_UPPER); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("BERLIN"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("BRUSSELS"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("PARIS"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("PEKING"), m_pDoc->GetString(2, 3, 0)); -} - -void ScDataTransformationTest::testTextCapitalize() -{ - m_pDoc->SetString(2, 0, 0, "hello woRlD"); - m_pDoc->SetString(2, 1, 0, "qUe vA"); - m_pDoc->SetString(2, 2, 0, "si tu la ves"); - m_pDoc->SetString(2, 3, 0, "cUaNdO mE EnAmOro"); - - sc::TextTransformation aTransform({2}, sc::TEXT_TRANSFORM_TYPE::CAPITALIZE); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("Hello World"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Que Va"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Si Tu La Ves"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Cuando Me Enamoro"), m_pDoc->GetString(2, 3, 0)); -} - -void ScDataTransformationTest::testTextTrim() -{ - m_pDoc->SetString(2, 0, 0, " Berlin"); - m_pDoc->SetString(2, 1, 0, "Brussels "); - m_pDoc->SetString(2, 2, 0, " Paris "); - - sc::TextTransformation aTransform({2}, sc::TEXT_TRANSFORM_TYPE::TRIM); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("Berlin"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Brussels"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Paris"), m_pDoc->GetString(2, 2, 0)); -} - -void ScDataTransformationTest::testAggregateSum() -{ - m_pDoc->SetValue(2, 0, 0, 2034); - m_pDoc->SetValue(2, 1, 0, 2342); - m_pDoc->SetValue(2, 2, 0, 57452); - - m_pDoc->SetValue(4, 0, 0, 4829.98); - m_pDoc->SetValue(4, 1, 0, 53781.3); - m_pDoc->SetValue(4, 2, 0, 9876.4); - m_pDoc->SetValue(4, 3, 0, 0); - - sc::AggregateFunction aTransform({2, 4}, sc::AGGREGATE_FUNCTION::SUM); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(61828, m_pDoc->GetValue(2, 4, 0), 1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(68487.68, m_pDoc->GetValue(4, 4, 0), 1e-10); -} - -void ScDataTransformationTest::testAggregateAverage() -{ - m_pDoc->SetValue(2, 0, 0, 2034); - m_pDoc->SetValue(2, 1, 0, 2342); - m_pDoc->SetValue(2, 2, 0, 57453); - - m_pDoc->SetValue(3, 0, 0, 4); - m_pDoc->SetValue(3, 1, 0, 4); - m_pDoc->SetValue(3, 2, 0, 4); - - sc::AggregateFunction aTransform({2, 3}, sc::AGGREGATE_FUNCTION::AVERAGE); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(20609.6666666667, m_pDoc->GetValue(2, 3, 0), 1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4, m_pDoc->GetValue(3, 3, 0), 1e-10); -} - -void ScDataTransformationTest::testAggregateMin() -{ - m_pDoc->SetValue(2, 0, 0, 2034); - m_pDoc->SetValue(2, 1, 0, 2342); - m_pDoc->SetValue(2, 2, 0, 57453); - - m_pDoc->SetValue(3, 0, 0, 2034); - m_pDoc->SetValue(3, 1, 0, -2342); - m_pDoc->SetValue(3, 2, 0, 57453); - - sc::AggregateFunction aTransform({2, 3}, sc::AGGREGATE_FUNCTION::MIN); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(2034, m_pDoc->GetValue(2, 3, 0), 1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-2342, m_pDoc->GetValue(3, 3, 0), 1e-10); -} - -void ScDataTransformationTest::testAggregateMax() -{ - m_pDoc->SetValue(2, 0, 0, 2034); - m_pDoc->SetValue(2, 1, 0, 2342); - m_pDoc->SetValue(2, 2, 0, 57453); - m_pDoc->SetValue(2, 3, 0, -453); - - m_pDoc->SetValue(3, 0, 0, 2034); - m_pDoc->SetValue(3, 1, 0, -2342); - m_pDoc->SetValue(3, 2, 0, -57453); - m_pDoc->SetValue(3, 3, 0, -453); - - sc::AggregateFunction aTransform({2, 3}, sc::AGGREGATE_FUNCTION::MAX); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(57453, m_pDoc->GetValue(2, 4, 0), 1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2034, m_pDoc->GetValue(3, 4, 0), 1e-10); -} - -void ScDataTransformationTest::testNumberRound() -{ - m_pDoc->SetValue(2, 0, 0, 2034.342453456); - m_pDoc->SetValue(2, 1, 0, 2342.252678567542); - m_pDoc->SetValue(2, 2, 0, 57453.651345687654345676); - m_pDoc->SetValue(2, 3, 0, -453.22234567543); - - sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::ROUND, 4); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(2034.3425, m_pDoc->GetValue(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(2342.2527, m_pDoc->GetValue(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(57453.6513, m_pDoc->GetValue(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(-453.2223, m_pDoc->GetValue(2, 3, 0)); -} - -void ScDataTransformationTest::testNumberRoundUp() -{ - m_pDoc->SetValue(2, 0, 0, 2034.34); - m_pDoc->SetValue(2, 1, 0, 2342.22); - m_pDoc->SetValue(2, 2, 0, 57453.65); - m_pDoc->SetValue(2, 3, 0, -453.22); - - sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::ROUND_UP); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(2035.0, m_pDoc->GetValue(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(2343.0, m_pDoc->GetValue(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(57454.0, m_pDoc->GetValue(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(-453.0, m_pDoc->GetValue(2, 3, 0)); -} - -void ScDataTransformationTest::testNumberRoundDown() -{ - m_pDoc->SetValue(2, 0, 0, 2034.34); - m_pDoc->SetValue(2, 1, 0, 2342.22); - m_pDoc->SetValue(2, 2, 0, 57453.65); - m_pDoc->SetValue(2, 3, 0, -453.22); - - sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::ROUND_DOWN); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(2034.0, m_pDoc->GetValue(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(2342.0, m_pDoc->GetValue(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(57453.0, m_pDoc->GetValue(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(-454.0, m_pDoc->GetValue(2, 3, 0)); -} - -void ScDataTransformationTest::testNumberAbsolute() -{ - m_pDoc->SetValue(2, 0, 0, 2034.34); - m_pDoc->SetValue(2, 1, 0, -2342.22); - m_pDoc->SetValue(2, 2, 0, 57453.65); - m_pDoc->SetValue(2, 3, 0, -453.22); - - sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::ABSOLUTE); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(2034.34, m_pDoc->GetValue(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(2342.22, m_pDoc->GetValue(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(57453.65, m_pDoc->GetValue(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(453.22, m_pDoc->GetValue(2, 3, 0)); -} - -void ScDataTransformationTest::testNumberLogE() -{ - m_pDoc->SetValue(2, 0, 0, 1); - m_pDoc->SetValue(2, 1, 0, 5); - m_pDoc->SetValue(2, 2, 0, -9); - m_pDoc->SetValue(2, 3, 0, 500); - - sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::LOG_E); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(0, m_pDoc->GetValue(2, 0, 0), 1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.60943791243, m_pDoc->GetValue(2, 1, 0), 1e-10); - CPPUNIT_ASSERT_EQUAL(OUString(""), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.21460809842, m_pDoc->GetValue(2, 3, 0), 1e-10); -} - -void ScDataTransformationTest::testNumberLog10() -{ - m_pDoc->SetValue(2, 0, 0, 1); - m_pDoc->SetValue(2, 1, 0, 10); - m_pDoc->SetValue(2, 2, 0, -9); - m_pDoc->SetValue(2, 3, 0, 500); - - sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::LOG_10); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(0, m_pDoc->GetValue(2, 0, 0), 1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, m_pDoc->GetValue(2, 1, 0), 1e-10); - CPPUNIT_ASSERT_EQUAL(OUString(), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.69897000434, m_pDoc->GetValue(2, 3, 0), 1e-10); -} - -void ScDataTransformationTest::testNumberCube() -{ - m_pDoc->SetValue(2, 0, 0, 2); - m_pDoc->SetValue(2, 1, 0, -2); - m_pDoc->SetValue(2, 2, 0, 8); - m_pDoc->SetValue(2, 3, 0, -8); - - sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::CUBE); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(8.0, m_pDoc->GetValue(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(-8.0, m_pDoc->GetValue(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(512.0, m_pDoc->GetValue(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(-512.0, m_pDoc->GetValue(2, 3, 0)); -} - -void ScDataTransformationTest::testNumberSquare() -{ - m_pDoc->SetValue(2, 0, 0, 2); - m_pDoc->SetValue(2, 1, 0, -2); - m_pDoc->SetValue(2, 2, 0, 8); - m_pDoc->SetValue(2, 3, 0, -8); - - sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::SQUARE); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(4.0, m_pDoc->GetValue(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(4.0, m_pDoc->GetValue(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(64.0, m_pDoc->GetValue(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(64.0, m_pDoc->GetValue(2, 3, 0)); -} - -void ScDataTransformationTest::testNumberSquareRoot() -{ - m_pDoc->SetValue(2, 0, 0, 8); - m_pDoc->SetValue(2, 1, 0, 4); - m_pDoc->SetValue(2, 2, 0, 9); - - sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::SQUARE_ROOT); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.82842712475, m_pDoc->GetValue(2, 0, 0), 1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.0, m_pDoc->GetValue(2, 1, 0), 1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, m_pDoc->GetValue(2, 2, 0), 1e-10); -} - -void ScDataTransformationTest::testNumberEven() -{ - m_pDoc->SetValue(2, 0, 0, 2034); - m_pDoc->SetValue(2, 1, 0, 2343); - m_pDoc->SetValue(2, 2, 0, 57453.65); - m_pDoc->SetValue(2, 3, 0, -453); - - sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::IS_EVEN); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(2, 3, 0)); -} - -void ScDataTransformationTest::testNumberOdd() -{ - m_pDoc->SetValue(2, 0, 0, 2034); - m_pDoc->SetValue(2, 1, 0, 2343); - m_pDoc->SetValue(2, 2, 0, 57453.65); - m_pDoc->SetValue(2, 3, 0, -453); - - sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::IS_ODD); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(2, 3, 0)); -} - -void ScDataTransformationTest::testNumberSign() -{ - m_pDoc->SetValue(2, 0, 0, 2034.34); - m_pDoc->SetValue(2, 1, 0, -2342.22); - m_pDoc->SetValue(2, 2, 0, 0); - m_pDoc->SetValue(2, 3, 0, -453.22); - - sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::SIGN); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(-1.0, m_pDoc->GetValue(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(-1.0, m_pDoc->GetValue(2, 3, 0)); -} - -void ScDataTransformationTest::testReplaceNull() -{ - m_pDoc->SetString(2, 0, 0, "Berlin"); - m_pDoc->SetString(2, 1, 0, ""); - m_pDoc->SetString(2, 2, 0, ""); - m_pDoc->SetString(2, 3, 0, "Peking"); - - sc::ReplaceNullTransformation aTransform({2}, "Empty"); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("Berlin"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Empty"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Empty"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("Peking"), m_pDoc->GetString(2, 3, 0)); - -} - -void ScDataTransformationTest::testGetDateString() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::DATE_STRING ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("01/25/11"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("10/12/94"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("09/23/96"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("08/15/47"), m_pDoc->GetString(2, 3, 0)); -} - -void ScDataTransformationTest::testGetYear() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::YEAR ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(2011, m_pDoc->GetValue(2, 0, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1994, m_pDoc->GetValue(2, 1, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1996, m_pDoc->GetValue(2, 2, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1947, m_pDoc->GetValue(2, 3, 0), 0); -} - -void ScDataTransformationTest::testGetStartOfYear() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::START_OF_YEAR ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("01/01/11"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("01/01/94"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("01/01/96"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("01/01/47"), m_pDoc->GetString(2, 3, 0)); -} - -void ScDataTransformationTest::testGetEndOfYear() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::END_OF_YEAR ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("12/31/11"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("12/31/94"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("12/31/96"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("12/31/47"), m_pDoc->GetString(2, 3, 0)); -} - -void ScDataTransformationTest::testGetMonth() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::MONTH ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(2, 0, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(10, m_pDoc->GetValue(2, 1, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9, m_pDoc->GetValue(2, 2, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8, m_pDoc->GetValue(2, 3, 0), 0); -} - -void ScDataTransformationTest::testGetMonthName() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::MONTH_NAME); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("January"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("October"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("September"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("August"), m_pDoc->GetString(2, 3, 0)); -} - -void ScDataTransformationTest::testGetStartOfMonth() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::START_OF_MONTH ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("01/01/11"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("10/01/94"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("09/01/96"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("08/01/47"), m_pDoc->GetString(2, 3, 0)); -} - -void ScDataTransformationTest::testGetEndOfMonth() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::END_OF_MONTH ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("01/31/11"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("10/31/94"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("09/30/96"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("08/31/47"), m_pDoc->GetString(2, 3, 0)); -} - -void ScDataTransformationTest::testGetDay() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::DAY ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(25, m_pDoc->GetValue(2, 0, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(12, m_pDoc->GetValue(2, 1, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(23, m_pDoc->GetValue(2, 2, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15, m_pDoc->GetValue(2, 3, 0), 0); -} - -void ScDataTransformationTest::testGetDayOfWeek() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_WEEK ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(2, 0, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2, m_pDoc->GetValue(2, 1, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0, m_pDoc->GetValue(2, 2, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4, m_pDoc->GetValue(2, 3, 0), 0); -} - -void ScDataTransformationTest::testGetDayOfYear() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_YEAR ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(25, m_pDoc->GetValue(2, 0, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(285, m_pDoc->GetValue(2, 1, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(267, m_pDoc->GetValue(2, 2, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(227, m_pDoc->GetValue(2, 3, 0), 0); -} - -void ScDataTransformationTest::testGetQuarter() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::QUARTER ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(2, 0, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4, m_pDoc->GetValue(2, 1, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3, m_pDoc->GetValue(2, 2, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3, m_pDoc->GetValue(2, 3, 0), 0); -} - -void ScDataTransformationTest::testGetStartOfQuarter() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::START_OF_QUARTER ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("01/01/11"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("10/01/94"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("07/01/96"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("07/01/47"), m_pDoc->GetString(2, 3, 0)); -} - -void ScDataTransformationTest::testGetEndOfQuarter() -{ - SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); - css::util::Date aDate1(25,1,2011); - css::util::Date aDate2(12,10,1994); - css::util::Date aDate3(23,9,1996); - css::util::Date aDate4(15,8,1947); - - double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); - double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); - double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); - double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); - - m_pDoc->SetValue(2, 0, 0, nDate1); - m_pDoc->SetValue(2, 1, 0, nDate2); - m_pDoc->SetValue(2, 2, 0, nDate3); - m_pDoc->SetValue(2, 3, 0, nDate4); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::END_OF_QUARTER ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("03/31/11"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("12/31/94"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("09/30/96"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("09/30/47"), m_pDoc->GetString(2, 3, 0)); -} - -void ScDataTransformationTest::testGetTime() -{ - tools::Time aTime1(5,30,12); - tools::Time aTime2(7,23,9); - tools::Time aTime3(9,34,40); - tools::Time aTime4(22,9,49); - - m_pDoc->SetValue(2, 0, 0, aTime1.GetTimeInDays()); - m_pDoc->SetValue(2, 1, 0, aTime2.GetTimeInDays()); - m_pDoc->SetValue(2, 2, 0, aTime3.GetTimeInDays()); - m_pDoc->SetValue(2, 3, 0, aTime4.GetTimeInDays()); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::TIME ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_EQUAL(OUString("05:30:12 AM"), m_pDoc->GetString(2, 0, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("07:23:09 AM"), m_pDoc->GetString(2, 1, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("09:34:40 AM"), m_pDoc->GetString(2, 2, 0)); - CPPUNIT_ASSERT_EQUAL(OUString("10:09:49 PM"), m_pDoc->GetString(2, 3, 0)); -} - -void ScDataTransformationTest::testGetHour() -{ - tools::Time aTime1(5,30,12); - tools::Time aTime2(7,23,9); - tools::Time aTime3(9,34,40); - tools::Time aTime4(22,9,49); - - m_pDoc->SetValue(2, 0, 0, aTime1.GetTimeInDays()); - m_pDoc->SetValue(2, 1, 0, aTime2.GetTimeInDays()); - m_pDoc->SetValue(2, 2, 0, aTime3.GetTimeInDays()); - m_pDoc->SetValue(2, 3, 0, aTime4.GetTimeInDays()); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::HOUR ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(5, m_pDoc->GetValue(2, 0, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7, m_pDoc->GetValue(2, 1, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9, m_pDoc->GetValue(2, 2, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(22, m_pDoc->GetValue(2, 3, 0), 0); -} - -void ScDataTransformationTest::testGetMinute() -{ - tools::Time aTime1(5,30,12); - tools::Time aTime2(7,23,9); - tools::Time aTime3(9,34,40); - tools::Time aTime4(22,9,49); - - m_pDoc->SetValue(2, 0, 0, aTime1.GetTimeInDays()); - m_pDoc->SetValue(2, 1, 0, aTime2.GetTimeInDays()); - m_pDoc->SetValue(2, 2, 0, aTime3.GetTimeInDays()); - m_pDoc->SetValue(2, 3, 0, aTime4.GetTimeInDays()); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::MINUTE ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(30, m_pDoc->GetValue(2, 0, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(23, m_pDoc->GetValue(2, 1, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(34, m_pDoc->GetValue(2, 2, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9, m_pDoc->GetValue(2, 3, 0), 0); -} - -void ScDataTransformationTest::testGetSecond() -{ - tools::Time aTime1(5,30,53); - tools::Time aTime2(7,23,10); - tools::Time aTime3(9,34,40); - tools::Time aTime4(22,9,49); - - m_pDoc->SetValue(2, 0, 0, aTime1.GetTimeInDays()); - m_pDoc->SetValue(2, 1, 0, aTime2.GetTimeInDays()); - m_pDoc->SetValue(2, 2, 0, aTime3.GetTimeInDays()); - m_pDoc->SetValue(2, 3, 0, aTime4.GetTimeInDays()); - - sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::SECOND ); - aTransform.Transform(*m_pDoc); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(53, m_pDoc->GetValue(2, 0, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(10, m_pDoc->GetValue(2, 1, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(40, m_pDoc->GetValue(2, 2, 0), 0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(49, m_pDoc->GetValue(2, 3, 0), 0); -} - -void ScDataTransformationTest::setUp() -{ - ScSimpleBootstrapFixture::setUp(); - m_pDoc->InsertTab(0, "Tab"); -} - -CPPUNIT_TEST_SUITE_REGISTRATION(ScDataTransformationTest); - -CPPUNIT_PLUGIN_IMPLEMENT(); - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/parallelism.cxx b/sc/qa/unit/parallelism.cxx deleted file mode 100644 index ee148f822410..000000000000 --- a/sc/qa/unit/parallelism.cxx +++ /dev/null @@ -1,1000 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ - -#include -#include - -#include - -#include "helper/qahelper.hxx" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace css; -using namespace css::uno; - -class ScParallelismTest : public ScSimpleBootstrapFixture -{ -public: - virtual void setUp() override; - virtual void tearDown() override; - - void testSUMIFS(); - void testDivision(); - void testVLOOKUP(); - void testVLOOKUPSUM(); - void testSingleRef(); - void testTdf147905(); - void testSUMIFImplicitRange(); - void testFGCycleWithPlainFormulaCell1(); - void testFGCycleWithPlainFormulaCell2(); - void testMultipleFGColumn(); - void testFormulaGroupSpanEval(); - void testFormulaGroupSpanEvalNonGroup(); - void testArrayFormulaGroup(); - void testDependentFormulaGroupCollection(); - void testFormulaGroupWithForwardSelfReference(); - void testFormulaGroupsInCyclesAndWithSelfReference(); - void testFormulaGroupsInCyclesAndWithSelfReference2(); - void testFormulaGroupsInCyclesAndWithSelfReference3(); - - CPPUNIT_TEST_SUITE(ScParallelismTest); - CPPUNIT_TEST(testSUMIFS); - CPPUNIT_TEST(testDivision); - CPPUNIT_TEST(testVLOOKUP); - CPPUNIT_TEST(testVLOOKUPSUM); - CPPUNIT_TEST(testSingleRef); - CPPUNIT_TEST(testTdf147905); - CPPUNIT_TEST(testSUMIFImplicitRange); - CPPUNIT_TEST(testFGCycleWithPlainFormulaCell1); - CPPUNIT_TEST(testFGCycleWithPlainFormulaCell2); - CPPUNIT_TEST(testMultipleFGColumn); - CPPUNIT_TEST(testFormulaGroupSpanEval); - CPPUNIT_TEST(testFormulaGroupSpanEvalNonGroup); - CPPUNIT_TEST(testArrayFormulaGroup); - CPPUNIT_TEST(testDependentFormulaGroupCollection); - CPPUNIT_TEST(testFormulaGroupWithForwardSelfReference); - CPPUNIT_TEST(testFormulaGroupsInCyclesAndWithSelfReference); - CPPUNIT_TEST(testFormulaGroupsInCyclesAndWithSelfReference2); - CPPUNIT_TEST(testFormulaGroupsInCyclesAndWithSelfReference3); - CPPUNIT_TEST_SUITE_END(); - -private: - - bool getThreadingFlag() const; - void setThreadingFlag(bool bSet); - - bool m_bThreadingFlagCfg; -}; - -bool ScParallelismTest::getThreadingFlag() const -{ - return officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::get(); -} - -void ScParallelismTest::setThreadingFlag( bool bSet ) -{ - std::shared_ptr xBatch(comphelper::ConfigurationChanges::create()); - officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::set(bSet, xBatch); - xBatch->commit(); -} - -void ScParallelismTest::setUp() -{ - ScSimpleBootstrapFixture::setUp(); - - sc::FormulaGroupInterpreter::disableOpenCL_UnitTestsOnly(); - - m_bThreadingFlagCfg = getThreadingFlag(); - if (!m_bThreadingFlagCfg) - setThreadingFlag(true); -} - -void ScParallelismTest::tearDown() -{ - // Restore threading flag - if (!m_bThreadingFlagCfg) - setThreadingFlag(false); - - ScSimpleBootstrapFixture::tearDown(); -} - -void ScParallelismTest::testSUMIFS() -{ - m_pDoc->InsertTab(0, "1"); - - m_pDoc->SetValue(0, 0, 0, 1001); - - for (auto i = 1; i < 1000; i++) - { - /*A*/ - if (i%19) - m_pDoc->SetValue(0, i, 0, i/10 + 1000); - else - m_pDoc->SetValue(0, i, 0, 123456); - /*B*/ m_pDoc->SetValue(1, i, 0, i%10); - /*C*/ m_pDoc->SetValue(2, i, 0, i%5); - - /*F*/ m_pDoc->SetValue(5, i, 0, i%17 + i%13); - - /*L*/ m_pDoc->SetValue(11, i, 0, i%10); - /*M*/ m_pDoc->SetValue(12, i, 0, i%5); - } - - for (auto i = 1; i < 1000; i++) - { - // For instance P389 will contain the formula: - // =SUMIFS($F$2:$F$1000; $A$2:$A$1000; A$1; $B$2:$B$1000; $L389; $C$2:$C$1000; $M389) - - // In other words, it will sum those values in F2:1000 where the A value matches A1 (1001), - // the B value matches L389 and the C value matches M389. (There should be just one such - // value, so the formula is actually simply used to pick out that single value from the F - // column where A,B,C match. Silly, but that is how SUMIFS is used in some corners of the - // real world, apparently.) - - /*P*/ m_pDoc->SetFormula(ScAddress(15, i, 0), - "=SUMIFS($F$2:$F$1000; " - "$A$2:$A$1000; A$1; " - "$B$2:$B$1000; $L" + OUString::number(i+1) + "; " - "$C$2:$C$1000; $M" + OUString::number(i+1) + - ")", - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - m_xDocShell->DoHardRecalc(); - -#if 1 - OUString sFormula; - - std::cerr << "A1=" << m_pDoc->GetValue(0, 0, 0) << std::endl; - - std::cerr << " A,B,C F L,M" << std::endl; - for (auto i = 1; i < 30; i++) - { - std::cerr << - i+1 << ": " << - m_pDoc->GetValue(0, i, 0) << "," << - m_pDoc->GetValue(1, i, 0) << "," << - m_pDoc->GetValue(2, i, 0) << " " << - m_pDoc->GetValue(5, i, 0) << " " << - m_pDoc->GetValue(11, i, 0) << "," << - m_pDoc->GetValue(12, i, 0) << " \""; - sFormula = m_pDoc->GetFormula(15, i, 0); - std::cerr << sFormula << "\": \"" << - m_pDoc->GetString(15, i, 0) << "\": " << - m_pDoc->GetValue(15, i, 0) << std::endl; - } -#endif - - for (auto i = 1; i < 1000; i++) - { - OString sMessage = "At row " + OString::number(i+1); - if ((10+i%10)%19) - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(sMessage.getStr(), m_pDoc->GetValue(5, 10+i%10, 0), m_pDoc->GetValue(15, i, 0), 1e-10); - else - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(sMessage.getStr(), 0, m_pDoc->GetValue(15, i, 0), 1e-10); - } - - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testDivision() -{ - m_pDoc->InsertTab(0, "1"); - - for (auto i = 1; i < 1000; i++) - { - /*A*/ m_pDoc->SetValue(0, i, 0, i); - /*B*/ m_pDoc->SetValue(1, i, 0, i%10); - /*C*/ m_pDoc->SetFormula(ScAddress(2, i, 0), - "=A" + OUString::number(i+1) + "/B" + OUString::number(i+1), - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - m_xDocShell->DoHardRecalc(); - - for (auto i = 1; i < 1000; i++) - { - OString sMessage = "At row " + OString::number(i+1); - if (i%10) - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(sMessage.getStr(), static_cast(i)/(i%10), m_pDoc->GetValue(2, i, 0), 1e-10); - else - CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), OUString("#DIV/0!"), m_pDoc->GetString(2, i, 0)); - } - - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testVLOOKUP() -{ - m_pDoc->InsertTab(0, "1"); - - for (auto i = 1; i < 2000; i++) - { - if (i == 1042) - m_pDoc->SetValue(0, i, 0, 1042.42); - else if (i%5) - m_pDoc->SetValue(0, i, 0, i); - else - m_pDoc->SetValue(0, i, 0, i+0.1); - - if (i%2) - m_pDoc->SetValue(1, i, 0, i*10); - else - m_pDoc->SetString(1, i, 0, "N" + OUString::number(i*10)); - - if (i < 1000) - { - m_pDoc->SetFormula(ScAddress(2, i, 0), - "=VLOOKUP(" + OUString::number(i) + "; " - "A$2:B$2000; 2; 0)", - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - else - { - if (i == 1042) - m_pDoc->SetFormula(ScAddress(2, i, 0), - "=VLOOKUP(1042.42; " - "A$2:B$2000; 2; 0)", - formula::FormulaGrammar::GRAM_NATIVE_UI); - else - m_pDoc->SetFormula(ScAddress(2, i, 0), - "=VLOOKUP(1.234; " - "A$2:B$2000; 2; 0)", - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - } - - m_xDocShell->DoHardRecalc(); - - for (auto i = 1; i < 2000; i++) - { - OString sMessage = "At row " + OString::number(i+1); - if (i < 1000) - { - if (i%5) - { - if (i%2) - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(sMessage.getStr(), static_cast(i*10), m_pDoc->GetValue(2, i, 0), 1e-10); - else - CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), OUString("N" + OUString::number(i*10)), m_pDoc->GetString(2, i, 0)); - } - else - { - // The corresponding value in A is i+0.1 - CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), OUString("#N/A"), m_pDoc->GetString(2, i, 0)); - } - } - else - { - if (i == 1042) - CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), OUString("N" + OUString::number(i*10)), m_pDoc->GetString(2, i, 0)); - else - CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), OUString("#N/A"), m_pDoc->GetString(2, i, 0)); - } - } - - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testVLOOKUPSUM() -{ - m_pDoc->InsertTab(0, "1"); - - const size_t nNumRows = 2048; - OUString aTableRef = "$A$1:$B$" + OUString::number(nNumRows); - for (size_t i = 0; i < nNumRows; ++i) - { - m_pDoc->SetValue(0, i, 0, static_cast(i)); - m_pDoc->SetValue(1, i, 0, static_cast(5*i + 100)); - m_pDoc->SetValue(2, i, 0, static_cast(nNumRows - i - 1)); - } - for (size_t i = 0; i < nNumRows; ++i) - { - OUString aArgNum = "C" + OUString::number(i+1); - m_pDoc->SetFormula(ScAddress(3, i, 0), - "=SUM(" + aArgNum + ";VLOOKUP(" + aArgNum + ";" + aTableRef + "; 2; 0)) + SUM($A1:$A2)", - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - m_xDocShell->DoHardRecalc(); - - for (size_t i = 0; i < nNumRows; ++i) - { - OString aMsg = "At row " + OString::number(i); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), 6 * (nNumRows - i - 1) + 101, static_cast(m_pDoc->GetValue(3, i, 0))); - } - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testSingleRef() -{ - m_pDoc->InsertTab(0, "1"); - - const size_t nNumRows = 200; - for (size_t i = 0; i < nNumRows; ++i) - { - m_pDoc->SetValue(0, i, 0, static_cast(i)); - m_pDoc->SetFormula(ScAddress(1, i, 0), "=A" + OUString::number(i+1), formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - m_xDocShell->DoHardRecalc(); - - for (size_t i = 0; i < nNumRows; ++i) - { - OString aMsg = "At row " + OString::number(i); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), i, static_cast(m_pDoc->GetValue(1, i, 0))); - } - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testTdf147905() -{ - m_pDoc->InsertTab(0, "1"); - - OUString aFormula; - const size_t nNumRows = 500; - for (size_t i = 0; i < nNumRows; ++i) - { - m_pDoc->SetString(0, i, 0, "AAAAAAAA"); - aFormula = "=PROPER($A" + OUString::number(i+1) + ")"; - m_pDoc->SetFormula(ScAddress(1, i, 0), - aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - m_xDocShell->DoHardRecalc(); - - for (size_t i = 0; i < nNumRows; ++i) - { - OString aMsg = "At row " + OString::number(i); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), OUString("AAAAAAAA"), m_pDoc->GetString(0, i, 0)); - - // Without the fix in place, this test would have failed here - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), OUString("Aaaaaaaa"), m_pDoc->GetString(1, i, 0)); - } - m_pDoc->DeleteTab(0); -} - -// Common test setup steps for testSUMIFImplicitRange*() -static void lcl_setupCommon(ScDocument* pDoc, size_t nNumRows, size_t nConstCellValue) -{ - pDoc->SetValue(3, 0, 0, static_cast(nConstCellValue)); // D1 - for (size_t i = 0; i <= (nNumRows*2); ++i) - { - pDoc->SetValue(0, i, 0, static_cast(i)); - pDoc->SetFormula(ScAddress(1, i, 0), - "=A" + OUString::number(i+1), - formula::FormulaGrammar::GRAM_NATIVE_UI); - } -} - -void ScParallelismTest::testSUMIFImplicitRange() -{ - sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); - m_pDoc->InsertTab(0, "1"); - - const size_t nNumRows = 1048; - const size_t nConstCellValue = 20; - lcl_setupCommon(m_pDoc, nNumRows, nConstCellValue); - OUString aSrcRange = "$A$1:$A$" + OUString::number(nNumRows); - OUString aFormula; - for (size_t i = 0; i < nNumRows; ++i) - { - aFormula = "=SUMIF(" + aSrcRange + ";$D$1;$B$1)"; - m_pDoc->SetFormula(ScAddress(2, i, 0), - aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - ScFormulaCell* pCell = m_pDoc->GetFormulaCell(ScAddress(2, 0, 0)); - sc::AutoCalcSwitch aACSwitch2(*m_pDoc, true); - pCell->InterpretFormulaGroup(); // Start calculation on the F.G at C1 - - for (size_t i = 0; i < nNumRows; ++i) - { - OString aMsg = "At row " + OString::number(i); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nConstCellValue, static_cast(m_pDoc->GetValue(2, i, 0))); - } - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testFGCycleWithPlainFormulaCell1() -{ - sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); - m_pDoc->InsertTab(0, "1"); - const size_t nNumRows = 1048; - // Column A contains no formula-group - // A1 = 100 - m_pDoc->SetValue(0, 0, 0, 100.0); - // A500 = B499 + 1 - m_pDoc->SetFormula(ScAddress(0, 499, 0), - "=$B499 + 1", - formula::FormulaGrammar::GRAM_NATIVE_UI); - // Column B has a formula-group referencing column A. - OUString aFormula; - for (size_t i = 0; i < nNumRows; ++i) - { - aFormula = "=$A" + OUString::number(i+1) + " + 100"; - m_pDoc->SetFormula(ScAddress(1, i, 0), - aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - m_xDocShell->DoHardRecalc(); - // Value at A500 must be 101 - const size_t nVal = 100; - CPPUNIT_ASSERT_EQUAL_MESSAGE("Value at A500", nVal + 1, static_cast(m_pDoc->GetValue(0, 499, 0))); - for (size_t i = 0; i < nNumRows; ++i) - { - OString aMsg = "Value at cell B" + OString::number(i+1); - size_t nExpected = nVal; - if (i == 0) - nExpected = 200; - else if (i == 499) - nExpected = 201; - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast(m_pDoc->GetValue(1, i, 0))); - } - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testFGCycleWithPlainFormulaCell2() -{ - sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); - m_pDoc->InsertTab(0, "1"); - const size_t nNumRows = 1048; - // Column A - OUString aFormula; - for (size_t i = 0; i < nNumRows; ++i) - { - aFormula = "=$B" + OUString::number(i+1) + " + 1"; - m_pDoc->SetFormula(ScAddress(0, i, 0), - aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - // Column B - for (size_t i = 0; i < nNumRows; ++i) - { - aFormula = "=$C" + OUString::number(i+1) + " + 1"; - m_pDoc->SetFormula(ScAddress(1, i, 0), - aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - // Column C has no FG but a cell at C500 that references A499 - m_pDoc->SetFormula(ScAddress(2, 499, 0), // C500 - "=$A499 + 1", - formula::FormulaGrammar::GRAM_NATIVE_UI); - m_xDocShell->DoHardRecalc(); - - size_t nExpected = 0; - for (size_t i = 0; i < nNumRows; ++i) - { - OString aMsg = "Value at cell A" + OString::number(i+1); - nExpected = 2; - if (i == 499) // A500 must have value = 5 - nExpected = 5; - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast(m_pDoc->GetValue(0, i, 0))); - aMsg = "Value at cell B" + OString::number(i+1); - nExpected = 1; - if (i == 499) // B500 must have value = 4 - nExpected = 4; - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast(m_pDoc->GetValue(1, i, 0))); - } - - // C500 must have value = 3 - nExpected = 3; - CPPUNIT_ASSERT_EQUAL_MESSAGE("Value at cell C500", nExpected, static_cast(m_pDoc->GetValue(2, 499, 0))); - m_pDoc->DeleteTab(0); -} - -static void lcl_setupMultipleFGColumn(ScDocument* pDocument, size_t nNumRowsInBlock, size_t nNumFG, size_t nOffset) -{ - OUString aFormula; - ScAddress aAddr(1, 0, 0); - // Column B with multiple FG's - for (size_t nFGIdx = 0; nFGIdx < nNumFG; ++nFGIdx) - { - size_t nRowStart = 2*nFGIdx*nNumRowsInBlock; - for (size_t nRow = nRowStart; nRow < (nRowStart + nNumRowsInBlock); ++nRow) - { - aAddr.SetRow(nRow); - aFormula = "=$C" + OUString::number(nRow+1) + " + 0"; - pDocument->SetFormula(aAddr, aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - // Fill Column C with doubles. - pDocument->SetValue(2, nRow, 0, static_cast(nFGIdx)); - } - } - - // Column A with a single FG that depends on Column B. - size_t nNumRowsInRef = nNumRowsInBlock*2; - size_t nColAFGLen = 2*nNumRowsInBlock*nNumFG - nNumRowsInRef + 1; - aAddr.SetCol(0); - for (size_t nRow = nOffset; nRow < nColAFGLen; ++nRow) - { - aAddr.SetRow(nRow); - aFormula = "=SUM($B" + OUString::number(nRow+1) + ":$B" + OUString::number(nRow+nNumRowsInRef) + ")"; - pDocument->SetFormula(aAddr, aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - } -} - -void ScParallelismTest::testMultipleFGColumn() -{ - sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); - m_pDoc->InsertTab(0, "1"); - - constexpr size_t nNumRowsInBlock = 200; - constexpr size_t nNumFG = 50; - constexpr size_t nNumRowsInRef = nNumRowsInBlock*2; - constexpr size_t nColAFGLen = 2*nNumRowsInBlock*nNumFG - nNumRowsInRef + 1; - constexpr size_t nColAStartOffset = nNumRowsInBlock/2; - lcl_setupMultipleFGColumn(m_pDoc, nNumRowsInBlock, nNumFG, nColAStartOffset); - - m_xDocShell->DoHardRecalc(); - - OString aMsg; - // First cell in the FG in col A references nColAStartOffset cells in second formula-group of column B each having value 1. - size_t nExpected = nColAStartOffset; - size_t nIn = 0, nOut = 0; - for (size_t nRow = nColAStartOffset; nRow < nColAFGLen; ++nRow) - { - aMsg = "Value at Cell A" + OString::number(nRow+1); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast(m_pDoc->GetValue(0, nRow, 0))); - nIn = static_cast(m_pDoc->GetValue(2, nRow+nNumRowsInRef, 0)); - nOut = static_cast(m_pDoc->GetValue(2, nRow, 0)); - nExpected = nExpected + nIn - nOut; - } - - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testFormulaGroupSpanEval() -{ - sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); - m_pDoc->InsertTab(0, "1"); - - constexpr size_t nFGLen = 2048; - OUString aFormula; - - for (size_t nRow = 0; nRow < nFGLen; ++nRow) - { - aFormula = "=$C" + OUString::number(nRow+1) + " + 0"; - m_pDoc->SetFormula(ScAddress(1, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - aFormula = "=SUM($B" + OUString::number(nRow+1) + ":$B" + OUString::number(nRow+2) + ")"; - m_pDoc->SetFormula(ScAddress(0, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - m_xDocShell->DoHardRecalc(); - - for (size_t nRow = 0; nRow < nFGLen; ++nRow) - { - m_pDoc->SetValue(2, nRow, 0, 1.0); - ScFormulaCell* pFCell = m_pDoc->GetFormulaCell(ScAddress(1, nRow, 0)); - pFCell->SetDirtyVar(); - pFCell = m_pDoc->GetFormulaCell(ScAddress(0, nRow, 0)); - pFCell->SetDirtyVar(); - } - - constexpr size_t nSpanStart = 100; - constexpr size_t nSpanLen = 1024; - constexpr size_t nSpanEnd = nSpanStart + nSpanLen - 1; - - m_pDoc->SetAutoCalc(true); - - // EnsureFormulaCellResults should only calculate the specified range along with the dependent spans recursively and nothing more. - // The specified range is A99:A1124, and the dependent range is B99:B1125 (since A99 = SUM(B99:B100) and A1124 = SUM(B1124:B1125) ) - bool bAnyDirty = m_pDoc->EnsureFormulaCellResults(ScRange(0, nSpanStart, 0, 0, nSpanEnd, 0)); - CPPUNIT_ASSERT(bAnyDirty); - m_pDoc->SetAutoCalc(false); - - OString aMsg; - for (size_t nRow = 0; nRow < nFGLen; ++nRow) - { - size_t nExpectedA = 0, nExpectedB = 0; - // For nRow from 100(nSpanStart) to 1123(nSpanEnd) column A must have the value of 2 and - // column B should have value 1. - - // For nRow == 1124, column A should have value 0 and column B should have value 1. - - // For all other rows both column A and B must have value 0. - if (nRow >= nSpanStart) - { - if (nRow <= nSpanEnd) - { - nExpectedA = 2; - nExpectedB = 1; - } - else if (nRow == nSpanEnd + 1) - nExpectedB = 1; - } - - aMsg = "Value at Cell A" + OString::number(nRow+1); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpectedA, static_cast(m_pDoc->GetValue(0, nRow, 0))); - aMsg = "Value at Cell B" + OString::number(nRow+1); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpectedB, static_cast(m_pDoc->GetValue(1, nRow, 0))); - } - - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testFormulaGroupSpanEvalNonGroup() -{ - sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); - m_pDoc->InsertTab(0, "1"); - - constexpr size_t nFGLen = 2048; - OUString aFormula; - - for (size_t nRow = 0; nRow < nFGLen; ++nRow) - { - aFormula = "=$B" + OUString::number(nRow+1) + " + 0"; - m_pDoc->SetFormula(ScAddress(0, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - m_xDocShell->DoHardRecalc(); - - constexpr size_t nNumChanges = 12; - constexpr size_t nChangeRows[nNumChanges] = {10, 11, 12, 101, 102, 103, 251, 252, 253, 503, 671, 1029}; - for (size_t nIdx = 0; nIdx < nNumChanges; ++nIdx) - { - size_t nRow = nChangeRows[nIdx]; - m_pDoc->SetValue(1, nRow, 0, 1.0); - ScFormulaCell* pFCell = m_pDoc->GetFormulaCell(ScAddress(0, nRow, 0)); - pFCell->SetDirtyVar(); - } - - m_pDoc->SetAutoCalc(true); - bool bAnyDirty = m_pDoc->EnsureFormulaCellResults(ScRange(0, 9, 0, 0, 1030, 0)); - CPPUNIT_ASSERT(bAnyDirty); - m_pDoc->SetAutoCalc(false); - - OString aMsg; - for (size_t nRow = 0, nIdx = 0; nRow < nFGLen; ++nRow) - { - size_t nExpected = 0; - if (nIdx < nNumChanges && nRow == nChangeRows[nIdx]) - { - nExpected = 1; - ++nIdx; - } - - aMsg = "Value at Cell A" + OString::number(nRow+1); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast(m_pDoc->GetValue(0, nRow, 0))); - } - - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testArrayFormulaGroup() -{ - sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); - m_pDoc->InsertTab(0, "1"); - - m_pDoc->SetValue(1, 0, 0, 2.0); // B1 <== 2 - m_pDoc->SetValue(2, 0, 0, 1.0); // C1 <== 1 - OUString aFormula; - - for (size_t nRow = 1; nRow < 16; ++nRow) - { - m_pDoc->SetValue(0, nRow, 0, 1.0); // A2:A16 <== 1 - - if (nRow > 10) - continue; - - aFormula = "=SUMPRODUCT(($A" + OUString::number(1 + nRow) + - ":$A" + OUString::number(499 + nRow) + ")*B$1+C$1)"; - // Formula-group in B2:B11 with first cell = "=SUMPRODUCT(($A2:$A500)*B$1+C$1)" - m_pDoc->SetFormula(ScAddress(1, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - m_xDocShell->DoHardRecalc(); - - size_t nExpected = 529; - OString aMsg; - for (size_t nRow = 1; nRow < 11; ++nRow) - { - aMsg = "Value at Cell B" + OString::number(nRow+1); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast(m_pDoc->GetValue(1, nRow, 0))); - nExpected -= 2; - } - - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testDependentFormulaGroupCollection() -{ - sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); - m_pDoc->InsertTab(0, "1"); - - OUString aFormula; - - for (size_t nRow = 0; nRow < 16; ++nRow) - { - m_pDoc->SetValue(0, nRow, 0, 1.0); // A1:A16 <== 1 - - if (nRow > 7) - continue; - - // Formula-group in B1:B8 with first cell = "=SUM($A1:$A1024)" - aFormula = "=SUM($A" + OUString::number(1 + nRow) + - ":$A" + OUString::number(1024 + nRow) + ")"; - m_pDoc->SetFormula(ScAddress(1, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - - // Formula-group in C1:C8 with first cell = "=SUM($K1:$K1024)" - aFormula = "=SUM($K" + OUString::number(1 + nRow) + - ":$K" + OUString::number(1024 + nRow) + ")"; - m_pDoc->SetFormula(ScAddress(2, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - - // Formula-group in D1:D8 with first cell = "=SUM($A1:$A1024) - $A2" - aFormula = "=SUM($A" + OUString::number(1 + nRow) + - ":$A" + OUString::number(1024 + nRow) + ") - $A" + OUString::number(2 + nRow); - m_pDoc->SetFormula(ScAddress(3, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - - // Formula-group in K1:K8 with first cell = "=SUM($B1:$B1024)" - aFormula = "=SUM($B" + OUString::number(1 + nRow) + - ":$B" + OUString::number(1024 + nRow) + ")"; - m_pDoc->SetFormula(ScAddress(10, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - m_xDocShell->DoHardRecalc(); - - size_t nExpected[8] = { 408, 308, 224, 155, 100, 58, 28, 9 }; - - OString aMsg; - for (size_t nRow = 0; nRow < 8; ++nRow) - { - aMsg = "Value at Cell C" + OString::number(nRow+1); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected[nRow], static_cast(m_pDoc->GetValue(2, nRow, 0))); - } - - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testFormulaGroupWithForwardSelfReference() -{ - sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); - m_pDoc->InsertTab(0, "1"); - - OUString aFormula; - m_pDoc->SetValue(2, 4, 0, 10.0); // C5 <== 10 - - for (size_t nRow = 0; nRow < 4; ++nRow) - { - // Formula-group in B1:B4 with first cell = "=SUM($A1:$A1024) + C1" - aFormula = "=SUM($A" + OUString::number(1 + nRow) + - ":$A" + OUString::number(1024 + nRow) + ") + C" + OUString::number(nRow + 1); - m_pDoc->SetFormula(ScAddress(1, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - - // Formula-group in C1:C4 with first cell = "=SUM($A1:$A1024) + C2" - aFormula = "=SUM($A" + OUString::number(1 + nRow) + - ":$A" + OUString::number(1024 + nRow) + ") + C" + OUString::number(nRow + 2); - m_pDoc->SetFormula(ScAddress(2, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - m_xDocShell->DoHardRecalc(); - - OString aMsg; - for (size_t nCol = 0; nCol < 2; ++nCol) - { - for (size_t nRow = 0; nRow < 4; ++nRow) - { - aMsg = "Value at Cell (Col = " + OString::number(nCol + 1) + ", Row = " + OString::number(nRow) + ", Tab = 0)"; - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), 10.0, m_pDoc->GetValue(1 + nCol, nRow, 0)); - } - } - - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testFormulaGroupsInCyclesAndWithSelfReference() -{ - sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); - m_pDoc->InsertTab(0, "1"); - - m_pDoc->SetValue(1, 0, 0, 1.0); // B1 <== 1 - m_pDoc->SetValue(3, 0, 0, 2.0); // D1 <== 2 - OUString aFormula; - - for (size_t nRow = 0; nRow < 5; ++nRow) - { - // Formula-group in C1:C5 with first cell = "=SUM($A1:$A1024) + D1" - aFormula = "=SUM($A" + OUString::number(1 + nRow) + - ":$A" + OUString::number(1024 + nRow) + ") + D" + OUString::number(nRow + 1); - m_pDoc->SetFormula(ScAddress(2, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - - if (nRow == 0) - continue; - - // nRow starts from 1 till 4 (for D2 to D5). - // Formula-group in D2:D5 with first cell = "=SUM($A1:$A1024) + D1 + B2" - aFormula = "=SUM($A" + OUString::number(nRow) + - ":$A" + OUString::number(1023 + nRow) + ") + D" + OUString::number(nRow) + - " + B" + OUString::number(nRow + 1); - m_pDoc->SetFormula(ScAddress(3, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - - // Formula-group in B2:B5 with first cell = "=SUM($A1:$A1024) + C1 + B1" - aFormula = "=SUM($A" + OUString::number(nRow) + - ":$A" + OUString::number(1023 + nRow) + ") + C" + OUString::number(nRow) + - " + B" + OUString::number(nRow); - m_pDoc->SetFormula(ScAddress(1, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - m_xDocShell->DoHardRecalc(); - m_pDoc->SetAutoCalc(true); - - const ScRange aChangeRange(1, 1, 0, 1, 4, 0); // B2:B5 - ScMarkData aMark(m_pDoc->GetSheetLimits()); - aMark.SelectOneTable(0); - - // Set up clip document. - ScDocument aClipDoc(SCDOCMODE_CLIP); - aClipDoc.ResetClip(m_pDoc, &aMark); - // Cut B1:B2 to clipboard. - cutToClip(*m_xDocShell, aChangeRange, &aClipDoc, false); - pasteFromClip(m_pDoc, aChangeRange, &aClipDoc); - - double fExpected[3][5] = { - { 1, 3, 8, 21, 55 }, - { 2, 5, 13, 34, 89 }, - { 2, 5, 13, 34, 89 } - }; - - OString aMsg; - for (size_t nCol = 0; nCol < 3; ++nCol) - { - for (size_t nRow = 0; nRow < 5; ++nRow) - { - aMsg = "Value at Cell (Col = " + OString::number(nCol + 1) + ", Row = " + OString::number(nRow) + ", Tab = 0)"; - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), fExpected[nCol][nRow], m_pDoc->GetValue(1 + nCol, nRow, 0)); - } - } - - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testFormulaGroupsInCyclesAndWithSelfReference2() -{ - sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); - m_pDoc->InsertTab(0, "1"); - - m_pDoc->SetValue(1, 0, 0, 1.0); // B1 <== 1 - m_pDoc->SetValue(3, 0, 0, 2.0); // D1 <== 2 - m_pDoc->SetValue(4, 0, 0, 1.0); // E1 <== 1 - OUString aFormula; - - for (size_t nRow = 0; nRow < 5; ++nRow) - { - // Formula-group in C1:C5 with first cell = "=SUM($A1:$A1024) + D1 + E1" - aFormula = "=SUM($A" + OUString::number(1 + nRow) + - ":$A" + OUString::number(1024 + nRow) + ") + D" + OUString::number(nRow + 1) + - " + E" + OUString::number(nRow + 1); - m_pDoc->SetFormula(ScAddress(2, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - - if (nRow == 0) - continue; - - // Formula-group in B2:B5 with first cell = "=SUM($A1:$A1024) + C1 + B1" - aFormula = "=SUM($A" + OUString::number(nRow) + - ":$A" + OUString::number(1023 + nRow) + ") + C" + OUString::number(nRow) + - " + B" + OUString::number(nRow); - m_pDoc->SetFormula(ScAddress(1, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - - // Formula-group in D2:D5 with first cell = "=SUM($A1:$A1024) + D1 + B2" - aFormula = "=SUM($A" + OUString::number(nRow) + - ":$A" + OUString::number(1023 + nRow) + ") + D" + OUString::number(nRow) + - " + B" + OUString::number(nRow + 1); - m_pDoc->SetFormula(ScAddress(3, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - - // Formula-group in E2:E5 with first cell = "=SUM($A1:$A1024) + E1 + D2" - aFormula = "=SUM($A" + OUString::number(nRow) + - ":$A" + OUString::number(1023 + nRow) + ") + E" + OUString::number(nRow) + - " + D" + OUString::number(nRow + 1); - m_pDoc->SetFormula(ScAddress(4, nRow, 0), aFormula, - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - m_xDocShell->DoHardRecalc(); - - double fExpected[4][5] = { - { 1, 4, 17, 70, 286 }, - { 3, 13, 53, 216, 881 }, - { 2, 6, 23, 93, 379 }, - { 1, 7, 30, 123, 502 } - }; - - OString aMsg; - for (size_t nCol = 0; nCol < 4; ++nCol) - { - for (size_t nRow = 0; nRow < 5; ++nRow) - { - aMsg = "Value at Cell (Col = " + OString::number(nCol + 1) + ", Row = " + OString::number(nRow) + ", Tab = 0)"; - CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), fExpected[nCol][nRow], m_pDoc->GetValue(1 + nCol, nRow, 0)); - } - } - - m_pDoc->DeleteTab(0); -} - -void ScParallelismTest::testFormulaGroupsInCyclesAndWithSelfReference3() -{ - sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); - m_pDoc->InsertTab(0, "1"); - - m_pDoc->SetValue(1, 1, 0, 2.0); // B2 <== 2 - for (size_t nRow = 1; nRow < 105; ++nRow) - { - // Formula-group in B3:B104 with first cell "=D2+0.001" - if( nRow != 1 ) - m_pDoc->SetFormula(ScAddress(1, nRow, 0), "=D" + OUString::number(nRow) + "+0.001", - formula::FormulaGrammar::GRAM_NATIVE_UI); - // Formula-group in C2:C104 with first cell "=B2*1.01011" - m_pDoc->SetFormula(ScAddress(2, nRow, 0), "=B" + OUString::number(nRow + 1) + "*1.01011", - formula::FormulaGrammar::GRAM_NATIVE_UI); - // Formula-group in D2:C104 with first cell "=C2*1.02" - m_pDoc->SetFormula(ScAddress(3, nRow, 0), "=C" + OUString::number(nRow + 1) + "*1.02", - formula::FormulaGrammar::GRAM_NATIVE_UI); - } - - m_xDocShell->DoHardRecalc(); - - // What happens with tdf#132451 is that the copy&paste C6->C5 really just sets the dirty flag - // for C5 and all the cells that depend on it (D5,B6,C6,D6,B7,...), and it also resets - // flags marking the C formula group as disabled for parallel calculation because of the cycle. - m_pDoc->SetFormula(ScAddress(2, 4, 0), "=B5*1.01011", formula::FormulaGrammar::GRAM_NATIVE_UI); - m_pDoc->GetFormulaCell(ScAddress(2,4,0))->GetCellGroup()->mbPartOfCycle = false; - m_pDoc->GetFormulaCell(ScAddress(2,4,0))->GetCellGroup()->meCalcState = sc::GroupCalcEnabled; - - m_pDoc->SetAutoCalc(true); - // Without the fix, getting value of C5 would try to parallel-interpret formula group in B - // from its first dirty cell (B6), which depends on D5, which depends on C5, where the cycle - // would be detected and dependency check would bail out. But the result from Interpret()-ing - // D5 would be used and D5's dirty flag reset, with D5 value incorrect. - m_pDoc->GetValue(2,4,0); - - double fExpected[2][3] = { - { 2.19053373572776, 2.21268003179597, 2.25693363243189 }, - { 2.25793363243189, 2.28076134145577, 2.32637656828489 } - }; - for (size_t nCol = 1; nCol < 4; ++nCol) - { - for (size_t nRow = 4; nRow < 6; ++nRow) - { - OString aMsg = "Value at Cell (Col = " + OString::number(nCol) + ", Row = " + OString::number(nRow) + ", Tab = 0)"; - ASSERT_DOUBLES_EQUAL_MESSAGE(aMsg.getStr(), fExpected[nRow - 4][nCol - 1], m_pDoc->GetValue(nCol, nRow, 0)); - } - } - - m_pDoc->DeleteTab(0); -} - -CPPUNIT_TEST_SUITE_REGISTRATION(ScParallelismTest); - -CPPUNIT_PLUGIN_IMPLEMENT(); - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/range.cxx b/sc/qa/unit/range.cxx deleted file mode 100644 index 30f8a1f8cc3c..000000000000 --- a/sc/qa/unit/range.cxx +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- 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 -#include "helper/qahelper.hxx" -#include -#include -#include -#include -#include - -#include -#include -#include - -class ScRangeTest : public ScSimpleBootstrapFixture -{ -public: - CPPUNIT_TEST_SUITE(ScRangeTest); - CPPUNIT_TEST(testOverlap); - CPPUNIT_TEST(testRangeParsing); - CPPUNIT_TEST(testAddressParsing); - CPPUNIT_TEST(testTdf147451); - CPPUNIT_TEST_SUITE_END(); - - void testOverlap(); - void testRangeParsing(); - void testAddressParsing(); - void testTdf147451(); -}; - -void ScRangeTest::testOverlap() -{ - ScRange aRange1( ScAddress( 0, 0, 0 ), ScAddress( 1, 1, 1 )); - CPPUNIT_ASSERT(aRange1.Contains( ScAddress( 0, 0, 0 ))); - CPPUNIT_ASSERT(aRange1.Contains( ScAddress( 1, 1, 1 ))); - CPPUNIT_ASSERT(!aRange1.Contains( ScAddress( 2, 1, 1 ))); - CPPUNIT_ASSERT(!aRange1.Contains( ScAddress( 1, 2, 1 ))); - CPPUNIT_ASSERT(!aRange1.Contains( ScAddress( 1, 1, 2 ))); - - ScRange aRange2( ScAddress( 0, 0, 0 ), ScAddress( 10, 10, 10 )); - ScRange aRange3( ScAddress( 5, 5, 5 ), ScAddress( 15, 15, 15 )); - CPPUNIT_ASSERT(!aRange2.Contains( aRange3 )); - CPPUNIT_ASSERT(!aRange3.Contains( aRange2 )); - CPPUNIT_ASSERT(aRange2.Intersects( aRange3 )); - CPPUNIT_ASSERT(aRange3.Intersects( aRange2 )); - CPPUNIT_ASSERT(!aRange3.Intersects( aRange1 )); - CPPUNIT_ASSERT(!aRange1.Intersects( aRange3 )); -} - -void ScRangeTest::testRangeParsing() -{ - ScRange aRange; - ScRefFlags nRes = aRange.Parse(":1", *m_pDoc, formula::FormulaGrammar::CONV_OOO); - CPPUNIT_ASSERT_MESSAGE("Should fail to parse.", !(nRes & ScRefFlags::VALID)); -} - -void ScRangeTest::testAddressParsing() -{ - ScAddress aAddr; - ScRefFlags nRes = aAddr.Parse("1", *m_pDoc, formula::FormulaGrammar::CONV_OOO); - CPPUNIT_ASSERT_MESSAGE("Should fail to parse.", !(nRes & ScRefFlags::VALID)); -} - -void ScRangeTest::testTdf147451() -{ - ScAddress aAddr; - // "Sheet1" is technically a valid address like "XF1", but it should overflow. - ScRefFlags nRes = aAddr.Parse("Sheet1", *m_pDoc, formula::FormulaGrammar::CONV_OOO); - CPPUNIT_ASSERT_MESSAGE("Should fail to parse.", !(nRes & ScRefFlags::VALID)); -} - -class ScRangeUpdaterTest : public CppUnit::TestFixture -{ -public: - - virtual void setUp() override - { - utl::ConfigManager::EnableFuzzing(); - ScDLL::Init(); - ScGlobal::Init(); - } - void testUpdateInsertTabBeforePos(); - void testUpdateInsertTabAtPos(); - void testUpdateInsertTabAfterPos(); - void testUpdateDeleteTabBeforePos(); - void testUpdateDeleteTabAtPos(); - void testUpdateDeleteTabAfterPos(); - - CPPUNIT_TEST_SUITE(ScRangeUpdaterTest); - CPPUNIT_TEST(testUpdateInsertTabBeforePos); - CPPUNIT_TEST(testUpdateInsertTabAtPos); - CPPUNIT_TEST(testUpdateInsertTabAfterPos); - CPPUNIT_TEST(testUpdateDeleteTabBeforePos); - CPPUNIT_TEST(testUpdateDeleteTabAtPos); - CPPUNIT_TEST(testUpdateDeleteTabAfterPos); - CPPUNIT_TEST_SUITE_END(); -}; - -void ScRangeUpdaterTest::testUpdateInsertTabBeforePos() -{ - ScDocument aDoc; - ScAddress aAddr(1, 1, 1); - sc::RefUpdateInsertTabContext aContext(aDoc, 0, 1); - ScRangeUpdater::UpdateInsertTab(aAddr, aContext); - CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 2), aAddr); -} - -void ScRangeUpdaterTest::testUpdateInsertTabAtPos() -{ - ScDocument aDoc; - ScAddress aAddr(1, 1, 1); - sc::RefUpdateInsertTabContext aContext(aDoc, 1, 1); - ScRangeUpdater::UpdateInsertTab(aAddr, aContext); - CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 2), aAddr); -} - -void ScRangeUpdaterTest::testUpdateInsertTabAfterPos() -{ - ScDocument aDoc; - ScAddress aAddr(1, 1, 1); - sc::RefUpdateInsertTabContext aContext(aDoc, 2, 1); - ScRangeUpdater::UpdateInsertTab(aAddr, aContext); - CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 1), aAddr); -} - -void ScRangeUpdaterTest::testUpdateDeleteTabBeforePos() -{ - ScDocument aDoc; - ScAddress aAddr(1, 1, 1); - sc::RefUpdateDeleteTabContext aContext(aDoc, 0, 1); - ScRangeUpdater::UpdateDeleteTab(aAddr, aContext); - CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 0), aAddr); -} - -void ScRangeUpdaterTest::testUpdateDeleteTabAtPos() -{ - ScDocument aDoc; - - // Position within deleted range is moved to the front. - { - ScAddress aAddr(1, 1, 1); - sc::RefUpdateDeleteTabContext aContext(aDoc, 1, 1); - ScRangeUpdater::UpdateDeleteTab(aAddr, aContext); - CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 0), aAddr); - } - { - ScAddress aAddr(1, 1, 2); - sc::RefUpdateDeleteTabContext aContext(aDoc, 1, 2); - ScRangeUpdater::UpdateDeleteTab(aAddr, aContext); - CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 0), aAddr); - } - - // Would-be negative results are clamped to 0. - { - ScAddress aAddr(1, 1, 0); - sc::RefUpdateDeleteTabContext aContext(aDoc, 0, 1); - ScRangeUpdater::UpdateDeleteTab(aAddr, aContext); - CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 0), aAddr); - } - { - ScAddress aAddr(1, 1, 1); - sc::RefUpdateDeleteTabContext aContext(aDoc, 0, 2); - ScRangeUpdater::UpdateDeleteTab(aAddr, aContext); - CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 0), aAddr); - } -} - -void ScRangeUpdaterTest::testUpdateDeleteTabAfterPos() -{ - ScDocument aDoc; - ScAddress aAddr(1, 1, 1); - sc::RefUpdateDeleteTabContext aContext(aDoc, 2, 1); - ScRangeUpdater::UpdateDeleteTab(aAddr, aContext); - CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 1), aAddr); -} - -CPPUNIT_TEST_SUITE_REGISTRATION(ScRangeTest); -CPPUNIT_TEST_SUITE_REGISTRATION(ScRangeUpdaterTest); - -CPPUNIT_PLUGIN_IMPLEMENT(); - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/rangelst_test.cxx b/sc/qa/unit/rangelst_test.cxx deleted file mode 100644 index 48d95dddfcbc..000000000000 --- a/sc/qa/unit/rangelst_test.cxx +++ /dev/null @@ -1,554 +0,0 @@ -/* -*- 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 -#include "helper/qahelper.hxx" -#include - -#include - -class Test : public ScSimpleBootstrapFixture -{ -public: - void testDeleteArea_4Ranges(); - void testDeleteArea_3Ranges(); - void testDeleteArea_3Ranges_Case2(); - void testDeleteArea_3Ranges_Case3(); - void testDeleteArea_3Ranges_Case4(); - void testDeleteArea_3Ranges_Case5(); - void testDeleteArea_2Ranges(); - void testDeleteArea_2Ranges_Case2(); - void testDeleteArea_2Ranges_Case3(); - void testDeleteArea_2Ranges_Case4(); - void testDeleteArea_2Ranges_Case5(); - void testDeleteArea_2Ranges_Case6(); - void testDeleteArea_2Ranges_Case7(); - void testDeleteArea_2Ranges_Case8(); - void testDeleteArea_1Range(); - void testDeleteArea_0Ranges(); - void testJoin_Case1(); - void testJoin_Case2(); - void testJoin_Case3(); - void testJoin_Case4(); - void testJoin_Case5(); - void testGetIntersectedRange(); - - void testUpdateReference_DeleteRow(); - void testUpdateReference_DeleteLastRow(); - void testUpdateReference_DeleteCol(); - - void testInsertRow(); - void testInsertCol(); - - CPPUNIT_TEST_SUITE(Test); - CPPUNIT_TEST(testDeleteArea_4Ranges); - CPPUNIT_TEST(testDeleteArea_3Ranges); - CPPUNIT_TEST(testDeleteArea_3Ranges_Case2); - CPPUNIT_TEST(testDeleteArea_3Ranges_Case3); - CPPUNIT_TEST(testDeleteArea_3Ranges_Case4); - CPPUNIT_TEST(testDeleteArea_3Ranges_Case5); - CPPUNIT_TEST(testDeleteArea_2Ranges); - CPPUNIT_TEST(testDeleteArea_2Ranges_Case2); - CPPUNIT_TEST(testDeleteArea_2Ranges_Case3); - CPPUNIT_TEST(testDeleteArea_2Ranges_Case4); - CPPUNIT_TEST(testDeleteArea_2Ranges_Case5); - CPPUNIT_TEST(testDeleteArea_2Ranges_Case6); - CPPUNIT_TEST(testDeleteArea_2Ranges_Case7); - CPPUNIT_TEST(testDeleteArea_2Ranges_Case8); - CPPUNIT_TEST(testDeleteArea_1Range); - CPPUNIT_TEST(testDeleteArea_0Ranges); - CPPUNIT_TEST(testJoin_Case1); - CPPUNIT_TEST(testJoin_Case2); - CPPUNIT_TEST(testJoin_Case3); - CPPUNIT_TEST(testJoin_Case4); - CPPUNIT_TEST(testJoin_Case5); - CPPUNIT_TEST(testUpdateReference_DeleteRow); - CPPUNIT_TEST(testUpdateReference_DeleteLastRow); - CPPUNIT_TEST(testUpdateReference_DeleteCol); - CPPUNIT_TEST(testGetIntersectedRange); - CPPUNIT_TEST(testInsertRow); - CPPUNIT_TEST(testInsertCol); - CPPUNIT_TEST_SUITE_END(); -}; - -void Test::testDeleteArea_4Ranges() -{ - ScRangeList aList(ScRange(0,0,0,5,5,0)); - aList.DeleteArea(2,2,0,3,3,0); - - CPPUNIT_ASSERT_EQUAL(static_cast(4), aList.size()); - for(SCCOL nCol = 0; nCol <= 5; ++nCol) - { - for(SCROW nRow = 0; nRow <= 5; ++nRow) - { - if((nCol == 2 || nCol == 3) && ( nRow == 2 || nRow == 3)) - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); - } - } -} - -void Test::testDeleteArea_3Ranges() -{ - ScRangeList aList(ScRange(1,1,0,6,6,0)); - aList.DeleteArea(3,3,0,8,4,0); - - CPPUNIT_ASSERT_EQUAL(static_cast(3), aList.size()); - for(SCCOL nCol = 1; nCol <= 6; ++nCol) - { - for(SCROW nRow = 1; nRow <= 6; ++nRow) - { - if((nRow == 3 || nRow == 4) && (nCol >= 3)) - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); - } - } - - CPPUNIT_ASSERT_EQUAL(static_cast(28), aList.GetCellCount()); -} - -void Test::testDeleteArea_3Ranges_Case2() -{ - ScRangeList aList(ScRange(1,1,0,6,6,0)); - CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); - aList.DeleteArea(0,2,0,2,4,0); - CPPUNIT_ASSERT_EQUAL(static_cast(3), aList.size()); - - // Column 1-2 && Row 2-4 should not be in the range list. The rest should - // be in the list. - for (SCCOL nCol = 1; nCol <= 6; ++nCol) - { - for (SCROW nRow = 1; nRow <= 6; ++nRow) - { - if ((1 <= nCol && nCol <= 2) && (2 <= nRow && nRow <= 4)) - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); - } - } -} - -void Test::testDeleteArea_3Ranges_Case3() -{ - ScRangeList aList(ScRange(1,5,0,6,11,0)); - CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); - aList.DeleteArea(3,2,0,4,8,0); - CPPUNIT_ASSERT_EQUAL(static_cast(3), aList.size()); - - // Column 3-4 && Row 5-8 should not be in the range list. - for (SCCOL nCol = 1; nCol <= 6; ++nCol) - { - for (SCROW nRow = 5; nRow <= 11; ++nRow) - { - if ((3 <= nCol && nCol <= 4) && (5 <= nRow && nRow <= 8)) - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); - } - } -} - -void Test::testDeleteArea_3Ranges_Case4() -{ - ScRangeList aList(ScRange(1,5,0,6,11,0)); - CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); - aList.DeleteArea(3,5,0,4,5,0); - CPPUNIT_ASSERT_EQUAL(static_cast(3), aList.size()); - - // Column 3-4 && Row 5 should not be in the range list. - for (SCCOL nCol = 1; nCol <= 6; ++nCol) - { - for (SCROW nRow = 5; nRow <= 11; ++nRow) - { - if ((3 <= nCol && nCol <= 4) && 5 == nRow ) - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); - } - } -} - -void Test::testDeleteArea_3Ranges_Case5() -{ - ScRangeList aList(ScRange(1,5,0,6,11,0)); - CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); - aList.DeleteArea(6,7,0,6,9,0); - CPPUNIT_ASSERT_EQUAL(static_cast(3), aList.size()); - - // Column 6 && Row 7-9 should not be in the range list. - for (SCCOL nCol = 1; nCol <= 6; ++nCol) - { - for (SCROW nRow = 5; nRow <= 11; ++nRow) - { - if ( nCol == 6 && (7 <= nRow && nRow <= 9)) - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); - } - } -} - -void Test::testDeleteArea_2Ranges() -{ - ScRangeList aList(ScRange(0,0,0,5,5,5)); - ScRangeList aList2(aList); - - aList.DeleteArea(4,4,0,6,7,0); - aList2.DeleteArea(4,4,0,6,7,0); - CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); - CPPUNIT_ASSERT_EQUAL(static_cast(2), aList2.size()); - - for(SCCOL nCol = 0; nCol <= 5; ++nCol) - { - for(SCROW nRow = 0; nRow <= 5; ++nRow) - { - if(nCol>=4 && nRow >= 4) - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); - } - } -} - -void Test::testDeleteArea_2Ranges_Case2() -{ - ScRangeList aList(ScRange(1,1,0,1,5,0)); - aList.DeleteArea(0,3,0,ScSheetLimits::CreateDefault().MaxCol(),3,0); - - for(SCROW nRow = 1; nRow <= 5; ++nRow) - { - if(nRow == 3) - CPPUNIT_ASSERT(!aList.Contains(ScRange(1,3,0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(1,nRow,0))); - } - CPPUNIT_ASSERT_EQUAL(static_cast(4), aList.GetCellCount()); -} - -void Test::testDeleteArea_2Ranges_Case3() -{ - ScRangeList aList(ScRange(0,5,0,2,10,0)); - aList.DeleteArea(2,3,0,3,7,0); - CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); - - // Column 2 Row 5-7 shouldn't be in the list. - for (SCCOL nCol = 0; nCol <= 2; ++nCol) - { - for (SCROW nRow = 5; nRow <= 10; ++nRow) - { - if (nCol == 2 && (5 <= nRow && nRow <= 7)) - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol,nRow,0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol,nRow,0))); - } - } -} - -void Test::testDeleteArea_2Ranges_Case4() -{ - ScRangeList aList(ScRange(2,3,0,4,7,0)); - aList.DeleteArea(0,1,0,2,5,0); - CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); - - // Column 2 Row 3-5 shouldn't be in the list. - for (SCCOL nCol = 2; nCol <= 4; ++nCol) - { - for (SCROW nRow = 3; nRow <= 7; ++nRow) - { - if (nCol == 2 && (3 <= nRow && nRow <= 5)) - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol,nRow,0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol,nRow,0))); - } - } -} - -void Test::testDeleteArea_2Ranges_Case5() -{ - ScRangeList aList(ScRange(2,2,0,5,5,0)); - aList.DeleteArea(4,5,0,5,5,0); - CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); - - // Column 4 and 5 Row 5 shouldn't be in the list. - for(SCCOL nCol = 2; nCol <= 5; ++nCol) - { - for(SCROW nRow = 2; nRow <= 5; ++nRow) - { - if(nRow == 5 && 4 <= nCol) - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); - } - } -} - -void Test::testDeleteArea_2Ranges_Case6() -{ - ScRangeList aList(ScRange(2,2,0,5,5,0)); - aList.DeleteArea(4,2,0,5,2,0); - CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); - - // Column 4 and 5 Row 2 shouldn't be in the list. - for(SCCOL nCol = 2; nCol <= 5; ++nCol) - { - for(SCROW nRow = 2; nRow <= 5; ++nRow) - { - if(nRow == 2 && 4 <= nCol) - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); - } - } -} - -void Test::testDeleteArea_2Ranges_Case7() -{ - ScRangeList aList(ScRange(2,2,0,5,5,0)); - aList.DeleteArea(2,5,0,2,5,0); - CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); - - // Column 2 Row 5 shouldn't be in the list. - for(SCCOL nCol = 2; nCol <= 5; ++nCol) - { - for(SCROW nRow = 2; nRow <= 5; ++nRow) - { - if(nRow == 5 && nCol == 2) - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); - } - } -} - -void Test::testDeleteArea_2Ranges_Case8() -{ - ScRangeList aList(ScRange(2,2,0,5,5,0)); - aList.DeleteArea(2,2,0,3,2,0); - CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); - - // Column 2 & 3 Row 2 shouldn't be in the list. - for(SCCOL nCol = 2; nCol <= 5; ++nCol) - { - for(SCROW nRow = 2; nRow <= 5; ++nRow) - { - if(nRow == 2 && nCol <= 3) - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); - else - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); - } - } -} - -void Test::testDeleteArea_1Range() -{ - ScRangeList aList(ScRange(1,1,0,3,3,0)); - aList.DeleteArea(1,1,0,2,3,0); - - CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); - - for(SCROW nRow = 1; nRow <= 3; ++nRow) - { - CPPUNIT_ASSERT(aList.Contains(ScRange(3,nRow,0))); - } - CPPUNIT_ASSERT_EQUAL(static_cast(3), aList.GetCellCount()); -} - -void Test::testDeleteArea_0Ranges() -{ - ScRangeList aList(ScRange(1,1,0,3,3,0)); - aList.DeleteArea(1,1,0,3,3,0); - - CPPUNIT_ASSERT(aList.empty()); - - ScRangeList aList2(ScRange(1,1,0,3,3,0)); - aList2.DeleteArea(0,0,0,4,4,0); - - CPPUNIT_ASSERT(aList.empty()); -} - -void Test::testJoin_Case1() -{ - ScRangeList aList; - aList.push_back(ScRange(1,1,0,3,3,0)); - aList.Join(ScRange(4,1,0,6,3,0)); - - CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); - CPPUNIT_ASSERT_EQUAL( ScRange(1,1,0,6,3,0), aList[0]); -} - -void Test::testJoin_Case2() -{ - ScRangeList aList; - aList.push_back(ScRange(1,1,0,3,3,0)); - aList.push_back(ScRange(4,1,0,6,3,0)); - aList.push_back(ScRange(7,1,0,9,3,0)); - - aList.Join(aList[2], true); - - CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); - CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,9,3,0), aList[0]); -} - -void Test::testJoin_Case3() -{ - ScRangeList aList; - aList.Join(ScRange(1,1,0,6,6,0)); - aList.Join(ScRange(3,3,0,4,4,0)); - - // The second one should have been swallowed by the first one - CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); - CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,6,6,0), aList[0]); - - // Add a disjoint one - aList.Join(ScRange(8,8,0,9,9,0)); - - // Should be two ones now - CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); - // The first one should still be as is - CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,6,6,0), aList[0]); - // Ditto for the second one - CPPUNIT_ASSERT_EQUAL(ScRange(8,8,0,9,9,0), aList[1]); -} - -void Test::testJoin_Case4() -{ - ScRangeList aList; - aList.Join(ScRange(1,1,0,2,6,0)); - // Join a range that overlaps it and extends it vertically - aList.Join(ScRange(1,4,0,2,8,0)); - - // The one range in the list should have been extended - CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); - CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,2,8,0), aList[0]); - - // Join a range that overlaps it and extends it horizontally - aList.Join(ScRange(2,1,0,4,8,0)); - - // Again, should have just been extended - CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); - CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,4,8,0), aList[0]); - - // And then the same but on top / to the left of existing range - ScRangeList aList2; - aList2.Join(ScRange(4,4,0,8,8,0)); - aList2.Join(ScRange(4,1,0,8,6,0)); - - CPPUNIT_ASSERT_EQUAL(static_cast(1), aList2.size()); - CPPUNIT_ASSERT_EQUAL(ScRange(4,1,0,8,8,0), aList2[0]); - - aList2.Join(ScRange(1,1,0,6,8,0)); - - CPPUNIT_ASSERT_EQUAL(static_cast(1), aList2.size()); - CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,8,8,0), aList2[0]); -} - -void Test::testJoin_Case5() -{ - ScRangeList aList; - aList.Join(ScRange(0,0,0,4,4,0)); - aList.Join(ScRange(8,0,0,10,4,0)); - - // Nothing special so far, two disjoint ranges - CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); - CPPUNIT_ASSERT_EQUAL(ScRange(0,0,0,4,4,0), aList[0]); - CPPUNIT_ASSERT_EQUAL(ScRange(8,0,0,10,4,0), aList[1]); - - // This should join the two ranges into one - aList.Join(ScRange(5,0,0,9,4,0)); - - CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); - CPPUNIT_ASSERT_EQUAL(ScRange(0,0,0,10,4,0), aList[0]); -} - -void Test::testUpdateReference_DeleteRow() -{ - ScRangeList aList(ScRange(1,1,0,4,4,0)); - bool bUpdated = aList.UpdateReference(URM_INSDEL, m_pDoc, ScRange(0,3,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0), 0, -1, 0); - CPPUNIT_ASSERT(bUpdated); - - for(SCCOL nCol = 1; nCol <= 4; ++nCol) - { - for(SCROW nRow = 1; nRow <= 3; ++nRow) - { - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); - } - CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, 4, 0))); - } - CPPUNIT_ASSERT_EQUAL(static_cast(12), aList.GetCellCount()); - - ScRangeList aList2(ScRange(2,2,0,2,2,0)); - aList2.UpdateReference(URM_INSDEL, m_pDoc, ScRange(0,3,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0), 0, -1, 0); - CPPUNIT_ASSERT(aList2.empty()); - - ScRangeList aList3; - aList3.push_back(ScRange(2,2,0,2,8,0)); - aList3.push_back(ScRange(4,2,0,4,8,0)); - aList3.UpdateReference(URM_INSDEL, m_pDoc, ScRange(2,5,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0), 0, -1, 0); - // Verify all ranges in the list have been updated properly. - CPPUNIT_ASSERT_EQUAL(size_t(2), aList3.size()); - CPPUNIT_ASSERT_EQUAL(ScRange(2,2,0,2,7,0), aList3[0]); - CPPUNIT_ASSERT_EQUAL(ScRange(4,2,0,4,7,0), aList3[1]); - - ScRangeList aList4(ScRange(0,0,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0)); - ScRangeList aList4Copy = aList4; - aList4.UpdateReference(URM_INSDEL, m_pDoc, ScRange(14,3,0,m_pDoc->MaxCol(),7,0), 0, -2, 0); - CPPUNIT_ASSERT_EQUAL(aList4Copy, aList4); -} - -void Test::testUpdateReference_DeleteLastRow() -{ - ScRangeList aList(ScRange(1,1,0,4,4,0)); - bool bUpdated = aList.UpdateReference(URM_INSDEL, m_pDoc, ScRange(0,4,0,m_pDoc->MaxCol(),4,0), 0, -1, 0); - CPPUNIT_ASSERT(bUpdated); -} - -void Test::testUpdateReference_DeleteCol() -{ - ScRangeList aList(ScRange(1,1,0,4,4,0)); - bool bUpdated = aList.UpdateReference(URM_INSDEL, m_pDoc, ScRange(3,0,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0), -1, 0, 0); - CPPUNIT_ASSERT(bUpdated); - - for(SCROW nRow = 1; nRow <= 4; ++nRow) - { - for(SCCOL nCol = 1; nCol <= 3; ++nCol) - { - CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); - } - CPPUNIT_ASSERT(!aList.Contains(ScRange(4, nRow, 0))); - } - CPPUNIT_ASSERT_EQUAL(static_cast(12), aList.GetCellCount()); -} - -void Test::testGetIntersectedRange() -{ - ScRangeList aList(ScRange(2, 2, 0, 5, 5, 0)); - ScRangeList aIntersecting = aList.GetIntersectedRange(ScRange(0, 0, 0, 3, 3, 0)); - CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(2,2,0,3,3,0)), aIntersecting); -} - -void Test::testInsertRow() -{ - ScRangeList aList(ScRange(1,1,0,4,4,0)); - aList.InsertRow(0, 0, m_pDoc->MaxCol(), 5, 2); - CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(1,1,0,4,6,0)), aList); -} - -void Test::testInsertCol() -{ - ScRangeList aList(ScRange(1,1,0,4,4,0)); - aList.InsertCol(0, 0, m_pDoc->MaxRow(), 5, 2); - CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(1,1,0,6,4,0)), aList); -} - -CPPUNIT_TEST_SUITE_REGISTRATION(Test); - -CPPUNIT_PLUGIN_IMPLEMENT(); -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/ucalc_datatransformation.cxx b/sc/qa/unit/ucalc_datatransformation.cxx new file mode 100644 index 000000000000..7f33aa21548a --- /dev/null +++ b/sc/qa/unit/ucalc_datatransformation.cxx @@ -0,0 +1,1005 @@ +/* -*- 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 + +#include "helper/qahelper.hxx" +#include +#include +#include +#include + +class ScDataTransformationTest : public ScSimpleBootstrapFixture +{ +public: + + virtual void setUp() override; + + void testColumnRemove(); + void testColumnSplit(); + void testColumnMerge(); + void testTextToLower(); + void testTextToUpper(); + void testTextCapitalize(); + void testTextTrim(); + void testAggregateSum(); + void testAggregateAverage(); + void testAggregateMin(); + void testAggregateMax(); + void testNumberRound(); + void testNumberRoundUp(); + void testNumberRoundDown(); + void testNumberAbsolute(); + void testNumberLogE(); + void testNumberLog10(); + void testNumberCube(); + void testNumberSquare(); + void testNumberSquareRoot(); + void testNumberEven(); + void testNumberOdd(); + void testNumberSign(); + void testReplaceNull(); + void testGetDateString(); + void testGetYear(); + void testGetStartOfYear(); + void testGetEndOfYear(); + void testGetMonth(); + void testGetMonthName(); + void testGetStartOfMonth(); + void testGetEndOfMonth(); + void testGetDay(); + void testGetDayOfWeek(); + void testGetDayOfYear(); + void testGetQuarter(); + void testGetStartOfQuarter(); + void testGetEndOfQuarter(); + void testGetTime(); + void testGetHour(); + void testGetMinute(); + void testGetSecond(); + + CPPUNIT_TEST_SUITE(ScDataTransformationTest); + CPPUNIT_TEST(testColumnRemove); + CPPUNIT_TEST(testColumnSplit); + CPPUNIT_TEST(testColumnMerge); + CPPUNIT_TEST(testTextToLower); + CPPUNIT_TEST(testTextToUpper); + CPPUNIT_TEST(testTextCapitalize); + CPPUNIT_TEST(testTextTrim); + CPPUNIT_TEST(testAggregateSum); + CPPUNIT_TEST(testAggregateAverage); + CPPUNIT_TEST(testAggregateMin); + CPPUNIT_TEST(testAggregateMax); + CPPUNIT_TEST(testNumberRound); + CPPUNIT_TEST(testNumberRoundUp); + CPPUNIT_TEST(testNumberRoundDown); + CPPUNIT_TEST(testNumberAbsolute); + CPPUNIT_TEST(testNumberLogE); + CPPUNIT_TEST(testNumberLog10); + CPPUNIT_TEST(testNumberCube); + CPPUNIT_TEST(testNumberSquare); + CPPUNIT_TEST(testNumberSquareRoot); + CPPUNIT_TEST(testNumberEven); + CPPUNIT_TEST(testNumberOdd); + CPPUNIT_TEST(testNumberSign); + CPPUNIT_TEST(testReplaceNull); + CPPUNIT_TEST(testGetDateString); + CPPUNIT_TEST(testGetYear); + CPPUNIT_TEST(testGetStartOfYear); + CPPUNIT_TEST(testGetEndOfYear); + CPPUNIT_TEST(testGetMonth); + CPPUNIT_TEST(testGetMonthName); + CPPUNIT_TEST(testGetStartOfMonth); + CPPUNIT_TEST(testGetEndOfMonth); + CPPUNIT_TEST(testGetDay); + CPPUNIT_TEST(testGetDayOfWeek); + CPPUNIT_TEST(testGetDayOfYear); + CPPUNIT_TEST(testGetQuarter); + CPPUNIT_TEST(testGetStartOfQuarter); + CPPUNIT_TEST(testGetEndOfQuarter); + CPPUNIT_TEST(testGetTime); + CPPUNIT_TEST(testGetHour); + CPPUNIT_TEST(testGetMinute); + CPPUNIT_TEST(testGetSecond); + CPPUNIT_TEST_SUITE_END(); +}; + +void ScDataTransformationTest::testColumnRemove() +{ + for (SCROW nRow = 0; nRow < 10; ++nRow) + { + for (SCCOL nCol = 0; nCol < 10; ++nCol) + { + m_pDoc->SetValue(nCol, nRow, 0, nRow*nCol); + } + } + + sc::ColumnRemoveTransformation aTransformation({5}); + aTransformation.Transform(*m_pDoc); + + for (SCROW nRow = 0; nRow < 10; ++nRow) + { + for (SCCOL nCol = 0; nCol < 9; ++nCol) + { + double nVal = m_pDoc->GetValue(nCol, nRow, 0); + if (nCol < 5) + { + ASSERT_DOUBLES_EQUAL(static_cast(nCol)*nRow, nVal); + } + else + { + ASSERT_DOUBLES_EQUAL(static_cast(nCol+1)*nRow, nVal); + } + } + } +} + +void ScDataTransformationTest::testColumnSplit() +{ + m_pDoc->SetString(2, 0, 0, "Test1,Test2"); + m_pDoc->SetString(2, 1, 0, "Test1,"); + m_pDoc->SetString(2, 2, 0, ",Test1"); + m_pDoc->SetString(2, 3, 0, "Test1,Test2,Test3"); + m_pDoc->SetString(3, 0, 0, "AnotherString"); + + sc::SplitColumnTransformation aTransform(2, ','); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("AnotherString"), m_pDoc->GetString(4, 0, 0)); + + CPPUNIT_ASSERT_EQUAL(OUString("Test1"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Test1"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString(""), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Test1"), m_pDoc->GetString(2, 3, 0)); + + CPPUNIT_ASSERT_EQUAL(OUString("Test2"), m_pDoc->GetString(3, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString(""), m_pDoc->GetString(3, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Test1"), m_pDoc->GetString(3, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Test2,Test3"), m_pDoc->GetString(3, 3, 0)); +} + +void ScDataTransformationTest::testColumnMerge() +{ + m_pDoc->SetString(2, 0, 0, "Berlin"); + m_pDoc->SetString(2, 1, 0, "Brussels"); + m_pDoc->SetString(2, 2, 0, "Paris"); + m_pDoc->SetString(2, 3, 0, "Peking"); + + m_pDoc->SetString(4, 0, 0, "Germany"); + m_pDoc->SetString(4, 1, 0, "Belgium"); + m_pDoc->SetString(4, 2, 0, "France"); + m_pDoc->SetString(4, 3, 0, "China"); + + sc::MergeColumnTransformation aTransform({2, 4}, ", "); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("Berlin, Germany"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Brussels, Belgium"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Paris, France"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Peking, China"), m_pDoc->GetString(2, 3, 0)); + + for (SCROW nRow = 0; nRow <= 3; ++nRow) + { + CPPUNIT_ASSERT(m_pDoc->GetString(4, nRow, 0).isEmpty()); + } +} + +void ScDataTransformationTest::testTextToLower() +{ + m_pDoc->SetString(2, 0, 0, "Berlin"); + m_pDoc->SetString(2, 1, 0, "Brussels"); + m_pDoc->SetString(2, 2, 0, "Paris"); + m_pDoc->SetString(2, 3, 0, "Peking"); + + sc::TextTransformation aTransform({2}, sc::TEXT_TRANSFORM_TYPE::TO_LOWER); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("berlin"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("brussels"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("paris"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("peking"), m_pDoc->GetString(2, 3, 0)); +} + +void ScDataTransformationTest::testTextToUpper() +{ + m_pDoc->SetString(2, 0, 0, "Berlin"); + m_pDoc->SetString(2, 1, 0, "Brussels"); + m_pDoc->SetString(2, 2, 0, "Paris"); + m_pDoc->SetString(2, 3, 0, "Peking"); + + sc::TextTransformation aTransform({2}, sc::TEXT_TRANSFORM_TYPE::TO_UPPER); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("BERLIN"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("BRUSSELS"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("PARIS"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("PEKING"), m_pDoc->GetString(2, 3, 0)); +} + +void ScDataTransformationTest::testTextCapitalize() +{ + m_pDoc->SetString(2, 0, 0, "hello woRlD"); + m_pDoc->SetString(2, 1, 0, "qUe vA"); + m_pDoc->SetString(2, 2, 0, "si tu la ves"); + m_pDoc->SetString(2, 3, 0, "cUaNdO mE EnAmOro"); + + sc::TextTransformation aTransform({2}, sc::TEXT_TRANSFORM_TYPE::CAPITALIZE); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("Hello World"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Que Va"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Si Tu La Ves"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Cuando Me Enamoro"), m_pDoc->GetString(2, 3, 0)); +} + +void ScDataTransformationTest::testTextTrim() +{ + m_pDoc->SetString(2, 0, 0, " Berlin"); + m_pDoc->SetString(2, 1, 0, "Brussels "); + m_pDoc->SetString(2, 2, 0, " Paris "); + + sc::TextTransformation aTransform({2}, sc::TEXT_TRANSFORM_TYPE::TRIM); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("Berlin"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Brussels"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Paris"), m_pDoc->GetString(2, 2, 0)); +} + +void ScDataTransformationTest::testAggregateSum() +{ + m_pDoc->SetValue(2, 0, 0, 2034); + m_pDoc->SetValue(2, 1, 0, 2342); + m_pDoc->SetValue(2, 2, 0, 57452); + + m_pDoc->SetValue(4, 0, 0, 4829.98); + m_pDoc->SetValue(4, 1, 0, 53781.3); + m_pDoc->SetValue(4, 2, 0, 9876.4); + m_pDoc->SetValue(4, 3, 0, 0); + + sc::AggregateFunction aTransform({2, 4}, sc::AGGREGATE_FUNCTION::SUM); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(61828, m_pDoc->GetValue(2, 4, 0), 1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(68487.68, m_pDoc->GetValue(4, 4, 0), 1e-10); +} + +void ScDataTransformationTest::testAggregateAverage() +{ + m_pDoc->SetValue(2, 0, 0, 2034); + m_pDoc->SetValue(2, 1, 0, 2342); + m_pDoc->SetValue(2, 2, 0, 57453); + + m_pDoc->SetValue(3, 0, 0, 4); + m_pDoc->SetValue(3, 1, 0, 4); + m_pDoc->SetValue(3, 2, 0, 4); + + sc::AggregateFunction aTransform({2, 3}, sc::AGGREGATE_FUNCTION::AVERAGE); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(20609.6666666667, m_pDoc->GetValue(2, 3, 0), 1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4, m_pDoc->GetValue(3, 3, 0), 1e-10); +} + +void ScDataTransformationTest::testAggregateMin() +{ + m_pDoc->SetValue(2, 0, 0, 2034); + m_pDoc->SetValue(2, 1, 0, 2342); + m_pDoc->SetValue(2, 2, 0, 57453); + + m_pDoc->SetValue(3, 0, 0, 2034); + m_pDoc->SetValue(3, 1, 0, -2342); + m_pDoc->SetValue(3, 2, 0, 57453); + + sc::AggregateFunction aTransform({2, 3}, sc::AGGREGATE_FUNCTION::MIN); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(2034, m_pDoc->GetValue(2, 3, 0), 1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-2342, m_pDoc->GetValue(3, 3, 0), 1e-10); +} + +void ScDataTransformationTest::testAggregateMax() +{ + m_pDoc->SetValue(2, 0, 0, 2034); + m_pDoc->SetValue(2, 1, 0, 2342); + m_pDoc->SetValue(2, 2, 0, 57453); + m_pDoc->SetValue(2, 3, 0, -453); + + m_pDoc->SetValue(3, 0, 0, 2034); + m_pDoc->SetValue(3, 1, 0, -2342); + m_pDoc->SetValue(3, 2, 0, -57453); + m_pDoc->SetValue(3, 3, 0, -453); + + sc::AggregateFunction aTransform({2, 3}, sc::AGGREGATE_FUNCTION::MAX); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(57453, m_pDoc->GetValue(2, 4, 0), 1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2034, m_pDoc->GetValue(3, 4, 0), 1e-10); +} + +void ScDataTransformationTest::testNumberRound() +{ + m_pDoc->SetValue(2, 0, 0, 2034.342453456); + m_pDoc->SetValue(2, 1, 0, 2342.252678567542); + m_pDoc->SetValue(2, 2, 0, 57453.651345687654345676); + m_pDoc->SetValue(2, 3, 0, -453.22234567543); + + sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::ROUND, 4); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(2034.3425, m_pDoc->GetValue(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(2342.2527, m_pDoc->GetValue(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(57453.6513, m_pDoc->GetValue(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(-453.2223, m_pDoc->GetValue(2, 3, 0)); +} + +void ScDataTransformationTest::testNumberRoundUp() +{ + m_pDoc->SetValue(2, 0, 0, 2034.34); + m_pDoc->SetValue(2, 1, 0, 2342.22); + m_pDoc->SetValue(2, 2, 0, 57453.65); + m_pDoc->SetValue(2, 3, 0, -453.22); + + sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::ROUND_UP); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(2035.0, m_pDoc->GetValue(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(2343.0, m_pDoc->GetValue(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(57454.0, m_pDoc->GetValue(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(-453.0, m_pDoc->GetValue(2, 3, 0)); +} + +void ScDataTransformationTest::testNumberRoundDown() +{ + m_pDoc->SetValue(2, 0, 0, 2034.34); + m_pDoc->SetValue(2, 1, 0, 2342.22); + m_pDoc->SetValue(2, 2, 0, 57453.65); + m_pDoc->SetValue(2, 3, 0, -453.22); + + sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::ROUND_DOWN); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(2034.0, m_pDoc->GetValue(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(2342.0, m_pDoc->GetValue(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(57453.0, m_pDoc->GetValue(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(-454.0, m_pDoc->GetValue(2, 3, 0)); +} + +void ScDataTransformationTest::testNumberAbsolute() +{ + m_pDoc->SetValue(2, 0, 0, 2034.34); + m_pDoc->SetValue(2, 1, 0, -2342.22); + m_pDoc->SetValue(2, 2, 0, 57453.65); + m_pDoc->SetValue(2, 3, 0, -453.22); + + sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::ABSOLUTE); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(2034.34, m_pDoc->GetValue(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(2342.22, m_pDoc->GetValue(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(57453.65, m_pDoc->GetValue(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(453.22, m_pDoc->GetValue(2, 3, 0)); +} + +void ScDataTransformationTest::testNumberLogE() +{ + m_pDoc->SetValue(2, 0, 0, 1); + m_pDoc->SetValue(2, 1, 0, 5); + m_pDoc->SetValue(2, 2, 0, -9); + m_pDoc->SetValue(2, 3, 0, 500); + + sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::LOG_E); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(0, m_pDoc->GetValue(2, 0, 0), 1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.60943791243, m_pDoc->GetValue(2, 1, 0), 1e-10); + CPPUNIT_ASSERT_EQUAL(OUString(""), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.21460809842, m_pDoc->GetValue(2, 3, 0), 1e-10); +} + +void ScDataTransformationTest::testNumberLog10() +{ + m_pDoc->SetValue(2, 0, 0, 1); + m_pDoc->SetValue(2, 1, 0, 10); + m_pDoc->SetValue(2, 2, 0, -9); + m_pDoc->SetValue(2, 3, 0, 500); + + sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::LOG_10); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(0, m_pDoc->GetValue(2, 0, 0), 1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, m_pDoc->GetValue(2, 1, 0), 1e-10); + CPPUNIT_ASSERT_EQUAL(OUString(), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.69897000434, m_pDoc->GetValue(2, 3, 0), 1e-10); +} + +void ScDataTransformationTest::testNumberCube() +{ + m_pDoc->SetValue(2, 0, 0, 2); + m_pDoc->SetValue(2, 1, 0, -2); + m_pDoc->SetValue(2, 2, 0, 8); + m_pDoc->SetValue(2, 3, 0, -8); + + sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::CUBE); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(8.0, m_pDoc->GetValue(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(-8.0, m_pDoc->GetValue(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(512.0, m_pDoc->GetValue(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(-512.0, m_pDoc->GetValue(2, 3, 0)); +} + +void ScDataTransformationTest::testNumberSquare() +{ + m_pDoc->SetValue(2, 0, 0, 2); + m_pDoc->SetValue(2, 1, 0, -2); + m_pDoc->SetValue(2, 2, 0, 8); + m_pDoc->SetValue(2, 3, 0, -8); + + sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::SQUARE); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(4.0, m_pDoc->GetValue(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(4.0, m_pDoc->GetValue(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(64.0, m_pDoc->GetValue(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(64.0, m_pDoc->GetValue(2, 3, 0)); +} + +void ScDataTransformationTest::testNumberSquareRoot() +{ + m_pDoc->SetValue(2, 0, 0, 8); + m_pDoc->SetValue(2, 1, 0, 4); + m_pDoc->SetValue(2, 2, 0, 9); + + sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::SQUARE_ROOT); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.82842712475, m_pDoc->GetValue(2, 0, 0), 1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.0, m_pDoc->GetValue(2, 1, 0), 1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, m_pDoc->GetValue(2, 2, 0), 1e-10); +} + +void ScDataTransformationTest::testNumberEven() +{ + m_pDoc->SetValue(2, 0, 0, 2034); + m_pDoc->SetValue(2, 1, 0, 2343); + m_pDoc->SetValue(2, 2, 0, 57453.65); + m_pDoc->SetValue(2, 3, 0, -453); + + sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::IS_EVEN); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(2, 3, 0)); +} + +void ScDataTransformationTest::testNumberOdd() +{ + m_pDoc->SetValue(2, 0, 0, 2034); + m_pDoc->SetValue(2, 1, 0, 2343); + m_pDoc->SetValue(2, 2, 0, 57453.65); + m_pDoc->SetValue(2, 3, 0, -453); + + sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::IS_ODD); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(2, 3, 0)); +} + +void ScDataTransformationTest::testNumberSign() +{ + m_pDoc->SetValue(2, 0, 0, 2034.34); + m_pDoc->SetValue(2, 1, 0, -2342.22); + m_pDoc->SetValue(2, 2, 0, 0); + m_pDoc->SetValue(2, 3, 0, -453.22); + + sc::NumberTransformation aTransform({2}, sc::NUMBER_TRANSFORM_TYPE::SIGN); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(-1.0, m_pDoc->GetValue(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(-1.0, m_pDoc->GetValue(2, 3, 0)); +} + +void ScDataTransformationTest::testReplaceNull() +{ + m_pDoc->SetString(2, 0, 0, "Berlin"); + m_pDoc->SetString(2, 1, 0, ""); + m_pDoc->SetString(2, 2, 0, ""); + m_pDoc->SetString(2, 3, 0, "Peking"); + + sc::ReplaceNullTransformation aTransform({2}, "Empty"); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("Berlin"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Empty"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Empty"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("Peking"), m_pDoc->GetString(2, 3, 0)); + +} + +void ScDataTransformationTest::testGetDateString() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::DATE_STRING ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("01/25/11"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("10/12/94"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("09/23/96"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("08/15/47"), m_pDoc->GetString(2, 3, 0)); +} + +void ScDataTransformationTest::testGetYear() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::YEAR ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(2011, m_pDoc->GetValue(2, 0, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1994, m_pDoc->GetValue(2, 1, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1996, m_pDoc->GetValue(2, 2, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1947, m_pDoc->GetValue(2, 3, 0), 0); +} + +void ScDataTransformationTest::testGetStartOfYear() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::START_OF_YEAR ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("01/01/11"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("01/01/94"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("01/01/96"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("01/01/47"), m_pDoc->GetString(2, 3, 0)); +} + +void ScDataTransformationTest::testGetEndOfYear() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::END_OF_YEAR ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("12/31/11"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("12/31/94"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("12/31/96"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("12/31/47"), m_pDoc->GetString(2, 3, 0)); +} + +void ScDataTransformationTest::testGetMonth() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::MONTH ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(2, 0, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(10, m_pDoc->GetValue(2, 1, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9, m_pDoc->GetValue(2, 2, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8, m_pDoc->GetValue(2, 3, 0), 0); +} + +void ScDataTransformationTest::testGetMonthName() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::MONTH_NAME); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("January"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("October"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("September"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("August"), m_pDoc->GetString(2, 3, 0)); +} + +void ScDataTransformationTest::testGetStartOfMonth() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::START_OF_MONTH ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("01/01/11"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("10/01/94"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("09/01/96"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("08/01/47"), m_pDoc->GetString(2, 3, 0)); +} + +void ScDataTransformationTest::testGetEndOfMonth() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::END_OF_MONTH ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("01/31/11"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("10/31/94"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("09/30/96"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("08/31/47"), m_pDoc->GetString(2, 3, 0)); +} + +void ScDataTransformationTest::testGetDay() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::DAY ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(25, m_pDoc->GetValue(2, 0, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(12, m_pDoc->GetValue(2, 1, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(23, m_pDoc->GetValue(2, 2, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15, m_pDoc->GetValue(2, 3, 0), 0); +} + +void ScDataTransformationTest::testGetDayOfWeek() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_WEEK ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(2, 0, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2, m_pDoc->GetValue(2, 1, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0, m_pDoc->GetValue(2, 2, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4, m_pDoc->GetValue(2, 3, 0), 0); +} + +void ScDataTransformationTest::testGetDayOfYear() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_YEAR ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(25, m_pDoc->GetValue(2, 0, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(285, m_pDoc->GetValue(2, 1, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(267, m_pDoc->GetValue(2, 2, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(227, m_pDoc->GetValue(2, 3, 0), 0); +} + +void ScDataTransformationTest::testGetQuarter() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::QUARTER ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(2, 0, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4, m_pDoc->GetValue(2, 1, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3, m_pDoc->GetValue(2, 2, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3, m_pDoc->GetValue(2, 3, 0), 0); +} + +void ScDataTransformationTest::testGetStartOfQuarter() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::START_OF_QUARTER ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("01/01/11"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("10/01/94"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("07/01/96"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("07/01/47"), m_pDoc->GetString(2, 3, 0)); +} + +void ScDataTransformationTest::testGetEndOfQuarter() +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + css::util::Date aDate1(25,1,2011); + css::util::Date aDate2(12,10,1994); + css::util::Date aDate3(23,9,1996); + css::util::Date aDate4(15,8,1947); + + double nDate1 = static_cast(aDate1 - pFormatter->GetNullDate()); + double nDate2 = static_cast(aDate2 - pFormatter->GetNullDate()); + double nDate3 = static_cast(aDate3 - pFormatter->GetNullDate()); + double nDate4 = static_cast(aDate4 - pFormatter->GetNullDate()); + + m_pDoc->SetValue(2, 0, 0, nDate1); + m_pDoc->SetValue(2, 1, 0, nDate2); + m_pDoc->SetValue(2, 2, 0, nDate3); + m_pDoc->SetValue(2, 3, 0, nDate4); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::END_OF_QUARTER ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("03/31/11"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("12/31/94"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("09/30/96"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("09/30/47"), m_pDoc->GetString(2, 3, 0)); +} + +void ScDataTransformationTest::testGetTime() +{ + tools::Time aTime1(5,30,12); + tools::Time aTime2(7,23,9); + tools::Time aTime3(9,34,40); + tools::Time aTime4(22,9,49); + + m_pDoc->SetValue(2, 0, 0, aTime1.GetTimeInDays()); + m_pDoc->SetValue(2, 1, 0, aTime2.GetTimeInDays()); + m_pDoc->SetValue(2, 2, 0, aTime3.GetTimeInDays()); + m_pDoc->SetValue(2, 3, 0, aTime4.GetTimeInDays()); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::TIME ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("05:30:12 AM"), m_pDoc->GetString(2, 0, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("07:23:09 AM"), m_pDoc->GetString(2, 1, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("09:34:40 AM"), m_pDoc->GetString(2, 2, 0)); + CPPUNIT_ASSERT_EQUAL(OUString("10:09:49 PM"), m_pDoc->GetString(2, 3, 0)); +} + +void ScDataTransformationTest::testGetHour() +{ + tools::Time aTime1(5,30,12); + tools::Time aTime2(7,23,9); + tools::Time aTime3(9,34,40); + tools::Time aTime4(22,9,49); + + m_pDoc->SetValue(2, 0, 0, aTime1.GetTimeInDays()); + m_pDoc->SetValue(2, 1, 0, aTime2.GetTimeInDays()); + m_pDoc->SetValue(2, 2, 0, aTime3.GetTimeInDays()); + m_pDoc->SetValue(2, 3, 0, aTime4.GetTimeInDays()); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::HOUR ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(5, m_pDoc->GetValue(2, 0, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7, m_pDoc->GetValue(2, 1, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9, m_pDoc->GetValue(2, 2, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(22, m_pDoc->GetValue(2, 3, 0), 0); +} + +void ScDataTransformationTest::testGetMinute() +{ + tools::Time aTime1(5,30,12); + tools::Time aTime2(7,23,9); + tools::Time aTime3(9,34,40); + tools::Time aTime4(22,9,49); + + m_pDoc->SetValue(2, 0, 0, aTime1.GetTimeInDays()); + m_pDoc->SetValue(2, 1, 0, aTime2.GetTimeInDays()); + m_pDoc->SetValue(2, 2, 0, aTime3.GetTimeInDays()); + m_pDoc->SetValue(2, 3, 0, aTime4.GetTimeInDays()); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::MINUTE ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(30, m_pDoc->GetValue(2, 0, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(23, m_pDoc->GetValue(2, 1, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(34, m_pDoc->GetValue(2, 2, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9, m_pDoc->GetValue(2, 3, 0), 0); +} + +void ScDataTransformationTest::testGetSecond() +{ + tools::Time aTime1(5,30,53); + tools::Time aTime2(7,23,10); + tools::Time aTime3(9,34,40); + tools::Time aTime4(22,9,49); + + m_pDoc->SetValue(2, 0, 0, aTime1.GetTimeInDays()); + m_pDoc->SetValue(2, 1, 0, aTime2.GetTimeInDays()); + m_pDoc->SetValue(2, 2, 0, aTime3.GetTimeInDays()); + m_pDoc->SetValue(2, 3, 0, aTime4.GetTimeInDays()); + + sc:: DateTimeTransformation aTransform({2}, sc::DATETIME_TRANSFORMATION_TYPE::SECOND ); + aTransform.Transform(*m_pDoc); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(53, m_pDoc->GetValue(2, 0, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(10, m_pDoc->GetValue(2, 1, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(40, m_pDoc->GetValue(2, 2, 0), 0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(49, m_pDoc->GetValue(2, 3, 0), 0); +} + +void ScDataTransformationTest::setUp() +{ + ScSimpleBootstrapFixture::setUp(); + m_pDoc->InsertTab(0, "Tab"); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(ScDataTransformationTest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/ucalc_parallelism.cxx b/sc/qa/unit/ucalc_parallelism.cxx new file mode 100644 index 000000000000..ee148f822410 --- /dev/null +++ b/sc/qa/unit/ucalc_parallelism.cxx @@ -0,0 +1,1000 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ + +#include +#include + +#include + +#include "helper/qahelper.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace css; +using namespace css::uno; + +class ScParallelismTest : public ScSimpleBootstrapFixture +{ +public: + virtual void setUp() override; + virtual void tearDown() override; + + void testSUMIFS(); + void testDivision(); + void testVLOOKUP(); + void testVLOOKUPSUM(); + void testSingleRef(); + void testTdf147905(); + void testSUMIFImplicitRange(); + void testFGCycleWithPlainFormulaCell1(); + void testFGCycleWithPlainFormulaCell2(); + void testMultipleFGColumn(); + void testFormulaGroupSpanEval(); + void testFormulaGroupSpanEvalNonGroup(); + void testArrayFormulaGroup(); + void testDependentFormulaGroupCollection(); + void testFormulaGroupWithForwardSelfReference(); + void testFormulaGroupsInCyclesAndWithSelfReference(); + void testFormulaGroupsInCyclesAndWithSelfReference2(); + void testFormulaGroupsInCyclesAndWithSelfReference3(); + + CPPUNIT_TEST_SUITE(ScParallelismTest); + CPPUNIT_TEST(testSUMIFS); + CPPUNIT_TEST(testDivision); + CPPUNIT_TEST(testVLOOKUP); + CPPUNIT_TEST(testVLOOKUPSUM); + CPPUNIT_TEST(testSingleRef); + CPPUNIT_TEST(testTdf147905); + CPPUNIT_TEST(testSUMIFImplicitRange); + CPPUNIT_TEST(testFGCycleWithPlainFormulaCell1); + CPPUNIT_TEST(testFGCycleWithPlainFormulaCell2); + CPPUNIT_TEST(testMultipleFGColumn); + CPPUNIT_TEST(testFormulaGroupSpanEval); + CPPUNIT_TEST(testFormulaGroupSpanEvalNonGroup); + CPPUNIT_TEST(testArrayFormulaGroup); + CPPUNIT_TEST(testDependentFormulaGroupCollection); + CPPUNIT_TEST(testFormulaGroupWithForwardSelfReference); + CPPUNIT_TEST(testFormulaGroupsInCyclesAndWithSelfReference); + CPPUNIT_TEST(testFormulaGroupsInCyclesAndWithSelfReference2); + CPPUNIT_TEST(testFormulaGroupsInCyclesAndWithSelfReference3); + CPPUNIT_TEST_SUITE_END(); + +private: + + bool getThreadingFlag() const; + void setThreadingFlag(bool bSet); + + bool m_bThreadingFlagCfg; +}; + +bool ScParallelismTest::getThreadingFlag() const +{ + return officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::get(); +} + +void ScParallelismTest::setThreadingFlag( bool bSet ) +{ + std::shared_ptr xBatch(comphelper::ConfigurationChanges::create()); + officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::set(bSet, xBatch); + xBatch->commit(); +} + +void ScParallelismTest::setUp() +{ + ScSimpleBootstrapFixture::setUp(); + + sc::FormulaGroupInterpreter::disableOpenCL_UnitTestsOnly(); + + m_bThreadingFlagCfg = getThreadingFlag(); + if (!m_bThreadingFlagCfg) + setThreadingFlag(true); +} + +void ScParallelismTest::tearDown() +{ + // Restore threading flag + if (!m_bThreadingFlagCfg) + setThreadingFlag(false); + + ScSimpleBootstrapFixture::tearDown(); +} + +void ScParallelismTest::testSUMIFS() +{ + m_pDoc->InsertTab(0, "1"); + + m_pDoc->SetValue(0, 0, 0, 1001); + + for (auto i = 1; i < 1000; i++) + { + /*A*/ + if (i%19) + m_pDoc->SetValue(0, i, 0, i/10 + 1000); + else + m_pDoc->SetValue(0, i, 0, 123456); + /*B*/ m_pDoc->SetValue(1, i, 0, i%10); + /*C*/ m_pDoc->SetValue(2, i, 0, i%5); + + /*F*/ m_pDoc->SetValue(5, i, 0, i%17 + i%13); + + /*L*/ m_pDoc->SetValue(11, i, 0, i%10); + /*M*/ m_pDoc->SetValue(12, i, 0, i%5); + } + + for (auto i = 1; i < 1000; i++) + { + // For instance P389 will contain the formula: + // =SUMIFS($F$2:$F$1000; $A$2:$A$1000; A$1; $B$2:$B$1000; $L389; $C$2:$C$1000; $M389) + + // In other words, it will sum those values in F2:1000 where the A value matches A1 (1001), + // the B value matches L389 and the C value matches M389. (There should be just one such + // value, so the formula is actually simply used to pick out that single value from the F + // column where A,B,C match. Silly, but that is how SUMIFS is used in some corners of the + // real world, apparently.) + + /*P*/ m_pDoc->SetFormula(ScAddress(15, i, 0), + "=SUMIFS($F$2:$F$1000; " + "$A$2:$A$1000; A$1; " + "$B$2:$B$1000; $L" + OUString::number(i+1) + "; " + "$C$2:$C$1000; $M" + OUString::number(i+1) + + ")", + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + m_xDocShell->DoHardRecalc(); + +#if 1 + OUString sFormula; + + std::cerr << "A1=" << m_pDoc->GetValue(0, 0, 0) << std::endl; + + std::cerr << " A,B,C F L,M" << std::endl; + for (auto i = 1; i < 30; i++) + { + std::cerr << + i+1 << ": " << + m_pDoc->GetValue(0, i, 0) << "," << + m_pDoc->GetValue(1, i, 0) << "," << + m_pDoc->GetValue(2, i, 0) << " " << + m_pDoc->GetValue(5, i, 0) << " " << + m_pDoc->GetValue(11, i, 0) << "," << + m_pDoc->GetValue(12, i, 0) << " \""; + sFormula = m_pDoc->GetFormula(15, i, 0); + std::cerr << sFormula << "\": \"" << + m_pDoc->GetString(15, i, 0) << "\": " << + m_pDoc->GetValue(15, i, 0) << std::endl; + } +#endif + + for (auto i = 1; i < 1000; i++) + { + OString sMessage = "At row " + OString::number(i+1); + if ((10+i%10)%19) + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(sMessage.getStr(), m_pDoc->GetValue(5, 10+i%10, 0), m_pDoc->GetValue(15, i, 0), 1e-10); + else + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(sMessage.getStr(), 0, m_pDoc->GetValue(15, i, 0), 1e-10); + } + + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testDivision() +{ + m_pDoc->InsertTab(0, "1"); + + for (auto i = 1; i < 1000; i++) + { + /*A*/ m_pDoc->SetValue(0, i, 0, i); + /*B*/ m_pDoc->SetValue(1, i, 0, i%10); + /*C*/ m_pDoc->SetFormula(ScAddress(2, i, 0), + "=A" + OUString::number(i+1) + "/B" + OUString::number(i+1), + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + m_xDocShell->DoHardRecalc(); + + for (auto i = 1; i < 1000; i++) + { + OString sMessage = "At row " + OString::number(i+1); + if (i%10) + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(sMessage.getStr(), static_cast(i)/(i%10), m_pDoc->GetValue(2, i, 0), 1e-10); + else + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), OUString("#DIV/0!"), m_pDoc->GetString(2, i, 0)); + } + + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testVLOOKUP() +{ + m_pDoc->InsertTab(0, "1"); + + for (auto i = 1; i < 2000; i++) + { + if (i == 1042) + m_pDoc->SetValue(0, i, 0, 1042.42); + else if (i%5) + m_pDoc->SetValue(0, i, 0, i); + else + m_pDoc->SetValue(0, i, 0, i+0.1); + + if (i%2) + m_pDoc->SetValue(1, i, 0, i*10); + else + m_pDoc->SetString(1, i, 0, "N" + OUString::number(i*10)); + + if (i < 1000) + { + m_pDoc->SetFormula(ScAddress(2, i, 0), + "=VLOOKUP(" + OUString::number(i) + "; " + "A$2:B$2000; 2; 0)", + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + else + { + if (i == 1042) + m_pDoc->SetFormula(ScAddress(2, i, 0), + "=VLOOKUP(1042.42; " + "A$2:B$2000; 2; 0)", + formula::FormulaGrammar::GRAM_NATIVE_UI); + else + m_pDoc->SetFormula(ScAddress(2, i, 0), + "=VLOOKUP(1.234; " + "A$2:B$2000; 2; 0)", + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + } + + m_xDocShell->DoHardRecalc(); + + for (auto i = 1; i < 2000; i++) + { + OString sMessage = "At row " + OString::number(i+1); + if (i < 1000) + { + if (i%5) + { + if (i%2) + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(sMessage.getStr(), static_cast(i*10), m_pDoc->GetValue(2, i, 0), 1e-10); + else + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), OUString("N" + OUString::number(i*10)), m_pDoc->GetString(2, i, 0)); + } + else + { + // The corresponding value in A is i+0.1 + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), OUString("#N/A"), m_pDoc->GetString(2, i, 0)); + } + } + else + { + if (i == 1042) + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), OUString("N" + OUString::number(i*10)), m_pDoc->GetString(2, i, 0)); + else + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), OUString("#N/A"), m_pDoc->GetString(2, i, 0)); + } + } + + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testVLOOKUPSUM() +{ + m_pDoc->InsertTab(0, "1"); + + const size_t nNumRows = 2048; + OUString aTableRef = "$A$1:$B$" + OUString::number(nNumRows); + for (size_t i = 0; i < nNumRows; ++i) + { + m_pDoc->SetValue(0, i, 0, static_cast(i)); + m_pDoc->SetValue(1, i, 0, static_cast(5*i + 100)); + m_pDoc->SetValue(2, i, 0, static_cast(nNumRows - i - 1)); + } + for (size_t i = 0; i < nNumRows; ++i) + { + OUString aArgNum = "C" + OUString::number(i+1); + m_pDoc->SetFormula(ScAddress(3, i, 0), + "=SUM(" + aArgNum + ";VLOOKUP(" + aArgNum + ";" + aTableRef + "; 2; 0)) + SUM($A1:$A2)", + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + m_xDocShell->DoHardRecalc(); + + for (size_t i = 0; i < nNumRows; ++i) + { + OString aMsg = "At row " + OString::number(i); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), 6 * (nNumRows - i - 1) + 101, static_cast(m_pDoc->GetValue(3, i, 0))); + } + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testSingleRef() +{ + m_pDoc->InsertTab(0, "1"); + + const size_t nNumRows = 200; + for (size_t i = 0; i < nNumRows; ++i) + { + m_pDoc->SetValue(0, i, 0, static_cast(i)); + m_pDoc->SetFormula(ScAddress(1, i, 0), "=A" + OUString::number(i+1), formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + m_xDocShell->DoHardRecalc(); + + for (size_t i = 0; i < nNumRows; ++i) + { + OString aMsg = "At row " + OString::number(i); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), i, static_cast(m_pDoc->GetValue(1, i, 0))); + } + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testTdf147905() +{ + m_pDoc->InsertTab(0, "1"); + + OUString aFormula; + const size_t nNumRows = 500; + for (size_t i = 0; i < nNumRows; ++i) + { + m_pDoc->SetString(0, i, 0, "AAAAAAAA"); + aFormula = "=PROPER($A" + OUString::number(i+1) + ")"; + m_pDoc->SetFormula(ScAddress(1, i, 0), + aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + m_xDocShell->DoHardRecalc(); + + for (size_t i = 0; i < nNumRows; ++i) + { + OString aMsg = "At row " + OString::number(i); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), OUString("AAAAAAAA"), m_pDoc->GetString(0, i, 0)); + + // Without the fix in place, this test would have failed here + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), OUString("Aaaaaaaa"), m_pDoc->GetString(1, i, 0)); + } + m_pDoc->DeleteTab(0); +} + +// Common test setup steps for testSUMIFImplicitRange*() +static void lcl_setupCommon(ScDocument* pDoc, size_t nNumRows, size_t nConstCellValue) +{ + pDoc->SetValue(3, 0, 0, static_cast(nConstCellValue)); // D1 + for (size_t i = 0; i <= (nNumRows*2); ++i) + { + pDoc->SetValue(0, i, 0, static_cast(i)); + pDoc->SetFormula(ScAddress(1, i, 0), + "=A" + OUString::number(i+1), + formula::FormulaGrammar::GRAM_NATIVE_UI); + } +} + +void ScParallelismTest::testSUMIFImplicitRange() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); + m_pDoc->InsertTab(0, "1"); + + const size_t nNumRows = 1048; + const size_t nConstCellValue = 20; + lcl_setupCommon(m_pDoc, nNumRows, nConstCellValue); + OUString aSrcRange = "$A$1:$A$" + OUString::number(nNumRows); + OUString aFormula; + for (size_t i = 0; i < nNumRows; ++i) + { + aFormula = "=SUMIF(" + aSrcRange + ";$D$1;$B$1)"; + m_pDoc->SetFormula(ScAddress(2, i, 0), + aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + ScFormulaCell* pCell = m_pDoc->GetFormulaCell(ScAddress(2, 0, 0)); + sc::AutoCalcSwitch aACSwitch2(*m_pDoc, true); + pCell->InterpretFormulaGroup(); // Start calculation on the F.G at C1 + + for (size_t i = 0; i < nNumRows; ++i) + { + OString aMsg = "At row " + OString::number(i); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nConstCellValue, static_cast(m_pDoc->GetValue(2, i, 0))); + } + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testFGCycleWithPlainFormulaCell1() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); + m_pDoc->InsertTab(0, "1"); + const size_t nNumRows = 1048; + // Column A contains no formula-group + // A1 = 100 + m_pDoc->SetValue(0, 0, 0, 100.0); + // A500 = B499 + 1 + m_pDoc->SetFormula(ScAddress(0, 499, 0), + "=$B499 + 1", + formula::FormulaGrammar::GRAM_NATIVE_UI); + // Column B has a formula-group referencing column A. + OUString aFormula; + for (size_t i = 0; i < nNumRows; ++i) + { + aFormula = "=$A" + OUString::number(i+1) + " + 100"; + m_pDoc->SetFormula(ScAddress(1, i, 0), + aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + m_xDocShell->DoHardRecalc(); + // Value at A500 must be 101 + const size_t nVal = 100; + CPPUNIT_ASSERT_EQUAL_MESSAGE("Value at A500", nVal + 1, static_cast(m_pDoc->GetValue(0, 499, 0))); + for (size_t i = 0; i < nNumRows; ++i) + { + OString aMsg = "Value at cell B" + OString::number(i+1); + size_t nExpected = nVal; + if (i == 0) + nExpected = 200; + else if (i == 499) + nExpected = 201; + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast(m_pDoc->GetValue(1, i, 0))); + } + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testFGCycleWithPlainFormulaCell2() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); + m_pDoc->InsertTab(0, "1"); + const size_t nNumRows = 1048; + // Column A + OUString aFormula; + for (size_t i = 0; i < nNumRows; ++i) + { + aFormula = "=$B" + OUString::number(i+1) + " + 1"; + m_pDoc->SetFormula(ScAddress(0, i, 0), + aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + // Column B + for (size_t i = 0; i < nNumRows; ++i) + { + aFormula = "=$C" + OUString::number(i+1) + " + 1"; + m_pDoc->SetFormula(ScAddress(1, i, 0), + aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + // Column C has no FG but a cell at C500 that references A499 + m_pDoc->SetFormula(ScAddress(2, 499, 0), // C500 + "=$A499 + 1", + formula::FormulaGrammar::GRAM_NATIVE_UI); + m_xDocShell->DoHardRecalc(); + + size_t nExpected = 0; + for (size_t i = 0; i < nNumRows; ++i) + { + OString aMsg = "Value at cell A" + OString::number(i+1); + nExpected = 2; + if (i == 499) // A500 must have value = 5 + nExpected = 5; + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast(m_pDoc->GetValue(0, i, 0))); + aMsg = "Value at cell B" + OString::number(i+1); + nExpected = 1; + if (i == 499) // B500 must have value = 4 + nExpected = 4; + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast(m_pDoc->GetValue(1, i, 0))); + } + + // C500 must have value = 3 + nExpected = 3; + CPPUNIT_ASSERT_EQUAL_MESSAGE("Value at cell C500", nExpected, static_cast(m_pDoc->GetValue(2, 499, 0))); + m_pDoc->DeleteTab(0); +} + +static void lcl_setupMultipleFGColumn(ScDocument* pDocument, size_t nNumRowsInBlock, size_t nNumFG, size_t nOffset) +{ + OUString aFormula; + ScAddress aAddr(1, 0, 0); + // Column B with multiple FG's + for (size_t nFGIdx = 0; nFGIdx < nNumFG; ++nFGIdx) + { + size_t nRowStart = 2*nFGIdx*nNumRowsInBlock; + for (size_t nRow = nRowStart; nRow < (nRowStart + nNumRowsInBlock); ++nRow) + { + aAddr.SetRow(nRow); + aFormula = "=$C" + OUString::number(nRow+1) + " + 0"; + pDocument->SetFormula(aAddr, aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + // Fill Column C with doubles. + pDocument->SetValue(2, nRow, 0, static_cast(nFGIdx)); + } + } + + // Column A with a single FG that depends on Column B. + size_t nNumRowsInRef = nNumRowsInBlock*2; + size_t nColAFGLen = 2*nNumRowsInBlock*nNumFG - nNumRowsInRef + 1; + aAddr.SetCol(0); + for (size_t nRow = nOffset; nRow < nColAFGLen; ++nRow) + { + aAddr.SetRow(nRow); + aFormula = "=SUM($B" + OUString::number(nRow+1) + ":$B" + OUString::number(nRow+nNumRowsInRef) + ")"; + pDocument->SetFormula(aAddr, aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } +} + +void ScParallelismTest::testMultipleFGColumn() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); + m_pDoc->InsertTab(0, "1"); + + constexpr size_t nNumRowsInBlock = 200; + constexpr size_t nNumFG = 50; + constexpr size_t nNumRowsInRef = nNumRowsInBlock*2; + constexpr size_t nColAFGLen = 2*nNumRowsInBlock*nNumFG - nNumRowsInRef + 1; + constexpr size_t nColAStartOffset = nNumRowsInBlock/2; + lcl_setupMultipleFGColumn(m_pDoc, nNumRowsInBlock, nNumFG, nColAStartOffset); + + m_xDocShell->DoHardRecalc(); + + OString aMsg; + // First cell in the FG in col A references nColAStartOffset cells in second formula-group of column B each having value 1. + size_t nExpected = nColAStartOffset; + size_t nIn = 0, nOut = 0; + for (size_t nRow = nColAStartOffset; nRow < nColAFGLen; ++nRow) + { + aMsg = "Value at Cell A" + OString::number(nRow+1); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast(m_pDoc->GetValue(0, nRow, 0))); + nIn = static_cast(m_pDoc->GetValue(2, nRow+nNumRowsInRef, 0)); + nOut = static_cast(m_pDoc->GetValue(2, nRow, 0)); + nExpected = nExpected + nIn - nOut; + } + + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testFormulaGroupSpanEval() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); + m_pDoc->InsertTab(0, "1"); + + constexpr size_t nFGLen = 2048; + OUString aFormula; + + for (size_t nRow = 0; nRow < nFGLen; ++nRow) + { + aFormula = "=$C" + OUString::number(nRow+1) + " + 0"; + m_pDoc->SetFormula(ScAddress(1, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + aFormula = "=SUM($B" + OUString::number(nRow+1) + ":$B" + OUString::number(nRow+2) + ")"; + m_pDoc->SetFormula(ScAddress(0, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + m_xDocShell->DoHardRecalc(); + + for (size_t nRow = 0; nRow < nFGLen; ++nRow) + { + m_pDoc->SetValue(2, nRow, 0, 1.0); + ScFormulaCell* pFCell = m_pDoc->GetFormulaCell(ScAddress(1, nRow, 0)); + pFCell->SetDirtyVar(); + pFCell = m_pDoc->GetFormulaCell(ScAddress(0, nRow, 0)); + pFCell->SetDirtyVar(); + } + + constexpr size_t nSpanStart = 100; + constexpr size_t nSpanLen = 1024; + constexpr size_t nSpanEnd = nSpanStart + nSpanLen - 1; + + m_pDoc->SetAutoCalc(true); + + // EnsureFormulaCellResults should only calculate the specified range along with the dependent spans recursively and nothing more. + // The specified range is A99:A1124, and the dependent range is B99:B1125 (since A99 = SUM(B99:B100) and A1124 = SUM(B1124:B1125) ) + bool bAnyDirty = m_pDoc->EnsureFormulaCellResults(ScRange(0, nSpanStart, 0, 0, nSpanEnd, 0)); + CPPUNIT_ASSERT(bAnyDirty); + m_pDoc->SetAutoCalc(false); + + OString aMsg; + for (size_t nRow = 0; nRow < nFGLen; ++nRow) + { + size_t nExpectedA = 0, nExpectedB = 0; + // For nRow from 100(nSpanStart) to 1123(nSpanEnd) column A must have the value of 2 and + // column B should have value 1. + + // For nRow == 1124, column A should have value 0 and column B should have value 1. + + // For all other rows both column A and B must have value 0. + if (nRow >= nSpanStart) + { + if (nRow <= nSpanEnd) + { + nExpectedA = 2; + nExpectedB = 1; + } + else if (nRow == nSpanEnd + 1) + nExpectedB = 1; + } + + aMsg = "Value at Cell A" + OString::number(nRow+1); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpectedA, static_cast(m_pDoc->GetValue(0, nRow, 0))); + aMsg = "Value at Cell B" + OString::number(nRow+1); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpectedB, static_cast(m_pDoc->GetValue(1, nRow, 0))); + } + + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testFormulaGroupSpanEvalNonGroup() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); + m_pDoc->InsertTab(0, "1"); + + constexpr size_t nFGLen = 2048; + OUString aFormula; + + for (size_t nRow = 0; nRow < nFGLen; ++nRow) + { + aFormula = "=$B" + OUString::number(nRow+1) + " + 0"; + m_pDoc->SetFormula(ScAddress(0, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + m_xDocShell->DoHardRecalc(); + + constexpr size_t nNumChanges = 12; + constexpr size_t nChangeRows[nNumChanges] = {10, 11, 12, 101, 102, 103, 251, 252, 253, 503, 671, 1029}; + for (size_t nIdx = 0; nIdx < nNumChanges; ++nIdx) + { + size_t nRow = nChangeRows[nIdx]; + m_pDoc->SetValue(1, nRow, 0, 1.0); + ScFormulaCell* pFCell = m_pDoc->GetFormulaCell(ScAddress(0, nRow, 0)); + pFCell->SetDirtyVar(); + } + + m_pDoc->SetAutoCalc(true); + bool bAnyDirty = m_pDoc->EnsureFormulaCellResults(ScRange(0, 9, 0, 0, 1030, 0)); + CPPUNIT_ASSERT(bAnyDirty); + m_pDoc->SetAutoCalc(false); + + OString aMsg; + for (size_t nRow = 0, nIdx = 0; nRow < nFGLen; ++nRow) + { + size_t nExpected = 0; + if (nIdx < nNumChanges && nRow == nChangeRows[nIdx]) + { + nExpected = 1; + ++nIdx; + } + + aMsg = "Value at Cell A" + OString::number(nRow+1); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast(m_pDoc->GetValue(0, nRow, 0))); + } + + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testArrayFormulaGroup() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); + m_pDoc->InsertTab(0, "1"); + + m_pDoc->SetValue(1, 0, 0, 2.0); // B1 <== 2 + m_pDoc->SetValue(2, 0, 0, 1.0); // C1 <== 1 + OUString aFormula; + + for (size_t nRow = 1; nRow < 16; ++nRow) + { + m_pDoc->SetValue(0, nRow, 0, 1.0); // A2:A16 <== 1 + + if (nRow > 10) + continue; + + aFormula = "=SUMPRODUCT(($A" + OUString::number(1 + nRow) + + ":$A" + OUString::number(499 + nRow) + ")*B$1+C$1)"; + // Formula-group in B2:B11 with first cell = "=SUMPRODUCT(($A2:$A500)*B$1+C$1)" + m_pDoc->SetFormula(ScAddress(1, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + m_xDocShell->DoHardRecalc(); + + size_t nExpected = 529; + OString aMsg; + for (size_t nRow = 1; nRow < 11; ++nRow) + { + aMsg = "Value at Cell B" + OString::number(nRow+1); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast(m_pDoc->GetValue(1, nRow, 0))); + nExpected -= 2; + } + + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testDependentFormulaGroupCollection() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); + m_pDoc->InsertTab(0, "1"); + + OUString aFormula; + + for (size_t nRow = 0; nRow < 16; ++nRow) + { + m_pDoc->SetValue(0, nRow, 0, 1.0); // A1:A16 <== 1 + + if (nRow > 7) + continue; + + // Formula-group in B1:B8 with first cell = "=SUM($A1:$A1024)" + aFormula = "=SUM($A" + OUString::number(1 + nRow) + + ":$A" + OUString::number(1024 + nRow) + ")"; + m_pDoc->SetFormula(ScAddress(1, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + + // Formula-group in C1:C8 with first cell = "=SUM($K1:$K1024)" + aFormula = "=SUM($K" + OUString::number(1 + nRow) + + ":$K" + OUString::number(1024 + nRow) + ")"; + m_pDoc->SetFormula(ScAddress(2, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + + // Formula-group in D1:D8 with first cell = "=SUM($A1:$A1024) - $A2" + aFormula = "=SUM($A" + OUString::number(1 + nRow) + + ":$A" + OUString::number(1024 + nRow) + ") - $A" + OUString::number(2 + nRow); + m_pDoc->SetFormula(ScAddress(3, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + + // Formula-group in K1:K8 with first cell = "=SUM($B1:$B1024)" + aFormula = "=SUM($B" + OUString::number(1 + nRow) + + ":$B" + OUString::number(1024 + nRow) + ")"; + m_pDoc->SetFormula(ScAddress(10, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + m_xDocShell->DoHardRecalc(); + + size_t nExpected[8] = { 408, 308, 224, 155, 100, 58, 28, 9 }; + + OString aMsg; + for (size_t nRow = 0; nRow < 8; ++nRow) + { + aMsg = "Value at Cell C" + OString::number(nRow+1); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected[nRow], static_cast(m_pDoc->GetValue(2, nRow, 0))); + } + + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testFormulaGroupWithForwardSelfReference() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); + m_pDoc->InsertTab(0, "1"); + + OUString aFormula; + m_pDoc->SetValue(2, 4, 0, 10.0); // C5 <== 10 + + for (size_t nRow = 0; nRow < 4; ++nRow) + { + // Formula-group in B1:B4 with first cell = "=SUM($A1:$A1024) + C1" + aFormula = "=SUM($A" + OUString::number(1 + nRow) + + ":$A" + OUString::number(1024 + nRow) + ") + C" + OUString::number(nRow + 1); + m_pDoc->SetFormula(ScAddress(1, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + + // Formula-group in C1:C4 with first cell = "=SUM($A1:$A1024) + C2" + aFormula = "=SUM($A" + OUString::number(1 + nRow) + + ":$A" + OUString::number(1024 + nRow) + ") + C" + OUString::number(nRow + 2); + m_pDoc->SetFormula(ScAddress(2, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + m_xDocShell->DoHardRecalc(); + + OString aMsg; + for (size_t nCol = 0; nCol < 2; ++nCol) + { + for (size_t nRow = 0; nRow < 4; ++nRow) + { + aMsg = "Value at Cell (Col = " + OString::number(nCol + 1) + ", Row = " + OString::number(nRow) + ", Tab = 0)"; + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), 10.0, m_pDoc->GetValue(1 + nCol, nRow, 0)); + } + } + + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testFormulaGroupsInCyclesAndWithSelfReference() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); + m_pDoc->InsertTab(0, "1"); + + m_pDoc->SetValue(1, 0, 0, 1.0); // B1 <== 1 + m_pDoc->SetValue(3, 0, 0, 2.0); // D1 <== 2 + OUString aFormula; + + for (size_t nRow = 0; nRow < 5; ++nRow) + { + // Formula-group in C1:C5 with first cell = "=SUM($A1:$A1024) + D1" + aFormula = "=SUM($A" + OUString::number(1 + nRow) + + ":$A" + OUString::number(1024 + nRow) + ") + D" + OUString::number(nRow + 1); + m_pDoc->SetFormula(ScAddress(2, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + + if (nRow == 0) + continue; + + // nRow starts from 1 till 4 (for D2 to D5). + // Formula-group in D2:D5 with first cell = "=SUM($A1:$A1024) + D1 + B2" + aFormula = "=SUM($A" + OUString::number(nRow) + + ":$A" + OUString::number(1023 + nRow) + ") + D" + OUString::number(nRow) + + " + B" + OUString::number(nRow + 1); + m_pDoc->SetFormula(ScAddress(3, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + + // Formula-group in B2:B5 with first cell = "=SUM($A1:$A1024) + C1 + B1" + aFormula = "=SUM($A" + OUString::number(nRow) + + ":$A" + OUString::number(1023 + nRow) + ") + C" + OUString::number(nRow) + + " + B" + OUString::number(nRow); + m_pDoc->SetFormula(ScAddress(1, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + m_xDocShell->DoHardRecalc(); + m_pDoc->SetAutoCalc(true); + + const ScRange aChangeRange(1, 1, 0, 1, 4, 0); // B2:B5 + ScMarkData aMark(m_pDoc->GetSheetLimits()); + aMark.SelectOneTable(0); + + // Set up clip document. + ScDocument aClipDoc(SCDOCMODE_CLIP); + aClipDoc.ResetClip(m_pDoc, &aMark); + // Cut B1:B2 to clipboard. + cutToClip(*m_xDocShell, aChangeRange, &aClipDoc, false); + pasteFromClip(m_pDoc, aChangeRange, &aClipDoc); + + double fExpected[3][5] = { + { 1, 3, 8, 21, 55 }, + { 2, 5, 13, 34, 89 }, + { 2, 5, 13, 34, 89 } + }; + + OString aMsg; + for (size_t nCol = 0; nCol < 3; ++nCol) + { + for (size_t nRow = 0; nRow < 5; ++nRow) + { + aMsg = "Value at Cell (Col = " + OString::number(nCol + 1) + ", Row = " + OString::number(nRow) + ", Tab = 0)"; + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), fExpected[nCol][nRow], m_pDoc->GetValue(1 + nCol, nRow, 0)); + } + } + + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testFormulaGroupsInCyclesAndWithSelfReference2() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); + m_pDoc->InsertTab(0, "1"); + + m_pDoc->SetValue(1, 0, 0, 1.0); // B1 <== 1 + m_pDoc->SetValue(3, 0, 0, 2.0); // D1 <== 2 + m_pDoc->SetValue(4, 0, 0, 1.0); // E1 <== 1 + OUString aFormula; + + for (size_t nRow = 0; nRow < 5; ++nRow) + { + // Formula-group in C1:C5 with first cell = "=SUM($A1:$A1024) + D1 + E1" + aFormula = "=SUM($A" + OUString::number(1 + nRow) + + ":$A" + OUString::number(1024 + nRow) + ") + D" + OUString::number(nRow + 1) + + " + E" + OUString::number(nRow + 1); + m_pDoc->SetFormula(ScAddress(2, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + + if (nRow == 0) + continue; + + // Formula-group in B2:B5 with first cell = "=SUM($A1:$A1024) + C1 + B1" + aFormula = "=SUM($A" + OUString::number(nRow) + + ":$A" + OUString::number(1023 + nRow) + ") + C" + OUString::number(nRow) + + " + B" + OUString::number(nRow); + m_pDoc->SetFormula(ScAddress(1, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + + // Formula-group in D2:D5 with first cell = "=SUM($A1:$A1024) + D1 + B2" + aFormula = "=SUM($A" + OUString::number(nRow) + + ":$A" + OUString::number(1023 + nRow) + ") + D" + OUString::number(nRow) + + " + B" + OUString::number(nRow + 1); + m_pDoc->SetFormula(ScAddress(3, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + + // Formula-group in E2:E5 with first cell = "=SUM($A1:$A1024) + E1 + D2" + aFormula = "=SUM($A" + OUString::number(nRow) + + ":$A" + OUString::number(1023 + nRow) + ") + E" + OUString::number(nRow) + + " + D" + OUString::number(nRow + 1); + m_pDoc->SetFormula(ScAddress(4, nRow, 0), aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + m_xDocShell->DoHardRecalc(); + + double fExpected[4][5] = { + { 1, 4, 17, 70, 286 }, + { 3, 13, 53, 216, 881 }, + { 2, 6, 23, 93, 379 }, + { 1, 7, 30, 123, 502 } + }; + + OString aMsg; + for (size_t nCol = 0; nCol < 4; ++nCol) + { + for (size_t nRow = 0; nRow < 5; ++nRow) + { + aMsg = "Value at Cell (Col = " + OString::number(nCol + 1) + ", Row = " + OString::number(nRow) + ", Tab = 0)"; + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), fExpected[nCol][nRow], m_pDoc->GetValue(1 + nCol, nRow, 0)); + } + } + + m_pDoc->DeleteTab(0); +} + +void ScParallelismTest::testFormulaGroupsInCyclesAndWithSelfReference3() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); + m_pDoc->InsertTab(0, "1"); + + m_pDoc->SetValue(1, 1, 0, 2.0); // B2 <== 2 + for (size_t nRow = 1; nRow < 105; ++nRow) + { + // Formula-group in B3:B104 with first cell "=D2+0.001" + if( nRow != 1 ) + m_pDoc->SetFormula(ScAddress(1, nRow, 0), "=D" + OUString::number(nRow) + "+0.001", + formula::FormulaGrammar::GRAM_NATIVE_UI); + // Formula-group in C2:C104 with first cell "=B2*1.01011" + m_pDoc->SetFormula(ScAddress(2, nRow, 0), "=B" + OUString::number(nRow + 1) + "*1.01011", + formula::FormulaGrammar::GRAM_NATIVE_UI); + // Formula-group in D2:C104 with first cell "=C2*1.02" + m_pDoc->SetFormula(ScAddress(3, nRow, 0), "=C" + OUString::number(nRow + 1) + "*1.02", + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + m_xDocShell->DoHardRecalc(); + + // What happens with tdf#132451 is that the copy&paste C6->C5 really just sets the dirty flag + // for C5 and all the cells that depend on it (D5,B6,C6,D6,B7,...), and it also resets + // flags marking the C formula group as disabled for parallel calculation because of the cycle. + m_pDoc->SetFormula(ScAddress(2, 4, 0), "=B5*1.01011", formula::FormulaGrammar::GRAM_NATIVE_UI); + m_pDoc->GetFormulaCell(ScAddress(2,4,0))->GetCellGroup()->mbPartOfCycle = false; + m_pDoc->GetFormulaCell(ScAddress(2,4,0))->GetCellGroup()->meCalcState = sc::GroupCalcEnabled; + + m_pDoc->SetAutoCalc(true); + // Without the fix, getting value of C5 would try to parallel-interpret formula group in B + // from its first dirty cell (B6), which depends on D5, which depends on C5, where the cycle + // would be detected and dependency check would bail out. But the result from Interpret()-ing + // D5 would be used and D5's dirty flag reset, with D5 value incorrect. + m_pDoc->GetValue(2,4,0); + + double fExpected[2][3] = { + { 2.19053373572776, 2.21268003179597, 2.25693363243189 }, + { 2.25793363243189, 2.28076134145577, 2.32637656828489 } + }; + for (size_t nCol = 1; nCol < 4; ++nCol) + { + for (size_t nRow = 4; nRow < 6; ++nRow) + { + OString aMsg = "Value at Cell (Col = " + OString::number(nCol) + ", Row = " + OString::number(nRow) + ", Tab = 0)"; + ASSERT_DOUBLES_EQUAL_MESSAGE(aMsg.getStr(), fExpected[nRow - 4][nCol - 1], m_pDoc->GetValue(nCol, nRow, 0)); + } + } + + m_pDoc->DeleteTab(0); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(ScParallelismTest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/ucalc_range.cxx b/sc/qa/unit/ucalc_range.cxx new file mode 100644 index 000000000000..30f8a1f8cc3c --- /dev/null +++ b/sc/qa/unit/ucalc_range.cxx @@ -0,0 +1,189 @@ +/* -*- 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 +#include "helper/qahelper.hxx" +#include +#include +#include +#include +#include + +#include +#include +#include + +class ScRangeTest : public ScSimpleBootstrapFixture +{ +public: + CPPUNIT_TEST_SUITE(ScRangeTest); + CPPUNIT_TEST(testOverlap); + CPPUNIT_TEST(testRangeParsing); + CPPUNIT_TEST(testAddressParsing); + CPPUNIT_TEST(testTdf147451); + CPPUNIT_TEST_SUITE_END(); + + void testOverlap(); + void testRangeParsing(); + void testAddressParsing(); + void testTdf147451(); +}; + +void ScRangeTest::testOverlap() +{ + ScRange aRange1( ScAddress( 0, 0, 0 ), ScAddress( 1, 1, 1 )); + CPPUNIT_ASSERT(aRange1.Contains( ScAddress( 0, 0, 0 ))); + CPPUNIT_ASSERT(aRange1.Contains( ScAddress( 1, 1, 1 ))); + CPPUNIT_ASSERT(!aRange1.Contains( ScAddress( 2, 1, 1 ))); + CPPUNIT_ASSERT(!aRange1.Contains( ScAddress( 1, 2, 1 ))); + CPPUNIT_ASSERT(!aRange1.Contains( ScAddress( 1, 1, 2 ))); + + ScRange aRange2( ScAddress( 0, 0, 0 ), ScAddress( 10, 10, 10 )); + ScRange aRange3( ScAddress( 5, 5, 5 ), ScAddress( 15, 15, 15 )); + CPPUNIT_ASSERT(!aRange2.Contains( aRange3 )); + CPPUNIT_ASSERT(!aRange3.Contains( aRange2 )); + CPPUNIT_ASSERT(aRange2.Intersects( aRange3 )); + CPPUNIT_ASSERT(aRange3.Intersects( aRange2 )); + CPPUNIT_ASSERT(!aRange3.Intersects( aRange1 )); + CPPUNIT_ASSERT(!aRange1.Intersects( aRange3 )); +} + +void ScRangeTest::testRangeParsing() +{ + ScRange aRange; + ScRefFlags nRes = aRange.Parse(":1", *m_pDoc, formula::FormulaGrammar::CONV_OOO); + CPPUNIT_ASSERT_MESSAGE("Should fail to parse.", !(nRes & ScRefFlags::VALID)); +} + +void ScRangeTest::testAddressParsing() +{ + ScAddress aAddr; + ScRefFlags nRes = aAddr.Parse("1", *m_pDoc, formula::FormulaGrammar::CONV_OOO); + CPPUNIT_ASSERT_MESSAGE("Should fail to parse.", !(nRes & ScRefFlags::VALID)); +} + +void ScRangeTest::testTdf147451() +{ + ScAddress aAddr; + // "Sheet1" is technically a valid address like "XF1", but it should overflow. + ScRefFlags nRes = aAddr.Parse("Sheet1", *m_pDoc, formula::FormulaGrammar::CONV_OOO); + CPPUNIT_ASSERT_MESSAGE("Should fail to parse.", !(nRes & ScRefFlags::VALID)); +} + +class ScRangeUpdaterTest : public CppUnit::TestFixture +{ +public: + + virtual void setUp() override + { + utl::ConfigManager::EnableFuzzing(); + ScDLL::Init(); + ScGlobal::Init(); + } + void testUpdateInsertTabBeforePos(); + void testUpdateInsertTabAtPos(); + void testUpdateInsertTabAfterPos(); + void testUpdateDeleteTabBeforePos(); + void testUpdateDeleteTabAtPos(); + void testUpdateDeleteTabAfterPos(); + + CPPUNIT_TEST_SUITE(ScRangeUpdaterTest); + CPPUNIT_TEST(testUpdateInsertTabBeforePos); + CPPUNIT_TEST(testUpdateInsertTabAtPos); + CPPUNIT_TEST(testUpdateInsertTabAfterPos); + CPPUNIT_TEST(testUpdateDeleteTabBeforePos); + CPPUNIT_TEST(testUpdateDeleteTabAtPos); + CPPUNIT_TEST(testUpdateDeleteTabAfterPos); + CPPUNIT_TEST_SUITE_END(); +}; + +void ScRangeUpdaterTest::testUpdateInsertTabBeforePos() +{ + ScDocument aDoc; + ScAddress aAddr(1, 1, 1); + sc::RefUpdateInsertTabContext aContext(aDoc, 0, 1); + ScRangeUpdater::UpdateInsertTab(aAddr, aContext); + CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 2), aAddr); +} + +void ScRangeUpdaterTest::testUpdateInsertTabAtPos() +{ + ScDocument aDoc; + ScAddress aAddr(1, 1, 1); + sc::RefUpdateInsertTabContext aContext(aDoc, 1, 1); + ScRangeUpdater::UpdateInsertTab(aAddr, aContext); + CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 2), aAddr); +} + +void ScRangeUpdaterTest::testUpdateInsertTabAfterPos() +{ + ScDocument aDoc; + ScAddress aAddr(1, 1, 1); + sc::RefUpdateInsertTabContext aContext(aDoc, 2, 1); + ScRangeUpdater::UpdateInsertTab(aAddr, aContext); + CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 1), aAddr); +} + +void ScRangeUpdaterTest::testUpdateDeleteTabBeforePos() +{ + ScDocument aDoc; + ScAddress aAddr(1, 1, 1); + sc::RefUpdateDeleteTabContext aContext(aDoc, 0, 1); + ScRangeUpdater::UpdateDeleteTab(aAddr, aContext); + CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 0), aAddr); +} + +void ScRangeUpdaterTest::testUpdateDeleteTabAtPos() +{ + ScDocument aDoc; + + // Position within deleted range is moved to the front. + { + ScAddress aAddr(1, 1, 1); + sc::RefUpdateDeleteTabContext aContext(aDoc, 1, 1); + ScRangeUpdater::UpdateDeleteTab(aAddr, aContext); + CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 0), aAddr); + } + { + ScAddress aAddr(1, 1, 2); + sc::RefUpdateDeleteTabContext aContext(aDoc, 1, 2); + ScRangeUpdater::UpdateDeleteTab(aAddr, aContext); + CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 0), aAddr); + } + + // Would-be negative results are clamped to 0. + { + ScAddress aAddr(1, 1, 0); + sc::RefUpdateDeleteTabContext aContext(aDoc, 0, 1); + ScRangeUpdater::UpdateDeleteTab(aAddr, aContext); + CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 0), aAddr); + } + { + ScAddress aAddr(1, 1, 1); + sc::RefUpdateDeleteTabContext aContext(aDoc, 0, 2); + ScRangeUpdater::UpdateDeleteTab(aAddr, aContext); + CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 0), aAddr); + } +} + +void ScRangeUpdaterTest::testUpdateDeleteTabAfterPos() +{ + ScDocument aDoc; + ScAddress aAddr(1, 1, 1); + sc::RefUpdateDeleteTabContext aContext(aDoc, 2, 1); + ScRangeUpdater::UpdateDeleteTab(aAddr, aContext); + CPPUNIT_ASSERT_EQUAL(ScAddress(1, 1, 1), aAddr); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(ScRangeTest); +CPPUNIT_TEST_SUITE_REGISTRATION(ScRangeUpdaterTest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/ucalc_rangelst.cxx b/sc/qa/unit/ucalc_rangelst.cxx new file mode 100644 index 000000000000..48d95dddfcbc --- /dev/null +++ b/sc/qa/unit/ucalc_rangelst.cxx @@ -0,0 +1,554 @@ +/* -*- 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 +#include "helper/qahelper.hxx" +#include + +#include + +class Test : public ScSimpleBootstrapFixture +{ +public: + void testDeleteArea_4Ranges(); + void testDeleteArea_3Ranges(); + void testDeleteArea_3Ranges_Case2(); + void testDeleteArea_3Ranges_Case3(); + void testDeleteArea_3Ranges_Case4(); + void testDeleteArea_3Ranges_Case5(); + void testDeleteArea_2Ranges(); + void testDeleteArea_2Ranges_Case2(); + void testDeleteArea_2Ranges_Case3(); + void testDeleteArea_2Ranges_Case4(); + void testDeleteArea_2Ranges_Case5(); + void testDeleteArea_2Ranges_Case6(); + void testDeleteArea_2Ranges_Case7(); + void testDeleteArea_2Ranges_Case8(); + void testDeleteArea_1Range(); + void testDeleteArea_0Ranges(); + void testJoin_Case1(); + void testJoin_Case2(); + void testJoin_Case3(); + void testJoin_Case4(); + void testJoin_Case5(); + void testGetIntersectedRange(); + + void testUpdateReference_DeleteRow(); + void testUpdateReference_DeleteLastRow(); + void testUpdateReference_DeleteCol(); + + void testInsertRow(); + void testInsertCol(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testDeleteArea_4Ranges); + CPPUNIT_TEST(testDeleteArea_3Ranges); + CPPUNIT_TEST(testDeleteArea_3Ranges_Case2); + CPPUNIT_TEST(testDeleteArea_3Ranges_Case3); + CPPUNIT_TEST(testDeleteArea_3Ranges_Case4); + CPPUNIT_TEST(testDeleteArea_3Ranges_Case5); + CPPUNIT_TEST(testDeleteArea_2Ranges); + CPPUNIT_TEST(testDeleteArea_2Ranges_Case2); + CPPUNIT_TEST(testDeleteArea_2Ranges_Case3); + CPPUNIT_TEST(testDeleteArea_2Ranges_Case4); + CPPUNIT_TEST(testDeleteArea_2Ranges_Case5); + CPPUNIT_TEST(testDeleteArea_2Ranges_Case6); + CPPUNIT_TEST(testDeleteArea_2Ranges_Case7); + CPPUNIT_TEST(testDeleteArea_2Ranges_Case8); + CPPUNIT_TEST(testDeleteArea_1Range); + CPPUNIT_TEST(testDeleteArea_0Ranges); + CPPUNIT_TEST(testJoin_Case1); + CPPUNIT_TEST(testJoin_Case2); + CPPUNIT_TEST(testJoin_Case3); + CPPUNIT_TEST(testJoin_Case4); + CPPUNIT_TEST(testJoin_Case5); + CPPUNIT_TEST(testUpdateReference_DeleteRow); + CPPUNIT_TEST(testUpdateReference_DeleteLastRow); + CPPUNIT_TEST(testUpdateReference_DeleteCol); + CPPUNIT_TEST(testGetIntersectedRange); + CPPUNIT_TEST(testInsertRow); + CPPUNIT_TEST(testInsertCol); + CPPUNIT_TEST_SUITE_END(); +}; + +void Test::testDeleteArea_4Ranges() +{ + ScRangeList aList(ScRange(0,0,0,5,5,0)); + aList.DeleteArea(2,2,0,3,3,0); + + CPPUNIT_ASSERT_EQUAL(static_cast(4), aList.size()); + for(SCCOL nCol = 0; nCol <= 5; ++nCol) + { + for(SCROW nRow = 0; nRow <= 5; ++nRow) + { + if((nCol == 2 || nCol == 3) && ( nRow == 2 || nRow == 3)) + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); + } + } +} + +void Test::testDeleteArea_3Ranges() +{ + ScRangeList aList(ScRange(1,1,0,6,6,0)); + aList.DeleteArea(3,3,0,8,4,0); + + CPPUNIT_ASSERT_EQUAL(static_cast(3), aList.size()); + for(SCCOL nCol = 1; nCol <= 6; ++nCol) + { + for(SCROW nRow = 1; nRow <= 6; ++nRow) + { + if((nRow == 3 || nRow == 4) && (nCol >= 3)) + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); + } + } + + CPPUNIT_ASSERT_EQUAL(static_cast(28), aList.GetCellCount()); +} + +void Test::testDeleteArea_3Ranges_Case2() +{ + ScRangeList aList(ScRange(1,1,0,6,6,0)); + CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); + aList.DeleteArea(0,2,0,2,4,0); + CPPUNIT_ASSERT_EQUAL(static_cast(3), aList.size()); + + // Column 1-2 && Row 2-4 should not be in the range list. The rest should + // be in the list. + for (SCCOL nCol = 1; nCol <= 6; ++nCol) + { + for (SCROW nRow = 1; nRow <= 6; ++nRow) + { + if ((1 <= nCol && nCol <= 2) && (2 <= nRow && nRow <= 4)) + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); + } + } +} + +void Test::testDeleteArea_3Ranges_Case3() +{ + ScRangeList aList(ScRange(1,5,0,6,11,0)); + CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); + aList.DeleteArea(3,2,0,4,8,0); + CPPUNIT_ASSERT_EQUAL(static_cast(3), aList.size()); + + // Column 3-4 && Row 5-8 should not be in the range list. + for (SCCOL nCol = 1; nCol <= 6; ++nCol) + { + for (SCROW nRow = 5; nRow <= 11; ++nRow) + { + if ((3 <= nCol && nCol <= 4) && (5 <= nRow && nRow <= 8)) + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); + } + } +} + +void Test::testDeleteArea_3Ranges_Case4() +{ + ScRangeList aList(ScRange(1,5,0,6,11,0)); + CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); + aList.DeleteArea(3,5,0,4,5,0); + CPPUNIT_ASSERT_EQUAL(static_cast(3), aList.size()); + + // Column 3-4 && Row 5 should not be in the range list. + for (SCCOL nCol = 1; nCol <= 6; ++nCol) + { + for (SCROW nRow = 5; nRow <= 11; ++nRow) + { + if ((3 <= nCol && nCol <= 4) && 5 == nRow ) + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); + } + } +} + +void Test::testDeleteArea_3Ranges_Case5() +{ + ScRangeList aList(ScRange(1,5,0,6,11,0)); + CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); + aList.DeleteArea(6,7,0,6,9,0); + CPPUNIT_ASSERT_EQUAL(static_cast(3), aList.size()); + + // Column 6 && Row 7-9 should not be in the range list. + for (SCCOL nCol = 1; nCol <= 6; ++nCol) + { + for (SCROW nRow = 5; nRow <= 11; ++nRow) + { + if ( nCol == 6 && (7 <= nRow && nRow <= 9)) + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); + } + } +} + +void Test::testDeleteArea_2Ranges() +{ + ScRangeList aList(ScRange(0,0,0,5,5,5)); + ScRangeList aList2(aList); + + aList.DeleteArea(4,4,0,6,7,0); + aList2.DeleteArea(4,4,0,6,7,0); + CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); + CPPUNIT_ASSERT_EQUAL(static_cast(2), aList2.size()); + + for(SCCOL nCol = 0; nCol <= 5; ++nCol) + { + for(SCROW nRow = 0; nRow <= 5; ++nRow) + { + if(nCol>=4 && nRow >= 4) + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); + } + } +} + +void Test::testDeleteArea_2Ranges_Case2() +{ + ScRangeList aList(ScRange(1,1,0,1,5,0)); + aList.DeleteArea(0,3,0,ScSheetLimits::CreateDefault().MaxCol(),3,0); + + for(SCROW nRow = 1; nRow <= 5; ++nRow) + { + if(nRow == 3) + CPPUNIT_ASSERT(!aList.Contains(ScRange(1,3,0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(1,nRow,0))); + } + CPPUNIT_ASSERT_EQUAL(static_cast(4), aList.GetCellCount()); +} + +void Test::testDeleteArea_2Ranges_Case3() +{ + ScRangeList aList(ScRange(0,5,0,2,10,0)); + aList.DeleteArea(2,3,0,3,7,0); + CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); + + // Column 2 Row 5-7 shouldn't be in the list. + for (SCCOL nCol = 0; nCol <= 2; ++nCol) + { + for (SCROW nRow = 5; nRow <= 10; ++nRow) + { + if (nCol == 2 && (5 <= nRow && nRow <= 7)) + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol,nRow,0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol,nRow,0))); + } + } +} + +void Test::testDeleteArea_2Ranges_Case4() +{ + ScRangeList aList(ScRange(2,3,0,4,7,0)); + aList.DeleteArea(0,1,0,2,5,0); + CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); + + // Column 2 Row 3-5 shouldn't be in the list. + for (SCCOL nCol = 2; nCol <= 4; ++nCol) + { + for (SCROW nRow = 3; nRow <= 7; ++nRow) + { + if (nCol == 2 && (3 <= nRow && nRow <= 5)) + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol,nRow,0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol,nRow,0))); + } + } +} + +void Test::testDeleteArea_2Ranges_Case5() +{ + ScRangeList aList(ScRange(2,2,0,5,5,0)); + aList.DeleteArea(4,5,0,5,5,0); + CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); + + // Column 4 and 5 Row 5 shouldn't be in the list. + for(SCCOL nCol = 2; nCol <= 5; ++nCol) + { + for(SCROW nRow = 2; nRow <= 5; ++nRow) + { + if(nRow == 5 && 4 <= nCol) + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); + } + } +} + +void Test::testDeleteArea_2Ranges_Case6() +{ + ScRangeList aList(ScRange(2,2,0,5,5,0)); + aList.DeleteArea(4,2,0,5,2,0); + CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); + + // Column 4 and 5 Row 2 shouldn't be in the list. + for(SCCOL nCol = 2; nCol <= 5; ++nCol) + { + for(SCROW nRow = 2; nRow <= 5; ++nRow) + { + if(nRow == 2 && 4 <= nCol) + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); + } + } +} + +void Test::testDeleteArea_2Ranges_Case7() +{ + ScRangeList aList(ScRange(2,2,0,5,5,0)); + aList.DeleteArea(2,5,0,2,5,0); + CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); + + // Column 2 Row 5 shouldn't be in the list. + for(SCCOL nCol = 2; nCol <= 5; ++nCol) + { + for(SCROW nRow = 2; nRow <= 5; ++nRow) + { + if(nRow == 5 && nCol == 2) + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); + } + } +} + +void Test::testDeleteArea_2Ranges_Case8() +{ + ScRangeList aList(ScRange(2,2,0,5,5,0)); + aList.DeleteArea(2,2,0,3,2,0); + CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); + + // Column 2 & 3 Row 2 shouldn't be in the list. + for(SCCOL nCol = 2; nCol <= 5; ++nCol) + { + for(SCROW nRow = 2; nRow <= 5; ++nRow) + { + if(nRow == 2 && nCol <= 3) + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0))); + else + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); + } + } +} + +void Test::testDeleteArea_1Range() +{ + ScRangeList aList(ScRange(1,1,0,3,3,0)); + aList.DeleteArea(1,1,0,2,3,0); + + CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); + + for(SCROW nRow = 1; nRow <= 3; ++nRow) + { + CPPUNIT_ASSERT(aList.Contains(ScRange(3,nRow,0))); + } + CPPUNIT_ASSERT_EQUAL(static_cast(3), aList.GetCellCount()); +} + +void Test::testDeleteArea_0Ranges() +{ + ScRangeList aList(ScRange(1,1,0,3,3,0)); + aList.DeleteArea(1,1,0,3,3,0); + + CPPUNIT_ASSERT(aList.empty()); + + ScRangeList aList2(ScRange(1,1,0,3,3,0)); + aList2.DeleteArea(0,0,0,4,4,0); + + CPPUNIT_ASSERT(aList.empty()); +} + +void Test::testJoin_Case1() +{ + ScRangeList aList; + aList.push_back(ScRange(1,1,0,3,3,0)); + aList.Join(ScRange(4,1,0,6,3,0)); + + CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); + CPPUNIT_ASSERT_EQUAL( ScRange(1,1,0,6,3,0), aList[0]); +} + +void Test::testJoin_Case2() +{ + ScRangeList aList; + aList.push_back(ScRange(1,1,0,3,3,0)); + aList.push_back(ScRange(4,1,0,6,3,0)); + aList.push_back(ScRange(7,1,0,9,3,0)); + + aList.Join(aList[2], true); + + CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); + CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,9,3,0), aList[0]); +} + +void Test::testJoin_Case3() +{ + ScRangeList aList; + aList.Join(ScRange(1,1,0,6,6,0)); + aList.Join(ScRange(3,3,0,4,4,0)); + + // The second one should have been swallowed by the first one + CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); + CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,6,6,0), aList[0]); + + // Add a disjoint one + aList.Join(ScRange(8,8,0,9,9,0)); + + // Should be two ones now + CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); + // The first one should still be as is + CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,6,6,0), aList[0]); + // Ditto for the second one + CPPUNIT_ASSERT_EQUAL(ScRange(8,8,0,9,9,0), aList[1]); +} + +void Test::testJoin_Case4() +{ + ScRangeList aList; + aList.Join(ScRange(1,1,0,2,6,0)); + // Join a range that overlaps it and extends it vertically + aList.Join(ScRange(1,4,0,2,8,0)); + + // The one range in the list should have been extended + CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); + CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,2,8,0), aList[0]); + + // Join a range that overlaps it and extends it horizontally + aList.Join(ScRange(2,1,0,4,8,0)); + + // Again, should have just been extended + CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); + CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,4,8,0), aList[0]); + + // And then the same but on top / to the left of existing range + ScRangeList aList2; + aList2.Join(ScRange(4,4,0,8,8,0)); + aList2.Join(ScRange(4,1,0,8,6,0)); + + CPPUNIT_ASSERT_EQUAL(static_cast(1), aList2.size()); + CPPUNIT_ASSERT_EQUAL(ScRange(4,1,0,8,8,0), aList2[0]); + + aList2.Join(ScRange(1,1,0,6,8,0)); + + CPPUNIT_ASSERT_EQUAL(static_cast(1), aList2.size()); + CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,8,8,0), aList2[0]); +} + +void Test::testJoin_Case5() +{ + ScRangeList aList; + aList.Join(ScRange(0,0,0,4,4,0)); + aList.Join(ScRange(8,0,0,10,4,0)); + + // Nothing special so far, two disjoint ranges + CPPUNIT_ASSERT_EQUAL(static_cast(2), aList.size()); + CPPUNIT_ASSERT_EQUAL(ScRange(0,0,0,4,4,0), aList[0]); + CPPUNIT_ASSERT_EQUAL(ScRange(8,0,0,10,4,0), aList[1]); + + // This should join the two ranges into one + aList.Join(ScRange(5,0,0,9,4,0)); + + CPPUNIT_ASSERT_EQUAL(static_cast(1), aList.size()); + CPPUNIT_ASSERT_EQUAL(ScRange(0,0,0,10,4,0), aList[0]); +} + +void Test::testUpdateReference_DeleteRow() +{ + ScRangeList aList(ScRange(1,1,0,4,4,0)); + bool bUpdated = aList.UpdateReference(URM_INSDEL, m_pDoc, ScRange(0,3,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0), 0, -1, 0); + CPPUNIT_ASSERT(bUpdated); + + for(SCCOL nCol = 1; nCol <= 4; ++nCol) + { + for(SCROW nRow = 1; nRow <= 3; ++nRow) + { + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); + } + CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, 4, 0))); + } + CPPUNIT_ASSERT_EQUAL(static_cast(12), aList.GetCellCount()); + + ScRangeList aList2(ScRange(2,2,0,2,2,0)); + aList2.UpdateReference(URM_INSDEL, m_pDoc, ScRange(0,3,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0), 0, -1, 0); + CPPUNIT_ASSERT(aList2.empty()); + + ScRangeList aList3; + aList3.push_back(ScRange(2,2,0,2,8,0)); + aList3.push_back(ScRange(4,2,0,4,8,0)); + aList3.UpdateReference(URM_INSDEL, m_pDoc, ScRange(2,5,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0), 0, -1, 0); + // Verify all ranges in the list have been updated properly. + CPPUNIT_ASSERT_EQUAL(size_t(2), aList3.size()); + CPPUNIT_ASSERT_EQUAL(ScRange(2,2,0,2,7,0), aList3[0]); + CPPUNIT_ASSERT_EQUAL(ScRange(4,2,0,4,7,0), aList3[1]); + + ScRangeList aList4(ScRange(0,0,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0)); + ScRangeList aList4Copy = aList4; + aList4.UpdateReference(URM_INSDEL, m_pDoc, ScRange(14,3,0,m_pDoc->MaxCol(),7,0), 0, -2, 0); + CPPUNIT_ASSERT_EQUAL(aList4Copy, aList4); +} + +void Test::testUpdateReference_DeleteLastRow() +{ + ScRangeList aList(ScRange(1,1,0,4,4,0)); + bool bUpdated = aList.UpdateReference(URM_INSDEL, m_pDoc, ScRange(0,4,0,m_pDoc->MaxCol(),4,0), 0, -1, 0); + CPPUNIT_ASSERT(bUpdated); +} + +void Test::testUpdateReference_DeleteCol() +{ + ScRangeList aList(ScRange(1,1,0,4,4,0)); + bool bUpdated = aList.UpdateReference(URM_INSDEL, m_pDoc, ScRange(3,0,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0), -1, 0, 0); + CPPUNIT_ASSERT(bUpdated); + + for(SCROW nRow = 1; nRow <= 4; ++nRow) + { + for(SCCOL nCol = 1; nCol <= 3; ++nCol) + { + CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0))); + } + CPPUNIT_ASSERT(!aList.Contains(ScRange(4, nRow, 0))); + } + CPPUNIT_ASSERT_EQUAL(static_cast(12), aList.GetCellCount()); +} + +void Test::testGetIntersectedRange() +{ + ScRangeList aList(ScRange(2, 2, 0, 5, 5, 0)); + ScRangeList aIntersecting = aList.GetIntersectedRange(ScRange(0, 0, 0, 3, 3, 0)); + CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(2,2,0,3,3,0)), aIntersecting); +} + +void Test::testInsertRow() +{ + ScRangeList aList(ScRange(1,1,0,4,4,0)); + aList.InsertRow(0, 0, m_pDoc->MaxCol(), 5, 2); + CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(1,1,0,4,6,0)), aList); +} + +void Test::testInsertCol() +{ + ScRangeList aList(ScRange(1,1,0,4,4,0)); + aList.InsertCol(0, 0, m_pDoc->MaxRow(), 5, 2); + CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(1,1,0,6,4,0)), aList); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(Test); + +CPPUNIT_PLUGIN_IMPLEMENT(); +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit