summaryrefslogtreecommitdiffstats
path: root/tools/qa
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /tools/qa
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.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')
-rw-r--r--tools/qa/cppunit/test_100mm2twips.cxx53
-rw-r--r--tools/qa/cppunit/test_GenericTypeSerializer.cxx144
-rw-r--r--tools/qa/cppunit/test_Wildcard.cxx46
-rw-r--r--tools/qa/cppunit/test_bigint.cxx97
-rw-r--r--tools/qa/cppunit/test_color.cxx252
-rw-r--r--tools/qa/cppunit/test_config.cxx200
-rw-r--r--tools/qa/cppunit/test_cpu_runtime_detection_AVX2.cxx40
-rw-r--r--tools/qa/cppunit/test_cpu_runtime_detection_AVX2_check.cxx56
-rw-r--r--tools/qa/cppunit/test_cpu_runtime_detection_SSE2.cxx40
-rw-r--r--tools/qa/cppunit/test_cpu_runtime_detection_SSE2_check.cxx37
-rw-r--r--tools/qa/cppunit/test_cpu_runtime_detection_SSSE3.cxx40
-rw-r--r--tools/qa/cppunit/test_cpu_runtime_detection_SSSE3_check.cxx37
-rw-r--r--tools/qa/cppunit/test_cpu_runtime_detection_x86_checks.hxx23
-rw-r--r--tools/qa/cppunit/test_cpuid.cxx57
-rw-r--r--tools/qa/cppunit/test_date.cxx564
-rw-r--r--tools/qa/cppunit/test_fract.cxx107
-rw-r--r--tools/qa/cppunit/test_fround.cxx62
-rw-r--r--tools/qa/cppunit/test_guid.cxx123
-rw-r--r--tools/qa/cppunit/test_inetmime.cxx167
-rw-r--r--tools/qa/cppunit/test_json_writer.cxx104
-rw-r--r--tools/qa/cppunit/test_minmax.cxx98
-rw-r--r--tools/qa/cppunit/test_pathutils.cxx66
-rw-r--r--tools/qa/cppunit/test_poly.cxx54
-rw-r--r--tools/qa/cppunit/test_rectangle.cxx115
-rw-r--r--tools/qa/cppunit/test_reversemap.cxx154
-rw-r--r--tools/qa/cppunit/test_stream.cxx321
-rw-r--r--tools/qa/cppunit/test_time.cxx154
-rw-r--r--tools/qa/cppunit/test_urlobj.cxx373
-rw-r--r--tools/qa/cppunit/test_xmlwalker.cxx92
-rw-r--r--tools/qa/cppunit/test_xmlwriter.cxx70
-rw-r--r--tools/qa/data/test.xml13
-rw-r--r--tools/qa/data/testconfig.ini5
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, &parameters);
+ 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, &parameters);
+ 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, &parameters);
+ 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>&lt;&gt;</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