2042 lines
86 KiB
C++
2042 lines
86 KiB
C++
/* -*- 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 <sal/config.h>
|
||
|
||
#include <cppuhelper/bootstrap.hxx>
|
||
#include <comphelper/processfactory.hxx>
|
||
|
||
#include <com/sun/star/lang/XComponent.hpp>
|
||
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
|
||
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
|
||
#include <com/sun/star/uno/XComponentContext.hpp>
|
||
|
||
#include <i18nlangtag/lang.h>
|
||
|
||
#include <math.h>
|
||
|
||
#include <o3tl/nonstaticstring.hxx>
|
||
#include <svl/numformat.hxx>
|
||
#include <svl/zforlist.hxx>
|
||
#include <svl/zformat.hxx>
|
||
#include <svl/sharedstringpool.hxx>
|
||
#include <svl/sharedstring.hxx>
|
||
#include <tools/color.hxx>
|
||
#include <unotools/syslocale.hxx>
|
||
|
||
#include <memory>
|
||
#include <optional>
|
||
#include <unicode/timezone.h>
|
||
|
||
using namespace ::com::sun::star;
|
||
using namespace svl;
|
||
|
||
namespace svl
|
||
{
|
||
static std::ostream& operator<<(std::ostream& rStrm, const SharedString& string )
|
||
{
|
||
return rStrm << "(" << static_cast<const void*>(string.getData()) << ")" << string.getString();
|
||
}
|
||
}
|
||
|
||
|
||
namespace {
|
||
|
||
class Test : public CppUnit::TestFixture {
|
||
public:
|
||
Test();
|
||
virtual ~Test() override;
|
||
|
||
virtual void tearDown() override;
|
||
|
||
void testNumberFormat();
|
||
void testSharedString();
|
||
void testSharedStringPool();
|
||
void testSharedStringPoolPurge();
|
||
void testSharedStringPoolPurgeBug1();
|
||
void testSharedStringPoolEmptyString();
|
||
void testFdo60915();
|
||
void testI116701();
|
||
void testTdf103060();
|
||
void testDateInput();
|
||
void testIsNumberFormat();
|
||
void testIsNumberFormatSpecific();
|
||
void testUserDefinedNumberFormats();
|
||
void testNfEnglishKeywordsIntegrity();
|
||
void testStandardColorIntegrity();
|
||
void testColorNamesConversion();
|
||
void testExcelExportFormats();
|
||
|
||
CPPUNIT_TEST_SUITE(Test);
|
||
CPPUNIT_TEST(testNumberFormat);
|
||
CPPUNIT_TEST(testSharedString);
|
||
CPPUNIT_TEST(testSharedStringPool);
|
||
CPPUNIT_TEST(testSharedStringPoolPurge);
|
||
CPPUNIT_TEST(testSharedStringPoolPurgeBug1);
|
||
CPPUNIT_TEST(testSharedStringPoolEmptyString);
|
||
CPPUNIT_TEST(testFdo60915);
|
||
CPPUNIT_TEST(testI116701);
|
||
CPPUNIT_TEST(testTdf103060);
|
||
CPPUNIT_TEST(testDateInput);
|
||
CPPUNIT_TEST(testIsNumberFormat);
|
||
CPPUNIT_TEST(testIsNumberFormatSpecific);
|
||
CPPUNIT_TEST(testUserDefinedNumberFormats);
|
||
CPPUNIT_TEST(testNfEnglishKeywordsIntegrity);
|
||
CPPUNIT_TEST(testStandardColorIntegrity);
|
||
CPPUNIT_TEST(testColorNamesConversion);
|
||
CPPUNIT_TEST(testExcelExportFormats);
|
||
CPPUNIT_TEST_SUITE_END();
|
||
|
||
protected:
|
||
uno::Reference< uno::XComponentContext > m_xContext;
|
||
void checkPreviewString(SvNumberFormatter& aFormatter,
|
||
const OUString& sCode,
|
||
double fPreviewNumber,
|
||
LanguageType eLang,
|
||
OUString const & sExpected);
|
||
void checkDateInput( SvNumberFormatter& rFormatter, const char* pTimezone, const char* pIsoDate );
|
||
std::unique_ptr<icu::TimeZone> m_pDefaultTimeZone;
|
||
};
|
||
|
||
Test::Test() : m_xContext(cppu::defaultBootstrap_InitialComponentContext())
|
||
{
|
||
uno::Reference<lang::XMultiComponentFactory> xFactory(m_xContext->getServiceManager());
|
||
uno::Reference<lang::XMultiServiceFactory> xSM(xFactory, uno::UNO_QUERY_THROW);
|
||
|
||
//Without this we're crashing because callees are using
|
||
//getProcessServiceFactory. In general those should be removed in favour
|
||
//of retaining references to the root ServiceFactory as it's passed around
|
||
comphelper::setProcessServiceFactory(xSM);
|
||
m_pDefaultTimeZone.reset(icu::TimeZone::createDefault());
|
||
}
|
||
|
||
void Test::tearDown()
|
||
{
|
||
icu::TimeZone::setDefault(*m_pDefaultTimeZone);
|
||
}
|
||
|
||
Test::~Test()
|
||
{
|
||
uno::Reference< lang::XComponent >(m_xContext, uno::UNO_QUERY_THROW)->dispose();
|
||
}
|
||
|
||
void Test::testNumberFormat()
|
||
{
|
||
LanguageType eLang = LANGUAGE_ENGLISH_US;
|
||
|
||
const char* pNumber[] = {
|
||
"General",
|
||
"0",
|
||
"0.00",
|
||
"#,##0",
|
||
"#,##0.00",
|
||
"#,###.00",
|
||
nullptr
|
||
};
|
||
|
||
const char* pScientific[] = {
|
||
"0.00E+000",
|
||
"0.00E+00",
|
||
nullptr
|
||
};
|
||
|
||
const char* pPercent[] = {
|
||
"0%",
|
||
"0.00%",
|
||
nullptr
|
||
};
|
||
|
||
const char* pFraction[] = {
|
||
"# \?/\?",
|
||
"# \?\?/\?\?",
|
||
nullptr
|
||
};
|
||
|
||
// Following aren't in range of NF_FRACTION_START and NF_FRACTION_END
|
||
// see enum NfIndexTableOffset in svl/inc/svl/zforlist.hxx
|
||
const char* pFractionExt[] = {
|
||
"# \?\?\?/\?\?\?",
|
||
"# \?/2",
|
||
"# \?/4",
|
||
"# \?/8",
|
||
"# \?\?/16",
|
||
"# \?\?/10",
|
||
"# \?\?/100",
|
||
nullptr
|
||
};
|
||
|
||
const char* pCurrency[] = {
|
||
"$#,##0;-$#,##0",
|
||
"$#,##0.00;-$#,##0.00",
|
||
"$#,##0;[RED]-$#,##0",
|
||
"$#,##0.00;[RED]-$#,##0.00",
|
||
"#,##0.00 CCC",
|
||
"$#,##0.--;[RED]-$#,##0.--",
|
||
nullptr
|
||
};
|
||
|
||
const char* pDate[] = {
|
||
"M/D/YY",
|
||
"NNNNMMMM D, YYYY",
|
||
"MM/DD/YY",
|
||
"MM/DD/YYYY",
|
||
"MMM D, YY",
|
||
"MMM D, YYYY",
|
||
"D. MMM. YYYY",
|
||
"MMMM D, YYYY",
|
||
"D. MMMM YYYY",
|
||
"NN, MMM D, YY",
|
||
"NN DD/MMM YY",
|
||
"NN, MMMM D, YYYY",
|
||
"NNNNMMMM D, YYYY",
|
||
"MM-DD",
|
||
"YY-MM-DD",
|
||
"YYYY-MM-DD",
|
||
"MM/YY",
|
||
"MMM DD",
|
||
"MMMM",
|
||
"QQ YY",
|
||
"WW",
|
||
nullptr
|
||
};
|
||
|
||
const char* pTime[] = {
|
||
"HH:MM",
|
||
"HH:MM:SS",
|
||
"HH:MM AM/PM",
|
||
"HH:MM:SS AM/PM",
|
||
"[HH]:MM:SS",
|
||
"MM:SS.00",
|
||
"[HH]:MM:SS.00",
|
||
nullptr
|
||
};
|
||
|
||
const char* pDateTime[] = {
|
||
"MM/DD/YY HH:MM AM/PM",
|
||
"MM/DD/YYYY HH:MM:SS",
|
||
nullptr
|
||
};
|
||
|
||
// Following aren't in range of NF_DATETIME_START and NF_DATETIME_END
|
||
// see enum NfIndexTableOffset in svl/inc/svl/zforlist.hxx
|
||
const char* pDateTimeExt1[] = {
|
||
"MM/DD/YYYY HH:MM AM/PM",
|
||
nullptr
|
||
};
|
||
|
||
const char* pDateTimeExt2[] = {
|
||
"YYYY-MM-DD HH:MM:SS",
|
||
"YYYY-MM-DD HH:MM:SS.000",
|
||
"YYYY-MM-DD\"T\"HH:MM:SS",
|
||
"YYYY-MM-DD\"T\"HH:MM:SS.000",
|
||
nullptr
|
||
};
|
||
|
||
const char* pBoolean[] = {
|
||
"BOOLEAN",
|
||
nullptr
|
||
};
|
||
|
||
const char* pText[] = {
|
||
"@",
|
||
nullptr
|
||
};
|
||
|
||
struct {
|
||
NfIndexTableOffset eStart;
|
||
NfIndexTableOffset eEnd;
|
||
size_t nSize;
|
||
const char** pCodes;
|
||
} aTests[] = {
|
||
{ NF_NUMBER_START, NF_NUMBER_END, 6, pNumber },
|
||
{ NF_SCIENTIFIC_START, NF_SCIENTIFIC_END, 2, pScientific },
|
||
{ NF_PERCENT_START, NF_PERCENT_END, 2, pPercent },
|
||
{ NF_FRACTION_START, NF_FRACTION_END, 2, pFraction },
|
||
{ NF_CURRENCY_START, NF_CURRENCY_END, 6, pCurrency },
|
||
{ NF_DATE_START, NF_DATE_END, 21, pDate },
|
||
{ NF_TIME_START, NF_TIME_END, 7, pTime },
|
||
{ NF_DATETIME_START, NF_DATETIME_END, 2, pDateTime },
|
||
{ NF_BOOLEAN, NF_BOOLEAN, 1, pBoolean },
|
||
{ NF_TEXT, NF_TEXT, 1, pText },
|
||
{ NF_DATETIME_SYS_DDMMYYYY_HHMM, NF_DATETIME_SYS_DDMMYYYY_HHMM, 1, pDateTimeExt1 },
|
||
{ NF_FRACTION_3D, NF_FRACTION_100, 7, pFractionExt },
|
||
{ NF_DATETIME_ISO_YYYYMMDD_HHMMSS, NF_DATETIME_ISO_YYYYMMDDTHHMMSS000, 4, pDateTimeExt2 }
|
||
};
|
||
|
||
SvNumberFormatter aFormatter(m_xContext, eLang);
|
||
|
||
for (auto const[eStart, eEnd, nSize, pCodes] : aTests)
|
||
{
|
||
size_t nStart = eStart;
|
||
size_t nEnd = eEnd;
|
||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Unexpected number of formats for this category.", nSize,
|
||
(nEnd - nStart + 1));
|
||
|
||
for (size_t j = nStart; j <= nEnd; ++j)
|
||
{
|
||
sal_uInt32 nIndex =
|
||
aFormatter.GetFormatIndex(static_cast<NfIndexTableOffset>(j));
|
||
const SvNumberformat* p = aFormatter.GetEntry(nIndex);
|
||
|
||
CPPUNIT_ASSERT_MESSAGE("Number format entry is expected, but doesn't exist.", p);
|
||
OUString aCode = p->GetFormatstring();
|
||
CPPUNIT_ASSERT_EQUAL(OString( pCodes[j-nStart]), aCode.toUtf8());
|
||
}
|
||
}
|
||
|
||
sal_Int32 nPos;
|
||
SvNumFormatType nType = SvNumFormatType::DEFINED;
|
||
sal_uInt32 nKey;
|
||
OUString aCode;
|
||
// Thai date format (implicit locale).
|
||
aCode = "[$-1070000]d/mm/yyyy;@";
|
||
if (!aFormatter.PutEntry(aCode, nPos, nType, nKey))
|
||
{
|
||
CPPUNIT_ASSERT_MESSAGE("failed to insert format code '[$-1070000]d/mm/yyyy;@'", false);
|
||
}
|
||
|
||
// Thai date format (explicit locale)
|
||
aCode = "[$-107041E]d/mm/yyyy;@";
|
||
if (!aFormatter.PutEntry(aCode, nPos, nType, nKey))
|
||
{
|
||
CPPUNIT_ASSERT_MESSAGE("failed to insert format code '[$-107041E]d/mm/yyyy;@'", false);
|
||
}
|
||
|
||
// Thai date format (using buddhist calendar type).
|
||
aCode = "[~buddhist]D MMMM YYYY";
|
||
if (!aFormatter.PutEntry(aCode, nPos, nType, nKey))
|
||
{
|
||
CPPUNIT_ASSERT_MESSAGE("failed to insert format code '[~buddhist]D MMMM YYYY'", false);
|
||
}
|
||
}
|
||
|
||
void Test::testSharedString()
|
||
{
|
||
// Use shared string as normal, non-shared string, which is allowed.
|
||
SharedString aSS1(u"Test"_ustr), aSS2(u"Test"_ustr);
|
||
CPPUNIT_ASSERT_MESSAGE("Equality check should return true.", bool(aSS1 == aSS2));
|
||
SharedString aSS3(u"test"_ustr);
|
||
CPPUNIT_ASSERT_MESSAGE("Equality check is case sensitive.", aSS1 != aSS3);
|
||
}
|
||
|
||
void Test::testSharedStringPool()
|
||
{
|
||
SvtSysLocale aSysLocale;
|
||
svl::SharedStringPool aPool(aSysLocale.GetCharClass());
|
||
|
||
svl::SharedString p1, p2;
|
||
p1 = aPool.intern(u"Andy"_ustr);
|
||
p2 = aPool.intern(u"Andy"_ustr);
|
||
CPPUNIT_ASSERT_EQUAL(p1.getData(), p2.getData());
|
||
|
||
p2 = aPool.intern(u"Bruce"_ustr);
|
||
CPPUNIT_ASSERT_MESSAGE("They must differ.", p1.getData() != p2.getData());
|
||
|
||
OUString aAndy(u"Andy"_ustr);
|
||
p1 = aPool.intern(u"Andy"_ustr);
|
||
p2 = aPool.intern(aAndy);
|
||
CPPUNIT_ASSERT_MESSAGE("Identifier shouldn't be NULL.", p1.getData());
|
||
CPPUNIT_ASSERT_MESSAGE("Identifier shouldn't be NULL.", p2.getData());
|
||
CPPUNIT_ASSERT_EQUAL(p1.getData(), p2.getData());
|
||
|
||
// Test case insensitive string ID's.
|
||
p1 = aPool.intern(aAndy);
|
||
p2 = aPool.intern(u"andy"_ustr);
|
||
CPPUNIT_ASSERT_MESSAGE("Failed to intern strings.", p1.getData());
|
||
CPPUNIT_ASSERT_MESSAGE("Failed to intern strings.", p2.getData());
|
||
CPPUNIT_ASSERT_MESSAGE("These two ID's should differ.", p1.getData() != p2.getData());
|
||
CPPUNIT_ASSERT_EQUAL_MESSAGE("These two ID's should be equal.", p2.getDataIgnoreCase(), p1.getDataIgnoreCase());
|
||
p2 = aPool.intern(u"ANDY"_ustr);
|
||
CPPUNIT_ASSERT_MESSAGE("Failed to intern string.", p2.getData());
|
||
CPPUNIT_ASSERT_MESSAGE("These two ID's should differ.", p1.getData() != p2.getData());
|
||
CPPUNIT_ASSERT_EQUAL_MESSAGE("These two ID's should be equal.", p2.getDataIgnoreCase(), p1.getDataIgnoreCase());
|
||
}
|
||
|
||
void Test::testSharedStringPoolPurge()
|
||
{
|
||
SvtSysLocale aSysLocale;
|
||
svl::SharedStringPool aPool(aSysLocale.GetCharClass());
|
||
size_t extraCount = aPool.getCount(); // internal items such as SharedString::getEmptyString()
|
||
size_t extraCountIgnoreCase = aPool.getCountIgnoreCase();
|
||
|
||
aPool.intern(o3tl::nonStaticString(u"Andy"));
|
||
aPool.intern(o3tl::nonStaticString(u"andy"));
|
||
aPool.intern(o3tl::nonStaticString(u"ANDY"));
|
||
|
||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong string count.", 3+extraCount, aPool.getCount());
|
||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong case insensitive string count.", 1+extraCountIgnoreCase, aPool.getCountIgnoreCase());
|
||
|
||
// Since no string objects referencing the pooled strings exist, purging
|
||
// the pool should empty it (except for internal items).
|
||
aPool.purge();
|
||
CPPUNIT_ASSERT_EQUAL(extraCount, aPool.getCount());
|
||
CPPUNIT_ASSERT_EQUAL(extraCountIgnoreCase, aPool.getCountIgnoreCase());
|
||
|
||
// Now, create string objects using optional so we can clear them
|
||
std::optional<svl::SharedString> pStr1 = aPool.intern(o3tl::nonStaticString(u"Andy"));
|
||
std::optional<svl::SharedString> pStr2 = aPool.intern(o3tl::nonStaticString(u"andy"));
|
||
std::optional<svl::SharedString> pStr3 = aPool.intern(o3tl::nonStaticString(u"ANDY"));
|
||
std::optional<svl::SharedString> pStr4 = aPool.intern(o3tl::nonStaticString(u"Bruce"));
|
||
|
||
CPPUNIT_ASSERT_EQUAL(5+extraCount, aPool.getCount());
|
||
CPPUNIT_ASSERT_EQUAL(2+extraCountIgnoreCase, aPool.getCountIgnoreCase());
|
||
|
||
// This shouldn't purge anything.
|
||
aPool.purge();
|
||
CPPUNIT_ASSERT_EQUAL(5+extraCount, aPool.getCount());
|
||
CPPUNIT_ASSERT_EQUAL(2+extraCountIgnoreCase, aPool.getCountIgnoreCase());
|
||
|
||
// Delete one heap string object, and purge. That should purge one string.
|
||
pStr1.reset();
|
||
aPool.purge();
|
||
CPPUNIT_ASSERT_EQUAL(4+extraCount, aPool.getCount());
|
||
CPPUNIT_ASSERT_EQUAL(2+extraCountIgnoreCase, aPool.getCountIgnoreCase());
|
||
|
||
// Nothing changes, because the upper-string is still in the map
|
||
pStr3.reset();
|
||
aPool.purge();
|
||
CPPUNIT_ASSERT_EQUAL(4+extraCount, aPool.getCount());
|
||
CPPUNIT_ASSERT_EQUAL(2+extraCountIgnoreCase, aPool.getCountIgnoreCase());
|
||
|
||
// Again.
|
||
pStr2.reset();
|
||
aPool.purge();
|
||
CPPUNIT_ASSERT_EQUAL(2+extraCount, aPool.getCount());
|
||
CPPUNIT_ASSERT_EQUAL(1+extraCountIgnoreCase, aPool.getCountIgnoreCase());
|
||
|
||
// Delete 'Bruce' and purge.
|
||
pStr4.reset();
|
||
aPool.purge();
|
||
CPPUNIT_ASSERT_EQUAL(extraCount, aPool.getCount());
|
||
CPPUNIT_ASSERT_EQUAL(extraCountIgnoreCase, aPool.getCountIgnoreCase());
|
||
}
|
||
|
||
void Test::testSharedStringPoolPurgeBug1()
|
||
{
|
||
// We had a bug where, if we had two strings that mapped to the same uppercase string,
|
||
// purge() would de-reference a dangling pointer and consequently cause an ASAN failure.
|
||
SvtSysLocale aSysLocale;
|
||
svl::SharedStringPool aPool(aSysLocale.GetCharClass());
|
||
size_t extraCount = aPool.getCount(); // internal items such as SharedString::getEmptyString()
|
||
size_t extraCountIgnoreCase = aPool.getCountIgnoreCase();
|
||
aPool.intern(o3tl::nonStaticString(u"Andy"));
|
||
aPool.intern(o3tl::nonStaticString(u"andy"));
|
||
aPool.purge();
|
||
CPPUNIT_ASSERT_EQUAL(extraCount, aPool.getCount());
|
||
CPPUNIT_ASSERT_EQUAL(extraCountIgnoreCase, aPool.getCountIgnoreCase());
|
||
}
|
||
|
||
void Test::testSharedStringPoolEmptyString()
|
||
{
|
||
// Make sure SharedString::getEmptyString() is in the pool and matches empty strings.
|
||
SvtSysLocale aSysLocale;
|
||
svl::SharedStringPool aPool(aSysLocale.GetCharClass());
|
||
aPool.intern(u""_ustr);
|
||
CPPUNIT_ASSERT_EQUAL(SharedString::getEmptyString(), aPool.intern(u""_ustr));
|
||
CPPUNIT_ASSERT_EQUAL(SharedString::getEmptyString(), aPool.intern(SharedString::EMPTY_STRING));
|
||
// And it should still work even after purging.
|
||
aPool.purge();
|
||
CPPUNIT_ASSERT_EQUAL(SharedString::getEmptyString(), aPool.intern(SharedString::EMPTY_STRING));
|
||
}
|
||
|
||
void Test::checkPreviewString(SvNumberFormatter& aFormatter,
|
||
const OUString& sCode,
|
||
double fPreviewNumber,
|
||
LanguageType eLang,
|
||
OUString const & sExpected)
|
||
{
|
||
OUString sStr;
|
||
const Color* pColor = nullptr;
|
||
if (!aFormatter.GetPreviewString(sCode, fPreviewNumber, sStr, &pColor, eLang))
|
||
{
|
||
OString aMessage = "GetPreviewString( \"" +
|
||
OUStringToOString( sCode, RTL_TEXTENCODING_ASCII_US ) +
|
||
"\", " +
|
||
OString::number( fPreviewNumber ) +
|
||
", sStr, ppColor, ";
|
||
aMessage += OString::number( static_cast<sal_uInt16>(eLang) ) +
|
||
" ) failed";
|
||
CPPUNIT_FAIL( aMessage.getStr() );
|
||
}
|
||
CPPUNIT_ASSERT_EQUAL(sExpected, sStr);
|
||
}
|
||
|
||
void Test::testFdo60915()
|
||
{
|
||
LanguageType eLang = LANGUAGE_THAI;
|
||
OUString sCode, sExpected;
|
||
double fPreviewNumber = 36486; // equals 1999-11-22 (2542 B.E.)
|
||
SvNumberFormatter aFormatter(m_xContext, eLang);
|
||
{
|
||
sCode = "[~buddhist]D/MM/YYYY";
|
||
sExpected = "22/11/2542";
|
||
checkPreviewString(aFormatter, sCode, fPreviewNumber, eLang, sExpected);
|
||
}
|
||
{
|
||
sCode = "[~buddhist]D/MM/YY";
|
||
sExpected = "22/11/42";
|
||
checkPreviewString(aFormatter, sCode, fPreviewNumber, eLang, sExpected);
|
||
}
|
||
{
|
||
sCode = "[NatNum1][$-41E][~buddhist]D/MM/YYYY";
|
||
sal_Unicode sTemp[] =
|
||
{
|
||
0x0E52, 0x0E52, 0x002F,
|
||
0x0E51, 0x0E51, 0x002F,
|
||
0x0E52, 0x0E55, 0x0E54, 0x0E52
|
||
};
|
||
sExpected = OUString(sTemp, SAL_N_ELEMENTS(sTemp));
|
||
checkPreviewString(aFormatter, sCode, fPreviewNumber, eLang, sExpected);
|
||
}
|
||
{
|
||
sCode = "[NatNum1][$-41E][~buddhist]D/MM/YY";
|
||
sal_Unicode sTemp[] =
|
||
{
|
||
0x0E52, 0x0E52, 0x002F,
|
||
0x0E51, 0x0E51, 0x002F,
|
||
0x0E54, 0x0E52
|
||
};
|
||
sExpected = OUString(sTemp, SAL_N_ELEMENTS(sTemp));
|
||
checkPreviewString(aFormatter, sCode, fPreviewNumber, eLang, sExpected);
|
||
}
|
||
}
|
||
|
||
// https://bz.apache.org/ooo/show_bug.cgi?id=116701
|
||
void Test::testI116701()
|
||
{
|
||
LanguageType eLang = LANGUAGE_CHINESE_TRADITIONAL;
|
||
OUString sCode, sExpected;
|
||
double fPreviewNumber = 40573; // equals 30/01/2011
|
||
SvNumberFormatter aFormatter(m_xContext, eLang);
|
||
// DateFormatskey25 in i18npool/source/localedata/data/zh_TW.xml
|
||
sal_Unicode CODE1[] =
|
||
{
|
||
0x0047, 0x0047, 0x0047, 0x0045, 0x0045, // GGGEE
|
||
0x0022, 0x5E74, 0x0022,
|
||
0x004D, // M
|
||
0x0022, 0x6708, 0x0022,
|
||
0x0044, // D
|
||
0x0022, 0x65E5, 0x0022
|
||
};
|
||
sCode = OUString(CODE1, SAL_N_ELEMENTS(CODE1));
|
||
sal_Unicode EXPECTED[] =
|
||
{
|
||
0x4E2D, 0x83EF, 0x6C11, 0x570B,
|
||
0x0031, 0x0030, 0x0030, // 100
|
||
0x5E74,
|
||
0x0031, // 1
|
||
0x6708,
|
||
0x0033, 0x0030, // 30
|
||
0x65E5
|
||
};
|
||
sExpected = OUString(EXPECTED, SAL_N_ELEMENTS(EXPECTED));
|
||
checkPreviewString(aFormatter, sCode, fPreviewNumber, eLang, sExpected);
|
||
sal_Unicode CODE2[] =
|
||
{
|
||
0x0047, 0x0047, 0x0047, 0x0045, // GGGE
|
||
0x0022, 0x5E74, 0x0022,
|
||
0x004D, // M
|
||
0x0022, 0x6708, 0x0022,
|
||
0x0044, // D
|
||
0x0022, 0x65E5, 0x0022
|
||
};
|
||
sCode = OUString(CODE2, SAL_N_ELEMENTS(CODE2));
|
||
checkPreviewString(aFormatter, sCode, fPreviewNumber, eLang, sExpected);
|
||
}
|
||
|
||
void Test::testTdf103060()
|
||
{
|
||
LanguageType eLang = LANGUAGE_JAPANESE;
|
||
OUString sCode, sExpected;
|
||
double fPreviewNumber = 42655; // equals 2016-10-12
|
||
SvNumberFormatter aFormatter(m_xContext, eLang);
|
||
sCode = "G";
|
||
sExpected = "H"; // Heisei era
|
||
checkPreviewString(aFormatter, sCode, fPreviewNumber, eLang, sExpected);
|
||
sCode = "GG";
|
||
sExpected = u"\u5E73"_ustr;
|
||
checkPreviewString(aFormatter, sCode, fPreviewNumber, eLang, sExpected);
|
||
sCode = "GGG";
|
||
sExpected = u"\u5E73\u6210"_ustr;
|
||
checkPreviewString(aFormatter, sCode, fPreviewNumber, eLang, sExpected);
|
||
}
|
||
|
||
void Test::testDateInput()
|
||
{
|
||
const char* aData[][2] = {
|
||
{ "Europe/Paris", "1938-10-07" }, // i#76623
|
||
{ "Europe/Moscow", "1919-07-01" }, // i#86094
|
||
{ "America/St_Johns", "1935-03-30" }, // i#86094 i#90627
|
||
{ "Europe/Tallinn", "1790-03-01" }, // i#105864
|
||
{ "Australia/Perth", "2004-04-11" }, // i#17222
|
||
{ "America/Sao_Paulo", "1902-04-22" }, // tdf#44286
|
||
{ "Europe/Berlin", "1790-07-27" },
|
||
{ "US/Mountain", "1790-07-26" },
|
||
{ "Asia/Tehran", "1999-03-22" },
|
||
|
||
// Data from https://bugs.documentfoundation.org/show_bug.cgi?id=63230
|
||
// https://bugs.documentfoundation.org/attachment.cgi?id=79051
|
||
// https://bugs.documentfoundation.org/show_bug.cgi?id=79663
|
||
{ "Africa/Accra", "1800-01-01" },
|
||
{ "Africa/Accra", "1800-04-10" },
|
||
{ "Africa/Addis_Ababa", "1870-01-01" },
|
||
{ "Africa/Addis_Ababa", "1936-05-05" },
|
||
{ "Africa/Algiers", "1956-01-29" },
|
||
{ "Africa/Algiers", "1981-05-01" },
|
||
{ "Africa/Asmara", "1936-05-05" },
|
||
{ "Africa/Asmera", "1936-05-05" },
|
||
{ "Africa/Bujumbura", "1890-01-01" },
|
||
{ "Africa/Casablanca", "1984-03-16" },
|
||
{ "Africa/Ceuta", "1984-03-16" },
|
||
{ "Africa/Dar_es_Salaam", "1931-01-01" },
|
||
{ "Africa/Dar_es_Salaam", "1961-01-01" },
|
||
{ "Africa/Djibouti", "1911-07-01" },
|
||
{ "Africa/Douala", "1912-01-01" },
|
||
{ "Africa/El_Aaiun", "1934-01-01" },
|
||
{ "Africa/Freetown", "1913-06-01" },
|
||
{ "Africa/Gaborone", "1885-01-01" },
|
||
{ "Africa/Johannesburg", "1903-03-01" },
|
||
{ "Africa/Kampala", "1928-07-01" },
|
||
{ "Africa/Kampala", "1948-01-01" },
|
||
{ "Africa/Kampala", "1957-01-01" },
|
||
{ "Africa/Lagos", "1919-09-01" },
|
||
{ "Africa/Libreville", "1912-01-01" },
|
||
{ "Africa/Luanda", "1911-05-26" },
|
||
{ "Africa/Lubumbashi", "1897-11-09" },
|
||
{ "Africa/Lusaka", "1903-03-01" },
|
||
{ "Africa/Malabo", "1963-12-15" },
|
||
{ "Africa/Maseru", "1903-03-01" },
|
||
{ "Africa/Mogadishu", "1957-01-01" },
|
||
{ "Africa/Monrovia", "1919-03-01" },
|
||
{ "Africa/Nairobi", "1928-07-01" },
|
||
{ "Africa/Nairobi", "1940-01-01" },
|
||
{ "Africa/Nairobi", "1960-01-01" },
|
||
{ "Africa/Niamey", "1960-01-01" },
|
||
{ "Africa/Porto-Novo", "1934-02-26" },
|
||
{ "Africa/Tripoli", "1920-01-01" },
|
||
{ "Africa/Tripoli", "1959-01-01" },
|
||
{ "Africa/Tripoli", "1990-05-04" },
|
||
{ "Africa/Tunis", "1911-03-11" },
|
||
{ "Africa/Windhoek", "1892-02-08" },
|
||
{ "Africa/Windhoek", "1903-03-01" },
|
||
{ "America/Antigua", "1912-03-02" },
|
||
{ "America/Argentina/Buenos_Aires", "1894-10-31" },
|
||
{ "America/Argentina/Catamarca", "1991-10-20" },
|
||
{ "America/Argentina/Catamarca", "2004-06-01" },
|
||
{ "America/Argentina/ComodRivadavia", "1991-10-20" },
|
||
{ "America/Argentina/ComodRivadavia", "2004-06-01" },
|
||
{ "America/Argentina/Cordoba", "1991-10-20" },
|
||
{ "America/Argentina/Jujuy", "1991-10-06" },
|
||
{ "America/Argentina/La_Rioja", "2004-06-01" },
|
||
{ "America/Argentina/Mendoza", "1992-10-18" },
|
||
{ "America/Argentina/Mendoza", "2004-05-23" },
|
||
{ "America/Argentina/Rio_Gallegos", "2004-06-01" },
|
||
{ "America/Argentina/Salta", "1991-10-20" },
|
||
{ "America/Argentina/San_Juan", "2004-05-31" },
|
||
{ "America/Argentina/San_Luis", "2004-05-31" },
|
||
{ "America/Argentina/San_Luis", "2008-01-21" },
|
||
{ "America/Argentina/Tucuman", "1991-10-20" },
|
||
{ "America/Argentina/Tucuman", "2004-06-01" },
|
||
{ "America/Argentina/Ushuaia", "2004-05-30" },
|
||
{ "America/Asuncion", "1931-10-10" },
|
||
{ "America/Asuncion", "1974-04-01" },
|
||
{ "America/Bahia", "1914-01-01" },
|
||
{ "America/Bahia_Banderas", "1930-11-15" },
|
||
{ "America/Bahia_Banderas", "1931-10-01" },
|
||
{ "America/Bahia_Banderas", "1942-04-24" },
|
||
{ "America/Bahia_Banderas", "1949-01-14" },
|
||
{ "America/Barbados", "1932-01-01" },
|
||
{ "America/Belize", "1912-04-01" },
|
||
{ "America/Blanc-Sablon", "1884-01-01" },
|
||
{ "America/Bogota", "1914-11-23" },
|
||
{ "America/Buenos_Aires", "1894-10-31" },
|
||
{ "America/Cambridge_Bay", "2000-11-05" },
|
||
{ "America/Campo_Grande", "1914-01-01" },
|
||
{ "America/Caracas", "1912-02-12" },
|
||
{ "America/Catamarca", "1991-10-20" },
|
||
{ "America/Catamarca", "2004-06-01" },
|
||
{ "America/Cayenne", "1911-07-01" },
|
||
{ "America/Chihuahua", "1930-11-15" },
|
||
{ "America/Chihuahua", "1931-10-01" },
|
||
{ "America/Cordoba", "1991-10-20" },
|
||
{ "America/Costa_Rica", "1921-01-15" },
|
||
{ "America/Cuiaba", "1914-01-01" },
|
||
{ "America/Danmarkshavn", "1916-07-28" },
|
||
{ "America/Detroit", "1905-01-01" },
|
||
{ "America/Eirunepe", "1914-01-01" },
|
||
{ "America/El_Salvador", "1921-01-01" },
|
||
{ "America/Ensenada", "1924-01-01" },
|
||
{ "America/Ensenada", "1930-11-15" },
|
||
{ "America/Fortaleza", "1914-01-01" },
|
||
{ "America/Glace_Bay", "1902-06-15" },
|
||
{ "America/Grand_Turk", "1890-01-01" },
|
||
{ "America/Guyana", "1991-01-01" },
|
||
{ "America/Havana", "1890-01-01" },
|
||
{ "America/Hermosillo", "1930-11-15" },
|
||
{ "America/Hermosillo", "1931-10-01" },
|
||
{ "America/Hermosillo", "1942-04-24" },
|
||
{ "America/Hermosillo", "1949-01-14" },
|
||
{ "America/Jujuy", "1991-10-06" },
|
||
{ "America/Lima", "1890-01-01" },
|
||
{ "America/Maceio", "1914-01-01" },
|
||
{ "America/Managua", "1890-01-01" },
|
||
{ "America/Managua", "1934-06-23" },
|
||
{ "America/Managua", "1975-02-16" },
|
||
{ "America/Managua", "1992-09-24" },
|
||
{ "America/Managua", "1997-01-01" },
|
||
{ "America/Mazatlan", "1930-11-15" },
|
||
{ "America/Mazatlan", "1931-10-01" },
|
||
{ "America/Mazatlan", "1942-04-24" },
|
||
{ "America/Mazatlan", "1949-01-14" },
|
||
{ "America/Mendoza", "1992-10-18" },
|
||
{ "America/Mendoza", "2004-05-23" },
|
||
{ "America/Merida", "1982-12-02" },
|
||
{ "America/Mexico_City", "1930-11-15" },
|
||
{ "America/Mexico_City", "1931-10-01" },
|
||
{ "America/Miquelon", "1911-05-15" },
|
||
{ "America/Moncton", "1883-12-09" },
|
||
{ "America/Montevideo", "1942-12-14" },
|
||
{ "America/Montevideo", "1974-12-22" },
|
||
{ "America/Montreal", "1884-01-01" },
|
||
{ "America/Ojinaga", "1930-11-15" },
|
||
{ "America/Ojinaga", "1931-10-01" },
|
||
{ "America/Panama", "1890-01-01" },
|
||
{ "America/Paramaribo", "1911-01-01" },
|
||
{ "America/Porto_Acre", "1914-01-01" },
|
||
{ "America/Recife", "1914-01-01" },
|
||
{ "America/Regina", "1905-09-01" },
|
||
{ "America/Rio_Branco", "1914-01-01" },
|
||
{ "America/Rosario", "1991-10-20" },
|
||
{ "America/Santa_Isabel", "1924-01-01" },
|
||
{ "America/Santa_Isabel", "1930-11-15" },
|
||
{ "America/Santarem", "1914-01-01" },
|
||
{ "America/Santiago", "1910-01-01" },
|
||
{ "America/Santiago", "1919-07-01" },
|
||
{ "America/Santo_Domingo", "1890-01-01" },
|
||
{ "America/Scoresbysund", "1916-07-28" },
|
||
{ "America/Scoresbysund", "1981-03-29" },
|
||
{ "America/Tegucigalpa", "1921-04-01" },
|
||
{ "America/Thunder_Bay", "1895-01-01" },
|
||
{ "America/Tijuana", "1924-01-01" },
|
||
{ "America/Tijuana", "1930-11-15" },
|
||
{ "Antarctica/Casey", "1969-01-01" },
|
||
{ "Antarctica/Casey", "2009-10-18" },
|
||
{ "Antarctica/Davis", "1957-01-13" },
|
||
{ "Antarctica/Davis", "1969-02-01" },
|
||
{ "Antarctica/Davis", "2010-03-11" },
|
||
{ "Antarctica/DumontDUrville", "1947-01-01" },
|
||
{ "Antarctica/DumontDUrville", "1956-11-01" },
|
||
{ "Antarctica/Macquarie", "1911-01-01" },
|
||
{ "Antarctica/Mawson", "1954-02-13" },
|
||
{ "Antarctica/McMurdo", "1956-01-01" },
|
||
{ "Antarctica/Palmer", "1982-05-01" },
|
||
{ "Antarctica/South_Pole", "1956-01-01" },
|
||
{ "Antarctica/Syowa", "1957-01-29" },
|
||
{ "Antarctica/Vostok", "1957-12-16" },
|
||
{ "Arctic/Longyearbyen", "1895-01-01" },
|
||
{ "Asia/Almaty", "1930-06-21" },
|
||
{ "Asia/Anadyr", "1924-05-02" },
|
||
{ "Asia/Anadyr", "1930-06-21" },
|
||
{ "Asia/Anadyr", "1992-01-19" },
|
||
{ "Asia/Anadyr", "2011-03-27" },
|
||
{ "Asia/Aqtau", "1924-05-02" },
|
||
{ "Asia/Aqtau", "1930-06-21" },
|
||
{ "Asia/Aqtau", "1981-10-01" },
|
||
{ "Asia/Aqtau", "2005-03-15" },
|
||
{ "Asia/Aqtobe", "1924-05-02" },
|
||
{ "Asia/Aqtobe", "1930-06-21" },
|
||
{ "Asia/Ashgabat", "1924-05-02" },
|
||
{ "Asia/Ashgabat", "1930-06-21" },
|
||
{ "Asia/Ashgabat", "1992-01-19" },
|
||
{ "Asia/Ashkhabad", "1924-05-02" },
|
||
{ "Asia/Ashkhabad", "1930-06-21" },
|
||
{ "Asia/Ashkhabad", "1992-01-19" },
|
||
{ "Asia/Baghdad", "1918-01-01" },
|
||
{ "Asia/Bahrain", "1920-01-01" },
|
||
{ "Asia/Baku", "1957-03-01" },
|
||
{ "Asia/Bangkok", "1920-04-01" },
|
||
{ "Asia/Bishkek", "1924-05-02" },
|
||
{ "Asia/Bishkek", "1930-06-21" },
|
||
{ "Asia/Brunei", "1933-01-01" },
|
||
{ "Asia/Calcutta", "1941-10-01" },
|
||
{ "Asia/Choibalsan", "1978-01-01" },
|
||
{ "Asia/Chongqing", "1980-05-01" },
|
||
{ "Asia/Chungking", "1980-05-01" },
|
||
{ "Asia/Colombo", "1880-01-01" },
|
||
{ "Asia/Colombo", "1906-01-01" },
|
||
{ "Asia/Colombo", "1942-09-01" },
|
||
{ "Asia/Colombo", "1996-05-25" },
|
||
{ "Asia/Dacca", "1941-10-01" },
|
||
{ "Asia/Dacca", "1942-09-01" },
|
||
{ "Asia/Dhaka", "1941-10-01" },
|
||
{ "Asia/Dhaka", "1942-09-01" },
|
||
{ "Asia/Dili", "2000-09-17" },
|
||
{ "Asia/Dubai", "1920-01-01" },
|
||
{ "Asia/Dushanbe", "1924-05-02" },
|
||
{ "Asia/Dushanbe", "1930-06-21" },
|
||
{ "Asia/Harbin", "1928-01-01" },
|
||
{ "Asia/Harbin", "1940-01-01" },
|
||
{ "Asia/Ho_Chi_Minh", "1912-05-01" },
|
||
{ "Asia/Hong_Kong", "1904-10-30" },
|
||
{ "Asia/Hong_Kong", "1941-12-25" },
|
||
{ "Asia/Hovd", "1978-01-01" },
|
||
{ "Asia/Irkutsk", "1920-01-25" },
|
||
{ "Asia/Irkutsk", "1930-06-21" },
|
||
{ "Asia/Irkutsk", "1992-01-19" },
|
||
{ "Asia/Irkutsk", "2011-03-27" },
|
||
{ "Asia/Istanbul", "1880-01-01" },
|
||
{ "Asia/Istanbul", "1910-10-01" },
|
||
{ "Asia/Istanbul", "1978-10-15" },
|
||
{ "Asia/Jakarta", "1932-11-01" },
|
||
{ "Asia/Jakarta", "1942-03-23" },
|
||
{ "Asia/Jakarta", "1948-05-01" },
|
||
{ "Asia/Jayapura", "1944-09-01" },
|
||
{ "Asia/Kabul", "1945-01-01" },
|
||
{ "Asia/Kamchatka", "1922-11-10" },
|
||
{ "Asia/Kamchatka", "1930-06-21" },
|
||
{ "Asia/Kamchatka", "1992-01-19" },
|
||
{ "Asia/Kamchatka", "2011-03-27" },
|
||
{ "Asia/Karachi", "1907-01-01" },
|
||
{ "Asia/Kashgar", "1928-01-01" },
|
||
{ "Asia/Kashgar", "1980-05-01" },
|
||
{ "Asia/Kathmandu", "1986-01-01" },
|
||
{ "Asia/Katmandu", "1986-01-01" },
|
||
{ "Asia/Kolkata", "1941-10-01" },
|
||
{ "Asia/Krasnoyarsk", "1930-06-21" },
|
||
{ "Asia/Krasnoyarsk", "1992-01-19" },
|
||
{ "Asia/Krasnoyarsk", "2011-03-27" },
|
||
{ "Asia/Kuala_Lumpur", "1901-01-01" },
|
||
{ "Asia/Kuala_Lumpur", "1905-06-01" },
|
||
{ "Asia/Kuala_Lumpur", "1941-09-01" },
|
||
{ "Asia/Kuala_Lumpur", "1942-02-16" },
|
||
{ "Asia/Kuala_Lumpur", "1982-01-01" },
|
||
{ "Asia/Kuching", "1926-03-01" },
|
||
{ "Asia/Kuching", "1933-01-01" },
|
||
{ "Asia/Kuching", "1942-02-16" },
|
||
{ "Asia/Macao", "1912-01-01" },
|
||
{ "Asia/Macau", "1912-01-01" },
|
||
{ "Asia/Magadan", "1930-06-21" },
|
||
{ "Asia/Magadan", "1992-01-19" },
|
||
{ "Asia/Magadan", "2011-03-27" },
|
||
{ "Asia/Makassar", "1932-11-01" },
|
||
{ "Asia/Makassar", "1942-02-09" },
|
||
{ "Asia/Manila", "1942-05-01" },
|
||
{ "Asia/Muscat", "1920-01-01" },
|
||
{ "Asia/Novokuznetsk", "1920-01-06" },
|
||
{ "Asia/Novokuznetsk", "1930-06-21" },
|
||
{ "Asia/Novokuznetsk", "1992-01-19" },
|
||
{ "Asia/Novokuznetsk", "2011-03-27" },
|
||
{ "Asia/Novosibirsk", "1930-06-21" },
|
||
{ "Asia/Novosibirsk", "1992-01-19" },
|
||
{ "Asia/Novosibirsk", "2011-03-27" },
|
||
{ "Asia/Omsk", "1919-11-14" },
|
||
{ "Asia/Omsk", "1930-06-21" },
|
||
{ "Asia/Omsk", "1992-01-19" },
|
||
{ "Asia/Omsk", "2011-03-27" },
|
||
{ "Asia/Oral", "1924-05-02" },
|
||
{ "Asia/Oral", "1930-06-21" },
|
||
{ "Asia/Oral", "2005-03-15" },
|
||
{ "Asia/Phnom_Penh", "1906-06-09" },
|
||
{ "Asia/Phnom_Penh", "1912-05-01" },
|
||
{ "Asia/Pontianak", "1932-11-01" },
|
||
{ "Asia/Pontianak", "1942-01-29" },
|
||
{ "Asia/Pontianak", "1948-05-01" },
|
||
{ "Asia/Pontianak", "1964-01-01" },
|
||
{ "Asia/Pyongyang", "1890-01-01" },
|
||
{ "Asia/Pyongyang", "1904-12-01" },
|
||
{ "Asia/Pyongyang", "1932-01-01" },
|
||
{ "Asia/Pyongyang", "1961-08-10" },
|
||
{ "Asia/Qatar", "1920-01-01" },
|
||
{ "Asia/Qyzylorda", "1930-06-21" },
|
||
{ "Asia/Qyzylorda", "1992-01-19" },
|
||
{ "Asia/Rangoon", "1920-01-01" },
|
||
{ "Asia/Rangoon", "1942-05-01" },
|
||
{ "Asia/Saigon", "1912-05-01" },
|
||
{ "Asia/Sakhalin", "1945-08-25" },
|
||
{ "Asia/Sakhalin", "1992-01-19" },
|
||
{ "Asia/Sakhalin", "2011-03-27" },
|
||
{ "Asia/Samarkand", "1930-06-21" },
|
||
{ "Asia/Seoul", "1890-01-01" },
|
||
{ "Asia/Seoul", "1904-12-01" },
|
||
{ "Asia/Seoul", "1932-01-01" },
|
||
{ "Asia/Seoul", "1961-08-10" },
|
||
{ "Asia/Seoul", "1968-10-01" },
|
||
{ "Asia/Singapore", "1905-06-01" },
|
||
{ "Asia/Singapore", "1941-09-01" },
|
||
{ "Asia/Singapore", "1942-02-16" },
|
||
{ "Asia/Singapore", "1982-01-01" },
|
||
{ "Asia/Tashkent", "1924-05-02" },
|
||
{ "Asia/Tashkent", "1930-06-21" },
|
||
{ "Asia/Tbilisi", "1924-05-02" },
|
||
{ "Asia/Tbilisi", "1957-03-01" },
|
||
{ "Asia/Tbilisi", "2005-03-27" },
|
||
{ "Asia/Tehran", "1946-01-01" },
|
||
{ "Asia/Tehran", "1977-11-01" },
|
||
{ "Asia/Thimbu", "1987-10-01" },
|
||
{ "Asia/Thimphu", "1987-10-01" },
|
||
{ "Asia/Ujung_Pandang", "1932-11-01" },
|
||
{ "Asia/Ujung_Pandang", "1942-02-09" },
|
||
{ "Asia/Ulaanbaatar", "1978-01-01" },
|
||
{ "Asia/Ulan_Bator", "1978-01-01" },
|
||
{ "Asia/Urumqi", "1928-01-01" },
|
||
{ "Asia/Urumqi", "1980-05-01" },
|
||
{ "Asia/Vientiane", "1906-06-09" },
|
||
{ "Asia/Vientiane", "1912-05-01" },
|
||
{ "Asia/Vladivostok", "1922-11-15" },
|
||
{ "Asia/Vladivostok", "1930-06-21" },
|
||
{ "Asia/Vladivostok", "1992-01-19" },
|
||
{ "Asia/Vladivostok", "2011-03-27" },
|
||
{ "Asia/Yakutsk", "1930-06-21" },
|
||
{ "Asia/Yakutsk", "1992-01-19" },
|
||
{ "Asia/Yakutsk", "2011-03-27" },
|
||
{ "Asia/Yekaterinburg", "1930-06-21" },
|
||
{ "Asia/Yekaterinburg", "1992-01-19" },
|
||
{ "Asia/Yekaterinburg", "2011-03-27" },
|
||
{ "Asia/Yerevan", "1924-05-02" },
|
||
{ "Asia/Yerevan", "1957-03-01" },
|
||
{ "Atlantic/Azores", "1884-01-01" },
|
||
{ "Atlantic/Azores", "1911-05-24" },
|
||
{ "Atlantic/Azores", "1942-04-25" },
|
||
{ "Atlantic/Azores", "1943-04-17" },
|
||
{ "Atlantic/Azores", "1944-04-22" },
|
||
{ "Atlantic/Azores", "1945-04-21" },
|
||
{ "Atlantic/Cape_Verde", "1907-01-01" },
|
||
{ "Atlantic/Jan_Mayen", "1895-01-01" },
|
||
{ "Atlantic/Madeira", "1942-04-25" },
|
||
{ "Atlantic/Madeira", "1943-04-17" },
|
||
{ "Atlantic/Madeira", "1944-04-22" },
|
||
{ "Atlantic/Madeira", "1945-04-21" },
|
||
{ "Atlantic/Reykjavik", "1837-01-01" },
|
||
{ "Atlantic/Stanley", "1912-03-12" },
|
||
{ "Australia/Adelaide", "1899-05-01" },
|
||
{ "Australia/Broken_Hill", "1895-02-01" },
|
||
{ "Australia/Broken_Hill", "1899-05-01" },
|
||
{ "Australia/Currie", "1895-09-01" },
|
||
{ "Australia/Darwin", "1895-02-01" },
|
||
{ "Australia/Darwin", "1899-05-01" },
|
||
{ "Australia/Eucla", "1895-12-01" },
|
||
{ "Australia/Hobart", "1895-09-01" },
|
||
{ "Australia/LHI", "1981-03-01" },
|
||
{ "Australia/Lindeman", "1895-01-01" },
|
||
{ "Australia/Lord_Howe", "1981-03-01" },
|
||
{ "Australia/Melbourne", "1895-02-01" },
|
||
{ "Australia/North", "1895-02-01" },
|
||
{ "Australia/North", "1899-05-01" },
|
||
{ "Australia/Perth", "1895-12-01" },
|
||
{ "Australia/South", "1899-05-01" },
|
||
{ "Australia/Tasmania", "1895-09-01" },
|
||
{ "Australia/Victoria", "1895-02-01" },
|
||
{ "Australia/West", "1895-12-01" },
|
||
{ "Australia/Yancowinna", "1895-02-01" },
|
||
{ "Australia/Yancowinna", "1899-05-01" },
|
||
{ "Brazil/Acre", "1914-01-01" },
|
||
{ "Canada/East-Saskatchewan", "1905-09-01" },
|
||
{ "Canada/Saskatchewan", "1905-09-01" },
|
||
{ "Chile/Continental", "1910-01-01" },
|
||
{ "Chile/Continental", "1919-07-01" },
|
||
{ "Chile/EasterIsland", "1932-09-01" },
|
||
{ "Cuba", "1890-01-01" },
|
||
{ "Eire", "1880-08-02" },
|
||
{ "Europe/Amsterdam", "1937-07-01" },
|
||
{ "Europe/Andorra", "1946-09-30" },
|
||
{ "Europe/Athens", "1916-07-28" },
|
||
{ "Europe/Athens", "1944-04-04" },
|
||
{ "Europe/Berlin", "1893-04-01" },
|
||
{ "Europe/Bratislava", "1891-10-01" },
|
||
{ "Europe/Brussels", "1914-11-08" },
|
||
{ "Europe/Bucharest", "1931-07-24" },
|
||
{ "Europe/Chisinau", "1931-07-24" },
|
||
{ "Europe/Copenhagen", "1894-01-01" },
|
||
{ "Europe/Dublin", "1880-08-02" },
|
||
{ "Europe/Gibraltar", "1941-05-04" },
|
||
{ "Europe/Gibraltar", "1942-04-05" },
|
||
{ "Europe/Gibraltar", "1943-04-04" },
|
||
{ "Europe/Gibraltar", "1944-04-02" },
|
||
{ "Europe/Gibraltar", "1945-04-02" },
|
||
{ "Europe/Gibraltar", "1947-04-13" },
|
||
{ "Europe/Helsinki", "1921-05-01" },
|
||
{ "Europe/Istanbul", "1880-01-01" },
|
||
{ "Europe/Istanbul", "1910-10-01" },
|
||
{ "Europe/Istanbul", "1978-10-15" },
|
||
{ "Europe/Kaliningrad", "1945-01-01" },
|
||
{ "Europe/Kaliningrad", "1946-01-01" },
|
||
{ "Europe/Kaliningrad", "2011-03-27" },
|
||
{ "Europe/Kiev", "1930-06-21" },
|
||
{ "Europe/Kiev", "1943-11-06" },
|
||
{ "Europe/Luxembourg", "1904-06-01" },
|
||
{ "Europe/Madrid", "1942-05-02" },
|
||
{ "Europe/Madrid", "1943-04-17" },
|
||
{ "Europe/Madrid", "1944-04-15" },
|
||
{ "Europe/Madrid", "1945-04-14" },
|
||
{ "Europe/Madrid", "1946-04-13" },
|
||
{ "Europe/Malta", "1893-11-02" },
|
||
{ "Europe/Mariehamn", "1921-05-01" },
|
||
{ "Europe/Minsk", "1924-05-02" },
|
||
{ "Europe/Minsk", "1930-06-21" },
|
||
{ "Europe/Minsk", "2011-03-27" },
|
||
{ "Europe/Monaco", "1941-05-05" },
|
||
{ "Europe/Monaco", "1942-03-09" },
|
||
{ "Europe/Monaco", "1943-03-29" },
|
||
{ "Europe/Monaco", "1944-04-03" },
|
||
{ "Europe/Monaco", "1945-04-02" },
|
||
{ "Europe/Moscow", "1916-07-03" },
|
||
{ "Europe/Moscow", "1919-05-31" },
|
||
{ "Europe/Moscow", "1930-06-21" },
|
||
{ "Europe/Moscow", "1992-01-19" },
|
||
{ "Europe/Moscow", "2011-03-27" },
|
||
{ "Europe/Oslo", "1895-01-01" },
|
||
{ "Europe/Paris", "1945-04-02" },
|
||
{ "Europe/Prague", "1891-10-01" },
|
||
{ "Europe/Riga", "1926-05-11" },
|
||
{ "Europe/Riga", "1940-08-05" },
|
||
{ "Europe/Riga", "1944-10-13" },
|
||
{ "Europe/Rome", "1893-11-01" },
|
||
{ "Europe/Samara", "1930-06-21" },
|
||
{ "Europe/Samara", "1991-10-20" },
|
||
{ "Europe/Samara", "2011-03-27" },
|
||
{ "Europe/San_Marino", "1893-11-01" },
|
||
{ "Europe/Simferopol", "1930-06-21" },
|
||
{ "Europe/Simferopol", "1994-05-01" },
|
||
{ "Europe/Sofia", "1880-01-01" },
|
||
{ "Europe/Sofia", "1894-11-30" },
|
||
{ "Europe/Tallinn", "1919-07-01" },
|
||
{ "Europe/Tallinn", "1921-05-01" },
|
||
{ "Europe/Tallinn", "1940-08-06" },
|
||
{ "Europe/Tiraspol", "1931-07-24" },
|
||
{ "Europe/Uzhgorod", "1945-06-29" },
|
||
{ "Europe/Vaduz", "1894-06-01" },
|
||
{ "Europe/Vatican", "1893-11-01" },
|
||
{ "Europe/Vilnius", "1917-01-01" },
|
||
{ "Europe/Vilnius", "1920-07-12" },
|
||
{ "Europe/Vilnius", "1940-08-03" },
|
||
{ "Europe/Volgograd", "1920-01-03" },
|
||
{ "Europe/Volgograd", "1930-06-21" },
|
||
{ "Europe/Volgograd", "1991-03-31" },
|
||
{ "Europe/Volgograd", "2011-03-27" },
|
||
{ "Europe/Zaporozhye", "1930-06-21" },
|
||
{ "Europe/Zaporozhye", "1943-10-25" },
|
||
{ "Europe/Zurich", "1894-06-01" },
|
||
{ "Hongkong", "1904-10-30" },
|
||
{ "Hongkong", "1941-12-25" },
|
||
{ "Iceland", "1837-01-01" },
|
||
{ "Indian/Chagos", "1907-01-01" },
|
||
{ "Indian/Chagos", "1996-01-01" },
|
||
{ "Indian/Cocos", "1900-01-01" },
|
||
{ "Indian/Comoro", "1911-07-01" },
|
||
{ "Indian/Kerguelen", "1950-01-01" },
|
||
{ "Indian/Mahe", "1906-06-01" },
|
||
{ "Indian/Maldives", "1960-01-01" },
|
||
{ "Indian/Mauritius", "1907-01-01" },
|
||
{ "Indian/Reunion", "1911-06-01" },
|
||
{ "Iran", "1946-01-01" },
|
||
{ "Iran", "1977-11-01" },
|
||
{ "Libya", "1920-01-01" },
|
||
{ "Libya", "1959-01-01" },
|
||
{ "Libya", "1990-05-04" },
|
||
{ "Mexico/BajaNorte", "1924-01-01" },
|
||
{ "Mexico/BajaNorte", "1930-11-15" },
|
||
{ "Mexico/BajaSur", "1930-11-15" },
|
||
{ "Mexico/BajaSur", "1931-10-01" },
|
||
{ "Mexico/BajaSur", "1942-04-24" },
|
||
{ "Mexico/BajaSur", "1949-01-14" },
|
||
{ "Mexico/General", "1930-11-15" },
|
||
{ "Mexico/General", "1931-10-01" },
|
||
{ "NZ-CHAT", "1957-01-01" },
|
||
{ "Pacific/Apia", "1911-01-01" },
|
||
{ "Pacific/Apia", "2011-12-30" },
|
||
{ "Pacific/Chatham", "1957-01-01" },
|
||
{ "Pacific/Easter", "1932-09-01" },
|
||
{ "Pacific/Enderbury", "1901-01-01" },
|
||
{ "Pacific/Enderbury", "1995-01-01" },
|
||
{ "Pacific/Fakaofo", "2011-12-30" },
|
||
{ "Pacific/Fiji", "1915-10-26" },
|
||
{ "Pacific/Funafuti", "1901-01-01" },
|
||
{ "Pacific/Galapagos", "1986-01-01" },
|
||
{ "Pacific/Gambier", "1912-10-01" },
|
||
{ "Pacific/Guadalcanal", "1912-10-01" },
|
||
{ "Pacific/Guam", "1901-01-01" },
|
||
{ "Pacific/Kiritimati", "1901-01-01" },
|
||
{ "Pacific/Kiritimati", "1995-01-01" },
|
||
{ "Pacific/Kosrae", "1901-01-01" },
|
||
{ "Pacific/Kosrae", "1969-10-01" },
|
||
{ "Pacific/Kwajalein", "1993-08-20" },
|
||
{ "Pacific/Majuro", "1969-10-01" },
|
||
{ "Pacific/Marquesas", "1912-10-01" },
|
||
{ "Pacific/Nauru", "1921-01-15" },
|
||
{ "Pacific/Nauru", "1944-08-15" },
|
||
{ "Pacific/Nauru", "1979-05-01" },
|
||
{ "Pacific/Niue", "1901-01-01" },
|
||
{ "Pacific/Niue", "1951-01-01" },
|
||
{ "Pacific/Norfolk", "1901-01-01" },
|
||
{ "Pacific/Norfolk", "1951-01-01" },
|
||
{ "Pacific/Pago_Pago", "1911-01-01" },
|
||
{ "Pacific/Palau", "1901-01-01" },
|
||
{ "Pacific/Pohnpei", "1901-01-01" },
|
||
{ "Pacific/Ponape", "1901-01-01" },
|
||
{ "Pacific/Port_Moresby", "1895-01-01" },
|
||
{ "Pacific/Rarotonga", "1978-11-12" },
|
||
{ "Pacific/Saipan", "1969-10-01" },
|
||
{ "Pacific/Samoa", "1911-01-01" },
|
||
{ "Pacific/Tahiti", "1912-10-01" },
|
||
{ "Pacific/Tarawa", "1901-01-01" },
|
||
{ "Pacific/Tongatapu", "1901-01-01" },
|
||
{ "Pacific/Tongatapu", "1941-01-01" },
|
||
{ "Pacific/Wake", "1901-01-01" },
|
||
{ "ROK", "1890-01-01" },
|
||
{ "ROK", "1904-12-01" },
|
||
{ "ROK", "1932-01-01" },
|
||
{ "ROK", "1961-08-10" },
|
||
{ "ROK", "1968-10-01" },
|
||
{ "Singapore", "1905-06-01" },
|
||
{ "Singapore", "1941-09-01" },
|
||
{ "Singapore", "1942-02-16" },
|
||
{ "Singapore", "1982-01-01" },
|
||
{ "Turkey", "1880-01-01" },
|
||
{ "Turkey", "1910-10-01" },
|
||
{ "Turkey", "1978-10-15" },
|
||
{ "US/Michigan", "1905-01-01" },
|
||
{ "US/Samoa", "1911-01-01" },
|
||
{ "W-SU", "1916-07-03" },
|
||
{ "W-SU", "1930-06-21" },
|
||
{ "W-SU", "1992-01-19" },
|
||
{ "W-SU", "2011-03-27" }
|
||
};
|
||
|
||
LanguageType eLang = LANGUAGE_ENGLISH_US;
|
||
SvNumberFormatter aFormatter(m_xContext, eLang);
|
||
|
||
for (auto const& aEntry : aData)
|
||
{
|
||
checkDateInput(aFormatter, aEntry[0], aEntry[1]);
|
||
}
|
||
}
|
||
|
||
void Test::checkDateInput( SvNumberFormatter& rFormatter, const char* pTimezone, const char* pIsoDate )
|
||
{
|
||
icu::TimeZone::adoptDefault( icu::TimeZone::createTimeZone( pTimezone));
|
||
OUString aDate( OUString::createFromAscii(pIsoDate));
|
||
sal_uInt32 nIndex = 0;
|
||
double fVal = 0.0;
|
||
bool bVal = rFormatter.IsNumberFormat( aDate, nIndex, fVal);
|
||
CPPUNIT_ASSERT_MESSAGE( OString(OString::Concat("Date not recognized: ") +
|
||
pTimezone + " " + pIsoDate).getStr(), bVal);
|
||
CPPUNIT_ASSERT_MESSAGE("Format parsed is not date.",
|
||
(rFormatter.GetType(nIndex) & SvNumFormatType::DATE));
|
||
OUString aOutString;
|
||
const Color *pColor;
|
||
rFormatter.GetOutputString( fVal, nIndex, aOutString, &pColor);
|
||
CPPUNIT_ASSERT_EQUAL( aDate, aOutString);
|
||
}
|
||
|
||
void Test::testIsNumberFormat()
|
||
{
|
||
LanguageType eLang = LANGUAGE_ENGLISH_US;
|
||
SvNumberFormatter aFormatter(m_xContext, eLang);
|
||
|
||
static struct NumberFormatData
|
||
{
|
||
const char* pFormat;
|
||
bool bIsNumber;
|
||
} const aTests[] = {
|
||
{ "20.3", true },
|
||
{ "2", true },
|
||
{ "test", false },
|
||
{ "$0.12", true }, // tdf#48706
|
||
{ "$.12", true }, // tdf#48706
|
||
{ "1 .", false }, // tdf#131562
|
||
{ "1 .2", false }, // tdf#131562
|
||
{ "1 . 2", false }, // tdf#131562
|
||
{ "1. 2", false }, // tdf#131562
|
||
{ " . 2", false }, // tdf#131562
|
||
{ ". 2", false }, // tdf#131562
|
||
{ " .2", true }, // tdf#131562
|
||
{ "Jan1", false }, // tdf#34724
|
||
{ "1Jan", false }, // tdf#34724
|
||
{ "Jan1 2000", true }, // tdf#91420
|
||
{ "Jan1, 2000", true }, // tdf#91420
|
||
{ "Jan 1", true },
|
||
{ "Sept 1", true }, //tdf#127363
|
||
{ "5/d", false }, //tdf#143165
|
||
{ "Jan 1 2000", true },
|
||
{ "5-12-14", true }, // tdf#164239
|
||
{ "005-12-14", true },
|
||
{ "15-10-30", true },
|
||
{ "2015-10-30", true },
|
||
{ "1999-11-23T12:34:56", true },
|
||
{ "1999-11-23 12:34:56", true },
|
||
{ "1999-11-23T12:34:56.789", true },
|
||
{ "1999-11-23T12:34:56,789", true }, // ISO 8601 defines both dot and comma as fractional separator
|
||
{ "1999-11-23 12:34:56.789", true },
|
||
{ "1999-11-23 12:34:56,789", false }, // comma not in en-US if 'T' separator is not present,
|
||
// debatable, 'T' "may be omitted by mutual consent of those
|
||
// interchanging data, if ambiguity can be avoided."
|
||
{ "1999-11-23T12:34:56/789", false },
|
||
{ "−1000", true } // unicode minus
|
||
};
|
||
|
||
for (auto const[pFormat, bTestIsNumber] : aTests)
|
||
{
|
||
sal_uInt32 nIndex = 0;
|
||
double nNumber = 0;
|
||
OUString aString = OUString::fromUtf8(pFormat);
|
||
bool bIsNumber = aFormatter.IsNumberFormat(aString, nIndex, nNumber);
|
||
CPPUNIT_ASSERT_EQUAL_MESSAGE(pFormat, bTestIsNumber, bIsNumber);
|
||
}
|
||
}
|
||
|
||
struct FormatInputOutput
|
||
{
|
||
const char* mpInput;
|
||
const bool mbNumber;
|
||
const char* mpOutput;
|
||
const sal_uInt32 mnOutputIndex;
|
||
};
|
||
|
||
void checkSpecificNumberFormats( SvNumberFormatter& rFormatter,
|
||
const std::vector<FormatInputOutput>& rVec, const char* pName )
|
||
{
|
||
|
||
for (size_t i = 0; i < rVec.size(); ++i)
|
||
{
|
||
sal_uInt32 nIndex = 0;
|
||
double fNumber = 0;
|
||
OUString aString( OUString::fromUtf8( rVec[i].mpInput));
|
||
const bool bIsNumber = rFormatter.IsNumberFormat( aString, nIndex, fNumber);
|
||
CPPUNIT_ASSERT_EQUAL_MESSAGE( OString( pName + OString::Concat(" ") + OString::number(i) +
|
||
(rVec[i].mbNumber ? " not recognized: " : " should not be recognized: ") +
|
||
OUStringToOString( aString, RTL_TEXTENCODING_UTF8)).getStr(), rVec[i].mbNumber, bIsNumber);
|
||
if (bIsNumber)
|
||
{
|
||
if (rVec[i].mnOutputIndex)
|
||
nIndex = rVec[i].mnOutputIndex;
|
||
const Color* pColor;
|
||
rFormatter.GetOutputString( fNumber, nIndex, aString, &pColor);
|
||
CPPUNIT_ASSERT_EQUAL_MESSAGE( OString( pName + OString::Concat(" ") + OString::number(i) + " mismatch").getStr(),
|
||
OUString::fromUtf8( rVec[i].mpOutput), aString);
|
||
}
|
||
}
|
||
}
|
||
|
||
void Test::testIsNumberFormatSpecific()
|
||
{
|
||
{
|
||
// en-US uses M/D/Y format, test that without Y-M-D pattern an a-b-c
|
||
// input with a<=12 leads to ISO a-b-c date output.
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_ENGLISH_US);
|
||
|
||
std::vector<FormatInputOutput> aIO = {
|
||
{ "005-12-14", true, "0005-12-14", 0 },
|
||
{ "5-12-14", true, "2005-12-14", 0 },
|
||
{ "32-12-14", true, "1932-12-14", 0 }
|
||
};
|
||
|
||
checkSpecificNumberFormats( aFormatter, aIO, "[en-US] date");
|
||
}
|
||
|
||
{
|
||
// de-DE uses D.M.Y format, test that without Y-M-D pattern an a-b-c
|
||
// input with a<=31 leads to ISO a-b-c date output.
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_GERMAN);
|
||
|
||
std::vector<FormatInputOutput> aIO = {
|
||
{ "005-12-14", true, "0005-12-14", 0 },
|
||
{ "5-12-14", true, "2005-12-14", 0 },
|
||
{ "32-12-14", true, "1932-12-14", 0 }
|
||
};
|
||
|
||
checkSpecificNumberFormats( aFormatter, aIO, "[de-DE] date");
|
||
}
|
||
|
||
{
|
||
// nl-NL uses D-M-Y format, test that D-M-Y input leads to D-M-Y output
|
||
// and ISO Y-M-D input leads to Y-M-D output.
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_DUTCH);
|
||
|
||
std::vector<FormatInputOutput> aIO = {
|
||
{ "001-2-11", true, "0001-02-11", 0 },
|
||
{ "22-11-1999", true, "22-11-99", 0 }, // if default YY changes to YYYY adapt this
|
||
{ "1999-11-22", true, "1999-11-22", 0 },
|
||
{ "1-2-11", true, "01-02-11", 0 }, // if default YY changes to YYYY adapt this
|
||
{ "99-2-11", true, "1999-02-11", 0 }
|
||
};
|
||
|
||
checkSpecificNumberFormats( aFormatter, aIO, "[nl-NL] date");
|
||
}
|
||
|
||
{
|
||
// en-ZA uses Y-M-D and Y/M/D format, test that either are accepted.
|
||
// The default format changed from YY/MM/DD to YYYY-MM-DD.
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_ENGLISH_SAFRICA);
|
||
|
||
std::vector<FormatInputOutput> aIO = {
|
||
{ "1999/11/22", true, "1999-11-22", 0 },
|
||
{ "1999-11-22", true, "1999-11-22", 0 },
|
||
{ "11/2/1", true, "2011-02-01", 0 },
|
||
{ "99-2-11", true, "1999-02-11", 0 },
|
||
{ "22-2-11", true, "2022-02-11", 0 },
|
||
{ "02 Mar 2020",true, "2020-03-02", 0 }
|
||
};
|
||
|
||
checkSpecificNumberFormats( aFormatter, aIO, "[en-ZA] date");
|
||
}
|
||
|
||
{
|
||
// fr-FR uses D/M/Y format with additional D.M.Y and D-M-Y date
|
||
// acceptance patterns, test combinations.
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_FRENCH);
|
||
|
||
std::vector<FormatInputOutput> aIO = {
|
||
{ "22/11/1999", true, "22/11/99", 0 }, // if default YY changes to YYYY adapt this
|
||
{ "1999-11-22", true, "1999-11-22", 0 },
|
||
{ "1/2/11", true, "01/02/11", 0 }, // if default YY changes to YYYY adapt this
|
||
{ "99-2-11", true, "1999-02-11", 0 },
|
||
{ "22-2-11", true, "22/02/11", 0 }, // if default YY changes to YYYY adapt this
|
||
{ "22.2.11", true, "22/02/11", 0 } // if default YY changes to YYYY adapt this
|
||
};
|
||
|
||
checkSpecificNumberFormats( aFormatter, aIO, "[fr-FR] date");
|
||
}
|
||
|
||
{
|
||
// Test Spanish "mar" short name ambiguity, day "martes" or month "marzo".
|
||
// Day of week names are only parsed away, not evaluated if they actually
|
||
// correspond to the date given.
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_SPANISH);
|
||
|
||
const sal_uInt32 n = aFormatter.GetFormatIndex( NF_DATE_SYS_DDMMYYYY, LANGUAGE_SPANISH);
|
||
std::vector<FormatInputOutput> aIO = {
|
||
{ "22/11/1999", true, "22/11/1999", n },
|
||
{ "Lun 22/11/1999", true, "22/11/1999", n },
|
||
{ "Mar 22/11/1999", true, "22/11/1999", n },
|
||
{ "Abr 22/11/1999", false, "", n }, // month name AND numeric month don't go along
|
||
{ "Lun Mar 22/11/1999", false, "", n }, // month name AND numeric month don't go along
|
||
{ "Mar Mar 22/11/1999", false, "", n }, // month name AND numeric month don't go along
|
||
{ "Lun Mar 22 1999", true, "22/03/1999", n },
|
||
{ "Mar Mar 22 1999", true, "22/03/1999", n },
|
||
{ "Mar Lun 22 1999", false, "", n } // day name only at the beginning (could change?)
|
||
};
|
||
|
||
checkSpecificNumberFormats( aFormatter, aIO, "[es-ES] date");
|
||
}
|
||
|
||
{
|
||
// Test that de-DE accepts Januar and Jänner.
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_GERMAN);
|
||
|
||
const sal_uInt32 n = aFormatter.GetFormatIndex( NF_DATE_SYS_DDMMYYYY, LANGUAGE_GERMAN);
|
||
std::vector<FormatInputOutput> aIO = {
|
||
{ "23. Januar 1999", true, "23.01.1999", n },
|
||
{ "23. J\xC3\xA4nner 1999", true, "23.01.1999", n },
|
||
{ "23. Jan. 1999", true, "23.01.1999", n },
|
||
{ "23. J\xC3\xA4n. 1999", true, "23.01.1999", n },
|
||
};
|
||
|
||
checkSpecificNumberFormats( aFormatter, aIO, "[de-DE] date January month names");
|
||
}
|
||
|
||
{
|
||
// tdf#143664
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_GERMAN);
|
||
|
||
const sal_uInt32 n = aFormatter.GetFormatIndex( NF_DATE_SYS_DDMMYYYY, LANGUAGE_GERMAN);
|
||
std::vector<FormatInputOutput> aIO = {
|
||
{ "23. M\u00C4R 1999", true, "23.03.1999", n },
|
||
{ "23. M\u00C4RZ 1999", true, "23.03.1999", n },
|
||
{ "23. MRZ 1999", true, "23.03.1999", n },
|
||
};
|
||
|
||
checkSpecificNumberFormats( aFormatter, aIO, "[de-DE] date March month names");
|
||
}
|
||
|
||
{
|
||
// Test that de-AT accepts Januar and Jänner.
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_GERMAN_AUSTRIAN);
|
||
|
||
const sal_uInt32 n = aFormatter.GetFormatIndex( NF_DATE_SYS_DDMMYYYY, LANGUAGE_GERMAN_AUSTRIAN);
|
||
std::vector<FormatInputOutput> aIO = {
|
||
{ "23. Januar 1999", true, "23.01.1999", n },
|
||
{ "23. J\xC3\xA4nner 1999", true, "23.01.1999", n },
|
||
{ "23. Jan. 1999", true, "23.01.1999", n },
|
||
{ "23. J\xC3\xA4n. 1999", true, "23.01.1999", n },
|
||
};
|
||
|
||
checkSpecificNumberFormats( aFormatter, aIO, "[de-AT] date January month names");
|
||
}
|
||
}
|
||
|
||
void Test::testUserDefinedNumberFormats()
|
||
{
|
||
LanguageType eLang = LANGUAGE_ENGLISH_US;
|
||
OUString sCode, sExpected;
|
||
SvNumberFormatter aFormatter(m_xContext, eLang);
|
||
// tdf#158890 replace '?' with figure blank (0x2007)
|
||
static constexpr OUString sBlankDigit = u" "_ustr;
|
||
{ // tdf#97835: suppress decimal separator
|
||
sCode = "0.##\" m\"";
|
||
sExpected = "12 m";
|
||
checkPreviewString(aFormatter, sCode, 12.0, eLang, sExpected);
|
||
}
|
||
{ // tdf#61996: skip quoted text
|
||
sCode = "0.00\" ;\"";
|
||
sExpected = "-12.00 ;";
|
||
checkPreviewString(aFormatter, sCode, -12.0, eLang, sExpected);
|
||
}
|
||
{ // tdf#100755
|
||
sCode = "000\" \"000/000";
|
||
sExpected = "003 016/113";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
}
|
||
{ // tdf#100834
|
||
sCode = "#\" string \"?/???";
|
||
sExpected = "3 string 16/113";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
}
|
||
{ // tdf#129878
|
||
sCode = "[HH]";
|
||
sExpected = "#FMT";
|
||
checkPreviewString(aFormatter, sCode, 2E+306, eLang, sExpected);
|
||
}
|
||
{ // tdf#144697
|
||
sCode = "YYYY-MM-DD";
|
||
sExpected = "#FMT";
|
||
checkPreviewString(aFormatter, sCode, -12662108.0, eLang, sExpected);
|
||
}
|
||
{ // tdf#122991
|
||
sCode = "[HH]:MM:SS";
|
||
sExpected = "08:47:00";
|
||
checkPreviewString(aFormatter, sCode, 0.365972222222222, eLang, sExpected);
|
||
|
||
sCode = "HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, 0.365972222222222, eLang, sExpected);
|
||
}
|
||
{ // tdf#100122
|
||
sCode = "?/?";
|
||
sExpected = "-1/2";
|
||
checkPreviewString(aFormatter, sCode, -0.5, eLang, sExpected);
|
||
}
|
||
{ // tdf#52510
|
||
sCode = "_($* #,##0.00_);_($* (#,##0.00);";
|
||
sExpected = "";
|
||
checkPreviewString(aFormatter, sCode, 0.0, eLang, sExpected);
|
||
}
|
||
{ // tdf#95339: detect SSMM as second minute
|
||
sCode = "SS:MM:HH DD/MM/YY"; // Month not detected by Excel, but we do not follow that.
|
||
sExpected = "53:23:03 02/01/00";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
}
|
||
{ // tdf#101147: detect SSMM as second month
|
||
sCode = "HH:MM:SS MM/DD";
|
||
sExpected = "03:23:53 01/02";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
}
|
||
{ // tdf#123748
|
||
sCode = "HH:MM:SS.000000";
|
||
sExpected = "12:54:00.000000";
|
||
checkPreviewString(aFormatter, sCode, 43521.5375, eLang, sExpected);
|
||
}
|
||
{ // tdf#101096: different detection of month/minute with Excel
|
||
sCode = "HH DD MM"; // month detected because of previous DD
|
||
sExpected = "03 02 01";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "HH:MM HH DD/MM"; // month detected because of previous DD
|
||
sExpected = "03:23 03 02/01";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "SS:DD-MM-YY SS:MM"; // 1st is month, because of previous DD; 2nd is minute as SS has not minute
|
||
sExpected = "53:02-01-00 53:23";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
}
|
||
{ // tdf#99996: better algorithm for fraction representation
|
||
sCode = "# ?/???";
|
||
sExpected = "-575 540/697";
|
||
checkPreviewString(aFormatter, sCode, -575.774749601315, eLang, sExpected);
|
||
}
|
||
{ // tdf#153887: integer value without integer part displayed
|
||
sCode = "#/?";
|
||
sExpected = "2/1";
|
||
checkPreviewString(aFormatter, sCode, 1.95, eLang, sExpected);
|
||
checkPreviewString(aFormatter, sCode, 2.00, eLang, sExpected);
|
||
checkPreviewString(aFormatter, sCode, 2.05, eLang, sExpected);
|
||
sCode = "0/8";
|
||
sExpected = "16/8";
|
||
checkPreviewString(aFormatter, sCode, 1.95, eLang, sExpected);
|
||
checkPreviewString(aFormatter, sCode, 2.00, eLang, sExpected);
|
||
checkPreviewString(aFormatter, sCode, 2.05, eLang, sExpected);
|
||
}
|
||
{ // tdf#102507: left alignment of denominator
|
||
sCode = "# ?/???";
|
||
sExpected = OUString::Concat( u"3 1/2"_ustr ) + sBlankDigit + sBlankDigit;
|
||
checkPreviewString(aFormatter, sCode, 3.5, eLang, sExpected);
|
||
}
|
||
{ // tdf#100594: forced denominator
|
||
sCode = "# ?/100";
|
||
sExpected = " 6/100";
|
||
checkPreviewString(aFormatter, sCode, 0.06, eLang, sExpected);
|
||
}
|
||
{ // tdf#100754: forced denominator with text after fraction
|
||
sCode = "# ?/16\" inch\"";
|
||
sExpected = "2 6/16 inch";
|
||
checkPreviewString(aFormatter, sCode, 2.379, eLang, sExpected);
|
||
}
|
||
{ // tdf#100842: text before/after fraction
|
||
sCode = "\"before \"?/?\" after\"";
|
||
sExpected = "before 11/9 after";
|
||
checkPreviewString(aFormatter, sCode, 1.2345667, eLang, sExpected);
|
||
sCode = "\"before \"# ?/?\" after\"";
|
||
sExpected = "before 1 2/9 after";
|
||
checkPreviewString(aFormatter, sCode, 1.2345667, eLang, sExpected);
|
||
sCode = "\"before \"0.0\"inside\"0E+0\"middle\"0\" after\"";
|
||
sExpected = "before 1.2inside3E+0middle4 after";
|
||
checkPreviewString(aFormatter, sCode, 12345.667, eLang, sExpected);
|
||
}
|
||
{ // tdf#106190: text after fraction bar
|
||
sCode = "?/ ?";
|
||
sExpected = "11/ 9";
|
||
checkPreviewString(aFormatter, sCode, 1.2345667, eLang, sExpected);
|
||
sCode = "?/ 12";
|
||
sExpected = "15/ 12";
|
||
checkPreviewString(aFormatter, sCode, 1.2345667, eLang, sExpected);
|
||
sCode = "# ?/\" divisor \"?";
|
||
sExpected = "1 2/ divisor 9";
|
||
checkPreviewString(aFormatter, sCode, 1.2345667, eLang, sExpected);
|
||
sCode = "# ?/\"divided by \"?";
|
||
sExpected = "1 2/divided by 9";
|
||
checkPreviewString(aFormatter, sCode, 1.2345667, eLang, sExpected);
|
||
sCode = "?/\" \"12";
|
||
sExpected = "15/ 12";
|
||
checkPreviewString(aFormatter, sCode, 1.2345667, eLang, sExpected);
|
||
sCode = "?/\\ 12";
|
||
sExpected = "15/ 12";
|
||
checkPreviewString(aFormatter, sCode, 1.2345667, eLang, sExpected);
|
||
sCode = "# ?/ ???";
|
||
sExpected = OUString::Concat( u"3 1/ 2"_ustr ) + sBlankDigit + sBlankDigit;
|
||
checkPreviewString(aFormatter, sCode, 3.5, eLang, sExpected);
|
||
}
|
||
{ // Display 1.96 as 2 and not 1 1/1
|
||
sCode = "# ?/?";
|
||
sExpected = OUString::Concat( u"2 "_ustr ) + sBlankDigit + u" "_ustr + sBlankDigit;
|
||
checkPreviewString(aFormatter, sCode, 1.96, eLang, sExpected);
|
||
sCode = "# ?/ ?";
|
||
sExpected = OUString::Concat( u"2 "_ustr ) + sBlankDigit + u" "_ustr + sBlankDigit;
|
||
checkPreviewString(aFormatter, sCode, 1.96, eLang, sExpected);
|
||
sCode = "# #/#";
|
||
sExpected = "2";
|
||
checkPreviewString(aFormatter, sCode, 1.96, eLang, sExpected);
|
||
}
|
||
{ // tdf#79399 tdf#101462 Native Number Formats
|
||
sCode = "[NatNum5][$-0404]General\\ ";
|
||
// Chinese upper case number characters for 120
|
||
sExpected = u"\u58F9\u4F70\u8CB3\u62FE "_ustr;
|
||
checkPreviewString(aFormatter, sCode, 120, eLang, sExpected);
|
||
sCode = "[DBNum2][$-0404]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 120, eLang, sExpected);
|
||
// tdf#115007 - cardinal/ordinal number names/indicators
|
||
sCode = "[NatNum12]0";
|
||
sExpected = "one hundred twenty-three";
|
||
checkPreviewString(aFormatter, sCode, 123, eLang, sExpected);
|
||
sCode = "[NatNum12]0.00";
|
||
sExpected = "one hundred twenty-three point four five";
|
||
checkPreviewString(aFormatter, sCode, 123.45, eLang, sExpected);
|
||
sCode = "[NatNum12 ordinal]0";
|
||
sExpected = "one hundred twenty-third";
|
||
checkPreviewString(aFormatter, sCode, 123, eLang, sExpected);
|
||
sCode = "[NatNum12 ordinal-number]0";
|
||
sExpected = "123rd";
|
||
checkPreviewString(aFormatter, sCode, 123, eLang, sExpected);
|
||
sCode = "[NatNum12 capitalize]0";
|
||
sExpected = "One hundred twenty-three";
|
||
checkPreviewString(aFormatter, sCode, 123, eLang, sExpected);
|
||
sCode = "[NatNum12 title ordinal]0";
|
||
sExpected = "One Thousand Two Hundred Thirty-Fourth";
|
||
checkPreviewString(aFormatter, sCode, 1234, eLang, sExpected);
|
||
sCode = "[NatNum12 upper ordinal-number]0";
|
||
sExpected = "12345TH";
|
||
checkPreviewString(aFormatter, sCode, 12345, eLang, sExpected);
|
||
sCode = "[NatNum12 D=ordinal-number]D\" of \"MMMM";
|
||
sExpected = "2nd of January";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "[NatNum12 D=ordinal-number,YYYY=year]D\" of \"MMMM\", \"YYYY";
|
||
sExpected = "2nd of January, nineteen hundred";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "[NatNum12 YYYY=title year, D=capitalize ordinal]D\" of \"MMMM\", \"YYYY";
|
||
sExpected = "Second of January, Nineteen Hundred";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "[NatNum12 MMMM=upper MMM=upper MMMMM=upper]MMMM MMM MMMMM";
|
||
sExpected = "JANUARY JAN J";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "[NatNum12 DDDD=upper DDD=upper]DDDD DDD";
|
||
sExpected = "TUESDAY TUE";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "[NatNum12 NNN=upper NN=upper]NNN NN";
|
||
sExpected = "TUESDAY TUE";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "[NatNum12 MMMM=lower MMM=lower MMMMM=lower]MMMM MMM MMMMM";
|
||
sExpected = "january jan j";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "[NatNum12 DDDD=lower DDD=lower]DDDD DDD";
|
||
sExpected = "tuesday tue";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "[NatNum12 NNN=lower NN=lower]NNN NN";
|
||
sExpected = "tuesday tue";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
}
|
||
{ // tdf#130193 tdf#130140 Native Number Formats mapping for Chinese (Traditional), Japanese, Korean
|
||
// -- Traditional Chinese: DBNum1 -> NatNum4, DBNum2 -> NatNum5, DBnum3 -> NatNum3
|
||
|
||
// DBNum1 -> NatNum4: Chinese lower case text for 123456789
|
||
// 一億二千三百四十五萬六千七百八十九
|
||
sExpected = u"\u4e00\u5104\u4e8c\u5343\u4e09\u767e\u56db\u5341\u4e94\u842c\u516d\u5343"
|
||
u"\u4e03\u767e\u516b\u5341\u4e5d "_ustr;
|
||
sCode = "[NatNum4][$-0404]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
sCode = "[DBNum1][$-0404]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
|
||
// DBNum2 -> NatNum5: Chinese upper case text
|
||
// 壹億貳仟參佰肆拾伍萬陸仟柒佰捌拾玖
|
||
sExpected = u"\u58f9\u5104\u8cb3\u4edf\u53c3\u4f70\u8086\u62fe\u4f0d\u842c\u9678\u4edf"
|
||
u"\u67d2\u4f70\u634c\u62fe\u7396 "_ustr;
|
||
sCode = "[NatNum5][$-0404]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
sCode = "[DBNum2][$-0404]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
|
||
// DBNum3 -> NatNum3: fullwidth text
|
||
// 123456789
|
||
sExpected = u"\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19 "_ustr;
|
||
sCode = "[NatNum3][$-0404]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
sCode = "[DBNum3][$-0404]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
|
||
// -- Japanese: DBNum1 -> NatNum4, DBNum2 -> NatNum5, DBnum3 -> NatNum3
|
||
|
||
// DBNum1 -> NatNum4: Japanese modern long Kanji text for 123456789
|
||
// 一億二千三百四十五万六千七百八十九
|
||
sExpected = u"\u4e00\u5104\u4e8c\u5343\u4e09\u767e\u56db\u5341\u4e94\u4e07\u516d\u5343"
|
||
u"\u4e03\u767e\u516b\u5341\u4e5d "_ustr;
|
||
sCode = "[NatNum4][$-0411]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
sCode = "[DBNum1][$-0411]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
|
||
// DBNum2 -> NatNum5: traditional long Kanji text
|
||
// 壱億弐阡参百四拾伍萬六阡七百八拾九
|
||
sExpected = u"\u58f1\u5104\u5f10\u9621\u53c2\u767e\u56db\u62fe\u4f0d\u842c\u516d\u9621"
|
||
u"\u4e03\u767e\u516b\u62fe\u4e5d "_ustr;
|
||
sCode = "[NatNum5][$-0411]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
sCode = "[DBNum2][$-0411]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
|
||
// DBNum3 -> NatNum3: fullwidth Arabic digits
|
||
// 123456789
|
||
sExpected = u"\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19 "_ustr;
|
||
sCode = "[NatNum3][$-0411]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
sCode = "[DBNum3][$-0411]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
|
||
// -- Korean: DBNum1 -> NatNum4, DBNum2 -> NatNum5, DBNum3 -> NatNum6, DBNum4 -> NatNum10
|
||
|
||
// DBNum1 -> NatNum4: Korean lower case characters
|
||
// 一億二千三百四十五万六千七百八十九
|
||
sExpected = u"\u4e00\u5104\u4e8c\u5343\u4e09\u767e\u56db\u5341\u4e94\u4e07\u516d\u5343\u4e03\u767e\u516b\u5341\u4e5d "_ustr;
|
||
sCode = "[NatNum4][$-0412]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
sCode = "[DBNum1][$-0412]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
|
||
// DBNum2 -> NatNum5: Korean upper case characters
|
||
// 壹億貳阡參佰四拾伍萬六阡七佰八拾九
|
||
sExpected = u"\u58f9\u5104\u8cb3\u9621\u53c3\u4f70\u56db\u62fe\u4f0d\u842c\u516d\u9621\u4e03\u4f70\u516b\u62fe\u4e5d "_ustr;
|
||
sCode = "[NatNum5][$-0412]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
sCode = "[DBNum2][$-0412]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
|
||
// DBNum3 -> NatNum6: fullwidth Arabic digits
|
||
// 1억2천3백4십5만6천7백8십9
|
||
sExpected = u"\uff11\uc5b5\uff12\ucc9c\uff13\ubc31\uff14\uc2ed\uff15\ub9cc\uff16\ucc9c\uff17\ubc31\uff18\uc2ed\uff19 "_ustr;
|
||
sCode = "[NatNum6][$-0412]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
sCode = "[DBNum3][$-0412]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
|
||
// DBNum4 -> NatNum10: Hangul characters
|
||
// 일억이천삼백사십오만육천칠백팔십구
|
||
sExpected = u"\uc77c\uc5b5\uc774\ucc9c\uc0bc\ubc31\uc0ac\uc2ed\uc624\ub9cc\uc721\ucc9c\uce60\ubc31\ud314\uc2ed\uad6c "_ustr;
|
||
sCode = "[NatNum10][$-0412]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
sCode = "[DBNum4][$-0412]General\\ ";
|
||
checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected);
|
||
}
|
||
{ // tdf#105968 engineering format with value rounded up to next magnitude
|
||
sCode = "##0.00E+00";
|
||
sExpected = "100.00E+00";
|
||
checkPreviewString(aFormatter, sCode, 99.995, eLang, sExpected);
|
||
// test '1'=='1' assumption
|
||
checkPreviewString(aFormatter, sCode, 100.0, eLang, sExpected);
|
||
sExpected = "199.99E+00";
|
||
checkPreviewString(aFormatter, sCode, 199.99, eLang, sExpected);
|
||
sExpected = "1.00E+03";
|
||
checkPreviewString(aFormatter, sCode, 1000.0, eLang, sExpected);
|
||
// and another just "normally" rounded value
|
||
sExpected = "894.55E-06";
|
||
checkPreviewString(aFormatter, sCode, 0.000894549, eLang, sExpected);
|
||
// not expecting rounding into another magnitude
|
||
sExpected = "999.99E-06";
|
||
checkPreviewString(aFormatter, sCode, 0.000999991, eLang, sExpected);
|
||
// expecting rounding into another magnitude
|
||
sExpected = "1.00E-03";
|
||
checkPreviewString(aFormatter, sCode, 0.000999999, eLang, sExpected);
|
||
|
||
// Now the same all negative values.
|
||
sExpected = "-100.00E+00";
|
||
checkPreviewString(aFormatter, sCode, -99.995, eLang, sExpected);
|
||
checkPreviewString(aFormatter, sCode, -100.0, eLang, sExpected);
|
||
sExpected = "-199.99E+00";
|
||
checkPreviewString(aFormatter, sCode, -199.99, eLang, sExpected);
|
||
sExpected = "-1.00E+03";
|
||
checkPreviewString(aFormatter, sCode, -1000.0, eLang, sExpected);
|
||
sExpected = "-894.55E-06";
|
||
checkPreviewString(aFormatter, sCode, -0.000894549, eLang, sExpected);
|
||
sExpected = "-999.99E-06";
|
||
checkPreviewString(aFormatter, sCode, -0.000999991, eLang, sExpected);
|
||
sExpected = "-1.00E-03";
|
||
checkPreviewString(aFormatter, sCode, -0.000999999, eLang, sExpected);
|
||
}
|
||
{ // tdf#112933 one decimal seconds fraction
|
||
sCode = "MM:SS.0";
|
||
sExpected = "23:53.6";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
// Two decimals.
|
||
sCode = "MM:SS.00";
|
||
sExpected = "23:53.61";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
// Three decimals.
|
||
sCode = "MM:SS.000";
|
||
sExpected = "23:53.605";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
|
||
// Same with date+time.
|
||
sCode = "YYYY-MM-DD MM:SS.0";
|
||
sExpected = "1900-01-02 23:53.6";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "YYYY-MM-DD MM:SS.00";
|
||
sExpected = "1900-01-02 23:53.61";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "YYYY-MM-DD MM:SS.000";
|
||
sExpected = "1900-01-02 23:53.605";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
}
|
||
{ // tdf#150028 decimals of seconds fraction without truncate on overflow
|
||
sCode = "[SS]";
|
||
sExpected = "271434";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
// One decimal.
|
||
sCode = "[SS].0";
|
||
sExpected = "271433.6";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
// Two decimals.
|
||
sCode = "[SS].00";
|
||
sExpected = "271433.61";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
// Three decimals.
|
||
sCode = "[SS].000";
|
||
sExpected = "271433.605";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
}
|
||
{ // tdf#156449 Use '?' in exponent of scientific number
|
||
sCode = "0.00E+?0";
|
||
sExpected = OUString::Concat( u"3.14E+"_ustr ) + sBlankDigit + u"0"_ustr; // before change it was "3.14E+00"
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
// There should be at least one '0' in exponent
|
||
sCode = "0.00E+??";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
}
|
||
{ // tdf#33689 use English NfKeywords in non-English language
|
||
eLang = LANGUAGE_DUTCH;
|
||
sExpected = "Dutch: 1900/01/02 03:23:53";
|
||
sCode = "\"Dutch:\" JJJJ/MM/DD UU:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "\"Dutch: \"YYYY/MM/DD HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
eLang = LANGUAGE_GERMAN;
|
||
sExpected = "German: 1900/01/02 03:23:53";
|
||
sCode = "\"German: \"JJJJ/MM/TT HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "\"German: \"YYYY/MM/DD HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
eLang = LANGUAGE_FRENCH;
|
||
sExpected = "French: 1900/01/02 03:23:53";
|
||
sCode = "\"French: \"AAAA/MM/JJ HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "\"French: \"YYYY/MM/DD HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
eLang = LANGUAGE_ITALIAN;
|
||
sExpected = "Italian: 1900/01/02 03:23:53";
|
||
sCode = "\"Italian: \"AAAA/MM/GG HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "\"Italian: \"YYYY/MM/DD HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
eLang = LANGUAGE_PORTUGUESE;
|
||
sExpected = "Portuguese: 1900/01/02 03:23:53";
|
||
sCode = "\"Portuguese: \"AAAA/MM/DD HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "\"Portuguese: \"YYYY/MM/DD HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
eLang = LANGUAGE_SPANISH_MODERN;
|
||
sExpected = "Spanish: 1900/01/02 03:23:53";
|
||
sCode = "\"Spanish: \"AAAA/MM/DD HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "\"Spanish: \"YYYY/MM/DD HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
eLang = LANGUAGE_DANISH;
|
||
sExpected = "Danish: 1900/01/02 03:23:53";
|
||
sCode = "\"Danish: \"YYYY/MM/DD TT:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "\"Danish: \"YYYY/MM/DD HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
eLang = LANGUAGE_FINNISH;
|
||
sExpected = "Finnish: 1900/01/02 03:23:53";
|
||
sCode = "\"Finnish: \"VVVV/KK/PP TT:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
sCode = "\"Finnish: \"YYYY/MM/DD HH:MM:SS";
|
||
checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected);
|
||
}
|
||
{ // tdf#117819 wrong separator positions when displaying integers with
|
||
// more decimals than rtl::math::doubleToUString delivers.
|
||
sCode = "#,##0.00000000000000000000";
|
||
sExpected = "117,669,030,460,994.00000000000000000000";
|
||
checkPreviewString(aFormatter, sCode, 117669030460994.0, LANGUAGE_ENGLISH_US, sExpected);
|
||
}
|
||
{ // tdf#117575 treat thousand separator with '?' in integer part
|
||
sCode = "\"Value= \"?,??0.00";
|
||
sExpected = OUString::Concat( u"Value= "_ustr ) + sBlankDigit + u" "_ustr + sBlankDigit + sBlankDigit + u"3.14"_ustr;
|
||
checkPreviewString(aFormatter, sCode, M_PI, LANGUAGE_ENGLISH_US, sExpected);
|
||
sExpected = OUString::Concat( u"Value= "_ustr ) + sBlankDigit + u" "_ustr + sBlankDigit + u"12.00"_ustr;
|
||
checkPreviewString(aFormatter, sCode, 12, LANGUAGE_ENGLISH_US, sExpected);
|
||
sExpected = OUString::Concat( u"Value= "_ustr ) + sBlankDigit + u" 123.00"_ustr;
|
||
checkPreviewString(aFormatter, sCode, 123, LANGUAGE_ENGLISH_US, sExpected);
|
||
sExpected = "Value= 1,234.00";
|
||
checkPreviewString(aFormatter, sCode, 1234, LANGUAGE_ENGLISH_US, sExpected);
|
||
sExpected = "Value= 12,345.00";
|
||
checkPreviewString(aFormatter, sCode, 12345, LANGUAGE_ENGLISH_US, sExpected);
|
||
}
|
||
{ // tdf#159930 no digit in integer part
|
||
sCode = "+.000;-.000";
|
||
sExpected = "+3.142"; // without the patch is would display "3+.142"
|
||
checkPreviewString(aFormatter, sCode, M_PI, LANGUAGE_ENGLISH_US, sExpected);
|
||
}
|
||
}
|
||
|
||
void Test::testNfEnglishKeywordsIntegrity()
|
||
{
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_ENGLISH_US);
|
||
const NfKeywordTable& rEnglishKeywords = SvNumberFormatter::GetEnglishKeywords();
|
||
const NfKeywordTable& sKeywords = aFormatter.GetKeywords(0);
|
||
CPPUNIT_ASSERT_EQUAL( size_t(NF_KEYWORD_ENTRIES_COUNT), rEnglishKeywords.size() );
|
||
for (size_t i = 0; i < size_t(NF_KEYWORD_ENTRIES_COUNT); ++i)
|
||
{
|
||
CPPUNIT_ASSERT_EQUAL( sKeywords[i], rEnglishKeywords[i] );
|
||
}
|
||
// Check the order of sEnglishKeyword
|
||
CPPUNIT_ASSERT_EQUAL( u"E"_ustr, rEnglishKeywords[NF_KEY_E] );
|
||
CPPUNIT_ASSERT_EQUAL( u"AM/PM"_ustr, rEnglishKeywords[NF_KEY_AMPM] );
|
||
CPPUNIT_ASSERT_EQUAL( u"A/P"_ustr, rEnglishKeywords[NF_KEY_AP] );
|
||
CPPUNIT_ASSERT_EQUAL( u"M"_ustr, rEnglishKeywords[NF_KEY_MI] );
|
||
CPPUNIT_ASSERT_EQUAL( u"MM"_ustr, rEnglishKeywords[NF_KEY_MMI] );
|
||
CPPUNIT_ASSERT_EQUAL( u"M"_ustr, rEnglishKeywords[NF_KEY_M] );
|
||
CPPUNIT_ASSERT_EQUAL( u"MM"_ustr, rEnglishKeywords[NF_KEY_MM] );
|
||
CPPUNIT_ASSERT_EQUAL( u"MMM"_ustr, rEnglishKeywords[NF_KEY_MMM] );
|
||
CPPUNIT_ASSERT_EQUAL( u"MMMM"_ustr, rEnglishKeywords[NF_KEY_MMMM] );
|
||
CPPUNIT_ASSERT_EQUAL( u"H"_ustr, rEnglishKeywords[NF_KEY_H] );
|
||
CPPUNIT_ASSERT_EQUAL( u"HH"_ustr, rEnglishKeywords[NF_KEY_HH] );
|
||
CPPUNIT_ASSERT_EQUAL( u"S"_ustr, rEnglishKeywords[NF_KEY_S] );
|
||
CPPUNIT_ASSERT_EQUAL( u"SS"_ustr, rEnglishKeywords[NF_KEY_SS] );
|
||
CPPUNIT_ASSERT_EQUAL( u"Q"_ustr, rEnglishKeywords[NF_KEY_Q] );
|
||
CPPUNIT_ASSERT_EQUAL( u"QQ"_ustr, rEnglishKeywords[NF_KEY_QQ] );
|
||
CPPUNIT_ASSERT_EQUAL( u"D"_ustr, rEnglishKeywords[NF_KEY_D] );
|
||
CPPUNIT_ASSERT_EQUAL( u"DD"_ustr, rEnglishKeywords[NF_KEY_DD] );
|
||
CPPUNIT_ASSERT_EQUAL( u"DDD"_ustr, rEnglishKeywords[NF_KEY_DDD] );
|
||
CPPUNIT_ASSERT_EQUAL( u"DDDD"_ustr, rEnglishKeywords[NF_KEY_DDDD] );
|
||
CPPUNIT_ASSERT_EQUAL( u"YY"_ustr, rEnglishKeywords[NF_KEY_YY] );
|
||
CPPUNIT_ASSERT_EQUAL( u"YYYY"_ustr, rEnglishKeywords[NF_KEY_YYYY] );
|
||
CPPUNIT_ASSERT_EQUAL( u"NN"_ustr, rEnglishKeywords[NF_KEY_NN] );
|
||
CPPUNIT_ASSERT_EQUAL( u"NNNN"_ustr, rEnglishKeywords[NF_KEY_NNNN] );
|
||
CPPUNIT_ASSERT_EQUAL( u"CCC"_ustr, rEnglishKeywords[NF_KEY_CCC] );
|
||
CPPUNIT_ASSERT_EQUAL( u"GENERAL"_ustr, rEnglishKeywords[NF_KEY_GENERAL] );
|
||
CPPUNIT_ASSERT_EQUAL( u"NNN"_ustr, rEnglishKeywords[NF_KEY_NNN] );
|
||
CPPUNIT_ASSERT_EQUAL( u"WW"_ustr, rEnglishKeywords[NF_KEY_WW] );
|
||
CPPUNIT_ASSERT_EQUAL( u"MMMMM"_ustr, rEnglishKeywords[NF_KEY_MMMMM] );
|
||
CPPUNIT_ASSERT_EQUAL( u"TRUE"_ustr, rEnglishKeywords[NF_KEY_TRUE] );
|
||
CPPUNIT_ASSERT_EQUAL( u"FALSE"_ustr, rEnglishKeywords[NF_KEY_FALSE] );
|
||
CPPUNIT_ASSERT_EQUAL( u"BOOLEAN"_ustr, rEnglishKeywords[NF_KEY_BOOLEAN] );
|
||
CPPUNIT_ASSERT_EQUAL( u"COLOR"_ustr, rEnglishKeywords[NF_KEY_COLOR] );
|
||
CPPUNIT_ASSERT_EQUAL( u"BLACK"_ustr, rEnglishKeywords[NF_KEY_BLACK] );
|
||
CPPUNIT_ASSERT_EQUAL( u"BLUE"_ustr, rEnglishKeywords[NF_KEY_BLUE] );
|
||
CPPUNIT_ASSERT_EQUAL( u"GREEN"_ustr, rEnglishKeywords[NF_KEY_GREEN] );
|
||
CPPUNIT_ASSERT_EQUAL( u"CYAN"_ustr, rEnglishKeywords[NF_KEY_CYAN] );
|
||
CPPUNIT_ASSERT_EQUAL( u"RED"_ustr, rEnglishKeywords[NF_KEY_RED] );
|
||
CPPUNIT_ASSERT_EQUAL( u"MAGENTA"_ustr, rEnglishKeywords[NF_KEY_MAGENTA] );
|
||
CPPUNIT_ASSERT_EQUAL( u"BROWN"_ustr, rEnglishKeywords[NF_KEY_BROWN] );
|
||
CPPUNIT_ASSERT_EQUAL( u"GREY"_ustr, rEnglishKeywords[NF_KEY_GREY] );
|
||
CPPUNIT_ASSERT_EQUAL( u"YELLOW"_ustr, rEnglishKeywords[NF_KEY_YELLOW] );
|
||
CPPUNIT_ASSERT_EQUAL( u"WHITE"_ustr, rEnglishKeywords[NF_KEY_WHITE] );
|
||
CPPUNIT_ASSERT_EQUAL( u"AAA"_ustr, rEnglishKeywords[NF_KEY_AAA]);
|
||
CPPUNIT_ASSERT_EQUAL( u"AAAA"_ustr, rEnglishKeywords[NF_KEY_AAAA] );
|
||
CPPUNIT_ASSERT_EQUAL( u"E"_ustr, rEnglishKeywords[NF_KEY_EC] );
|
||
CPPUNIT_ASSERT_EQUAL( u"EE"_ustr, rEnglishKeywords[NF_KEY_EEC] );
|
||
CPPUNIT_ASSERT_EQUAL( u"G"_ustr, rEnglishKeywords[NF_KEY_G] );
|
||
CPPUNIT_ASSERT_EQUAL( u"GG"_ustr, rEnglishKeywords[NF_KEY_GG] );
|
||
CPPUNIT_ASSERT_EQUAL( u"GGG"_ustr, rEnglishKeywords[NF_KEY_GGG] );
|
||
CPPUNIT_ASSERT_EQUAL( u"R"_ustr, rEnglishKeywords[NF_KEY_R] );
|
||
CPPUNIT_ASSERT_EQUAL( u"RR"_ustr, rEnglishKeywords[NF_KEY_RR] );
|
||
CPPUNIT_ASSERT_EQUAL( u"t"_ustr, rEnglishKeywords[NF_KEY_THAI_T] );
|
||
}
|
||
|
||
void Test::testStandardColorIntegrity()
|
||
{
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_ENGLISH_US);
|
||
const ::std::vector<Color> & rStandardColors = SvNumberFormatter::GetStandardColors();
|
||
const size_t nMaxDefaultColors = SvNumberFormatter::GetMaxDefaultColors();
|
||
CPPUNIT_ASSERT_EQUAL( size_t(NF_KEY_LASTCOLOR) - size_t(NF_KEY_FIRSTCOLOR) + 1, nMaxDefaultColors );
|
||
CPPUNIT_ASSERT_EQUAL( nMaxDefaultColors, rStandardColors.size() );
|
||
// Colors must follow same order as in sEnglishKeyword
|
||
CPPUNIT_ASSERT_EQUAL( COL_BLACK, rStandardColors[0] );
|
||
CPPUNIT_ASSERT_EQUAL( COL_LIGHTBLUE, rStandardColors[1] );
|
||
CPPUNIT_ASSERT_EQUAL( COL_LIGHTGREEN, rStandardColors[2] );
|
||
CPPUNIT_ASSERT_EQUAL( COL_LIGHTCYAN, rStandardColors[3] );
|
||
CPPUNIT_ASSERT_EQUAL( COL_LIGHTRED, rStandardColors[4] );
|
||
CPPUNIT_ASSERT_EQUAL( COL_LIGHTMAGENTA, rStandardColors[5] );
|
||
CPPUNIT_ASSERT_EQUAL( COL_BROWN, rStandardColors[6] );
|
||
CPPUNIT_ASSERT_EQUAL( COL_GRAY, rStandardColors[7] );
|
||
CPPUNIT_ASSERT_EQUAL( COL_YELLOW, rStandardColors[8] );
|
||
CPPUNIT_ASSERT_EQUAL( COL_WHITE, rStandardColors[9] );
|
||
}
|
||
|
||
void Test::testColorNamesConversion()
|
||
{
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_GERMAN);
|
||
const NfKeywordTable& rEnglishKeywords = SvNumberFormatter::GetEnglishKeywords();
|
||
const NfKeywordTable& rKeywords = aFormatter.GetKeywords(0);
|
||
|
||
// Holding a reference to the NfKeywordTable doesn't help if we switch
|
||
// locales internally, so copy the relevant parts in advance.
|
||
std::vector<OUString> aGermanKeywords(NF_KEYWORD_ENTRIES_COUNT);
|
||
for (size_t i = NF_KEY_COLOR; i <= NF_KEY_WHITE; ++i)
|
||
aGermanKeywords[i] = rKeywords[i];
|
||
|
||
// Check that we actually have German and English keywords.
|
||
CPPUNIT_ASSERT_EQUAL( u"FARBE"_ustr, aGermanKeywords[NF_KEY_COLOR]);
|
||
CPPUNIT_ASSERT_EQUAL( u"COLOR"_ustr, rEnglishKeywords[NF_KEY_COLOR]);
|
||
|
||
// Test each color conversion.
|
||
// [FARBE1] -> [COLOR1] can't be tested because we have no color table link
|
||
// set, so the scanner returns nCheckPos error.
|
||
sal_Int32 nCheckPos;
|
||
SvNumFormatType nType;
|
||
sal_uInt32 nKey;
|
||
OUString aFormatCode;
|
||
|
||
for (size_t i = NF_KEY_BLACK; i <= NF_KEY_WHITE; ++i)
|
||
{
|
||
aFormatCode = "[" + aGermanKeywords[i] + "]0";
|
||
aFormatter.PutandConvertEntry( aFormatCode, nCheckPos, nType, nKey, LANGUAGE_GERMAN, LANGUAGE_ENGLISH_US, false);
|
||
CPPUNIT_ASSERT_EQUAL_MESSAGE("CheckPos should be 0.", sal_Int32(0), nCheckPos);
|
||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Type should be NUMBER.", SvNumFormatType::NUMBER, nType);
|
||
CPPUNIT_ASSERT_EQUAL( OUString("[" + rEnglishKeywords[i] + "]0"), aFormatCode);
|
||
}
|
||
}
|
||
|
||
void Test::testExcelExportFormats()
|
||
{
|
||
// Create a formatter with "system" locale other than the specific formats'
|
||
// locale, and different from the en-US export locale.
|
||
SvNumberFormatter aFormatter( m_xContext, LANGUAGE_ENGLISH_UK);
|
||
|
||
OUString aCode;
|
||
sal_Int32 nCheckPos;
|
||
SvNumFormatType eType;
|
||
sal_uInt32 nKey1, nKey2;
|
||
|
||
aCode = "00.00";
|
||
aFormatter.PutandConvertEntry( aCode, nCheckPos, eType, nKey1,
|
||
LANGUAGE_ENGLISH_US, LANGUAGE_ENGLISH_SAFRICA, false);
|
||
CPPUNIT_ASSERT_EQUAL_MESSAGE("CheckPos should be 0.", sal_Int32(0), nCheckPos);
|
||
CPPUNIT_ASSERT_MESSAGE("Key should be greater than system locale's keys.",
|
||
nKey1 > SV_COUNTRY_LANGUAGE_OFFSET);
|
||
|
||
aCode = "[$R-1C09] #,##0.0;[$R-1C09]-#,##0.0";
|
||
aFormatter.PutandConvertEntry( aCode, nCheckPos, eType, nKey2,
|
||
LANGUAGE_ENGLISH_US, LANGUAGE_ENGLISH_SAFRICA, false);
|
||
CPPUNIT_ASSERT_EQUAL_MESSAGE("CheckPos should be 0.", sal_Int32(0), nCheckPos);
|
||
CPPUNIT_ASSERT_MESSAGE("Key should be greater than system locale's keys.",
|
||
nKey2 > SV_COUNTRY_LANGUAGE_OFFSET);
|
||
|
||
// The export formatter.
|
||
SvNumberFormatter aTempFormatter( m_xContext, LANGUAGE_ENGLISH_US);
|
||
NfKeywordTable aKeywords;
|
||
aTempFormatter.FillKeywordTableForExcel( aKeywords);
|
||
|
||
aCode = aFormatter.GetFormatStringForExcel( nKey1, aKeywords, aTempFormatter);
|
||
// Test that LCID is prepended.
|
||
CPPUNIT_ASSERT_EQUAL( u"[$-1C09]00.00"_ustr, aCode);
|
||
|
||
aCode = aFormatter.GetFormatStringForExcel( nKey2, aKeywords, aTempFormatter);
|
||
// Test that LCID is not prepended. Note that literal characters are escaped.
|
||
CPPUNIT_ASSERT_EQUAL( u"[$R-1C09]\\ #,##0.0;[$R-1C09]\\-#,##0.0"_ustr, aCode);
|
||
}
|
||
|
||
CPPUNIT_TEST_FIXTURE(Test, testLanguageNone)
|
||
{
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_ENGLISH_US);
|
||
NfKeywordTable keywords;
|
||
aFormatter.FillKeywordTableForExcel(keywords);
|
||
OUString code(u"TT.MM.JJJJ"_ustr);
|
||
sal_uInt32 nKey = aFormatter.GetEntryKey(code, LANGUAGE_GERMAN);
|
||
CPPUNIT_ASSERT(nKey != NUMBERFORMAT_ENTRY_NOT_FOUND);
|
||
SvNumberformat const*const pFormat = aFormatter.GetEntry(nKey);
|
||
LocaleDataWrapper ldw(m_xContext, LanguageTag(pFormat->GetLanguage()));
|
||
CPPUNIT_ASSERT_EQUAL(u"dd.mm.yyyy"_ustr, pFormat->GetMappedFormatstring(keywords, ldw));
|
||
}
|
||
|
||
CPPUNIT_TEST_FIXTURE(Test, testTdf160306)
|
||
{
|
||
// Check some cases, where the output of ROUND and of number formatter differed
|
||
SvNumberFormatter aFormatter(m_xContext, LANGUAGE_ENGLISH_US);
|
||
sal_uInt32 format = aFormatter.GetEntryKey(u"0.00", LANGUAGE_ENGLISH_US);
|
||
CPPUNIT_ASSERT(format != NUMBERFORMAT_ENTRY_NOT_FOUND);
|
||
OUString output;
|
||
const Color* color;
|
||
aFormatter.GetOutputString(2697.0649999999996, format, output, &color);
|
||
// Without the fix in place, this would fail with
|
||
// - Expected: 2697.07
|
||
// - Actual : 2697.06
|
||
CPPUNIT_ASSERT_EQUAL(u"2697.07"_ustr, output);
|
||
aFormatter.GetOutputString(57.374999999999993, format, output, &color);
|
||
// Without the fix in place, this would fail with
|
||
// - Expected: 57.38
|
||
// - Actual : 57.37
|
||
CPPUNIT_ASSERT_EQUAL(u"57.38"_ustr, output);
|
||
}
|
||
|
||
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
|
||
|
||
}
|
||
|
||
CPPUNIT_PLUGIN_IMPLEMENT();
|
||
|
||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|