editeng/CppunitTest_editeng_core.mk | 1 editeng/qa/unit/ESelectionTest.cxx | 185 ++++++++++++++++++++++++++++++++++++ include/editeng/ESelection.hxx | 126 ++++++++++-------------- 3 files changed, 238 insertions(+), 74 deletions(-)
New commits: commit 5d579ddc04d2862861a9b948ebc12ace74fc122c Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Tue Dec 5 23:08:25 2023 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Thu Dec 28 04:21:25 2023 +0100 editeng: simplify and clean-up ESelection Change-Id: I8c0ee3f6b0f4e20277e006c15fddbda6ba9c05e6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161340 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/include/editeng/ESelection.hxx b/include/editeng/ESelection.hxx index 2ddc90c997d8..7f5aa8e81cf6 100644 --- a/include/editeng/ESelection.hxx +++ b/include/editeng/ESelection.hxx @@ -21,24 +21,18 @@ struct ESelection { - sal_Int32 nStartPara; - sal_Int32 nStartPos; - sal_Int32 nEndPara; - sal_Int32 nEndPos; + sal_Int32 nStartPara = 0; + sal_Int32 nStartPos = 0; + sal_Int32 nEndPara = 0; + sal_Int32 nEndPos = 0; - ESelection() - : nStartPara(0) - , nStartPos(0) - , nEndPara(0) - , nEndPos(0) - { - } + ESelection() = default; - ESelection(sal_Int32 nStPara, sal_Int32 nStPos, sal_Int32 nEPara, sal_Int32 nEPos) - : nStartPara(nStPara) - , nStartPos(nStPos) - , nEndPara(nEPara) - , nEndPos(nEPos) + ESelection(sal_Int32 _nStartPara, sal_Int32 _nStartPos, sal_Int32 _nEndPara, sal_Int32 _nEndPos) + : nStartPara(_nStartPara) + , nStartPos(_nStartPos) + , nEndPara(_nEndPara) + , nEndPos(_nEndPos) { } @@ -50,71 +44,55 @@ struct ESelection { } - void Adjust(); - bool operator==(const ESelection& rS) const; - bool operator!=(const ESelection& rS) const { return !operator==(rS); } - bool operator<(const ESelection& rS) const; - bool operator>(const ESelection& rS) const; - bool IsZero() const; - bool HasRange() const; -}; + void Adjust() + { + if (nStartPara > nEndPara || (nStartPara == nEndPara && nStartPos > nEndPos)) + { + std::swap(nStartPara, nEndPara); + std::swap(nStartPos, nEndPos); + } + } -template <typename charT, typename traits> -inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream, - ESelection const& sel) -{ - return stream << "ESelection(" << sel.nStartPara << ',' << sel.nStartPos << "," << sel.nEndPara - << "," << sel.nEndPos << ")"; -} + bool operator==(const ESelection& rSelection) const + { + return nStartPara == rSelection.nStartPara && nStartPos == rSelection.nStartPos + && nEndPara == rSelection.nEndPara && nEndPos == rSelection.nEndPos; + } -inline bool ESelection::HasRange() const -{ - return (nStartPara != nEndPara) || (nStartPos != nEndPos); -} + bool operator!=(const ESelection& rSelection) const = default; -inline bool ESelection::IsZero() const -{ - return ((nStartPara == 0) && (nStartPos == 0) && (nEndPara == 0) && (nEndPos == 0)); -} + bool operator<(const ESelection& rSelection) const + { + // The selection must be adjusted. + // => Only check if end of 'this' < Start of rS + return nEndPara < rSelection.nStartPara + || (nEndPara == rSelection.nStartPara && nEndPos < rSelection.nStartPos + && operator!=(rSelection)); + } -inline bool ESelection::operator==(const ESelection& rS) const -{ - return ((nStartPara == rS.nStartPara) && (nStartPos == rS.nStartPos) - && (nEndPara == rS.nEndPara) && (nEndPos == rS.nEndPos)); -} + bool operator>(const ESelection& rSelection) const + { + // The selection must be adjusted. + // => Only check if end of 'this' < Start of rS + return nStartPara > rSelection.nEndPara + || (nStartPara == rSelection.nEndPara && nStartPos > rSelection.nEndPos + && operator!=(rSelection)); + } -inline bool ESelection::operator<(const ESelection& rS) const -{ - // The selection must be adjusted. - // => Only check if end of 'this' < Start of rS - return (nEndPara < rS.nStartPara) - || ((nEndPara == rS.nStartPara) && (nEndPos < rS.nStartPos) && !operator==(rS)); -} + bool IsZero() const + { + return nStartPara == 0 && nStartPos == 0 && nEndPara == 0 && nEndPos == 0; + } -inline bool ESelection::operator>(const ESelection& rS) const -{ - // The selection must be adjusted. - // => Only check if end of 'this' < Start of rS - return (nStartPara > rS.nEndPara) - || ((nStartPara == rS.nEndPara) && (nStartPos > rS.nEndPos) && !operator==(rS)); -} + bool HasRange() const { return nStartPara != nEndPara || nStartPos != nEndPos; } +}; -inline void ESelection::Adjust() +template <typename charT, typename traits> +inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream, + ESelection const& rSelection) { - bool bSwap = false; - if (nStartPara > nEndPara) - bSwap = true; - else if ((nStartPara == nEndPara) && (nStartPos > nEndPos)) - bSwap = true; - - if (bSwap) - { - sal_Int32 nSPar = nStartPara; - sal_Int32 nSPos = nStartPos; - nStartPara = nEndPara; - nStartPos = nEndPos; - nEndPara = nSPar; - nEndPos = nSPos; - } + return stream << "ESelection(" << rSelection.nStartPara << ',' << rSelection.nStartPos << "," + << rSelection.nEndPara << "," << rSelection.nEndPos << ")"; } + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 23bef8567e839a3894deb3fd05f1c237d2dcc14f Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Tue Dec 5 22:49:38 2023 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Thu Dec 28 04:21:17 2023 +0100 editeng: add ESelection unit tests Change-Id: I79cff7b08944fe81c785c224587e4e6f6c8ff9c2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161339 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/editeng/CppunitTest_editeng_core.mk b/editeng/CppunitTest_editeng_core.mk index 9b79048b637a..67a3c949555b 100644 --- a/editeng/CppunitTest_editeng_core.mk +++ b/editeng/CppunitTest_editeng_core.mk @@ -13,6 +13,7 @@ $(eval $(call gb_CppunitTest_CppunitTest,editeng_core)) $(eval $(call gb_CppunitTest_add_exception_objects,editeng_core, \ editeng/qa/unit/core-test \ + editeng/qa/unit/ESelectionTest \ )) $(eval $(call gb_CppunitTest_use_library_objects,editeng_core,editeng)) diff --git a/editeng/qa/unit/ESelectionTest.cxx b/editeng/qa/unit/ESelectionTest.cxx new file mode 100644 index 000000000000..2d1f1a807229 --- /dev/null +++ b/editeng/qa/unit/ESelectionTest.cxx @@ -0,0 +1,185 @@ +/* -*- 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 <test/bootstrapfixture.hxx> +#include <editeng/ESelection.hxx> + +namespace +{ +class ESelectionTest : public test::BootstrapFixture +{ +}; + +CPPUNIT_TEST_FIXTURE(ESelectionTest, testConstruction) +{ + { + ESelection aNewSelection; + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aNewSelection.nStartPara); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aNewSelection.nStartPos); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aNewSelection.nEndPara); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aNewSelection.nEndPos); + } + + { + ESelection aNewSelection(1, 2, 3, 4); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aNewSelection.nStartPara); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aNewSelection.nStartPos); + CPPUNIT_ASSERT_EQUAL(sal_Int32(3), aNewSelection.nEndPara); + CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aNewSelection.nEndPos); + } + + { + ESelection aNewSelection = { 1, 2, 3, 4 }; + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aNewSelection.nStartPara); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aNewSelection.nStartPos); + CPPUNIT_ASSERT_EQUAL(sal_Int32(3), aNewSelection.nEndPara); + CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aNewSelection.nEndPos); + } + + { + ESelection aNewSelection{ 1, 2, 3, 4 }; + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aNewSelection.nStartPara); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aNewSelection.nStartPos); + CPPUNIT_ASSERT_EQUAL(sal_Int32(3), aNewSelection.nEndPara); + CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aNewSelection.nEndPos); + } + + { + ESelection aNewSelection(1, 2); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aNewSelection.nStartPara); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aNewSelection.nStartPos); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aNewSelection.nEndPara); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aNewSelection.nEndPos); + } +} + +CPPUNIT_TEST_FIXTURE(ESelectionTest, testAssign) +{ + ESelection aSelection1; + ESelection aSelection2; + + // set selection2 + aSelection2 = ESelection{ 1, 1, 2, 1 }; + + // selections are not equal + CPPUNIT_ASSERT(aSelection2 != aSelection1); + + // assign selection1 with selection2 content + aSelection1 = aSelection2; + + // expect selections to be equal + CPPUNIT_ASSERT_EQUAL(aSelection2, aSelection1); +} + +CPPUNIT_TEST_FIXTURE(ESelectionTest, testEquals) +{ + ESelection aSelection1; + ESelection aSelection2; + + // both empty = equal + CPPUNIT_ASSERT_EQUAL(aSelection1, aSelection2); + + // set selection1 + aSelection1 = { 1, 2, 3, 4 }; + + // expect them to be not equal + CPPUNIT_ASSERT(aSelection1 != aSelection2); + + // set selection 2 to the same value + aSelection2 = { 1, 2, 3, 4 }; + + // equal again + CPPUNIT_ASSERT_EQUAL(aSelection1, aSelection2); +} + +CPPUNIT_TEST_FIXTURE(ESelectionTest, testIsZero) +{ + ESelection aEmpty; + CPPUNIT_ASSERT_EQUAL(true, aEmpty.IsZero()); + + CPPUNIT_ASSERT_EQUAL(false, ESelection(1, 2, 1, 2).IsZero()); + CPPUNIT_ASSERT_EQUAL(true, ESelection(0, 0, 0, 0).IsZero()); +} + +CPPUNIT_TEST_FIXTURE(ESelectionTest, testLess) +{ + // Both equal + CPPUNIT_ASSERT_EQUAL(false, ESelection(0, 0, 1, 1) < ESelection(0, 0, 1, 1)); + + // Obviously not less + CPPUNIT_ASSERT_EQUAL(false, ESelection(0, 2, 0, 2) < ESelection(0, 1, 0, 1)); + + // Equal at a point therfore not strictly "<" + CPPUNIT_ASSERT_EQUAL(false, ESelection(0, 0, 0, 0) < ESelection(0, 0, 0, 1)); + + // Strictly "<" + CPPUNIT_ASSERT_EQUAL(true, ESelection(0, 0, 0, 0) < ESelection(0, 1, 0, 1)); + + // Check if paragraph taken into account + CPPUNIT_ASSERT_EQUAL(false, ESelection(1, 0, 1, 0) < ESelection(0, 1, 0, 1)); + CPPUNIT_ASSERT_EQUAL(true, ESelection(1, 0, 1, 0) < ESelection(2, 0, 2, 0)); +} + +CPPUNIT_TEST_FIXTURE(ESelectionTest, testGreater) +{ + // Both equal + CPPUNIT_ASSERT_EQUAL(false, ESelection(0, 0, 1, 1) > ESelection(0, 0, 1, 1)); + + // Obviously not greater + CPPUNIT_ASSERT_EQUAL(false, ESelection(0, 1, 0, 1) > ESelection(0, 2, 0, 2)); + + // Equal at a point therfore not strictly ">" + CPPUNIT_ASSERT_EQUAL(false, ESelection(0, 0, 0, 1) > ESelection(0, 0, 0, 0)); + + // Strictly ">" + CPPUNIT_ASSERT_EQUAL(true, ESelection(0, 1, 0, 1) > ESelection(0, 0, 0, 0)); + + // Check if paragraph taken into account + CPPUNIT_ASSERT_EQUAL(false, ESelection(0, 1, 0, 1) > ESelection(1, 0, 1, 0)); + CPPUNIT_ASSERT_EQUAL(true, ESelection(2, 0, 2, 0) > ESelection(1, 0, 1, 0)); +} + +CPPUNIT_TEST_FIXTURE(ESelectionTest, testAdjust) +{ + // Scenarios where Adjust doesn't change the selection + ESelection aSelection; + aSelection.Adjust(); + CPPUNIT_ASSERT_EQUAL(ESelection(), aSelection); + + aSelection = { 1, 1, 1, 1 }; + aSelection.Adjust(); + CPPUNIT_ASSERT_EQUAL(ESelection(1, 1, 1, 1), aSelection); + + aSelection = { 1, 1, 1, 2 }; + aSelection.Adjust(); + CPPUNIT_ASSERT_EQUAL(ESelection(1, 1, 1, 2), aSelection); + + aSelection = { 1, 1, 2, 1 }; + aSelection.Adjust(); + CPPUNIT_ASSERT_EQUAL(ESelection(1, 1, 2, 1), aSelection); + + // Position is greater - flip + aSelection = { 1, 2, 1, 1 }; + aSelection.Adjust(); + CPPUNIT_ASSERT_EQUAL(ESelection(1, 1, 1, 2), aSelection); + + // Paragraph is greater - flip + aSelection = { 2, 1, 1, 1 }; + aSelection.Adjust(); + CPPUNIT_ASSERT_EQUAL(ESelection(1, 1, 2, 1), aSelection); + + // Both are greater - flip + aSelection = { 2, 2, 1, 1 }; + aSelection.Adjust(); + CPPUNIT_ASSERT_EQUAL(ESelection(1, 1, 2, 2), aSelection); +} + +} // end anonymous namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */