diff options
Diffstat (limited to 'Build/source/libs/icu/icu-src/source/test')
59 files changed, 1839 insertions, 1191 deletions
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/ccaltst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/ccaltst.c index 7f03cb16a6e..205e9fbda44 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/ccaltst.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/ccaltst.c @@ -111,7 +111,7 @@ static void TestCalendar() UDateFormat *datdef = 0; UChar *result = 0; int32_t resultlength, resultlengthneeded; - char tempMsgBuf[256]; + char tempMsgBuf[1024]; // u_austrcpy() of some formatted dates & times. UChar zone1[32], zone2[32]; const char *tzver = 0; UChar canonicalID[64]; diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cintltst.vcxproj b/Build/source/libs/icu/icu-src/source/test/cintltst/cintltst.vcxproj index 8b926f3c1f3..f64f9d20048 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/cintltst.vcxproj +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cintltst.vcxproj @@ -1,51 +1,16 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> + <!-- The following import will include the 'default' configuration options for VS projects. --> + <Import Project="..\..\allinone\Build.Windows.ProjectConfiguration.props" /> + <PropertyGroup Label="Globals"> <ProjectGuid>{3D1246AE-1B32-479B-BECA-AEFA97BE2321}</ProjectGuid> - <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - <CharacterSet>MultiByte</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <PropertyGroup Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseOfMfc>false</UseOfMfc> <CharacterSet>MultiByte</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - <CharacterSet>MultiByte</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - <CharacterSet>MultiByte</CharacterSet> - <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -82,38 +47,33 @@ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</IntDir> <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> </PropertyGroup> + <!-- Options that are common to *all* project configurations --> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>..\..\..\include;..\..\tools\ctestfw;..\..\common;..\..\i18n;..\..\tools\toolutil;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableLanguageExtensions>false</DisableLanguageExtensions> + <WarningLevel>Level3</WarningLevel> + </ClCompile> + </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <Midl> <TypeLibraryName>.\x86\Debug/cintltst.tlb</TypeLibraryName> </Midl> <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>..\..\..\include;..\..\tools\ctestfw;..\..\common;..\..\i18n;..\..\tools\toolutil;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <BufferSecurityCheck>true</BufferSecurityCheck> - <DisableLanguageExtensions>false</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <PrecompiledHeaderOutputFile>.\x86\Debug/cintltst.pch</PrecompiledHeaderOutputFile> <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation> <ObjectFileName>.\x86\Debug/</ObjectFileName> <ProgramDataBaseFileName>.\x86\Debug/</ProgramDataBaseFileName> <BrowseInformation>true</BrowseInformation> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> <DebugInformationFormat>EditAndContinue</DebugInformationFormat> <CompileAs>Default</CompileAs> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> <Link> <OutputFile>.\x86\Debug/cintltst.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>icuucd.lib;icuind.lib;icutestd.lib;icutud.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>..\..\..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <ProgramDatabaseFile>.\x86\Debug/cintltst.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> <RandomizedBaseAddress>false</RandomizedBaseAddress> @@ -127,30 +87,19 @@ <TypeLibraryName>.\x86\Release/cintltst.tlb</TypeLibraryName> </Midl> <ClCompile> - <AdditionalIncludeDirectories>..\..\..\include;..\..\tools\ctestfw;..\..\common;..\..\i18n;..\..\tools\toolutil;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <StringPooling>true</StringPooling> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <BufferSecurityCheck>true</BufferSecurityCheck> <FunctionLevelLinking>true</FunctionLevelLinking> - <DisableLanguageExtensions>false</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <PrecompiledHeaderOutputFile>.\x86\Release/cintltst.pch</PrecompiledHeaderOutputFile> <AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation> <ObjectFileName>.\x86\Release/</ObjectFileName> <ProgramDataBaseFileName>.\x86\Release/</ProgramDataBaseFileName> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> <CompileAs>Default</CompileAs> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> <Link> <OutputFile>.\x86\Release/cintltst.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalDependencies>icuuc.lib;icuin.lib;icutest.lib;icutu.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>..\..\..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <GenerateDebugInformation>true</GenerateDebugInformation> <ProgramDatabaseFile>.\x86\Release/cintltst.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> @@ -161,77 +110,48 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <Midl> - <TargetEnvironment>X64</TargetEnvironment> <TypeLibraryName>.\x64\Debug/cintltst.tlb</TypeLibraryName> </Midl> <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>..\..\..\include;..\..\tools\ctestfw;..\..\common;..\..\i18n;..\..\tools\toolutil;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN64;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <BufferSecurityCheck>true</BufferSecurityCheck> - <DisableLanguageExtensions>false</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <PrecompiledHeaderOutputFile>.\x64\Debug/cintltst.pch</PrecompiledHeaderOutputFile> <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation> <ObjectFileName>.\x64\Debug/</ObjectFileName> <ProgramDataBaseFileName>.\x64\Debug/</ProgramDataBaseFileName> <BrowseInformation>true</BrowseInformation> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <CompileAs>Default</CompileAs> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> <Link> <OutputFile>.\x64\Debug/cintltst.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>icuucd.lib;icuind.lib;icutestd.lib;icutud.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>..\..\..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <ProgramDatabaseFile>.\x64\Debug/cintltst.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> - <TargetMachine>MachineX64</TargetMachine> <FixedBaseAddress>false</FixedBaseAddress> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <Midl> - <TargetEnvironment>X64</TargetEnvironment> <TypeLibraryName>.\x64\Release/cintltst.tlb</TypeLibraryName> </Midl> <ClCompile> - <AdditionalIncludeDirectories>..\..\..\include;..\..\tools\ctestfw;..\..\common;..\..\i18n;..\..\tools\toolutil;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <StringPooling>true</StringPooling> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <BufferSecurityCheck>true</BufferSecurityCheck> <FunctionLevelLinking>true</FunctionLevelLinking> - <DisableLanguageExtensions>false</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <PrecompiledHeaderOutputFile>.\x64\Release/cintltst.pch</PrecompiledHeaderOutputFile> <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation> <ObjectFileName>.\x64\Release/</ObjectFileName> <ProgramDataBaseFileName>.\x64\Release/</ProgramDataBaseFileName> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> <CompileAs>Default</CompileAs> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> <Link> <OutputFile>.\x64\Release/cintltst.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalDependencies>icuuc.lib;icuin.lib;icutest.lib;icutu.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>..\..\..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <GenerateDebugInformation>true</GenerateDebugInformation> <ProgramDatabaseFile>.\x64\Release/cintltst.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> - <TargetMachine>MachineX64</TargetMachine> </Link> </ItemDefinitionGroup> <ItemGroup> @@ -255,10 +175,7 @@ <ClCompile Include="cturtst.c" /> <ClCompile Include="encoll.c" /> <ClCompile Include="usrchdat.c"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="usrchtst.c" /> <ClCompile Include="chashtst.c" /> @@ -278,8 +195,7 @@ <ClCompile Include="stdnmtst.c" /> <ClCompile Include="ucnvseltst.c" /> <ClCompile Include="ucsdetst.c" /> - <ClCompile Include="udatatst.c"> - </ClCompile> + <ClCompile Include="udatatst.c"/> <ClCompile Include="ccaltst.c" /> <ClCompile Include="cdateintervalformattest.c" /> <ClCompile Include="cdattst.c" /> @@ -364,25 +280,7 @@ <ClInclude Include="cucdapi.h" /> <ClInclude Include="nfsprep.h" /> </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\..\common\common.vcxproj"> - <Project>{73c0a65b-d1f2-4de1-b3a6-15dad2c23f3d}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="..\..\i18n\i18n.vcxproj"> - <Project>{0178b127-6269-407d-b112-93877bb62776}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="..\..\tools\ctestfw\ctestfw.vcxproj"> - <Project>{eca6b435-b4fa-4f9f-bf95-f451d078fc47}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="..\..\tools\toolutil\toolutil.vcxproj"> - <Project>{6b231032-3cb5-4eed-9210-810d666a23a0}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> +</Project>
\ No newline at end of file diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cnumtst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cnumtst.c index e2cd68abae1..d11cca78b3e 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/cnumtst.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cnumtst.c @@ -2372,7 +2372,7 @@ static const NumSysTestItem numSysTestItems[] = { { "en", "latn", 10, FALSE, latnDesc }, { "en@numbers=roman", "roman", 10, TRUE, romanDesc }, { "en@numbers=finance", "latn", 10, FALSE, latnDesc }, - { "ar", "arab", 10, FALSE, arabDesc }, + { "ar-EG", "arab", 10, FALSE, arabDesc }, { "fa", "arabext", 10, FALSE, arabextDesc }, { "zh_Hans@numbers=hanidec", "hanidec", 10, FALSE, hanidecDesc }, { "zh_Hant@numbers=traditional", "hant", 10, TRUE, hantDesc }, diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/creststn.c b/Build/source/libs/icu/icu-src/source/test/cintltst/creststn.c index 48717c10653..098cd46e472 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/creststn.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/creststn.c @@ -2129,7 +2129,7 @@ static void TestFallback() UResourceBundle* tResB; UResourceBundle* zoneResource; const UChar* version = NULL; - static const UChar versionStr[] = { 0x0032, 0x002E, 0x0031, 0x002E, 0x0033, 0x0031, 0x002E, 0x0033, 0x0033, 0x0000}; // 2.1.31.33 in nn_NO + static const UChar versionStr[] = { 0x0032, 0x002E, 0x0031, 0x002E, 0x0033, 0x0038, 0x002E, 0x0036, 0x0039, 0x0000}; // 2.1.38.69 in nn_NO if(err != U_ZERO_ERROR){ log_data_err("Expected U_ZERO_ERROR when trying to test no_NO_NY aliased to nn_NO for Version err=%s\n",u_errorName(err)); diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cucdtst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cucdtst.c index 788aa803757..67b53a62e0f 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/cucdtst.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cucdtst.c @@ -60,7 +60,6 @@ static void TestNumericProperties(void); static void TestPropertyNames(void); static void TestPropertyValues(void); static void TestConsistency(void); -static void TestUBiDiProps(void); static void TestCaseFolding(void); /* internal methods used */ @@ -196,7 +195,6 @@ void addUnicodeTest(TestNode** root) addTest(root, &TestPropertyNames, "tsutil/cucdtst/TestPropertyNames"); addTest(root, &TestPropertyValues, "tsutil/cucdtst/TestPropertyValues"); addTest(root, &TestConsistency, "tsutil/cucdtst/TestConsistency"); - addTest(root, &TestUBiDiProps, "tsutil/cucdtst/TestUBiDiProps"); addTest(root, &TestCaseFolding, "tsutil/cucdtst/TestCaseFolding"); } @@ -3302,59 +3300,6 @@ TestConsistency() { uset_close(set2); } -/* - * Starting with ICU4C 3.4, the core Unicode properties files - * (uprops.icu, ucase.icu, ubidi.icu, unorm.icu) - * are hardcoded in the common DLL and therefore not included - * in the data package any more. - * Test requiring these files are disabled so that - * we need not jump through hoops (like adding snapshots of these files - * to testdata). - * See Jitterbug 4497. - */ -#define HARDCODED_DATA_4497 1 - -/* API coverage for ubidi_props.c */ -static void TestUBiDiProps() { -#if !HARDCODED_DATA_4497 - UDataMemory *pData; - UBiDiProps *bdp; - const UBiDiProps *cbdp; - UErrorCode errorCode; - - /* coverage for ubidi_openBinary() */ - errorCode=U_ZERO_ERROR; - pData=udata_open(NULL, UBIDI_DATA_TYPE, UBIDI_DATA_NAME, &errorCode); - if(U_FAILURE(errorCode)) { - log_data_err("unable to open " UBIDI_DATA_NAME "." UBIDI_DATA_TYPE ": %s\n", - u_errorName(errorCode)); - return; - } - - bdp=ubidi_openBinary((const uint8_t *)pData->pHeader, -1, &errorCode); - if(U_FAILURE(errorCode)) { - log_err("ubidi_openBinary() fails for the contents of " UBIDI_DATA_NAME "." UBIDI_DATA_TYPE ": %s\n", - u_errorName(errorCode)); - udata_close(pData); - return; - } - - if(0x2215!=ubidi_getMirror(bdp, 0x29F5)) { /* verify some data */ - log_err("ubidi_openBinary() does not seem to return working UBiDiProps\n"); - } - - ubidi_closeProps(bdp); - udata_close(pData); - - /* coverage for ubidi_getDummy() */ - errorCode=U_ZERO_ERROR; - cbdp=ubidi_getDummy(&errorCode); - if(ubidi_getClass(cbdp, 0x20)!=0) { - log_err("ubidi_getClass(dummy, space)!=0\n"); - } -#endif -} - /* test case folding, compare return values with CaseFolding.txt ------------ */ /* bit set for which case foldings for a character have been tested already */ diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/udatpg_test.c b/Build/source/libs/icu/icu-src/source/test/cintltst/udatpg_test.c index 8895c508acc..2338a2f687f 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/udatpg_test.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/udatpg_test.c @@ -42,12 +42,14 @@ static void TestOpenClose(void); static void TestUsage(void); static void TestBuilder(void); static void TestOptions(void); +static void TestGetFieldDisplayNames(void); void addDateTimePatternGeneratorTest(TestNode** root) { TESTCASE(TestOpenClose); TESTCASE(TestUsage); TESTCASE(TestBuilder); TESTCASE(TestOptions); + TESTCASE(TestGetFieldDisplayNames); } /* @@ -438,4 +440,74 @@ static void TestOptions() { } } +typedef struct FieldDisplayNameData { + const char * locale; + UDateTimePatternField field; + UDateTimePGDisplayWidth width; + const char * expected; +} FieldDisplayNameData; +enum { kFieldDisplayNameMax = 32, kFieldDisplayNameBytesMax = 64}; + +static void TestGetFieldDisplayNames() { + const FieldDisplayNameData testData[] = { + /*loc field width expectedName */ + { "de", UDATPG_QUARTER_FIELD, UDATPG_WIDE, "Quartal" }, + { "de", UDATPG_QUARTER_FIELD, UDATPG_ABBREVIATED, "Quart." }, + { "de", UDATPG_QUARTER_FIELD, UDATPG_NARROW, "Q" }, + { "en", UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD, UDATPG_WIDE, "weekday of the month" }, + { "en", UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD, UDATPG_ABBREVIATED, "wkday. of mo." }, + { "en", UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD, UDATPG_NARROW, "wkday. of mo." }, // fallback + { "en_GB", UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD, UDATPG_WIDE, "weekday of the month" }, + { "en_GB", UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD, UDATPG_ABBREVIATED, "wkday of mo" }, // override + { "en_GB", UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD, UDATPG_NARROW, "wkday of mo" }, + { "it", UDATPG_SECOND_FIELD, UDATPG_WIDE, "secondo" }, + { "it", UDATPG_SECOND_FIELD, UDATPG_ABBREVIATED, "s" }, + { "it", UDATPG_SECOND_FIELD, UDATPG_NARROW, "s" }, + }; + + int count = UPRV_LENGTHOF(testData); + const FieldDisplayNameData * testDataPtr = testData; + for (; count-- > 0; ++testDataPtr) { + UErrorCode status = U_ZERO_ERROR; + UDateTimePatternGenerator * dtpgen = udatpg_open(testDataPtr->locale, &status); + if ( U_FAILURE(status) ) { + log_data_err("ERROR udatpg_open failed for locale %s : %s - (Are you missing data?)\n", testDataPtr->locale, myErrorName(status)); + } else { + UChar expName[kFieldDisplayNameMax]; + UChar getName[kFieldDisplayNameMax]; + u_unescape(testDataPtr->expected, expName, kFieldDisplayNameMax); + + int32_t getLen = udatpg_getFieldDisplayName(dtpgen, testDataPtr->field, testDataPtr->width, + getName, kFieldDisplayNameMax, &status); + if ( U_FAILURE(status) ) { + log_err("ERROR udatpg_getFieldDisplayName locale %s field %d width %d, got status %s, len %d\n", + testDataPtr->locale, testDataPtr->field, testDataPtr->width, u_errorName(status), getLen); + } else if ( u_strncmp(expName, getName, kFieldDisplayNameMax) != 0 ) { + char expNameB[kFieldDisplayNameBytesMax]; + char getNameB[kFieldDisplayNameBytesMax]; + log_err("ERROR udatpg_getFieldDisplayName locale %s field %d width %d, expected %s, got %s, status %s\n", + testDataPtr->locale, testDataPtr->field, testDataPtr->width, + u_austrncpy(expNameB,expName,kFieldDisplayNameBytesMax), + u_austrncpy(getNameB,getName,kFieldDisplayNameBytesMax), u_errorName(status) ); + } else if (testDataPtr->width == UDATPG_WIDE && getLen > 1) { + // test preflight & inadequate buffer + int32_t getNewLen; + status = U_ZERO_ERROR; + getNewLen = udatpg_getFieldDisplayName(dtpgen, testDataPtr->field, UDATPG_WIDE, NULL, 0, &status); + if (U_FAILURE(status) || getNewLen != getLen) { + log_err("ERROR udatpg_getFieldDisplayName locale %s field %d width %d, preflight expected len %d, got %d, status %s\n", + testDataPtr->locale, testDataPtr->field, testDataPtr->width, getLen, getNewLen, u_errorName(status) ); + } + status = U_ZERO_ERROR; + getNewLen = udatpg_getFieldDisplayName(dtpgen, testDataPtr->field, UDATPG_WIDE, getName, getLen-1, &status); + if (status!=U_BUFFER_OVERFLOW_ERROR || getNewLen != getLen) { + log_err("ERROR udatpg_getFieldDisplayName locale %s field %d width %d, overflow expected len %d & BUFFER_OVERFLOW_ERROR, got %d & status %s\n", + testDataPtr->locale, testDataPtr->field, testDataPtr->width, getLen, getNewLen, u_errorName(status) ); + } + } + udatpg_close(dtpgen); + } + } +} + #endif diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/uregiontest.c b/Build/source/libs/icu/icu-src/source/test/cintltst/uregiontest.c index cefbfde4a15..fb8690db91a 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/uregiontest.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/uregiontest.c @@ -122,12 +122,12 @@ static KnownRegion knownRegions[] = { { "BS" , 44, "029", URGN_TERRITORY, "019" }, { "BT" , 64, "034", URGN_TERRITORY, "142" }, { "BU" , 104, "035", URGN_TERRITORY, "142" }, - { "BV" , 74, "QO" , URGN_TERRITORY, "009" }, + { "BV" , 74, "005", URGN_TERRITORY, "019" }, { "BW" , 72, "018", URGN_TERRITORY, "002" }, { "BY" , 112, "151", URGN_TERRITORY, "150" }, { "BZ" , 84, "013", URGN_TERRITORY, "019" }, { "CA" , 124, "021", URGN_TERRITORY, "019" }, - { "CC" , 166, "QO" , URGN_TERRITORY, "009" }, + { "CC" , 166, "053", URGN_TERRITORY, "009" }, { "CD" , 180, "017", URGN_TERRITORY, "002" }, { "CF" , 140, "017", URGN_TERRITORY, "002" }, { "CG" , 178, "017", URGN_TERRITORY, "002" }, @@ -143,7 +143,7 @@ static KnownRegion knownRegions[] = { { "CU" , 192, "029", URGN_TERRITORY, "019" }, { "CV" , 132, "011", URGN_TERRITORY, "002" }, { "CW" , 531, "029", URGN_TERRITORY, "019" }, - { "CX" , 162, "QO" , URGN_TERRITORY, "009" }, + { "CX" , 162, "053", URGN_TERRITORY, "009" }, { "CY" , 196, "145", URGN_TERRITORY, "142" }, { "CZ" , 203, "151", URGN_TERRITORY, "150" }, { "DD" , 276, "155", URGN_TERRITORY, "150" }, @@ -184,13 +184,13 @@ static KnownRegion knownRegions[] = { { "GP" , 312, "029", URGN_TERRITORY, "019" }, { "GQ" , 226, "017", URGN_TERRITORY, "002" }, { "GR" , 300, "039", URGN_TERRITORY, "150" }, - { "GS" , 239, "QO" , URGN_TERRITORY, "009" }, + { "GS" , 239, "005", URGN_TERRITORY, "019" }, { "GT" , 320, "013", URGN_TERRITORY, "019" }, { "GU" , 316, "057", URGN_TERRITORY, "009" }, { "GW" , 624, "011", URGN_TERRITORY, "002" }, { "GY" , 328, "005", URGN_TERRITORY, "019" }, { "HK" , 344, "030", URGN_TERRITORY, "142" }, - { "HM" , 334, "QO" , URGN_TERRITORY, "009" }, + { "HM" , 334, "053", URGN_TERRITORY, "009" }, { "HN" , 340, "013", URGN_TERRITORY, "019" }, { "HR" , 191, "039", URGN_TERRITORY, "150" }, { "HT" , 332, "029", URGN_TERRITORY, "019" }, @@ -201,7 +201,7 @@ static KnownRegion knownRegions[] = { { "IL" , 376, "145", URGN_TERRITORY, "142" }, { "IM" , 833, "154", URGN_TERRITORY, "150" }, { "IN" , 356, "034", URGN_TERRITORY, "142" }, - { "IO" , 86, "QO" , URGN_TERRITORY, "009" }, + { "IO" , 86, "014", URGN_TERRITORY, "002" }, { "IQ" , 368, "145", URGN_TERRITORY, "142" }, { "IR" , 364, "034", URGN_TERRITORY, "142" }, { "IS" , 352, "154", URGN_TERRITORY, "150" }, @@ -316,7 +316,7 @@ static KnownRegion knownRegions[] = { { "TA" , -1, "QO", URGN_TERRITORY, "009" }, { "TC" , 796, "029", URGN_TERRITORY, "019" }, { "TD" , 148, "017", URGN_TERRITORY, "002" }, - { "TF" , 260, "QO" , URGN_TERRITORY, "009" }, + { "TF" , 260, "145", URGN_TERRITORY, "142" }, { "TG" , 768, "011", URGN_TERRITORY, "002" }, { "TH" , 764, "035", URGN_TERRITORY, "142" }, { "TJ" , 762, "143", URGN_TERRITORY, "142" }, @@ -333,7 +333,7 @@ static KnownRegion knownRegions[] = { { "TZ" , 834, "014", URGN_TERRITORY, "002" }, { "UA" , 804, "151", URGN_TERRITORY, "150" }, { "UG" , 800, "014", URGN_TERRITORY, "002" }, - { "UM" , 581, "QO" , URGN_TERRITORY, "009" }, + { "UM" , 581, "057", URGN_TERRITORY, "009" }, { "US" , 840, "021", URGN_TERRITORY, "019" }, { "UY" , 858, "005", URGN_TERRITORY, "019" }, { "UZ" , 860, "143", URGN_TERRITORY, "142" }, diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/utf8tst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/utf8tst.c index 0bbb5e5413d..9f4109c2078 100644 --- a/Build/source/libs/icu/icu-src/source/test/cintltst/utf8tst.c +++ b/Build/source/libs/icu/icu-src/source/test/cintltst/utf8tst.c @@ -94,6 +94,7 @@ static void TestFwdBack(void); static void TestFwdBackUnsafe(void); static void TestSetChar(void); static void TestSetCharUnsafe(void); +static void TestTruncateIfIncomplete(void); static void TestAppendChar(void); static void TestAppend(void); static void TestSurrogates(void); @@ -114,6 +115,7 @@ addUTF8Test(TestNode** root) addTest(root, &TestFwdBackUnsafe, "utf8tst/TestFwdBackUnsafe"); addTest(root, &TestSetChar, "utf8tst/TestSetChar"); addTest(root, &TestSetCharUnsafe, "utf8tst/TestSetCharUnsafe"); + addTest(root, &TestTruncateIfIncomplete, "utf8tst/TestTruncateIfIncomplete"); addTest(root, &TestAppendChar, "utf8tst/TestAppendChar"); addTest(root, &TestAppend, "utf8tst/TestAppend"); addTest(root, &TestSurrogates, "utf8tst/TestSurrogates"); @@ -755,6 +757,14 @@ static void TestFwdBack() { } } +/** +* Ticket #13636 - Visual Studio 2017 has problems optimizing this function. +* As a workaround, we will turn off optimization just for this function on VS2017 and above. +*/ +#if defined(_MSC_VER) && (_MSC_VER > 1900) +#pragma optimize( "", off ) +#endif + static void TestFwdBackUnsafe() { /* * Use a (mostly) well-formed UTF-8 string and test at code point boundaries. @@ -840,6 +850,13 @@ static void TestFwdBackUnsafe() { } } +/** +* Ticket #13636 - Turn optimization back on. +*/ +#if defined(_MSC_VER) && (_MSC_VER > 1900) +#pragma optimize( "", on ) +#endif + static void TestSetChar() { static const uint8_t input[] = {0x61, 0xe4, 0xba, 0x8c, 0x7f, 0xfe, 0x62, 0xc5, 0x7f, 0x61, 0x80, 0x80, 0xe0, 0x00 }; @@ -927,6 +944,64 @@ static void TestSetCharUnsafe() { } } +static void TestTruncateIfIncomplete() { + // Difference from U8_SET_CP_START(): + // U8_TRUNCATE_IF_INCOMPLETE() does not look at s[length]. + // Therefore, if the last byte is a lead byte, then this macro truncates + // even if the byte at the input index cannot continue a valid sequence + // (including when that is not a trail byte). + // On the other hand, if the last byte is a trail byte, then the two macros behave the same. + static const struct { + const char *s; + int32_t expected; + } cases[] = { + { "", 0 }, + { "a", 1 }, + { "\x80", 1 }, + { "\xC1", 1 }, + { "\xC2", 0 }, + { "\xE0", 0 }, + { "\xF4", 0 }, + { "\xF5", 1 }, + { "\x80\x80", 2 }, + { "\xC2\xA0", 2 }, + { "\xE0\x9F", 2 }, + { "\xE0\xA0", 0 }, + { "\xED\x9F", 0 }, + { "\xED\xA0", 2 }, + { "\xF0\x8F", 2 }, + { "\xF0\x90", 0 }, + { "\xF4\x8F", 0 }, + { "\xF4\x90", 2 }, + { "\xF5\x80", 2 }, + { "\x80\x80\x80", 3 }, + { "\xC2\xA0\x80", 3 }, + { "\xE0\xA0\x80", 3 }, + { "\xF0\x8F\x80", 3 }, + { "\xF0\x90\x80", 0 }, + { "\xF4\x8F\x80", 0 }, + { "\xF4\x90\x80", 3 }, + { "\xF5\x80\x80", 3 }, + { "\x80\x80\x80\x80", 4 }, + { "\xC2\xA0\x80\x80", 4 }, + { "\xE0\xA0\x80\x80", 4 }, + { "\xF0\x90\x80\x80", 4 }, + { "\xF5\x80\x80\x80", 4 } + }; + int32_t i; + for (i = 0; i < UPRV_LENGTHOF(cases); ++i) { + const char *s = cases[i].s; + int32_t expected = cases[i].expected; + int32_t length = (int32_t)strlen(s); + int32_t adjusted = length; + U8_TRUNCATE_IF_INCOMPLETE(s, 0, adjusted); + if (adjusted != expected) { + log_err("ERROR: U8_TRUNCATE_IF_INCOMPLETE failed for i=%d, length=%d. Expected:%d Got:%d\n", + (int)i, (int)length, (int)expected, (int)adjusted); + } + } +} + static void TestAppendChar(){ #if !U_HIDE_OBSOLETE_UTF_OLD_H static const uint8_t s[11]={0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00}; diff --git a/Build/source/libs/icu/icu-src/source/test/depstest/dependencies.txt b/Build/source/libs/icu/icu-src/source/test/depstest/dependencies.txt index 0422318dc85..f4605547dc7 100644 --- a/Build/source/libs/icu/icu-src/source/test/depstest/dependencies.txt +++ b/Build/source/libs/icu/icu-src/source/test/depstest/dependencies.txt @@ -16,7 +16,8 @@ system_symbols: deps # C - PIC system_debug malloc_functions c_strings c_string_formatting + PIC system_misc system_debug malloc_functions ubsan + c_strings c_string_formatting floating_point trigonometry stdlib_qsort pthread system_locale @@ -28,12 +29,19 @@ group: PIC # Position-Independent Code (-fPIC) requires a Global Offset Table. _GLOBAL_OFFSET_TABLE_ +group: system_misc + abort + group: system_debug __assert_fail __stack_chk_fail group: malloc_functions free malloc realloc +group: ubsan + # UBSan=UndefinedBehaviorSanitizer, clang -fsanitize=bounds + __ubsan_handle_out_of_bounds + group: c_strings isspace isdigit __ctype_b_loc # for <ctype.h> @@ -415,7 +423,7 @@ group: simpleformatter group: patternprops patternprops.o deps - PIC + PIC ubsan group: ushape ushape.o @@ -760,6 +768,8 @@ group: errorcode # ErrorCode base class group: utypes # u_errorName() utypes.o + deps + ubsan group: platform # Files in the "platform" group. @@ -779,7 +789,8 @@ group: platform utrace.o deps # The "platform" group has no ICU dependencies. - PIC system_debug malloc_functions c_strings c_string_formatting + PIC system_misc system_debug malloc_functions ubsan + c_strings c_string_formatting floating_point pthread system_locale stdio_input readlink_function dir_io dlfcn # Move related code into icuplug.c? @@ -793,7 +804,7 @@ library: i18n alphabetic_index collation collation_builder string_search dayperiodrules formatting formattable_cnv regex regex_cnv translit - numberformatter + double_conversion numberformatter universal_time_scale uclean_i18n @@ -867,6 +878,13 @@ group: dayperiodrules deps resourcebundle uclean_i18n +group: double_conversion + double-conversion.o double-conversion-bignum.o double-conversion-bignum-dtoa.o + double-conversion-cached-powers.o double-conversion-diy-fp.o + double-conversion-fast-dtoa.o + deps + platform + group: numberformatter # ICU 60+ NumberFormatter API number_affixutils.o number_compact.o number_decimalquantity.o @@ -938,7 +956,7 @@ group: units group: digitlist digitlst.o decContext.o decNumber.o visibledigits.o deps - uclean_i18n + double_conversion uclean_i18n group: formattable fmtable.o @@ -980,6 +998,8 @@ group: translit group: universal_time_scale utmscale.o + deps + ubsan group: uclean_i18n ucln_in.o diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/Makefile.in b/Build/source/libs/icu/icu-src/source/test/intltest/Makefile.in index d41ef25f521..e8a5b72b22d 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/Makefile.in +++ b/Build/source/libs/icu/icu-src/source/test/intltest/Makefile.in @@ -64,7 +64,7 @@ scientificnumberformattertest.o datadrivennumberformattestsuite.o \ numberformattesttuple.o numberformat2test.o pluralmaptest.o \ numbertest_affixutils.o numbertest_api.o numbertest_decimalquantity.o \ numbertest_modifiers.o numbertest_patternmodifier.o numbertest_patternstring.o \ -numbertest_stringbuilder.o +numbertest_stringbuilder.o numbertest_doubleconversion.o DEPS = $(OBJECTS:.o=.d) diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/alphaindextst.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/alphaindextst.cpp index a3ebd1114a8..8a4edb27711 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/alphaindextst.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/alphaindextst.cpp @@ -22,6 +22,7 @@ #include "unicode/localpointer.h" #include "unicode/tblcoll.h" #include "unicode/uniset.h" +#include "unicode/uscript.h" #if !UCONFIG_NO_COLLATION && !UCONFIG_NO_NORMALIZATION @@ -66,6 +67,7 @@ void AlphabeticIndexTest::runIndexedTest( int32_t index, UBool exec, const char* TESTCASE_AUTO(TestChineseZhuyin); TESTCASE_AUTO(TestJapaneseKanji); TESTCASE_AUTO(TestChineseUnihan); + TESTCASE_AUTO(testHasBuckets); TESTCASE_AUTO_END; } @@ -724,4 +726,27 @@ void AlphabeticIndexTest::TestChineseUnihan() { assertEquals("getBucketIndex(U+7527)", 101, bucketIndex); } +void AlphabeticIndexTest::testHasBuckets() { + checkHasBuckets(Locale("am"), USCRIPT_ETHIOPIC); + checkHasBuckets(Locale("haw"), USCRIPT_LATIN); + checkHasBuckets(Locale("hy"), USCRIPT_ARMENIAN); + checkHasBuckets(Locale("vai"), USCRIPT_VAI); +} + +void AlphabeticIndexTest::checkHasBuckets(const Locale &locale, UScriptCode script) { + IcuTestErrorCode errorCode(*this, "checkHasBuckets"); + AlphabeticIndex aindex(locale, errorCode); + LocalPointer<AlphabeticIndex::ImmutableIndex> index(aindex.buildImmutableIndex(errorCode), errorCode); + if (U_FAILURE(errorCode)) { + dataerrln("%s %d Error in index creation", __FILE__, __LINE__); + return; + } + UnicodeString loc = locale.getName(); + assertTrue(loc + u" at least 3 buckets", index->getBucketCount() >= 3); + const AlphabeticIndex::Bucket *bucket = index->getBucket(1); + assertEquals(loc + u" real bucket", U_ALPHAINDEX_NORMAL, bucket->getLabelType()); + assertEquals(loc + u" expected script", script, + uscript_getScript(bucket->getLabel().char32At(0), errorCode)); +} + #endif diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/alphaindextst.h b/Build/source/libs/icu/icu-src/source/test/intltest/alphaindextst.h index 6bbe153f6fa..a785fca08e7 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/alphaindextst.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/alphaindextst.h @@ -13,6 +13,7 @@ #ifndef ALPHAINDEXTST_H #define ALPHAINDEXTST_H +#include "unicode/uscript.h" #include "intltest.h" class AlphabeticIndexTest: public IntlTest { @@ -49,6 +50,9 @@ public: void TestChineseZhuyin(); void TestJapaneseKanji(); void TestChineseUnihan(); + + void testHasBuckets(); + void checkHasBuckets(const Locale &locale, UScriptCode script); }; #endif diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/calregts.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/calregts.cpp index f1eb17bbed3..da522637c6f 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/calregts.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/calregts.cpp @@ -17,6 +17,7 @@ #include "unicode/simpletz.h" #include "unicode/smpdtfmt.h" #include "unicode/strenum.h" +#include "unicode/localpointer.h" #include "cmemory.h" #include "caltest.h" #include "unicode/localpointer.h" @@ -93,6 +94,8 @@ CalendarRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* & CASE(50,TestT9452); CASE(51,TestT11632); CASE(52,TestPersianCalOverflow); + CASE(53,TestIslamicCalOverflow); + CASE(54,TestWeekOfYear13548); default: name = ""; break; } } @@ -3009,9 +3012,9 @@ void CalendarRegressionTest::TestPersianCalOverflow(void) { month = cal->get(UCAL_MONTH, status); dayOfMonth = cal->get(UCAL_DATE, status); if ( U_FAILURE(status) ) { - errln("FAIL: Calendar->get MONTH/DATE for localeID %s, julianDay %d, status %s\n", localeID, jd, u_errorName(status)); + errln("FAIL: Calendar->get MONTH/DATE for localeID %s, julianDay %d, status %s", localeID, jd, u_errorName(status)); } else if (month > maxMonth || dayOfMonth > maxDayOfMonth) { - errln("FAIL: localeID %s, julianDay %d; maxMonth %d, got month %d; maxDayOfMonth %d, got dayOfMonth %d\n", + errln("FAIL: localeID %s, julianDay %d; maxMonth %d, got month %d; maxDayOfMonth %d, got dayOfMonth %d", localeID, jd, maxMonth, month, maxDayOfMonth, dayOfMonth); } } @@ -3019,4 +3022,51 @@ void CalendarRegressionTest::TestPersianCalOverflow(void) { } } +/** + * @bug tickets 12661, 13538 + */ +void CalendarRegressionTest::TestIslamicCalOverflow(void) { + const char* localeID = "ar@calendar=islamic-civil"; + UErrorCode status = U_ZERO_ERROR; + Calendar* cal = Calendar::createInstance(Locale(localeID), status); + if(U_FAILURE(status)) { + dataerrln("FAIL: Calendar::createInstance for localeID %s: %s", localeID, u_errorName(status)); + } else { + int32_t maxMonth = cal->getMaximum(UCAL_MONTH); + int32_t maxDayOfMonth = cal->getMaximum(UCAL_DATE); + int32_t jd, year, month, dayOfMonth; + for (jd = 73530872; jd <= 73530876; jd++) { // year 202002, int32_t overflow if jd >= 73530874 + status = U_ZERO_ERROR; + cal->clear(); + cal->set(UCAL_JULIAN_DAY, jd); + year = cal->get(UCAL_YEAR, status); + month = cal->get(UCAL_MONTH, status); + dayOfMonth = cal->get(UCAL_DATE, status); + if ( U_FAILURE(status) ) { + errln("FAIL: Calendar->get YEAR/MONTH/DATE for localeID %s, julianDay %d, status %s", localeID, jd, u_errorName(status)); + } else if (month > maxMonth || dayOfMonth > maxDayOfMonth) { + errln("FAIL: localeID %s, julianDay %d; got year %d; maxMonth %d, got month %d; maxDayOfMonth %d, got dayOfMonth %d", + localeID, jd, year, maxMonth, month, maxDayOfMonth, dayOfMonth); + } + } + delete cal; + } +} + +void CalendarRegressionTest::TestWeekOfYear13548(void) { + int32_t year = 2000; + UErrorCode status = U_ZERO_ERROR; + LocalPointer<Calendar> cal(Calendar::createInstance(status)); + failure(status, "Calendar::createInstance(status)"); + + cal->set(UCAL_YEAR, year); + cal->set(UCAL_WEEK_OF_YEAR, 4); + + int32_t resultYear = cal->get(UCAL_YEAR, status); + failure(status, "get(UCAL_YEAR, status)"); + if (year != resultYear) { + errln((UnicodeString)"Fail: Expected year=" + year + ", actual=" + resultYear); + } +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/calregts.h b/Build/source/libs/icu/icu-src/source/test/intltest/calregts.h index 15d55029093..b4166a0c61d 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/calregts.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/calregts.h @@ -79,6 +79,8 @@ public: void TestT9452(void); void TestT11632(void); void TestPersianCalOverflow(void); + void TestIslamicCalOverflow(void); + void TestWeekOfYear13548(void); void printdate(GregorianCalendar *cal, const char *string); void dowTest(UBool lenient) ; diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/compactdecimalformattest.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/compactdecimalformattest.cpp index 5ced1513b36..9bdaaad6636 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/compactdecimalformattest.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/compactdecimalformattest.cpp @@ -279,7 +279,7 @@ void CompactDecimalFormatTest::TestSwahiliShortNegative() { } void CompactDecimalFormatTest::TestArabicLong() { - CheckLocale("ar", UNUM_LONG, kArabicLong, UPRV_LENGTHOF(kArabicLong)); + CheckLocale("ar-EG", UNUM_LONG, kArabicLong, UPRV_LENGTHOF(kArabicLong)); } void CompactDecimalFormatTest::TestSignificantDigits() { diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/convtest.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/convtest.cpp index db0aa86912b..3a0e5414d6f 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/convtest.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/convtest.cpp @@ -733,6 +733,7 @@ ConversionTest::TestUTF8ToUTF8Overflow() { UChar *pivotSource = buffer16; UChar *pivotTarget = buffer16; const UChar *pivotLimit = buffer16 + UPRV_LENGTHOF(buffer16); + int32_t length; // Convert with insufficient target capacity. result[2] = 5; @@ -741,7 +742,7 @@ ConversionTest::TestUTF8ToUTF8Overflow() { buffer16, &pivotSource, &pivotTarget, pivotLimit, FALSE, FALSE, errorCode); assertEquals("overflow", U_BUFFER_OVERFLOW_ERROR, errorCode.reset()); - int32_t length = (int32_t)(target - result); + length = (int32_t)(target - result); assertEquals("number of bytes written", 2, length); assertEquals("next byte not clobbered", 5, result[2]); @@ -790,6 +791,52 @@ ConversionTest::TestUTF8ToUTF8Overflow() { if (length == 5) { assertTrue("text2 result same as input", memcmp(text2, result, length) == 0); } + + ucnv_reset(cnv1.getAlias()); + ucnv_reset(cnv2.getAlias()); + memset(result, 0, sizeof(result)); + static const char *illFormed = "\xf1\x91\x93\x96\x91\x94"; // U+514D6 + two more trail bytes + source = illFormed; + sourceLimit = illFormed + strlen(illFormed); + target = result; + pivotSource = pivotTarget = buffer16; + + ucnv_setToUCallBack(cnv1.getAlias(), UCNV_TO_U_CALLBACK_STOP, nullptr, nullptr, nullptr, errorCode); + + // Convert only two bytes and flush (but expect failure). + char errorBytes[10]; + int8_t errorLength; + result[0] = 5; + ucnv_convertEx(cnv2.getAlias(), cnv1.getAlias(), + &target, targetLimit, &source, source + 2, + buffer16, &pivotSource, &pivotTarget, pivotLimit, + FALSE, TRUE, errorCode); + assertEquals("illFormed truncated", U_TRUNCATED_CHAR_FOUND, errorCode.reset()); + length = (int32_t)(target - result); + assertEquals("illFormed number of bytes written", 0, length); + errorLength = UPRV_LENGTHOF(errorBytes); + ucnv_getInvalidChars(cnv1.getAlias(), errorBytes, &errorLength, errorCode); + assertEquals("illFormed truncated errorLength", 2, (int32_t)errorLength); + if (errorLength == 2) { + assertEquals("illFormed truncated errorBytes", 0xf191, + ((int32_t)(uint8_t)errorBytes[0] << 8) | (uint8_t)errorBytes[1]); + } + + // Continue conversion starting with a trail byte. + ucnv_convertEx(cnv2.getAlias(), cnv1.getAlias(), + &target, targetLimit, &source, sourceLimit, + buffer16, &pivotSource, &pivotTarget, pivotLimit, + FALSE, TRUE, errorCode); + + assertEquals("illFormed trail byte", U_ILLEGAL_CHAR_FOUND, errorCode.reset()); + length = (int32_t)(target - result); + assertEquals("illFormed trail byte number of bytes written", 0, length); + errorLength = UPRV_LENGTHOF(errorBytes); + ucnv_getInvalidChars(cnv1.getAlias(), errorBytes, &errorLength, errorCode); + assertEquals("illFormed trail byte errorLength", 1, (int32_t)errorLength); + if (errorLength == 1) { + assertEquals("illFormed trail byte errorBytes", 0x93, (int32_t)(uint8_t)errorBytes[0]); + } } // open testdata or ICU data converter ------------------------------------- *** diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/dtfmttst.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/dtfmttst.cpp index fd3a9f1faf0..35870f780f5 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/dtfmttst.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/dtfmttst.cpp @@ -1355,18 +1355,18 @@ DateFormatTest::TestLocaleDateFormat() // Bug 495 void DateFormatTest::TestFormattingLocaleTimeSeparator() { - // This test not as useful is it once was, since timeSeparator - // in the Arabic is changed back to ":" in CLDR 28. + // This test not as useful as it once was, since timeSeparator + // in the Arabic locale is changed back to ":" in CLDR 28. const UDate testDate = 874266720000.; // Sun Sep 14 21:52:00 CET 1997 logln((UnicodeString)"Date set to : " + dateToString(testDate)); const LocalPointer<const TimeZone> tz(TimeZone::createTimeZone("CET")); const LocalPointer<DateFormat> dfArab(DateFormat::createTimeInstance( - DateFormat::SHORT, Locale("ar"))); + DateFormat::SHORT, Locale("ar", "EG"))); const LocalPointer<DateFormat> dfLatn(DateFormat::createTimeInstance( - DateFormat::SHORT, Locale("ar", NULL, NULL, "numbers=latn"))); + DateFormat::SHORT, Locale("ar", "EG", NULL, "numbers=latn"))); if (dfLatn.isNull() || dfArab.isNull()) { dataerrln("Error calling DateFormat::createTimeInstance()"); diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.cpp index 33d248d5f31..da262ba99e4 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.cpp @@ -18,6 +18,7 @@ #include "unicode/smpdtfmt.h" #include "unicode/dtfmtsym.h" #include "unicode/dtptngen.h" +#include "unicode/ustring.h" #include "cmemory.h" #include "loctest.h" @@ -36,6 +37,7 @@ void IntlTestDateTimePatternGeneratorAPI::runIndexedTest( int32_t index, UBool e TESTCASE(3, testStaticGetSkeleton); TESTCASE(4, testC); TESTCASE(5, testSkeletonsWithDayPeriods); + TESTCASE(6, testGetFieldDisplayNames); default: name = ""; break; } } @@ -1210,4 +1212,51 @@ void IntlTestDateTimePatternGeneratorAPI::testSkeletonsWithDayPeriods() { delete gen; } +typedef struct FieldDisplayNameData { + const char * locale; + UDateTimePatternField field; + UDateTimePGDisplayWidth width; + const char * expected; // can have escapes such as \\u00E0 +} FieldDisplayNameData; +enum { kFieldDisplayNameMax = 32 }; + +void IntlTestDateTimePatternGeneratorAPI::testGetFieldDisplayNames() { + const FieldDisplayNameData testData[] = { + /*loc field width expectedName */ + { "de", UDATPG_QUARTER_FIELD, UDATPG_WIDE, "Quartal" }, + { "de", UDATPG_QUARTER_FIELD, UDATPG_ABBREVIATED, "Quart." }, + { "de", UDATPG_QUARTER_FIELD, UDATPG_NARROW, "Q" }, + { "en", UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD, UDATPG_WIDE, "weekday of the month" }, + { "en", UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD, UDATPG_ABBREVIATED, "wkday. of mo." }, + { "en", UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD, UDATPG_NARROW, "wkday. of mo." }, // fallback + { "en_GB", UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD, UDATPG_WIDE, "weekday of the month" }, + { "en_GB", UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD, UDATPG_ABBREVIATED, "wkday of mo" }, // override + { "en_GB", UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD, UDATPG_NARROW, "wkday of mo" }, + { "it", UDATPG_SECOND_FIELD, UDATPG_WIDE, "secondo" }, + { "it", UDATPG_SECOND_FIELD, UDATPG_ABBREVIATED, "s" }, + { "it", UDATPG_SECOND_FIELD, UDATPG_NARROW, "s" }, + }; + + int count = UPRV_LENGTHOF(testData); + const FieldDisplayNameData * testDataPtr = testData; + for (; count-- > 0; ++testDataPtr) { + UErrorCode status = U_ZERO_ERROR; + Locale locale(testDataPtr->locale); + DateTimePatternGenerator * dtpg = DateTimePatternGenerator::createInstance(locale, status); + if (U_FAILURE(status)) { + dataerrln("FAIL: DateTimePatternGenerator::createInstance failed for locale %s", testDataPtr->locale); + } else { + UChar expName[kFieldDisplayNameMax+1]; + u_unescape(testDataPtr->expected, expName, kFieldDisplayNameMax); + expName[kFieldDisplayNameMax] = 0; // ensure 0 termination + UnicodeString getName = dtpg->getFieldDisplayName(testDataPtr->field, testDataPtr->width); + if (getName.compare(expName, u_strlen(expName)) != 0) { + errln("ERROR: locale %s field %d width %d, expected %s\n", + testDataPtr->locale, testDataPtr->field, testDataPtr->width, testDataPtr->expected); + } + delete dtpg; + } + } +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.h b/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.h index 03da8485984..adef0dca5cf 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.h @@ -31,6 +31,7 @@ private: void testStaticGetSkeleton(/* char* par */); void testC(); void testSkeletonsWithDayPeriods(); + void testGetFieldDisplayNames(); }; #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/intltest.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/intltest.cpp index 5edf872d3b7..c45913796a4 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/intltest.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/intltest.cpp @@ -2030,6 +2030,25 @@ UBool IntlTest::assertEquals(const char* message, return TRUE; } + +UBool IntlTest::assertEquals(const char* message, + UErrorCode expected, + UErrorCode actual) { + if (expected != actual) { + errln((UnicodeString)"FAIL: " + message + "; got " + + u_errorName(actual) + + "; expected " + u_errorName(expected)); + return FALSE; + } +#ifdef VERBOSE_ASSERTIONS + else { + logln((UnicodeString)"Ok: " + message + "; got " + u_errorName(actual)); + } +#endif + return TRUE; +} + + #if !UCONFIG_NO_FORMATTING UBool IntlTest::assertEquals(const char* message, const Formattable& expected, @@ -2105,6 +2124,16 @@ UBool IntlTest::assertEquals(const UnicodeString& message, int64_t actual) { return assertEquals(extractToAssertBuf(message), expected, actual); } +UBool IntlTest::assertEquals(const UnicodeString& message, + double expected, + double actual) { + return assertEquals(extractToAssertBuf(message), expected, actual); +} +UBool IntlTest::assertEquals(const UnicodeString& message, + UErrorCode expected, + UErrorCode actual) { + return assertEquals(extractToAssertBuf(message), expected, actual); +} #if !UCONFIG_NO_FORMATTING UBool IntlTest::assertEquals(const UnicodeString& message, diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/intltest.h b/Build/source/libs/icu/icu-src/source/test/intltest/intltest.h index 1f7c80d4794..08765b707d0 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/intltest.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/intltest.h @@ -289,13 +289,12 @@ public: UBool assertSuccess(const char* message, UErrorCode ec, UBool possibleDataError=FALSE, const char *file=NULL, int line=0); UBool assertEquals(const char* message, const UnicodeString& expected, const UnicodeString& actual, UBool possibleDataError=FALSE); - UBool assertEquals(const char* message, const char* expected, - const char* actual); - UBool assertEquals(const char* message, UBool expected, - UBool actual); + UBool assertEquals(const char* message, const char* expected, const char* actual); + UBool assertEquals(const char* message, UBool expected, UBool actual); UBool assertEquals(const char* message, int32_t expected, int32_t actual); UBool assertEquals(const char* message, int64_t expected, int64_t actual); UBool assertEquals(const char* message, double expected, double actual); + UBool assertEquals(const char* message, UErrorCode expected, UErrorCode actual); #if !UCONFIG_NO_FORMATTING UBool assertEquals(const char* message, const Formattable& expected, const Formattable& actual, UBool possibleDataError=FALSE); @@ -307,11 +306,12 @@ public: UBool assertSuccess(const UnicodeString& message, UErrorCode ec); UBool assertEquals(const UnicodeString& message, const UnicodeString& expected, const UnicodeString& actual, UBool possibleDataError=FALSE); - UBool assertEquals(const UnicodeString& message, const char* expected, - const char* actual); + UBool assertEquals(const UnicodeString& message, const char* expected, const char* actual); UBool assertEquals(const UnicodeString& message, UBool expected, UBool actual); UBool assertEquals(const UnicodeString& message, int32_t expected, int32_t actual); UBool assertEquals(const UnicodeString& message, int64_t expected, int64_t actual); + UBool assertEquals(const UnicodeString& message, double expected, double actual); + UBool assertEquals(const UnicodeString& message, UErrorCode expected, UErrorCode actual); virtual void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); // overide ! diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/intltest.vcxproj b/Build/source/libs/icu/icu-src/source/test/intltest/intltest.vcxproj index 148b42c0187..32bd338d795 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/intltest.vcxproj +++ b/Build/source/libs/icu/icu-src/source/test/intltest/intltest.vcxproj @@ -1,52 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> + <!-- The following import will include the 'default' configuration options for VS projects. --> + <Import Project="..\..\allinone\Build.Windows.ProjectConfiguration.props" /> + <PropertyGroup Label="Globals"> <ProjectGuid>{73632960-B3A6-464D-83A3-4B43365F19B8}</ProjectGuid> - <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <RootNamespace>intltest</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - <CharacterSet>MultiByte</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - <CharacterSet>MultiByte</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <PropertyGroup Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseOfMfc>false</UseOfMfc> <CharacterSet>MultiByte</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - <CharacterSet>MultiByte</CharacterSet> - <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -83,38 +48,33 @@ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</IntDir> <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> </PropertyGroup> + <!-- Options that are common to *all* project configurations --> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>..\..\..\include;..\..\common;..\..\i18n;..\..\tools\toolutil;..\..\tools\ctestfw;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableLanguageExtensions>false</DisableLanguageExtensions> + <WarningLevel>Level3</WarningLevel> + </ClCompile> + </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <Midl> <TypeLibraryName>.\x86\Debug/intltest.tlb</TypeLibraryName> </Midl> <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>..\..\..\include;..\..\common;..\..\i18n;..\..\tools\toolutil;..\..\tools\ctestfw;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <BufferSecurityCheck>true</BufferSecurityCheck> - <DisableLanguageExtensions>false</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <PrecompiledHeaderOutputFile>.\x86\Debug/intltest.pch</PrecompiledHeaderOutputFile> <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation> <ObjectFileName>.\x86\Debug/</ObjectFileName> <ProgramDataBaseFileName>.\x86\Debug/</ProgramDataBaseFileName> <BrowseInformation>true</BrowseInformation> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> <DebugInformationFormat>EditAndContinue</DebugInformationFormat> <CompileAs>Default</CompileAs> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> <Link> <OutputFile>.\x86\Debug/intltest.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>icuucd.lib;icuind.lib;icutud.lib;icutestd.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>..\..\..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <ProgramDatabaseFile>.\x86\Debug/intltest.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> <RandomizedBaseAddress>false</RandomizedBaseAddress> @@ -125,41 +85,26 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <Midl> - <TargetEnvironment>X64</TargetEnvironment> <TypeLibraryName>.\x64\Debug/intltest.tlb</TypeLibraryName> </Midl> <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>..\..\..\include;..\..\common;..\..\i18n;..\..\tools\toolutil;..\..\tools\ctestfw;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN64;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <BufferSecurityCheck>true</BufferSecurityCheck> - <DisableLanguageExtensions>false</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <PrecompiledHeaderOutputFile>.\x64\Debug/intltest.pch</PrecompiledHeaderOutputFile> <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation> <ObjectFileName>.\x64\Debug/</ObjectFileName> <ProgramDataBaseFileName>.\x64\Debug/</ProgramDataBaseFileName> <BrowseInformation>true</BrowseInformation> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <CompileAs>Default</CompileAs> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> <Link> <OutputFile>.\x64\Debug/intltest.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalDependencies>icuucd.lib;icuind.lib;icutud.lib;icutestd.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>..\..\..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <GenerateDebugInformation>true</GenerateDebugInformation> <ProgramDatabaseFile>.\x64\Debug/intltest.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> <FixedBaseAddress>false</FixedBaseAddress> - <TargetMachine>MachineX64</TargetMachine> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> @@ -167,28 +112,17 @@ <TypeLibraryName>.\x86\Release/intltest.tlb</TypeLibraryName> </Midl> <ClCompile> - <AdditionalIncludeDirectories>..\..\..\include;..\..\common;..\..\i18n;..\..\tools\toolutil;..\..\tools\ctestfw;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <StringPooling>true</StringPooling> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <DisableLanguageExtensions>false</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <PrecompiledHeaderOutputFile>.\x86\Release/intltest.pch</PrecompiledHeaderOutputFile> <AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation> <ObjectFileName>.\x86\Release/</ObjectFileName> <ProgramDataBaseFileName>.\x86\Release/</ProgramDataBaseFileName> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> <CompileAs>Default</CompileAs> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> <Link> <OutputFile>.\x86\Release/intltest.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalDependencies>icuuc.lib;icuin.lib;icutu.lib;icutest.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>..\..\..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <GenerateDebugInformation>true</GenerateDebugInformation> <ProgramDatabaseFile>.\x86\Release/intltest.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> @@ -199,36 +133,23 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <Midl> - <TargetEnvironment>X64</TargetEnvironment> <TypeLibraryName>.\x64\Release/intltest.tlb</TypeLibraryName> </Midl> <ClCompile> - <AdditionalIncludeDirectories>..\..\..\include;..\..\common;..\..\i18n;..\..\tools\toolutil;..\..\tools\ctestfw;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <StringPooling>true</StringPooling> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <DisableLanguageExtensions>false</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <PrecompiledHeaderOutputFile>.\x64\Release/intltest.pch</PrecompiledHeaderOutputFile> <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation> <ObjectFileName>.\x64\Release/</ObjectFileName> <ProgramDataBaseFileName>.\x64\Release/</ProgramDataBaseFileName> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> <CompileAs>Default</CompileAs> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> <Link> <OutputFile>.\x64\Release/intltest.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalDependencies>icuuc.lib;icuin.lib;icutu.lib;icutest.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>..\..\..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <GenerateDebugInformation>true</GenerateDebugInformation> <ProgramDatabaseFile>.\x64\Release/intltest.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> - <TargetMachine>MachineX64</TargetMachine> </Link> </ItemDefinitionGroup> <ItemGroup> @@ -327,6 +248,7 @@ <ClCompile Include="numbertest_affixutils.cpp" /> <ClCompile Include="numbertest_api.cpp" /> <ClCompile Include="numbertest_decimalquantity.cpp" /> + <ClCompile Include="numbertest_doubleconversion.cpp" /> <ClCompile Include="numbertest_modifiers.cpp" /> <ClCompile Include="numbertest_patternmodifier.cpp" /> <ClCompile Include="numbertest_patternstring.cpp" /> @@ -566,25 +488,7 @@ <ClInclude Include="csdetest.h" /> <ClInclude Include="listformattertest.h" /> </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\..\common\common.vcxproj"> - <Project>{73c0a65b-d1f2-4de1-b3a6-15dad2c23f3d}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="..\..\i18n\i18n.vcxproj"> - <Project>{0178b127-6269-407d-b112-93877bb62776}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="..\..\tools\ctestfw\ctestfw.vcxproj"> - <Project>{eca6b435-b4fa-4f9f-bf95-f451d078fc47}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="..\..\tools\toolutil\toolutil.vcxproj"> - <Project>{6b231032-3cb5-4eed-9210-810d666a23a0}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> +</Project>
\ No newline at end of file diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/intltest.vcxproj.filters b/Build/source/libs/icu/icu-src/source/test/intltest/intltest.vcxproj.filters index 384f6da184e..442793e69df 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/intltest.vcxproj.filters +++ b/Build/source/libs/icu/icu-src/source/test/intltest/intltest.vcxproj.filters @@ -268,6 +268,9 @@ <ClCompile Include="numbertest_decimalquantity.cpp"> <Filter>formatting</Filter> </ClCompile> + <ClCompile Include="numbertest_doubleconversion.cpp"> + <Filter>formatting</Filter> + </ClCompile> <ClCompile Include="numbertest_modifiers.cpp"> <Filter>formatting</Filter> </ClCompile> diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/itrbnf.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/itrbnf.cpp index 97700251a38..e6e90780145 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/itrbnf.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/itrbnf.cpp @@ -75,6 +75,7 @@ void IntlTestRBNF::runIndexedTest(int32_t index, UBool exec, const char* &name, TESTCASE(23, TestVariableDecimalPoint); TESTCASE(24, TestLargeNumbers); TESTCASE(25, TestCompactDecimalFormatStyle); + TESTCASE(26, TestParseFailure); #else TESTCASE(0, TestRBNFDisabled); #endif @@ -2283,6 +2284,22 @@ void IntlTestRBNF::TestCompactDecimalFormatStyle() { doTest(&rbnf, enTestFullData, false); } +void IntlTestRBNF::TestParseFailure() { + UErrorCode status = U_ZERO_ERROR; + RuleBasedNumberFormat rbnf(URBNF_SPELLOUT, Locale::getJapanese(), status); + static const UChar* testData[] = { + u"・・・・・・・・・・・・・・・・・・・・・・・・" + }; + for (int i = 0; i < UPRV_LENGTHOF(testData); ++i) { + UnicodeString spelledNumberString(testData[i]); + Formattable actualNumber; + rbnf.parse(spelledNumberString, actualNumber, status); + if (status != U_INVALID_FORMAT_ERROR) { // I would have expected U_PARSE_ERROR, but NumberFormat::parse gives U_INVALID_FORMAT_ERROR + errln("FAIL: string should be unparseable index=%d %s", i, u_errorName(status)); + } + } +} + void IntlTestRBNF::doTest(RuleBasedNumberFormat* formatter, const char* const testData[][2], UBool testParsing) { diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/itrbnf.h b/Build/source/libs/icu/icu-src/source/test/intltest/itrbnf.h index 540b8033342..e58d321362c 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/itrbnf.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/itrbnf.h @@ -147,6 +147,7 @@ class IntlTestRBNF : public IntlTest { void TestRounding(); void TestLargeNumbers(); void TestCompactDecimalFormatStyle(); + void TestParseFailure(); protected: virtual void doTest(RuleBasedNumberFormat* formatter, const char* const testData[][2], UBool testParsing); diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/measfmttest.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/measfmttest.cpp index d997a26cde0..7be9adfed02 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/measfmttest.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/measfmttest.cpp @@ -1747,7 +1747,7 @@ void MeasureFormatTest::TestMultiples() { helperTestMultiples(en, UMEASFMT_WIDTH_SHORT, "2 mi, 1 ft, 2.3 in"); helperTestMultiples(en, UMEASFMT_WIDTH_NARROW, "2mi 1\\u2032 2.3\\u2033"); helperTestMultiples(ru, UMEASFMT_WIDTH_WIDE, "2 \\u043C\\u0438\\u043B\\u0438 1 \\u0444\\u0443\\u0442 2,3 \\u0434\\u044E\\u0439\\u043C\\u0430"); - helperTestMultiples(ru, UMEASFMT_WIDTH_SHORT, "2 \\u043C\\u0438\\u043B\\u0438 1 \\u0444\\u0443\\u0442 2,3 \\u0434\\u044E\\u0439\\u043C."); + helperTestMultiples(ru, UMEASFMT_WIDTH_SHORT, "2 \\u043C\\u0438\\u043B\\u0438 1 \\u0444\\u0442 2,3 \\u0434\\u044E\\u0439\\u043C."); helperTestMultiples(ru, UMEASFMT_WIDTH_NARROW, "2 \\u043C\\u0438\\u043B\\u044C 1 \\u0444\\u0442 2,3 \\u0434\\u044E\\u0439\\u043C\\u0430"); } diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numberformattesttuple.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/numberformattesttuple.cpp index 01c2815d5ec..496aaeccde2 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/numberformattesttuple.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/numberformattesttuple.cpp @@ -325,6 +325,7 @@ const NumberFormatTestTupleFieldData gFieldData[] = { FIELD_INIT(positiveSuffix, &gStrOps), FIELD_INIT(negativePrefix, &gStrOps), FIELD_INIT(negativeSuffix, &gStrOps), + FIELD_INIT(signAlwaysShown, &gIntOps), FIELD_INIT(localizedPattern, &gStrOps), FIELD_INIT(toPattern, &gStrOps), FIELD_INIT(toLocalizedPattern, &gStrOps), diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numberformattesttuple.h b/Build/source/libs/icu/icu-src/source/test/intltest/numberformattesttuple.h index f417b3ef995..685c3d698e1 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/numberformattesttuple.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/numberformattesttuple.h @@ -55,6 +55,7 @@ enum ENumberFormatTestTupleField { kPositiveSuffix, kNegativePrefix, kNegativeSuffix, + kSignAlwaysShown, kLocalizedPattern, kToPattern, kToLocalizedPattern, @@ -118,6 +119,7 @@ public: UnicodeString positiveSuffix; UnicodeString negativePrefix; UnicodeString negativeSuffix; + int32_t signAlwaysShown; UnicodeString localizedPattern; UnicodeString toPattern; UnicodeString toLocalizedPattern; @@ -164,6 +166,7 @@ public: UBool positiveSuffixFlag; UBool negativePrefixFlag; UBool negativeSuffixFlag; + UBool signAlwaysShownFlag; UBool localizedPatternFlag; UBool toPatternFlag; UBool toLocalizedPatternFlag; diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest.h b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest.h index 3e600318339..c1d5044761b 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest.h @@ -45,6 +45,7 @@ class NumberFormatterApiTest : public IntlTest { void notationScientific(); void notationCompact(); void unitMeasure(); + void unitCompoundMeasure(); void unitCurrency(); void unitPercent(); void roundingFraction(); @@ -62,6 +63,7 @@ class NumberFormatterApiTest : public IntlTest { void locale(); void formatTypes(); void errors(); + void validRanges(); void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); @@ -70,11 +72,19 @@ class NumberFormatterApiTest : public IntlTest { CurrencyUnit GBP; CurrencyUnit CZK; CurrencyUnit CAD; + CurrencyUnit ESP; + CurrencyUnit PTE; MeasureUnit METER; MeasureUnit DAY; MeasureUnit SQUARE_METER; MeasureUnit FAHRENHEIT; + MeasureUnit SECOND; + MeasureUnit POUND; + MeasureUnit SQUARE_MILE; + MeasureUnit JOULE; + MeasureUnit FURLONG; + MeasureUnit KELVIN; NumberingSystem MATHSANB; NumberingSystem LATN; @@ -100,6 +110,7 @@ class DecimalQuantityTest : public IntlTest { void testAppend(); void testConvertToAccurateDouble(); void testUseApproximateDoubleWhenAble(); + void testHardDoubleConversion(); void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); @@ -110,6 +121,13 @@ class DecimalQuantityTest : public IntlTest { void checkDoubleBehavior(double d, bool explicitRequired); }; +class DoubleConversionTest : public IntlTest { + public: + void testDoubleConversionApi(); + + void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); +}; + class ModifiersTest : public IntlTest { public: void testConstantAffixModifier(); @@ -132,6 +150,7 @@ class ModifiersTest : public IntlTest { class PatternModifierTest : public IntlTest { public: void testBasic(); + void testPatternWithNoPlaceholder(); void testMutableEqualsImmutable(); void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); @@ -155,6 +174,7 @@ class PatternStringTest : public IntlTest { class NumberStringBuilderTest : public IntlTest { public: void testInsertAppendUnicodeString(); + void testSplice(); void testInsertAppendCodePoint(); void testCopy(); void testFields(); @@ -195,6 +215,7 @@ class NumberTest : public IntlTest { TESTCLASS(4, PatternModifierTest); TESTCLASS(5, PatternStringTest); TESTCLASS(6, NumberStringBuilderTest); + TESTCLASS(7, DoubleConversionTest); default: name = ""; break; // needed to end loop } } diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_api.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_api.cpp index 63514043eeb..5b1c46f1e5e 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_api.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_api.cpp @@ -22,33 +22,31 @@ NumberFormatterApiTest::NumberFormatterApiTest() NumberFormatterApiTest::NumberFormatterApiTest(UErrorCode &status) : USD(u"USD", status), GBP(u"GBP", status), CZK(u"CZK", status), CAD(u"CAD", status), + ESP(u"ESP", status), PTE(u"PTE", status), FRENCH_SYMBOLS(Locale::getFrench(), status), SWISS_SYMBOLS(Locale("de-CH"), status), MYANMAR_SYMBOLS(Locale("my"), status) { - MeasureUnit *unit = MeasureUnit::createMeter(status); + // Check for error on the first MeasureUnit in case there is no data + LocalPointer<MeasureUnit> unit(MeasureUnit::createMeter(status)); if (U_FAILURE(status)) { dataerrln("%s %d status = %s", __FILE__, __LINE__, u_errorName(status)); return; } METER = *unit; - delete unit; - unit = MeasureUnit::createDay(status); - DAY = *unit; - delete unit; - unit = MeasureUnit::createSquareMeter(status); - SQUARE_METER = *unit; - delete unit; - unit = MeasureUnit::createFahrenheit(status); - FAHRENHEIT = *unit; - delete unit; - - NumberingSystem *ns = NumberingSystem::createInstanceByName("mathsanb", status); - MATHSANB = *ns; - delete ns; - ns = NumberingSystem::createInstanceByName("latn", status); - LATN = *ns; - delete ns; + + DAY = *LocalPointer<MeasureUnit>(MeasureUnit::createDay(status)); + SQUARE_METER = *LocalPointer<MeasureUnit>(MeasureUnit::createSquareMeter(status)); + FAHRENHEIT = *LocalPointer<MeasureUnit>(MeasureUnit::createFahrenheit(status)); + SECOND = *LocalPointer<MeasureUnit>(MeasureUnit::createSecond(status)); + POUND = *LocalPointer<MeasureUnit>(MeasureUnit::createPound(status)); + SQUARE_MILE = *LocalPointer<MeasureUnit>(MeasureUnit::createSquareMile(status)); + JOULE = *LocalPointer<MeasureUnit>(MeasureUnit::createJoule(status)); + FURLONG = *LocalPointer<MeasureUnit>(MeasureUnit::createFurlong(status)); + KELVIN = *LocalPointer<MeasureUnit>(MeasureUnit::createKelvin(status)); + + MATHSANB = *LocalPointer<NumberingSystem>(NumberingSystem::createInstanceByName("mathsanb", status)); + LATN = *LocalPointer<NumberingSystem>(NumberingSystem::createInstanceByName("latn", status)); } void NumberFormatterApiTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char *) { @@ -60,6 +58,7 @@ void NumberFormatterApiTest::runIndexedTest(int32_t index, UBool exec, const cha TESTCASE_AUTO(notationScientific); TESTCASE_AUTO(notationCompact); TESTCASE_AUTO(unitMeasure); + TESTCASE_AUTO(unitCompoundMeasure); TESTCASE_AUTO(unitCurrency); TESTCASE_AUTO(unitPercent); TESTCASE_AUTO(roundingFraction); @@ -77,6 +76,7 @@ void NumberFormatterApiTest::runIndexedTest(int32_t index, UBool exec, const cha TESTCASE_AUTO(locale); TESTCASE_AUTO(formatTypes); TESTCASE_AUTO(errors); + TESTCASE_AUTO(validRanges); TESTCASE_AUTO_END; } @@ -351,12 +351,15 @@ void NumberFormatterApiTest::notationCompact() { Locale::getEnglish(), 9990000, u"10M"); + + // NOTE: There is no API for compact custom data in C++ + // and thus no "Compact Somali No Figure" test } void NumberFormatterApiTest::unitMeasure() { assertFormatDescending( - u"Meters Short", - NumberFormatter::with().adoptUnit(new MeasureUnit(METER)), + u"Meters Short and unit() method", + NumberFormatter::with().unit(METER), Locale::getEnglish(), u"87,650 m", u"8,765 m", @@ -369,7 +372,7 @@ void NumberFormatterApiTest::unitMeasure() { u"0 m"); assertFormatDescending( - u"Meters Long", + u"Meters Long and adoptUnit() method", NumberFormatter::with().adoptUnit(new MeasureUnit(METER)) .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME), Locale::getEnglish(), @@ -386,7 +389,7 @@ void NumberFormatterApiTest::unitMeasure() { assertFormatDescending( u"Compact Meters Long", NumberFormatter::with().notation(Notation::compactLong()) - .adoptUnit(new MeasureUnit(METER)) + .unit(METER) .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME), Locale::getEnglish(), u"88 thousand meters", @@ -410,14 +413,14 @@ void NumberFormatterApiTest::unitMeasure() { // TODO: Implement Measure in C++ // assertFormatSingleMeasure( // u"Measure format method takes precedence over fluent chain", -// NumberFormatter::with().adoptUnit(new MeasureUnit(METER)), +// NumberFormatter::with().unit(METER), // Locale::getEnglish(), // new Measure(5.43, USD), // u"$5.43"); assertFormatSingle( u"Meters with Negative Sign", - NumberFormatter::with().adoptUnit(new MeasureUnit(METER)), + NumberFormatter::with().unit(METER), Locale::getEnglish(), -9876543.21, u"-9,876,543.21 m"); @@ -425,7 +428,7 @@ void NumberFormatterApiTest::unitMeasure() { // The locale string "सान" appears only in brx.txt: assertFormatSingle( u"Interesting Data Fallback 1", - NumberFormatter::with().adoptUnit(new MeasureUnit(DAY)) + NumberFormatter::with().unit(DAY) .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME), Locale::createFromName("brx"), 5.43, @@ -434,7 +437,7 @@ void NumberFormatterApiTest::unitMeasure() { // Requires following the alias from unitsNarrow to unitsShort: assertFormatSingle( u"Interesting Data Fallback 2", - NumberFormatter::with().adoptUnit(new MeasureUnit(DAY)) + NumberFormatter::with().unit(DAY) .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW), Locale::createFromName("brx"), 5.43, @@ -444,7 +447,7 @@ void NumberFormatterApiTest::unitMeasure() { // requiring fallback to the root. assertFormatSingle( u"Interesting Data Fallback 3", - NumberFormatter::with().adoptUnit(new MeasureUnit(SQUARE_METER)) + NumberFormatter::with().unit(SQUARE_METER) .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW), Locale::createFromName("en-GB"), 5.43, @@ -454,7 +457,7 @@ void NumberFormatterApiTest::unitMeasure() { // NOTE: This example is in the documentation. assertFormatSingle( u"Difference between Narrow and Short (Narrow Version)", - NumberFormatter::with().adoptUnit(new MeasureUnit(FAHRENHEIT)) + NumberFormatter::with().unit(FAHRENHEIT) .unitWidth(UNUM_UNIT_WIDTH_NARROW), Locale("es-US"), 5.43, @@ -462,11 +465,74 @@ void NumberFormatterApiTest::unitMeasure() { assertFormatSingle( u"Difference between Narrow and Short (Short Version)", - NumberFormatter::with().adoptUnit(new MeasureUnit(FAHRENHEIT)) + NumberFormatter::with().unit(FAHRENHEIT) .unitWidth(UNUM_UNIT_WIDTH_SHORT), Locale("es-US"), 5.43, u"5.43 °F"); + + assertFormatSingle( + u"MeasureUnit form without {0} in CLDR pattern", + NumberFormatter::with() + .unit(KELVIN) + .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME), + Locale("es-MX"), + 1, + u"kelvin"); + + assertFormatSingle( + u"MeasureUnit form without {0} in CLDR pattern and wide base form", + NumberFormatter::with() + .rounding(Rounder::fixedFraction(20)) + .unit(KELVIN) + .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME), + Locale("es-MX"), + 1, + u"kelvin"); +} + +void NumberFormatterApiTest::unitCompoundMeasure() { + assertFormatDescending( + u"Meters Per Second Short (unit that simplifies) and perUnit method", + NumberFormatter::with().unit(METER).perUnit(SECOND), + Locale::getEnglish(), + u"87,650 m/s", + u"8,765 m/s", + u"876.5 m/s", + u"87.65 m/s", + u"8.765 m/s", + u"0.8765 m/s", + u"0.08765 m/s", + u"0.008765 m/s", + u"0 m/s"); + + assertFormatDescending( + u"Pounds Per Square Mile Short (secondary unit has per-format) and adoptPerUnit method", + NumberFormatter::with().unit(POUND).adoptPerUnit(new MeasureUnit(SQUARE_MILE)), + Locale::getEnglish(), + u"87,650 lb/mi²", + u"8,765 lb/mi²", + u"876.5 lb/mi²", + u"87.65 lb/mi²", + u"8.765 lb/mi²", + u"0.8765 lb/mi²", + u"0.08765 lb/mi²", + u"0.008765 lb/mi²", + u"0 lb/mi²"); + + assertFormatDescending( + u"Joules Per Furlong Short (unit with no simplifications or special patterns)", + NumberFormatter::with().unit(JOULE).perUnit(FURLONG), + Locale::getEnglish(), + u"87,650 J/fur", + u"8,765 J/fur", + u"876.5 J/fur", + u"87.65 J/fur", + u"8.765 J/fur", + u"0.8765 J/fur", + u"0.08765 J/fur", + u"0.008765 J/fur", + u"0 J/fur"); } void NumberFormatterApiTest::unitCurrency() { @@ -547,6 +613,66 @@ void NumberFormatterApiTest::unitCurrency() { Locale::getEnglish(), -9876543.21, u"-£9,876,543.21"); + + // The full currency symbol is not shown in NARROW format. + // NOTE: This example is in the documentation. + assertFormatSingle( + u"Currency Difference between Narrow and Short (Narrow Version)", + NumberFormatter::with().unit(USD).unitWidth(UNUM_UNIT_WIDTH_NARROW), + Locale("en-CA"), + 5.43, + u"$5.43"); + + assertFormatSingle( + u"Currency Difference between Narrow and Short (Short Version)", + NumberFormatter::with().unit(USD).unitWidth(UNUM_UNIT_WIDTH_SHORT), + Locale("en-CA"), + 5.43, + u"US$5.43"); + + assertFormatSingle( + u"Currency-dependent format (Control)", + NumberFormatter::with().unit(USD).unitWidth(UNUM_UNIT_WIDTH_SHORT), + Locale("ca"), + 444444.55, + u"444.444,55 USD"); + + assertFormatSingle( + u"Currency-dependent format (Test)", + NumberFormatter::with().unit(ESP).unitWidth(UNUM_UNIT_WIDTH_SHORT), + Locale("ca"), + 444444.55, + u"₧ 444.445"); + + assertFormatSingle( + u"Currency-dependent symbols (Control)", + NumberFormatter::with().unit(USD).unitWidth(UNUM_UNIT_WIDTH_SHORT), + Locale("pt-PT"), + 444444.55, + u"444 444,55 US$"); + + // NOTE: This is a bit of a hack on CLDR's part. They set the currency symbol to U+200B (zero- + // width space), and they set the decimal separator to the $ symbol. + assertFormatSingle( + u"Currency-dependent symbols (Test Short)", + NumberFormatter::with().unit(PTE).unitWidth(UNUM_UNIT_WIDTH_SHORT), + Locale("pt-PT"), + 444444.55, + u"444,444$55 \u200B"); + + assertFormatSingle( + u"Currency-dependent symbols (Test Narrow)", + NumberFormatter::with().unit(PTE).unitWidth(UNUM_UNIT_WIDTH_NARROW), + Locale("pt-PT"), + 444444.55, + u"444,444$55 PTE"); + + assertFormatSingle( + u"Currency-dependent symbols (Test ISO Code)", + NumberFormatter::with().unit(PTE).unitWidth(UNUM_UNIT_WIDTH_ISO_CODE), + Locale("pt-PT"), + 444444.55, + u"444,444$55 PTE"); } void NumberFormatterApiTest::unitPercent() { @@ -765,6 +891,20 @@ void NumberFormatterApiTest::roundingFractionFigures() { u"0.09", u"0.01", u"0.00"); + + assertFormatSingle( + "FracSig with trailing zeros A", + NumberFormatter::with().rounding(Rounder::fixedFraction(2).withMinDigits(3)), + Locale::getEnglish(), + 0.1, + u"0.10"); + + assertFormatSingle( + "FracSig with trailing zeros B", + NumberFormatter::with().rounding(Rounder::fixedFraction(2).withMinDigits(3)), + Locale::getEnglish(), + 0.0999999, + u"0.10"); } void NumberFormatterApiTest::roundingOther() { @@ -889,7 +1029,7 @@ void NumberFormatterApiTest::roundingOther() { void NumberFormatterApiTest::grouping() { assertFormatDescendingBig( u"Western Grouping", - NumberFormatter::with().grouping(Grouper::defaults()), + NumberFormatter::with().grouping(UNUM_GROUPING_AUTO), Locale::getEnglish(), u"87,650,000", u"8,765,000", @@ -903,7 +1043,7 @@ void NumberFormatterApiTest::grouping() { assertFormatDescendingBig( u"Indic Grouping", - NumberFormatter::with().grouping(Grouper::defaults()), + NumberFormatter::with().grouping(UNUM_GROUPING_AUTO), Locale("en-IN"), u"8,76,50,000", u"87,65,000", @@ -917,7 +1057,7 @@ void NumberFormatterApiTest::grouping() { assertFormatDescendingBig( u"Western Grouping, Wide", - NumberFormatter::with().grouping(Grouper::minTwoDigits()), + NumberFormatter::with().grouping(UNUM_GROUPING_MIN2), Locale::getEnglish(), u"87,650,000", u"8,765,000", @@ -931,7 +1071,7 @@ void NumberFormatterApiTest::grouping() { assertFormatDescendingBig( u"Indic Grouping, Wide", - NumberFormatter::with().grouping(Grouper::minTwoDigits()), + NumberFormatter::with().grouping(UNUM_GROUPING_MIN2), Locale("en-IN"), u"8,76,50,000", u"87,65,000", @@ -945,7 +1085,7 @@ void NumberFormatterApiTest::grouping() { assertFormatDescendingBig( u"No Grouping", - NumberFormatter::with().grouping(Grouper::none()), + NumberFormatter::with().grouping(UNUM_GROUPING_OFF), Locale("en-IN"), u"87650000", u"8765000", @@ -956,6 +1096,111 @@ void NumberFormatterApiTest::grouping() { u"87.65", u"8.765", u"0"); + + assertFormatDescendingBig( + u"Indic locale with THOUSANDS grouping", + NumberFormatter::with().grouping(UNUM_GROUPING_THOUSANDS), + Locale("en-IN"), + u"87,650,000", + u"8,765,000", + u"876,500", + u"87,650", + u"8,765", + u"876.5", + u"87.65", + u"8.765", + u"0"); + + // NOTE: Hungarian is interesting because it has minimumGroupingDigits=4 in locale data + // If this test breaks due to data changes, find another locale that has minimumGroupingDigits. + assertFormatDescendingBig( + u"Hungarian Grouping", + NumberFormatter::with().grouping(UNUM_GROUPING_AUTO), + Locale("hu"), + u"87 650 000", + u"8 765 000", + u"876500", + u"87650", + u"8765", + u"876,5", + u"87,65", + u"8,765", + u"0"); + + assertFormatDescendingBig( + u"Hungarian Grouping, Min 2", + NumberFormatter::with().grouping(UNUM_GROUPING_MIN2), + Locale("hu"), + u"87 650 000", + u"8 765 000", + u"876500", + u"87650", + u"8765", + u"876,5", + u"87,65", + u"8,765", + u"0"); + + assertFormatDescendingBig( + u"Hungarian Grouping, Always", + NumberFormatter::with().grouping(UNUM_GROUPING_ON_ALIGNED), + Locale("hu"), + u"87 650 000", + u"8 765 000", + u"876 500", + u"87 650", + u"8 765", + u"876,5", + u"87,65", + u"8,765", + u"0"); + + // NOTE: Bulgarian is interesting because it has no grouping in the default currency format. + // If this test breaks due to data changes, find another locale that has no default grouping. + assertFormatDescendingBig( + u"Bulgarian Currency Grouping", + NumberFormatter::with().grouping(UNUM_GROUPING_AUTO).unit(USD), + Locale("bg"), + u"87650000,00 щ.д.", + u"8765000,00 щ.д.", + u"876500,00 щ.д.", + u"87650,00 щ.д.", + u"8765,00 щ.д.", + u"876,50 щ.д.", + u"87,65 щ.д.", + u"8,76 щ.д.", + u"0,00 щ.д."); + + assertFormatDescendingBig( + u"Bulgarian Currency Grouping, Always", + NumberFormatter::with().grouping(UNUM_GROUPING_ON_ALIGNED).unit(USD), + Locale("bg"), + u"87 650 000,00 щ.д.", + u"8 765 000,00 щ.д.", + u"876 500,00 щ.д.", + u"87 650,00 щ.д.", + u"8 765,00 щ.д.", + u"876,50 щ.д.", + u"87,65 щ.д.", + u"8,76 щ.д.", + u"0,00 щ.д."); + + // TODO: Enable this test when macro-setter is available in C++ + // MacroProps macros; + // macros.grouping = Grouper(4, 1, 3); + // assertFormatDescendingBig( + // u"Custom Grouping via Internal API", + // NumberFormatter::with().macros(macros), + // Locale::getEnglish(), + // u"8,7,6,5,0000", + // u"8,7,6,5000", + // u"876500", + // u"87650", + // u"8765", + // u"876.5", + // u"87.65", + // u"8.765", + // u"0"); } void NumberFormatterApiTest::padding() { @@ -1241,9 +1486,9 @@ void NumberFormatterApiTest::symbols() { u"US$ 12,345.67"); assertFormatSingle( - u"Currency symbol should follow number in ar with NS arab", + u"Currency symbol should follow number in ar-EG with NS arab", NumberFormatter::with().unit(USD), - Locale("ar"), + Locale("ar-EG"), 12345.67, u"١٢٬٣٤٥٫٦٧ US$"); @@ -1254,7 +1499,22 @@ void NumberFormatterApiTest::symbols() { 12345.67, u"١٢٬٣٤٥٫٦٧ US$"); + assertFormatSingle( + u"NumberingSystem in API should win over @numbers keyword", + NumberFormatter::with().adoptSymbols(new NumberingSystem(LATN)).unit(USD), + Locale("ar@numbers=arab"), + 12345.67, + u"US$ 12,345.67"); + UErrorCode status = U_ZERO_ERROR; + assertEquals("NumberingSystem in API should win over @numbers keyword in reverse order", + u"US$ 12,345.67", + NumberFormatter::withLocale(Locale("ar@numbers=arab")) + .adoptSymbols(new NumberingSystem(LATN)) + .unit(USD) + .formatDouble(12345.67, status) + .toString()); + DecimalFormatSymbols symbols = SWISS_SYMBOLS; UnlocalizedNumberFormatter f = NumberFormatter::with().symbols(symbols); symbols.setSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kGroupingSeparatorSymbol, u"!", status); @@ -1305,6 +1565,13 @@ void NumberFormatterApiTest::sign() { u"-444,444"); assertFormatSingle( + u"Sign Auto Zero", + NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_AUTO), + Locale::getEnglish(), + 0, + u"0"); + + assertFormatSingle( u"Sign Always Positive", NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ALWAYS), Locale::getEnglish(), @@ -1319,6 +1586,13 @@ void NumberFormatterApiTest::sign() { u"-444,444"); assertFormatSingle( + u"Sign Always Zero", + NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ALWAYS), + Locale::getEnglish(), + 0, + u"+0"); + + assertFormatSingle( u"Sign Never Positive", NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_NEVER), Locale::getEnglish(), @@ -1333,6 +1607,13 @@ void NumberFormatterApiTest::sign() { u"444,444"); assertFormatSingle( + u"Sign Never Zero", + NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_NEVER), + Locale::getEnglish(), + 0, + u"0"); + + assertFormatSingle( u"Sign Accounting Positive", NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING).unit(USD), Locale::getEnglish(), @@ -1347,6 +1628,13 @@ void NumberFormatterApiTest::sign() { u"($444,444.00)"); assertFormatSingle( + u"Sign Accounting Zero", + NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING).unit(USD), + Locale::getEnglish(), + 0, + u"$0.00"); + + assertFormatSingle( u"Sign Accounting-Always Positive", NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_ALWAYS).unit(USD), Locale::getEnglish(), @@ -1361,6 +1649,55 @@ void NumberFormatterApiTest::sign() { u"($444,444.00)"); assertFormatSingle( + u"Sign Accounting-Always Zero", + NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_ALWAYS).unit(USD), + Locale::getEnglish(), + 0, + u"+$0.00"); + + assertFormatSingle( + u"Sign Except-Zero Positive", + NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_EXCEPT_ZERO), + Locale::getEnglish(), + 444444, + u"+444,444"); + + assertFormatSingle( + u"Sign Except-Zero Negative", + NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_EXCEPT_ZERO), + Locale::getEnglish(), + -444444, + u"-444,444"); + + assertFormatSingle( + u"Sign Except-Zero Zero", + NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_EXCEPT_ZERO), + Locale::getEnglish(), + 0, + u"0"); + + assertFormatSingle( + u"Sign Accounting-Except-Zero Positive", + NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO).unit(USD), + Locale::getEnglish(), + 444444, + u"+$444,444.00"); + + assertFormatSingle( + u"Sign Accounting-Except-Zero Negative", + NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO).unit(USD), + Locale::getEnglish(), + -444444, + u"($444,444.00)"); + + assertFormatSingle( + u"Sign Accounting-Except-Zero Zero", + NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO).unit(USD), + Locale::getEnglish(), + 0, + u"$0.00"); + + assertFormatSingle( u"Sign Accounting Negative Hidden", NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING) .unit(USD) @@ -1426,14 +1763,14 @@ void NumberFormatterApiTest::errors() { UErrorCode status2 = U_ZERO_ERROR; FormattedNumber fn = lnf.formatInt(1, status1); assertEquals( - "Should fail with U_ILLEGAL_ARGUMENT_ERROR since rounder is not legal", - U_ILLEGAL_ARGUMENT_ERROR, + "Should fail since rounder is not legal", + U_NUMBER_ARG_OUTOFBOUNDS_ERROR, status1); FieldPosition fp; fn.populateFieldPosition(fp, status2); assertEquals( - "Should fail with U_ILLEGAL_ARGUMENT_ERROR on terminal method", - U_ILLEGAL_ARGUMENT_ERROR, + "Should fail on terminal method", + U_NUMBER_ARG_OUTOFBOUNDS_ERROR, status2); } @@ -1441,12 +1778,68 @@ void NumberFormatterApiTest::errors() { UErrorCode status = U_ZERO_ERROR; lnf.copyErrorTo(status); assertEquals( - "Should fail with U_ILLEGAL_ARGUMENT_ERROR since rounder is not legal", - U_ILLEGAL_ARGUMENT_ERROR, + "Should fail since rounder is not legal", + U_NUMBER_ARG_OUTOFBOUNDS_ERROR, status); } } +void NumberFormatterApiTest::validRanges() { + +#define EXPECTED_MAX_INT_FRAC_SIG 999 + +#define VALID_RANGE_ASSERT(status, method, lowerBound, argument) { \ + UErrorCode expectedStatus = ((lowerBound <= argument) && (argument <= EXPECTED_MAX_INT_FRAC_SIG)) \ + ? U_ZERO_ERROR \ + : U_NUMBER_ARG_OUTOFBOUNDS_ERROR; \ + assertEquals( \ + UnicodeString(u"Incorrect status for " #method " on input ") \ + + Int64ToUnicodeString(argument), \ + expectedStatus, \ + status); \ +} + +#define VALID_RANGE_ONEARG(setting, method, lowerBound) { \ + for (int32_t argument = -2; argument <= EXPECTED_MAX_INT_FRAC_SIG + 2; argument++) { \ + UErrorCode status = U_ZERO_ERROR; \ + NumberFormatter::with().setting(method(argument)).copyErrorTo(status); \ + VALID_RANGE_ASSERT(status, method, lowerBound, argument); \ + } \ +} + +#define VALID_RANGE_TWOARGS(setting, method, lowerBound) { \ + for (int32_t argument = -2; argument <= EXPECTED_MAX_INT_FRAC_SIG + 2; argument++) { \ + UErrorCode status = U_ZERO_ERROR; \ + /* Pass EXPECTED_MAX_INT_FRAC_SIG as the second argument so arg1 <= arg2 in expected cases */ \ + NumberFormatter::with().setting(method(argument, EXPECTED_MAX_INT_FRAC_SIG)).copyErrorTo(status); \ + VALID_RANGE_ASSERT(status, method, lowerBound, argument); \ + status = U_ZERO_ERROR; \ + /* Pass lowerBound as the first argument so arg1 <= arg2 in expected cases */ \ + NumberFormatter::with().setting(method(lowerBound, argument)).copyErrorTo(status); \ + VALID_RANGE_ASSERT(status, method, lowerBound, argument); \ + /* Check that first argument must be less than or equal to second argument */ \ + NumberFormatter::with().setting(method(argument, argument - 1)).copyErrorTo(status); \ + assertEquals("Incorrect status for " #method " on max < min input", \ + U_NUMBER_ARG_OUTOFBOUNDS_ERROR, \ + status); \ + } \ +} + + VALID_RANGE_ONEARG(rounding, Rounder::fixedFraction, 0); + VALID_RANGE_ONEARG(rounding, Rounder::minFraction, 0); + VALID_RANGE_ONEARG(rounding, Rounder::maxFraction, 0); + VALID_RANGE_TWOARGS(rounding, Rounder::minMaxFraction, 0); + VALID_RANGE_ONEARG(rounding, Rounder::fixedDigits, 1); + VALID_RANGE_ONEARG(rounding, Rounder::minDigits, 1); + VALID_RANGE_ONEARG(rounding, Rounder::maxDigits, 1); + VALID_RANGE_TWOARGS(rounding, Rounder::minMaxDigits, 1); + VALID_RANGE_ONEARG(rounding, Rounder::fixedFraction(1).withMinDigits, 1); + VALID_RANGE_ONEARG(rounding, Rounder::fixedFraction(1).withMaxDigits, 1); + VALID_RANGE_ONEARG(notation, Notation::scientific().withMinExponentDigits, 1); + VALID_RANGE_ONEARG(integerWidth, IntegerWidth::zeroFillTo, 0); + VALID_RANGE_ONEARG(integerWidth, IntegerWidth::zeroFillTo(0).truncateAt, -1); +} + void NumberFormatterApiTest::assertFormatDescending(const UnicodeString &message, const UnlocalizedNumberFormatter &f, diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_decimalquantity.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_decimalquantity.cpp index b298b43219e..0cbcc524644 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_decimalquantity.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_decimalquantity.cpp @@ -20,6 +20,7 @@ void DecimalQuantityTest::runIndexedTest(int32_t index, UBool exec, const char * TESTCASE_AUTO(testAppend); TESTCASE_AUTO(testConvertToAccurateDouble); TESTCASE_AUTO(testUseApproximateDoubleWhenAble); + TESTCASE_AUTO(testHardDoubleConversion); TESTCASE_AUTO_END; } @@ -233,7 +234,7 @@ void DecimalQuantityTest::testConvertToAccurateDouble() { } void DecimalQuantityTest::testUseApproximateDoubleWhenAble() { - struct TestCase { + static const struct TestCase { double d; int32_t maxFrac; RoundingMode roundingMode; @@ -264,4 +265,33 @@ void DecimalQuantityTest::testUseApproximateDoubleWhenAble() { } } +void DecimalQuantityTest::testHardDoubleConversion() { + static const struct TestCase { + double input; + const char16_t* expectedOutput; + } cases[] = { + { 512.0000000000017, u"512.0000000000017" }, + { 4095.9999999999977, u"4095.9999999999977" }, + { 4095.999999999998, u"4095.999999999998" }, + { 4095.9999999999986, u"4095.9999999999986" }, + { 4095.999999999999, u"4095.999999999999" }, + { 4095.9999999999995, u"4095.9999999999995" }, + { 4096.000000000001, u"4096.000000000001" }, + { 4096.000000000002, u"4096.000000000002" }, + { 4096.000000000003, u"4096.000000000003" }, + { 4096.000000000004, u"4096.000000000004" }, + { 4096.000000000005, u"4096.000000000005" }, + { 4096.0000000000055, u"4096.0000000000055" }, + { 4096.000000000006, u"4096.000000000006" }, + { 4096.000000000007, u"4096.000000000007" } }; + + for (auto& cas : cases) { + DecimalQuantity q; + q.setToDouble(cas.input); + q.roundToInfinity(); + UnicodeString actualOutput = q.toPlainString(); + assertEquals("", cas.expectedOutput, actualOutput); + } +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_doubleconversion.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_doubleconversion.cpp new file mode 100644 index 00000000000..a52865d8d3d --- /dev/null +++ b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_doubleconversion.cpp @@ -0,0 +1,45 @@ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING && !UPRV_INCOMPLETE_CPP11_SUPPORT + +#include "numbertest.h" +#include "double-conversion.h" + +using namespace double_conversion; + +void DoubleConversionTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char *) { + if (exec) { + logln("TestSuite DoubleConversionTest: "); + } + TESTCASE_AUTO_BEGIN; + TESTCASE_AUTO(testDoubleConversionApi); + TESTCASE_AUTO_END; +} + +void DoubleConversionTest::testDoubleConversionApi() { + double v = 87.65; + char buffer[DoubleToStringConverter::kBase10MaximalLength + 1]; + bool sign; + int32_t length; + int32_t point; + + DoubleToStringConverter::DoubleToAscii( + v, + DoubleToStringConverter::DtoaMode::SHORTEST, + 0, + buffer, + sizeof(buffer), + &sign, + &length, + &point + ); + + UnicodeString result(buffer, length); + assertEquals("Digits", u"8765", result); + assertEquals("Scale", 2, point); +} + +#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_modifiers.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_modifiers.cpp index 279df757f69..bebb3f8b2b6 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_modifiers.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_modifiers.cpp @@ -38,13 +38,13 @@ void ModifiersTest::testConstantMultiFieldModifier() { UErrorCode status = U_ZERO_ERROR; NumberStringBuilder prefix; NumberStringBuilder suffix; - ConstantMultiFieldModifier mod1(prefix, suffix, true); + ConstantMultiFieldModifier mod1(prefix, suffix, false, true); assertModifierEquals(mod1, 0, true, u"|", u"n", status); assertSuccess("Spot 1", status); prefix.append(u"a📻", UNUM_PERCENT_FIELD, status); suffix.append(u"b", UNUM_CURRENCY_FIELD, status); - ConstantMultiFieldModifier mod2(prefix, suffix, true); + ConstantMultiFieldModifier mod2(prefix, suffix, false, true); assertModifierEquals(mod2, 3, true, u"a📻|b", u"%%%n$", status); assertSuccess("Spot 2", status); @@ -105,14 +105,14 @@ void ModifiersTest::testCurrencySpacingEnabledModifier() { NumberStringBuilder prefix; NumberStringBuilder suffix; - CurrencySpacingEnabledModifier mod1(prefix, suffix, true, symbols, status); + CurrencySpacingEnabledModifier mod1(prefix, suffix, false, true, symbols, status); assertSuccess("Spot 2", status); assertModifierEquals(mod1, 0, true, u"|", u"n", status); assertSuccess("Spot 3", status); prefix.append(u"USD", UNUM_CURRENCY_FIELD, status); assertSuccess("Spot 4", status); - CurrencySpacingEnabledModifier mod2(prefix, suffix, true, symbols, status); + CurrencySpacingEnabledModifier mod2(prefix, suffix, false, true, symbols, status); assertSuccess("Spot 5", status); assertModifierEquals(mod2, 3, true, u"USD|", u"$$$n", status); assertSuccess("Spot 6", status); @@ -138,7 +138,7 @@ void ModifiersTest::testCurrencySpacingEnabledModifier() { symbols.setPatternForCurrencySpacing(UNUM_CURRENCY_SURROUNDING_MATCH, true, u"[|]"); suffix.append("XYZ", UNUM_CURRENCY_FIELD, status); assertSuccess("Spot 11", status); - CurrencySpacingEnabledModifier mod3(prefix, suffix, true, symbols, status); + CurrencySpacingEnabledModifier mod3(prefix, suffix, false, true, symbols, status); assertSuccess("Spot 12", status); assertModifierEquals(mod3, 3, true, u"USD|\u00A0XYZ", u"$$$nn$$$", status); assertSuccess("Spot 13", status); diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_patternmodifier.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_patternmodifier.cpp index f30203ea80c..79c99e9c224 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_patternmodifier.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_patternmodifier.cpp @@ -14,6 +14,7 @@ void PatternModifierTest::runIndexedTest(int32_t index, UBool exec, const char * } TESTCASE_AUTO_BEGIN; TESTCASE_AUTO(testBasic); + TESTCASE_AUTO(testPatternWithNoPlaceholder); TESTCASE_AUTO(testMutableEqualsImmutable); TESTCASE_AUTO_END; } @@ -31,13 +32,19 @@ void PatternModifierTest::testBasic() { assertSuccess("Spot 2", status); mod.setSymbols(&symbols, currency, UNUM_UNIT_WIDTH_SHORT, nullptr); - mod.setNumberProperties(false, StandardPlural::Form::COUNT); + mod.setNumberProperties(1, StandardPlural::Form::COUNT); assertEquals("Pattern a0b", u"a", getPrefix(mod, status)); assertEquals("Pattern a0b", u"b", getSuffix(mod, status)); mod.setPatternAttributes(UNUM_SIGN_ALWAYS, false); assertEquals("Pattern a0b", u"+a", getPrefix(mod, status)); assertEquals("Pattern a0b", u"b", getSuffix(mod, status)); - mod.setNumberProperties(true, StandardPlural::Form::COUNT); + mod.setNumberProperties(0, StandardPlural::Form::COUNT); + assertEquals("Pattern a0b", u"+a", getPrefix(mod, status)); + assertEquals("Pattern a0b", u"b", getSuffix(mod, status)); + mod.setPatternAttributes(UNUM_SIGN_EXCEPT_ZERO, false); + assertEquals("Pattern a0b", u"a", getPrefix(mod, status)); + assertEquals("Pattern a0b", u"b", getSuffix(mod, status)); + mod.setNumberProperties(-1, StandardPlural::Form::COUNT); assertEquals("Pattern a0b", u"-a", getPrefix(mod, status)); assertEquals("Pattern a0b", u"b", getSuffix(mod, status)); mod.setPatternAttributes(UNUM_SIGN_NEVER, false); @@ -50,24 +57,69 @@ void PatternModifierTest::testBasic() { assertSuccess("Spot 4", status); mod.setPatternInfo(&patternInfo2); mod.setPatternAttributes(UNUM_SIGN_AUTO, false); - mod.setNumberProperties(false, StandardPlural::Form::COUNT); + mod.setNumberProperties(1, StandardPlural::Form::COUNT); assertEquals("Pattern a0b;c-0d", u"a", getPrefix(mod, status)); assertEquals("Pattern a0b;c-0d", u"b", getSuffix(mod, status)); mod.setPatternAttributes(UNUM_SIGN_ALWAYS, false); assertEquals("Pattern a0b;c-0d", u"c+", getPrefix(mod, status)); assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status)); - mod.setNumberProperties(true, StandardPlural::Form::COUNT); + mod.setNumberProperties(0, StandardPlural::Form::COUNT); + assertEquals("Pattern a0b;c-0d", u"c+", getPrefix(mod, status)); + assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status)); + mod.setPatternAttributes(UNUM_SIGN_EXCEPT_ZERO, false); + assertEquals("Pattern a0b;c-0d", u"a", getPrefix(mod, status)); + assertEquals("Pattern a0b;c-0d", u"b", getSuffix(mod, status)); + mod.setNumberProperties(-1, StandardPlural::Form::COUNT); assertEquals("Pattern a0b;c-0d", u"c-", getPrefix(mod, status)); assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status)); mod.setPatternAttributes(UNUM_SIGN_NEVER, false); - assertEquals( - "Pattern a0b;c-0d", - u"c-", - getPrefix(mod, status)); // TODO: What should this behavior be? + // TODO: What should this behavior be? + assertEquals("Pattern a0b;c-0d", u"c-", getPrefix(mod, status)); assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status)); assertSuccess("Spot 5", status); } +void PatternModifierTest::testPatternWithNoPlaceholder() { + UErrorCode status = U_ZERO_ERROR; + MutablePatternModifier mod(false); + ParsedPatternInfo patternInfo; + PatternParser::parseToPatternInfo(u"abc", patternInfo, status); + assertSuccess("Spot 1", status); + mod.setPatternInfo(&patternInfo); + mod.setPatternAttributes(UNUM_SIGN_AUTO, false); + DecimalFormatSymbols symbols(Locale::getEnglish(), status); + CurrencyUnit currency(u"USD", status); + assertSuccess("Spot 2", status); + mod.setSymbols(&symbols, currency, UNUM_UNIT_WIDTH_SHORT, nullptr); + mod.setNumberProperties(1, StandardPlural::Form::COUNT); + + // Unsafe Code Path + NumberStringBuilder nsb; + nsb.append(u"x123y", UNUM_FIELD_COUNT, status); + assertSuccess("Spot 3", status); + mod.apply(nsb, 1, 4, status); + assertSuccess("Spot 4", status); + assertEquals("Unsafe Path", u"xabcy", nsb.toUnicodeString()); + + // Safe Code Path + nsb.clear(); + nsb.append(u"x123y", UNUM_FIELD_COUNT, status); + assertSuccess("Spot 5", status); + MicroProps micros; + LocalPointer<ImmutablePatternModifier> imod(mod.createImmutable(status), status); + if (U_FAILURE(status)) { + dataerrln("%s %d Error in ImmutablePatternModifier creation", + __FILE__, __LINE__); + assertSuccess("Spot 6", status); + return; + } + DecimalQuantity quantity; + imod->applyToMicros(micros, quantity); + micros.modMiddle->apply(nsb, 1, 4, status); + assertSuccess("Spot 7", status); + assertEquals("Safe Path", u"xabcy", nsb.toUnicodeString()); +} + void PatternModifierTest::testMutableEqualsImmutable() { UErrorCode status = U_ZERO_ERROR; MutablePatternModifier mod(false); diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_stringbuilder.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_stringbuilder.cpp index 323c4bd6859..76d27e1b12a 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_stringbuilder.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_stringbuilder.cpp @@ -23,6 +23,7 @@ void NumberStringBuilderTest::runIndexedTest(int32_t index, UBool exec, const ch } TESTCASE_AUTO_BEGIN; TESTCASE_AUTO(testInsertAppendUnicodeString); + TESTCASE_AUTO(testSplice); TESTCASE_AUTO(testInsertAppendCodePoint); TESTCASE_AUTO(testCopy); TESTCASE_AUTO(testFields); @@ -75,6 +76,55 @@ void NumberStringBuilderTest::testInsertAppendUnicodeString() { } } +void NumberStringBuilderTest::testSplice() { + const struct TestCase { + const char16_t* input; + const int32_t startThis; + const int32_t endThis; + } cases[] = { + { u"", 0, 0 }, + { u"abc", 0, 0 }, + { u"abc", 1, 1 }, + { u"abc", 1, 2 }, + { u"abc", 0, 2 }, + { u"abc", 0, 3 }, + { u"lorem ipsum dolor sit amet", 8, 8 }, + { u"lorem ipsum dolor sit amet", 8, 11 }, // 3 chars, equal to replacement "xyz" + { u"lorem ipsum dolor sit amet", 8, 18 } }; // 10 chars, larger than several replacements + + UErrorCode status = U_ZERO_ERROR; + UnicodeString sb1; + NumberStringBuilder sb2; + for (auto cas : cases) { + for (const char16_t* replacementPtr : EXAMPLE_STRINGS) { + UnicodeString replacement(replacementPtr); + + // Test replacement with full string + sb1.remove(); + sb1.append(cas.input); + sb1.replace(cas.startThis, cas.endThis - cas.startThis, replacement); + sb2.clear(); + sb2.append(cas.input, UNUM_FIELD_COUNT, status); + sb2.splice(cas.startThis, cas.endThis, replacement, 0, replacement.length(), UNUM_FIELD_COUNT, status); + assertSuccess("Splicing into sb2 first time", status); + assertEqualsImpl(sb1, sb2); + + // Test replacement with partial string + if (replacement.length() <= 2) { + continue; + } + sb1.remove(); + sb1.append(cas.input); + sb1.replace(cas.startThis, cas.endThis - cas.startThis, UnicodeString(replacement, 1, 2)); + sb2.clear(); + sb2.append(cas.input, UNUM_FIELD_COUNT, status); + sb2.splice(cas.startThis, cas.endThis, replacement, 1, 3, UNUM_FIELD_COUNT, status); + assertSuccess("Splicing into sb2 second time", status); + assertEqualsImpl(sb1, sb2); + } + } +} + void NumberStringBuilderTest::testInsertAppendCodePoint() { static const UChar32 cases[] = { 0, 1, 60, 127, 128, 0x7fff, 0x8000, 0xffff, 0x10000, 0x1f000, 0x10ffff}; @@ -230,7 +280,8 @@ void NumberStringBuilderTest::assertEqualsImpl(const UnicodeString &a, const Num for (int32_t i = 0; i < a.length(); i++) { IntlTest::assertEquals( UnicodeString(u"Char at position ") + Int64ToUnicodeString(i) + - UnicodeString(u" in string ") + a, a.charAt(i), b.charAt(i)); + UnicodeString(u" in \"") + a + UnicodeString("\" versus \"") + + b.toUnicodeString() + UnicodeString("\""), a.charAt(i), b.charAt(i)); } } diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numfmtst.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/numfmtst.cpp index fc562f385ac..c8fce9e28b6 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/numfmtst.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/numfmtst.cpp @@ -42,7 +42,7 @@ #include "unicode/msgfmt.h" #if (U_PLATFORM == U_PF_AIX) || (U_PLATFORM == U_PF_OS390) -// These should not be macros. If they are, +// These should not be macros. If they are, // replace them with std::isnan and std::isinf #if defined(isnan) #undef isnan @@ -229,6 +229,9 @@ static void adjustDecimalFormat( if (tuple.negativeSuffixFlag) { fmt.setNegativeSuffix(tuple.negativeSuffix); } + if (tuple.signAlwaysShownFlag) { + // Not currently supported + } if (tuple.localizedPatternFlag) { UErrorCode status = U_ZERO_ERROR; fmt.applyLocalizedPattern(tuple.localizedPattern, status); @@ -581,8 +584,8 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n TESTCASE_AUTO(TestFieldPositionIterator); TESTCASE_AUTO(TestDecimal); TESTCASE_AUTO(TestCurrencyFractionDigits); - TESTCASE_AUTO(TestExponentParse); - TESTCASE_AUTO(TestExplicitParents); + TESTCASE_AUTO(TestExponentParse); + TESTCASE_AUTO(TestExplicitParents); TESTCASE_AUTO(TestLenientParse); TESTCASE_AUTO(TestAvailableNumberingSystems); TESTCASE_AUTO(TestRoundingPattern); @@ -623,6 +626,8 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n TESTCASE_AUTO(Test11649_toPatternWithMultiCurrency); TESTCASE_AUTO(Test13327_numberingSystemBufferOverflow); TESTCASE_AUTO(Test13391_chakmaParsing); + TESTCASE_AUTO(Test11035_FormatCurrencyAmount); + TESTCASE_AUTO(Test11318_DoubleConversion); TESTCASE_AUTO_END; } @@ -1458,19 +1463,19 @@ NumberFormatTest::TestLenientParse(void) Locale en_US("en_US"); Locale sv_SE("sv_SE"); - + NumberFormat *mFormat = NumberFormat::createInstance(sv_SE, UNUM_DECIMAL, status); - + if (mFormat == NULL || U_FAILURE(status)) { dataerrln("Unable to create NumberFormat (sv_SE, UNUM_DECIMAL) - %s", u_errorName(status)); } else { mFormat->setLenient(TRUE); for (int32_t t = 0; t < UPRV_LENGTHOF(lenientMinusTestCases); t += 1) { UnicodeString testCase = ctou(lenientMinusTestCases[t]); - + mFormat->parse(testCase, n, status); logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong()); - + if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) { errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t] + (UnicodeString) "\""); status = U_ZERO_ERROR; @@ -1478,19 +1483,19 @@ NumberFormatTest::TestLenientParse(void) } delete mFormat; } - + mFormat = NumberFormat::createInstance(en_US, UNUM_DECIMAL, status); - + if (mFormat == NULL || U_FAILURE(status)) { dataerrln("Unable to create NumberFormat (en_US, UNUM_DECIMAL) - %s", u_errorName(status)); } else { mFormat->setLenient(TRUE); for (int32_t t = 0; t < UPRV_LENGTHOF(lenientMinusTestCases); t += 1) { UnicodeString testCase = ctou(lenientMinusTestCases[t]); - + mFormat->parse(testCase, n, status); logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong()); - + if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) { errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t] + (UnicodeString) "\""); status = U_ZERO_ERROR; @@ -1498,7 +1503,7 @@ NumberFormatTest::TestLenientParse(void) } delete mFormat; } - + NumberFormat *cFormat = NumberFormat::createInstance(en_US, UNUM_CURRENCY, status); if (cFormat == NULL || U_FAILURE(status)) { @@ -1572,10 +1577,10 @@ NumberFormatTest::TestLenientParse(void) // Test cases that should fail with a strict parse and pass with a // lenient parse. NumberFormat *nFormat = NumberFormat::createInstance(en_US, status); - + if (nFormat == NULL || U_FAILURE(status)) { dataerrln("Unable to create NumberFormat (en_US) - %s", u_errorName(status)); - } else { + } else { // first, make sure that they fail with a strict parse for (int32_t t = 0; t < UPRV_LENGTHOF(strictFailureTestCases); t += 1) { UnicodeString testCase = ctou(strictFailureTestCases[t]); @@ -2311,30 +2316,54 @@ void NumberFormatTest::TestCurrencyNames(void) { const UBool possibleDataError = TRUE; // Warning: HARD-CODED LOCALE DATA in this test. If it fails, CHECK // THE LOCALE DATA before diving into the code. - assertEquals("USD.getName(SYMBOL_NAME)", + assertEquals("USD.getName(SYMBOL_NAME, en)", UnicodeString("$"), UnicodeString(ucurr_getName(USD, "en", UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &ec)), possibleDataError); - assertEquals("USD.getName(LONG_NAME)", + assertEquals("USD.getName(NARROW_SYMBOL_NAME, en)", + UnicodeString("$"), + UnicodeString(ucurr_getName(USD, "en", + UCURR_NARROW_SYMBOL_NAME, + &isChoiceFormat, &len, &ec)), + possibleDataError); + assertEquals("USD.getName(LONG_NAME, en)", UnicodeString("US Dollar"), UnicodeString(ucurr_getName(USD, "en", UCURR_LONG_NAME, &isChoiceFormat, &len, &ec)), possibleDataError); - assertEquals("CAD.getName(SYMBOL_NAME)", + assertEquals("CAD.getName(SYMBOL_NAME, en)", UnicodeString("CA$"), UnicodeString(ucurr_getName(CAD, "en", UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &ec)), possibleDataError); - assertEquals("CAD.getName(SYMBOL_NAME)", + assertEquals("CAD.getName(NARROW_SYMBOL_NAME, en)", + UnicodeString("$"), + UnicodeString(ucurr_getName(CAD, "en", + UCURR_NARROW_SYMBOL_NAME, + &isChoiceFormat, &len, &ec)), + possibleDataError); + assertEquals("CAD.getName(SYMBOL_NAME, en_CA)", UnicodeString("$"), UnicodeString(ucurr_getName(CAD, "en_CA", UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &ec)), possibleDataError); + assertEquals("USD.getName(SYMBOL_NAME, en_CA)", + UnicodeString("US$"), + UnicodeString(ucurr_getName(USD, "en_CA", + UCURR_SYMBOL_NAME, + &isChoiceFormat, &len, &ec)), + possibleDataError); + assertEquals("USD.getName(NARROW_SYMBOL_NAME, en_CA)", + UnicodeString("$"), + UnicodeString(ucurr_getName(USD, "en_CA", + UCURR_NARROW_SYMBOL_NAME, + &isChoiceFormat, &len, &ec)), + possibleDataError); assertEquals("USD.getName(SYMBOL_NAME) in en_NZ", UnicodeString("US$"), UnicodeString(ucurr_getName(USD, "en_NZ", @@ -2347,6 +2376,18 @@ void NumberFormatTest::TestCurrencyNames(void) { UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &ec)), possibleDataError); + assertEquals("USX.getName(SYMBOL_NAME)", + UnicodeString("USX"), + UnicodeString(ucurr_getName(USX, "en_US", + UCURR_SYMBOL_NAME, + &isChoiceFormat, &len, &ec)), + possibleDataError); + assertEquals("USX.getName(NARROW_SYMBOL_NAME)", + UnicodeString("USX"), + UnicodeString(ucurr_getName(USX, "en_US", + UCURR_NARROW_SYMBOL_NAME, + &isChoiceFormat, &len, &ec)), + possibleDataError); assertEquals("USX.getName(LONG_NAME)", UnicodeString("USX"), UnicodeString(ucurr_getName(USX, "en_US", @@ -2497,7 +2538,7 @@ void NumberFormatTest::TestSymbolsWithBadLocale(void) { UnicodeString intlCurrencySymbol((UChar)0xa4); intlCurrencySymbol.append((UChar)0xa4); - + logln("Current locale is %s", Locale::getDefault().getName()); Locale::setDefault(locBad, status); logln("Current locale is %s", Locale::getDefault().getName()); @@ -3208,7 +3249,7 @@ void NumberFormatTest::TestCompatibleCurrencies() { expectParseCurrency(*fmtJP, JPY, 1235, "\\u00A51,235"); logln("%s:%d - testing parse of fullwidth yen sign in JP\n", __FILE__, __LINE__); expectParseCurrency(*fmtJP, JPY, 1235, "\\uFFE51,235"); - + // more.. */ } @@ -3228,7 +3269,7 @@ void NumberFormatTest::expectParseCurrency(const NumberFormat &fmt, const UChar* fmt.getLocale(ULOC_ACTUAL_LOCALE, status).getBaseName(), text); u_austrcpy(theInfo+uprv_strlen(theInfo), currency); - + char theOperation[100]; uprv_strcpy(theOperation, theInfo); @@ -3239,7 +3280,7 @@ void NumberFormatTest::expectParseCurrency(const NumberFormat &fmt, const UChar* uprv_strcat(theOperation, ", check currency:"); assertEquals(theOperation, currency, currencyAmount->getISOCurrency()); } - + void NumberFormatTest::TestJB3832(){ const char* localeID = "pt_PT@currency=PTE"; @@ -3672,7 +3713,7 @@ void NumberFormatTest::TestNumberingSystems() { NumberFormat *fmt = (NumberFormat *) origFmt->clone(); delete origFmt; - + if (item->isRBNF) { expect3(*fmt,item->value,CharsToUnicodeString(item->expectedResult)); } else { @@ -4044,7 +4085,7 @@ for (;;) { UErrorCode status = U_ZERO_ERROR; NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status); logln("#%d NumberFormat(%s, %s) Currency=%s\n", - i, localeString, currencyStyleNames[kIndex], + i, localeString, currencyStyleNames[kIndex], currencyISOCode); if (U_FAILURE(status)) { @@ -4063,6 +4104,8 @@ for (;;) { UnicodeString strBuf; numFmt->format(numberToBeFormat, strBuf); + // TODO: Re-enable the following test block. It has been disabled since + // the code was first checked-in (r25497) /* int resultDataIndex = 3 + kIndex; // DATA[i][resultDataIndex] is the currency format result @@ -6802,7 +6845,7 @@ void NumberFormatTest::TestFormatAttributes() { DecimalFormat *decFmt = (DecimalFormat *) NumberFormat::createInstance(locale, UNUM_CURRENCY, status); if (failure(status, "NumberFormat::createInstance", TRUE)) return; double val = 12345.67; - + { int32_t expected[] = { UNUM_CURRENCY_FIELD, 0, 1, @@ -6887,7 +6930,7 @@ const char* attrString(int32_t attrId) { // // Test formatting & parsing of big decimals. -// API test, not a comprehensive test. +// API test, not a comprehensive test. // See DecimalFormatTest/DataDrivenTests // #define ASSERT_SUCCESS(status) {if (U_FAILURE(status)) errln("file %s, line %d: status: %s", \ @@ -7020,7 +7063,7 @@ void NumberFormatTest::TestDecimal() { delete fmtr; } } - + #if U_PLATFORM != U_PF_CYGWIN || defined(CYGWINMSVC) /* * This test fails on Cygwin (1.7.16) using GCC because of a rounding issue with strtod(). @@ -7072,38 +7115,38 @@ void NumberFormatTest::TestCurrencyFractionDigits() { } } -void NumberFormatTest::TestExponentParse() { - - UErrorCode status = U_ZERO_ERROR; - Formattable result; - ParsePosition parsePos(0); - - // set the exponent symbol - status = U_ZERO_ERROR; - DecimalFormatSymbols *symbols = new DecimalFormatSymbols(Locale::getDefault(), status); - if(U_FAILURE(status)) { - dataerrln((UnicodeString)"ERROR: Could not create DecimalFormatSymbols (Default)"); - return; - } - - // create format instance - status = U_ZERO_ERROR; - DecimalFormat fmt("#####", symbols, status); - if(U_FAILURE(status)) { - errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols*)"); - } - - // parse the text - fmt.parse("5.06e-27", result, parsePos); - if(result.getType() != Formattable::kDouble && - result.getDouble() != 5.06E-27 && - parsePos.getIndex() != 8 - ) - { - errln("ERROR: parse failed - expected 5.06E-27, 8 - returned %d, %i", - result.getDouble(), parsePos.getIndex()); - } -} +void NumberFormatTest::TestExponentParse() { + + UErrorCode status = U_ZERO_ERROR; + Formattable result; + ParsePosition parsePos(0); + + // set the exponent symbol + status = U_ZERO_ERROR; + DecimalFormatSymbols *symbols = new DecimalFormatSymbols(Locale::getDefault(), status); + if(U_FAILURE(status)) { + dataerrln((UnicodeString)"ERROR: Could not create DecimalFormatSymbols (Default)"); + return; + } + + // create format instance + status = U_ZERO_ERROR; + DecimalFormat fmt("#####", symbols, status); + if(U_FAILURE(status)) { + errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols*)"); + } + + // parse the text + fmt.parse("5.06e-27", result, parsePos); + if(result.getType() != Formattable::kDouble && + result.getDouble() != 5.06E-27 && + parsePos.getIndex() != 8 + ) + { + errln("ERROR: parse failed - expected 5.06E-27, 8 - returned %d, %i", + result.getDouble(), parsePos.getIndex()); + } +} void NumberFormatTest::TestExplicitParents() { @@ -7186,13 +7229,13 @@ NumberFormatTest::Test9087(void) { U_STRING_DECL(pattern,"#",1); U_STRING_INIT(pattern,"#",1); - + U_STRING_DECL(infstr,"INF",3); U_STRING_INIT(infstr,"INF",3); U_STRING_DECL(nanstr,"NAN",3); U_STRING_INIT(nanstr,"NAN",3); - + UChar outputbuf[50] = {0}; UErrorCode status = U_ZERO_ERROR; UNumberFormat* fmt = unum_open(UNUM_PATTERN_DECIMAL,pattern,1,NULL,NULL,&status); @@ -7214,7 +7257,7 @@ NumberFormatTest::Test9087(void) UFieldPosition position = { 0, 0, 0}; unum_formatDouble(fmt,inf,outputbuf,50,&position,&status); - + if ( u_strcmp(infstr, outputbuf)) { errln((UnicodeString)"FAIL: unexpected result for infinity - expected " + infstr + " got " + outputbuf); } @@ -7235,7 +7278,7 @@ void NumberFormatTest::TestFormatFastpaths() { } #else infoln("NOTE: UCONFIG_FORMAT_FASTPATHS not set, test skipped."); -#endif +#endif // get some additional case { @@ -7498,9 +7541,9 @@ UBool NumberFormatTest::testFormattableAsUFormattable(const char *file, int line UErrorCode int64ConversionU = U_ZERO_ERROR; int64_t r = ufmt_getInt64(u, &int64ConversionU); - if( (l==r) + if( (l==r) && ( uType != UFMT_INT64 ) // int64 better not overflow - && (U_INVALID_FORMAT_ERROR==int64ConversionU) + && (U_INVALID_FORMAT_ERROR==int64ConversionU) && (U_INVALID_FORMAT_ERROR==int64ConversionF) ) { logln("%s:%d: OK: 64 bit overflow", file, line); } else { @@ -7625,7 +7668,7 @@ void NumberFormatTest::TestSignificantDigits(void) { numberFormat->setMinimumSignificantDigits(3); numberFormat->setMaximumSignificantDigits(5); numberFormat->setGroupingUsed(false); - + UnicodeString result; UnicodeString expectedResult; for (unsigned int i = 0; i < UPRV_LENGTHOF(input); ++i) { @@ -7647,7 +7690,7 @@ void NumberFormatTest::TestShowZero() { numberFormat->setSignificantDigitsUsed(TRUE); numberFormat->setMaximumSignificantDigits(3); - + UnicodeString result; numberFormat->format(0.0, result); if (result != "0") { @@ -7664,7 +7707,7 @@ void NumberFormatTest::TestBug9936() { dataerrln("File %s, Line %d: status = %s.\n", __FILE__, __LINE__, u_errorName(status)); return; } - + if (numberFormat->areSignificantDigitsUsed() == TRUE) { errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__, __LINE__); } @@ -7688,7 +7731,7 @@ void NumberFormatTest::TestBug9936() { if (numberFormat->areSignificantDigitsUsed() == FALSE) { errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__, __LINE__); } - + } void NumberFormatTest::TestParseNegativeWithFaLocale() { @@ -7779,7 +7822,7 @@ void NumberFormatTest::TestParseSignsAndMarks() { { "en@numbers=arabext", FALSE, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 }, { "en@numbers=arabext", TRUE, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 }, { "en@numbers=arabext", TRUE, CharsToUnicodeString("\\u200E-\\u200E \\u06F6\\u06F7"), -67 }, - + { "he", FALSE, CharsToUnicodeString("12"), 12 }, { "he", TRUE, CharsToUnicodeString("12"), 12 }, { "he", FALSE, CharsToUnicodeString("-23"), -23 }, @@ -7908,7 +7951,7 @@ void NumberFormatTest::Test10468ApplyPattern() { // explicit padding char is specified in the new pattern. fmt.applyPattern("AA#,##0.00ZZ", status); - // Oops this still prints 'a' even though we changed the pattern. + // Oops this still prints 'a' even though we changed the pattern. if (fmt.getPadCharacterString() != UnicodeString(" ")) { errln("applyPattern did not clear padding character."); } @@ -7921,7 +7964,7 @@ void NumberFormatTest::TestRoundingScientific10542() { errcheckln(status, "DecimalFormat constructor failed - %s", u_errorName(status)); return; } - + DecimalFormat::ERoundingMode roundingModes[] = { DecimalFormat::kRoundCeiling, DecimalFormat::kRoundDown, @@ -7938,7 +7981,7 @@ void NumberFormatTest::TestRoundingScientific10542() { "Round half even", "Round half up", "Round up"}; - + { double values[] = {-0.003006, -0.003005, -0.003004, 0.003014, 0.003015, 0.003016}; // The order of these expected values correspond to the order of roundingModes and the order of values. @@ -8231,7 +8274,7 @@ void NumberFormatTest::TestCurrencyUsage() { assertEquals("Test Currency Usage 3", UnicodeString("CA$123.57"), original_rounding); fmt->setCurrencyUsage(UCURR_USAGE_CASH, &status); }else{ - fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CASH_CURRENCY, status); + fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CASH_CURRENCY, status); if (assertSuccess("en_US@currency=CAD/CASH", status, TRUE) == FALSE) { continue; } @@ -8632,7 +8675,7 @@ void NumberFormatTest::Test10727_RoundingZero() { DigitList d; d.set(-0.0); assertFalse("", d.isPositive()); - d.round(3); + d.round(3); assertFalse("", d.isPositive()); } @@ -8648,7 +8691,7 @@ void NumberFormatTest::Test11376_getAndSetPositivePrefix() { DecimalFormat *dfmt = (DecimalFormat *) fmt.getAlias(); dfmt->setCurrency(USD); UnicodeString result; - + // This line should be a no-op. I am setting the positive prefix // to be the same thing it was before. dfmt->setPositivePrefix(dfmt->getPositivePrefix(result)); @@ -8772,7 +8815,7 @@ void NumberFormatTest::Test11649_toPatternWithMultiCurrency() { static UChar USD[] = {0x55, 0x53, 0x44, 0x0}; fmt.setCurrency(USD); UnicodeString appendTo; - + assertEquals("", "US dollars 12.34", fmt.format(12.34, appendTo)); UnicodeString topattern; @@ -8782,7 +8825,7 @@ void NumberFormatTest::Test11649_toPatternWithMultiCurrency() { return; } fmt2.setCurrency(USD); - + appendTo.remove(); assertEquals("", "US dollars 12.34", fmt2.format(12.34, appendTo)); } @@ -8883,4 +8926,49 @@ void NumberFormatTest::checkExceptionIssue11735() { assertEquals("Issue11735 ppos", 0, ppos.getIndex()); } +void NumberFormatTest::Test11035_FormatCurrencyAmount() { + UErrorCode status = U_ZERO_ERROR; + double amount = 12345.67; + const char16_t* expected = u"12,345$67 "; + + // Test two ways to set a currency via API + + Locale loc1 = Locale("pt_PT"); + LocalPointer<NumberFormat> fmt1(NumberFormat::createCurrencyInstance("loc1", status), + status); + if (U_FAILURE(status)) { + dataerrln("%s %d NumberFormat instance fmt1 is null", __FILE__, __LINE__); + return; + } + fmt1->setCurrency(u"PTE", status); + assertSuccess("Setting currency on fmt1", status); + UnicodeString actualSetCurrency; + fmt1->format(amount, actualSetCurrency); + + Locale loc2 = Locale("pt_PT@currency=PTE"); + LocalPointer<NumberFormat> fmt2(NumberFormat::createCurrencyInstance(loc2, status)); + assertSuccess("Creating fmt2", status); + UnicodeString actualLocaleString; + fmt2->format(amount, actualLocaleString); + + // TODO: The following test will fail until DecimalFormat wraps NumberFormatter. + if (!logKnownIssue("13574")) { + assertEquals("Custom Currency Pattern, Set Currency", expected, actualSetCurrency); + } +} + +void NumberFormatTest::Test11318_DoubleConversion() { + IcuTestErrorCode status(*this, "Test11318_DoubleConversion"); + LocalPointer<NumberFormat> nf(NumberFormat::createInstance("en", status), status); + if (U_FAILURE(status)) { + dataerrln("%s %d Error in NumberFormat instance creation", __FILE__, __LINE__); + return; + } + nf->setMaximumFractionDigits(40); + nf->setMaximumIntegerDigits(40); + UnicodeString appendTo; + nf->format(999999999999999.9, appendTo); + assertEquals("Should render all digits", u"999,999,999,999,999.9", appendTo); +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numfmtst.h b/Build/source/libs/icu/icu-src/source/test/intltest/numfmtst.h index 8477fcbcdb2..c212bea393a 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/numfmtst.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/numfmtst.h @@ -219,6 +219,8 @@ class NumberFormatTest: public CalendarTimeZoneTest { void Test13391_chakmaParsing(); void checkExceptionIssue11735(); + void Test11035_FormatCurrencyAmount(); + void Test11318_DoubleConversion(); private: UBool testFormattableAsUFormattable(const char *file, int line, Formattable &f); diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/rbbiapts.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/rbbiapts.cpp index 1a872907595..fa6ea066807 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/rbbiapts.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/rbbiapts.cpp @@ -1035,7 +1035,7 @@ void RBBIAPITest::RoundtripRule(const char *dataFile) { builtRules = (const uint8_t *)udata_getMemory(data.getAlias()); builtSource = (const UChar *)(builtRules + ((RBBIDataHeader*)builtRules)->fRuleSource); - RuleBasedBreakIterator *brkItr = new RuleBasedBreakIterator(builtSource, parseError, status); + LocalPointer<RuleBasedBreakIterator> brkItr (new RuleBasedBreakIterator(builtSource, parseError, status)); if (U_FAILURE(status)) { errln("%s:%d createRuleBasedBreakIterator: ICU Error \"%s\" at line %d, column %d\n", __FILE__, __LINE__, u_errorName(status), parseError.line, parseError.offset); @@ -1048,7 +1048,6 @@ void RBBIAPITest::RoundtripRule(const char *dataFile) { errln("%s:%d Built rules and rebuilt rules are different %s", __FILE__, __LINE__, dataFile); return; } - delete brkItr; } void RBBIAPITest::TestRoundtripRules() { diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.cpp index 25038627932..02785167d76 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.cpp @@ -17,6 +17,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <vector> #include "unicode/brkiter.h" #include "unicode/localpointer.h" @@ -39,10 +40,12 @@ #include "cstr.h" #include "intltest.h" #include "rbbitst.h" +#include "rbbidata.h" #include "utypeinfo.h" // for 'typeid' to work #include "uvector.h" #include "uvectr32.h" + #if !UCONFIG_NO_FILTERED_BREAK_ITERATION #include "unicode/filteredbrk.h" #endif // !UCONFIG_NO_FILTERED_BREAK_ITERATION @@ -75,7 +78,6 @@ void RBBITest::runIndexedTest( int32_t index, UBool exec, const char* &name, cha #endif #if !UCONFIG_NO_FILE_IO TESTCASE_AUTO(TestUnicodeFiles); - TESTCASE_AUTO(TestEmptyString); #endif TESTCASE_AUTO(TestGetAvailableLocales); TESTCASE_AUTO(TestGetDisplayName); @@ -106,151 +108,13 @@ void RBBITest::runIndexedTest( int32_t index, UBool exec, const char* &name, cha TESTCASE_AUTO(TestBug12932); TESTCASE_AUTO(TestEmoji); TESTCASE_AUTO(TestBug12519); + TESTCASE_AUTO(TestBug12677); + TESTCASE_AUTO(TestTableRedundancies); + TESTCASE_AUTO(TestBug13447); TESTCASE_AUTO_END; } -//--------------------------------------------------------------------------- -// -// class BITestData Holds a set of Break iterator test data and results -// Includes -// - the string data to be broken -// - a vector of the expected break positions. -// - a vector of source line numbers for the data, -// (to help see where errors occured.) -// - The expected break tag values. -// - Vectors of actual break positions and tag values. -// - Functions for comparing actual with expected and -// reporting errors. -// -//---------------------------------------------------------------------------- -class BITestData { -public: - UnicodeString fDataToBreak; - UVector fExpectedBreakPositions; - UVector fExpectedTags; - UVector fLineNum; - UVector fActualBreakPositions; // Test Results. - UVector fActualTags; - - BITestData(UErrorCode &status); - void addDataChunk(const char *data, int32_t tag, int32_t lineNum, UErrorCode status); - void checkResults(const char *heading, RBBITest *test); - void err(const char *heading, RBBITest *test, int32_t expectedIdx, int32_t actualIdx); - void clearResults(); -}; - -// -// Constructor. -// -BITestData::BITestData(UErrorCode &status) -: fExpectedBreakPositions(status), fExpectedTags(status), fLineNum(status), fActualBreakPositions(status), - fActualTags(status) -{ -} - -// -// addDataChunk. Add a section (non-breaking) piece if data to the test data. -// The macro form collects the line number, which is helpful -// when tracking down failures. -// -// A null data item is inserted at the start of each test's data -// to put the starting zero into the data list. The position saved for -// each non-null item is its ending position. -// -#define ADD_DATACHUNK(td, data, tag, status) td.addDataChunk(data, tag, __LINE__, status); -void BITestData::addDataChunk(const char *data, int32_t tag, int32_t lineNum, UErrorCode status) { - if (U_FAILURE(status)) {return;} - if (data != NULL) { - fDataToBreak.append(CharsToUnicodeString(data)); - } - fExpectedBreakPositions.addElement(fDataToBreak.length(), status); - fExpectedTags.addElement(tag, status); - fLineNum.addElement(lineNum, status); -} - - -// -// checkResults. Compare the actual and expected break positions, report any differences. -// -void BITestData::checkResults(const char *heading, RBBITest *test) { - int32_t expectedIndex = 0; - int32_t actualIndex = 0; - - for (;;) { - // If we've run through both the expected and actual results vectors, we're done. - // break out of the loop. - if (expectedIndex >= fExpectedBreakPositions.size() && - actualIndex >= fActualBreakPositions.size()) { - break; - } - - - if (expectedIndex >= fExpectedBreakPositions.size()) { - err(heading, test, expectedIndex-1, actualIndex); - actualIndex++; - continue; - } - - if (actualIndex >= fActualBreakPositions.size()) { - err(heading, test, expectedIndex, actualIndex-1); - expectedIndex++; - continue; - } - - if (fActualBreakPositions.elementAti(actualIndex) != fExpectedBreakPositions.elementAti(expectedIndex)) { - err(heading, test, expectedIndex, actualIndex); - // Try to resync the positions of the indices, to avoid a rash of spurious erros. - if (fActualBreakPositions.elementAti(actualIndex) < fExpectedBreakPositions.elementAti(expectedIndex)) { - actualIndex++; - } else { - expectedIndex++; - } - continue; - } - - if (fActualTags.elementAti(actualIndex) != fExpectedTags.elementAti(expectedIndex)) { - test->errln("%s, tag mismatch. Test Line = %d, expected tag=%d, got %d", - heading, fLineNum.elementAt(expectedIndex), - fExpectedTags.elementAti(expectedIndex), fActualTags.elementAti(actualIndex)); - } - - actualIndex++; - expectedIndex++; - } -} - -// -// err - An error was found. Report it, along with information about where the -// incorrectly broken test data appeared in the source file. -// -void BITestData::err(const char *heading, RBBITest *test, int32_t expectedIdx, int32_t actualIdx) -{ - int32_t expected = fExpectedBreakPositions.elementAti(expectedIdx); - int32_t actual = fActualBreakPositions.elementAti(actualIdx); - int32_t o = 0; - int32_t line = fLineNum.elementAti(expectedIdx); - if (expectedIdx > 0) { - // The line numbers are off by one because a premature break occurs somewhere - // within the previous item, rather than at the start of the current (expected) item. - // We want to report the offset of the unexpected break from the start of - // this previous item. - o = actual - fExpectedBreakPositions.elementAti(expectedIdx-1); - } - if (actual < expected) { - test->errln("%s unexpected break at offset %d in test item from line %d. actual break: %d expected break: %d", heading, o, line, actual, expected); - } else { - test->errln("%s Failed to find break at end of item from line %d. actual break: %d expected break: %d", heading, line, actual, expected); - } -} - - -void BITestData::clearResults() { - fActualBreakPositions.removeAllElements(); - fActualTags.removeAllElements(); -} - - //-------------------------------------------------------------------------------------- // // RBBITest constructor and destructor @@ -345,277 +209,12 @@ void RBBITest::TestBug3818() { delete bi; } -//---------------------------------------------------------------------------- -// -// generalIteratorTest Given a break iterator and a set of test data, -// Run the tests and report the results. -// -//---------------------------------------------------------------------------- -void RBBITest::generalIteratorTest(RuleBasedBreakIterator& bi, BITestData &td) -{ - - bi.setText(td.fDataToBreak); - - testFirstAndNext(bi, td); - - testLastAndPrevious(bi, td); - - testFollowing(bi, td); - testPreceding(bi, td); - testIsBoundary(bi, td); - doMultipleSelectionTest(bi, td); -} - - -// -// testFirstAndNext. Run the iterator forwards in the obvious first(), next() -// kind of loop. -// -void RBBITest::testFirstAndNext(RuleBasedBreakIterator& bi, BITestData &td) -{ - UErrorCode status = U_ZERO_ERROR; - int32_t p; - int32_t lastP = -1; - int32_t tag; - - logln("Test first and next"); - bi.setText(td.fDataToBreak); - td.clearResults(); - - for (p=bi.first(); p!=RuleBasedBreakIterator::DONE; p=bi.next()) { - td.fActualBreakPositions.addElement(p, status); // Save result. - tag = bi.getRuleStatus(); - td.fActualTags.addElement(tag, status); - if (p <= lastP) { - // If the iterator is not making forward progress, stop. - // No need to raise an error here, it'll be detected in the normal check of results. - break; - } - lastP = p; - } - td.checkResults("testFirstAndNext", this); -} - - -// -// TestLastAndPrevious. Run the iterator backwards, starting with last(). -// -void RBBITest::testLastAndPrevious(RuleBasedBreakIterator& bi, BITestData &td) -{ - UErrorCode status = U_ZERO_ERROR; - int32_t p; - int32_t lastP = 0x7ffffffe; - int32_t tag; - - logln("Test last and previous"); - bi.setText(td.fDataToBreak); - td.clearResults(); - - for (p=bi.last(); p!=RuleBasedBreakIterator::DONE; p=bi.previous()) { - // Save break position. Insert it at start of vector of results, shoving - // already-saved results further towards the end. - td.fActualBreakPositions.insertElementAt(p, 0, status); - // bi.previous(); // TODO: Why does this fix things up???? - // bi.next(); - tag = bi.getRuleStatus(); - td.fActualTags.insertElementAt(tag, 0, status); - if (p >= lastP) { - // If the iterator is not making progress, stop. - // No need to raise an error here, it'll be detected in the normal check of results. - break; - } - lastP = p; - } - td.checkResults("testLastAndPrevious", this); -} - - -void RBBITest::testFollowing(RuleBasedBreakIterator& bi, BITestData &td) -{ - UErrorCode status = U_ZERO_ERROR; - int32_t p; - int32_t tag; - int32_t lastP = -2; // A value that will never be returned as a break position. - // cannot be -1; that is returned for DONE. - int i; - - logln("testFollowing():"); - bi.setText(td.fDataToBreak); - td.clearResults(); - - // Save the starting point, since we won't get that out of following. - p = bi.first(); - td.fActualBreakPositions.addElement(p, status); // Save result. - tag = bi.getRuleStatus(); - td.fActualTags.addElement(tag, status); - - for (i = 0; i <= td.fDataToBreak.length()+1; i++) { - p = bi.following(i); - if (p != lastP) { - if (p == RuleBasedBreakIterator::DONE) { - break; - } - // We've reached a new break position. Save it. - td.fActualBreakPositions.addElement(p, status); // Save result. - tag = bi.getRuleStatus(); - td.fActualTags.addElement(tag, status); - lastP = p; - } - } - // The loop normally exits by means of the break in the middle. - // Make sure that the index was at the correct position for the break iterator to have - // returned DONE. - if (i != td.fDataToBreak.length()) { - errln("testFollowing(): iterator returned DONE prematurely."); - } - - // Full check of all results. - td.checkResults("testFollowing", this); -} - - - -void RBBITest::testPreceding(RuleBasedBreakIterator& bi, BITestData &td) { - UErrorCode status = U_ZERO_ERROR; - int32_t p; - int32_t tag; - int32_t lastP = 0x7ffffffe; - int i; - - logln("testPreceding():"); - bi.setText(td.fDataToBreak); - td.clearResults(); - - p = bi.last(); - td.fActualBreakPositions.addElement(p, status); - tag = bi.getRuleStatus(); - td.fActualTags.addElement(tag, status); - - for (i = td.fDataToBreak.length(); i>=-1; i--) { - p = bi.preceding(i); - if (p != lastP) { - if (p == RuleBasedBreakIterator::DONE) { - break; - } - // We've reached a new break position. Save it. - td.fActualBreakPositions.insertElementAt(p, 0, status); - lastP = p; - tag = bi.getRuleStatus(); - td.fActualTags.insertElementAt(tag, 0, status); - } - } - // The loop normally exits by means of the break in the middle. - // Make sure that the index was at the correct position for the break iterator to have - // returned DONE. - if (i != 0) { - errln("testPreceding(): iterator returned DONE prematurely."); - } - - // Full check of all results. - td.checkResults("testPreceding", this); -} - - - -void RBBITest::testIsBoundary(RuleBasedBreakIterator& bi, BITestData &td) { - UErrorCode status = U_ZERO_ERROR; - int i; - int32_t tag; - - logln("testIsBoundary():"); - bi.setText(td.fDataToBreak); - td.clearResults(); - - for (i = 0; i <= td.fDataToBreak.length(); i++) { - if (bi.isBoundary(i)) { - td.fActualBreakPositions.addElement(i, status); // Save result. - tag = bi.getRuleStatus(); - td.fActualTags.addElement(tag, status); - } - } - td.checkResults("testIsBoundary: ", this); -} - - - -void RBBITest::doMultipleSelectionTest(RuleBasedBreakIterator& iterator, BITestData &td) -{ - iterator.setText(td.fDataToBreak); - - RuleBasedBreakIterator* testIterator =(RuleBasedBreakIterator*)iterator.clone(); - int32_t offset = iterator.first(); - int32_t testOffset; - int32_t count = 0; - - logln("doMultipleSelectionTest text of length: %d", td.fDataToBreak.length()); - - if (*testIterator != iterator) - errln("clone() or operator!= failed: two clones compared unequal"); - - do { - testOffset = testIterator->first(); - testOffset = testIterator->next(count); - if (offset != testOffset) - errln(UnicodeString("next(n) and next() not returning consistent results: for step ") + count + ", next(n) returned " + testOffset + " and next() had " + offset); - - if (offset != RuleBasedBreakIterator::DONE) { - count++; - offset = iterator.next(); - - if (offset != RuleBasedBreakIterator::DONE && *testIterator == iterator) { - errln("operator== failed: Two unequal iterators compared equal. count=%d offset=%d", count, offset); - if (count > 10000 || offset == -1) { - errln("operator== failed too many times. Stopping test."); - if (offset == -1) { - errln("Does (RuleBasedBreakIterator::DONE == -1)?"); - } - return; - } - } - } - } while (offset != RuleBasedBreakIterator::DONE); - - // now do it backwards... - offset = iterator.last(); - count = 0; - - do { - testOffset = testIterator->last(); - testOffset = testIterator->next(count); // next() with a negative arg is same as previous - if (offset != testOffset) - errln(UnicodeString("next(n) and next() not returning consistent results: for step ") + count + ", next(n) returned " + testOffset + " and next() had " + offset); - - if (offset != RuleBasedBreakIterator::DONE) { - count--; - offset = iterator.previous(); - } - } while (offset != RuleBasedBreakIterator::DONE); - - delete testIterator; -} - //--------------------------------------------- // // other tests // //--------------------------------------------- -void RBBITest::TestEmptyString() -{ - UnicodeString text = ""; - UErrorCode status = U_ZERO_ERROR; - - BITestData x(status); - ADD_DATACHUNK(x, "", 0, status); // Break at start of data - RuleBasedBreakIterator* bi = (RuleBasedBreakIterator *)BreakIterator::createLineInstance(Locale::getDefault(), status); - if (U_FAILURE(status)) - { - errcheckln(status, "Failed to create the BreakIterator for default locale in TestEmptyString. - %s", u_errorName(status)); - return; - } - generalIteratorTest(*bi, x); - delete bi; -} void RBBITest::TestGetAvailableLocales() { @@ -4843,6 +4442,102 @@ void RBBITest::TestBug12519() { assertTrue(WHERE "after assignment of \"biDe = biFr\", they should be equal, but are not.", *biFr == *biDe); } +void RBBITest::TestBug12677() { + // Check that stripping of comments from rules for getRules() is not confused by + // the presence of '#' characters in the rules that do not introduce comments. + UnicodeString rules(u"!!forward; \n" + "$x = [ab#]; # a set with a # literal. \n" + " # .; # a comment that looks sort of like a rule. \n" + " '#' '?'; # a rule with a quoted # \n" + ); + + UErrorCode status = U_ZERO_ERROR; + UParseError pe; + RuleBasedBreakIterator bi(rules, pe, status); + assertSuccess(WHERE, status); + UnicodeString rtRules = bi.getRules(); + assertEquals(WHERE, UnicodeString(u"!!forward; $x = [ab#]; '#' '?'; "), rtRules); +} + + +void RBBITest::TestTableRedundancies() { + UErrorCode status = U_ZERO_ERROR; + + LocalPointer<RuleBasedBreakIterator> bi ( + (RuleBasedBreakIterator *)BreakIterator::createLineInstance(Locale::getEnglish(), status)); + assertSuccess(WHERE, status); + if (U_FAILURE(status)) return; + + RBBIDataWrapper *dw = bi->fData; + const RBBIStateTable *fwtbl = dw->fForwardTable; + int32_t numCharClasses = dw->fHeader->fCatCount; + // printf("Char Classes: %d states: %d\n", numCharClasses, fwtbl->fNumStates); + + // Check for duplicate columns (character categories) + + std::vector<UnicodeString> columns; + for (int32_t column = 0; column < numCharClasses; column++) { + UnicodeString s; + for (int32_t r = 1; r < (int32_t)fwtbl->fNumStates; r++) { + RBBIStateTableRow *row = (RBBIStateTableRow *) (fwtbl->fTableData + (fwtbl->fRowLen * r)); + s.append(row->fNextState[column]); + } + columns.push_back(s); + } + // Ignore column (char class) 0 while checking; it's special, and may have duplicates. + for (int c1=1; c1<numCharClasses; c1++) { + for (int c2 = c1+1; c2 < numCharClasses; c2++) { + if (columns.at(c1) == columns.at(c2)) { + errln("%s:%d Duplicate columns (%d, %d)\n", __FILE__, __LINE__, c1, c2); + goto out; + } + } + } + out: + + // Check for duplicate states + std::vector<UnicodeString> rows; + for (int32_t r=0; r < (int32_t)fwtbl->fNumStates; r++) { + UnicodeString s; + RBBIStateTableRow *row = (RBBIStateTableRow *) (fwtbl->fTableData + (fwtbl->fRowLen * r)); + assertTrue(WHERE, row->fAccepting >= -1); + s.append(row->fAccepting + 1); // values of -1 are expected. + s.append(row->fLookAhead); + s.append(row->fTagIdx); + for (int32_t column = 0; column < numCharClasses; column++) { + s.append(row->fNextState[column]); + } + rows.push_back(s); + } + for (int r1=0; r1 < (int32_t)fwtbl->fNumStates; r1++) { + for (int r2 = r1+1; r2 < (int32_t)fwtbl->fNumStates; r2++) { + if (rows.at(r1) == rows.at(r2)) { + errln("%s:%d Duplicate rows (%d, %d)\n", __FILE__, __LINE__, r1, r2); + return; + } + } + } +} + +// Bug 13447: verify that getRuleStatus() returns the value corresponding to current(), +// even after next() has returned DONE. + +void RBBITest::TestBug13447() { + UErrorCode status = U_ZERO_ERROR; + LocalPointer<RuleBasedBreakIterator> bi( + (RuleBasedBreakIterator *)BreakIterator::createWordInstance(Locale::getEnglish(), status)); + assertSuccess(WHERE, status); + if (U_FAILURE(status)) return; + UnicodeString data(u"1234"); + bi->setText(data); + assertEquals(WHERE, UBRK_WORD_NONE, bi->getRuleStatus()); + assertEquals(WHERE, 4, bi->next()); + assertEquals(WHERE, UBRK_WORD_NUMBER, bi->getRuleStatus()); + assertEquals(WHERE, UBRK_DONE, bi->next()); + assertEquals(WHERE, 4, bi->current()); + assertEquals(WHERE, UBRK_WORD_NUMBER, bi->getRuleStatus()); +} + // // TestDebug - A place-holder test for debugging purposes. // For putting in fragments of other tests that can be invoked diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.h b/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.h index ba3c5b94cd2..21fdfb9f01a 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.h @@ -41,7 +41,6 @@ public: void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); - void TestEmptyString(); void TestGetAvailableLocales(); void TestGetDisplayName(); void TestEndBehaviour(); @@ -75,6 +74,9 @@ public: void TestBug12932(); void TestEmoji(); void TestBug12519(); + void TestBug12677(); + void TestTableRedundancies(); + void TestBug13447(); void TestDebug(); void TestProperties(); @@ -85,40 +87,6 @@ private: * internal methods to prepare test data **/ - /** - * Perform tests of BreakIterator forward and backward functionality - * on different kinds of iterators (word, sentence, line and character). - * It tests the methods first(), next(), current(), preceding(), following() - * previous() and isBoundary(). - * It makes use of internal functions to achieve this. - **/ - void generalIteratorTest(RuleBasedBreakIterator& bi, BITestData &td); - /** - * Internal method to perform iteration and test the first() and next() functions - **/ - void testFirstAndNext(RuleBasedBreakIterator& bi, BITestData &td); - /** - * Internal method to perform iteration and test the last() and previous() functions - **/ - void testLastAndPrevious(RuleBasedBreakIterator& bi, BITestData &td); - /** - * Internal method to perform iteration and test the following() function - **/ - void testFollowing(RuleBasedBreakIterator& bi, BITestData &td); - /** - * Internal method to perform iteration and test the preceding() function - **/ - void testPreceding(RuleBasedBreakIterator& bi, BITestData &td); - /** - * Internal method to perform iteration and test the isBoundary() function - **/ - void testIsBoundary(RuleBasedBreakIterator& bi, BITestData &td); - /** - * Internal method to perform tests of BreakIterator multiple selection functionality - * on different kinds of iterators (word, sentence, line and character) - **/ - void doMultipleSelectionTest(RuleBasedBreakIterator& iterator, BITestData &td); - void RunMonkey(BreakIterator *bi, RBBIMonkeyKind &mk, const char *name, uint32_t seed, int32_t loopCount, UBool useUText); diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/regextst.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/regextst.cpp index 398bc68e279..4b0a2f43fca 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/regextst.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/regextst.cpp @@ -39,6 +39,7 @@ #include "unicode/ustring.h" #include "unicode/utext.h" #include "unicode/utf16.h" +#include "cstr.h" #include "regextst.h" #include "regexcmp.h" #include "uvector.h" @@ -101,6 +102,8 @@ void RegexTest::runIndexedTest( int32_t index, UBool exec, const char* &name, ch TESTCASE_AUTO(NamedCapture); TESTCASE_AUTO(NamedCaptureLimits); TESTCASE_AUTO(TestBug12884); + TESTCASE_AUTO(TestBug13631); + TESTCASE_AUTO(TestBug13632); TESTCASE_AUTO_END; } @@ -5806,4 +5809,46 @@ void RegexTest::TestBug12884() { REGEX_ASSERT(status == U_REGEX_TIME_OUT); } +// Bug 13631. A find() of a pattern with a zero length look-behind assertions +// can cause a read past the end of the input text. +// The failure is seen when running this test with Clang's Addresss Sanitizer. + +void RegexTest::TestBug13631() { + const UChar *pats[] = { u"(?<!^)", + u"(?<=^)", + nullptr + }; + for (const UChar **pat=pats; *pat; ++pat) { + UErrorCode status = U_ZERO_ERROR; + UnicodeString upat(*pat); + RegexMatcher matcher(upat, 0, status); + const UChar s =u'a'; + UText *ut = utext_openUChars(nullptr, &s, 1, &status); + REGEX_CHECK_STATUS; + matcher.reset(ut); + while (matcher.find()) { + } + utext_close(ut); + } +} + +// Bug 13632 Out of bounds memory reference if a replacement string ends with a '$', +// where a following group specification would be expected. +// Failure shows when running the test under Clang's Address Sanitizer. + +void RegexTest::TestBug13632() { + UErrorCode status = U_ZERO_ERROR; + URegularExpression *re = uregex_openC(" ", 0, nullptr, &status); + const char16_t *sourceString = u"Hello, world."; + uregex_setText(re, sourceString, u_strlen(sourceString), &status); + + const int32_t destCap = 20; + char16_t dest[destCap] = {}; + const char16_t replacement[] = {u'x', u'$'}; // Not nul terminated string. + uregex_replaceAll(re, replacement, 2, dest, destCap, &status); + + assertEquals("", U_REGEX_INVALID_CAPTURE_GROUP_NAME, status); + uregex_close(re); +} + #endif /* !UCONFIG_NO_REGULAR_EXPRESSIONS */ diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/regextst.h b/Build/source/libs/icu/icu-src/source/test/intltest/regextst.h index 3f90de0558d..cfa62d70384 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/regextst.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/regextst.h @@ -57,7 +57,9 @@ public: virtual void TestBug11371(); virtual void TestBug11480(); virtual void TestBug12884(); - + virtual void TestBug13631(); + virtual void TestBug13632(); + // The following functions are internal to the regexp tests. virtual void assertUText(const char *expected, UText *actual, const char *file, int line); virtual void assertUTextInvariant(const char *invariant, UText *actual, const char *file, int line); diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/regiontst.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/regiontst.cpp index 4d3561a3c42..20d62f30c04 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/regiontst.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/regiontst.cpp @@ -96,12 +96,12 @@ static KnownRegion knownRegions[] = { { "BS" , 44, "029", URGN_TERRITORY, "019" }, { "BT" , 64, "034", URGN_TERRITORY, "142" }, { "BU" , 104, "035", URGN_TERRITORY, "142" }, - { "BV" , 74, "QO" , URGN_TERRITORY, "009" }, + { "BV" , 74, "005", URGN_TERRITORY, "019" }, { "BW" , 72, "018", URGN_TERRITORY, "002" }, { "BY" , 112, "151", URGN_TERRITORY, "150" }, { "BZ" , 84, "013", URGN_TERRITORY, "019" }, { "CA" , 124, "021", URGN_TERRITORY, "019" }, - { "CC" , 166, "QO" , URGN_TERRITORY, "009" }, + { "CC" , 166, "053", URGN_TERRITORY, "009" }, { "CD" , 180, "017", URGN_TERRITORY, "002" }, { "CF" , 140, "017", URGN_TERRITORY, "002" }, { "CG" , 178, "017", URGN_TERRITORY, "002" }, @@ -117,7 +117,7 @@ static KnownRegion knownRegions[] = { { "CU" , 192, "029", URGN_TERRITORY, "019" }, { "CV" , 132, "011", URGN_TERRITORY, "002" }, { "CW" , 531, "029", URGN_TERRITORY, "019" }, - { "CX" , 162, "QO" , URGN_TERRITORY, "009" }, + { "CX" , 162, "053", URGN_TERRITORY, "009" }, { "CY" , 196, "145", URGN_TERRITORY, "142" }, { "CZ" , 203, "151", URGN_TERRITORY, "150" }, { "DD" , 276, "155", URGN_TERRITORY, "150" }, @@ -158,13 +158,13 @@ static KnownRegion knownRegions[] = { { "GP" , 312, "029", URGN_TERRITORY, "019" }, { "GQ" , 226, "017", URGN_TERRITORY, "002" }, { "GR" , 300, "039", URGN_TERRITORY, "150" }, - { "GS" , 239, "QO" , URGN_TERRITORY, "009" }, + { "GS" , 239, "005", URGN_TERRITORY, "019" }, { "GT" , 320, "013", URGN_TERRITORY, "019" }, { "GU" , 316, "057", URGN_TERRITORY, "009" }, { "GW" , 624, "011", URGN_TERRITORY, "002" }, { "GY" , 328, "005", URGN_TERRITORY, "019" }, { "HK" , 344, "030", URGN_TERRITORY, "142" }, - { "HM" , 334, "QO" , URGN_TERRITORY, "009" }, + { "HM" , 334, "053", URGN_TERRITORY, "009" }, { "HN" , 340, "013", URGN_TERRITORY, "019" }, { "HR" , 191, "039", URGN_TERRITORY, "150" }, { "HT" , 332, "029", URGN_TERRITORY, "019" }, @@ -175,7 +175,7 @@ static KnownRegion knownRegions[] = { { "IL" , 376, "145", URGN_TERRITORY, "142" }, { "IM" , 833, "154", URGN_TERRITORY, "150" }, { "IN" , 356, "034", URGN_TERRITORY, "142" }, - { "IO" , 86, "QO" , URGN_TERRITORY, "009" }, + { "IO" , 86, "014", URGN_TERRITORY, "002" }, { "IQ" , 368, "145", URGN_TERRITORY, "142" }, { "IR" , 364, "034", URGN_TERRITORY, "142" }, { "IS" , 352, "154", URGN_TERRITORY, "150" }, @@ -290,7 +290,7 @@ static KnownRegion knownRegions[] = { { "TA" , -1, "QO", URGN_TERRITORY, "009" }, { "TC" , 796, "029", URGN_TERRITORY, "019" }, { "TD" , 148, "017", URGN_TERRITORY, "002" }, - { "TF" , 260, "QO" , URGN_TERRITORY, "009" }, + { "TF" , 260, "145", URGN_TERRITORY, "142" }, { "TG" , 768, "011", URGN_TERRITORY, "002" }, { "TH" , 764, "035", URGN_TERRITORY, "142" }, { "TJ" , 762, "143", URGN_TERRITORY, "142" }, @@ -307,7 +307,7 @@ static KnownRegion knownRegions[] = { { "TZ" , 834, "014", URGN_TERRITORY, "002" }, { "UA" , 804, "151", URGN_TERRITORY, "150" }, { "UG" , 800, "014", URGN_TERRITORY, "002" }, - { "UM" , 581, "QO" , URGN_TERRITORY, "009" }, + { "UM" , 581, "057", URGN_TERRITORY, "009" }, { "US" , 840, "021", URGN_TERRITORY, "019" }, { "UY" , 858, "005", URGN_TERRITORY, "019" }, { "UZ" , 860, "143", URGN_TERRITORY, "142" }, diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/tsdcfmsy.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/tsdcfmsy.cpp index 90198e070f4..1ed6d760e67 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/tsdcfmsy.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/tsdcfmsy.cpp @@ -23,6 +23,7 @@ void IntlTestDecimalFormatSymbols::runIndexedTest( int32_t index, UBool exec, co TESTCASE_AUTO_BEGIN; TESTCASE_AUTO(testSymbols); TESTCASE_AUTO(testLastResortData); + TESTCASE_AUTO(testDigitSymbols); TESTCASE_AUTO(testNumberingSystem); TESTCASE_AUTO_END; } @@ -249,6 +250,102 @@ void IntlTestDecimalFormatSymbols::testLastResortData() { Verify(1234567.25, "#,##0.##", *lastResort, "1,234,567.25"); } +void IntlTestDecimalFormatSymbols::testDigitSymbols() { + // This test does more in ICU4J than in ICU4C right now. + // In ICU4C, it is basically just a test for codePointZero and getConstDigitSymbol. + UChar defZero = u'0'; + UChar32 osmanyaZero = U'\U000104A0'; + static const UChar* osmanyaDigitStrings[] = { + u"\U000104A0", u"\U000104A1", u"\U000104A2", u"\U000104A3", u"\U000104A4", + u"\U000104A5", u"\U000104A6", u"\U000104A7", u"\U000104A8", u"\U000104A9" + }; + + IcuTestErrorCode status(*this, "testDigitSymbols()"); + DecimalFormatSymbols symbols(Locale("en"), status); + + if (defZero != symbols.getCodePointZero()) { + errln("ERROR: Code point zero be ASCII 0"); + } + for (int32_t i=0; i<=9; i++) { + assertEquals(UnicodeString("i. ASCII Digit at index ") + Int64ToUnicodeString(i), + UnicodeString(u'0' + i), + symbols.getConstDigitSymbol(i)); + } + + for (int32_t i=0; i<=9; i++) { + DecimalFormatSymbols::ENumberFormatSymbol key = + i == 0 + ? DecimalFormatSymbols::kZeroDigitSymbol + : static_cast<DecimalFormatSymbols::ENumberFormatSymbol> + (DecimalFormatSymbols::kOneDigitSymbol + i - 1); + symbols.setSymbol(key, UnicodeString(osmanyaDigitStrings[i]), FALSE); + } + // NOTE: in ICU4J, the calculation of codePointZero is smarter; + // in ICU4C, it is more conservative and is only set if propogateDigits is true. + if (-1 != symbols.getCodePointZero()) { + errln("ERROR: Code point zero be invalid"); + } + for (int32_t i=0; i<=9; i++) { + assertEquals(UnicodeString("ii. Osmanya digit at index ") + Int64ToUnicodeString(i), + UnicodeString(osmanyaDigitStrings[i]), + symbols.getConstDigitSymbol(i)); + } + + // Check Osmanya codePointZero + symbols.setSymbol( + DecimalFormatSymbols::kZeroDigitSymbol, + UnicodeString(osmanyaDigitStrings[0]), TRUE); + if (osmanyaZero != symbols.getCodePointZero()) { + errln("ERROR: Code point zero be Osmanya code point zero"); + } + for (int32_t i=0; i<=9; i++) { + assertEquals(UnicodeString("iii. Osmanya digit at index ") + Int64ToUnicodeString(i), + UnicodeString(osmanyaDigitStrings[i]), + symbols.getConstDigitSymbol(i)); + } + + // Check after copy + DecimalFormatSymbols copy(symbols); + if (osmanyaZero != copy.getCodePointZero()) { + errln("ERROR: Code point zero be Osmanya code point zero"); + } + for (int32_t i=0; i<=9; i++) { + assertEquals(UnicodeString("iv. After copy at index ") + Int64ToUnicodeString(i), + UnicodeString(osmanyaDigitStrings[i]), + copy.getConstDigitSymbol(i)); + } + + // Check when loaded from resource bundle + DecimalFormatSymbols fromData(Locale("en@numbers=osma"), status); + if (osmanyaZero != fromData.getCodePointZero()) { + errln("ERROR: Code point zero be Osmanya code point zero"); + } + for (int32_t i=0; i<=9; i++) { + assertEquals(UnicodeString("v. Resource bundle at index ") + Int64ToUnicodeString(i), + UnicodeString(osmanyaDigitStrings[i]), + fromData.getConstDigitSymbol(i)); + } + + // Setting a digit somewhere in the middle should invalidate codePointZero + symbols.setSymbol(DecimalFormatSymbols::kOneDigitSymbol, u"foo", FALSE); + if (-1 != symbols.getCodePointZero()) { + errln("ERROR: Code point zero be invalid"); + } + + // Reset digits to Latin + symbols.setSymbol( + DecimalFormatSymbols::kZeroDigitSymbol, + UnicodeString(defZero)); + if (defZero != symbols.getCodePointZero()) { + errln("ERROR: Code point zero be ASCII 0"); + } + for (int32_t i=0; i<=9; i++) { + assertEquals(UnicodeString("vi. ASCII Digit at index ") + Int64ToUnicodeString(i), + UnicodeString(u'0' + i), + symbols.getConstDigitSymbol(i)); + } +} + void IntlTestDecimalFormatSymbols::testNumberingSystem() { IcuTestErrorCode errorCode(*this, "testNumberingSystem"); struct testcase { diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/tsdcfmsy.h b/Build/source/libs/icu/icu-src/source/test/intltest/tsdcfmsy.h index 1fd1dfdfba3..1922941b847 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/tsdcfmsy.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/tsdcfmsy.h @@ -28,6 +28,7 @@ private: */ void testSymbols(/*char *par*/); void testLastResortData(); + void testDigitSymbols(); void testNumberingSystem(); /** helper functions**/ diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/tsmthred.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/tsmthred.cpp index 036d5e1d355..1a717e3dc03 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/tsmthred.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/tsmthred.cpp @@ -448,7 +448,8 @@ struct FormatThreadTestData // "Someone from {2} is receiving a #{0} error - {1}. Their telephone call is costing {3 number,currency}." static void formatErrorMessage(UErrorCode &realStatus, const UnicodeString& pattern, const Locale& theLocale, - UErrorCode inStatus0, /* statusString 1 */ const Locale &inCountry2, double currency3, // these numbers are the message arguments. + UErrorCode inStatus0, // statusString 1 + const Locale &inCountry2, double currency3, // these numbers are the message arguments. UnicodeString &result) { if(U_FAILURE(realStatus)) @@ -666,13 +667,13 @@ public: // Keep this data here to avoid static initialization. FormatThreadTestData kNumberFormatTestData[] = { - FormatThreadTestData((double)5.0, UnicodeString("5", "")), - FormatThreadTestData( 6.0, UnicodeString("6", "")), - FormatThreadTestData( 20.0, UnicodeString("20", "")), - FormatThreadTestData( 8.0, UnicodeString("8", "")), - FormatThreadTestData( 8.3, UnicodeString("8.3", "")), - FormatThreadTestData( 12345, UnicodeString("12,345", "")), - FormatThreadTestData( 81890.23, UnicodeString("81,890.23", "")), + FormatThreadTestData((double)5.0, UnicodeString(u"5")), + FormatThreadTestData( 6.0, UnicodeString(u"6")), + FormatThreadTestData( 20.0, UnicodeString(u"20")), + FormatThreadTestData( 8.0, UnicodeString(u"8")), + FormatThreadTestData( 8.3, UnicodeString(u"8.3")), + FormatThreadTestData( 12345, UnicodeString(u"12,345")), + FormatThreadTestData( 81890.23, UnicodeString(u"81,890.23")), }; int32_t kNumberFormatTestDataLength = UPRV_LENGTHOF(kNumberFormatTestData); @@ -1388,7 +1389,7 @@ const UCTMultiThreadItem *LocaleCacheKey<UCTMultiThreadItem>::createObject( } else { result->addRef(); } - + // Log that we created an object. The first object was already counted, // don't do it again. umtx_lock(&gCTMutex); @@ -1451,7 +1452,7 @@ void UnifiedCacheThread::exerciseByLocale(const Locale &locale) { void UnifiedCacheThread::run() { // Run the exercise with 2 different locales so that we can exercise - // eviction more. If each thread exerices just one locale, then + // eviction more. If each thread exercises just one locale, then // eviction can't start until the threads end. exerciseByLocale(fLoc); exerciseByLocale(fLoc2); diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/tzregts.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/tzregts.cpp index b749c2d4422..c5f59d9182d 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/tzregts.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/tzregts.cpp @@ -12,6 +12,7 @@ #include "unicode/simpletz.h" #include "unicode/smpdtfmt.h" #include "unicode/strenum.h" +#include "unicode/gregocal.h" #include "tzregts.h" #include "calregts.h" #include "cmemory.h" @@ -46,6 +47,7 @@ TimeZoneRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* & CASE(16, TestJDK12API); CASE(17, Test4176686); CASE(18, Test4184229); + CASE(19, TestNegativeDaylightSaving); default: name = ""; break; } } @@ -709,10 +711,10 @@ TimeZoneRegressionTest::Test4154525() int32_t DATA [] = { 1, GOOD, 0, BAD, - -1, BAD, + -1, GOOD, // #13566 updates SimpleTimeZone to support negative DST saving amount 60*60*1000, GOOD, - INT32_MIN, BAD, - // Integer.MAX_VALUE, ?, // no upper limit on DST savings at this time + INT32_MAX, GOOD, // no upper limit on DST savings at this time + INT32_MIN, GOOD // no lower limit as well }; UErrorCode status = U_ZERO_ERROR; @@ -1206,4 +1208,61 @@ void TimeZoneRegressionTest::Test4184229() { delete zone; } +void TimeZoneRegressionTest::TestNegativeDaylightSaving() { + UErrorCode status = U_ZERO_ERROR; + int32_t stdOff = 1 * 60*60*1000; // Standard offset UTC+1 + int save = -1 * 60*60*1000; // DST saving amount -1 hour + SimpleTimeZone stzDublin(stdOff, "Dublin-2018", + UCAL_OCTOBER, -1, -UCAL_SUNDAY, 2*60*60*1000, + UCAL_MARCH, -1, -UCAL_SUNDAY, 1*60*60*1000, + save, status); + failure(status, "SimpleTimeZone constructor"); + + if (save != stzDublin.getDSTSavings()) { + errln((UnicodeString)"FAIL: DST saving is not " + save); + } + + GregorianCalendar cal(* TimeZone::getGMT(), status); + failure(status, "GregorianCalendar constructor"); + + UDate testDate; + int32_t rawOffset; + int32_t dstOffset; + + cal.set(2018, UCAL_JANUARY, 15, 0, 0, 0); + testDate = cal.getTime(status); + failure(status, "calendar getTime() - Jan 15"); + + if (!stzDublin.inDaylightTime(testDate, status)) { + errln("FAIL: The test date (Jan 15) must be in DST."); + } + failure(status, "inDaylightTime() - Jan 15"); + + stzDublin.getOffset(testDate, FALSE, rawOffset, dstOffset, status); + failure(status, "getOffset() - Jan 15"); + if (rawOffset != stdOff || dstOffset != save) { + errln((UnicodeString)"FAIL: Expected [stdoff=" + stdOff + ",save=" + save + + "] on the test date (Jan 15), actual[stdoff=" + rawOffset + + ",save=" + dstOffset + "]"); + } + + cal.set(2018, UCAL_JULY, 15, 0, 0, 0); + testDate = cal.getTime(status); + failure(status, "calendar getTime() - Jul 15"); + + if (stzDublin.inDaylightTime(testDate, status)) { + errln("FAIL: The test date (Jul 15) must be in DST."); + } + failure(status, "inDaylightTime() - Jul 15"); + + stzDublin.getOffset(testDate, FALSE, rawOffset, dstOffset, status); + failure(status, "getOffset() - Jul 15"); + if (rawOffset != stdOff || dstOffset != 0) { + errln((UnicodeString)"FAIL: Expected [stdoff=" + stdOff + ",save=" + 0 + + "] on the test date (Jul 15), actual[stdoff=" + rawOffset + + ",save=" + dstOffset + "]"); + } +} + + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/tzregts.h b/Build/source/libs/icu/icu-src/source/test/intltest/tzregts.h index 2d7f7ef13f8..46e43cd2502 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/tzregts.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/tzregts.h @@ -49,6 +49,7 @@ public: void TestJDK12API(void); void Test4184229(void); UBool checkCalendar314(GregorianCalendar *testCal, TimeZone *testTZ); + void TestNegativeDaylightSaving(void); protected: diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/ucdtest.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/ucdtest.cpp index 489d6cdf275..8a52c94820f 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/ucdtest.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/ucdtest.cpp @@ -63,6 +63,7 @@ void UnicodeTest::runIndexedTest( int32_t index, UBool exec, const char* &name, TESTCASE_AUTO(TestBidiPairedBracketType); TESTCASE_AUTO(TestEmojiProperties); TESTCASE_AUTO(TestDefaultScriptExtensions); + TESTCASE_AUTO(TestInvalidCodePointFolding); TESTCASE_AUTO_END; } @@ -546,3 +547,22 @@ void UnicodeTest::TestDefaultScriptExtensions() { uscript_getScriptExtensions(0x3012, scx, UPRV_LENGTHOF(scx), errorCode)); assertEquals("U+3012 num scx[0]", USCRIPT_COMMON, scx[0]); } + +void UnicodeTest::TestInvalidCodePointFolding(void) { + // Test behavior when an invalid code point is passed to u_foldCase + static const UChar32 invalidCodePoints[] = { + 0xD800, // lead surrogate + 0xDFFF, // trail surrogate + 0xFDD0, // noncharacter + 0xFFFF, // noncharacter + 0x110000, // out of range + -1 // negative + }; + for (int32_t i=0; i<UPRV_LENGTHOF(invalidCodePoints); ++i) { + UChar32 cp = invalidCodePoints[i]; + assertEquals("Invalid code points should be echoed back", + cp, u_foldCase(cp, U_FOLD_CASE_DEFAULT)); + assertEquals("Invalid code points should be echoed back", + cp, u_foldCase(cp, U_FOLD_CASE_EXCLUDE_SPECIAL_I)); + } +} diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/ucdtest.h b/Build/source/libs/icu/icu-src/source/test/intltest/ucdtest.h index 82ffb0e8dcc..8a7ae3f4ecf 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/ucdtest.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/ucdtest.h @@ -42,6 +42,7 @@ public: void TestBidiPairedBracketType(); void TestEmojiProperties(); void TestDefaultScriptExtensions(); + void TestInvalidCodePointFolding(); private: diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/unifiedcachetest.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/unifiedcachetest.cpp index 762194a87f5..0525d475c0a 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/unifiedcachetest.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/unifiedcachetest.cpp @@ -153,8 +153,8 @@ void UnifiedCacheTest::TestEvictionPolicy() { unusedReference->removeRef(); // unused count not to exeed in use count - assertEquals("", UPRV_LENGTHOF(usedReferences), cache.unusedCount()); - assertEquals("", 2*UPRV_LENGTHOF(usedReferences), cache.keyCount()); + assertEquals("T1", UPRV_LENGTHOF(usedReferences), cache.unusedCount()); + assertEquals("T2", 2*UPRV_LENGTHOF(usedReferences), cache.keyCount()); // Free up those used entries. for (int32_t i = 0; i < UPRV_LENGTHOF(usedReferences); i++) { @@ -162,9 +162,9 @@ void UnifiedCacheTest::TestEvictionPolicy() { } // This should free up all cache items - assertEquals("", 0, cache.keyCount()); + assertEquals("T3", 0, cache.keyCount()); - assertSuccess("", status); + assertSuccess("T4", status); } @@ -181,7 +181,7 @@ void UnifiedCacheTest::TestBounded() { // complete control over it. Real clients should never ever create // their own cache! UnifiedCache cache(status); - assertSuccess("", status); + assertSuccess("T0", status); // Maximum unused count is 3. cache.setEvictionPolicy(3, 0, status); @@ -202,15 +202,15 @@ void UnifiedCacheTest::TestBounded() { const UCTItem *frFr = NULL; cache.get(LocaleCacheKey<UCTItem>("en_US"), &cache, enUs, status); cache.get(LocaleCacheKey<UCTItem>("en"), &cache, en, status); - assertEquals("", 1, cache.unusedCount()); + assertEquals("T1", 1, cache.unusedCount()); cache.get(LocaleCacheKey<UCTItem>("en_GB"), &cache, enGb, status); cache.get(LocaleCacheKey<UCTItem>("fr_FR"), &cache, frFr, status); cache.get(LocaleCacheKey<UCTItem>("fr"), &cache, fr, status); // Client holds two unique references, "en" and "fr" the other three // entries are eligible for eviction. - assertEquals("", 3, cache.unusedCount()); - assertEquals("", 5, cache.keyCount()); + assertEquals("T2", 3, cache.unusedCount()); + assertEquals("T3", 5, cache.keyCount()); // Exercise cache more but don't hold the references except for // the last one. At the end of this, we will hold references to one @@ -227,40 +227,40 @@ void UnifiedCacheTest::TestBounded() { // Client holds three unique references, "en", "fr", "de" although we // could have a total of 8 entries in the cache maxUnusedCount == 3 // so we have only 6 entries. - assertEquals("", 3, cache.unusedCount()); - assertEquals("", 6, cache.keyCount()); + assertEquals("T4", 3, cache.unusedCount()); + assertEquals("T5", 6, cache.keyCount()); // For all the references we have, cache must continue to return // those same references (#2) cache.get(LocaleCacheKey<UCTItem>("en"), &cache, throwAway, status); if (throwAway != en) { - errln("Expected en to resolve to the same object."); + errln("T6: Expected en to resolve to the same object."); } cache.get(LocaleCacheKey<UCTItem>("en_US"), &cache, throwAway, status); if (throwAway != enUs) { - errln("Expected enUs to resolve to the same object."); + errln("T7: Expected enUs to resolve to the same object."); } cache.get(LocaleCacheKey<UCTItem>("en_GB"), &cache, throwAway, status); if (throwAway != enGb) { - errln("Expected enGb to resolve to the same object."); + errln("T8: Expected enGb to resolve to the same object."); } cache.get(LocaleCacheKey<UCTItem>("fr_FR"), &cache, throwAway, status); if (throwAway != frFr) { - errln("Expected frFr to resolve to the same object."); + errln("T9: Expected frFr to resolve to the same object."); } cache.get(LocaleCacheKey<UCTItem>("fr_FR"), &cache, throwAway, status); cache.get(LocaleCacheKey<UCTItem>("fr"), &cache, throwAway, status); if (throwAway != fr) { - errln("Expected fr to resolve to the same object."); + errln("T10: Expected fr to resolve to the same object."); } cache.get(LocaleCacheKey<UCTItem>("de_AU"), &cache, throwAway, status); if (throwAway != deAu) { - errln("Expected deAu to resolve to the same object."); + errln("T11: Expected deAu to resolve to the same object."); } - assertEquals("", 3, cache.unusedCount()); - assertEquals("", 6, cache.keyCount()); + assertEquals("T12", 3, cache.unusedCount()); + assertEquals("T13", 6, cache.keyCount()); // Now we hold a references to two more distinct values. Cache size // should grow to 8. @@ -268,8 +268,8 @@ void UnifiedCacheTest::TestBounded() { const UCTItem *ru = NULL; cache.get(LocaleCacheKey<UCTItem>("es"), &cache, es, status); cache.get(LocaleCacheKey<UCTItem>("ru"), &cache, ru, status); - assertEquals("", 3, cache.unusedCount()); - assertEquals("", 8, cache.keyCount()); + assertEquals("T14", 3, cache.unusedCount()); + assertEquals("T15", 8, cache.keyCount()); // Now release all the references we hold except for // es, ru, and en @@ -284,13 +284,13 @@ void UnifiedCacheTest::TestBounded() { SharedObject::clearPtr(throwAway); // Size of cache should magically drop to 3. - assertEquals("", 3, cache.unusedCount()); - assertEquals("", 3, cache.keyCount()); + assertEquals("T16", 3, cache.unusedCount()); + assertEquals("T17", 3, cache.keyCount()); // Be sure nothing happens setting the eviction policy in the middle of // a run. cache.setEvictionPolicy(3, 0, status); - assertSuccess("", status); + assertSuccess("T18", status); } @@ -311,7 +311,7 @@ void UnifiedCacheTest::TestBasic() { cache->get(LocaleCacheKey<UCTItem>("en_GB"), enGb, status); cache->get(LocaleCacheKey<UCTItem>("fr_FR"), frFr, status); cache->get(LocaleCacheKey<UCTItem>("fr"), fr, status); - cache->get(LocaleCacheKey<UCTItem>("en_GB"), enGb2, status); + cache->get(LocaleCacheKey<UCTItem>("en_GB"), enGb2, status); SharedObject::clearPtr(enGb2); if (enGb != enUs) { errln("Expected en_GB and en_US to resolve to same object."); @@ -322,16 +322,16 @@ void UnifiedCacheTest::TestBasic() { if (enGb == fr) { errln("Expected en_GB and fr to return different objects."); } - assertSuccess("", status); + assertSuccess("T1", status); // en_US, en_GB, en share one object; fr_FR and fr don't share. // 5 keys in all. - assertEquals("", baseCount + 5, cache->keyCount()); + assertEquals("T2", baseCount + 5, cache->keyCount()); SharedObject::clearPtr(enGb); cache->flush(); // Only 2 unique values in the cache. flushing trims cache down // to this minimum size. - assertEquals("", baseCount + 2, cache->keyCount()); + assertEquals("T3", baseCount + 2, cache->keyCount()); SharedObject::clearPtr(enUs); SharedObject::clearPtr(en); cache->flush(); @@ -339,14 +339,14 @@ void UnifiedCacheTest::TestBasic() { // the "en" object, so it gets flushed and the keys that refer to it // get removed from the cache. Now we have just one unique value, fr, in // the cache - assertEquals("", baseCount + 1, cache->keyCount()); + assertEquals("T4", baseCount + 1, cache->keyCount()); SharedObject::clearPtr(fr); cache->flush(); - assertEquals("", baseCount + 1, cache->keyCount()); + assertEquals("T5", baseCount + 1, cache->keyCount()); SharedObject::clearPtr(frFr); cache->flush(); - assertEquals("", baseCount + 0, cache->keyCount()); - assertSuccess("", status); + assertEquals("T6", baseCount + 0, cache->keyCount()); + assertSuccess("T7", status); } void UnifiedCacheTest::TestError() { diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/usettest.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/usettest.cpp index d142f048d58..b6f2eab6a84 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/usettest.cpp +++ b/Build/source/libs/icu/icu-src/source/test/intltest/usettest.cpp @@ -42,15 +42,6 @@ UnicodeString operator+(const UnicodeString& left, const UnicodeSet& set) { return left + UnicodeSetTest::escape(pat); } -#define CASE(id,test) case id: \ - name = #test; \ - if (exec) { \ - logln(#test "---"); \ - logln(); \ - test(); \ - } \ - break - UnicodeSetTest::UnicodeSetTest() : utf8Cnv(NULL) { } @@ -100,6 +91,7 @@ UnicodeSetTest::runIndexedTest(int32_t index, UBool exec, TESTCASE_AUTO(TestUCAUnsafeBackwards); TESTCASE_AUTO(TestIntOverflow); TESTCASE_AUTO(TestUnusedCcc); + TESTCASE_AUTO(TestDeepPattern); TESTCASE_AUTO_END; } @@ -3970,3 +3962,19 @@ void UnicodeSetTest::TestUnusedCcc() { assertTrue("[:ccc=1.1:] -> empty set", ccc1_1.isEmpty()); #endif } + +void UnicodeSetTest::TestDeepPattern() { + IcuTestErrorCode errorCode(*this, "TestDeepPattern"); + // Nested ranges are parsed via recursion which can use a lot of stack space. + // After a reasonable limit, we should get an error. + constexpr int32_t DEPTH = 20000; + UnicodeString pattern, suffix; + for (int32_t i = 0; i < DEPTH; ++i) { + pattern.append(u"[a", 2); + suffix.append(']'); + } + pattern.append(suffix); + UnicodeSet set(pattern, errorCode); + assertTrue("[a[a[a...1000s...]]] -> error", errorCode.isFailure()); + errorCode.reset(); +} diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/usettest.h b/Build/source/libs/icu/icu-src/source/test/intltest/usettest.h index b34728ae631..e79a9e8e77d 100644 --- a/Build/source/libs/icu/icu-src/source/test/intltest/usettest.h +++ b/Build/source/libs/icu/icu-src/source/test/intltest/usettest.h @@ -93,6 +93,7 @@ private: void TestUCAUnsafeBackwards(); void TestIntOverflow(); void TestUnusedCcc(); + void TestDeepPattern(); private: diff --git a/Build/source/libs/icu/icu-src/source/test/iotest/iotest.vcxproj b/Build/source/libs/icu/icu-src/source/test/iotest/iotest.vcxproj index 5b7a4044f15..f67c0b19a48 100644 --- a/Build/source/libs/icu/icu-src/source/test/iotest/iotest.vcxproj +++ b/Build/source/libs/icu/icu-src/source/test/iotest/iotest.vcxproj @@ -1,51 +1,16 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> + <!-- The following import will include the 'default' configuration options for VS projects. --> + <Import Project="..\..\allinone\Build.Windows.ProjectConfiguration.props" /> + <PropertyGroup Label="Globals"> <ProjectGuid>{E4993E82-D68A-46CA-BAE0-9D35E172E46F}</ProjectGuid> - <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - <CharacterSet>MultiByte</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - <CharacterSet>MultiByte</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - <CharacterSet>MultiByte</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <PropertyGroup Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseOfMfc>false</UseOfMfc> <CharacterSet>MultiByte</CharacterSet> - <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -82,6 +47,15 @@ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</IntDir> <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> </PropertyGroup> + <!-- Options that are common to *all* project configurations --> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>..\..\..\include;..\..\tools\ctestfw;..\..\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableLanguageExtensions>true</DisableLanguageExtensions> + <WarningLevel>Level3</WarningLevel> + </ClCompile> + </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <Midl> <TypeLibraryName>.\x86\Debug/iotest.tlb</TypeLibraryName> @@ -89,39 +63,26 @@ </HeaderFileName> </Midl> <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>..\..\..\include;..\..\tools\ctestfw;..\..\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <BufferSecurityCheck>true</BufferSecurityCheck> <DisableLanguageExtensions>true</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <PrecompiledHeaderOutputFile>.\x86\Debug/iotest.pch</PrecompiledHeaderOutputFile> <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation> <ObjectFileName>.\x86\Debug/</ObjectFileName> <ProgramDataBaseFileName>.\x86\Debug/</ProgramDataBaseFileName> <BrowseInformation>true</BrowseInformation> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> <DebugInformationFormat>EditAndContinue</DebugInformationFormat> <CompileAs>Default</CompileAs> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> <Link> <OutputFile>.\x86\Debug/iotest.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalDependencies>icuucd.lib;icuind.lib;icuiod.lib;icutestd.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>..\..\..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <GenerateDebugInformation>true</GenerateDebugInformation> <ProgramDatabaseFile>.\x86\Debug/iotest.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> <RandomizedBaseAddress>false</RandomizedBaseAddress> <DataExecutionPrevention> </DataExecutionPrevention> - <TargetMachine>MachineX86</TargetMachine> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> @@ -129,117 +90,74 @@ <TypeLibraryName>.\x86\Release/iotest.tlb</TypeLibraryName> </Midl> <ClCompile> - <AdditionalIncludeDirectories>..\..\..\include;..\..\tools\ctestfw;..\..\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <StringPooling>true</StringPooling> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> - <DisableLanguageExtensions>true</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <PrecompiledHeaderOutputFile>.\x86\Release/iotest.pch</PrecompiledHeaderOutputFile> <AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation> <ObjectFileName>.\x86\Release/</ObjectFileName> <ProgramDataBaseFileName>.\x86\Release/</ProgramDataBaseFileName> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> <CompileAs>Default</CompileAs> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> <Link> <OutputFile>.\x86\Release/iotest.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalDependencies>icuuc.lib;icuin.lib;icuio.lib;icutest.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>..\..\..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <ProgramDatabaseFile>.\x86\Release/iotest.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> <RandomizedBaseAddress>false</RandomizedBaseAddress> <DataExecutionPrevention> </DataExecutionPrevention> - <TargetMachine>MachineX86</TargetMachine> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <Midl> - <TargetEnvironment>X64</TargetEnvironment> <TypeLibraryName>.\x64\Debug/iotest.tlb</TypeLibraryName> <HeaderFileName> </HeaderFileName> </Midl> <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>..\..\..\include;..\..\tools\ctestfw;..\..\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN64;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <BufferSecurityCheck>true</BufferSecurityCheck> - <DisableLanguageExtensions>true</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <PrecompiledHeaderOutputFile>.\x64\Debug/iotest.pch</PrecompiledHeaderOutputFile> <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation> <ObjectFileName>.\x64\Debug/</ObjectFileName> <ProgramDataBaseFileName>.\x64\Debug/</ProgramDataBaseFileName> <BrowseInformation>true</BrowseInformation> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <CompileAs>Default</CompileAs> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> <Link> <OutputFile>.\x64\Debug/iotest.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalDependencies>icuucd.lib;icuind.lib;icuiod.lib;icutestd.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>..\..\..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <GenerateDebugInformation>true</GenerateDebugInformation> <ProgramDatabaseFile>.\x64\Debug/iotest.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> - <TargetMachine>MachineX64</TargetMachine> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <Midl> - <TargetEnvironment>X64</TargetEnvironment> <TypeLibraryName>.\x64\Release/iotest.tlb</TypeLibraryName> </Midl> <ClCompile> - <AdditionalIncludeDirectories>..\..\..\include;..\..\tools\ctestfw;..\..\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <StringPooling>true</StringPooling> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> - <DisableLanguageExtensions>true</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <PrecompiledHeaderOutputFile>.\x64\Release/iotest.pch</PrecompiledHeaderOutputFile> <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation> <ObjectFileName>.\x64\Release/</ObjectFileName> <ProgramDataBaseFileName>.\x64\Release/</ProgramDataBaseFileName> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> <CompileAs>Default</CompileAs> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> <Link> <OutputFile>.\x64\Release/iotest.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalDependencies>icuuc.lib;icuin.lib;icuio.lib;icutest.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>..\..\..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <ProgramDatabaseFile>.\x64\Release/iotest.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> - <TargetMachine>MachineX64</TargetMachine> </Link> </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="filetst.c" /> <ClCompile Include="iotest.cpp" /> <ClCompile Include="stream.cpp"> - <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions> - <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions> - <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions> - <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions> + <DisableLanguageExtensions>false</DisableLanguageExtensions> </ClCompile> <ClCompile Include="strtst.c" /> <ClCompile Include="trnstst.c" /> @@ -247,25 +165,7 @@ <ItemGroup> <ClInclude Include="iotest.h" /> </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\..\common\common.vcxproj"> - <Project>{73c0a65b-d1f2-4de1-b3a6-15dad2c23f3d}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="..\..\i18n\i18n.vcxproj"> - <Project>{0178b127-6269-407d-b112-93877bb62776}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="..\..\io\io.vcxproj"> - <Project>{c2b04507-2521-4801-bf0d-5fd79d6d518c}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="..\..\tools\ctestfw\ctestfw.vcxproj"> - <Project>{eca6b435-b4fa-4f9f-bf95-f451d078fc47}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> +</Project>
\ No newline at end of file diff --git a/Build/source/libs/icu/icu-src/source/test/letest/letest.vcxproj b/Build/source/libs/icu/icu-src/source/test/letest/letest.vcxproj index 50c54ee0b42..0a83aacc285 100644 --- a/Build/source/libs/icu/icu-src/source/test/letest/letest.vcxproj +++ b/Build/source/libs/icu/icu-src/source/test/letest/letest.vcxproj @@ -110,6 +110,8 @@ <Link> <OutputFile>.\x86\Release/letest.exe</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalDependencies>icuuc.lib;icuin.lib;iculx.lib;icutest.lib;icutu.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>.\..\..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <ProgramDatabaseFile>.\x86\Release/letest.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> <RandomizedBaseAddress>false</RandomizedBaseAddress> @@ -146,6 +148,8 @@ <Link> <OutputFile>.\x86\Debug/letest.exe</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalDependencies>icuucd.lib;icuind.lib;iculxd.lib;icutestd.lib;icutud.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>.\..\..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <GenerateDebugInformation>true</GenerateDebugInformation> <ProgramDatabaseFile>.\x86\Debug/letest.pdb</ProgramDatabaseFile> @@ -185,6 +189,8 @@ <Link> <OutputFile>.\x64\Release/letest.exe</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalDependencies>icuuc.lib;icuin.lib;iculx.lib;icutest.lib;icutu.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>.\..\..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <ProgramDatabaseFile>.\x64\Release/letest.pdb</ProgramDatabaseFile> <SubSystem>Console</SubSystem> <TargetMachine>MachineX64</TargetMachine> @@ -220,6 +226,8 @@ <Link> <OutputFile>.\x64\Debug/letest.exe</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalDependencies>icuucd.lib;icuind.lib;iculxd.lib;icutestd.lib;icutud.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>.\..\..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <GenerateDebugInformation>true</GenerateDebugInformation> <ProgramDatabaseFile>.\x64\Debug/letest.pdb</ProgramDatabaseFile> @@ -250,30 +258,10 @@ <ClInclude Include="xmlreader.h" /> </ItemGroup> <ItemGroup> - <ProjectReference Include="..\..\common\common.vcxproj"> - <Project>{73c0a65b-d1f2-4de1-b3a6-15dad2c23f3d}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="..\..\i18n\i18n.vcxproj"> - <Project>{0178b127-6269-407d-b112-93877bb62776}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="..\..\layoutex\layoutex.vcxproj"> - <Project>{37fc2c7f-1904-4811-8955-2f478830ead1}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> <ProjectReference Include="..\..\layout\layout.vcxproj"> <Project>{c920062a-0647-4553-a3b2-37c58065664b}</Project> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> </ProjectReference> - <ProjectReference Include="..\..\tools\ctestfw\ctestfw.vcxproj"> - <Project>{eca6b435-b4fa-4f9f-bf95-f451d078fc47}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="..\..\tools\toolutil\toolutil.vcxproj"> - <Project>{6b231032-3cb5-4eed-9210-810d666a23a0}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> diff --git a/Build/source/libs/icu/icu-src/source/test/testdata/numberformattestspecification.txt b/Build/source/libs/icu/icu-src/source/test/testdata/numberformattestspecification.txt index 113473a2a57..1f11f8da7c1 100644 --- a/Build/source/libs/icu/icu-src/source/test/testdata/numberformattestspecification.txt +++ b/Build/source/libs/icu/icu-src/source/test/testdata/numberformattestspecification.txt @@ -13,7 +13,7 @@ // https://docs.google.com/document/d/1T2P0p953_Lh1pRwo-5CuPVrHlIBa_wcXElG-Hhg_WHM/edit?usp=sharing test plus sign -set locale ar +set locale ar-EG set pattern +0;-# begin format output breaks @@ -441,11 +441,10 @@ en_US 1 123,456 123456 en_US 0 123,456 123 en_US 1 123.456 123.456 en_US 0 123.456 123.456 -fr_FR 1 123,456 123.456 -fr_FR 0 123,456 123.456 -// JDK returns 123 here; not sure why. -fr_FR 1 123.456 123456 K -fr_FR 0 123.456 123 +it_IT 1 123,456 123.456 +it_IT 0 123,456 123.456 +it_IT 1 123.456 123456 +it_IT 0 123.456 123 test no grouping in pattern with parsing set pattern 0 @@ -466,9 +465,8 @@ output grouping breaks grouping2 minGroupingDigits 1,2345,6789 4 1,23,45,6789 4 K 2 1,23,45,6789 4 K 2 2 -// Q only supports minGrouping<=2 123,456789 6 6 3 -123456789 6 JKQ 6 4 +123456789 6 JK 6 4 test multiplier setters set locale en_US @@ -754,6 +752,7 @@ parse output breaks +3.52EE4 3.52 +1,234,567.8901 1234567.8901 +1,23,4567.8901 1234567.8901 +// Fraction grouping is disabled by default +1,23,4567.89,01 1234567.89 +1,23,456.78.9 123456.78 +12.34,56 12.34 @@ -831,15 +830,14 @@ parse output breaks // JDK does allow separators in the wrong place and parses as -5347.25 (53,47.25) fail K // strict requires prefix or suffix, except in C -65,347.25 fail +65,347.25 fail +3.52E4 35200 (34.8E-3) -0.0348 (3425E-1) -342.5 // Strict doesn't allow separators in sci notation. (63,425) -63425 -// JDK and S allow separators in sci notation and parses as -342.5 -// C passes -(63,425E-1) fail CKS +// J does not allow grouping separators in scientific notation. +(63,425E-1) -6342.5 J // Both prefix and suffix needed for strict. // JDK accepts this and parses as -342.5 (3425E-1 fail K @@ -954,12 +952,12 @@ set negativeSuffix 9N begin parse output breaks // S is the only implementation that passes these cases. -// C consumes the '9' as a digit and assumes number is negative +// C and P consume the '9' as a digit and assumes number is negative // J and JDK bail -6549K 654 CJK -// C consumes the '9' as a digit and assumes number is negative +6549K 654 CJKP +// C and P consume the '9' as a digit and assumes number is negative // J and JDK bail -6549N -654 CJK +6549N -654 CJKP test really strange prefix set locale en @@ -974,7 +972,7 @@ test parse pattern with quotes set locale en set pattern '-'#y begin -parse output +parse output breaks -45y 45 test parse with locale symbols @@ -1187,17 +1185,17 @@ $53.45 fail USD J USD 53.45 53.45 USD J 53.45USD 53.45 USD CJ USD53.45 53.45 USD -// S fails these because '(' is an incomplete prefix. -(7.92) USD -7.92 USD CJS -(7.92) GBP -7.92 GBP CJS -(7.926) USD -7.926 USD CJS -(7.926 USD) -7.926 USD CJS +// P fails these because '(' is an incomplete prefix. +(7.92) USD -7.92 USD CJP +(7.92) GBP -7.92 GBP CJP +(7.926) USD -7.926 USD CJP +(7.926 USD) -7.926 USD CJP (USD 7.926) -7.926 USD J -USD (7.926) -7.926 USD CJS -USD (7.92) -7.92 USD CJS -(7.92)USD -7.92 USD CJS -USD(7.92) -7.92 USD CJS -(8) USD -8 USD CJS +USD (7.926) -7.926 USD CJP +USD (7.92) -7.92 USD CJP +(7.92)USD -7.92 USD CJP +USD(7.92) -7.92 USD CJP +(8) USD -8 USD CJP -8 USD -8 USD C 67 USD 67 USD C 53.45$ fail USD @@ -1223,37 +1221,38 @@ test parse foreign currency symbol set pattern \u00a4 0.00;\u00a4 -# set locale fa_IR begin -parse output outputCurrency +parse output outputCurrency breaks \u0631\u06cc\u0627\u0644 \u06F1\u06F2\u06F3\u06F5 1235 IRR IRR \u06F1\u06F2\u06F3\u06F5 1235 IRR -\u0631\u06cc\u0627\u0644 \u0627\u06cc\u0631\u0627\u0646 \u06F1\u06F2\u06F3\u06F5 1235 IRR +// P fails here because this currency name is in the Trie only, but it has the same prefix as the non-Trie currency +\u0631\u06cc\u0627\u0644 \u0627\u06cc\u0631\u0627\u0646 \u06F1\u06F2\u06F3\u06F5 1235 IRR P IRR 1235 1235 IRR \u0631\u06cc\u0627\u0644 1235 1235 IRR -\u0631\u06cc\u0627\u0644 \u0627\u06cc\u0631\u0627\u0646 1235 1235 IRR +\u0631\u06cc\u0627\u0644 \u0627\u06cc\u0631\u0627\u0646 1235 1235 IRR P test parse foreign currency ISO set pattern \u00a4\u00a4 0.00;\u00a4\u00a4 -# set locale fa_IR begin -parse output outputCurrency +parse output outputCurrency breaks \u0631\u06cc\u0627\u0644 \u06F1\u06F2\u06F3\u06F5 1235 IRR IRR \u06F1\u06F2\u06F3\u06F5 1235 IRR -\u0631\u06cc\u0627\u0644 \u0627\u06cc\u0631\u0627\u0646 \u06F1\u06F2\u06F3\u06F5 1235 IRR +\u0631\u06cc\u0627\u0644 \u0627\u06cc\u0631\u0627\u0646 \u06F1\u06F2\u06F3\u06F5 1235 IRR P IRR 1235 1235 IRR \u0631\u06cc\u0627\u0644 1235 1235 IRR -\u0631\u06cc\u0627\u0644 \u0627\u06cc\u0631\u0627\u0646 1235 1235 IRR +\u0631\u06cc\u0627\u0644 \u0627\u06cc\u0631\u0627\u0646 1235 1235 IRR P test parse foreign currency full set pattern \u00a4\u00a4\u00a4 0.00;\u00a4\u00a4\u00a4 -# set locale fa_IR begin -parse output outputCurrency +parse output outputCurrency breaks \u0631\u06cc\u0627\u0644 \u06F1\u06F2\u06F3\u06F5 1235 IRR IRR \u06F1\u06F2\u06F3\u06F5 1235 IRR -\u0631\u06cc\u0627\u0644 \u0627\u06cc\u0631\u0627\u0646 \u06F1\u06F2\u06F3\u06F5 1235 IRR +\u0631\u06cc\u0627\u0644 \u0627\u06cc\u0631\u0627\u0646 \u06F1\u06F2\u06F3\u06F5 1235 IRR P IRR 1235 1235 IRR \u0631\u06cc\u0627\u0644 1235 1235 IRR -\u0631\u06cc\u0627\u0644 \u0627\u06cc\u0631\u0627\u0646 1235 1235 IRR +\u0631\u06cc\u0627\u0644 \u0627\u06cc\u0631\u0627\u0646 1235 1235 IRR P test parse currency with foreign symbols symbol english set pattern \u00a4 0.00;\u00a4 (#) @@ -1288,16 +1287,17 @@ Euros 7.82 7.82 EUR test parse currency without currency mode // Should accept a symbol associated with the currency specified by the API, // but should not traverse the full currency data. +// P always traverses full currency data. set locale en_US set pattern \u00a4#,##0.00 begin parse currency output breaks $52.41 USD 52.41 USD52.41 USD 52.41 K -\u20ac52.41 USD fail -EUR52.41 USD fail -$52.41 EUR fail -USD52.41 EUR fail +\u20ac52.41 USD fail P +EUR52.41 USD fail P +$52.41 EUR fail P +USD52.41 EUR fail P \u20ac52.41 EUR 52.41 K EUR52.41 EUR 52.41 @@ -1307,11 +1307,11 @@ set locale en_US set lenient 0 begin parse output outputCurrency breaks -$53.45 53.45 USD +$53.45 53.45 USD P 53.45 USD 53.45 USD USD 53.45 fail USD 53.45USD fail USD -USD53.45 53.45 USD +USD53.45 53.45 USD P (7.92) USD -7.92 USD (7.92) EUR -7.92 EUR (7.926) USD -7.926 USD @@ -1329,9 +1329,9 @@ US Dollars 53.45 fail USD 53.45 US Dollars 53.45 USD US Dollar 53.45 fail USD 53.45 US Dollar 53.45 USD -US Dollars53.45 53.45 USD +US Dollars53.45 53.45 USD P 53.45US Dollars fail USD -US Dollar53.45 53.45 USD +US Dollar53.45 53.45 USD P US Dollat53.45 fail USD 53.45US Dollar fail USD US Dollars (53.45) fail USD @@ -1376,13 +1376,15 @@ test parse minus sign set locale en set pattern # begin -parse output breaks --123 -123 -- 123 -123 JK - -123 -123 JK - - 123 -123 JK -123- -123 CJKS -123 - -123 CJKS +pattern parse output breaks +# -123 -123 +# - 123 -123 JK +# -123 -123 JK +# - 123 -123 JK +# 123- 123 +# 123 - 123 +#;#- 123- -123 +#;#- 123 - -123 JK test parse case sensitive set locale en @@ -1423,8 +1425,8 @@ NaN NaN K 1E2147483646 1E2147483646 1E-2147483649 0 1E-2147483648 0 -// S returns zero here -1E-2147483647 1E-2147483647 S +// P returns zero here +1E-2147483647 1E-2147483647 P 1E-2147483646 1E-2147483646 test format push limits @@ -1439,7 +1441,7 @@ maxFractionDigits format output breaks 100 9999999999999.9950000000001 9999999999999.9950000000001 C 2 9999999999999.9950000000001 10000000000000.00 C 2 9999999.99499999 9999999.99 -// K doesn't support halfDowm rounding mode? +// K doesn't support halfDown rounding mode? 2 9999999.995 9999999.99 K 2 9999999.99500001 10000000.00 100 56565656565656565656565656565656565656565656565656565656565656 56565656565656565656565656565656565656565656565656565656565656.00 C @@ -1453,8 +1455,8 @@ set locale en set pattern #,##0 begin parse output breaks -// K and J return null; S and C return 99 - 9 9 9 CJKS +// K and J return null; S, C, and P return 99 + 9 9 9 CJKP // K returns null 9 999 9999 K @@ -1497,7 +1499,7 @@ y g h56 -56 JK 56i jk -56 CJK 56i jk -56 CJK // S and C get 56 (accepts ' ' gs grouping); J and K get null -5 6 fail CS +5 6 fail CP 56 5 JK test parse spaces in grouping @@ -1507,9 +1509,9 @@ set locale en set pattern #,##0 begin parse output breaks -// C, J and S get "12" here -1 2 1 CJS -1 23 1 CJS +// C, J, S, and P get "12" here +1 2 1 CJP +1 23 1 CJP // K gets 1 here; doesn't pick up the grouping separator 1 234 1234 K @@ -1543,7 +1545,8 @@ begin parse output breaks 55% 0.55 // J and K get null -55 0.55 JK +// P requires the symbol to be present and gets 55 +55 0.55 JKP test trailing grouping separators in pattern // This test is for #13115 @@ -1573,6 +1576,34 @@ begin parse output breaks 9223372036854775807% 92233720368547758.07 +test sign always shown +set locale en +set pattern 0 +set signAlwaysShown 1 +begin +format output breaks +// C, J and K do not support this feature +42 +42 CJK +0 +0 CJK +-42 -42 + +test parse strict with plus sign +set locale en +set pattern 0 +set signAlwaysShown 1 +begin +lenient parse output breaks +1 42 42 +1 -42 -42 +1 +42 42 CJK +1 0 0 +1 +0 0 CJK +0 42 fail CJK +0 -42 -42 +0 +42 42 CJK +0 0 fail CJK +0 +0 0 CJK + diff --git a/Build/source/libs/icu/icu-src/source/test/testdata/rbbitst.txt b/Build/source/libs/icu/icu-src/source/test/testdata/rbbitst.txt index 1450a98d7be..761b3e01b5b 100644 --- a/Build/source/libs/icu/icu-src/source/test/testdata/rbbitst.txt +++ b/Build/source/libs/icu/icu-src/source/test/testdata/rbbitst.txt @@ -38,19 +38,8 @@ # Temp debugging tests -<locale en> -<word> -<data><0>コンピューター<400>は<400>、<0>本質<400>的<400>に<400>は<400>数字<400>しか<400>扱う<400>こと<400>が<400>でき<400>ま<400>せん<400>。<0>\ -コンピューター<400>は<400>、<0>文字<400>や<400>記号<400>など<400>の<400>それぞれに<400>番号<400>を<400>割り振る<400>こと<400>によって<400>扱える<400>\ -よう<400>にし<400>ます<400>。<0>ユニ<400>コード<400>が<400>出来る<400>まで<400>は<400>、<0>これらの<400>番号<400>を<400>割り振る<400>仕組み<400>が<400>\ -何<400>百<400>種類<400>も<400>存在<400>しま<400>した<400>。<0>どの<400>一つ<400>を<400>とっても<400>、<0>十分<400>な<400>文字<400>を<400>含<400>\ -んで<400>は<400>いま<400>せん<400>で<400>した<400>。<0>例えば<400>、<0>欧州<400>連合<400>一つ<400>を<400>見<400>て<400>も<400>、<0>その<400>\ -すべて<400>の<400>言語<400>を<400>カバー<400>する<400>ため<400>に<400>は<400>、<0>いくつか<400>の<400>異なる<400>符号<400>化<400>の<400>仕組み<400>\ -が<400>必要<400>で<400>した<400>。<0>英語<400>の<400>よう<400>な<400>一つ<400>の<400>言語<400>に<400>限<400>って<400>も<400>、<0>一つ<400>だけ<400>\ -の<400>符号<400>化<400>の<400>仕組み<400>では<400>、<0>一般<400>的<400>に<400>使<400>われる<400>すべて<400>の<400>文字<400>、<0>句読点<400>、<0>\ -。<0></data> +# -#<data><0>コンピューター<400>は<400>、<0>本質<400>的<400>に<400>は<400>数字<400>しか<400>扱う<400>こと<400>が<400>でき<400>ま<400>せん<400>。<0>\ ## FILTERED BREAK TESTS @@ -330,6 +319,15 @@ <data>•\U00011700<200>ロ<400>から<400>売却<400>完了<400>時<400>の<400>時価<400>が<400>提示<400>さ<400>れ<400>て<400>いる<400></data> # +# Ticket #13549 +# CjiBreakEngine::divideUpDictionaryRange: assertion failure. +# +<locale en> +<word> +<data>•\U00020029<400>\u3300<400>\U0002C400<400></data> +<data>•\uFAD7<400>\u331B<400>\u87DF<400>\u006D<200>\uFFFD•</data> + +# # What Is Unicode in Japanese # From http://unicode.org/standard/translations/japanese.html diff --git a/Build/source/libs/icu/icu-src/source/test/testdata/root.txt b/Build/source/libs/icu/icu-src/source/test/testdata/root.txt index d619b630bf5..8ba0f076148 100644 --- a/Build/source/libs/icu/icu-src/source/test/testdata/root.txt +++ b/Build/source/libs/icu/icu-src/source/test/testdata/root.txt @@ -13,8 +13,8 @@ root { Version { 44.0 } - ExpectCLDRVersionAtLeast { 32.0 } // 'base' cldr version. Allow up to version =.=.* of this - CurrentCLDRVersion { 32.0 } // Current CLDR version as of the test update. Warn if not an exact match. + ExpectCLDRVersionAtLeast { 33.0 } // 'base' cldr version. Allow up to version =.=.* of this + CurrentCLDRVersion { 33.0 } // Current CLDR version as of the test update. Warn if not an exact match. ShortLanguage { xxx } diff --git a/Build/source/libs/icu/icu-src/source/test/testdata/structLocale.txt b/Build/source/libs/icu/icu-src/source/test/testdata/structLocale.txt index bd3d2b92855..983a7441fad 100644 --- a/Build/source/libs/icu/icu-src/source/test/testdata/structLocale.txt +++ b/Build/source/libs/icu/icu-src/source/test/testdata/structLocale.txt @@ -4134,6 +4134,10 @@ structLocale:table(nofallback){ 2, 2, } + typographicNames:intvector{ + 2, + 2, + } unit-pattern:intvector{ 2, 2, @@ -8349,6 +8353,7 @@ structLocale:table(nofallback){ } } default{""} + default_latn{""} deva{ miscPatterns{ atLeast{""} |