diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /tools/qa | |
parent | Initial commit. (diff) | |
download | libreoffice-cb75148ebd0135178ff46f89a30139c44f8d2040.tar.xz libreoffice-cb75148ebd0135178ff46f89a30139c44f8d2040.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tools/qa')
32 files changed, 3764 insertions, 0 deletions
diff --git a/tools/qa/cppunit/test_100mm2twips.cxx b/tools/qa/cppunit/test_100mm2twips.cxx new file mode 100644 index 000000000..1fb69d982 --- /dev/null +++ b/tools/qa/cppunit/test_100mm2twips.cxx @@ -0,0 +1,53 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/types.h> + +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <tools/UnitConversion.hxx> + +class UnitConversionTest : public CppUnit::TestFixture +{ +public: + void testSanitiseMm100ToTwip() + { + CPPUNIT_ASSERT_EQUAL(sal_Int64(145), sanitiseMm100ToTwip(255)); + CPPUNIT_ASSERT_EQUAL(sal_Int64(-145), sanitiseMm100ToTwip(-255)); + } + + void testConvertPointToMm100() + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(599.72, convertPointToMm100(17.0), 1E-2); + CPPUNIT_ASSERT_EQUAL(sal_Int64(600), convertPointToMm100(sal_Int64(17))); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(22930.55, convertPointToMm100(650.0), 1E-2); + CPPUNIT_ASSERT_EQUAL(sal_Int64(22931), convertPointToMm100(sal_Int64(650))); + } + + CPPUNIT_TEST_SUITE(UnitConversionTest); + CPPUNIT_TEST(testSanitiseMm100ToTwip); + CPPUNIT_TEST(testConvertPointToMm100); + CPPUNIT_TEST_SUITE_END(); +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(UnitConversionTest); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_GenericTypeSerializer.cxx b/tools/qa/cppunit/test_GenericTypeSerializer.cxx new file mode 100644 index 000000000..d378dd7c3 --- /dev/null +++ b/tools/qa/cppunit/test_GenericTypeSerializer.cxx @@ -0,0 +1,144 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/types.h> + +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <tools/GenericTypeSerializer.hxx> +#include <tools/stream.hxx> +#include <tools/gen.hxx> + +namespace tools +{ +class GenericTypeSerializerTest : public CppUnit::TestFixture +{ +public: + void testRoundtripPoint() + { + Point aPoint(20, 50); + SvMemoryStream aStream; + GenericTypeSerializer aSerializer(aStream); + aSerializer.writePoint(aPoint); + aStream.Seek(STREAM_SEEK_TO_BEGIN); + Point aReadPoint; + aSerializer.readPoint(aReadPoint); + CPPUNIT_ASSERT_EQUAL(aPoint, aReadPoint); + } + + void testRoundtripSize() + { + Size aSize(40, 80); + SvMemoryStream aStream; + GenericTypeSerializer aSerializer(aStream); + aSerializer.writeSize(aSize); + aStream.Seek(STREAM_SEEK_TO_BEGIN); + Size aReadSize; + aSerializer.readSize(aReadSize); + CPPUNIT_ASSERT_EQUAL(aSize, aReadSize); + } + + void testRoundtripRectangle() + { + { + Rectangle aRectangle; + CPPUNIT_ASSERT(aRectangle.IsEmpty()); + SvMemoryStream aStream; + aStream.Seek(STREAM_SEEK_TO_BEGIN); + GenericTypeSerializer aSerializer(aStream); + aSerializer.writeRectangle(aRectangle); + aStream.Seek(STREAM_SEEK_TO_BEGIN); + // Need to set the rectangle to non-empty, so it will be set to empty later + Rectangle aReadRectangle(Point(20, 50), Size(10, 30)); + aSerializer.readRectangle(aReadRectangle); + CPPUNIT_ASSERT(aRectangle.IsEmpty()); + } + + { + Rectangle aRectangle(Point(20, 50), Size(10, 30)); + SvMemoryStream aStream; + aStream.Seek(STREAM_SEEK_TO_BEGIN); + GenericTypeSerializer aSerializer(aStream); + aSerializer.writeRectangle(aRectangle); + aStream.Seek(STREAM_SEEK_TO_BEGIN); + Rectangle aReadRectangle; + aSerializer.readRectangle(aReadRectangle); + CPPUNIT_ASSERT_EQUAL(aRectangle.Top(), aReadRectangle.Top()); + CPPUNIT_ASSERT_EQUAL(aRectangle.Left(), aReadRectangle.Left()); + CPPUNIT_ASSERT_EQUAL(aRectangle.Right(), aReadRectangle.Right()); + CPPUNIT_ASSERT_EQUAL(aRectangle.Bottom(), aReadRectangle.Bottom()); + } + } + + void testRoundtripFraction() + { + { + Fraction aFraction(2, 5); + CPPUNIT_ASSERT_EQUAL(true, aFraction.IsValid()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aFraction.GetNumerator()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(5), aFraction.GetDenominator()); + + SvMemoryStream aStream; + aStream.Seek(STREAM_SEEK_TO_BEGIN); + GenericTypeSerializer aSerializer(aStream); + aSerializer.writeFraction(aFraction); + + aStream.Seek(STREAM_SEEK_TO_BEGIN); + + Fraction aReadFraction(1, 2); + aSerializer.readFraction(aReadFraction); + CPPUNIT_ASSERT_EQUAL(true, aReadFraction.IsValid()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aReadFraction.GetNumerator()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(5), aReadFraction.GetDenominator()); + } + { + Fraction aFraction(1, 0); + CPPUNIT_ASSERT_EQUAL(false, aFraction.IsValid()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aFraction.GetNumerator()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aFraction.GetDenominator()); + + SvMemoryStream aStream; + aStream.Seek(STREAM_SEEK_TO_BEGIN); + GenericTypeSerializer aSerializer(aStream); + aSerializer.writeFraction(aFraction); + + aStream.Seek(STREAM_SEEK_TO_BEGIN); + + Fraction aReadFraction(1, 2); + aSerializer.readFraction(aReadFraction); + CPPUNIT_ASSERT_EQUAL(false, aReadFraction.IsValid()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aReadFraction.GetNumerator()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aReadFraction.GetDenominator()); + } + } + + CPPUNIT_TEST_SUITE(GenericTypeSerializerTest); + CPPUNIT_TEST(testRoundtripPoint); + CPPUNIT_TEST(testRoundtripSize); + CPPUNIT_TEST(testRoundtripRectangle); + CPPUNIT_TEST(testRoundtripFraction); + CPPUNIT_TEST_SUITE_END(); +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(GenericTypeSerializerTest); + +} // namespace tools + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_Wildcard.cxx b/tools/qa/cppunit/test_Wildcard.cxx new file mode 100644 index 000000000..1760ca693 --- /dev/null +++ b/tools/qa/cppunit/test_Wildcard.cxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 <sal/config.h> + +#include <sal/types.h> +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <tools/wldcrd.hxx> + +namespace +{ +class Test : public CppUnit::TestFixture +{ +public: + void test_Wildcard(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(test_Wildcard); + CPPUNIT_TEST_SUITE_END(); +}; + +void Test::test_Wildcard() +{ + WildCard wildcard(u"*.html;*??a;*\\*abc;*\\?xyz", ';'); // tdf#148253 + CPPUNIT_ASSERT(wildcard.Matches(u"foo.html")); + CPPUNIT_ASSERT(wildcard.Matches(u"foo.ht.html")); // test stepping back after partial match + CPPUNIT_ASSERT(wildcard.Matches(u"foo.html.html")); // test stepping back after full match + CPPUNIT_ASSERT(wildcard.Matches(u"??aa")); // test stepping back with question marks + CPPUNIT_ASSERT(wildcard.Matches(u"111*abc")); // test escaped asterisk + CPPUNIT_ASSERT(!wildcard.Matches(u"111-abc")); // test escaped asterisk + CPPUNIT_ASSERT(wildcard.Matches(u"111?xyz")); // test escaped question mark + CPPUNIT_ASSERT(!wildcard.Matches(u"111-xyz")); // test escaped question mark +} + +CPPUNIT_TEST_SUITE_REGISTRATION(Test); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/tools/qa/cppunit/test_bigint.cxx b/tools/qa/cppunit/test_bigint.cxx new file mode 100644 index 000000000..140562df0 --- /dev/null +++ b/tools/qa/cppunit/test_bigint.cxx @@ -0,0 +1,97 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <tools/bigint.hxx> + +namespace tools +{ +class BigIntTest : public CppUnit::TestFixture +{ +public: + void testConstructionFromLongLong(); + + CPPUNIT_TEST_SUITE(BigIntTest); + CPPUNIT_TEST(testConstructionFromLongLong); + CPPUNIT_TEST_SUITE_END(); +}; + +void BigIntTest::testConstructionFromLongLong() +{ + // small positive number + { + BigInt bi(static_cast<sal_Int64>(42)); + CPPUNIT_ASSERT(!bi.IsZero()); + CPPUNIT_ASSERT(!bi.IsNeg()); + CPPUNIT_ASSERT(bi.IsLong()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(42), static_cast<sal_Int32>(bi)); + } + + // small negative number + { + BigInt bi(static_cast<sal_Int64>(-42)); + CPPUNIT_ASSERT(!bi.IsZero()); + CPPUNIT_ASSERT(bi.IsNeg()); + CPPUNIT_ASSERT(bi.IsLong()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-42), static_cast<sal_Int32>(bi)); + } + +#if SAL_TYPES_SIZEOFLONG < SAL_TYPES_SIZEOFLONGLONG + // positive number just fitting to sal_Int32 + { + BigInt bi(static_cast<sal_Int64>(std::numeric_limits<sal_Int32>::max())); + CPPUNIT_ASSERT(!bi.IsZero()); + CPPUNIT_ASSERT(!bi.IsNeg()); + CPPUNIT_ASSERT(bi.IsLong()); + CPPUNIT_ASSERT_EQUAL(std::numeric_limits<sal_Int32>::max(), static_cast<sal_Int32>(bi)); + } + + // negative number just fitting to sal_Int32 + { + BigInt bi(static_cast<sal_Int64>(std::numeric_limits<sal_Int32>::min())); + CPPUNIT_ASSERT(!bi.IsZero()); + CPPUNIT_ASSERT(bi.IsNeg()); + CPPUNIT_ASSERT(bi.IsLong()); + CPPUNIT_ASSERT_EQUAL(std::numeric_limits<sal_Int32>::min(), static_cast<sal_Int32>(bi)); + } + + // positive number not fitting to sal_Int32 + { + BigInt bi(static_cast<sal_Int64>(std::numeric_limits<sal_Int32>::max()) + 1); + CPPUNIT_ASSERT(!bi.IsZero()); + CPPUNIT_ASSERT(!bi.IsNeg()); + CPPUNIT_ASSERT(!bi.IsLong()); + } + + // negative number not fitting to sal_Int32 + { + BigInt bi(static_cast<sal_Int64>(std::numeric_limits<sal_Int32>::min()) - 1); + CPPUNIT_ASSERT(!bi.IsZero()); + CPPUNIT_ASSERT(bi.IsNeg()); + CPPUNIT_ASSERT(!bi.IsLong()); + } +#endif +} + +CPPUNIT_TEST_SUITE_REGISTRATION(BigIntTest); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_color.cxx b/tools/qa/cppunit/test_color.cxx new file mode 100644 index 000000000..02f23fb3b --- /dev/null +++ b/tools/qa/cppunit/test_color.cxx @@ -0,0 +1,252 @@ +/* -*- 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 <sal/types.h> +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <tools/color.hxx> + +namespace +{ + +class Test: public CppUnit::TestFixture +{ +public: + void testVariables(); + void test_asRGBColor(); + void test_ApplyTintOrShade(); + void test_ApplyLumModOff(); + void testGetColorError(); + void testInvert(); + void testBColor(); + void testLuminance(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testVariables); + CPPUNIT_TEST(test_asRGBColor); + CPPUNIT_TEST(test_ApplyTintOrShade); + CPPUNIT_TEST(test_ApplyLumModOff); + CPPUNIT_TEST(testGetColorError); + CPPUNIT_TEST(testInvert); + CPPUNIT_TEST(testBColor); + CPPUNIT_TEST(testLuminance); + CPPUNIT_TEST_SUITE_END(); +}; + +void Test::testVariables() +{ + Color aColor(0x44, 0x88, 0xAA); + CPPUNIT_ASSERT_EQUAL(int(0x00), int(255 - aColor.GetAlpha())); + CPPUNIT_ASSERT_EQUAL(int(0x44), int(aColor.GetRed())); + CPPUNIT_ASSERT_EQUAL(int(0x88), int(aColor.GetGreen())); + CPPUNIT_ASSERT_EQUAL(int(0xAA), int(aColor.GetBlue())); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x004488AA), sal_uInt32(aColor)); + + aColor = Color(ColorTransparency, 0xAABBCCDD); + CPPUNIT_ASSERT_EQUAL(int(0xAA), int(255 - aColor.GetAlpha())); + CPPUNIT_ASSERT_EQUAL(int(0xBB), int(aColor.GetRed())); + CPPUNIT_ASSERT_EQUAL(int(0xCC), int(aColor.GetGreen())); + CPPUNIT_ASSERT_EQUAL(int(0xDD), int(aColor.GetBlue())); + + aColor.SetAlpha(255 - 0x11); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x11BBCCDD), sal_uInt32(aColor)); + + aColor.SetRed(0x22); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x1122CCDD), sal_uInt32(aColor)); + + aColor.SetGreen(0x33); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x112233DD), sal_uInt32(aColor)); + + aColor.SetBlue(0x44); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x11223344), sal_uInt32(aColor)); + + aColor.SetAlpha(255 - 0x77); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x77223344), sal_uInt32(aColor)); + + aColor.SetRed(0x88); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x77883344), sal_uInt32(aColor)); + + aColor.SetGreen(0x99); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x77889944), sal_uInt32(aColor)); + + aColor.SetBlue(0xAA); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x778899AA), sal_uInt32(aColor)); +} + +void Test::test_asRGBColor() +{ + Color aColor; + aColor = COL_BLACK; + CPPUNIT_ASSERT_EQUAL(OUString("000000"), aColor.AsRGBHexString()); + + aColor = COL_WHITE; + CPPUNIT_ASSERT_EQUAL(OUString("ffffff"), aColor.AsRGBHexString()); + + aColor = COL_RED; + CPPUNIT_ASSERT_EQUAL(OUString("800000"), aColor.AsRGBHexString()); + + aColor = COL_TRANSPARENT; + CPPUNIT_ASSERT_EQUAL(OUString("ffffff"), aColor.AsRGBHexString()); + + aColor = COL_BLUE; + CPPUNIT_ASSERT_EQUAL(OUString("000080"), aColor.AsRGBHexString()); + + aColor.SetRed(0x12); + aColor.SetGreen(0x34); + aColor.SetBlue(0x56); + CPPUNIT_ASSERT_EQUAL(OUString("123456"), aColor.AsRGBHexString()); + + aColor = COL_AUTO; + CPPUNIT_ASSERT_EQUAL(OUString("ffffff"), aColor.AsRGBHexString()); +} + +OUString createTintShade(sal_uInt8 nR, sal_uInt8 nG, sal_uInt8 nB, std::u16string_view sReference, sal_Int16 nTintShade) +{ + Color aColor(nR, nG, nB); + if (sReference != aColor.AsRGBHexString()) + return OUString(); + aColor.ApplyTintOrShade(nTintShade); + return aColor.AsRGBHexString(); +} + +void Test::test_ApplyTintOrShade() +{ + // BLACK reference + + // 5% tint + CPPUNIT_ASSERT_EQUAL(OUString("0d0d0d"), createTintShade(0x00, 0x00, 0x00, u"000000", 500)); + // 15% tint + CPPUNIT_ASSERT_EQUAL(OUString("262626"), createTintShade(0x00, 0x00, 0x00, u"000000", 1500)); + // 25% tint + CPPUNIT_ASSERT_EQUAL(OUString("404040"), createTintShade(0x00, 0x00, 0x00, u"000000", 2500)); + // 50% tint + CPPUNIT_ASSERT_EQUAL(OUString("808080"), createTintShade(0x00, 0x00, 0x00, u"000000", 5000)); + // 100% tint + CPPUNIT_ASSERT_EQUAL(OUString("ffffff"), createTintShade(0x00, 0x00, 0x00, u"000000", 10000)); + + // WHITE reference + + // 5% shade + CPPUNIT_ASSERT_EQUAL(OUString("f2f2f2"), createTintShade(0xff, 0xff, 0xff, u"ffffff", -500)); + // 15% shade + CPPUNIT_ASSERT_EQUAL(OUString("d9d9d9"), createTintShade(0xff, 0xff, 0xff, u"ffffff", -1500)); + // 25% shade + CPPUNIT_ASSERT_EQUAL(OUString("bfbfbf"), createTintShade(0xff, 0xff, 0xff, u"ffffff", -2500)); + // 50% shade + CPPUNIT_ASSERT_EQUAL(OUString("808080"), createTintShade(0xff, 0xff, 0xff, u"ffffff", -5000)); + // 100% shade + CPPUNIT_ASSERT_EQUAL(OUString("000000"), createTintShade(0xff, 0xff, 0xff, u"ffffff", -10000)); + + // GREY reference + + // 0% - no change + CPPUNIT_ASSERT_EQUAL(OUString("808080"), createTintShade(0x80, 0x80, 0x80, u"808080", 0)); + + // 25% tint + CPPUNIT_ASSERT_EQUAL(OUString("a0a0a0"), createTintShade(0x80, 0x80, 0x80, u"808080", 2500)); + // 50% tint + //CPPUNIT_ASSERT_EQUAL(OUString("c0c0c0"), createTintShade(0x80, 0x80, 0x80, "808080", 5000)); + // disable for now - a rounding error happens on come platforms... + // 100% tint + CPPUNIT_ASSERT_EQUAL(OUString("ffffff"), createTintShade(0x80, 0x80, 0x80, u"808080", 10000)); + + // 25% shade + CPPUNIT_ASSERT_EQUAL(OUString("606060"), createTintShade(0x80, 0x80, 0x80, u"808080", -2500)); + // 50% shade + CPPUNIT_ASSERT_EQUAL(OUString("404040"), createTintShade(0x80, 0x80, 0x80, u"808080", -5000)); + // 100% shade + CPPUNIT_ASSERT_EQUAL(OUString("000000"), createTintShade(0x80, 0x80, 0x80, u"808080", -10000)); +} + +void Test::test_ApplyLumModOff() +{ + // Kind of blue. + Color aColor(0x44, 0x72, 0xC4); + + // PowerPoint calls this "Lighter 40%". + aColor.ApplyLumModOff(6000, 4000); + + CPPUNIT_ASSERT_EQUAL(OUString("8faadc"), aColor.AsRGBHexString()); +} + +void Test::testGetColorError() +{ + CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), Color(0xAA, 0xBB, 0xCC).GetColorError(Color(0xAA, 0xBB, 0xCC))); + + CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), Color(0xA0, 0xB0, 0xC0).GetColorError(Color(0xA1, 0xB0, 0xC0))); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), Color(0xA0, 0xB0, 0xC0).GetColorError(Color(0xA0, 0xB1, 0xC0))); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), Color(0xA0, 0xB0, 0xC0).GetColorError(Color(0xA0, 0xB0, 0xC1))); + + CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), Color(0xA0, 0xB0, 0xC0).GetColorError(Color(0xA1, 0xB1, 0xC0))); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), Color(0xA0, 0xB0, 0xC0).GetColorError(Color(0xA0, 0xB1, 0xC1))); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), Color(0xA0, 0xB0, 0xC0).GetColorError(Color(0xA1, 0xB0, 0xC1))); + + CPPUNIT_ASSERT_EQUAL(sal_uInt16(3), Color(0xA0, 0xB0, 0xC0).GetColorError(Color(0xA1, 0xB1, 0xC1))); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(3), Color(0xA0, 0xB0, 0xC0).GetColorError(Color(0xA1, 0xB1, 0xC1))); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(3), Color(0xA0, 0xB0, 0xC0).GetColorError(Color(0xA1, 0xB1, 0xC1))); +} + +void Test::testInvert() +{ + Color aColor(0xFF, 0x00, 0x88); + aColor.Invert(); + CPPUNIT_ASSERT_EQUAL(Color(0x00, 0xFF, 0x77).AsRGBHexString(), aColor.AsRGBHexString()); + + // Alpha should be unaffected + aColor = Color(ColorTransparency, 0x22, 0xFF, 0x00, 0x88); + aColor.Invert(); + CPPUNIT_ASSERT_EQUAL(Color(ColorTransparency, 0x22, 0x00, 0xFF, 0x77).AsRGBHexString(), aColor.AsRGBHexString()); +} + +void Test::testBColor() +{ + Color aColor; + + aColor = Color(basegfx::BColor(0.0, 0.0, 0.0)); + + CPPUNIT_ASSERT_EQUAL(Color(0x00, 0x00, 0x00).AsRGBHexString(), aColor.AsRGBHexString()); + CPPUNIT_ASSERT_EQUAL(0.0, aColor.getBColor().getRed()); + CPPUNIT_ASSERT_EQUAL(0.0, aColor.getBColor().getGreen()); + CPPUNIT_ASSERT_EQUAL(0.0, aColor.getBColor().getBlue()); + + aColor = Color(basegfx::BColor(1.0, 1.0, 1.0)); + + CPPUNIT_ASSERT_EQUAL(Color(0xFF, 0xFF, 0xFF).AsRGBHexString(), aColor.AsRGBHexString()); + CPPUNIT_ASSERT_EQUAL(1.0, aColor.getBColor().getRed()); + CPPUNIT_ASSERT_EQUAL(1.0, aColor.getBColor().getGreen()); + CPPUNIT_ASSERT_EQUAL(1.0, aColor.getBColor().getBlue()); + + aColor = Color(basegfx::BColor(0.5, 0.25, 0.125)); + + CPPUNIT_ASSERT_EQUAL(Color(0x80, 0x40, 0x20).AsRGBHexString(), aColor.AsRGBHexString()); + // FP error is rather big, but that's normal + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.500, aColor.getBColor().getRed(), 1E-2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.250, aColor.getBColor().getGreen(), 1E-2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125, aColor.getBColor().getBlue(), 1E-2); + +} + +void Test::testLuminance() +{ + CPPUNIT_ASSERT_EQUAL(sal_uInt8(0), COL_BLACK.GetLuminance()); + CPPUNIT_ASSERT_EQUAL(sal_uInt8(255), COL_WHITE.GetLuminance()); + CPPUNIT_ASSERT_EQUAL(sal_uInt8(128), Color(128, 128, 128).GetLuminance()); + CPPUNIT_ASSERT(COL_WHITE.IsBright()); + CPPUNIT_ASSERT(COL_BLACK.IsDark()); + CPPUNIT_ASSERT(Color(249, 250, 251).IsBright()); + CPPUNIT_ASSERT(Color(9, 10, 11).IsDark()); + CPPUNIT_ASSERT(COL_WHITE.GetLuminance() > COL_BLACK.GetLuminance()); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(Test); + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_config.cxx b/tools/qa/cppunit/test_config.cxx new file mode 100644 index 000000000..9c9a40899 --- /dev/null +++ b/tools/qa/cppunit/test_config.cxx @@ -0,0 +1,200 @@ +/* -*- 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 <osl/file.hxx> +#include <rtl/ustring.hxx> + +#include <tools/config.hxx> + +class ToolsConfigTest : public test::BootstrapFixture +{ +public: + ToolsConfigTest() + : BootstrapFixture(true, false) + { + } + + virtual void setUp() override + { + maOriginalConfigFile = m_directories.getURLFromSrc(u"/tools/qa/data/"); + maOriginalConfigFile += "testconfig.ini"; + + auto const e = osl::FileBase::getTempDirURL(maConfigFile); + CPPUNIT_ASSERT_EQUAL_MESSAGE("cannot create temp folder", osl::File::RC::E_None, e); + maConfigFile += "/config.ini"; + + osl::File::copy(maOriginalConfigFile, maConfigFile); + } + + virtual void tearDown() override { osl::File::remove(maConfigFile); } + + void testHasGroup() + { + Config aConfig(maConfigFile); + CPPUNIT_ASSERT(aConfig.HasGroup("TestGroup")); + CPPUNIT_ASSERT(aConfig.HasGroup("TestGroup2")); + } + + void testGetGroup() + { + Config aConfig(maConfigFile); + CPPUNIT_ASSERT_EQUAL(OString(""), aConfig.GetGroup()); + + CPPUNIT_ASSERT_EQUAL(OString("TestGroup"), aConfig.GetGroupName(0)); + CPPUNIT_ASSERT_EQUAL(OString("TestGroup2"), aConfig.GetGroupName(1)); + CPPUNIT_ASSERT_EQUAL(OString(""), aConfig.GetGroupName(2)); + } + + void testSetGroup() + { + Config aConfig(maConfigFile); + + aConfig.SetGroup("TestGroup"); + CPPUNIT_ASSERT_EQUAL(OString("TestGroup"), aConfig.GetGroup()); + + // so this is a quirk of Config - you can set the group name, + // but it might not exist so you really should first check if + // it exists via HasGroup() + aConfig.SetGroup("TestGroupA"); + CPPUNIT_ASSERT(!aConfig.HasGroup("TestGroupA")); + CPPUNIT_ASSERT_EQUAL(OString("TestGroupA"), aConfig.GetGroup()); + } + + void testDeleteGroup() + { + { + Config aConfig(maConfigFile); + + aConfig.DeleteGroup("TestGroup"); + CPPUNIT_ASSERT(!aConfig.HasGroup("TestGroup")); + CPPUNIT_ASSERT_EQUAL(OString("TestGroup2"), aConfig.GetGroupName(0)); + + sal_uInt16 nActual = aConfig.GetGroupCount(); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), nActual); + } + + osl::File::copy(maOriginalConfigFile, maConfigFile); + + { + Config aConfig(maConfigFile); + + CPPUNIT_ASSERT(!aConfig.HasGroup("NonExistentTestGroup")); + aConfig.DeleteGroup("NonExistentTestGroup"); + CPPUNIT_ASSERT_EQUAL(OString("TestGroup"), aConfig.GetGroupName(0)); + + sal_uInt16 nActual = aConfig.GetGroupCount(); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), nActual); + } + + osl::File::copy(maOriginalConfigFile, maConfigFile); + } + + void testGetGroupCount() + { + Config aConfig(maConfigFile); + sal_uInt16 nActual = aConfig.GetGroupCount(); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), nActual); + } + + void testReadKey() + { + Config aConfig(maConfigFile); + aConfig.SetGroup("TestGroup"); + CPPUNIT_ASSERT_EQUAL(OString("testvalue"), aConfig.ReadKey("testkey")); + CPPUNIT_ASSERT_EQUAL(OString(), aConfig.ReadKey("nonexistenttestkey")); + CPPUNIT_ASSERT_EQUAL(OString("notexists"), + aConfig.ReadKey("nonexistenttestkey", "notexists")); + + aConfig.SetGroup("TestGroup2"); + CPPUNIT_ASSERT_EQUAL(OString("testvalue"), aConfig.ReadKey("testkey2")); + CPPUNIT_ASSERT_EQUAL(OString(), aConfig.ReadKey("nonexistenttestkey")); + CPPUNIT_ASSERT_EQUAL(OString("notexists"), + aConfig.ReadKey("nonexistenttestkey", "notexists")); + } + + void testGetKeyName() + { + Config aConfig(maConfigFile); + aConfig.SetGroup("TestGroup"); + CPPUNIT_ASSERT_EQUAL(OString("testkey"), aConfig.GetKeyName(0)); + + aConfig.SetGroup("TestGroup2"); + CPPUNIT_ASSERT_EQUAL(OString("testkey2"), aConfig.GetKeyName(0)); + } + + void testWriteDeleteKey() + { + Config aConfig(maConfigFile); + aConfig.SetGroup("TestGroup"); + aConfig.WriteKey("testkey_new", "testvalue"); + + sal_uInt16 nExpected = 2; + sal_uInt16 nActual = aConfig.GetKeyCount(); + CPPUNIT_ASSERT_EQUAL(nExpected, nActual); + CPPUNIT_ASSERT_EQUAL(OString("testvalue"), aConfig.ReadKey("testkey_new")); + + aConfig.DeleteKey("testkey_new"); + + nExpected = 1; + nActual = aConfig.GetKeyCount(); + CPPUNIT_ASSERT_EQUAL(nExpected, nActual); + CPPUNIT_ASSERT_EQUAL(OString(), aConfig.ReadKey("testkey_new")); + + aConfig.SetGroup("TestGroup2"); + aConfig.WriteKey("testkey_new", "testvalue"); + + nActual = aConfig.GetKeyCount(); + nExpected = 2; + CPPUNIT_ASSERT_EQUAL(nExpected, nActual); + CPPUNIT_ASSERT_EQUAL(OString("testvalue"), aConfig.ReadKey("testkey_new")); + + aConfig.DeleteKey("testkey_new"); + + nActual = aConfig.GetKeyCount(); + nExpected = 1; + CPPUNIT_ASSERT_EQUAL(nExpected, nActual); + CPPUNIT_ASSERT_EQUAL(OString(), aConfig.ReadKey("testkey_new")); + + aConfig.SetGroup("TestGroup3"); + aConfig.WriteKey("testkey_new_group3", "testvalue"); + + nActual = aConfig.GetKeyCount(); + nExpected = 1; + CPPUNIT_ASSERT_EQUAL(nExpected, nActual); + CPPUNIT_ASSERT_EQUAL(OString("testvalue"), aConfig.ReadKey("testkey_new_group3")); + + nExpected = 3; + CPPUNIT_ASSERT_EQUAL(nExpected, aConfig.GetGroupCount()); + + osl::File::copy(maOriginalConfigFile, maConfigFile); + } + + CPPUNIT_TEST_SUITE(ToolsConfigTest); + CPPUNIT_TEST(testHasGroup); + CPPUNIT_TEST(testGetGroup); + CPPUNIT_TEST(testSetGroup); + CPPUNIT_TEST(testDeleteGroup); + CPPUNIT_TEST(testReadKey); + CPPUNIT_TEST(testGetGroupCount); + CPPUNIT_TEST(testGetKeyName); + CPPUNIT_TEST(testWriteDeleteKey); + CPPUNIT_TEST_SUITE_END(); + +private: + OUString maOriginalConfigFile; + OUString maConfigFile; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(ToolsConfigTest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_cpu_runtime_detection_AVX2.cxx b/tools/qa/cppunit/test_cpu_runtime_detection_AVX2.cxx new file mode 100644 index 000000000..5ba8ed9ee --- /dev/null +++ b/tools/qa/cppunit/test_cpu_runtime_detection_AVX2.cxx @@ -0,0 +1,40 @@ +/* -*- 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_cpu_runtime_detection_x86_checks.hxx" + +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <tools/cpuid.hxx> + +namespace +{ +class CpuRuntimeDetection_AVX2 : public CppUnit::TestFixture +{ +public: + void testCpuRuntimeDetection(); + + CPPUNIT_TEST_SUITE(CpuRuntimeDetection_AVX2); + CPPUNIT_TEST(testCpuRuntimeDetection); + CPPUNIT_TEST_SUITE_END(); +}; + +void CpuRuntimeDetection_AVX2::testCpuRuntimeDetection() +{ + // can only run this function if CPU supports AVX2 + if (cpuid::isCpuInstructionSetSupported(cpuid::InstructionSetFlags::AVX2)) + CpuRuntimeDetectionX86Checks::checkAVX2(); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(CpuRuntimeDetection_AVX2); + +} // end anonymous namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_cpu_runtime_detection_AVX2_check.cxx b/tools/qa/cppunit/test_cpu_runtime_detection_AVX2_check.cxx new file mode 100644 index 000000000..7ed8495f3 --- /dev/null +++ b/tools/qa/cppunit/test_cpu_runtime_detection_AVX2_check.cxx @@ -0,0 +1,56 @@ +/* -*- 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 <sal/types.h> +#include <tools/simdsupport.hxx> + +#include <stdlib.h> + +#include "test_cpu_runtime_detection_x86_checks.hxx" + +/* WARNING: This file is compiled with AVX2 support, don't call + * any function without checking cpuid to check the CPU can actually + * handle it, and don't include any headers that contain templates + * or inline functions, which includes cppunit. + */ +#ifdef LO_AVX2_AVAILABLE +#define CPPUNIT_ASSERT_EQUAL(a, b) ((a) == (b) ? (void)0 : abort()) +#endif + +void CpuRuntimeDetectionX86Checks::checkAVX2() +{ +#ifdef LO_AVX2_AVAILABLE + __m256i a = _mm256_set_epi64x(1, 4, 8, 3); + __m256i b = _mm256_set_epi64x(2, 1, 1, 5); + __m256i c = _mm256_xor_si256(a, b); + + sal_Int64 values[4]; + _mm256_storeu_si256(reinterpret_cast<__m256i*>(&values), c); + + CPPUNIT_ASSERT_EQUAL(sal_Int64(6), values[0]); + CPPUNIT_ASSERT_EQUAL(sal_Int64(9), values[1]); + CPPUNIT_ASSERT_EQUAL(sal_Int64(5), values[2]); + CPPUNIT_ASSERT_EQUAL(sal_Int64(3), values[3]); + + __m256i d = _mm256_set_epi64x(3, 5, 1, 0); + + __m256i result = _mm256_cmpeq_epi64(d, c); + + // Compare equals + sal_Int64 compare[4]; + _mm256_storeu_si256(reinterpret_cast<__m256i*>(&compare), result); + + CPPUNIT_ASSERT_EQUAL(sal_Int64(0), compare[0]); + CPPUNIT_ASSERT_EQUAL(sal_Int64(0), compare[1]); + CPPUNIT_ASSERT_EQUAL(sal_Int64(-1), compare[2]); + CPPUNIT_ASSERT_EQUAL(sal_Int64(-1), compare[3]); +#endif +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_cpu_runtime_detection_SSE2.cxx b/tools/qa/cppunit/test_cpu_runtime_detection_SSE2.cxx new file mode 100644 index 000000000..93bac6f2a --- /dev/null +++ b/tools/qa/cppunit/test_cpu_runtime_detection_SSE2.cxx @@ -0,0 +1,40 @@ +/* -*- 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_cpu_runtime_detection_x86_checks.hxx" + +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <tools/cpuid.hxx> + +namespace +{ +class CpuRuntimeDetection_SSE2 : public CppUnit::TestFixture +{ +public: + void testCpuRuntimeDetection(); + + CPPUNIT_TEST_SUITE(CpuRuntimeDetection_SSE2); + CPPUNIT_TEST(testCpuRuntimeDetection); + CPPUNIT_TEST_SUITE_END(); +}; + +void CpuRuntimeDetection_SSE2::testCpuRuntimeDetection() +{ + // can only run this function if CPU supports SSE2 + if (cpuid::isCpuInstructionSetSupported(cpuid::InstructionSetFlags::SSE2)) + CpuRuntimeDetectionX86Checks::checkSSE2(); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(CpuRuntimeDetection_SSE2); + +} // end anonymous namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_cpu_runtime_detection_SSE2_check.cxx b/tools/qa/cppunit/test_cpu_runtime_detection_SSE2_check.cxx new file mode 100644 index 000000000..12e39eabf --- /dev/null +++ b/tools/qa/cppunit/test_cpu_runtime_detection_SSE2_check.cxx @@ -0,0 +1,37 @@ +/* -*- 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 <tools/simdsupport.hxx> + +#include <stdlib.h> + +#include "test_cpu_runtime_detection_x86_checks.hxx" + +/* WARNING: This file is compiled with SSE2 support, don't call + * any function without checking cpuid to check the CPU can actually + * handle it, and don't include any headers that contain templates + * or inline functions, which includes cppunit. + */ +#ifdef LO_SSE2_AVAILABLE +#define CPPUNIT_ASSERT_EQUAL(a, b) ((a) == (b) ? (void)0 : abort()) +#endif +void CpuRuntimeDetectionX86Checks::checkSSE2() +{ +#ifdef LO_SSE2_AVAILABLE + // Try some SSE2 intrinsics calculation + __m128i a = _mm_set1_epi32(15); + __m128i b = _mm_set1_epi32(15); + __m128i c = _mm_xor_si128(a, b); + + // Check zero + CPPUNIT_ASSERT_EQUAL(0xFFFF, _mm_movemask_epi8(_mm_cmpeq_epi32(c, _mm_setzero_si128()))); +#endif +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_cpu_runtime_detection_SSSE3.cxx b/tools/qa/cppunit/test_cpu_runtime_detection_SSSE3.cxx new file mode 100644 index 000000000..3c0e9d252 --- /dev/null +++ b/tools/qa/cppunit/test_cpu_runtime_detection_SSSE3.cxx @@ -0,0 +1,40 @@ +/* -*- 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_cpu_runtime_detection_x86_checks.hxx" + +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <tools/cpuid.hxx> + +namespace +{ +class CpuRuntimeDetection_SSSE3 : public CppUnit::TestFixture +{ +public: + void testCpuRuntimeDetection(); + + CPPUNIT_TEST_SUITE(CpuRuntimeDetection_SSSE3); + CPPUNIT_TEST(testCpuRuntimeDetection); + CPPUNIT_TEST_SUITE_END(); +}; + +void CpuRuntimeDetection_SSSE3::testCpuRuntimeDetection() +{ + // can only run this function if CPU supports SSSE3 + if (cpuid::isCpuInstructionSetSupported(cpuid::InstructionSetFlags::SSSE3)) + CpuRuntimeDetectionX86Checks::checkSSSE3(); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(CpuRuntimeDetection_SSSE3); + +} // end anonymous namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_cpu_runtime_detection_SSSE3_check.cxx b/tools/qa/cppunit/test_cpu_runtime_detection_SSSE3_check.cxx new file mode 100644 index 000000000..705e5c2ab --- /dev/null +++ b/tools/qa/cppunit/test_cpu_runtime_detection_SSSE3_check.cxx @@ -0,0 +1,37 @@ +/* -*- 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 <tools/simdsupport.hxx> + +#include <stdlib.h> + +#include "test_cpu_runtime_detection_x86_checks.hxx" + +/* WARNING: This file is compiled with SSSE3 support, don't call + * any function without checking cpuid to check the CPU can actually + * handle it, and don't include any headers that contain templates + * or inline functions, which includes cppunit. + */ +#ifdef LO_SSSE3_AVAILABLE +#define CPPUNIT_ASSERT_EQUAL(a, b) ((a) == (b) ? (void)0 : abort()) +#endif +void CpuRuntimeDetectionX86Checks::checkSSSE3() +{ +#ifdef LO_SSSE3_AVAILABLE + // Try some SSSE3 intrinsics calculation + __m128i a = _mm_set1_epi32(3); + __m128i b = _mm_set1_epi32(3); + __m128i c = _mm_maddubs_epi16(a, b); + + // Check result is 9 + CPPUNIT_ASSERT_EQUAL(0xFFFF, _mm_movemask_epi8(_mm_cmpeq_epi32(c, _mm_set1_epi32(9)))); +#endif +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_cpu_runtime_detection_x86_checks.hxx b/tools/qa/cppunit/test_cpu_runtime_detection_x86_checks.hxx new file mode 100644 index 000000000..0046985ac --- /dev/null +++ b/tools/qa/cppunit/test_cpu_runtime_detection_x86_checks.hxx @@ -0,0 +1,23 @@ +/* -*- 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/. + */ + +#ifndef INCLUDE_TOOLS_QA_CPPUNIT_TEST_CPU_RUNTIME_DETECTION_X86_CHECKS_H +#define INCLUDE_TOOLS_QA_CPPUNIT_TEST_CPU_RUNTIME_DETECTION_X86_CHECKS_H + +class CpuRuntimeDetectionX86Checks +{ +public: + static void checkAVX2(); + static void checkSSE2(); + static void checkSSSE3(); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_cpuid.cxx b/tools/qa/cppunit/test_cpuid.cxx new file mode 100644 index 000000000..7d9b5c41c --- /dev/null +++ b/tools/qa/cppunit/test_cpuid.cxx @@ -0,0 +1,57 @@ +/* -*- 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 <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <tools/cpuid.hxx> +#include <rtl/ustring.hxx> + +namespace +{ +class CpuInstructionSetSupport : public CppUnit::TestFixture +{ +public: + void testCpuInstructionSetSupport(); + + CPPUNIT_TEST_SUITE(CpuInstructionSetSupport); + CPPUNIT_TEST(testCpuInstructionSetSupport); + CPPUNIT_TEST_SUITE_END(); +}; + +void CpuInstructionSetSupport::testCpuInstructionSetSupport() +{ + OUString aString = cpuid::instructionSetSupportedString(); + + if (cpuid::isCpuInstructionSetSupported(cpuid::InstructionSetFlags::SSE2)) + { + CPPUNIT_ASSERT(aString.indexOf("SSE2") >= 0); + } + + if (cpuid::isCpuInstructionSetSupported(cpuid::InstructionSetFlags::SSSE3)) + { + CPPUNIT_ASSERT(aString.indexOf("SSSE3") >= 0); + } + + if (cpuid::isCpuInstructionSetSupported(cpuid::InstructionSetFlags::AVX)) + { + CPPUNIT_ASSERT(aString.indexOf("AVX") > 0); + } + + if (cpuid::isCpuInstructionSetSupported(cpuid::InstructionSetFlags::AVX2)) + { + CPPUNIT_ASSERT(aString.indexOf("AVX2") > 0); + } +} + +CPPUNIT_TEST_SUITE_REGISTRATION(CpuInstructionSetSupport); + +} // end anonymous namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_date.cxx b/tools/qa/cppunit/test_date.cxx new file mode 100644 index 000000000..e11270e6a --- /dev/null +++ b/tools/qa/cppunit/test_date.cxx @@ -0,0 +1,564 @@ +/* -*- 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 <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <tools/date.hxx> + +namespace tools +{ +class DateTest : public CppUnit::TestFixture +{ +public: + void testDate(); + void testLeapYear(); + void testGetDaysInYear(); + void testValidGregorianDate(); + void testValidDate(); + void testNormalize(); + void testGetDayOfWeek(); + void testGetDaysInMonth(); + void testIsBetween(); + void testIsEndOfMonth(); + + CPPUNIT_TEST_SUITE(DateTest); + CPPUNIT_TEST(testDate); + CPPUNIT_TEST(testLeapYear); + CPPUNIT_TEST(testGetDaysInYear); + CPPUNIT_TEST(testValidGregorianDate); + CPPUNIT_TEST(testValidDate); + CPPUNIT_TEST(testNormalize); + CPPUNIT_TEST(testGetDayOfWeek); + CPPUNIT_TEST(testGetDaysInMonth); + CPPUNIT_TEST(testIsBetween); + CPPUNIT_TEST(testIsEndOfMonth); + CPPUNIT_TEST_SUITE_END(); +}; + +void DateTest::testDate() +{ + const Date aCE(1, 1, 1); // first day CE + const Date aBCE(31, 12, -1); // last day BCE + const Date aMin(1, 1, -32768); // minimum date + const Date aMax(31, 12, 32767); // maximum date + Date aDate(Date::EMPTY); + const sal_Int32 kMinDays = -11968265; + const sal_Int32 kMaxDays = 11967900; + + // Last day BCE to first day CE is 1 day difference. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aCE - aBCE); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-1), aBCE - aCE); + aDate = aBCE; + aDate.AddDays(1); + CPPUNIT_ASSERT_EQUAL(aCE.GetDate(), aDate.GetDate()); + aDate = aCE; + aDate.AddDays(-1); + CPPUNIT_ASSERT_EQUAL(aBCE.GetDate(), aDate.GetDate()); + + // The entire BCE and CE ranges cover that many days. Day 0 is -0001-12-31 + CPPUNIT_ASSERT_EQUAL(kMaxDays, aMax - aBCE); + CPPUNIT_ASSERT_EQUAL(kMinDays, aMin - aBCE); + + // Truncate at limits, not under-/overflow or wrap. + aDate = aMin; + aDate.AddDays(-1); + CPPUNIT_ASSERT_EQUAL(aMin.GetDate(), aDate.GetDate()); + aDate = aMax; + aDate.AddDays(1); + CPPUNIT_ASSERT_EQUAL(aMax.GetDate(), aDate.GetDate()); + aDate = aBCE; + aDate.AddDays(kMinDays - 10); + CPPUNIT_ASSERT_EQUAL(aMin.GetDate(), aDate.GetDate()); + aDate = aBCE; + aDate.AddDays(kMaxDays + 10); + CPPUNIT_ASSERT_EQUAL(aMax.GetDate(), aDate.GetDate()); + aDate = aMax; + aDate.SetDay(32); + aDate.Normalize(); + CPPUNIT_ASSERT_EQUAL(aMax.GetDate(), aDate.GetDate()); + CPPUNIT_ASSERT(!aDate.IsEmpty()); + + // 0001-00-x normalized to -0001-12-x + aDate.SetYear(1); + aDate.SetMonth(0); + aDate.SetDay(22); + aDate.Normalize(); + CPPUNIT_ASSERT_EQUAL(Date(22, 12, -1).GetDate(), aDate.GetDate()); + + sal_uInt32 nExpected = 11222; + CPPUNIT_ASSERT_EQUAL(nExpected, aDate.GetDateUnsigned()); + // 1999-02-32 normalized to 1999-03-04 + aDate.SetYear(1999); + aDate.SetMonth(2); + aDate.SetDay(32); + aDate.Normalize(); + CPPUNIT_ASSERT_EQUAL(Date(4, 3, 1999).GetDate(), aDate.GetDate()); + + // Empty date is not normalized and stays empty date. + aDate = Date(Date::EMPTY); + aDate.Normalize(); + CPPUNIT_ASSERT_EQUAL(Date(Date::EMPTY).GetDate(), aDate.GetDate()); + CPPUNIT_ASSERT(!aDate.IsValidDate()); // GetDate() also shall have no normalizing side effect + + // 0000-01-00 normalized to -0001-12-31 + // SetYear(0) asserts, use empty date to force. + aDate = Date(Date::EMPTY); + aDate.SetMonth(1); + aDate.SetDay(0); + aDate.Normalize(); + CPPUNIT_ASSERT_EQUAL(Date(31, 12, -1).GetDate(), aDate.GetDate()); + + // 1999-00-00 normalized to 1998-12-31 (not 1998-11-30, or otherwise + // also 0001-00-00 should be -0001-11-30 which it should not, should it?) + aDate.SetYear(1999); + aDate.SetMonth(0); + aDate.SetDay(0); + aDate.Normalize(); + CPPUNIT_ASSERT_EQUAL(Date(31, 12, 1998).GetDate(), aDate.GetDate()); + + // 0001-00-00 normalized to -0001-12-31 + aDate.SetYear(1); + aDate.SetMonth(0); + aDate.SetDay(0); + aDate.Normalize(); + CPPUNIT_ASSERT_EQUAL(Date(31, 12, -1).GetDate(), aDate.GetDate()); +} + +void DateTest::testLeapYear() +{ + { + Date aDate(1, 1, 2000); + CPPUNIT_ASSERT(aDate.IsLeapYear()); + } + + { + Date aDate(1, 1, 1900); + CPPUNIT_ASSERT(!aDate.IsLeapYear()); + } + + { + Date aDate(1, 1, 1999); + CPPUNIT_ASSERT(!aDate.IsLeapYear()); + } + + { + Date aDate(1, 1, 2004); + CPPUNIT_ASSERT(aDate.IsLeapYear()); + } + + { + Date aDate(1, 1, 400); + CPPUNIT_ASSERT(aDate.IsLeapYear()); + } + + { + // Year -1 is a leap year. + Date aDate(28, 2, -1); + aDate.AddDays(1); + CPPUNIT_ASSERT(aDate.IsLeapYear()); + CPPUNIT_ASSERT_EQUAL(Date(29, 2, -1).GetDate(), aDate.GetDate()); + } + + { + Date aDate(1, 3, -1); + aDate.AddDays(-1); + CPPUNIT_ASSERT(aDate.IsLeapYear()); + CPPUNIT_ASSERT_EQUAL(Date(29, 2, -1).GetDate(), aDate.GetDate()); + } + + { + // Year -5 is a leap year. + Date aDate(28, 2, -5); + aDate.AddDays(1); + CPPUNIT_ASSERT(aDate.IsLeapYear()); + CPPUNIT_ASSERT_EQUAL(Date(29, 2, -5).GetDate(), aDate.GetDate()); + } + + { + Date aDate(1, 3, -5); + aDate.AddDays(-1); + CPPUNIT_ASSERT(aDate.IsLeapYear()); + CPPUNIT_ASSERT_EQUAL(Date(29, 2, -5).GetDate(), aDate.GetDate()); + } +} + +void DateTest::testGetDaysInYear() +{ + { + Date aDate(1, 1, 2000); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(366), aDate.GetDaysInYear()); + } + + { + Date aDate(1, 1, 1900); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(365), aDate.GetDaysInYear()); + } + + { + Date aDate(1, 1, 1999); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(365), aDate.GetDaysInYear()); + } + + { + Date aDate(1, 1, 2004); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(366), aDate.GetDaysInYear()); + } + + { + Date aDate(1, 1, 400); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(366), aDate.GetDaysInYear()); + } +} + +void DateTest::testValidGregorianDate() +{ + { + Date aDate(1, 0, 2000); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(1, 13, 2000); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(1, 1, 1581); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(1, 9, 1582); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(1, 10, 1582); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(32, 1, 2000); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(29, 2, 2000); + CPPUNIT_ASSERT(aDate.IsValidAndGregorian()); + } + + { + Date aDate(29, 2, 2001); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(32, 3, 2000); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(31, 4, 2000); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(32, 5, 2000); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(31, 6, 2000); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(32, 7, 2000); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(32, 8, 2000); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(31, 9, 2000); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(32, 10, 2000); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(31, 11, 2000); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } + + { + Date aDate(32, 12, 2000); + CPPUNIT_ASSERT(!aDate.IsValidAndGregorian()); + } +} + +void DateTest::testValidDate() +{ + { + // Empty date is not a valid date. + Date aDate(Date::EMPTY); + CPPUNIT_ASSERT(aDate.IsEmpty()); + CPPUNIT_ASSERT(!aDate.IsValidDate()); + } + + { + Date aDate(32, 1, 2000); + CPPUNIT_ASSERT(!aDate.IsValidDate()); + } + + { + Date aDate(29, 2, 2000); + CPPUNIT_ASSERT(aDate.IsValidDate()); + } + + { + Date aDate(29, 2, 2001); + CPPUNIT_ASSERT(!aDate.IsValidDate()); + } + + { + Date aDate(32, 3, 2000); + CPPUNIT_ASSERT(!aDate.IsValidDate()); + } + + { + Date aDate(31, 4, 2000); + CPPUNIT_ASSERT(!aDate.IsValidDate()); + } + + { + Date aDate(32, 5, 2000); + CPPUNIT_ASSERT(!aDate.IsValidDate()); + } + + { + Date aDate(31, 6, 2000); + CPPUNIT_ASSERT(!aDate.IsValidDate()); + } + + { + Date aDate(32, 7, 2000); + CPPUNIT_ASSERT(!aDate.IsValidDate()); + } + + { + Date aDate(32, 8, 2000); + CPPUNIT_ASSERT(!aDate.IsValidDate()); + } + + { + Date aDate(31, 9, 2000); + CPPUNIT_ASSERT(!aDate.IsValidDate()); + } + + { + Date aDate(32, 10, 2000); + CPPUNIT_ASSERT(!aDate.IsValidDate()); + } + + { + Date aDate(31, 11, 2000); + CPPUNIT_ASSERT(!aDate.IsValidDate()); + } + + { + Date aDate(32, 12, 2000); + CPPUNIT_ASSERT(!aDate.IsValidDate()); + } +} + +void DateTest::testNormalize() +{ + { + Date aDate(32, 2, 1999); + aDate.Normalize(); + Date aExpectedDate(4, 3, 1999); + CPPUNIT_ASSERT_EQUAL(aExpectedDate, aDate); + } + + { + Date aDate(1, 13, 1999); + aDate.Normalize(); + Date aExpectedDate(1, 1, 2000); + CPPUNIT_ASSERT_EQUAL(aExpectedDate, aDate); + } + + { + Date aDate(42, 13, 1999); + aDate.Normalize(); + Date aExpectedDate(11, 2, 2000); + CPPUNIT_ASSERT_EQUAL(aExpectedDate, aDate); + } + + { + Date aDate(1, 0, 1); + aDate.Normalize(); + Date aExpectedDate(1, 12, -1); + CPPUNIT_ASSERT_EQUAL(aExpectedDate, aDate); + } +} + +void DateTest::testGetDayOfWeek() +{ + { + DayOfWeek eExpectedDay = DayOfWeek::MONDAY; + Date aDate(30, 4, 2018); + CPPUNIT_ASSERT_EQUAL(eExpectedDay, aDate.GetDayOfWeek()); + } + + { + DayOfWeek eExpectedDay = DayOfWeek::TUESDAY; + Date aDate(1, 5, 2018); + CPPUNIT_ASSERT_EQUAL(eExpectedDay, aDate.GetDayOfWeek()); + } + + { + DayOfWeek eExpectedDay = DayOfWeek::WEDNESDAY; + Date aDate(2, 5, 2018); + CPPUNIT_ASSERT_EQUAL(eExpectedDay, aDate.GetDayOfWeek()); + } + + { + DayOfWeek eExpectedDay = DayOfWeek::THURSDAY; + Date aDate(3, 5, 2018); + CPPUNIT_ASSERT_EQUAL(eExpectedDay, aDate.GetDayOfWeek()); + } + + { + DayOfWeek eExpectedDay = DayOfWeek::FRIDAY; + Date aDate(4, 5, 2018); + CPPUNIT_ASSERT_EQUAL(eExpectedDay, aDate.GetDayOfWeek()); + } + + { + DayOfWeek eExpectedDay = DayOfWeek::SATURDAY; + Date aDate(5, 5, 2018); + CPPUNIT_ASSERT_EQUAL(eExpectedDay, aDate.GetDayOfWeek()); + } + + { + DayOfWeek eExpectedDay = DayOfWeek::SUNDAY; + Date aDate(6, 5, 2018); + CPPUNIT_ASSERT_EQUAL(eExpectedDay, aDate.GetDayOfWeek()); + } +} + +void DateTest::testGetDaysInMonth() +{ + { + Date aDate(1, 1, 2000); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate.GetDaysInMonth()); + } + + { + Date aDate(1, 2, 2000); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(29), aDate.GetDaysInMonth()); + } + + { + Date aDate(1, 2, 1999); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(28), aDate.GetDaysInMonth()); + } + + { + Date aDate(1, 3, 2000); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate.GetDaysInMonth()); + } + + { + Date aDate(1, 4, 2000); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), aDate.GetDaysInMonth()); + } + + { + Date aDate(1, 5, 2000); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate.GetDaysInMonth()); + } + + { + Date aDate(1, 6, 2000); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), aDate.GetDaysInMonth()); + } + + { + Date aDate(1, 7, 2000); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate.GetDaysInMonth()); + } + + { + Date aDate(1, 8, 2000); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate.GetDaysInMonth()); + } + + { + Date aDate(1, 9, 2000); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), aDate.GetDaysInMonth()); + } + + { + Date aDate(1, 10, 2000); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate.GetDaysInMonth()); + } + + { + Date aDate(1, 11, 2000); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), aDate.GetDaysInMonth()); + } + + { + Date aDate(1, 12, 2000); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate.GetDaysInMonth()); + } +} + +void DateTest::testIsBetween() +{ + Date aDate(6, 4, 2018); + CPPUNIT_ASSERT(aDate.IsBetween(Date(1, 1, 2018), Date(1, 12, 2018))); +} + +void DateTest::testIsEndOfMonth() +{ + { + Date aDate(31, 12, 2000); + CPPUNIT_ASSERT(aDate.IsEndOfMonth()); + } + + { + Date aDate(30, 12, 2000); + CPPUNIT_ASSERT(!aDate.IsEndOfMonth()); + } + + { + Date aDate(29, 2, 2000); + CPPUNIT_ASSERT(aDate.IsEndOfMonth()); + } + + { + Date aDate(28, 2, 2000); + CPPUNIT_ASSERT(!aDate.IsEndOfMonth()); + } +} + +CPPUNIT_TEST_SUITE_REGISTRATION(DateTest); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/tools/qa/cppunit/test_fract.cxx b/tools/qa/cppunit/test_fract.cxx new file mode 100644 index 000000000..1c3b8ad02 --- /dev/null +++ b/tools/qa/cppunit/test_fract.cxx @@ -0,0 +1,107 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/types.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <rtl/math.hxx> +#include <tools/fract.hxx> + +namespace tools +{ + +class FractionTest : public CppUnit::TestFixture +{ +public: + + void testFraction() + { + const Fraction aFract(1082130431,1073741824); + CPPUNIT_ASSERT_MESSAGE( "Fraction #1 not approximately equal to 1.007812499068677", + rtl::math::approxEqual(static_cast<double>(aFract),1.007812499068677) ); + + Fraction aFract2( aFract ); + aFract2.ReduceInaccurate(8); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #2 not 1", + sal_Int32(1), aFract2.GetNumerator() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #2 not 1", + sal_Int32(1), aFract2.GetDenominator() ); + + Fraction aFract3( 0x7AAAAAAA, 0x35555555 ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #3 cancellation wrong", + sal_Int32(0x7AAAAAAA), aFract3.GetNumerator() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #3 cancellation wrong", + sal_Int32(0x35555555), aFract3.GetDenominator() ); + aFract3.ReduceInaccurate(30); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #3 ReduceInaccurate erroneously cut precision", + sal_Int32(0x7AAAAAAA), aFract3.GetNumerator() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #3 ReduceInaccurate erroneously cut precision", + sal_Int32(0x35555555), aFract3.GetDenominator() ); + + aFract3.ReduceInaccurate(29); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #3 reduce to 29 bits failed", + sal_Int32(0x3D555555), aFract3.GetNumerator() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #3 reduce to 29 bits failed", + sal_Int32(0x1AAAAAAA), aFract3.GetDenominator() ); + + aFract3.ReduceInaccurate(9); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #3 reduce to 9 bits failed", + sal_Int32(0x0147), aFract3.GetNumerator() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #3 reduce to 9 bits failed", + sal_Int32(0x008E), aFract3.GetDenominator() ); + + aFract3.ReduceInaccurate(1); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #3 reduce to 1 bit failed", + sal_Int32(2), aFract3.GetNumerator() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #3 reduce to 1 bit failed", + sal_Int32(1), aFract3.GetDenominator() ); + + aFract3.ReduceInaccurate(0); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #3 reduce to 0 bits failed", + sal_Int32(2), aFract3.GetNumerator() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Fraction #3 reduce to 0 bits failed", + sal_Int32(1), aFract3.GetDenominator() ); + + } + + void testMinLongDouble() { + Fraction f(double(SAL_MIN_INT32)); + CPPUNIT_ASSERT_EQUAL(SAL_MIN_INT32, f.GetNumerator()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), f.GetDenominator()); + } + + void testCreateFromDoubleIn32BitsPlatform() { + // This pass in 64 bits but fail in 32 bits + Fraction f(0.960945); + CPPUNIT_ASSERT_EQUAL(true, f.IsValid()); + } + + CPPUNIT_TEST_SUITE(FractionTest); + CPPUNIT_TEST(testFraction); + CPPUNIT_TEST(testMinLongDouble); + CPPUNIT_TEST(testCreateFromDoubleIn32BitsPlatform); + CPPUNIT_TEST_SUITE_END(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION(FractionTest); +} // namespace tools + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_fround.cxx b/tools/qa/cppunit/test_fround.cxx new file mode 100644 index 000000000..4014ff3cb --- /dev/null +++ b/tools/qa/cppunit/test_fround.cxx @@ -0,0 +1,62 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/types.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <tools/helpers.hxx> + +namespace tools +{ +class FRoundTest : public CppUnit::TestFixture +{ +public: + void testPositiveFRound() + { + sal_Int64 nExpected = 2; + sal_Int64 nActual = FRound(1.6); + CPPUNIT_ASSERT_EQUAL(nExpected, nActual); + + nExpected = 1; + nActual = FRound(1.4); + CPPUNIT_ASSERT_EQUAL(nExpected, nActual); + } + + void testNegativeFRound() + { + sal_Int64 nExpected = -2; + sal_Int64 nActual = FRound(-1.6); + CPPUNIT_ASSERT_EQUAL(nExpected, nActual); + + nExpected = -1; + nActual = FRound(-1.4); + CPPUNIT_ASSERT_EQUAL(nExpected, nActual); + } + + CPPUNIT_TEST_SUITE(FRoundTest); + CPPUNIT_TEST(testPositiveFRound); + CPPUNIT_TEST(testNegativeFRound); + CPPUNIT_TEST_SUITE_END(); +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(FRoundTest); +} // namespace tools + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_guid.cxx b/tools/qa/cppunit/test_guid.cxx new file mode 100644 index 000000000..177e58591 --- /dev/null +++ b/tools/qa/cppunit/test_guid.cxx @@ -0,0 +1,123 @@ +/* -*- 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 <sal/types.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <tools/Guid.hxx> + +namespace tools +{ +class GuidTest : public CppUnit::TestFixture +{ +public: + void testGetString() + { + sal_uInt8 pArray[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + Guid aGuid(pArray); + CPPUNIT_ASSERT_EQUAL(OString("{01020304-0506-0708-090A-0B0C0D0E0F10}"), aGuid.getString()); + } + + void testCreate() + { + // data is generated when Guid is created + Guid aGuid1(Guid::Generate); + + // check it's not initialized to 0 + CPPUNIT_ASSERT(*std::max_element(aGuid1.begin(), aGuid1.end()) > 0u); + + // data is generated when Guid is created + Guid aGuid2(Guid::Generate); + + CPPUNIT_ASSERT_EQUAL(aGuid1, aGuid1); + CPPUNIT_ASSERT_EQUAL(aGuid2, aGuid2); + + CPPUNIT_ASSERT(aGuid1 != aGuid2); + } + + void testParse() + { + sal_uInt8 pArray1[16] = { 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5 }; + Guid aGuid1(pArray1); + + Guid aGuid2("{01010101-0202-0303-0404-050505050505}"); + CPPUNIT_ASSERT_EQUAL(aGuid1, aGuid2); + + sal_uInt8 pArray2[16] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + Guid aGuid3(pArray2); + + Guid aGuid4("{FFffFFff-FFff-FFff-FFff-FFffFFffFFff}"); + CPPUNIT_ASSERT_EQUAL(aGuid3, aGuid4); + + Guid aGuid5("{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}"); + CPPUNIT_ASSERT_EQUAL(aGuid5, aGuid4); + + Guid aGuid6("01010101-0202-0303-0404-0505050505005"); + CPPUNIT_ASSERT(aGuid6.isEmpty()); + + Guid aGuid7("Random"); + CPPUNIT_ASSERT(aGuid7.isEmpty()); + + Guid aGuid8("{0G010101-0202-0303-0404-050505050505}"); + CPPUNIT_ASSERT(aGuid8.isEmpty()); + + Guid aGuid9("{FFAAFFAA-FFAA-FFAA-FFAA-FF00FF11FF22}"); + CPPUNIT_ASSERT(!aGuid9.isEmpty()); + + Guid aGuid10("{FFAAFFAA?FFAA-FFAA-FFAA-FF00FF11FF22}"); + CPPUNIT_ASSERT(aGuid10.isEmpty()); + } + + void testEmpty() + { + sal_uInt8 pArray1[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + Guid aGuid1(pArray1); + CPPUNIT_ASSERT(aGuid1.isEmpty()); + + sal_uInt8 pArray2[16] = { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + Guid aGuid2(pArray2); + CPPUNIT_ASSERT(!aGuid2.isEmpty()); + + Guid aGuid3; + CPPUNIT_ASSERT(aGuid3.isEmpty()); + } + + void testCopyAndAssign() + { + sal_uInt8 pArray1[16] = { 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5 }; + Guid aGuid1(pArray1); + + // test copy constructor + Guid aGuid2(aGuid1); + CPPUNIT_ASSERT_EQUAL(aGuid1, aGuid2); + CPPUNIT_ASSERT(std::equal(aGuid1.cbegin(), aGuid1.cend(), aGuid2.cbegin(), aGuid2.cend())); + + // test assign + Guid aGuid3 = aGuid1; + CPPUNIT_ASSERT_EQUAL(aGuid3, aGuid1); + CPPUNIT_ASSERT(std::equal(aGuid3.cbegin(), aGuid3.cend(), aGuid1.cbegin(), aGuid1.cend())); + CPPUNIT_ASSERT_EQUAL(aGuid3, aGuid2); + CPPUNIT_ASSERT(std::equal(aGuid3.cbegin(), aGuid3.cend(), aGuid2.cbegin(), aGuid2.cend())); + } + + CPPUNIT_TEST_SUITE(GuidTest); + CPPUNIT_TEST(testGetString); + CPPUNIT_TEST(testCreate); + CPPUNIT_TEST(testParse); + CPPUNIT_TEST(testEmpty); + CPPUNIT_TEST(testCopyAndAssign); + CPPUNIT_TEST_SUITE_END(); +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(GuidTest); + +} // namespace tools + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_inetmime.cxx b/tools/qa/cppunit/test_inetmime.cxx new file mode 100644 index 000000000..12b164189 --- /dev/null +++ b/tools/qa/cppunit/test_inetmime.cxx @@ -0,0 +1,167 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <rtl/ustring.hxx> +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <tools/inetmime.hxx> + +namespace +{ + + class Test: public CppUnit::TestFixture + { + bool testDecode(char const * input, char const * expected); + public: + void test_decodeHeaderFieldBody(); + + void test_scanContentType_basic(); + void test_scanContentType_rfc2231(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(test_decodeHeaderFieldBody); + CPPUNIT_TEST(test_scanContentType_basic); + CPPUNIT_TEST(test_scanContentType_rfc2231); + CPPUNIT_TEST_SUITE_END(); + }; + + bool Test::testDecode(char const * input, char const * expected) + { + OUString result = INetMIME::decodeHeaderFieldBody(input); + return result.equalsAscii(expected); + } + + void Test::test_decodeHeaderFieldBody() + { + CPPUNIT_ASSERT(testDecode("=?iso-8859-1?B?QQ==?=", "A")); + CPPUNIT_ASSERT(testDecode("=?iso-8859-1?B?QUI=?=", "AB")); + CPPUNIT_ASSERT(testDecode("=?iso-8859-1?B?QUJD?=", "ABC")); + } + + void Test::test_scanContentType_basic() + { + OUString input + = "TEST/subTST; parm1=Value1; Parm2=\"unpacked value; %20\""; + // Just scan input for valid string: + auto end = INetMIME::scanContentType(input); + CPPUNIT_ASSERT(end != nullptr); + CPPUNIT_ASSERT_EQUAL(OUString(), OUString(end)); + // Scan input and parse type, subType and parameters: + OUString type; + OUString subType; + INetContentTypeParameterList parameters; + end = INetMIME::scanContentType(input, + &type, &subType, ¶meters); + CPPUNIT_ASSERT(end != nullptr); + CPPUNIT_ASSERT_EQUAL(OUString(), OUString(end)); + CPPUNIT_ASSERT_EQUAL(OUString("test"), type); + CPPUNIT_ASSERT_EQUAL(OUString("subtst"), subType); + CPPUNIT_ASSERT_EQUAL( + INetContentTypeParameterList::size_type(2), parameters.size()); + auto i = parameters.find("parm1"); + CPPUNIT_ASSERT(i != parameters.end()); + CPPUNIT_ASSERT_EQUAL(OString(), i->second.m_sCharset); + CPPUNIT_ASSERT_EQUAL(OString(), i->second.m_sLanguage); + CPPUNIT_ASSERT_EQUAL(OUString("Value1"), i->second.m_sValue); + CPPUNIT_ASSERT(i->second.m_bConverted); + i = parameters.find("parm2"); + CPPUNIT_ASSERT(i != parameters.end()); + CPPUNIT_ASSERT_EQUAL(OString(), i->second.m_sCharset); + CPPUNIT_ASSERT_EQUAL(OString(), i->second.m_sLanguage); + CPPUNIT_ASSERT_EQUAL(OUString("unpacked value; %20"), i->second.m_sValue); + CPPUNIT_ASSERT(i->second.m_bConverted); + } + + void Test::test_scanContentType_rfc2231() + { + // Test extended parameter with value split in 3 sections: + OUString input + = "TEST/subTST; " + "parm1*0*=US-ASCII'En'5%25%20; " + "Parm1*1*=of%2010;\t" + "parm1*2*=%20%3d%200.5"; + // Just scan input for valid string: + auto end = INetMIME::scanContentType(input); + CPPUNIT_ASSERT(end != nullptr); + CPPUNIT_ASSERT_EQUAL(OUString(), OUString(end)); + // Scan input and parse type, subType and parameters: + OUString type; + OUString subType; + INetContentTypeParameterList parameters; + end = INetMIME::scanContentType(input, + &type, &subType, ¶meters); + CPPUNIT_ASSERT(end != nullptr); + CPPUNIT_ASSERT_EQUAL(OUString(), OUString(end)); + CPPUNIT_ASSERT_EQUAL(OUString("test"), type); + CPPUNIT_ASSERT_EQUAL(OUString("subtst"), subType); + CPPUNIT_ASSERT_EQUAL( + INetContentTypeParameterList::size_type(1), parameters.size()); + auto i = parameters.find("parm1"); + CPPUNIT_ASSERT(i != parameters.end()); + CPPUNIT_ASSERT_EQUAL(OString("us-ascii"), i->second.m_sCharset); + CPPUNIT_ASSERT_EQUAL(OString("en"), i->second.m_sLanguage); + CPPUNIT_ASSERT_EQUAL(OUString("5% of 10 = 0.5"), i->second.m_sValue); + CPPUNIT_ASSERT(i->second.m_bConverted); + + // Test extended parameters with different value charsets: + input = "TEST/subTST;" + "parm1*0*=us-ascii'en'value;PARM1*1*=1;" + "parm2*0*=WINDOWS-1250'en-GB'value2%20%80;" + "parm3*0*=UNKNOWN'EN'value3;" + "parm1*1*=2"; // this parameter is a duplicate, + // the scan should end before this parameter + // Just scan input for valid string: + end = INetMIME::scanContentType(input); + CPPUNIT_ASSERT(end != nullptr); + CPPUNIT_ASSERT_EQUAL(OUString(";parm1*1*=2"), OUString(end)); // the invalid end of input + // Scan input and parse type, subType and parameters: + end = INetMIME::scanContentType(input, + &type, &subType, ¶meters); + CPPUNIT_ASSERT(end != nullptr); + CPPUNIT_ASSERT_EQUAL(OUString(";parm1*1*=2"), OUString(end)); // the invalid end of input + CPPUNIT_ASSERT_EQUAL(OUString("test"), type); + CPPUNIT_ASSERT_EQUAL(OUString("subtst"), subType); + CPPUNIT_ASSERT_EQUAL( + INetContentTypeParameterList::size_type(3), parameters.size()); + i = parameters.find("parm1"); + CPPUNIT_ASSERT(i != parameters.end()); + CPPUNIT_ASSERT_EQUAL(OString("us-ascii"), i->second.m_sCharset); + CPPUNIT_ASSERT_EQUAL(OString("en"), i->second.m_sLanguage); + CPPUNIT_ASSERT_EQUAL(OUString("value1"), i->second.m_sValue); + CPPUNIT_ASSERT(i->second.m_bConverted); + i = parameters.find("parm2"); + CPPUNIT_ASSERT(i != parameters.end()); + CPPUNIT_ASSERT_EQUAL(OString("windows-1250"), i->second.m_sCharset); + CPPUNIT_ASSERT_EQUAL(OString("en-gb"), i->second.m_sLanguage); + // Euro currency sign, windows-1250 x80 is converted to unicode u20AC: + CPPUNIT_ASSERT_EQUAL(OUString(u"value2 \u20AC"), i->second.m_sValue); + CPPUNIT_ASSERT(i->second.m_bConverted); + i = parameters.find("parm3"); + CPPUNIT_ASSERT(i != parameters.end()); + CPPUNIT_ASSERT_EQUAL(OString("unknown"), i->second.m_sCharset); + CPPUNIT_ASSERT_EQUAL(OString("en"), i->second.m_sLanguage); + // Conversion fails for unknown charsets: + CPPUNIT_ASSERT(!i->second.m_bConverted); + } + + CPPUNIT_TEST_SUITE_REGISTRATION(Test); +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_json_writer.cxx b/tools/qa/cppunit/test_json_writer.cxx new file mode 100644 index 000000000..188b22f9c --- /dev/null +++ b/tools/qa/cppunit/test_json_writer.cxx @@ -0,0 +1,104 @@ +/* -*- 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 <sal/config.h> + +#include <cppunit/extensions/HelperMacros.h> +#include <o3tl/deleter.hxx> +#include <test/bootstrapfixture.hxx> +#include <rtl/ustring.hxx> +#include <tools/json_writer.hxx> + +namespace +{ +class JsonWriterTest : public test::BootstrapFixture +{ +public: + JsonWriterTest() + : BootstrapFixture(true, false) + { + } + + virtual void setUp() override {} + + void test1(); + void test2(); + void testArray(); + + CPPUNIT_TEST_SUITE(JsonWriterTest); + CPPUNIT_TEST(test1); + CPPUNIT_TEST(test2); + CPPUNIT_TEST(testArray); + CPPUNIT_TEST_SUITE_END(); +}; + +void JsonWriterTest::test1() +{ + tools::JsonWriter aJson; + + { + auto testNode = aJson.startNode("node"); + aJson.put("oustring", OUString("val1")); + aJson.put("charptr", "val3"); + aJson.put("int", static_cast<sal_Int32>(12)); + } + + std::unique_ptr<char, o3tl::free_delete> result(aJson.extractData()); + + CPPUNIT_ASSERT_EQUAL(std::string("{ \"node\": { \"oustring\": \"val1\", " + "\"charptr\": \"val3\", \"int\": 12}}"), + std::string(result.get())); +} + +void JsonWriterTest::test2() +{ + tools::JsonWriter aJson; + + { + auto testNode = aJson.startNode("node"); + aJson.put("field1", OUString("val1")); + aJson.put("field2", OUString("val2")); + { + auto testNode2 = aJson.startNode("node"); + aJson.put("field3", OUString("val3")); + { + auto testNode3 = aJson.startNode("node"); + aJson.put("field4", OUString("val4")); + aJson.put("field5", OUString("val5")); + } + } + } + + std::unique_ptr<char, o3tl::free_delete> result(aJson.extractData()); + + CPPUNIT_ASSERT_EQUAL(std::string("{ \"node\": { \"field1\": \"val1\", \"field2\": \"val2\", " + "\"node\": { \"field3\": \"val3\", \"node\": { \"field4\": " + "\"val4\", \"field5\": \"val5\"}}}}"), + std::string(result.get())); +} + +void JsonWriterTest::testArray() +{ + tools::JsonWriter aJson; + { + tools::ScopedJsonWriterArray aArray = aJson.startArray("items"); + aJson.putSimpleValue("foo"); + aJson.putSimpleValue("bar"); + } + + std::unique_ptr<char, o3tl::free_delete> aResult(aJson.extractData()); + + CPPUNIT_ASSERT_EQUAL(std::string("{ \"items\": [ \"foo\", \"bar\"]}"), + std::string(aResult.get())); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(JsonWriterTest); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_minmax.cxx b/tools/qa/cppunit/test_minmax.cxx new file mode 100644 index 000000000..509499910 --- /dev/null +++ b/tools/qa/cppunit/test_minmax.cxx @@ -0,0 +1,98 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/types.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <tools/helpers.hxx> + +namespace tools +{ +class MinMaxTest : public CppUnit::TestFixture +{ +public: + void testSignedMinMax() + { + sal_Int32 nSignedVal = -10; + tools::Long nMin = 1; + tools::Long nMax = 10; + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(nMin), + static_cast<sal_Int32>(MinMax(nSignedVal, nMin, nMax))); + + nSignedVal = -10; + nMin = -15; + nMax = 10; + CPPUNIT_ASSERT_EQUAL(nSignedVal, static_cast<sal_Int32>(MinMax(nSignedVal, nMin, nMax))); + + nSignedVal = -15; + nMin = -15; + nMax = 10; + CPPUNIT_ASSERT_EQUAL(nSignedVal, static_cast<sal_Int32>(MinMax(nSignedVal, nMin, nMax))); + } + + void testUnsignedMinMax() + { + sal_uInt32 nUnsignedVal = 5; + tools::Long nMin = 1; + tools::Long nMax = 10; + CPPUNIT_ASSERT_EQUAL(nUnsignedVal, + static_cast<sal_uInt32>(MinMax(nUnsignedVal, nMin, nMax))); + + nUnsignedVal = 5; + nMin = 1; + nMax = 5; + CPPUNIT_ASSERT_EQUAL(nUnsignedVal, + static_cast<sal_uInt32>(MinMax(nUnsignedVal, nMin, nMax))); + + nUnsignedVal = 5; + nMin = 5; + nMax = 5; + CPPUNIT_ASSERT_EQUAL(nUnsignedVal, + static_cast<sal_uInt32>(MinMax(nUnsignedVal, nMin, nMax))); + + nUnsignedVal = 10; + nMin = -20; + nMax = 15; + CPPUNIT_ASSERT_EQUAL(nUnsignedVal, + static_cast<sal_uInt32>(MinMax(nUnsignedVal, nMin, nMax))); + + nUnsignedVal = 20; + nMin = 10; + nMax = 15; + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(nMax), + static_cast<sal_uInt32>(MinMax(nUnsignedVal, nMin, nMax))); + + nUnsignedVal = 5; + nMin = 10; + nMax = 15; // irrelevant, but cannot be less than nMin + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(nMin), + static_cast<sal_uInt32>(MinMax(nUnsignedVal, nMin, nMax))); + } + + CPPUNIT_TEST_SUITE(MinMaxTest); + CPPUNIT_TEST(testSignedMinMax); + CPPUNIT_TEST(testUnsignedMinMax); + CPPUNIT_TEST_SUITE_END(); +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(MinMaxTest); +} // namespace tools + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_pathutils.cxx b/tools/qa/cppunit/test_pathutils.cxx new file mode 100644 index 000000000..7ad75f1e8 --- /dev/null +++ b/tools/qa/cppunit/test_pathutils.cxx @@ -0,0 +1,66 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <cwchar> + +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <tools/pathutils.hxx> + +namespace +{ +void buildPath(wchar_t const* front, wchar_t const* back, wchar_t const* path) +{ +#if defined(_WIN32) + wchar_t p[MAX_PATH]; + wchar_t* e = tools::buildPath(p, front, front + std::wcslen(front), back, std::wcslen(back)); + CPPUNIT_ASSERT_EQUAL(static_cast<void*>(p + std::wcslen(path)), static_cast<void*>(e)); + CPPUNIT_ASSERT_EQUAL(0, std::wcscmp(path, p)); +#else + (void)front; + (void)back; + (void)path; +#endif +} + +class Test : public CppUnit::TestFixture +{ +public: + void testBuildPath(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testBuildPath); + CPPUNIT_TEST_SUITE_END(); +}; + +void Test::testBuildPath() +{ + buildPath(L"a:\\b\\", L"..", L"a:\\"); + buildPath(L"a:\\b\\", L"..\\", L"a:\\"); + buildPath(L"a:\\b\\c\\", L"..\\..\\..\\d", L"a:\\..\\d"); + buildPath(L"\\\\a\\b\\", L"..\\..\\..\\c", L"\\\\..\\c"); + buildPath(L"\\", L"..\\a", L"\\..\\a"); + buildPath(L"", L"..\\a", L"..\\a"); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(Test); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_poly.cxx b/tools/qa/cppunit/test_poly.cxx new file mode 100644 index 000000000..f966f5317 --- /dev/null +++ b/tools/qa/cppunit/test_poly.cxx @@ -0,0 +1,54 @@ +/* -*- 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 <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <tools/poly.hxx> + +namespace +{ +class Test : public CppUnit::TestFixture +{ +public: + void testTdf137068(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testTdf137068); + CPPUNIT_TEST_SUITE_END(); +}; + +void Test::testTdf137068() +{ + // Make sure PolyPolygon::Clip() does not break bezier curves. + const Point points[] = { { 1337, 411 }, { 1337, 471 }, { 1313, 530 }, { 1268, 582 } }; + const PolyFlags flags[] + = { PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control, PolyFlags::Normal }; + tools::Polygon polygon(4, points, flags); + tools::PolyPolygon polyPolygon(polygon); + polyPolygon.Clip(tools::Rectangle(Point(0, 0), Size(1920, 1080))); + // operator== is stupid and just compares pointers, compare data manually + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), polyPolygon.Count()); + tools::Polygon result = polyPolygon.GetObject(0); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(4), result.GetSize()); + CPPUNIT_ASSERT_EQUAL(points[0], result.GetPoint(0)); + CPPUNIT_ASSERT_EQUAL(points[1], result.GetPoint(1)); + CPPUNIT_ASSERT_EQUAL(points[2], result.GetPoint(2)); + CPPUNIT_ASSERT_EQUAL(points[3], result.GetPoint(3)); + CPPUNIT_ASSERT_EQUAL(flags[0], result.GetFlags(0)); + CPPUNIT_ASSERT_EQUAL(flags[1], result.GetFlags(1)); + CPPUNIT_ASSERT_EQUAL(flags[2], result.GetFlags(2)); + CPPUNIT_ASSERT_EQUAL(flags[3], result.GetFlags(3)); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(Test); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_rectangle.cxx b/tools/qa/cppunit/test_rectangle.cxx new file mode 100644 index 000000000..2b6518d79 --- /dev/null +++ b/tools/qa/cppunit/test_rectangle.cxx @@ -0,0 +1,115 @@ +/* -*- 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 <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <tools/gen.hxx> + +namespace +{ +class Test : public CppUnit::TestFixture +{ +public: + void test_rectangle(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(test_rectangle); + CPPUNIT_TEST_SUITE_END(); +}; + +void Test::test_rectangle() +{ + { + tools::Rectangle aRect(1, 1, 1, 1); + + CPPUNIT_ASSERT_EQUAL(tools::Long(1), aRect.GetWidth()); + CPPUNIT_ASSERT_EQUAL(tools::Long(1), aRect.GetHeight()); + + CPPUNIT_ASSERT_EQUAL(tools::Long(0), aRect.getWidth()); + CPPUNIT_ASSERT_EQUAL(tools::Long(0), aRect.getHeight()); + } + + { + tools::Rectangle aRect(Point(), Size(1, 1)); + + CPPUNIT_ASSERT_EQUAL(tools::Long(0), aRect.Left()); + CPPUNIT_ASSERT_EQUAL(tools::Long(0), aRect.Top()); + CPPUNIT_ASSERT_EQUAL(tools::Long(0), aRect.Right()); + CPPUNIT_ASSERT_EQUAL(tools::Long(0), aRect.Bottom()); + + CPPUNIT_ASSERT_EQUAL(tools::Long(1), aRect.GetWidth()); + CPPUNIT_ASSERT_EQUAL(tools::Long(1), aRect.GetHeight()); + + // getWidth and getHeight return the size that excludes one of the bounds, + // unlike the ctor and GetWidth / GetHeight that operate on inclusive size + CPPUNIT_ASSERT_EQUAL(tools::Long(0), aRect.getWidth()); + CPPUNIT_ASSERT_EQUAL(tools::Long(0), aRect.getHeight()); + + aRect.SetPosX(12); + CPPUNIT_ASSERT_EQUAL(tools::Long(1), aRect.GetHeight()); + aRect.SetPosY(12); + CPPUNIT_ASSERT_EQUAL(tools::Long(1), aRect.GetWidth()); + } + + { + constexpr tools::Rectangle aRect(Point(), Size(-1, -2)); + static_assert(!aRect.IsEmpty()); + static_assert(aRect.Right() == 0); + static_assert(aRect.Bottom() == -1); + + tools::Rectangle aRect2; + aRect2.SetSize(Size(-1, -2)); + CPPUNIT_ASSERT_EQUAL(aRect, aRect2); + } + + { + constexpr tools::Rectangle aRectTwip(100, 100, 100, 100); + constexpr tools::Rectangle aRectMm100( + o3tl::convert(aRectTwip, o3tl::Length::twip, o3tl::Length::mm100)); + static_assert(!aRectMm100.IsEmpty()); + // Make sure that we use coordinates for conversion, not width/height: + // the latter is ambiguous, and e.g. GetWidth(aRectTwip) gives 1, which + // would had been converted to 2, resulting in different LR coordinates + static_assert(aRectMm100.Left() == aRectMm100.Right()); + static_assert(aRectMm100.Top() == aRectMm100.Bottom()); + } + + { + constexpr tools::Rectangle aRectTwip(1, 1); + constexpr tools::Rectangle aRectMm100( + o3tl::convert(aRectTwip, o3tl::Length::twip, o3tl::Length::mm100)); + // Make sure that result keeps the empty flag + static_assert(aRectMm100.IsEmpty()); + static_assert(aRectMm100.IsWidthEmpty()); + static_assert(aRectMm100.IsHeightEmpty()); + static_assert(aRectMm100.GetWidth() == 0); + static_assert(aRectMm100.GetHeight() == 0); + } + + { + constexpr tools::Rectangle rect(Point(0, 0), Size(20, 20)); + constexpr tools::Rectangle inside(Point(10, 10), Size(10, 10)); + constexpr tools::Rectangle overlap(Point(10, 10), Size(20, 20)); + constexpr tools::Rectangle outside(Point(20, 20), Size(10, 10)); + CPPUNIT_ASSERT(rect.Contains(inside)); + CPPUNIT_ASSERT(rect.Contains(rect)); + CPPUNIT_ASSERT(!rect.Contains(overlap)); + CPPUNIT_ASSERT(!rect.Contains(outside)); + CPPUNIT_ASSERT(rect.Overlaps(inside)); + CPPUNIT_ASSERT(rect.Overlaps(rect)); + CPPUNIT_ASSERT(rect.Overlaps(overlap)); + CPPUNIT_ASSERT(!rect.Overlaps(outside)); + } +} + +CPPUNIT_TEST_SUITE_REGISTRATION(Test); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_reversemap.cxx b/tools/qa/cppunit/test_reversemap.cxx new file mode 100644 index 000000000..be70ade79 --- /dev/null +++ b/tools/qa/cppunit/test_reversemap.cxx @@ -0,0 +1,154 @@ +/* -*- 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 <sal/types.h> +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/plugin/TestPlugIn.h> +#include <rtl/ustring.hxx> +#include <vector> + +#include <tools/tenccvt.hxx> + +//Tests for getBestMSEncodingByChar + +namespace +{ + + class Test: public CppUnit::TestFixture + { + public: + void testEncoding(rtl_TextEncoding eEncoding); + + void test1258(); + void test1257(); + void test1256(); + void test1255(); + void test1254(); + void test1253(); + void test1252(); + void test1251(); + void test1250(); + void test874(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(test1258); + CPPUNIT_TEST(test1257); + CPPUNIT_TEST(test1256); + CPPUNIT_TEST(test1255); + CPPUNIT_TEST(test1254); + CPPUNIT_TEST(test1253); + CPPUNIT_TEST(test1252); + CPPUNIT_TEST(test1251); + CPPUNIT_TEST(test1250); + CPPUNIT_TEST(test874); + CPPUNIT_TEST_SUITE_END(); + }; + + void Test::testEncoding(rtl_TextEncoding eEncoding) + { + //Taking the single byte legacy encodings, fill in all possible values + std::vector<char> aAllChars(255); + for (int i = 1; i <= 255; ++i) + aAllChars[i-1] = static_cast<char>(i); + + //Some slots are unused, so don't map to private, just set them to 'X' + sal_uInt32 const convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS ^ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MAPTOPRIVATE; + OUString sOrigText(aAllChars.data(), aAllChars.size(), eEncoding, convertFlags); + sOrigText = sOrigText.replace( 0xfffd, 'X' ); + + //Should clearly be equal + sal_Int32 nLength = aAllChars.size(); + CPPUNIT_ASSERT_EQUAL(sOrigText.getLength(), nLength); + + OUString sFinalText; + + //Split up in chunks of the same encoding returned by + //getBestMSEncodingByChar, convert to it, and back + rtl_TextEncoding ePrevEncoding = RTL_TEXTENCODING_DONTKNOW; + const sal_Unicode *pStr = sOrigText.getStr(); + sal_Int32 nChunkStart=0; + for (int i = 0; i < 255; ++i) + { + rtl_TextEncoding eCurrEncoding = getBestMSEncodingByChar(pStr[i]); + if (eCurrEncoding != ePrevEncoding) + { + OString aChunk(pStr+nChunkStart, i-nChunkStart, ePrevEncoding); + sFinalText += OStringToOUString(aChunk, ePrevEncoding); + nChunkStart = i; + } + ePrevEncoding = eCurrEncoding; + } + if (nChunkStart < 255) + { + OString aChunk(pStr+nChunkStart, 255-nChunkStart, ePrevEncoding); + sFinalText += OStringToOUString(aChunk, ePrevEncoding); + } + + //Final text should be the same as original + CPPUNIT_ASSERT_EQUAL(sOrigText, sFinalText); + } + + void Test::test1252() + { + testEncoding(RTL_TEXTENCODING_MS_1252); + } + + void Test::test874() + { + testEncoding(RTL_TEXTENCODING_MS_874); + } + + void Test::test1258() + { + testEncoding(RTL_TEXTENCODING_MS_1258); + } + + void Test::test1257() + { + testEncoding(RTL_TEXTENCODING_MS_1257); + } + + void Test::test1256() + { + testEncoding(RTL_TEXTENCODING_MS_1256); + } + + void Test::test1255() + { + testEncoding(RTL_TEXTENCODING_MS_1255); + } + + void Test::test1254() + { + testEncoding(RTL_TEXTENCODING_MS_1254); + } + + void Test::test1253() + { + testEncoding(RTL_TEXTENCODING_MS_1253); + } + + void Test::test1251() + { + testEncoding(RTL_TEXTENCODING_MS_1251); + } + + void Test::test1250() + { + testEncoding(RTL_TEXTENCODING_MS_1250); + } + + CPPUNIT_TEST_SUITE_REGISTRATION(Test); +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_stream.cxx b/tools/qa/cppunit/test_stream.cxx new file mode 100644 index 000000000..02fe22343 --- /dev/null +++ b/tools/qa/cppunit/test_stream.cxx @@ -0,0 +1,321 @@ +/* -*- 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 <sal/types.h> +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <tools/stream.hxx> +#include <unotools/tempfile.hxx> +#include <sstream> + +//Tests for eofbit/badbit/goodbit/failbit + +namespace +{ + + class Test: public CppUnit::TestFixture + { + public: + void test_stdstream(); + void test_fastostring(); + void test_read_cstring(); + void test_read_pstring(); + void test_readline(); + void test_write_unicode(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(test_stdstream); + CPPUNIT_TEST(test_fastostring); + CPPUNIT_TEST(test_read_cstring); + CPPUNIT_TEST(test_read_pstring); + CPPUNIT_TEST(test_readline); + CPPUNIT_TEST(test_write_unicode); + CPPUNIT_TEST_SUITE_END(); + }; + + void Test::test_stdstream() + { + char foo[] = "foo"; + std::istringstream iss(foo, std::istringstream::in); + SvMemoryStream aMemStream(foo, SAL_N_ELEMENTS(foo)-1, StreamMode::READ); + + char std_a(78); + iss >> std_a; + CPPUNIT_ASSERT_EQUAL('f', std_a); + + char tools_a(78); + aMemStream.ReadChar( tools_a ); + CPPUNIT_ASSERT_EQUAL('f', tools_a); + + iss.seekg(0, std::ios_base::end); + //seeking to end doesn't set eof, reading past eof does + CPPUNIT_ASSERT(!iss.eof()); + CPPUNIT_ASSERT(iss.good()); + + aMemStream.Seek(STREAM_SEEK_TO_END); + //seeking to end doesn't set eof, reading past eof does + CPPUNIT_ASSERT(!aMemStream.eof()); + CPPUNIT_ASSERT(aMemStream.good()); + + std_a = 78; + iss >> std_a; + //so, now eof is set + CPPUNIT_ASSERT(iss.eof()); + //a failed read doesn't change the data, it remains unchanged + CPPUNIT_ASSERT_EQUAL(static_cast<char>(78), std_a); + //nothing wrong with the stream, so not bad + CPPUNIT_ASSERT(!iss.bad()); + //yet, the read didn't succeed + CPPUNIT_ASSERT(!iss.good()); + CPPUNIT_ASSERT_EQUAL((std::ios::failbit|std::ios::eofbit), iss.rdstate()); + + tools_a = 78; + aMemStream.ReadChar( tools_a ); + //so, now eof is set + CPPUNIT_ASSERT(aMemStream.eof()); + //a failed read doesn't change the data, it remains unchanged + CPPUNIT_ASSERT_EQUAL(static_cast<char>(78), tools_a); + //nothing wrong with the stream, so not bad + CPPUNIT_ASSERT(!aMemStream.bad()); + //yet, the read didn't succeed + CPPUNIT_ASSERT(!aMemStream.good()); + + //set things up so that there is only one byte available on an attempt + //to read a two-byte sal_uInt16. The byte should be consumed, but the + //operation should fail, and tools_b should remain unchanged, + sal_uInt16 tools_b = 0x1122; + aMemStream.SeekRel(-1); + CPPUNIT_ASSERT(!aMemStream.eof()); + CPPUNIT_ASSERT(aMemStream.good()); + aMemStream.ReadUInt16( tools_b ); + CPPUNIT_ASSERT(!aMemStream.good()); + CPPUNIT_ASSERT(aMemStream.eof()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(0x1122), tools_b); + + iss.clear(); + iss.seekg(0); + CPPUNIT_ASSERT(iss.good()); + iss >> std_a; + CPPUNIT_ASSERT_EQUAL('f', std_a); + + aMemStream.Seek(0); + CPPUNIT_ASSERT(aMemStream.good()); + aMemStream.ReadChar( tools_a ); + CPPUNIT_ASSERT_EQUAL('f', tools_a); + + //failbit is rather subtle wrt e.g seeks + + char buffer[1024]; + + iss.clear(); + iss.seekg(0); + CPPUNIT_ASSERT(iss.good()); + iss.read(buffer, sizeof(buffer)); + CPPUNIT_ASSERT_EQUAL(static_cast<std::streamsize>(3), iss.gcount()); + CPPUNIT_ASSERT(!iss.good()); + CPPUNIT_ASSERT(!iss.bad()); + CPPUNIT_ASSERT(iss.eof()); + + aMemStream.Seek(0); + CPPUNIT_ASSERT(aMemStream.good()); + std::size_t nRet = aMemStream.ReadBytes(buffer, sizeof(buffer)); + CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(3), nRet); + CPPUNIT_ASSERT(!aMemStream.good()); + CPPUNIT_ASSERT(!aMemStream.bad()); + CPPUNIT_ASSERT(aMemStream.eof()); + } + + void Test::test_fastostring() + { + char foo[] = "foobar"; + SvMemoryStream aMemStream(foo, SAL_N_ELEMENTS(foo)-1, StreamMode::READ); + + OString aOne = read_uInt8s_ToOString(aMemStream, 3); + CPPUNIT_ASSERT_EQUAL(OString("foo"), aOne); + + OString aTwo = read_uInt8s_ToOString(aMemStream, 3); + CPPUNIT_ASSERT_EQUAL(OString("bar"), aTwo); + + OString aThree = read_uInt8s_ToOString(aMemStream, 3); + CPPUNIT_ASSERT(aThree.isEmpty()); + + aMemStream.Seek(0); + + OString aFour = read_uInt8s_ToOString(aMemStream, 100); + CPPUNIT_ASSERT_EQUAL(OString(foo), aFour); + } + + void Test::test_read_cstring() + { + char foo[] = "foobar"; + SvMemoryStream aMemStream(foo, SAL_N_ELEMENTS(foo)-1, StreamMode::READ); + + OString aOne = read_zeroTerminated_uInt8s_ToOString(aMemStream); + CPPUNIT_ASSERT_EQUAL(OString("foobar"), aOne); + CPPUNIT_ASSERT(!aMemStream.good()); + CPPUNIT_ASSERT(!aMemStream.bad()); + CPPUNIT_ASSERT(aMemStream.eof()); + + aMemStream.Seek(0); + foo[3] = 0; + OString aTwo = read_zeroTerminated_uInt8s_ToOString(aMemStream); + CPPUNIT_ASSERT_EQUAL(OString("foo"), aTwo); + CPPUNIT_ASSERT(aMemStream.good()); + } + + void Test::test_read_pstring() + { + char foo[] = "\3foobar"; + SvMemoryStream aMemStream(foo, SAL_N_ELEMENTS(foo)-1, StreamMode::READ); + + OString aFoo = read_uInt8_lenPrefixed_uInt8s_ToOString(aMemStream); + CPPUNIT_ASSERT_EQUAL(OString("foo"), aFoo); + CPPUNIT_ASSERT(aMemStream.good()); + CPPUNIT_ASSERT(!aMemStream.bad()); + CPPUNIT_ASSERT(!aMemStream.eof()); + + aMemStream.Seek(0); + foo[0] = 10; + aFoo = read_uInt8_lenPrefixed_uInt8s_ToOString(aMemStream); + CPPUNIT_ASSERT_EQUAL(OString("foobar"), aFoo); + CPPUNIT_ASSERT(!aMemStream.good()); + CPPUNIT_ASSERT(!aMemStream.bad()); + CPPUNIT_ASSERT(aMemStream.eof()); + + aMemStream.SetEndian(SvStreamEndian::BIG); + aMemStream.Seek(0); + foo[0] = 0; + foo[1] = 3; + aFoo = read_uInt16_lenPrefixed_uInt8s_ToOString(aMemStream); + CPPUNIT_ASSERT_EQUAL(OString("oob"), aFoo); + CPPUNIT_ASSERT(aMemStream.good()); + CPPUNIT_ASSERT(!aMemStream.bad()); + CPPUNIT_ASSERT(!aMemStream.eof()); + } + + void Test::test_readline() + { + char foo[] = "foo\nbar\n\n"; + SvMemoryStream aMemStream(foo, SAL_N_ELEMENTS(foo)-1, StreamMode::READ); + + OString aFoo; + bool bRet; + + bRet = aMemStream.ReadLine(aFoo); + CPPUNIT_ASSERT(bRet); + CPPUNIT_ASSERT_EQUAL(OString("foo"), aFoo); + CPPUNIT_ASSERT(aMemStream.good()); + + bRet = aMemStream.ReadLine(aFoo); + CPPUNIT_ASSERT(bRet); + CPPUNIT_ASSERT_EQUAL(OString("bar"), aFoo); + CPPUNIT_ASSERT(aMemStream.good()); + + bRet = aMemStream.ReadLine(aFoo); + CPPUNIT_ASSERT(bRet); + CPPUNIT_ASSERT(aFoo.isEmpty()); + CPPUNIT_ASSERT(aMemStream.good()); + + bRet = aMemStream.ReadLine(aFoo); + CPPUNIT_ASSERT(!bRet); + CPPUNIT_ASSERT(aFoo.isEmpty()); + CPPUNIT_ASSERT(aMemStream.eof()); + + foo[3] = 0; //test reading embedded nulls + + aMemStream.Seek(0); + bRet = aMemStream.ReadLine(aFoo); + CPPUNIT_ASSERT(bRet); + CPPUNIT_ASSERT_EQUAL(sal_Int32(7), aFoo.getLength()); + CPPUNIT_ASSERT_EQUAL('\0', aFoo[3]); + CPPUNIT_ASSERT(aMemStream.good()); + + std::string sStr(foo, RTL_CONSTASCII_LENGTH(foo)); + std::istringstream iss(sStr, std::istringstream::in); + std::getline(iss, sStr, '\n'); + //embedded null read as expected + CPPUNIT_ASSERT_EQUAL(std::string::size_type(7), sStr.size()); + CPPUNIT_ASSERT_EQUAL('\0', sStr[3]); + CPPUNIT_ASSERT(iss.good()); + + bRet = aMemStream.ReadLine(aFoo); + CPPUNIT_ASSERT(bRet); + CPPUNIT_ASSERT(aFoo.isEmpty()); + CPPUNIT_ASSERT(aMemStream.good()); + + std::getline(iss, sStr, '\n'); + CPPUNIT_ASSERT(sStr.empty()); + CPPUNIT_ASSERT(iss.good()); + + bRet = aMemStream.ReadLine(aFoo); + CPPUNIT_ASSERT(!bRet); + CPPUNIT_ASSERT(aFoo.isEmpty()); + CPPUNIT_ASSERT(aMemStream.eof()); + CPPUNIT_ASSERT(!aMemStream.bad()); + + std::getline(iss, sStr, '\n'); + CPPUNIT_ASSERT(sStr.empty()); + CPPUNIT_ASSERT(iss.eof()); + CPPUNIT_ASSERT(!iss.bad()); + + char bar[] = "foo"; + SvMemoryStream aMemStreamB(bar, SAL_N_ELEMENTS(bar)-1, StreamMode::READ); + bRet = aMemStreamB.ReadLine(aFoo); + CPPUNIT_ASSERT(bRet); + CPPUNIT_ASSERT_EQUAL(OString("foo"), aFoo); + CPPUNIT_ASSERT(!aMemStreamB.eof()); //<-- diff A + + std::istringstream issB(bar, std::istringstream::in); + std::getline(issB, sStr, '\n'); + CPPUNIT_ASSERT_EQUAL(std::string("foo"), sStr); + CPPUNIT_ASSERT(issB.eof()); //<-- diff A + } + + void Test::test_write_unicode() + { + const OUString write("abc"); + utl::TempFile aTempFile(u"test_write_unicode"); + aTempFile.EnableKillingFile(); + { + SvStream& s = *aTempFile.GetStream(StreamMode::WRITE); + s.SetEndian(SvStreamEndian::BIG); + if (!s.IsEndianSwap()) + s.SetEndian(SvStreamEndian::LITTLE); + CPPUNIT_ASSERT(s.IsEndianSwap()); + // StartWritingUnicodeText must switch to no endian swapping and write 0xfeff + s.StartWritingUnicodeText(); + // Without the fix in place, this would fail + CPPUNIT_ASSERT(!s.IsEndianSwap()); + s.WriteUnicodeOrByteText(write, RTL_TEXTENCODING_UNICODE); + aTempFile.CloseStream(); + } + { + SvStream& s = *aTempFile.GetStream(StreamMode::READ); + s.SetEndian(SvStreamEndian::BIG); + if (!s.IsEndianSwap()) + s.SetEndian(SvStreamEndian::LITTLE); + CPPUNIT_ASSERT(s.IsEndianSwap()); + s.StartReadingUnicodeText(RTL_TEXTENCODING_DONTKNOW); + CPPUNIT_ASSERT(!s.IsEndianSwap()); + CPPUNIT_ASSERT_EQUAL(sal_uInt64(2), s.Tell()); // after BOM + OUString read; + CPPUNIT_ASSERT(s.ReadUniOrByteStringLine(read, RTL_TEXTENCODING_UNICODE)); + // Without the fix in place, this would fail with + // - Expected: abc + // - Actual : 愀戀挀 + CPPUNIT_ASSERT_EQUAL(write, read); + aTempFile.CloseStream(); + } + } + + CPPUNIT_TEST_SUITE_REGISTRATION(Test); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_time.cxx b/tools/qa/cppunit/test_time.cxx new file mode 100644 index 000000000..a21f98d7b --- /dev/null +++ b/tools/qa/cppunit/test_time.cxx @@ -0,0 +1,154 @@ +/* -*- 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 <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <tools/time.hxx> + +namespace tools +{ +class TimeTest : public CppUnit::TestFixture +{ +public: + void testTime(); + void testClockValues(); + + CPPUNIT_TEST_SUITE(TimeTest); + CPPUNIT_TEST(testTime); + CPPUNIT_TEST(testClockValues); + CPPUNIT_TEST_SUITE_END(); +}; + +void TimeTest::testTime() +{ + Time aOrigTime(1, 56, 10); + auto nMS = aOrigTime.GetMSFromTime(); + + Time aNewTime(0); + aNewTime.MakeTimeFromMS(nMS); + + CPPUNIT_ASSERT(bool(aOrigTime == aNewTime)); +} + +void TimeTest::testClockValues() +{ + double fTime, fFractionOfSecond; + sal_uInt16 nHour, nMinute, nSecond; + + fTime = 0.0; + Time::GetClock(fTime, nHour, nMinute, nSecond, fFractionOfSecond, 0); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Hour value.", sal_uInt16(0), nHour); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Minute value.", sal_uInt16(0), nMinute); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Second value.", sal_uInt16(0), nSecond); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Fraction value.", 0.0, fFractionOfSecond, 0.0); + + fTime = 1.0; + Time::GetClock(fTime, nHour, nMinute, nSecond, fFractionOfSecond, 0); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Hour value.", sal_uInt16(0), nHour); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Minute value.", sal_uInt16(0), nMinute); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Second value.", sal_uInt16(0), nSecond); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Fraction value.", 0.0, fFractionOfSecond, 0.0); + + fTime = -1.0; + Time::GetClock(fTime, nHour, nMinute, nSecond, fFractionOfSecond, 0); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Hour value.", sal_uInt16(0), nHour); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Minute value.", sal_uInt16(0), nMinute); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Second value.", sal_uInt16(0), nSecond); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Fraction value.", 0.0, fFractionOfSecond, 0.0); + + fTime = 1.5; + Time::GetClock(fTime, nHour, nMinute, nSecond, fFractionOfSecond, 0); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Hour value.", sal_uInt16(12), nHour); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Minute value.", sal_uInt16(0), nMinute); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Second value.", sal_uInt16(0), nSecond); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Fraction value.", 0.0, fFractionOfSecond, 0.0); + + fTime = -1.5; + Time::GetClock(fTime, nHour, nMinute, nSecond, fFractionOfSecond, 0); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Hour value.", sal_uInt16(12), nHour); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Minute value.", sal_uInt16(0), nMinute); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Second value.", sal_uInt16(0), nSecond); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Fraction value.", 0.0, fFractionOfSecond, 0.0); + + fTime = 0.75; + Time::GetClock(fTime, nHour, nMinute, nSecond, fFractionOfSecond, 0); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Hour value.", sal_uInt16(18), nHour); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Minute value.", sal_uInt16(0), nMinute); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Second value.", sal_uInt16(0), nSecond); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Fraction value.", 0.0, fFractionOfSecond, 0.0); + + fTime = 0.0208333333333333; + Time::GetClock(fTime, nHour, nMinute, nSecond, fFractionOfSecond, 0); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Hour value.", sal_uInt16(0), nHour); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Minute value.", sal_uInt16(30), nMinute); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Second value.", sal_uInt16(0), nSecond); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Fraction value.", 0.0, fFractionOfSecond, 0.0); + + fTime = 0.0000115740625; + Time::GetClock(fTime, nHour, nMinute, nSecond, fFractionOfSecond, 3); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Hour value.", sal_uInt16(0), nHour); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Minute value.", sal_uInt16(0), nMinute); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Second value.", sal_uInt16(0), nSecond); + // Expect this to be a truncated 0.999999 + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Fraction value.", 0.999, fFractionOfSecond, 0.0); + + fTime = 0.524268391203704; + Time::GetClock(fTime, nHour, nMinute, nSecond, fFractionOfSecond, 3); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Hour value.", sal_uInt16(12), nHour); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Minute value.", sal_uInt16(34), nMinute); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Second value.", sal_uInt16(56), nSecond); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Fraction value.", 0.789, fFractionOfSecond, 0.0); + + fTime = -0.000001; + Time::GetClock(fTime, nHour, nMinute, nSecond, fFractionOfSecond, 13); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Hour value.", sal_uInt16(23), nHour); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Minute value.", sal_uInt16(59), nMinute); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Second value.", sal_uInt16(59), nSecond); + // Expect this to be exact within floating point accuracy. + // This is a hairy rounding condition, if it yields problems on any + // platform feel free to disable the test for that platform. + // At least when doing a 32-bit build on Linux x86 with GCC 8.2.1, when -Os from + // gb_COMPILEROPTFLAGS in solenv/gbuild/platform/LINUX_INTEL_GCC.mk is overridden by -O1 (or + // higher) passed into CXXFLAGS, the test fails with an actual value of 0.9136, for reasons not + // investigated further: +#if !(defined __GNUC__ && !defined __clang__ && defined X86 && defined __OPTIMIZE__ \ + && !defined __OPTIMIZE_SIZE__) + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Fraction value.", 0.9135999999999, fFractionOfSecond, + 1e-14); +#endif + + fTime = -0.000001; + Time::GetClock(fTime, nHour, nMinute, nSecond, fFractionOfSecond, 4); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Hour value.", sal_uInt16(23), nHour); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Minute value.", sal_uInt16(59), nMinute); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Second value.", sal_uInt16(59), nSecond); + // Expect this to be rounded. + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Fraction value.", 0.9136, fFractionOfSecond, 0.0); + + fTime = -0.00000000001; + Time::GetClock(fTime, nHour, nMinute, nSecond, fFractionOfSecond, 4); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Hour value.", sal_uInt16(23), nHour); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Minute value.", sal_uInt16(59), nMinute); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Second value.", sal_uInt16(59), nSecond); + // Expect this to be a truncated 0.999999 + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Fraction value.", 0.9999, fFractionOfSecond, 0.0); + + fTime = -1e-24; // value insignificant for time + Time::GetClock(fTime, nHour, nMinute, nSecond, fFractionOfSecond, 0); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Hour value.", sal_uInt16(0), nHour); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Minute value.", sal_uInt16(0), nMinute); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Second value.", sal_uInt16(0), nSecond); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Fraction value.", 0.0, fFractionOfSecond, 0.0); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(TimeTest); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/tools/qa/cppunit/test_urlobj.cxx b/tools/qa/cppunit/test_urlobj.cxx new file mode 100644 index 000000000..8402fae5e --- /dev/null +++ b/tools/qa/cppunit/test_urlobj.cxx @@ -0,0 +1,373 @@ +/* -*- 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 <memory> +#include <string> + +#include <sal/types.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <tools/stream.hxx> +#include <tools/urlobj.hxx> + +#define OUSTR_TO_STDSTR( oustr ) std::string( OUStringToOString( oustr, RTL_TEXTENCODING_ASCII_US ).getStr() ) + +CPPUNIT_NS_BEGIN + +template<> struct assertion_traits<INetProtocol> +{ + static bool equal( const INetProtocol& x, const INetProtocol& y ) + { + return x == y; + } + + static std::string toString( const INetProtocol& x ) + { + OStringStream ost; + ost << static_cast<unsigned int>(x); + return ost.str(); + } +}; + +CPPUNIT_NS_END + +namespace tools_urlobj +{ + + class urlobjTest:public CppUnit::TestFixture + { + + public: + // insert your test code here. + // this is only demonstration code + void urlobjTest_001( ) + { + INetURLObject aUrl( u"file://10.10.1.1/sampledir/sample.file" ); + CPPUNIT_ASSERT_EQUAL(INetProtocol::File, aUrl.GetProtocol()); + CPPUNIT_ASSERT_EQUAL(OUString("10.10.1.1"), + aUrl.GetHost(INetURLObject::DecodeMechanism::NONE)); + CPPUNIT_ASSERT_EQUAL(OUString("/sampledir/sample.file"), + aUrl.GetURLPath(INetURLObject::DecodeMechanism::NONE)); + CPPUNIT_ASSERT_EQUAL(OUString("sample.file"), + aUrl.getName()); + CPPUNIT_ASSERT_EQUAL(OUString("sample"), aUrl.getBase()); + CPPUNIT_ASSERT_EQUAL(OUString("file"), aUrl.getExtension()); + } + + void urlobjTest_004( ) + { + INetURLObject aUrl( u"smb://10.10.1.1/sampledir/sample.file" ); + CPPUNIT_ASSERT_EQUAL( INetProtocol::Smb, aUrl.GetProtocol( ) ); + CPPUNIT_ASSERT_EQUAL(OUString("10.10.1.1"), + aUrl.GetHost(INetURLObject::DecodeMechanism::NONE)); + CPPUNIT_ASSERT_EQUAL(OUString("/sampledir/sample.file"), + aUrl.GetURLPath(INetURLObject::DecodeMechanism::NONE)); + CPPUNIT_ASSERT_EQUAL(OUString("sample.file"), aUrl.getName()); + CPPUNIT_ASSERT_EQUAL(OUString("sample"), aUrl.getBase()); + CPPUNIT_ASSERT_EQUAL(OUString("file"), aUrl.getExtension()); + } + + void urlobjCmisTest( ) + { + // Test with a username part + { + INetURLObject aUrl( u"vnd.libreoffice.cmis://username@http:%2F%2Ffoo.bar.com:8080%2Fmy%2Fcmis%2Fatom%23repo-id-encoded/path/to/content" ); + CPPUNIT_ASSERT_EQUAL( std::string( "http://foo.bar.com:8080/my/cmis/atom#repo-id-encoded" ), + OUSTR_TO_STDSTR( aUrl.GetHost( INetURLObject::DecodeMechanism::WithCharset ) ) ); + CPPUNIT_ASSERT_EQUAL( std::string( "username" ), OUSTR_TO_STDSTR( aUrl.GetUser( ) ) ); + CPPUNIT_ASSERT_EQUAL( std::string( "/path/to/content" ), + OUSTR_TO_STDSTR( aUrl.GetURLPath( INetURLObject::DecodeMechanism::NONE ) ) ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Wrong protocol found", INetProtocol::Cmis, aUrl.GetProtocol( ) ); + } + + // Test without a username part + { + INetURLObject aUrl( + u"vnd.libreoffice.cmis://http:%2F%2Ffoo.bar.com:8080%2Fmy%2Fcmis%2Fatom%23repo-id-encoded/path/to/content" ); + CPPUNIT_ASSERT_EQUAL( std::string( "http://foo.bar.com:8080/my/cmis/atom#repo-id-encoded" ), + OUSTR_TO_STDSTR( aUrl.GetHost( INetURLObject::DecodeMechanism::WithCharset ) ) ); + CPPUNIT_ASSERT( !aUrl.HasUserData() ); + CPPUNIT_ASSERT_EQUAL( std::string( "/path/to/content" ), + OUSTR_TO_STDSTR( aUrl.GetURLPath( INetURLObject::DecodeMechanism::NONE ) ) ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Wrong protocol found", INetProtocol::Cmis, aUrl.GetProtocol( ) ); + } + } + + void urlobjTest_emptyPath() { + { + INetURLObject url(u"http://example.com"); + CPPUNIT_ASSERT_EQUAL(INetProtocol::Http, url.GetProtocol()); + CPPUNIT_ASSERT_EQUAL(OUString("example.com"), url.GetHost()); + CPPUNIT_ASSERT_EQUAL(OUString("/"), url.GetURLPath()); + } + { + // This is an invalid http URL per RFC 2616: + INetURLObject url(u"http://example.com?query"); + CPPUNIT_ASSERT(url.HasError()); + } + { + INetURLObject url(u"http://example.com#fragment"); + CPPUNIT_ASSERT_EQUAL(INetProtocol::Http, url.GetProtocol()); + CPPUNIT_ASSERT_EQUAL(OUString("example.com"), url.GetHost()); + CPPUNIT_ASSERT_EQUAL(OUString("/"), url.GetURLPath()); + CPPUNIT_ASSERT_EQUAL(OUString("fragment"), url.GetMark()); + } + } + + void urlobjTest_data() { + INetURLObject url; + std::unique_ptr<SvMemoryStream> strm; + unsigned char const * buf; + + url = INetURLObject(u"data:"); + //TODO: CPPUNIT_ASSERT(url.HasError()); + strm = url.getData(); + CPPUNIT_ASSERT(!strm); + + url = INetURLObject(u"data:,"); + CPPUNIT_ASSERT(!url.HasError()); + strm = url.getData(); + CPPUNIT_ASSERT(strm != nullptr); + CPPUNIT_ASSERT_EQUAL(sal_uInt64(0), strm->GetSize()); + strm.reset(); + + url = INetURLObject(u"data:,,%C3%A4%90"); + CPPUNIT_ASSERT(!url.HasError()); + strm = url.getData(); + CPPUNIT_ASSERT(strm != nullptr); + CPPUNIT_ASSERT_EQUAL(sal_uInt64(4), strm->GetSize()); + buf = static_cast<unsigned char const *>(strm->GetData()); + CPPUNIT_ASSERT_EQUAL(0x2C, int(buf[0])); + CPPUNIT_ASSERT_EQUAL(0xC3, int(buf[1])); + CPPUNIT_ASSERT_EQUAL(0xA4, int(buf[2])); + CPPUNIT_ASSERT_EQUAL(0x90, int(buf[3])); + strm.reset(); + + url = INetURLObject(u"data:base64,"); + //TODO: CPPUNIT_ASSERT(url.HasError()); + strm = url.getData(); + CPPUNIT_ASSERT(!strm); + + url = INetURLObject(u"data:;base64,"); + CPPUNIT_ASSERT(!url.HasError()); + strm = url.getData(); + CPPUNIT_ASSERT(strm != nullptr); + CPPUNIT_ASSERT_EQUAL(sal_uInt64(0), strm->GetSize()); + strm.reset(); + + url = INetURLObject(u"data:;bAsE64,"); + CPPUNIT_ASSERT(!url.HasError()); + strm = url.getData(); + CPPUNIT_ASSERT(strm != nullptr); + CPPUNIT_ASSERT_EQUAL(sal_uInt64(0), strm->GetSize()); + strm.reset(); + + url = INetURLObject(u"data:;base64,YWJjCg=="); + CPPUNIT_ASSERT(!url.HasError()); + strm = url.getData(); + CPPUNIT_ASSERT(strm != nullptr); + CPPUNIT_ASSERT_EQUAL(sal_uInt64(4), strm->GetSize()); + buf = static_cast<unsigned char const *>(strm->GetData()); + CPPUNIT_ASSERT_EQUAL(0x61, int(buf[0])); + CPPUNIT_ASSERT_EQUAL(0x62, int(buf[1])); + CPPUNIT_ASSERT_EQUAL(0x63, int(buf[2])); + CPPUNIT_ASSERT_EQUAL(0x0A, int(buf[3])); + strm.reset(); + + url = INetURLObject(u"data:;base64,YWJjCg="); + CPPUNIT_ASSERT(!url.HasError()); + strm = url.getData(); + CPPUNIT_ASSERT(!strm); + + url = INetURLObject(u"data:;base64,YWJ$Cg=="); + CPPUNIT_ASSERT(!url.HasError()); + strm = url.getData(); + CPPUNIT_ASSERT(!strm); + + url = INetURLObject(u"data:text/plain;param=%22;base64,%22,YQ=="); + CPPUNIT_ASSERT(!url.HasError()); + strm = url.getData(); + CPPUNIT_ASSERT(strm != nullptr); + CPPUNIT_ASSERT_EQUAL(sal_uInt64(4), strm->GetSize()); + buf = static_cast<unsigned char const *>(strm->GetData()); + CPPUNIT_ASSERT_EQUAL(0x59, int(buf[0])); + CPPUNIT_ASSERT_EQUAL(0x51, int(buf[1])); + CPPUNIT_ASSERT_EQUAL(0x3D, int(buf[2])); + CPPUNIT_ASSERT_EQUAL(0x3D, int(buf[3])); + strm.reset(); + + url = INetURLObject(u"http://example.com"); + CPPUNIT_ASSERT(!url.HasError()); + strm = url.getData(); + CPPUNIT_ASSERT(!strm); + } + + void urlobjTest_isSchemeEqualTo() { + CPPUNIT_ASSERT(INetURLObject().isSchemeEqualTo(INetProtocol::NotValid)); + CPPUNIT_ASSERT(!INetURLObject().isSchemeEqualTo(u"")); + CPPUNIT_ASSERT( + INetURLObject(u"http://example.org").isSchemeEqualTo( + INetProtocol::Http)); + CPPUNIT_ASSERT( + !INetURLObject(u"http://example.org").isSchemeEqualTo( + INetProtocol::Https)); + CPPUNIT_ASSERT( + INetURLObject(u"http://example.org").isSchemeEqualTo(u"Http")); + CPPUNIT_ASSERT( + !INetURLObject(u"http://example.org").isSchemeEqualTo(u"dav")); + CPPUNIT_ASSERT( + INetURLObject(u"dav://example.org").isSchemeEqualTo(u"dav")); + } + + void urlobjTest_isAnyKnownWebDAVScheme() { + CPPUNIT_ASSERT( + INetURLObject(u"http://example.org").isAnyKnownWebDAVScheme()); + CPPUNIT_ASSERT( + INetURLObject(u"https://example.org").isAnyKnownWebDAVScheme()); + CPPUNIT_ASSERT( + INetURLObject(u"vnd.sun.star.webdav://example.org").isAnyKnownWebDAVScheme()); + CPPUNIT_ASSERT( + INetURLObject(u"vnd.sun.star.webdavs://example.org").isAnyKnownWebDAVScheme()); + CPPUNIT_ASSERT( + !INetURLObject(u"ftp://example.org").isAnyKnownWebDAVScheme()); + CPPUNIT_ASSERT( + !INetURLObject(u"file://example.org").isAnyKnownWebDAVScheme()); + CPPUNIT_ASSERT( + !INetURLObject(u"dav://example.org").isAnyKnownWebDAVScheme()); + CPPUNIT_ASSERT( + !INetURLObject(u"davs://example.org").isAnyKnownWebDAVScheme()); + CPPUNIT_ASSERT( + !INetURLObject(u"vnd.sun.star.pkg://example.org").isAnyKnownWebDAVScheme()); + } + + void testSetName() { + { + INetURLObject obj(u"file:///"); + bool ok = obj.setName(u"foo"); + CPPUNIT_ASSERT(!ok); + } + { + INetURLObject obj(u"file:///foo"); + bool ok = obj.setName(u"bar"); + CPPUNIT_ASSERT(ok); + CPPUNIT_ASSERT_EQUAL( + OUString("file:///bar"), obj.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + } + { + INetURLObject obj(u"file:///foo/"); + bool ok = obj.setName(u"bar"); + CPPUNIT_ASSERT(ok); + CPPUNIT_ASSERT_EQUAL( + OUString("file:///bar/"), obj.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + } + { + INetURLObject obj(u"file:///foo/bar"); + bool ok = obj.setName(u"baz"); + CPPUNIT_ASSERT(ok); + CPPUNIT_ASSERT_EQUAL( + OUString("file:///foo/baz"), + obj.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + } + { + INetURLObject obj(u"file:///foo/bar/"); + bool ok = obj.setName(u"baz"); + CPPUNIT_ASSERT(ok); + CPPUNIT_ASSERT_EQUAL( + OUString("file:///foo/baz/"), + obj.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + } + } + + void testSetExtension() { + INetURLObject obj(u"file:///foo/bar.baz/"); + bool ok = obj.setExtension( + u"other", INetURLObject::LAST_SEGMENT, false); + CPPUNIT_ASSERT(ok); + CPPUNIT_ASSERT_EQUAL( + OUString("file:///foo/bar.baz/.other"), + obj.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + } + + void testChangeScheme() { + INetURLObject obj(u"unknown://example.com/foo/bar"); + CPPUNIT_ASSERT(!obj.HasError()); + obj.changeScheme(INetProtocol::Http); + CPPUNIT_ASSERT_EQUAL( + OUString("http://example.com/foo/bar"), + obj.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + obj.changeScheme(INetProtocol::Https); + CPPUNIT_ASSERT_EQUAL( + OUString("https://example.com/foo/bar"), + obj.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + obj.changeScheme(INetProtocol::Ftp); + CPPUNIT_ASSERT_EQUAL( + OUString("ftp://example.com/foo/bar"), + obj.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + } + + void testTd146382() { + INetURLObject obj(u"file://share.allotropia.de@SSL/DavWWWRoot/remote.php"); + CPPUNIT_ASSERT(!obj.HasError()); + CPPUNIT_ASSERT_EQUAL( + OUString("file://share.allotropia.de@SSL/DavWWWRoot/remote.php"), + obj.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + } + + void testParseSmart() + { + { + // host:port must not be misinterpreted as scheme:path + INetURLObject obj(u"example.com:8080/foo", INetProtocol::Http); + CPPUNIT_ASSERT(!obj.HasError()); + CPPUNIT_ASSERT_EQUAL(OUString("http://example.com:8080/foo"), + obj.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + CPPUNIT_ASSERT_EQUAL(INetProtocol::Http, obj.GetProtocol()); + CPPUNIT_ASSERT_EQUAL(OUString("example.com"), obj.GetHost()); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(8080), obj.GetPort()); + CPPUNIT_ASSERT_EQUAL(OUString("/foo"), obj.GetURLPath()); + } + { + // port may only contain decimal digits, so this must be treated as unknown scheme + INetURLObject obj(u"example.com:80a0/foo", INetProtocol::Http); + CPPUNIT_ASSERT(!obj.HasError()); + CPPUNIT_ASSERT_EQUAL(OUString("example.com:80a0/foo"), + obj.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + CPPUNIT_ASSERT_EQUAL(INetProtocol::Generic, obj.GetProtocol()); + CPPUNIT_ASSERT(obj.isSchemeEqualTo(u"example.com")); + CPPUNIT_ASSERT_EQUAL(OUString(""), obj.GetHost()); + CPPUNIT_ASSERT_EQUAL(OUString("80a0/foo"), obj.GetURLPath()); + } + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE( urlobjTest ); + CPPUNIT_TEST( urlobjTest_001 ); + CPPUNIT_TEST( urlobjTest_004 ); + CPPUNIT_TEST( urlobjCmisTest ); + CPPUNIT_TEST( urlobjTest_emptyPath ); + CPPUNIT_TEST( urlobjTest_data ); + CPPUNIT_TEST( urlobjTest_isSchemeEqualTo ); + CPPUNIT_TEST( urlobjTest_isAnyKnownWebDAVScheme ); + CPPUNIT_TEST( testSetName ); + CPPUNIT_TEST( testSetExtension ); + CPPUNIT_TEST( testChangeScheme ); + CPPUNIT_TEST( testTd146382 ); + CPPUNIT_TEST( testParseSmart ); + CPPUNIT_TEST_SUITE_END( ); + }; // class createPool + + + CPPUNIT_TEST_SUITE_REGISTRATION( urlobjTest ); +} // namespace rtl_random + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_xmlwalker.cxx b/tools/qa/cppunit/test_xmlwalker.cxx new file mode 100644 index 000000000..ec0a695b6 --- /dev/null +++ b/tools/qa/cppunit/test_xmlwalker.cxx @@ -0,0 +1,92 @@ +/* -*- 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 <cppunit/extensions/HelperMacros.h> +#include <test/bootstrapfixture.hxx> +#include <rtl/ustring.hxx> +#include <tools/stream.hxx> +#include <tools/XmlWalker.hxx> + +namespace +{ +class XmlWalkerTest : public test::BootstrapFixture +{ + OUString maBasePath; + +public: + XmlWalkerTest() + : BootstrapFixture(true, false) + { + } + + virtual void setUp() override { maBasePath = m_directories.getURLFromSrc(u"/tools/qa/data/"); } + + void testReadXML(); + + CPPUNIT_TEST_SUITE(XmlWalkerTest); + CPPUNIT_TEST(testReadXML); + CPPUNIT_TEST_SUITE_END(); +}; + +void XmlWalkerTest::testReadXML() +{ + OUString aXmlFilePath = maBasePath + "test.xml"; + + tools::XmlWalker aWalker; + SvFileStream aFileStream(aXmlFilePath, StreamMode::READ); + CPPUNIT_ASSERT(aWalker.open(&aFileStream)); + CPPUNIT_ASSERT_EQUAL(OString("root"), aWalker.name()); + CPPUNIT_ASSERT_EQUAL(OString("Hello World"), aWalker.attribute("root-attr")); + + int nNumberOfChildNodes = 0; + + aWalker.children(); + while (aWalker.isValid()) + { + if (aWalker.name() == "child") + { + nNumberOfChildNodes++; + + CPPUNIT_ASSERT_EQUAL(OString(OString::number(nNumberOfChildNodes)), + aWalker.attribute("number")); + + if (nNumberOfChildNodes == 1) // only the first node has the attribute + CPPUNIT_ASSERT_EQUAL(OString("123"), aWalker.attribute("attribute")); + else + CPPUNIT_ASSERT_EQUAL(OString(), aWalker.attribute("attribute")); + + aWalker.children(); + while (aWalker.isValid()) + { + if (aWalker.name() == "grandchild") + { + CPPUNIT_ASSERT_EQUAL(OString("ABC"), aWalker.attribute("attribute1")); + CPPUNIT_ASSERT_EQUAL(OString("CDE"), aWalker.attribute("attribute2")); + CPPUNIT_ASSERT_EQUAL(OString("Content"), aWalker.content()); + } + aWalker.next(); + } + aWalker.parent(); + } + else if (aWalker.name() == "with-namespace") + { + CPPUNIT_ASSERT_EQUAL(OString("adobe:ns:meta/"), aWalker.namespaceHref()); + CPPUNIT_ASSERT_EQUAL(OString("xx"), aWalker.namespacePrefix()); + } + aWalker.next(); + } + aWalker.parent(); + + CPPUNIT_ASSERT_EQUAL(3, nNumberOfChildNodes); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(XmlWalkerTest); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_xmlwriter.cxx b/tools/qa/cppunit/test_xmlwriter.cxx new file mode 100644 index 000000000..0fddb3d77 --- /dev/null +++ b/tools/qa/cppunit/test_xmlwriter.cxx @@ -0,0 +1,70 @@ +/* -*- 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 <cppunit/extensions/HelperMacros.h> +#include <test/bootstrapfixture.hxx> +#include <tools/stream.hxx> +#include <tools/XmlWriter.hxx> + +namespace +{ +class XmlWriterTest : public test::BootstrapFixture +{ +public: + XmlWriterTest() + : BootstrapFixture(true, false) + { + } + + virtual void setUp() override {} + + void testSimpleRoot(); + void testSpecialChars(); + + CPPUNIT_TEST_SUITE(XmlWriterTest); + CPPUNIT_TEST(testSimpleRoot); + CPPUNIT_TEST(testSpecialChars); + CPPUNIT_TEST_SUITE_END(); +}; + +void XmlWriterTest::testSimpleRoot() +{ + SvMemoryStream aMemoryStream; + + tools::XmlWriter aWriter(&aMemoryStream); + aWriter.startDocument(0, false); + aWriter.startElement("test"); + aWriter.endElement(); + aWriter.endDocument(); + + aMemoryStream.Seek(0); + OString aString(static_cast<const char*>(aMemoryStream.GetData()), aMemoryStream.GetSize()); + CPPUNIT_ASSERT_EQUAL(OString("<test/>"), aString); +} + +void XmlWriterTest::testSpecialChars() +{ + SvMemoryStream aMemoryStream; + + tools::XmlWriter aWriter(&aMemoryStream); + aWriter.startDocument(0, false); + aWriter.startElement("test"); + aWriter.content("<>"); + aWriter.endElement(); + aWriter.endDocument(); + + aMemoryStream.Seek(0); + OString aString(static_cast<const char*>(aMemoryStream.GetData()), aMemoryStream.GetSize()); + CPPUNIT_ASSERT_EQUAL(OString("<test><></test>"), aString); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(XmlWriterTest); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/data/test.xml b/tools/qa/data/test.xml new file mode 100644 index 000000000..c2736e8bb --- /dev/null +++ b/tools/qa/data/test.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<root root-attr="Hello World"> + <child number="1" attribute="123"> + <grandchild attribute1="ABC" attribute2="CDE">Content</grandchild> + </child> + <child number="2"> + </child> + <child number="3"> + </child> + <xx:with-namespace xmlns:xx="adobe:ns:meta/"> + </xx:with-namespace> +</root> diff --git a/tools/qa/data/testconfig.ini b/tools/qa/data/testconfig.ini new file mode 100644 index 000000000..630753216 --- /dev/null +++ b/tools/qa/data/testconfig.ini @@ -0,0 +1,5 @@ +[TestGroup]
+testkey=testvalue
+
+[TestGroup2]
+testkey2=testvalue
|