From 34091779c63ba188392a1a410c631b4826799ce7 Mon Sep 17 00:00:00 2001 From: Jack Horton Date: Wed, 21 Mar 2018 03:32:56 -0700 Subject: [PATCH] deps: update ChakraCore to Microsoft/ChakraCore@adf0ecb899 [MERGE #4832 @jackhorton] Update PlatformAgnostic case conversion functions to allow expanding-length strings Merge pull request #4832 from jackhorton:icu/tocase Fixes #421 Fixes #4526 Also fixes a previously untracked? bug where String.prototype.toLocale{Upper|Lower}Case.call(null) would print Reviewed-By: chakrabot --- .../lib/Runtime/Library/JavascriptString.cpp | 199 ++---- .../lib/Runtime/Library/JavascriptString.h | 10 +- .../Chakra.Runtime.PlatformAgnostic.vcxproj | 3 +- ...a.Runtime.PlatformAgnostic.vcxproj.filters | 4 +- .../Platform/Common/UnicodeText.Common.cpp | 4 +- .../Platform/Common/UnicodeText.ICU.cpp | 78 +-- .../Platform/POSIX/UnicodeText.cpp | 37 +- .../Platform/Windows/UnicodeText.cpp | 63 +- .../RuntimePlatformAgnosticPch.h | 11 - .../Runtime/PlatformAgnostic/UnicodeText.h | 25 +- .../PlatformAgnostic/UnicodeTextInternal.h | 25 + deps/chakrashim/core/test/Strings/rlexe.xml | 4 +- deps/chakrashim/core/test/Strings/toCase.js | 104 +++ .../core/test/Strings/toLowerCase.baseline | 2 - .../core/test/Strings/toLowerCase.js | 116 --- .../unicode_toUpperCase_toLowerCase.js | 658 +++++++++--------- 16 files changed, 594 insertions(+), 749 deletions(-) create mode 100644 deps/chakrashim/core/lib/Runtime/PlatformAgnostic/UnicodeTextInternal.h create mode 100644 deps/chakrashim/core/test/Strings/toCase.js delete mode 100644 deps/chakrashim/core/test/Strings/toLowerCase.baseline delete mode 100644 deps/chakrashim/core/test/Strings/toLowerCase.js diff --git a/deps/chakrashim/core/lib/Runtime/Library/JavascriptString.cpp b/deps/chakrashim/core/lib/Runtime/Library/JavascriptString.cpp index f698d2cce03..7268ea70941 100644 --- a/deps/chakrashim/core/lib/Runtime/Library/JavascriptString.cpp +++ b/deps/chakrashim/core/lib/Runtime/Library/JavascriptString.cpp @@ -2125,7 +2125,10 @@ namespace Js Assert(!(callInfo.Flags & CallFlags_New)); - return ToLocaleCaseHelper(args[0], false, scriptContext); + JavascriptString * pThis = nullptr; + GetThisStringArgument(args, scriptContext, _u("String.prototype.toLocaleLowerCase"), &pThis); + + return ToLocaleCaseHelper(pThis); } Var JavascriptString::EntryToLocaleUpperCase(RecyclableObject* function, CallInfo callInfo, ...) @@ -2137,9 +2140,20 @@ namespace Js Assert(!(callInfo.Flags & CallFlags_New)); - return ToLocaleCaseHelper(args[0], true, scriptContext); + JavascriptString * pThis = nullptr; + GetThisStringArgument(args, scriptContext, _u("String.prototype.toLocaleUpperCase"), &pThis); + + return ToLocaleCaseHelper(pThis); } + template + JavascriptString* JavascriptString::ToLocaleCaseHelper(JavascriptString* pThis) + { + // TODO: implement locale-sensitive Intl versions of these functions + return ToCaseCore(pThis); + } + + Var JavascriptString::EntryToLowerCase(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); @@ -2152,23 +2166,7 @@ namespace Js JavascriptString * pThis = nullptr; GetThisStringArgument(args, scriptContext, _u("String.prototype.toLowerCase"), &pThis); - // Fast path for one character strings - if (pThis->GetLength() == 1) - { - char16 inChar = pThis->GetString()[0]; - char16 outChar = inChar; -#if DBG - DWORD converted = -#endif - PlatformAgnostic::UnicodeText::ChangeStringCaseInPlace( - PlatformAgnostic::UnicodeText::CaseFlags::CaseFlagsLower, &outChar, 1); - - Assert(converted == 1); - - return (inChar == outChar) ? pThis : scriptContext->GetLibrary()->GetCharStringCache().GetStringForChar(outChar); - } - - return ToCaseCore(pThis, ToLower); + return ToCaseCore(pThis); } Var JavascriptString::EntryToString(RecyclableObject* function, CallInfo callInfo, ...) @@ -2216,113 +2214,50 @@ namespace Js JavascriptString* pThis = nullptr; GetThisStringArgument(args, scriptContext, _u("String.prototype.toUpperCase"), &pThis); - // Fast path for one character strings - if (pThis->GetLength() == 1) - { - char16 inChar = pThis->GetString()[0]; - char16 outChar = inChar; -#if DBG - DWORD converted = -#endif - PlatformAgnostic::UnicodeText::ChangeStringCaseInPlace( - PlatformAgnostic::UnicodeText::CaseFlags::CaseFlagsUpper, &outChar, 1); - - Assert(converted == 1); - - return (inChar == outChar) ? pThis : scriptContext->GetLibrary()->GetCharStringCache().GetStringForChar(outChar); - } - - return ToCaseCore(pThis, ToUpper); + return ToCaseCore(pThis); } - Var JavascriptString::ToCaseCore(JavascriptString* pThis, ToCase toCase) + template + JavascriptString* JavascriptString::ToCaseCore(JavascriptString* pThis) { - Var resultVar = nullptr; - EnterPinnedScope((volatile void**)& pThis); - charcount_t count = pThis->GetLength(); - - const char16* inStr = pThis->GetString(); - const char16* inStrLim = inStr + count; - const char16* i = inStr; - - // Try to find out the chars that do not need casing (in the ASCII range) - if (toCase == ToUpper) - { - while (i < inStrLim) - { - // first range of ascii lower-case (97-122) - // second range of ascii lower-case (223-255) - // non-ascii chars (255+) - if (*i >= 'a') - { - if (*i <= 'z') { break; } - if (*i >= 223) { break; } - } - i++; - } - } - else + using namespace PlatformAgnostic::UnicodeText; + if (pThis->GetLength() == 0) { - Assert(toCase == ToLower); - while (i < inStrLim) - { - // first range of ascii uppercase (65-90) - // second range of ascii uppercase (192-222) - // non-ascii chars (255+) - if (*i >= 'A') - { - if (*i <= 'Z') { break; } - if (*i >= 192) - { - if (*i < 223) { break; } - if (*i >= 255) { break; } - } - } - i++; - } + return pThis; } - // If no char needs casing, return immediately - if (i == inStrLim) { return pThis; } + ScriptContext* scriptContext = pThis->type->GetScriptContext(); - // Otherwise, copy the string and start casing - charcount_t countToCase = (charcount_t)(inStrLim - i); - BufferStringBuilder builder(count, pThis->type->GetScriptContext()); - char16 *outStr = builder.DangerousGetWritableBuffer(); + ApiError error = ApiError::NoError; - char16* outStrLim = outStr + count; - char16 *o = outStr; + // pre-flight to get the length required, as it may be longer than the original string + // NOTE: ICU and Win32(/POSIX) implementations of these functions differ slightly in how to get the required number of characters. + // For Win32 (LCMapStringEx), you must provide nullptr/0, as providing a buffer that is too small will cause an error and will *not* + // report the number of characters required. For ICU, however, you can provide a buffer that is too short, and it will still return + // the length it actually needs. + // TODO: Investigate pre-allocating buffers for ICU, as the ICU case will be the default going forward + charcount_t requiredStringLength = ChangeStringLinguisticCase(pThis->GetSz(), pThis->GetLength(), nullptr, 0, &error); + Assert(error == ApiError::NoError || error == ApiError::InsufficientBuffer); - while (o < outStrLim) - { - *o++ = *inStr++; - } + // REVIEW: this assert may be too defensive if strings can get shorter through upper/lower casing + Assert(requiredStringLength >= pThis->GetLength()); - if (toCase == ToUpper) + if (requiredStringLength == 1) { -#if DBG - DWORD converted = -#endif - PlatformAgnostic::UnicodeText::ChangeStringCaseInPlace( - PlatformAgnostic::UnicodeText::CaseFlags::CaseFlagsUpper, outStrLim - countToCase, countToCase); - - Assert(converted == countToCase); + // Fast path for one-char strings + char16 buffer[2] = { pThis->GetSz()[0], 0 }; + charcount_t actualStringLength = ChangeStringLinguisticCase(pThis->GetSz(), pThis->GetLength(), buffer, 2, &error); + Assert(actualStringLength == 1 && error == ApiError::NoError); + return scriptContext->GetLibrary()->GetCharStringCache().GetStringForChar(buffer[0]); } else { - Assert(toCase == ToLower); -#if DBG - DWORD converted = -#endif - PlatformAgnostic::UnicodeText::ChangeStringCaseInPlace( - PlatformAgnostic::UnicodeText::CaseFlags::CaseFlagsLower, outStrLim - countToCase, countToCase); - - Assert(converted == countToCase); + charcount_t bufferLength = requiredStringLength + 1; + char16* buffer = RecyclerNewArrayLeaf(scriptContext->GetRecycler(), char16, bufferLength); + charcount_t actualStringLength = ChangeStringLinguisticCase(pThis->GetSz(), pThis->GetLength(), buffer, bufferLength, &error); + Assert(actualStringLength == requiredStringLength && error == ApiError::NoError); + return JavascriptString::NewWithBuffer(buffer, actualStringLength, scriptContext); } - resultVar = builder.ToString(); - LeavePinnedScope(); // pThis - - return resultVar; } Var JavascriptString::EntryTrim(RecyclableObject* function, CallInfo callInfo, ...) @@ -3320,48 +3255,6 @@ namespace Js return builder.ToString(); } - Var JavascriptString::ToLocaleCaseHelper(Var thisObj, bool toUpper, ScriptContext *scriptContext) - { - using namespace PlatformAgnostic::UnicodeText; - - JavascriptString * pThis = JavascriptOperators::TryFromVar(thisObj); - - if (!pThis) - { - pThis = JavascriptConversion::ToString(thisObj, scriptContext); - } - - uint32 strLength = pThis->GetLength(); - if (strLength == 0) - { - return pThis; - } - - // Get the number of chars in the mapped string. - CaseFlags caseFlags = (toUpper ? CaseFlags::CaseFlagsUpper : CaseFlags::CaseFlagsLower); - const char16* str = pThis->GetString(); - ApiError err = ApiError::NoError; - int32 count = PlatformAgnostic::UnicodeText::ChangeStringLinguisticCase(caseFlags, str, strLength, nullptr, 0, &err); - - if (count <= 0) - { - AssertMsg(err != ApiError::NoError, "LCMapString failed"); - Throw::InternalError(); - } - - BufferStringBuilder builder(count, scriptContext); - char16* stringBuffer = builder.DangerousGetWritableBuffer(); - - int count1 = PlatformAgnostic::UnicodeText::ChangeStringLinguisticCase(caseFlags, str, strLength, stringBuffer, count, &err); - - if (count1 <= 0) - { - AssertMsg(err != ApiError::NoError, "LCMapString failed"); - Throw::InternalError(); - } - - return builder.ToString(); - } int JavascriptString::IndexOfUsingJmpTable(JmpTable jmpTable, const char16* inputStr, charcount_t len, const char16* searchStr, int searchLen, int position) { diff --git a/deps/chakrashim/core/lib/Runtime/Library/JavascriptString.h b/deps/chakrashim/core/lib/Runtime/Library/JavascriptString.h index 20444a2e080..1c8b6519446 100644 --- a/deps/chakrashim/core/lib/Runtime/Library/JavascriptString.h +++ b/deps/chakrashim/core/lib/Runtime/Library/JavascriptString.h @@ -135,13 +135,10 @@ namespace Js static int strcmp(JavascriptString *string1, JavascriptString *string2); private: - enum ToCase{ - ToLower, - ToUpper - }; char16* GetSzCopy(); // get a copy of the inner string without compacting the chunks - static Var ToCaseCore(JavascriptString* pThis, ToCase toCase); + template + static JavascriptString* ToCaseCore(JavascriptString* pThis); static int IndexOfUsingJmpTable(JmpTable jmpTable, const char16* inputStr, charcount_t len, const char16* searchStr, int searchLen, int position); static int LastIndexOfUsingJmpTable(JmpTable jmpTable, const char16* inputStr, charcount_t len, const char16* searchStr, charcount_t searchLen, charcount_t position); @@ -331,7 +328,8 @@ namespace Js static void SearchValueHelper(ScriptContext* scriptContext, Var aValue, JavascriptRegExp ** ppSearchRegEx, JavascriptString ** ppSearchString); static void ReplaceValueHelper(ScriptContext* scriptContext, Var aValue, JavascriptFunction ** ppReplaceFn, JavascriptString ** ppReplaceString); - static Var ToLocaleCaseHelper(Var thisObj, bool toUpper, ScriptContext *scriptContext); + template + static JavascriptString* ToLocaleCaseHelper(JavascriptString* thisObj); static void InstantiateForceInlinedMembers(); diff --git a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Chakra.Runtime.PlatformAgnostic.vcxproj b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Chakra.Runtime.PlatformAgnostic.vcxproj index ae8888a2391..b6ba02ad956 100644 --- a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Chakra.Runtime.PlatformAgnostic.vcxproj +++ b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Chakra.Runtime.PlatformAgnostic.vcxproj @@ -57,7 +57,8 @@ - + + diff --git a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Chakra.Runtime.PlatformAgnostic.vcxproj.filters b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Chakra.Runtime.PlatformAgnostic.vcxproj.filters index 528e27e24b0..9e7d0942a4e 100644 --- a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Chakra.Runtime.PlatformAgnostic.vcxproj.filters +++ b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Chakra.Runtime.PlatformAgnostic.vcxproj.filters @@ -31,11 +31,9 @@ Interfaces - - Interfaces - Interfaces + diff --git a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/Common/UnicodeText.Common.cpp b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/Common/UnicodeText.Common.cpp index 031ce0d7833..16023f31580 100644 --- a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/Common/UnicodeText.Common.cpp +++ b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/Common/UnicodeText.Common.cpp @@ -44,13 +44,13 @@ namespace PlatformAgnostic namespace Internal { template - inline bool isDigit(__in CharType c) + bool isDigit(__in CharType c) { return c >= '0' && c <= '9'; } template - inline int readNumber(__inout CharType* &str) + int readNumber(__inout CharType* &str) { int num = 0; diff --git a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/Common/UnicodeText.ICU.cpp b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/Common/UnicodeText.ICU.cpp index c661404e283..60b38da6b5d 100644 --- a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/Common/UnicodeText.ICU.cpp +++ b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/Common/UnicodeText.ICU.cpp @@ -5,6 +5,7 @@ #include "RuntimePlatformAgnosticPch.h" #include "UnicodeText.h" +#include "UnicodeTextInternal.h" #include "ChakraICU.h" namespace PlatformAgnostic @@ -107,17 +108,20 @@ namespace PlatformAgnostic { switch (icuError) { - case U_BUFFER_OVERFLOW_ERROR: - return ApiError::InsufficientBuffer; - case U_ILLEGAL_ARGUMENT_ERROR: - case U_UNSUPPORTED_ERROR: - return ApiError::InvalidParameter; - case U_INVALID_CHAR_FOUND: - case U_TRUNCATED_CHAR_FOUND: - case U_ILLEGAL_CHAR_FOUND: - return ApiError::InvalidUnicodeText; - default: - return ApiError::UntranslatedError; + case U_ZERO_ERROR: + return ApiError::NoError; + case U_BUFFER_OVERFLOW_ERROR: + case U_STRING_NOT_TERMINATED_WARNING: + return ApiError::InsufficientBuffer; + case U_ILLEGAL_ARGUMENT_ERROR: + case U_UNSUPPORTED_ERROR: + return ApiError::InvalidParameter; + case U_INVALID_CHAR_FOUND: + case U_TRUNCATED_CHAR_FOUND: + case U_ILLEGAL_CHAR_FOUND: + return ApiError::InvalidUnicodeText; + default: + return ApiError::UntranslatedError; } } @@ -224,55 +228,35 @@ namespace PlatformAgnostic return u_isUWhiteSpace(ch) == 1; } - int32 ChangeStringLinguisticCase(CaseFlags caseFlags, const char16* sourceString, uint32 sourceLength, char16* destString, uint32 destLength, ApiError* pErrorOut) + template + charcount_t ChangeStringLinguisticCase(const char16* sourceString, charcount_t sourceLength, char16* destString, charcount_t destLength, ApiError* pErrorOut) { + Assert(sourceString != nullptr && sourceLength > 0); + Assert(destString != nullptr || destLength == 0); + int32_t resultStringLength = 0; UErrorCode errorCode = U_ZERO_ERROR; + *pErrorOut = ApiError::NoError; + + // u_strTo treats nullptr as the system default locale and "" as root + const char* locale = useInvariant ? "" : nullptr; - if (caseFlags == CaseFlagsUpper) + if (toUpper) { resultStringLength = u_strToUpper((UChar*) destString, destLength, - (UChar*) sourceString, sourceLength, NULL, &errorCode); - } - else if (caseFlags == CaseFlagsLower) - { - resultStringLength = u_strToLower((UChar*) destString, destLength, - (UChar*) sourceString, sourceLength, NULL, &errorCode); + (UChar*) sourceString, sourceLength, locale, &errorCode); } else { - Assert(false); - } - - if (U_FAILURE(errorCode) && - !(destLength == 0 && errorCode == U_BUFFER_OVERFLOW_ERROR)) - { - *pErrorOut = TranslateUErrorCode(errorCode); - return -1; + resultStringLength = u_strToLower((UChar*) destString, destLength, + (UChar*) sourceString, sourceLength, locale, &errorCode); } - // Todo: check for resultStringLength > destLength - // Return insufficient buffer in that case - return resultStringLength; - } - - uint32 ChangeStringCaseInPlace(CaseFlags caseFlags, char16* stringToChange, uint32 bufferLength) - { - // Assert pointers - Assert(stringToChange != nullptr); - ApiError error = NoError; - - if (bufferLength == 0 || stringToChange == nullptr) - { - return 0; - } + AssertMsg(resultStringLength > 0, "u_strToCase must return required destString length"); - int32 ret = ChangeStringLinguisticCase(caseFlags, stringToChange, bufferLength, stringToChange, bufferLength, &error); + *pErrorOut = TranslateUErrorCode(errorCode); - // Callers to this function don't expect any errors - Assert(error == ApiError::NoError); - Assert(ret > 0); - return (uint32) ret; + return static_cast(resultStringLength); } bool IsIdStart(codepoint_t ch) diff --git a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/POSIX/UnicodeText.cpp b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/POSIX/UnicodeText.cpp index 728a059541d..5f81fa555bc 100644 --- a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/POSIX/UnicodeText.cpp +++ b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/POSIX/UnicodeText.cpp @@ -5,6 +5,8 @@ #include "RuntimePlatformAgnosticPch.h" #include "UnicodeText.h" +#include "UnicodeTextInternal.h" + #include #include #define IS_CHAR(ch) \ @@ -46,7 +48,8 @@ namespace PlatformAgnostic return true; } - int32 ChangeStringLinguisticCase(CaseFlags caseFlags, const char16* sourceString, uint32 sourceLength, char16* destString, uint32 destLength, ApiError* pErrorOut) + template + charcount_t ChangeStringLinguisticCase(const char16* sourceString, charcount_t sourceLength, char16* destString, charcount_t destLength, ApiError* pErrorOut) { typedef WCHAR(*CaseConversionFunc)(WCHAR); *pErrorOut = ApiError::NoError; @@ -55,14 +58,14 @@ namespace PlatformAgnostic return sourceLength; } - int32 len = (int32)minm(minm(destLength, sourceLength), INT_MAX); - CaseConversionFunc fnc = caseFlags == CaseFlagsLower ? PAL_towlower : PAL_towupper; - for (int32 i = 0; i < len; i++) + charcount_t len = static_cast(minm(minm(destLength, sourceLength), MaxCharCount)); + CaseConversionFunc fnc = toUpper ? PAL_towupper : PAL_towlower; + for (charcount_t i = 0; i < len; i++) { destString[i] = fnc(sourceString[i]); } - return len; + return static_cast(len); } bool IsWhitespace(codepoint_t ch) @@ -120,30 +123,6 @@ namespace PlatformAgnostic } } - uint32 ChangeStringCaseInPlace(CaseFlags caseFlags, char16* stringToChange, uint32 bufferLength) - { - // ASCII only - typedef int (*CaseFlipper)(int); - CaseFlipper flipper; - if (caseFlags == CaseFlagsUpper) - { - flipper = toupper; - } - else - { - flipper = tolower; - } - for(uint32 i = 0; i < bufferLength; i++) - { - if (stringToChange[i] > 0 && stringToChange[i] < 127) - { - char ch = (char)stringToChange[i]; - stringToChange[i] = flipper(ch); - } - } - return bufferLength; - } - int LogicalStringCompare(const char16* string1, const char16* string2) { return PlatformAgnostic::UnicodeText::Internal::LogicalStringCompareImpl(string1, string2); diff --git a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/Windows/UnicodeText.cpp b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/Windows/UnicodeText.cpp index 5910ceec826..879bc244c6c 100644 --- a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/Windows/UnicodeText.cpp +++ b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/Platform/Windows/UnicodeText.cpp @@ -5,6 +5,7 @@ #include "RuntimePlatformAgnosticPch.h" #include "UnicodeText.h" +#include "UnicodeTextInternal.h" #include #include "Runtime.h" @@ -295,54 +296,46 @@ namespace PlatformAgnostic return (::IsNormalizedString(TranslateToWin32NormForm(normalizationForm), (LPCWSTR)testString, testStringLength) == TRUE); } - int32 ChangeStringLinguisticCase(CaseFlags caseFlags, const char16* sourceString, uint32 sourceLength, char16* destString, uint32 destLength, ApiError* pErrorOut) + template + charcount_t ChangeStringLinguisticCase(const char16* sourceString, charcount_t sourceLength, char16* destString, charcount_t destLength, ApiError* pErrorOut) { - // Assert pointers - Assert(sourceString != nullptr); + Assert(sourceString != nullptr && sourceLength > 0); Assert(destString != nullptr || destLength == 0); - // LCMapString does not allow the source length to be set to 0 - Assert(sourceLength > 0); - *pErrorOut = NoError; - DWORD dwFlags = caseFlags == CaseFlags::CaseFlagsUpper ? LCMAP_UPPERCASE : LCMAP_LOWERCASE; + DWORD dwFlags = toUpper ? LCMAP_UPPERCASE : LCMAP_LOWERCASE; dwFlags |= LCMAP_LINGUISTIC_CASING; - LCID lcid = GetUserDefaultLCID(); - - int translatedStringLength = LCMapStringW(lcid, dwFlags, sourceString, sourceLength, destString, destLength); - - if (translatedStringLength == 0) - { - *pErrorOut = TranslateWin32Error(::GetLastError()); - } - - Assert(translatedStringLength >= 0); - return (uint32) translatedStringLength; - } - - uint32 ChangeStringCaseInPlace(CaseFlags caseFlags, char16* sourceString, uint32 sourceLength) - { - // Assert pointers - Assert(sourceString != nullptr); - - if (sourceLength == 0 || sourceString == nullptr) + // REVIEW: The documentation for LCMapStringEx says that it returns "the number of characters or bytes in the translated string + // or sort key, including a terminating null character, if successful." However, in testing, this does not seem to be the case, + // as it always returns the count of characters without the null terminator. + // See https://msdn.microsoft.com/en-us/library/windows/desktop/dd318702(v=vs.85).aspx + int required = LCMapStringEx( + useInvariant ? LOCALE_NAME_INVARIANT : LOCALE_NAME_USER_DEFAULT, + dwFlags, + sourceString, + sourceLength, + destString, + destLength, + nullptr, + nullptr, + 0 + ); + + Assert(required >= 0); + if (destString != nullptr) { - return 0; + Assert(static_cast(required) == destLength - 1); + destString[required] = 0; } - if (caseFlags == CaseFlagsUpper) - { - return (uint32) CharUpperBuff(sourceString, sourceLength); - } - else if (caseFlags == CaseFlagsLower) + if (required == 0) { - return (uint32) CharLowerBuff(sourceString, sourceLength); + *pErrorOut = TranslateWin32Error(::GetLastError()); } - AssertMsg(false, "Invalid flags passed to ChangeStringCaseInPlace"); - return 0; + return static_cast(required); } UnicodeGeneralCategoryClass GetGeneralCategoryClass(codepoint_t codepoint) diff --git a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/RuntimePlatformAgnosticPch.h b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/RuntimePlatformAgnosticPch.h index b5b286daa83..038952c0945 100644 --- a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/RuntimePlatformAgnosticPch.h +++ b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/RuntimePlatformAgnosticPch.h @@ -50,14 +50,3 @@ class Throw #include #endif - -namespace PlatformAgnostic -{ - namespace UnicodeText - { - namespace Internal - { - int LogicalStringCompareImpl(const char16* p1, const char16* p2); - } - } -} diff --git a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/UnicodeText.h b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/UnicodeText.h index d2f5fa659a0..25cb0ab5ab0 100644 --- a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/UnicodeText.h +++ b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/UnicodeText.h @@ -6,6 +6,7 @@ #include "Core/CommonTypedefs.h" #include "ChakraICU.h" +#include "sal.h" namespace PlatformAgnostic { @@ -195,33 +196,17 @@ namespace PlatformAgnostic // // Change the case of a string using linguistic rules // Params: - // caseFlags: the case to convert to // sourceString: The string to convert - // sourceLength: The number of characters in the source string. This must be provided, the function does not assume null-termination etc. Length should be greater than 0. + // sourceLength: The number of characters in the source string. This must be provided, the function does not assume null-termination. Length should be greater than 0. // destString: Optional pointer to the destination string buffer. It can be null if destLength is 0, if you want the required buffer size // destLength: Size in characters of the destination buffer, or 0 if the function shuld just return the required character count for the dest buffer. // pErrorOut: Set to NoError, or the actual error if one occurred. // // Return Value: - // length of the translated string in the destination buffer - // If the return value is less than or equal to 0, then see the value of pErrorOut to understand the error - // - int32 ChangeStringLinguisticCase(CaseFlags caseFlags, const char16* sourceString, uint32 sourceLength, char16* destString, uint32 destLength, ApiError* pErrorOut); - - // - // Change the case of a string using linguistic rules - // The string is changed in place - // - // Params: - // caseFlags: the case to convert to - // sourceString: The string to convert - // sourceLength: The number of characters in the source string. This must be provided, the function does not assume null-termination etc. Length should be greater than 0. - // - // Return Value: - // length of the translated string in the destination buffer - // If the return value is less than or equal to 0, then see the value of pErrorOut to understand the error + // The length required to convert sourceString to the given case, even if destString was not large enough to hold it, including the null terminator // - uint32 ChangeStringCaseInPlace(CaseFlags caseFlags, char16* stringToChange, uint32 bufferLength); + template + charcount_t ChangeStringLinguisticCase(_In_count_(sourceLength) const char16* sourceString, _In_ charcount_t sourceLength, _Out_writes_(destLength) char16* destString, _In_ charcount_t destLength, _Out_ ApiError* pErrorOut); // // Return the classification type of the character using Unicode 2.0 rules diff --git a/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/UnicodeTextInternal.h b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/UnicodeTextInternal.h new file mode 100644 index 00000000000..81f59fdfffc --- /dev/null +++ b/deps/chakrashim/core/lib/Runtime/PlatformAgnostic/UnicodeTextInternal.h @@ -0,0 +1,25 @@ +//------------------------------------------------------------------------------------------------------- +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. +//------------------------------------------------------------------------------------------------------- +#pragma once + +namespace PlatformAgnostic +{ +namespace UnicodeText +{ + +// Instantiate templates here rather than in each implementing file +template charcount_t ChangeStringLinguisticCase(const char16* sourceString, charcount_t sourceLength, char16* destString, charcount_t destLength, ApiError* pErrorOut); +template charcount_t ChangeStringLinguisticCase(const char16* sourceString, charcount_t sourceLength, char16* destString, charcount_t destLength, ApiError* pErrorOut); +template charcount_t ChangeStringLinguisticCase(const char16* sourceString, charcount_t sourceLength, char16* destString, charcount_t destLength, ApiError* pErrorOut); +template charcount_t ChangeStringLinguisticCase(const char16* sourceString, charcount_t sourceLength, char16* destString, charcount_t destLength, ApiError* pErrorOut); + +namespace Internal +{ + +int LogicalStringCompareImpl(const char16* p1, const char16* p2); + +}; // namespace Internal +}; // namespace UnicodeText +}; // namespace PlatformAgnostic diff --git a/deps/chakrashim/core/test/Strings/rlexe.xml b/deps/chakrashim/core/test/Strings/rlexe.xml index 5b9bffb603a..bf3a1253faa 100644 --- a/deps/chakrashim/core/test/Strings/rlexe.xml +++ b/deps/chakrashim/core/test/Strings/rlexe.xml @@ -90,9 +90,7 @@ - toLowerCase.js - toLowerCase.baseline - -Intl- + toCase.js diff --git a/deps/chakrashim/core/test/Strings/toCase.js b/deps/chakrashim/core/test/Strings/toCase.js new file mode 100644 index 00000000000..942b5ba169b --- /dev/null +++ b/deps/chakrashim/core/test/Strings/toCase.js @@ -0,0 +1,104 @@ +//------------------------------------------------------------------------------------------------------- +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. +//------------------------------------------------------------------------------------------------------- + +WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js"); + +function testASCII(lower, upper, message) { + const toUppers = [ String.prototype.toUpperCase, String.prototype.toLocaleUpperCase ]; + const toLowers = [ String.prototype.toLowerCase, String.prototype.toLocaleLowerCase ]; + for (const func of toUppers) { + assert.areEqual(upper, func.call(lower), `lower.${func.name}(): ${message}`); + assert.areEqual(upper, func.call(upper), `upper.${func.name}(): ${message}`); + } + for (const func of toLowers) { + assert.areEqual(lower, func.call(upper), `upper.${func.name}(): ${message}`); + assert.areEqual(lower, func.call(lower), `lower.${func.name}(): ${message}`); + } +} + +testRunner.runTests([ + { + name: "Visible ASCII characters", + body() { + testASCII("", "", "Empty string"); + + let i = 32; + let upper = ""; + let lower = ""; + for (; i < 65; i++) { + upper += String.fromCharCode(i); + lower += String.fromCharCode(i); + } + for (; i < 91; i++) { + upper += String.fromCharCode(i); + } + for (i = 97; i < 123; i++) { + lower += String.fromCharCode(i); + } + for (i = 91; i < 97; i++) { + upper += String.fromCharCode(i); + lower += String.fromCharCode(i); + } + for (i = 123; i < 127; i++) { + upper += String.fromCharCode(i); + lower += String.fromCharCode(i); + } + + testASCII(lower, upper, "Visible ASCII"); + } + }, + { + name: "Special characters", + body() { + const specialCharacters = { + "\n": "newline", + "\t": "tab", + "\r": "carriage return", + "\0": "null", + "\"": "double quote", + "\'": "single quote", + "\b": "backspace", + }; + + for (const c in specialCharacters) { + testASCII(`${c}microsoft`, `${c}MICROSOFT`, `string with ${specialCharacters[c]} at the beginning`); + testASCII(`micro${c}soft`, `MICRO${c}SOFT`, `string with ${specialCharacters[c]} in the middle`); + testASCII(`microsoft${c}`, `MICROSOFT${c}`, `string with ${specialCharacters[c]} at the end`); + } + } + }, + { + name: "Type conversion", + body() { + const convertible = [ + [new Number(123), "123", "123"], + [new Boolean(true), "true", "TRUE"], + [new String("aBc"), "abc", "ABC"], + [new Object(), "[object object]", "[OBJECT OBJECT]"], + [["Chakra", 2018, true], "chakra,2018,true", "CHAKRA,2018,TRUE"], + [{ toString: () => "Hello" }, "hello", "HELLO"] + ]; + + for (const test of convertible) { + for (const func of [String.prototype.toLowerCase, String.prototype.toLocaleLowerCase]) { + assert.areEqual(test[1], func.call(test[0]), `${func.name}: type conversion of ${test[0]} to ${test[1]}`); + } + for (const func of [String.prototype.toUpperCase, String.prototype.toLocaleUpperCase]) { + assert.areEqual(test[2], func.call(test[0]), `${func.name}: type conversion of ${test[0]} to ${test[2]}`); + } + } + } + }, + { + name: "Correct errors are thrown", + body() { + for (const badThis of [null, undefined]) { + for (const func of [String.prototype.toUpperCase, String.prototype.toLocaleUpperCase, String.prototype.toLowerCase, String.prototype.toLocaleLowerCase]) { + assert.throws(() => func.call(badThis), TypeError, `${func.name}.call(${Object.prototype.toString.call(badThis)})`); + } + } + } + }, +], { verbose: false }); diff --git a/deps/chakrashim/core/test/Strings/toLowerCase.baseline b/deps/chakrashim/core/test/Strings/toLowerCase.baseline deleted file mode 100644 index a2fa990ff51..00000000000 --- a/deps/chakrashim/core/test/Strings/toLowerCase.baseline +++ /dev/null @@ -1,2 +0,0 @@ -done -3 diff --git a/deps/chakrashim/core/test/Strings/toLowerCase.js b/deps/chakrashim/core/test/Strings/toLowerCase.js deleted file mode 100644 index 1911d19a275..00000000000 --- a/deps/chakrashim/core/test/Strings/toLowerCase.js +++ /dev/null @@ -1,116 +0,0 @@ -//------------------------------------------------------------------------------------------------------- -// Copyright (C) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -//------------------------------------------------------------------------------------------------------- - -//String.prototype.toLowerCase() -//TO DO : Need to add Unicode and Upper Ascii Characters test cases and also Test cases that would throw exception(NaN and undefined Objects) - -var id=0; -function verify(get_actual,get_expected,testid,testdesc) -{ - - if(get_actual!=get_expected) - WScript.Echo(testid+":"+testdesc+"\t"+"failed"+"\n"+"got"+get_actual+"\t for\t"+get_expected) -} - -//test 1 - -verify("\tMICROSOFT".toLowerCase(), "\tmicrosoft", id++, "\"Testing Escape character tab\"") - -//test 2 -verify("\nMICROSOFT".toLowerCase(), "\nmicrosoft", id++, "\"Testing Escape character new line\"") - -//test3 - -verify("\rMICROSOFT".toLowerCase(), "\rmicrosoft", id++, "\"Testing Escape character return \"") - -//test 4 -verify("\'MICROSOFT\'".toLowerCase(), "\'microsoft\'", id++, "\"Testing Escape character single quote\"") - -//test 5 -verify("MICROO\bSOFT".toLowerCase(), "microo\bsoft", id++, "\"Testing Escape character backspace\"") - -//test 6 - -verify("\"MICROSOFT\"".toLowerCase(), "\"microsoft\"", id++, "\"Testing Escape character double quote\"") - -//test 7 - -verify("microsoft".toLowerCase(), "microsoft", id++, "\"Testing passing lower case characters\"") - -//test 8 -verify("ABCDEFGHIJKLMNOPQRSTUVWXYZ".toLowerCase(), "abcdefghijklmnopqrstuvwxyz", id++, "\"Testing passing uppercase case characters\"") - -//test 9 -verify("(!@#$%^&*<,()+;:>?/)".toLowerCase(), "(!@#$%^&*<,()+;:>?/)", id++, "\" Testing passing Special Characters \"") - -//test 10 - -verify("REDMOND@MICROSOFT.COM".toLowerCase(), "redmond@microsoft.com", id++, "\"Testing mix of characters eg email id\""); - -//test 11 - -verify("ONEMICROSOFTWAY,156THNE31STPL,WA98054".toLowerCase(), "onemicrosoftway,156thne31stpl,wa98054", id++, "\"Testing mix of characters eg address\""); - -//test 12 - -verify("1-800-CALL-HSBC".toLowerCase(), "1-800-call-hsbc", id++, id++, "\"Testing mix of characters eg phone number\" "); - -//test 13: Coercing Other Object types : Arrays - -var arr=new Array(3); -arr[0]="JSCRIPT"; -arr[1]=12345; -arr[2]="123@MiCrOSOFT.com"; -Array.prototype.toLowerCase=String.prototype.toLowerCase; //the prototype method of string can now be called from the array object -verify(arr.toLowerCase(), "jscript,12345,123@microsoft.com", id++, "\"Testing Coercible Objects eg Array\" "); - -//test 14 Coercing Other Object types : Number - -var num=new Number(); -num=12345 -Number.prototype.toLowerCase=String.prototype.toLowerCase; -verify(num.toLowerCase(), "12345", id++, "\"Testing Coercible Objects eg Number\" "); - -//test 15 Coercing Other Object types : Boolean - -var mybool=new Boolean(false); -Boolean.prototype.toLowerCase=String.prototype.toLowerCase; -verify(mybool.toLowerCase(), "false", id++, "\"Testing Coercible Objects eg Boolean\" "); - -//test 16 Coercing Other Object types : Object - -var obj=new Object() -Object.prototype.toLowerCase=String.prototype.toLowerCase; -verify(obj.toLowerCase(), "[object object]", id++, "\"Testing Coercible Objects eg Object\" "); - -//Need to test for null and undefined but have to know the error message - -//test 17 Concatenated String - -verify(("CONCATENATED"+"STRING").toLowerCase(), "concatenatedstring", id++, "\" Testing Concatenated String\""); - -//test 18 Indirect Call through Function - -var Foo=function(){} -Foo.prototype.test=function(){return "MYSTRING";} -var fun=new Foo() -verify(fun.test().toLowerCase(), "mystring", id++, "\"Testing indirect calling eg function\"") - -//test 19 Indirect call through property - -var myobj=new Object(); -myobj.prop="STRING"; -verify(myobj.prop.toLowerCase(), "string", id++, "\"Testing indirect calling eg property\""); - -WScript.Echo("done"); - -//test 20 implicit calls -var a = 1; -var b = 2; -var obj = {toString: function(){ a=3; return "Hello World";}}; -a = b; -Object.prototype.toLowerCase = String.prototype.toLowerCase; -var f = obj.toLowerCase(); -WScript.Echo (a); diff --git a/deps/chakrashim/core/test/Strings/unicode_toUpperCase_toLowerCase.js b/deps/chakrashim/core/test/Strings/unicode_toUpperCase_toLowerCase.js index 88c2b9c5684..e9cb1acee07 100644 --- a/deps/chakrashim/core/test/Strings/unicode_toUpperCase_toLowerCase.js +++ b/deps/chakrashim/core/test/Strings/unicode_toUpperCase_toLowerCase.js @@ -6,327 +6,343 @@ WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js"); var tests = [ - { - name: "Deseret alphabet toUpperCase", - body: function () { - assert.areEqual("\uD801\uDC00", "\uD801\uDC28".toUpperCase(), "Expecting Deseret alphabet upper-case long I"); - assert.areEqual("\uD801\uDC01", "\uD801\uDC29".toUpperCase(), "Expecting Deseret alphabet upper-case long E"); - assert.areEqual("\uD801\uDC02", "\uD801\uDC2A".toUpperCase(), "Expecting Deseret alphabet upper-case long A"); - assert.areEqual("\uD801\uDC03", "\uD801\uDC2B".toUpperCase(), "Expecting Deseret alphabet upper-case long Ah"); - assert.areEqual("\uD801\uDC04", "\uD801\uDC2C".toUpperCase(), "Expecting Deseret alphabet upper-case long O"); - assert.areEqual("\uD801\uDC05", "\uD801\uDC2D".toUpperCase(), "Expecting Deseret alphabet upper-case long Oo"); - assert.areEqual("\uD801\uDC06", "\uD801\uDC2E".toUpperCase(), "Expecting Deseret alphabet upper-case short I"); - assert.areEqual("\uD801\uDC07", "\uD801\uDC2F".toUpperCase(), "Expecting Deseret alphabet upper-case short E"); - assert.areEqual("\uD801\uDC08", "\uD801\uDC30".toUpperCase(), "Expecting Deseret alphabet upper-case short A"); - assert.areEqual("\uD801\uDC09", "\uD801\uDC31".toUpperCase(), "Expecting Deseret alphabet upper-case short Ah"); - assert.areEqual("\uD801\uDC0A", "\uD801\uDC32".toUpperCase(), "Expecting Deseret alphabet upper-case short O"); - assert.areEqual("\uD801\uDC0B", "\uD801\uDC33".toUpperCase(), "Expecting Deseret alphabet upper-case short Oo"); - assert.areEqual("\uD801\uDC0C", "\uD801\uDC34".toUpperCase(), "Expecting Deseret alphabet upper-case Ay"); - assert.areEqual("\uD801\uDC0D", "\uD801\uDC35".toUpperCase(), "Expecting Deseret alphabet upper-case Ow"); - assert.areEqual("\uD801\uDC0E", "\uD801\uDC36".toUpperCase(), "Expecting Deseret alphabet upper-case Wu"); - assert.areEqual("\uD801\uDC0F", "\uD801\uDC37".toUpperCase(), "Expecting Deseret alphabet upper-case Yee"); - assert.areEqual("\uD801\uDC10", "\uD801\uDC38".toUpperCase(), "Expecting Deseret alphabet upper-case H"); - assert.areEqual("\uD801\uDC11", "\uD801\uDC39".toUpperCase(), "Expecting Deseret alphabet upper-case Pee"); - assert.areEqual("\uD801\uDC12", "\uD801\uDC3A".toUpperCase(), "Expecting Deseret alphabet upper-case Bee"); - assert.areEqual("\uD801\uDC13", "\uD801\uDC3B".toUpperCase(), "Expecting Deseret alphabet upper-case Tee"); - assert.areEqual("\uD801\uDC14", "\uD801\uDC3C".toUpperCase(), "Expecting Deseret alphabet upper-case Dee"); - assert.areEqual("\uD801\uDC15", "\uD801\uDC3D".toUpperCase(), "Expecting Deseret alphabet upper-case Chee"); - assert.areEqual("\uD801\uDC16", "\uD801\uDC3E".toUpperCase(), "Expecting Deseret alphabet upper-case Jee"); - assert.areEqual("\uD801\uDC17", "\uD801\uDC3F".toUpperCase(), "Expecting Deseret alphabet upper-case Kay"); - assert.areEqual("\uD801\uDC18", "\uD801\uDC40".toUpperCase(), "Expecting Deseret alphabet upper-case Gay"); - assert.areEqual("\uD801\uDC19", "\uD801\uDC41".toUpperCase(), "Expecting Deseret alphabet upper-case Ef"); - assert.areEqual("\uD801\uDC1A", "\uD801\uDC42".toUpperCase(), "Expecting Deseret alphabet upper-case Vee"); - assert.areEqual("\uD801\uDC1B", "\uD801\uDC43".toUpperCase(), "Expecting Deseret alphabet upper-case Eth"); - assert.areEqual("\uD801\uDC1C", "\uD801\uDC44".toUpperCase(), "Expecting Deseret alphabet upper-case Thee"); - assert.areEqual("\uD801\uDC1D", "\uD801\uDC45".toUpperCase(), "Expecting Deseret alphabet upper-case Es"); - assert.areEqual("\uD801\uDC1E", "\uD801\uDC46".toUpperCase(), "Expecting Deseret alphabet upper-case Zee"); - assert.areEqual("\uD801\uDC1F", "\uD801\uDC47".toUpperCase(), "Expecting Deseret alphabet upper-case Esh"); - assert.areEqual("\uD801\uDC20", "\uD801\uDC48".toUpperCase(), "Expecting Deseret alphabet upper-case Zhee"); - assert.areEqual("\uD801\uDC21", "\uD801\uDC49".toUpperCase(), "Expecting Deseret alphabet upper-case Er"); - assert.areEqual("\uD801\uDC22", "\uD801\uDC4A".toUpperCase(), "Expecting Deseret alphabet upper-case El"); - assert.areEqual("\uD801\uDC23", "\uD801\uDC4B".toUpperCase(), "Expecting Deseret alphabet upper-case Em"); - assert.areEqual("\uD801\uDC24", "\uD801\uDC4C".toUpperCase(), "Expecting Deseret alphabet upper-case En"); - assert.areEqual("\uD801\uDC25", "\uD801\uDC4D".toUpperCase(), "Expecting Deseret alphabet upper-case Eng"); - assert.areEqual("\uD801\uDC26", "\uD801\uDC4E".toUpperCase(), "Expecting Deseret alphabet upper-case Oi"); - assert.areEqual("\uD801\uDC27", "\uD801\uDC4F".toUpperCase(), "Expecting Deseret alphabet upper-case Ew"); - } - }, - { - name: "Deseret alphabet toLowerCase", - body: function () { - assert.areEqual("\uD801\uDC28", "\uD801\uDC00".toLowerCase(), "Expecting Deseret alphabet lower-case long I"); - assert.areEqual("\uD801\uDC29", "\uD801\uDC01".toLowerCase(), "Expecting Deseret alphabet lower-case long E"); - assert.areEqual("\uD801\uDC2A", "\uD801\uDC02".toLowerCase(), "Expecting Deseret alphabet lower-case long A"); - assert.areEqual("\uD801\uDC2B", "\uD801\uDC03".toLowerCase(), "Expecting Deseret alphabet lower-case long Ah"); - assert.areEqual("\uD801\uDC2C", "\uD801\uDC04".toLowerCase(), "Expecting Deseret alphabet lower-case long O"); - assert.areEqual("\uD801\uDC2D", "\uD801\uDC05".toLowerCase(), "Expecting Deseret alphabet lower-case long Oo"); - assert.areEqual("\uD801\uDC2E", "\uD801\uDC06".toLowerCase(), "Expecting Deseret alphabet lower-case short I"); - assert.areEqual("\uD801\uDC2F", "\uD801\uDC07".toLowerCase(), "Expecting Deseret alphabet lower-case short E"); - assert.areEqual("\uD801\uDC30", "\uD801\uDC08".toLowerCase(), "Expecting Deseret alphabet lower-case short A"); - assert.areEqual("\uD801\uDC31", "\uD801\uDC09".toLowerCase(), "Expecting Deseret alphabet lower-case short Ah"); - assert.areEqual("\uD801\uDC32", "\uD801\uDC0A".toLowerCase(), "Expecting Deseret alphabet lower-case short O"); - assert.areEqual("\uD801\uDC33", "\uD801\uDC0B".toLowerCase(), "Expecting Deseret alphabet lower-case short Oo"); - assert.areEqual("\uD801\uDC34", "\uD801\uDC0C".toLowerCase(), "Expecting Deseret alphabet lower-case Ay"); - assert.areEqual("\uD801\uDC35", "\uD801\uDC0D".toLowerCase(), "Expecting Deseret alphabet lower-case Ow"); - assert.areEqual("\uD801\uDC36", "\uD801\uDC0E".toLowerCase(), "Expecting Deseret alphabet lower-case Wu"); - assert.areEqual("\uD801\uDC37", "\uD801\uDC0F".toLowerCase(), "Expecting Deseret alphabet lower-case Yee"); - assert.areEqual("\uD801\uDC38", "\uD801\uDC10".toLowerCase(), "Expecting Deseret alphabet lower-case H"); - assert.areEqual("\uD801\uDC39", "\uD801\uDC11".toLowerCase(), "Expecting Deseret alphabet lower-case Pee"); - assert.areEqual("\uD801\uDC3A", "\uD801\uDC12".toLowerCase(), "Expecting Deseret alphabet lower-case Bee"); - assert.areEqual("\uD801\uDC3B", "\uD801\uDC13".toLowerCase(), "Expecting Deseret alphabet lower-case Tee"); - assert.areEqual("\uD801\uDC3C", "\uD801\uDC14".toLowerCase(), "Expecting Deseret alphabet lower-case Dee"); - assert.areEqual("\uD801\uDC3D", "\uD801\uDC15".toLowerCase(), "Expecting Deseret alphabet lower-case Chee"); - assert.areEqual("\uD801\uDC3E", "\uD801\uDC16".toLowerCase(), "Expecting Deseret alphabet lower-case Jee"); - assert.areEqual("\uD801\uDC3F", "\uD801\uDC17".toLowerCase(), "Expecting Deseret alphabet lower-case Kay"); - assert.areEqual("\uD801\uDC40", "\uD801\uDC18".toLowerCase(), "Expecting Deseret alphabet lower-case Gay"); - assert.areEqual("\uD801\uDC41", "\uD801\uDC19".toLowerCase(), "Expecting Deseret alphabet lower-case Ef"); - assert.areEqual("\uD801\uDC42", "\uD801\uDC1A".toLowerCase(), "Expecting Deseret alphabet lower-case Vee"); - assert.areEqual("\uD801\uDC43", "\uD801\uDC1B".toLowerCase(), "Expecting Deseret alphabet lower-case Eth"); - assert.areEqual("\uD801\uDC44", "\uD801\uDC1C".toLowerCase(), "Expecting Deseret alphabet lower-case Thee"); - assert.areEqual("\uD801\uDC45", "\uD801\uDC1D".toLowerCase(), "Expecting Deseret alphabet lower-case Es"); - assert.areEqual("\uD801\uDC46", "\uD801\uDC1E".toLowerCase(), "Expecting Deseret alphabet lower-case Zee"); - assert.areEqual("\uD801\uDC47", "\uD801\uDC1F".toLowerCase(), "Expecting Deseret alphabet lower-case Esh"); - assert.areEqual("\uD801\uDC48", "\uD801\uDC20".toLowerCase(), "Expecting Deseret alphabet lower-case Zhee"); - assert.areEqual("\uD801\uDC49", "\uD801\uDC21".toLowerCase(), "Expecting Deseret alphabet lower-case Er"); - assert.areEqual("\uD801\uDC4A", "\uD801\uDC22".toLowerCase(), "Expecting Deseret alphabet lower-case El"); - assert.areEqual("\uD801\uDC4B", "\uD801\uDC23".toLowerCase(), "Expecting Deseret alphabet lower-case Em"); - assert.areEqual("\uD801\uDC4C", "\uD801\uDC24".toLowerCase(), "Expecting Deseret alphabet lower-case En"); - assert.areEqual("\uD801\uDC4D", "\uD801\uDC25".toLowerCase(), "Expecting Deseret alphabet lower-case Eng"); - assert.areEqual("\uD801\uDC4E", "\uD801\uDC26".toLowerCase(), "Expecting Deseret alphabet lower-case Oi"); - assert.areEqual("\uD801\uDC4F", "\uD801\uDC27".toLowerCase(), "Expecting Deseret alphabet lower-case Ew"); - } - }, - { - name: "Special casing toUpperCase", - body: function () { - //assert.areEqual("\u0053\u0053", "\u00DF".toUpperCase(), "Expecting Latin lower-case sharp s"); // not yet implemented - assert.areEqual("\u0130", "\u0130".toUpperCase(), "Expecting Latin upper-case i with dot above"); - //assert.areEqual("\u0046\u0046", "\uFB00".toUpperCase(), "Expecting Latin small ligature ff"); // not yet implemented - //assert.areEqual("\u0046\u0049", "\uFB01".toUpperCase(), "Expecting Latin small ligature fi"); // not yet implemented - //assert.areEqual("\u0046\u004C", "\uFB02".toUpperCase(), "Expecting Latin small ligature fl"); // not yet implemented - //assert.areEqual("\u0046\u0046\u0049", "\uFB03".toUpperCase(), "Expecting Latin small ligature ffi"); // not yet implemented - //assert.areEqual("\u0046\u0046\u004C", "\uFB04".toUpperCase(), "Expecting Latin small ligature ffl"); // not yet implemented - //assert.areEqual("\u0053\u0054", "\uFB05".toUpperCase(), "Expecting Latin small ligature long s t"); // not yet implemented - //assert.areEqual("\u0053\u0054", "\uFB06".toUpperCase(), "Expecting Latin small ligature st"); // not yet implemented - //assert.areEqual("\u0535\u0552", "\u0587".toUpperCase(), "Expecting Armenian small ligature ech yiwn"); // not yet implemented - //assert.areEqual("\u0544\u0546", "\uFB13".toUpperCase(), "Expecting Armenian small ligature men now"); // not yet implemented - //assert.areEqual("\u0544\u0535", "\uFB14".toUpperCase(), "Expecting Armenian small ligature men ech"); // not yet implemented - //assert.areEqual("\u0544\u053B", "\uFB15".toUpperCase(), "Expecting Armenian small ligature men ini"); // not yet implemented - //assert.areEqual("\u054E\u0546", "\uFB16".toUpperCase(), "Expecting Armenian small ligature vew now"); // not yet implemented - //assert.areEqual("\u0544\u053D", "\uFB17".toUpperCase(), "Expecting Armenian small ligature men xeh"); // not yet implemented - //assert.areEqual("\u02BC\u004E", "\u0149".toUpperCase(), "Expecting Latin lower-case n preceded by apostrophe"); // not yet implemented - //assert.areEqual("\u0399\u0308\u0301", "\u0390".toUpperCase(), "Expecting Greek lower-case iota with dialytika and tonos"); // not yet implemented - //assert.areEqual("\u03A5\u0308\u0301", "\u03B0".toUpperCase(), "Expecting Greek lower-case upsilon with dialytika and tonos"); // not yet implemented - //assert.areEqual("\u004A\u030C", "\u01F0".toUpperCase(), "Expecting Latin lower-case j with caron"); // not yet implemented - //assert.areEqual("\u0048\u0331", "\u1E96".toUpperCase(), "Expecting Latin lower-case h with line below"); // not yet implemented - //assert.areEqual("\u0054\u0308", "\u1E97".toUpperCase(), "Expecting Latin lower-case t with diaeresis"); // not yet implemented - //assert.areEqual("\u0057\u030A", "\u1E98".toUpperCase(), "Expecting Latin lower-case w with ring above"); // not yet implemented - //assert.areEqual("\u0059\u030A", "\u1E99".toUpperCase(), "Expecting Latin lower-case y with ring above"); // not yet implemented - //assert.areEqual("\u0041\u02BE", "\u1E9A".toUpperCase(), "Expecting Latin lower-case a with right half ring"); // not yet implemented - //assert.areEqual("\u03A5\u0313", "\u1F50".toUpperCase(), "Expecting Greek lower-case upsilon with psili"); // not yet implemented - //assert.areEqual("\u03A5\u0313\u0300", "\u1F52".toUpperCase(), "Expecting Greek lower-case upsilon with psili and varia"); // not yet implemented - //assert.areEqual("\u03A5\u0313\u0301", "\u1F54".toUpperCase(), "Expecting Greek lower-case upsilon with psili and oxia"); // not yet implemented - //assert.areEqual("\u03A5\u0313\u0342", "\u1F56".toUpperCase(), "Expecting Greek lower-case upsilon with psili and perispomeni"); // not yet implemented - //assert.areEqual("\u0391\u0342", "\u1FB6".toUpperCase(), "Expecting Greek lower-case alpha with perispomeni"); // not yet implemented - //assert.areEqual("\u0397\u0342", "\u1FC6".toUpperCase(), "Expecting Greek lower-case eta with perispomeni"); // not yet implemented - //assert.areEqual("\u0399\u0308\u0300", "\u1FD2".toUpperCase(), "Expecting Greek lower-case iota with dialytika and varia"); // not yet implemented - //assert.areEqual("\u0399\u0308\u0301", "\u1FD3".toUpperCase(), "Expecting Greek lower-case iota with dialytika and oxia"); // not yet implemented - //assert.areEqual("\u0399\u0342", "\u1FD6".toUpperCase(), "Expecting Greek lower-case iota with perispomeni"); // not yet implemented - //assert.areEqual("\u0399\u0308\u0342", "\u1FD7".toUpperCase(), "Expecting Greek lower-case iota with dialytika and perispomeni"); // not yet implemented - //assert.areEqual("\u03A5\u0308\u0300", "\u1FE2".toUpperCase(), "Expecting Greek lower-case upsilon with dialytika and varia"); // not yet implemented - //assert.areEqual("\u03A5\u0308\u0301", "\u1FE3".toUpperCase(), "Expecting Greek lower-case upsilon with dialytika and oxia"); // not yet implemented - //assert.areEqual("\u03A1\u0313", "\u1FE4".toUpperCase(), "Expecting Greek lower-case rho with psili"); // not yet implemented - //assert.areEqual("\u03A5\u0342", "\u1FE6".toUpperCase(), "Expecting Greek lower-case upsilon with perispomeni"); // not yet implemented - //assert.areEqual("\u03A5\u0308\u0342", "\u1FE7".toUpperCase(), "Expecting Greek lower-case upsilon with dialytika and perispomeni"); // not yet implemented - //assert.areEqual("\u03A9\u0342", "\u1FF6".toUpperCase(), "Expecting Greek lower-case omega with perispomeni"); // not yet implemented - //assert.areEqual("\u1F08\u0399", "\u1F80".toUpperCase(), "Expecting Greek lower-case alpha with psili and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F09\u0399", "\u1F81".toUpperCase(), "Expecting Greek lower-case alpha with dasia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F0A\u0399", "\u1F82".toUpperCase(), "Expecting Greek lower-case alpha with psili and varia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F0B\u0399", "\u1F83".toUpperCase(), "Expecting Greek lower-case alpha with dasia and varia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F0C\u0399", "\u1F84".toUpperCase(), "Expecting Greek lower-case alpha with psili and oxia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F0D\u0399", "\u1F85".toUpperCase(), "Expecting Greek lower-case alpha with dasia and oxia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F0E\u0399", "\u1F86".toUpperCase(), "Expecting Greek lower-case alpha with psili and perispomeni and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F0F\u0399", "\u1F87".toUpperCase(), "Expecting Greek lower-case alpha with dasia and perispomeni and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F08\u0399", "\u1F88".toUpperCase(), "Expecting Greek upper-case alpha with psili and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F09\u0399", "\u1F89".toUpperCase(), "Expecting Greek upper-case alpha with dasia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F0A\u0399", "\u1F8A".toUpperCase(), "Expecting Greek upper-case alpha with psili and varia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F0B\u0399", "\u1F8B".toUpperCase(), "Expecting Greek upper-case alpha with dasia and varia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F0C\u0399", "\u1F8C".toUpperCase(), "Expecting Greek upper-case alpha with psili and oxia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F0D\u0399", "\u1F8D".toUpperCase(), "Expecting Greek upper-case alpha with dasia and oxia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F0E\u0399", "\u1F8E".toUpperCase(), "Expecting Greek upper-case alpha with psili and perispomeni and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F0F\u0399", "\u1F8F".toUpperCase(), "Expecting Greek upper-case alpha with dasia and perispomeni and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F28\u0399", "\u1F90".toUpperCase(), "Expecting Greek lower-case eta with psili and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F29\u0399", "\u1F91".toUpperCase(), "Expecting Greek lower-case eta with dasia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F2A\u0399", "\u1F92".toUpperCase(), "Expecting Greek lower-case eta with psili and varia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F2B\u0399", "\u1F93".toUpperCase(), "Expecting Greek lower-case eta with dasia and varia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F2C\u0399", "\u1F94".toUpperCase(), "Expecting Greek lower-case eta with psili and oxia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F2D\u0399", "\u1F95".toUpperCase(), "Expecting Greek lower-case eta with dasia and oxia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F2E\u0399", "\u1F96".toUpperCase(), "Expecting Greek lower-case eta with psili and perispomeni and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F2F\u0399", "\u1F97".toUpperCase(), "Expecting Greek lower-case eta with dasia and perispomeni and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F28\u0399", "\u1F98".toUpperCase(), "Expecting Greek upper-case eta with psili and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F29\u0399", "\u1F99".toUpperCase(), "Expecting Greek upper-case eta with dasia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F2A\u0399", "\u1F9A".toUpperCase(), "Expecting Greek upper-case eta with psili and varia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F2B\u0399", "\u1F9B".toUpperCase(), "Expecting Greek upper-case eta with dasia and varia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F2C\u0399", "\u1F9C".toUpperCase(), "Expecting Greek upper-case eta with psili and oxia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F2D\u0399", "\u1F9D".toUpperCase(), "Expecting Greek upper-case eta with dasia and oxia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F2E\u0399", "\u1F9E".toUpperCase(), "Expecting Greek upper-case eta with psili and perispomeni and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F2F\u0399", "\u1F9F".toUpperCase(), "Expecting Greek upper-case eta with dasia and perispomeni and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F68\u0399", "\u1FA0".toUpperCase(), "Expecting Greek lower-case omega with psili and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F69\u0399", "\u1FA1".toUpperCase(), "Expecting Greek lower-case omega with dasia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F6A\u0399", "\u1FA2".toUpperCase(), "Expecting Greek lower-case omega with psili and varia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F6B\u0399", "\u1FA3".toUpperCase(), "Expecting Greek lower-case omega with dasia and varia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F6C\u0399", "\u1FA4".toUpperCase(), "Expecting Greek lower-case omega with psili and oxia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F6D\u0399", "\u1FA5".toUpperCase(), "Expecting Greek lower-case omega with dasia and oxia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F6E\u0399", "\u1FA6".toUpperCase(), "Expecting Greek lower-case omega with psili and perispomeni and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F6F\u0399", "\u1FA7".toUpperCase(), "Expecting Greek lower-case omega with dasia and perispomeni and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1F68\u0399", "\u1FA8".toUpperCase(), "Expecting Greek upper-case omega with psili and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F69\u0399", "\u1FA9".toUpperCase(), "Expecting Greek upper-case omega with dasia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F6A\u0399", "\u1FAA".toUpperCase(), "Expecting Greek upper-case omega with psili and varia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F6B\u0399", "\u1FAB".toUpperCase(), "Expecting Greek upper-case omega with dasia and varia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F6C\u0399", "\u1FAC".toUpperCase(), "Expecting Greek upper-case omega with psili and oxia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F6D\u0399", "\u1FAD".toUpperCase(), "Expecting Greek upper-case omega with dasia and oxia and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F6E\u0399", "\u1FAE".toUpperCase(), "Expecting Greek upper-case omega with psili and perispomeni and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1F6F\u0399", "\u1FAF".toUpperCase(), "Expecting Greek upper-case omega with dasia and perispomeni and prosgegrammeni"); // not yet implemented - //assert.areEqual("\u0391\u0399", "\u1FB3".toUpperCase(), "Expecting Greek lower-case alpha with ypogegrammeni"); // not yet implemented - //assert.areEqual("\u0391\u0399", "\u1FBC".toUpperCase(), "Expecting Greek upper-case alpha with prosgegrammeni"); // not yet implemented - //assert.areEqual("\u0397\u0399", "\u1FC3".toUpperCase(), "Expecting Greek lower-case eta with ypogegrammeni"); // not yet implemented - //assert.areEqual("\u0397\u0399", "\u1FCC".toUpperCase(), "Expecting Greek upper-case eta with prosgegrammeni"); // not yet implemented - //assert.areEqual("\u03A9\u0399", "\u1FF3".toUpperCase(), "Expecting Greek lower-case omega with ypogegrammeni"); // not yet implemented - //assert.areEqual("\u03A9\u0399", "\u1FFC".toUpperCase(), "Expecting Greek upper-case omega with prosgegrammeni"); // not yet implemented - //assert.areEqual("\u1FBA\u0399", "\u1FB2".toUpperCase(), "Expecting Greek lower-case alpha with varia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u0386\u0399", "\u1FB4".toUpperCase(), "Expecting Greek lower-case alpha with oxia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1FCA\u0399", "\u1FC2".toUpperCase(), "Expecting Greek lower-case eta with varia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u0389\u0399", "\u1FC4".toUpperCase(), "Expecting Greek lower-case eta with oxia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u1FFA\u0399", "\u1FF2".toUpperCase(), "Expecting Greek lower-case omega with varia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u038F\u0399", "\u1FF4".toUpperCase(), "Expecting Greek lower-case omega with oxia and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u0391\u0342\u0399", "\u1FB7".toUpperCase(), "Expecting Greek lower-case alpha with perispomeni and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u0397\u0342\u0399", "\u1FC7".toUpperCase(), "Expecting Greek lower-case eta with perispomeni and ypogegrammeni"); // not yet implemented - //assert.areEqual("\u03A9\u0342\u0399", "\u1FF7".toUpperCase(), "Expecting Greek lower-case omega with perispomeni and ypogegrammeni"); // not yet implemented - } - }, - { - name: "Special casing toLowerCase", - body: function () { - assert.areEqual("\u00DF", "\u00DF".toLowerCase(), "Expecting Latin lower-case sharp s"); - //assert.areEqual("\u0069\u0307", "\u0130".toLowerCase(), "Expecting Latin upper-case i with dot above"); // not yet implemented - assert.areEqual("\uFB00", "\uFB00".toLowerCase(), "Expecting Latin small ligature ff"); - assert.areEqual("\uFB01", "\uFB01".toLowerCase(), "Expecting Latin small ligature fi"); - assert.areEqual("\uFB02", "\uFB02".toLowerCase(), "Expecting Latin small ligature fl"); - assert.areEqual("\uFB03", "\uFB03".toLowerCase(), "Expecting Latin small ligature ffi"); - assert.areEqual("\uFB04", "\uFB04".toLowerCase(), "Expecting Latin small ligature ffl"); - assert.areEqual("\uFB05", "\uFB05".toLowerCase(), "Expecting Latin small ligature long s t"); - assert.areEqual("\uFB06", "\uFB06".toLowerCase(), "Expecting Latin small ligature st"); - assert.areEqual("\u0587", "\u0587".toLowerCase(), "Expecting Armenian small ligature ech yiwn"); - assert.areEqual("\uFB13", "\uFB13".toLowerCase(), "Expecting Armenian small ligature men now"); - assert.areEqual("\uFB14", "\uFB14".toLowerCase(), "Expecting Armenian small ligature men ech"); - assert.areEqual("\uFB15", "\uFB15".toLowerCase(), "Expecting Armenian small ligature men ini"); - assert.areEqual("\uFB16", "\uFB16".toLowerCase(), "Expecting Armenian small ligature vew now"); - assert.areEqual("\uFB17", "\uFB17".toLowerCase(), "Expecting Armenian small ligature men xeh"); - assert.areEqual("\u0149", "\u0149".toLowerCase(), "Expecting Latin lower-case n preceded by apostrophe"); - assert.areEqual("\u0390", "\u0390".toLowerCase(), "Expecting Greek lower-case iota with dialytika and tonos"); - assert.areEqual("\u03B0", "\u03B0".toLowerCase(), "Expecting Greek lower-case upsilon with dialytika and tonos"); - assert.areEqual("\u01F0", "\u01F0".toLowerCase(), "Expecting Latin lower-case j with caron"); - assert.areEqual("\u1E96", "\u1E96".toLowerCase(), "Expecting Latin lower-case h with line below"); - assert.areEqual("\u1E97", "\u1E97".toLowerCase(), "Expecting Latin lower-case t with diaeresis"); - assert.areEqual("\u1E98", "\u1E98".toLowerCase(), "Expecting Latin lower-case w with ring above"); - assert.areEqual("\u1E99", "\u1E99".toLowerCase(), "Expecting Latin lower-case y with ring above"); - assert.areEqual("\u1E9A", "\u1E9A".toLowerCase(), "Expecting Latin lower-case a with right half ring"); - assert.areEqual("\u1F50", "\u1F50".toLowerCase(), "Expecting Greek lower-case upsilon with psili"); - assert.areEqual("\u1F52", "\u1F52".toLowerCase(), "Expecting Greek lower-case upsilon with psili and varia"); - assert.areEqual("\u1F54", "\u1F54".toLowerCase(), "Expecting Greek lower-case upsilon with psili and oxia"); - assert.areEqual("\u1F56", "\u1F56".toLowerCase(), "Expecting Greek lower-case upsilon with psili and perispomeni"); - assert.areEqual("\u1FB6", "\u1FB6".toLowerCase(), "Expecting Greek lower-case alpha with perispomeni"); - assert.areEqual("\u1FC6", "\u1FC6".toLowerCase(), "Expecting Greek lower-case eta with perispomeni"); - assert.areEqual("\u1FD2", "\u1FD2".toLowerCase(), "Expecting Greek lower-case iota with dialytika and varia"); - assert.areEqual("\u1FD3", "\u1FD3".toLowerCase(), "Expecting Greek lower-case iota with dialytika and oxia"); - assert.areEqual("\u1FD6", "\u1FD6".toLowerCase(), "Expecting Greek lower-case iota with perispomeni"); - assert.areEqual("\u1FD7", "\u1FD7".toLowerCase(), "Expecting Greek lower-case iota with dialytika and perispomeni"); - assert.areEqual("\u1FE2", "\u1FE2".toLowerCase(), "Expecting Greek lower-case upsilon with dialytika and varia"); - assert.areEqual("\u1FE3", "\u1FE3".toLowerCase(), "Expecting Greek lower-case upsilon with dialytika and oxia"); - assert.areEqual("\u1FE4", "\u1FE4".toLowerCase(), "Expecting Greek lower-case rho with psili"); - assert.areEqual("\u1FE6", "\u1FE6".toLowerCase(), "Expecting Greek lower-case upsilon with perispomeni"); - assert.areEqual("\u1FE7", "\u1FE7".toLowerCase(), "Expecting Greek lower-case upsilon with dialytika and perispomeni"); - assert.areEqual("\u1FF6", "\u1FF6".toLowerCase(), "Expecting Greek lower-case omega with perispomeni"); - assert.areEqual("\u1F80", "\u1F80".toLowerCase(), "Expecting Greek lower-case alpha with psili and ypogegrammeni"); - assert.areEqual("\u1F81", "\u1F81".toLowerCase(), "Expecting Greek lower-case alpha with dasia and ypogegrammeni"); - assert.areEqual("\u1F82", "\u1F82".toLowerCase(), "Expecting Greek lower-case alpha with psili and varia and ypogegrammeni"); - assert.areEqual("\u1F83", "\u1F83".toLowerCase(), "Expecting Greek lower-case alpha with dasia and varia and ypogegrammeni"); - assert.areEqual("\u1F84", "\u1F84".toLowerCase(), "Expecting Greek lower-case alpha with psili and oxia and ypogegrammeni"); - assert.areEqual("\u1F85", "\u1F85".toLowerCase(), "Expecting Greek lower-case alpha with dasia and oxia and ypogegrammeni"); - assert.areEqual("\u1F86", "\u1F86".toLowerCase(), "Expecting Greek lower-case alpha with psili and perispomeni and ypogegrammeni"); - assert.areEqual("\u1F87", "\u1F87".toLowerCase(), "Expecting Greek lower-case alpha with dasia and perispomeni and ypogegrammeni"); - assert.areEqual("\u1F80", "\u1F88".toLowerCase(), "Expecting Greek upper-case alpha with psili and prosgegrammeni"); - assert.areEqual("\u1F81", "\u1F89".toLowerCase(), "Expecting Greek upper-case alpha with dasia and prosgegrammeni"); - assert.areEqual("\u1F82", "\u1F8A".toLowerCase(), "Expecting Greek upper-case alpha with psili and varia and prosgegrammeni"); - assert.areEqual("\u1F83", "\u1F8B".toLowerCase(), "Expecting Greek upper-case alpha with dasia and varia and prosgegrammeni"); - assert.areEqual("\u1F84", "\u1F8C".toLowerCase(), "Expecting Greek upper-case alpha with psili and oxia and prosgegrammeni"); - assert.areEqual("\u1F85", "\u1F8D".toLowerCase(), "Expecting Greek upper-case alpha with dasia and oxia and prosgegrammeni"); - assert.areEqual("\u1F86", "\u1F8E".toLowerCase(), "Expecting Greek upper-case alpha with psili and perispomeni and prosgegrammeni"); - assert.areEqual("\u1F87", "\u1F8F".toLowerCase(), "Expecting Greek upper-case alpha with dasia and perispomeni and prosgegrammeni"); - assert.areEqual("\u1F90", "\u1F90".toLowerCase(), "Expecting Greek lower-case eta with psili and ypogegrammeni"); - assert.areEqual("\u1F91", "\u1F91".toLowerCase(), "Expecting Greek lower-case eta with dasia and ypogegrammeni"); - assert.areEqual("\u1F92", "\u1F92".toLowerCase(), "Expecting Greek lower-case eta with psili and varia and ypogegrammeni"); - assert.areEqual("\u1F93", "\u1F93".toLowerCase(), "Expecting Greek lower-case eta with dasia and varia and ypogegrammeni"); - assert.areEqual("\u1F94", "\u1F94".toLowerCase(), "Expecting Greek lower-case eta with psili and oxia and ypogegrammeni"); - assert.areEqual("\u1F95", "\u1F95".toLowerCase(), "Expecting Greek lower-case eta with dasia and oxia and ypogegrammeni"); - assert.areEqual("\u1F96", "\u1F96".toLowerCase(), "Expecting Greek lower-case eta with psili and perispomeni and ypogegrammeni"); - assert.areEqual("\u1F97", "\u1F97".toLowerCase(), "Expecting Greek lower-case eta with dasia and perispomeni and ypogegrammeni"); - assert.areEqual("\u1F90", "\u1F98".toLowerCase(), "Expecting Greek upper-case eta with psili and prosgegrammeni"); - assert.areEqual("\u1F91", "\u1F99".toLowerCase(), "Expecting Greek upper-case eta with dasia and prosgegrammeni"); - assert.areEqual("\u1F92", "\u1F9A".toLowerCase(), "Expecting Greek upper-case eta with psili and varia and prosgegrammeni"); - assert.areEqual("\u1F93", "\u1F9B".toLowerCase(), "Expecting Greek upper-case eta with dasia and varia and prosgegrammeni"); - assert.areEqual("\u1F94", "\u1F9C".toLowerCase(), "Expecting Greek upper-case eta with psili and oxia and prosgegrammeni"); - assert.areEqual("\u1F95", "\u1F9D".toLowerCase(), "Expecting Greek upper-case eta with dasia and oxia and prosgegrammeni"); - assert.areEqual("\u1F96", "\u1F9E".toLowerCase(), "Expecting Greek upper-case eta with psili and perispomeni and prosgegrammeni"); - assert.areEqual("\u1F97", "\u1F9F".toLowerCase(), "Expecting Greek upper-case eta with dasia and perispomeni and prosgegrammeni"); - assert.areEqual("\u1FA0", "\u1FA0".toLowerCase(), "Expecting Greek lower-case omega with psili and ypogegrammeni"); - assert.areEqual("\u1FA1", "\u1FA1".toLowerCase(), "Expecting Greek lower-case omega with dasia and ypogegrammeni"); - assert.areEqual("\u1FA2", "\u1FA2".toLowerCase(), "Expecting Greek lower-case omega with psili and varia and ypogegrammeni"); - assert.areEqual("\u1FA3", "\u1FA3".toLowerCase(), "Expecting Greek lower-case omega with dasia and varia and ypogegrammeni"); - assert.areEqual("\u1FA4", "\u1FA4".toLowerCase(), "Expecting Greek lower-case omega with psili and oxia and ypogegrammeni"); - assert.areEqual("\u1FA5", "\u1FA5".toLowerCase(), "Expecting Greek lower-case omega with dasia and oxia and ypogegrammeni"); - assert.areEqual("\u1FA6", "\u1FA6".toLowerCase(), "Expecting Greek lower-case omega with psili and perispomeni and ypogegrammeni"); - assert.areEqual("\u1FA7", "\u1FA7".toLowerCase(), "Expecting Greek lower-case omega with dasia and perispomeni and ypogegrammeni"); - assert.areEqual("\u1FA0", "\u1FA8".toLowerCase(), "Expecting Greek upper-case omega with psili and prosgegrammeni"); - assert.areEqual("\u1FA1", "\u1FA9".toLowerCase(), "Expecting Greek upper-case omega with dasia and prosgegrammeni"); - assert.areEqual("\u1FA2", "\u1FAA".toLowerCase(), "Expecting Greek upper-case omega with psili and varia and prosgegrammeni"); - assert.areEqual("\u1FA3", "\u1FAB".toLowerCase(), "Expecting Greek upper-case omega with dasia and varia and prosgegrammeni"); - assert.areEqual("\u1FA4", "\u1FAC".toLowerCase(), "Expecting Greek upper-case omega with psili and oxia and prosgegrammeni"); - assert.areEqual("\u1FA5", "\u1FAD".toLowerCase(), "Expecting Greek upper-case omega with dasia and oxia and prosgegrammeni"); - assert.areEqual("\u1FA6", "\u1FAE".toLowerCase(), "Expecting Greek upper-case omega with psili and perispomeni and prosgegrammeni"); - assert.areEqual("\u1FA7", "\u1FAF".toLowerCase(), "Expecting Greek upper-case omega with dasia and perispomeni and prosgegrammeni"); - assert.areEqual("\u1FB3", "\u1FB3".toLowerCase(), "Expecting Greek lower-case alpha with ypogegrammeni"); - assert.areEqual("\u1FB3", "\u1FBC".toLowerCase(), "Expecting Greek upper-case alpha with prosgegrammeni"); - assert.areEqual("\u1FC3", "\u1FC3".toLowerCase(), "Expecting Greek lower-case eta with ypogegrammeni"); - assert.areEqual("\u1FC3", "\u1FCC".toLowerCase(), "Expecting Greek upper-case eta with prosgegrammeni"); - assert.areEqual("\u1FF3", "\u1FF3".toLowerCase(), "Expecting Greek lower-case omega with ypogegrammeni"); - assert.areEqual("\u1FF3", "\u1FFC".toLowerCase(), "Expecting Greek upper-case omega with prosgegrammeni"); - assert.areEqual("\u1FB2", "\u1FB2".toLowerCase(), "Expecting Greek lower-case alpha with varia and ypogegrammeni"); - assert.areEqual("\u1FB4", "\u1FB4".toLowerCase(), "Expecting Greek lower-case alpha with oxia and ypogegrammeni"); - assert.areEqual("\u1FC2", "\u1FC2".toLowerCase(), "Expecting Greek lower-case eta with varia and ypogegrammeni"); - assert.areEqual("\u1FC4", "\u1FC4".toLowerCase(), "Expecting Greek lower-case eta with oxia and ypogegrammeni"); - assert.areEqual("\u1FF2", "\u1FF2".toLowerCase(), "Expecting Greek lower-case omega with varia and ypogegrammeni"); - assert.areEqual("\u1FF4", "\u1FF4".toLowerCase(), "Expecting Greek lower-case omega with oxia and ypogegrammeni"); - assert.areEqual("\u1FB7", "\u1FB7".toLowerCase(), "Expecting Greek lower-case alpha with perispomeni and ypogegrammeni"); - assert.areEqual("\u1FC7", "\u1FC7".toLowerCase(), "Expecting Greek lower-case eta with perispomeni and ypogegrammeni"); - assert.areEqual("\u1FF7", "\u1FF7".toLowerCase(), "Expecting Greek lower-case omega with perispomeni and ypogegrammeni"); - assert.areEqual("\u03C3", "\u03A3".toLowerCase(), "Expecting single Greek upper-case sigma"); - //assert.areEqual("a\u03C2", "A\u03A3".toLowerCase(), "Expecting sigma preceded by Latin upper-case a"); // not yet implemented - //assert.areEqual("\uD835\uDCA2\u03C2", "\uD835\uDCA2\u03A3".toLowerCase(), "Expecting sigma preceded by mathematical script capital g (d835 dca2 = 1d4a2)"); // not yet implemented - //assert.areEqual("a.\u03C2", "A.\u03A3".toLowerCase(), "Expecting sigma preceded by full stop"); // not yet implemented - //assert.areEqual("a\u00AD\u03C2", "A\u00AD\u03A3".toLowerCase(), "Expecting sigma preceded by soft hyphen (00ad)"); // not yet implemented - //assert.areEqual("a\uD834\uDE42\u03C2", "A\uD834\uDE42\u03A3".toLowerCase(), "Expecting sigma preceded by combining Greek musical triseme (d834 de42 = 1d242)"); // not yet implemented - assert.areEqual("\u0345\u03C3", "\u0345\u03A3".toLowerCase(), "Expecting sigma preceded by combining Greek ypogegrammeni (0345)"); - //assert.areEqual("\u03B1\u0345\u03C2", "\u0391\u0345\u03A3".toLowerCase(), "Expecting sigma preceded by Greek upper-case alpha (0391), combining Greek ypogegrammeni (0345)"); // not yet implemented - assert.areEqual("a\u03C3b", "A\u03A3B".toLowerCase(), "Expecting sigma followed by Latin upper-case b"); - assert.areEqual("a\u03C3\uD835\uDCA2", "A\u03A3\uD835\uDCA2".toLowerCase(), "Expecting sigma followed by mathematical script capital g (d835 dca2 = 1d4a2)"); - assert.areEqual("a\u03C3.b", "A\u03A3.b".toLowerCase(), "Expecting sigma followed by full stop"); - assert.areEqual("a\u03C3\u00ADb", "A\u03A3\u00ADB".toLowerCase(), "Expecting sigma followed by soft hyphen (00ad)"); - assert.areEqual("a\u03C3\uD834\uDE42b", "A\u03A3\uD834\uDE42B".toLowerCase(), "Expecting sigma followed by combining Greek musical triseme (d834 de42 = 1d242)"); - //assert.areEqual("a\u03C2\u0345", "A\u03A3\u0345".toLowerCase(), "Expecting sigma followed by combining Greek ypogegrammeni (0345)"); // not yet implemented - assert.areEqual("a\u03C3\u0345\u03B1", "A\u03A3\u0345\u0391".toLowerCase(), "Expecting sigma followed by combining Greek ypogegrammeni (0345), Greek upper-case alpha (0391)"); - } - }, + { + name: "Edge cases", + body() { + assert.areEqual("\uDC37", "\uDC37".toUpperCase(), "Invalid unicode should be passed over (single character, toUpperCase)"); + assert.areEqual("\uDC37", "\uDC37".toLowerCase(), "Invalid unicode should be passed over (single character, toLowerCase)"); + assert.areEqual("ABC\uDC37DEF", "abc\uDC37def".toUpperCase(), "Invalid unicode should be passed over (mid-string, toUpperCase)"); + assert.areEqual("abc\uDC37def", "ABC\uDC37DEF".toLowerCase(), "Invalid unicode should be passed over (mid-string, toLowerCase)"); + } + }, + { + name: "Deseret alphabet toUpperCase", + body: function () { + assert.areEqual("\uD801\uDC00", "\uD801\uDC28".toUpperCase(), "Expecting Deseret alphabet upper-case long I"); + assert.areEqual("\uD801\uDC01", "\uD801\uDC29".toUpperCase(), "Expecting Deseret alphabet upper-case long E"); + assert.areEqual("\uD801\uDC02", "\uD801\uDC2A".toUpperCase(), "Expecting Deseret alphabet upper-case long A"); + assert.areEqual("\uD801\uDC03", "\uD801\uDC2B".toUpperCase(), "Expecting Deseret alphabet upper-case long Ah"); + assert.areEqual("\uD801\uDC04", "\uD801\uDC2C".toUpperCase(), "Expecting Deseret alphabet upper-case long O"); + assert.areEqual("\uD801\uDC05", "\uD801\uDC2D".toUpperCase(), "Expecting Deseret alphabet upper-case long Oo"); + assert.areEqual("\uD801\uDC06", "\uD801\uDC2E".toUpperCase(), "Expecting Deseret alphabet upper-case short I"); + assert.areEqual("\uD801\uDC07", "\uD801\uDC2F".toUpperCase(), "Expecting Deseret alphabet upper-case short E"); + assert.areEqual("\uD801\uDC08", "\uD801\uDC30".toUpperCase(), "Expecting Deseret alphabet upper-case short A"); + assert.areEqual("\uD801\uDC09", "\uD801\uDC31".toUpperCase(), "Expecting Deseret alphabet upper-case short Ah"); + assert.areEqual("\uD801\uDC0A", "\uD801\uDC32".toUpperCase(), "Expecting Deseret alphabet upper-case short O"); + assert.areEqual("\uD801\uDC0B", "\uD801\uDC33".toUpperCase(), "Expecting Deseret alphabet upper-case short Oo"); + assert.areEqual("\uD801\uDC0C", "\uD801\uDC34".toUpperCase(), "Expecting Deseret alphabet upper-case Ay"); + assert.areEqual("\uD801\uDC0D", "\uD801\uDC35".toUpperCase(), "Expecting Deseret alphabet upper-case Ow"); + assert.areEqual("\uD801\uDC0E", "\uD801\uDC36".toUpperCase(), "Expecting Deseret alphabet upper-case Wu"); + assert.areEqual("\uD801\uDC0F", "\uD801\uDC37".toUpperCase(), "Expecting Deseret alphabet upper-case Yee"); + assert.areEqual("\uD801\uDC10", "\uD801\uDC38".toUpperCase(), "Expecting Deseret alphabet upper-case H"); + assert.areEqual("\uD801\uDC11", "\uD801\uDC39".toUpperCase(), "Expecting Deseret alphabet upper-case Pee"); + assert.areEqual("\uD801\uDC12", "\uD801\uDC3A".toUpperCase(), "Expecting Deseret alphabet upper-case Bee"); + assert.areEqual("\uD801\uDC13", "\uD801\uDC3B".toUpperCase(), "Expecting Deseret alphabet upper-case Tee"); + assert.areEqual("\uD801\uDC14", "\uD801\uDC3C".toUpperCase(), "Expecting Deseret alphabet upper-case Dee"); + assert.areEqual("\uD801\uDC15", "\uD801\uDC3D".toUpperCase(), "Expecting Deseret alphabet upper-case Chee"); + assert.areEqual("\uD801\uDC16", "\uD801\uDC3E".toUpperCase(), "Expecting Deseret alphabet upper-case Jee"); + assert.areEqual("\uD801\uDC17", "\uD801\uDC3F".toUpperCase(), "Expecting Deseret alphabet upper-case Kay"); + assert.areEqual("\uD801\uDC18", "\uD801\uDC40".toUpperCase(), "Expecting Deseret alphabet upper-case Gay"); + assert.areEqual("\uD801\uDC19", "\uD801\uDC41".toUpperCase(), "Expecting Deseret alphabet upper-case Ef"); + assert.areEqual("\uD801\uDC1A", "\uD801\uDC42".toUpperCase(), "Expecting Deseret alphabet upper-case Vee"); + assert.areEqual("\uD801\uDC1B", "\uD801\uDC43".toUpperCase(), "Expecting Deseret alphabet upper-case Eth"); + assert.areEqual("\uD801\uDC1C", "\uD801\uDC44".toUpperCase(), "Expecting Deseret alphabet upper-case Thee"); + assert.areEqual("\uD801\uDC1D", "\uD801\uDC45".toUpperCase(), "Expecting Deseret alphabet upper-case Es"); + assert.areEqual("\uD801\uDC1E", "\uD801\uDC46".toUpperCase(), "Expecting Deseret alphabet upper-case Zee"); + assert.areEqual("\uD801\uDC1F", "\uD801\uDC47".toUpperCase(), "Expecting Deseret alphabet upper-case Esh"); + assert.areEqual("\uD801\uDC20", "\uD801\uDC48".toUpperCase(), "Expecting Deseret alphabet upper-case Zhee"); + assert.areEqual("\uD801\uDC21", "\uD801\uDC49".toUpperCase(), "Expecting Deseret alphabet upper-case Er"); + assert.areEqual("\uD801\uDC22", "\uD801\uDC4A".toUpperCase(), "Expecting Deseret alphabet upper-case El"); + assert.areEqual("\uD801\uDC23", "\uD801\uDC4B".toUpperCase(), "Expecting Deseret alphabet upper-case Em"); + assert.areEqual("\uD801\uDC24", "\uD801\uDC4C".toUpperCase(), "Expecting Deseret alphabet upper-case En"); + assert.areEqual("\uD801\uDC25", "\uD801\uDC4D".toUpperCase(), "Expecting Deseret alphabet upper-case Eng"); + assert.areEqual("\uD801\uDC26", "\uD801\uDC4E".toUpperCase(), "Expecting Deseret alphabet upper-case Oi"); + assert.areEqual("\uD801\uDC27", "\uD801\uDC4F".toUpperCase(), "Expecting Deseret alphabet upper-case Ew"); + } + }, + { + name: "Deseret alphabet toLowerCase", + body: function () { + assert.areEqual("\uD801\uDC28", "\uD801\uDC00".toLowerCase(), "Expecting Deseret alphabet lower-case long I"); + assert.areEqual("\uD801\uDC29", "\uD801\uDC01".toLowerCase(), "Expecting Deseret alphabet lower-case long E"); + assert.areEqual("\uD801\uDC2A", "\uD801\uDC02".toLowerCase(), "Expecting Deseret alphabet lower-case long A"); + assert.areEqual("\uD801\uDC2B", "\uD801\uDC03".toLowerCase(), "Expecting Deseret alphabet lower-case long Ah"); + assert.areEqual("\uD801\uDC2C", "\uD801\uDC04".toLowerCase(), "Expecting Deseret alphabet lower-case long O"); + assert.areEqual("\uD801\uDC2D", "\uD801\uDC05".toLowerCase(), "Expecting Deseret alphabet lower-case long Oo"); + assert.areEqual("\uD801\uDC2E", "\uD801\uDC06".toLowerCase(), "Expecting Deseret alphabet lower-case short I"); + assert.areEqual("\uD801\uDC2F", "\uD801\uDC07".toLowerCase(), "Expecting Deseret alphabet lower-case short E"); + assert.areEqual("\uD801\uDC30", "\uD801\uDC08".toLowerCase(), "Expecting Deseret alphabet lower-case short A"); + assert.areEqual("\uD801\uDC31", "\uD801\uDC09".toLowerCase(), "Expecting Deseret alphabet lower-case short Ah"); + assert.areEqual("\uD801\uDC32", "\uD801\uDC0A".toLowerCase(), "Expecting Deseret alphabet lower-case short O"); + assert.areEqual("\uD801\uDC33", "\uD801\uDC0B".toLowerCase(), "Expecting Deseret alphabet lower-case short Oo"); + assert.areEqual("\uD801\uDC34", "\uD801\uDC0C".toLowerCase(), "Expecting Deseret alphabet lower-case Ay"); + assert.areEqual("\uD801\uDC35", "\uD801\uDC0D".toLowerCase(), "Expecting Deseret alphabet lower-case Ow"); + assert.areEqual("\uD801\uDC36", "\uD801\uDC0E".toLowerCase(), "Expecting Deseret alphabet lower-case Wu"); + assert.areEqual("\uD801\uDC37", "\uD801\uDC0F".toLowerCase(), "Expecting Deseret alphabet lower-case Yee"); + assert.areEqual("\uD801\uDC38", "\uD801\uDC10".toLowerCase(), "Expecting Deseret alphabet lower-case H"); + assert.areEqual("\uD801\uDC39", "\uD801\uDC11".toLowerCase(), "Expecting Deseret alphabet lower-case Pee"); + assert.areEqual("\uD801\uDC3A", "\uD801\uDC12".toLowerCase(), "Expecting Deseret alphabet lower-case Bee"); + assert.areEqual("\uD801\uDC3B", "\uD801\uDC13".toLowerCase(), "Expecting Deseret alphabet lower-case Tee"); + assert.areEqual("\uD801\uDC3C", "\uD801\uDC14".toLowerCase(), "Expecting Deseret alphabet lower-case Dee"); + assert.areEqual("\uD801\uDC3D", "\uD801\uDC15".toLowerCase(), "Expecting Deseret alphabet lower-case Chee"); + assert.areEqual("\uD801\uDC3E", "\uD801\uDC16".toLowerCase(), "Expecting Deseret alphabet lower-case Jee"); + assert.areEqual("\uD801\uDC3F", "\uD801\uDC17".toLowerCase(), "Expecting Deseret alphabet lower-case Kay"); + assert.areEqual("\uD801\uDC40", "\uD801\uDC18".toLowerCase(), "Expecting Deseret alphabet lower-case Gay"); + assert.areEqual("\uD801\uDC41", "\uD801\uDC19".toLowerCase(), "Expecting Deseret alphabet lower-case Ef"); + assert.areEqual("\uD801\uDC42", "\uD801\uDC1A".toLowerCase(), "Expecting Deseret alphabet lower-case Vee"); + assert.areEqual("\uD801\uDC43", "\uD801\uDC1B".toLowerCase(), "Expecting Deseret alphabet lower-case Eth"); + assert.areEqual("\uD801\uDC44", "\uD801\uDC1C".toLowerCase(), "Expecting Deseret alphabet lower-case Thee"); + assert.areEqual("\uD801\uDC45", "\uD801\uDC1D".toLowerCase(), "Expecting Deseret alphabet lower-case Es"); + assert.areEqual("\uD801\uDC46", "\uD801\uDC1E".toLowerCase(), "Expecting Deseret alphabet lower-case Zee"); + assert.areEqual("\uD801\uDC47", "\uD801\uDC1F".toLowerCase(), "Expecting Deseret alphabet lower-case Esh"); + assert.areEqual("\uD801\uDC48", "\uD801\uDC20".toLowerCase(), "Expecting Deseret alphabet lower-case Zhee"); + assert.areEqual("\uD801\uDC49", "\uD801\uDC21".toLowerCase(), "Expecting Deseret alphabet lower-case Er"); + assert.areEqual("\uD801\uDC4A", "\uD801\uDC22".toLowerCase(), "Expecting Deseret alphabet lower-case El"); + assert.areEqual("\uD801\uDC4B", "\uD801\uDC23".toLowerCase(), "Expecting Deseret alphabet lower-case Em"); + assert.areEqual("\uD801\uDC4C", "\uD801\uDC24".toLowerCase(), "Expecting Deseret alphabet lower-case En"); + assert.areEqual("\uD801\uDC4D", "\uD801\uDC25".toLowerCase(), "Expecting Deseret alphabet lower-case Eng"); + assert.areEqual("\uD801\uDC4E", "\uD801\uDC26".toLowerCase(), "Expecting Deseret alphabet lower-case Oi"); + assert.areEqual("\uD801\uDC4F", "\uD801\uDC27".toLowerCase(), "Expecting Deseret alphabet lower-case Ew"); + } + }, + { + name: "Special casing toUpperCase", + body: function () { + assert.areEqual("\u0130", "\u0130".toUpperCase(), "Expecting Latin upper-case i with dot above"); + if (WScript.Platform.INTL_LIBRARY !== "icu") { + // Win32's version of toUpperCase does not support growing strings in the uppercase operation (see CharUpperBuff) + return; + } + assert.areEqual("\u0053\u0053", "\u00DF".toUpperCase(), "Expecting Latin lower-case sharp s"); + assert.areEqual("\u0046\u0046", "\uFB00".toUpperCase(), "Expecting Latin small ligature ff"); + assert.areEqual("\u0046\u0049", "\uFB01".toUpperCase(), "Expecting Latin small ligature fi"); + assert.areEqual("\u0046\u004C", "\uFB02".toUpperCase(), "Expecting Latin small ligature fl"); + assert.areEqual("\u0046\u0046\u0049", "\uFB03".toUpperCase(), "Expecting Latin small ligature ffi"); + assert.areEqual("\u0046\u0046\u004C", "\uFB04".toUpperCase(), "Expecting Latin small ligature ffl"); + assert.areEqual("\u0053\u0054", "\uFB05".toUpperCase(), "Expecting Latin small ligature long s t"); + assert.areEqual("\u0053\u0054", "\uFB06".toUpperCase(), "Expecting Latin small ligature st"); + assert.areEqual("\u0535\u0552", "\u0587".toUpperCase(), "Expecting Armenian small ligature ech yiwn"); + assert.areEqual("\u0544\u0546", "\uFB13".toUpperCase(), "Expecting Armenian small ligature men now"); + assert.areEqual("\u0544\u0535", "\uFB14".toUpperCase(), "Expecting Armenian small ligature men ech"); + assert.areEqual("\u0544\u053B", "\uFB15".toUpperCase(), "Expecting Armenian small ligature men ini"); + assert.areEqual("\u054E\u0546", "\uFB16".toUpperCase(), "Expecting Armenian small ligature vew now"); + assert.areEqual("\u0544\u053D", "\uFB17".toUpperCase(), "Expecting Armenian small ligature men xeh"); + assert.areEqual("\u02BC\u004E", "\u0149".toUpperCase(), "Expecting Latin lower-case n preceded by apostrophe"); + assert.areEqual("\u0399\u0308\u0301", "\u0390".toUpperCase(), "Expecting Greek lower-case iota with dialytika and tonos"); + assert.areEqual("\u03A5\u0308\u0301", "\u03B0".toUpperCase(), "Expecting Greek lower-case upsilon with dialytika and tonos"); + assert.areEqual("\u004A\u030C", "\u01F0".toUpperCase(), "Expecting Latin lower-case j with caron"); + assert.areEqual("\u0048\u0331", "\u1E96".toUpperCase(), "Expecting Latin lower-case h with line below"); + assert.areEqual("\u0054\u0308", "\u1E97".toUpperCase(), "Expecting Latin lower-case t with diaeresis"); + assert.areEqual("\u0057\u030A", "\u1E98".toUpperCase(), "Expecting Latin lower-case w with ring above"); + assert.areEqual("\u0059\u030A", "\u1E99".toUpperCase(), "Expecting Latin lower-case y with ring above"); + assert.areEqual("\u0041\u02BE", "\u1E9A".toUpperCase(), "Expecting Latin lower-case a with right half ring"); + assert.areEqual("\u03A5\u0313", "\u1F50".toUpperCase(), "Expecting Greek lower-case upsilon with psili"); + assert.areEqual("\u03A5\u0313\u0300", "\u1F52".toUpperCase(), "Expecting Greek lower-case upsilon with psili and varia"); + assert.areEqual("\u03A5\u0313\u0301", "\u1F54".toUpperCase(), "Expecting Greek lower-case upsilon with psili and oxia"); + assert.areEqual("\u03A5\u0313\u0342", "\u1F56".toUpperCase(), "Expecting Greek lower-case upsilon with psili and perispomeni"); + assert.areEqual("\u0391\u0342", "\u1FB6".toUpperCase(), "Expecting Greek lower-case alpha with perispomeni"); + assert.areEqual("\u0397\u0342", "\u1FC6".toUpperCase(), "Expecting Greek lower-case eta with perispomeni"); + assert.areEqual("\u0399\u0308\u0300", "\u1FD2".toUpperCase(), "Expecting Greek lower-case iota with dialytika and varia"); + assert.areEqual("\u0399\u0308\u0301", "\u1FD3".toUpperCase(), "Expecting Greek lower-case iota with dialytika and oxia"); + assert.areEqual("\u0399\u0342", "\u1FD6".toUpperCase(), "Expecting Greek lower-case iota with perispomeni"); + assert.areEqual("\u0399\u0308\u0342", "\u1FD7".toUpperCase(), "Expecting Greek lower-case iota with dialytika and perispomeni"); + assert.areEqual("\u03A5\u0308\u0300", "\u1FE2".toUpperCase(), "Expecting Greek lower-case upsilon with dialytika and varia"); + assert.areEqual("\u03A5\u0308\u0301", "\u1FE3".toUpperCase(), "Expecting Greek lower-case upsilon with dialytika and oxia"); + assert.areEqual("\u03A1\u0313", "\u1FE4".toUpperCase(), "Expecting Greek lower-case rho with psili"); + assert.areEqual("\u03A5\u0342", "\u1FE6".toUpperCase(), "Expecting Greek lower-case upsilon with perispomeni"); + assert.areEqual("\u03A5\u0308\u0342", "\u1FE7".toUpperCase(), "Expecting Greek lower-case upsilon with dialytika and perispomeni"); + assert.areEqual("\u03A9\u0342", "\u1FF6".toUpperCase(), "Expecting Greek lower-case omega with perispomeni"); + assert.areEqual("\u1F08\u0399", "\u1F80".toUpperCase(), "Expecting Greek lower-case alpha with psili and ypogegrammeni"); + assert.areEqual("\u1F09\u0399", "\u1F81".toUpperCase(), "Expecting Greek lower-case alpha with dasia and ypogegrammeni"); + assert.areEqual("\u1F0A\u0399", "\u1F82".toUpperCase(), "Expecting Greek lower-case alpha with psili and varia and ypogegrammeni"); + assert.areEqual("\u1F0B\u0399", "\u1F83".toUpperCase(), "Expecting Greek lower-case alpha with dasia and varia and ypogegrammeni"); + assert.areEqual("\u1F0C\u0399", "\u1F84".toUpperCase(), "Expecting Greek lower-case alpha with psili and oxia and ypogegrammeni"); + assert.areEqual("\u1F0D\u0399", "\u1F85".toUpperCase(), "Expecting Greek lower-case alpha with dasia and oxia and ypogegrammeni"); + assert.areEqual("\u1F0E\u0399", "\u1F86".toUpperCase(), "Expecting Greek lower-case alpha with psili and perispomeni and ypogegrammeni"); + assert.areEqual("\u1F0F\u0399", "\u1F87".toUpperCase(), "Expecting Greek lower-case alpha with dasia and perispomeni and ypogegrammeni"); + assert.areEqual("\u1F08\u0399", "\u1F88".toUpperCase(), "Expecting Greek upper-case alpha with psili and prosgegrammeni"); + assert.areEqual("\u1F09\u0399", "\u1F89".toUpperCase(), "Expecting Greek upper-case alpha with dasia and prosgegrammeni"); + assert.areEqual("\u1F0A\u0399", "\u1F8A".toUpperCase(), "Expecting Greek upper-case alpha with psili and varia and prosgegrammeni"); + assert.areEqual("\u1F0B\u0399", "\u1F8B".toUpperCase(), "Expecting Greek upper-case alpha with dasia and varia and prosgegrammeni"); + assert.areEqual("\u1F0C\u0399", "\u1F8C".toUpperCase(), "Expecting Greek upper-case alpha with psili and oxia and prosgegrammeni"); + assert.areEqual("\u1F0D\u0399", "\u1F8D".toUpperCase(), "Expecting Greek upper-case alpha with dasia and oxia and prosgegrammeni"); + assert.areEqual("\u1F0E\u0399", "\u1F8E".toUpperCase(), "Expecting Greek upper-case alpha with psili and perispomeni and prosgegrammeni"); + assert.areEqual("\u1F0F\u0399", "\u1F8F".toUpperCase(), "Expecting Greek upper-case alpha with dasia and perispomeni and prosgegrammeni"); + assert.areEqual("\u1F28\u0399", "\u1F90".toUpperCase(), "Expecting Greek lower-case eta with psili and ypogegrammeni"); + assert.areEqual("\u1F29\u0399", "\u1F91".toUpperCase(), "Expecting Greek lower-case eta with dasia and ypogegrammeni"); + assert.areEqual("\u1F2A\u0399", "\u1F92".toUpperCase(), "Expecting Greek lower-case eta with psili and varia and ypogegrammeni"); + assert.areEqual("\u1F2B\u0399", "\u1F93".toUpperCase(), "Expecting Greek lower-case eta with dasia and varia and ypogegrammeni"); + assert.areEqual("\u1F2C\u0399", "\u1F94".toUpperCase(), "Expecting Greek lower-case eta with psili and oxia and ypogegrammeni"); + assert.areEqual("\u1F2D\u0399", "\u1F95".toUpperCase(), "Expecting Greek lower-case eta with dasia and oxia and ypogegrammeni"); + assert.areEqual("\u1F2E\u0399", "\u1F96".toUpperCase(), "Expecting Greek lower-case eta with psili and perispomeni and ypogegrammeni"); + assert.areEqual("\u1F2F\u0399", "\u1F97".toUpperCase(), "Expecting Greek lower-case eta with dasia and perispomeni and ypogegrammeni"); + assert.areEqual("\u1F28\u0399", "\u1F98".toUpperCase(), "Expecting Greek upper-case eta with psili and prosgegrammeni"); + assert.areEqual("\u1F29\u0399", "\u1F99".toUpperCase(), "Expecting Greek upper-case eta with dasia and prosgegrammeni"); + assert.areEqual("\u1F2A\u0399", "\u1F9A".toUpperCase(), "Expecting Greek upper-case eta with psili and varia and prosgegrammeni"); + assert.areEqual("\u1F2B\u0399", "\u1F9B".toUpperCase(), "Expecting Greek upper-case eta with dasia and varia and prosgegrammeni"); + assert.areEqual("\u1F2C\u0399", "\u1F9C".toUpperCase(), "Expecting Greek upper-case eta with psili and oxia and prosgegrammeni"); + assert.areEqual("\u1F2D\u0399", "\u1F9D".toUpperCase(), "Expecting Greek upper-case eta with dasia and oxia and prosgegrammeni"); + assert.areEqual("\u1F2E\u0399", "\u1F9E".toUpperCase(), "Expecting Greek upper-case eta with psili and perispomeni and prosgegrammeni"); + assert.areEqual("\u1F2F\u0399", "\u1F9F".toUpperCase(), "Expecting Greek upper-case eta with dasia and perispomeni and prosgegrammeni"); + assert.areEqual("\u1F68\u0399", "\u1FA0".toUpperCase(), "Expecting Greek lower-case omega with psili and ypogegrammeni"); + assert.areEqual("\u1F69\u0399", "\u1FA1".toUpperCase(), "Expecting Greek lower-case omega with dasia and ypogegrammeni"); + assert.areEqual("\u1F6A\u0399", "\u1FA2".toUpperCase(), "Expecting Greek lower-case omega with psili and varia and ypogegrammeni"); + assert.areEqual("\u1F6B\u0399", "\u1FA3".toUpperCase(), "Expecting Greek lower-case omega with dasia and varia and ypogegrammeni"); + assert.areEqual("\u1F6C\u0399", "\u1FA4".toUpperCase(), "Expecting Greek lower-case omega with psili and oxia and ypogegrammeni"); + assert.areEqual("\u1F6D\u0399", "\u1FA5".toUpperCase(), "Expecting Greek lower-case omega with dasia and oxia and ypogegrammeni"); + assert.areEqual("\u1F6E\u0399", "\u1FA6".toUpperCase(), "Expecting Greek lower-case omega with psili and perispomeni and ypogegrammeni"); + assert.areEqual("\u1F6F\u0399", "\u1FA7".toUpperCase(), "Expecting Greek lower-case omega with dasia and perispomeni and ypogegrammeni"); + assert.areEqual("\u1F68\u0399", "\u1FA8".toUpperCase(), "Expecting Greek upper-case omega with psili and prosgegrammeni"); + assert.areEqual("\u1F69\u0399", "\u1FA9".toUpperCase(), "Expecting Greek upper-case omega with dasia and prosgegrammeni"); + assert.areEqual("\u1F6A\u0399", "\u1FAA".toUpperCase(), "Expecting Greek upper-case omega with psili and varia and prosgegrammeni"); + assert.areEqual("\u1F6B\u0399", "\u1FAB".toUpperCase(), "Expecting Greek upper-case omega with dasia and varia and prosgegrammeni"); + assert.areEqual("\u1F6C\u0399", "\u1FAC".toUpperCase(), "Expecting Greek upper-case omega with psili and oxia and prosgegrammeni"); + assert.areEqual("\u1F6D\u0399", "\u1FAD".toUpperCase(), "Expecting Greek upper-case omega with dasia and oxia and prosgegrammeni"); + assert.areEqual("\u1F6E\u0399", "\u1FAE".toUpperCase(), "Expecting Greek upper-case omega with psili and perispomeni and prosgegrammeni"); + assert.areEqual("\u1F6F\u0399", "\u1FAF".toUpperCase(), "Expecting Greek upper-case omega with dasia and perispomeni and prosgegrammeni"); + assert.areEqual("\u0391\u0399", "\u1FB3".toUpperCase(), "Expecting Greek lower-case alpha with ypogegrammeni"); + assert.areEqual("\u0391\u0399", "\u1FBC".toUpperCase(), "Expecting Greek upper-case alpha with prosgegrammeni"); + assert.areEqual("\u0397\u0399", "\u1FC3".toUpperCase(), "Expecting Greek lower-case eta with ypogegrammeni"); + assert.areEqual("\u0397\u0399", "\u1FCC".toUpperCase(), "Expecting Greek upper-case eta with prosgegrammeni"); + assert.areEqual("\u03A9\u0399", "\u1FF3".toUpperCase(), "Expecting Greek lower-case omega with ypogegrammeni"); + assert.areEqual("\u03A9\u0399", "\u1FFC".toUpperCase(), "Expecting Greek upper-case omega with prosgegrammeni"); + assert.areEqual("\u1FBA\u0399", "\u1FB2".toUpperCase(), "Expecting Greek lower-case alpha with varia and ypogegrammeni"); + assert.areEqual("\u0386\u0399", "\u1FB4".toUpperCase(), "Expecting Greek lower-case alpha with oxia and ypogegrammeni"); + assert.areEqual("\u1FCA\u0399", "\u1FC2".toUpperCase(), "Expecting Greek lower-case eta with varia and ypogegrammeni"); + assert.areEqual("\u0389\u0399", "\u1FC4".toUpperCase(), "Expecting Greek lower-case eta with oxia and ypogegrammeni"); + assert.areEqual("\u1FFA\u0399", "\u1FF2".toUpperCase(), "Expecting Greek lower-case omega with varia and ypogegrammeni"); + assert.areEqual("\u038F\u0399", "\u1FF4".toUpperCase(), "Expecting Greek lower-case omega with oxia and ypogegrammeni"); + assert.areEqual("\u0391\u0342\u0399", "\u1FB7".toUpperCase(), "Expecting Greek lower-case alpha with perispomeni and ypogegrammeni"); + assert.areEqual("\u0397\u0342\u0399", "\u1FC7".toUpperCase(), "Expecting Greek lower-case eta with perispomeni and ypogegrammeni"); + assert.areEqual("\u03A9\u0342\u0399", "\u1FF7".toUpperCase(), "Expecting Greek lower-case omega with perispomeni and ypogegrammeni"); + } + }, + { + name: "Special casing toLowerCase", + body: function () { + assert.areEqual("\u00DF", "\u00DF".toLowerCase(), "Expecting Latin lower-case sharp s"); + assert.areEqual("\uFB00", "\uFB00".toLowerCase(), "Expecting Latin small ligature ff"); + assert.areEqual("\uFB01", "\uFB01".toLowerCase(), "Expecting Latin small ligature fi"); + assert.areEqual("\uFB02", "\uFB02".toLowerCase(), "Expecting Latin small ligature fl"); + assert.areEqual("\uFB03", "\uFB03".toLowerCase(), "Expecting Latin small ligature ffi"); + assert.areEqual("\uFB04", "\uFB04".toLowerCase(), "Expecting Latin small ligature ffl"); + assert.areEqual("\uFB05", "\uFB05".toLowerCase(), "Expecting Latin small ligature long s t"); + assert.areEqual("\uFB06", "\uFB06".toLowerCase(), "Expecting Latin small ligature st"); + assert.areEqual("\u0587", "\u0587".toLowerCase(), "Expecting Armenian small ligature ech yiwn"); + assert.areEqual("\uFB13", "\uFB13".toLowerCase(), "Expecting Armenian small ligature men now"); + assert.areEqual("\uFB14", "\uFB14".toLowerCase(), "Expecting Armenian small ligature men ech"); + assert.areEqual("\uFB15", "\uFB15".toLowerCase(), "Expecting Armenian small ligature men ini"); + assert.areEqual("\uFB16", "\uFB16".toLowerCase(), "Expecting Armenian small ligature vew now"); + assert.areEqual("\uFB17", "\uFB17".toLowerCase(), "Expecting Armenian small ligature men xeh"); + assert.areEqual("\u0149", "\u0149".toLowerCase(), "Expecting Latin lower-case n preceded by apostrophe"); + assert.areEqual("\u0390", "\u0390".toLowerCase(), "Expecting Greek lower-case iota with dialytika and tonos"); + assert.areEqual("\u03B0", "\u03B0".toLowerCase(), "Expecting Greek lower-case upsilon with dialytika and tonos"); + assert.areEqual("\u01F0", "\u01F0".toLowerCase(), "Expecting Latin lower-case j with caron"); + assert.areEqual("\u1E96", "\u1E96".toLowerCase(), "Expecting Latin lower-case h with line below"); + assert.areEqual("\u1E97", "\u1E97".toLowerCase(), "Expecting Latin lower-case t with diaeresis"); + assert.areEqual("\u1E98", "\u1E98".toLowerCase(), "Expecting Latin lower-case w with ring above"); + assert.areEqual("\u1E99", "\u1E99".toLowerCase(), "Expecting Latin lower-case y with ring above"); + assert.areEqual("\u1E9A", "\u1E9A".toLowerCase(), "Expecting Latin lower-case a with right half ring"); + assert.areEqual("\u1F50", "\u1F50".toLowerCase(), "Expecting Greek lower-case upsilon with psili"); + assert.areEqual("\u1F52", "\u1F52".toLowerCase(), "Expecting Greek lower-case upsilon with psili and varia"); + assert.areEqual("\u1F54", "\u1F54".toLowerCase(), "Expecting Greek lower-case upsilon with psili and oxia"); + assert.areEqual("\u1F56", "\u1F56".toLowerCase(), "Expecting Greek lower-case upsilon with psili and perispomeni"); + assert.areEqual("\u1FB6", "\u1FB6".toLowerCase(), "Expecting Greek lower-case alpha with perispomeni"); + assert.areEqual("\u1FC6", "\u1FC6".toLowerCase(), "Expecting Greek lower-case eta with perispomeni"); + assert.areEqual("\u1FD2", "\u1FD2".toLowerCase(), "Expecting Greek lower-case iota with dialytika and varia"); + assert.areEqual("\u1FD3", "\u1FD3".toLowerCase(), "Expecting Greek lower-case iota with dialytika and oxia"); + assert.areEqual("\u1FD6", "\u1FD6".toLowerCase(), "Expecting Greek lower-case iota with perispomeni"); + assert.areEqual("\u1FD7", "\u1FD7".toLowerCase(), "Expecting Greek lower-case iota with dialytika and perispomeni"); + assert.areEqual("\u1FE2", "\u1FE2".toLowerCase(), "Expecting Greek lower-case upsilon with dialytika and varia"); + assert.areEqual("\u1FE3", "\u1FE3".toLowerCase(), "Expecting Greek lower-case upsilon with dialytika and oxia"); + assert.areEqual("\u1FE4", "\u1FE4".toLowerCase(), "Expecting Greek lower-case rho with psili"); + assert.areEqual("\u1FE6", "\u1FE6".toLowerCase(), "Expecting Greek lower-case upsilon with perispomeni"); + assert.areEqual("\u1FE7", "\u1FE7".toLowerCase(), "Expecting Greek lower-case upsilon with dialytika and perispomeni"); + assert.areEqual("\u1FF6", "\u1FF6".toLowerCase(), "Expecting Greek lower-case omega with perispomeni"); + assert.areEqual("\u1F80", "\u1F80".toLowerCase(), "Expecting Greek lower-case alpha with psili and ypogegrammeni"); + assert.areEqual("\u1F81", "\u1F81".toLowerCase(), "Expecting Greek lower-case alpha with dasia and ypogegrammeni"); + assert.areEqual("\u1F82", "\u1F82".toLowerCase(), "Expecting Greek lower-case alpha with psili and varia and ypogegrammeni"); + assert.areEqual("\u1F83", "\u1F83".toLowerCase(), "Expecting Greek lower-case alpha with dasia and varia and ypogegrammeni"); + assert.areEqual("\u1F84", "\u1F84".toLowerCase(), "Expecting Greek lower-case alpha with psili and oxia and ypogegrammeni"); + assert.areEqual("\u1F85", "\u1F85".toLowerCase(), "Expecting Greek lower-case alpha with dasia and oxia and ypogegrammeni"); + assert.areEqual("\u1F86", "\u1F86".toLowerCase(), "Expecting Greek lower-case alpha with psili and perispomeni and ypogegrammeni"); + assert.areEqual("\u1F87", "\u1F87".toLowerCase(), "Expecting Greek lower-case alpha with dasia and perispomeni and ypogegrammeni"); + assert.areEqual("\u1F80", "\u1F88".toLowerCase(), "Expecting Greek upper-case alpha with psili and prosgegrammeni"); + assert.areEqual("\u1F81", "\u1F89".toLowerCase(), "Expecting Greek upper-case alpha with dasia and prosgegrammeni"); + assert.areEqual("\u1F82", "\u1F8A".toLowerCase(), "Expecting Greek upper-case alpha with psili and varia and prosgegrammeni"); + assert.areEqual("\u1F83", "\u1F8B".toLowerCase(), "Expecting Greek upper-case alpha with dasia and varia and prosgegrammeni"); + assert.areEqual("\u1F84", "\u1F8C".toLowerCase(), "Expecting Greek upper-case alpha with psili and oxia and prosgegrammeni"); + assert.areEqual("\u1F85", "\u1F8D".toLowerCase(), "Expecting Greek upper-case alpha with dasia and oxia and prosgegrammeni"); + assert.areEqual("\u1F86", "\u1F8E".toLowerCase(), "Expecting Greek upper-case alpha with psili and perispomeni and prosgegrammeni"); + assert.areEqual("\u1F87", "\u1F8F".toLowerCase(), "Expecting Greek upper-case alpha with dasia and perispomeni and prosgegrammeni"); + assert.areEqual("\u1F90", "\u1F90".toLowerCase(), "Expecting Greek lower-case eta with psili and ypogegrammeni"); + assert.areEqual("\u1F91", "\u1F91".toLowerCase(), "Expecting Greek lower-case eta with dasia and ypogegrammeni"); + assert.areEqual("\u1F92", "\u1F92".toLowerCase(), "Expecting Greek lower-case eta with psili and varia and ypogegrammeni"); + assert.areEqual("\u1F93", "\u1F93".toLowerCase(), "Expecting Greek lower-case eta with dasia and varia and ypogegrammeni"); + assert.areEqual("\u1F94", "\u1F94".toLowerCase(), "Expecting Greek lower-case eta with psili and oxia and ypogegrammeni"); + assert.areEqual("\u1F95", "\u1F95".toLowerCase(), "Expecting Greek lower-case eta with dasia and oxia and ypogegrammeni"); + assert.areEqual("\u1F96", "\u1F96".toLowerCase(), "Expecting Greek lower-case eta with psili and perispomeni and ypogegrammeni"); + assert.areEqual("\u1F97", "\u1F97".toLowerCase(), "Expecting Greek lower-case eta with dasia and perispomeni and ypogegrammeni"); + assert.areEqual("\u1F90", "\u1F98".toLowerCase(), "Expecting Greek upper-case eta with psili and prosgegrammeni"); + assert.areEqual("\u1F91", "\u1F99".toLowerCase(), "Expecting Greek upper-case eta with dasia and prosgegrammeni"); + assert.areEqual("\u1F92", "\u1F9A".toLowerCase(), "Expecting Greek upper-case eta with psili and varia and prosgegrammeni"); + assert.areEqual("\u1F93", "\u1F9B".toLowerCase(), "Expecting Greek upper-case eta with dasia and varia and prosgegrammeni"); + assert.areEqual("\u1F94", "\u1F9C".toLowerCase(), "Expecting Greek upper-case eta with psili and oxia and prosgegrammeni"); + assert.areEqual("\u1F95", "\u1F9D".toLowerCase(), "Expecting Greek upper-case eta with dasia and oxia and prosgegrammeni"); + assert.areEqual("\u1F96", "\u1F9E".toLowerCase(), "Expecting Greek upper-case eta with psili and perispomeni and prosgegrammeni"); + assert.areEqual("\u1F97", "\u1F9F".toLowerCase(), "Expecting Greek upper-case eta with dasia and perispomeni and prosgegrammeni"); + assert.areEqual("\u1FA0", "\u1FA0".toLowerCase(), "Expecting Greek lower-case omega with psili and ypogegrammeni"); + assert.areEqual("\u1FA1", "\u1FA1".toLowerCase(), "Expecting Greek lower-case omega with dasia and ypogegrammeni"); + assert.areEqual("\u1FA2", "\u1FA2".toLowerCase(), "Expecting Greek lower-case omega with psili and varia and ypogegrammeni"); + assert.areEqual("\u1FA3", "\u1FA3".toLowerCase(), "Expecting Greek lower-case omega with dasia and varia and ypogegrammeni"); + assert.areEqual("\u1FA4", "\u1FA4".toLowerCase(), "Expecting Greek lower-case omega with psili and oxia and ypogegrammeni"); + assert.areEqual("\u1FA5", "\u1FA5".toLowerCase(), "Expecting Greek lower-case omega with dasia and oxia and ypogegrammeni"); + assert.areEqual("\u1FA6", "\u1FA6".toLowerCase(), "Expecting Greek lower-case omega with psili and perispomeni and ypogegrammeni"); + assert.areEqual("\u1FA7", "\u1FA7".toLowerCase(), "Expecting Greek lower-case omega with dasia and perispomeni and ypogegrammeni"); + assert.areEqual("\u1FA0", "\u1FA8".toLowerCase(), "Expecting Greek upper-case omega with psili and prosgegrammeni"); + assert.areEqual("\u1FA1", "\u1FA9".toLowerCase(), "Expecting Greek upper-case omega with dasia and prosgegrammeni"); + assert.areEqual("\u1FA2", "\u1FAA".toLowerCase(), "Expecting Greek upper-case omega with psili and varia and prosgegrammeni"); + assert.areEqual("\u1FA3", "\u1FAB".toLowerCase(), "Expecting Greek upper-case omega with dasia and varia and prosgegrammeni"); + assert.areEqual("\u1FA4", "\u1FAC".toLowerCase(), "Expecting Greek upper-case omega with psili and oxia and prosgegrammeni"); + assert.areEqual("\u1FA5", "\u1FAD".toLowerCase(), "Expecting Greek upper-case omega with dasia and oxia and prosgegrammeni"); + assert.areEqual("\u1FA6", "\u1FAE".toLowerCase(), "Expecting Greek upper-case omega with psili and perispomeni and prosgegrammeni"); + assert.areEqual("\u1FA7", "\u1FAF".toLowerCase(), "Expecting Greek upper-case omega with dasia and perispomeni and prosgegrammeni"); + assert.areEqual("\u1FB3", "\u1FB3".toLowerCase(), "Expecting Greek lower-case alpha with ypogegrammeni"); + assert.areEqual("\u1FB3", "\u1FBC".toLowerCase(), "Expecting Greek upper-case alpha with prosgegrammeni"); + assert.areEqual("\u1FC3", "\u1FC3".toLowerCase(), "Expecting Greek lower-case eta with ypogegrammeni"); + assert.areEqual("\u1FC3", "\u1FCC".toLowerCase(), "Expecting Greek upper-case eta with prosgegrammeni"); + assert.areEqual("\u1FF3", "\u1FF3".toLowerCase(), "Expecting Greek lower-case omega with ypogegrammeni"); + assert.areEqual("\u1FF3", "\u1FFC".toLowerCase(), "Expecting Greek upper-case omega with prosgegrammeni"); + assert.areEqual("\u1FB2", "\u1FB2".toLowerCase(), "Expecting Greek lower-case alpha with varia and ypogegrammeni"); + assert.areEqual("\u1FB4", "\u1FB4".toLowerCase(), "Expecting Greek lower-case alpha with oxia and ypogegrammeni"); + assert.areEqual("\u1FC2", "\u1FC2".toLowerCase(), "Expecting Greek lower-case eta with varia and ypogegrammeni"); + assert.areEqual("\u1FC4", "\u1FC4".toLowerCase(), "Expecting Greek lower-case eta with oxia and ypogegrammeni"); + assert.areEqual("\u1FF2", "\u1FF2".toLowerCase(), "Expecting Greek lower-case omega with varia and ypogegrammeni"); + assert.areEqual("\u1FF4", "\u1FF4".toLowerCase(), "Expecting Greek lower-case omega with oxia and ypogegrammeni"); + assert.areEqual("\u1FB7", "\u1FB7".toLowerCase(), "Expecting Greek lower-case alpha with perispomeni and ypogegrammeni"); + assert.areEqual("\u1FC7", "\u1FC7".toLowerCase(), "Expecting Greek lower-case eta with perispomeni and ypogegrammeni"); + assert.areEqual("\u1FF7", "\u1FF7".toLowerCase(), "Expecting Greek lower-case omega with perispomeni and ypogegrammeni"); + assert.areEqual("\u03C3", "\u03A3".toLowerCase(), "Expecting single Greek upper-case sigma"); + assert.areEqual("\u0345\u03C3", "\u0345\u03A3".toLowerCase(), "Expecting sigma preceded by combining Greek ypogegrammeni (0345)"); + assert.areEqual("a\u03C3b", "A\u03A3B".toLowerCase(), "Expecting sigma followed by Latin upper-case b"); + assert.areEqual("a\u03C3\uD835\uDCA2", "A\u03A3\uD835\uDCA2".toLowerCase(), "Expecting sigma followed by mathematical script capital g (d835 dca2 = 1d4a2)"); + assert.areEqual("a\u03C3.b", "A\u03A3.b".toLowerCase(), "Expecting sigma followed by full stop"); + assert.areEqual("a\u03C3\u00ADb", "A\u03A3\u00ADB".toLowerCase(), "Expecting sigma followed by soft hyphen (00ad)"); + assert.areEqual("a\u03C3\uD834\uDE42b", "A\u03A3\uD834\uDE42B".toLowerCase(), "Expecting sigma followed by combining Greek musical triseme (d834 de42 = 1d242)"); + assert.areEqual("a\u03C3\u0345\u03B1", "A\u03A3\u0345\u0391".toLowerCase(), "Expecting sigma followed by combining Greek ypogegrammeni (0345), Greek upper-case alpha (0391)"); + + if (WScript.Platform.INTL_LIBRARY === "icu") { + assert.areEqual("\u0069\u0307", "\u0130".toLowerCase(), "Expecting Latin upper-case i with dot above"); + assert.areEqual("a\u03C2", "A\u03A3".toLowerCase(), "Expecting sigma preceded by Latin upper-case a"); + assert.areEqual("\uD835\uDCA2\u03C2", "\uD835\uDCA2\u03A3".toLowerCase(), "Expecting sigma preceded by mathematical script capital g (d835 dca2 = 1d4a2)"); + assert.areEqual("a.\u03C2", "A.\u03A3".toLowerCase(), "Expecting sigma preceded by full stop"); + assert.areEqual("a\u00AD\u03C2", "A\u00AD\u03A3".toLowerCase(), "Expecting sigma preceded by soft hyphen (00ad)"); + assert.areEqual("a\uD834\uDE42\u03C2", "A\uD834\uDE42\u03A3".toLowerCase(), "Expecting sigma preceded by combining Greek musical triseme (d834 de42 = 1d242)"); + assert.areEqual("\u03B1\u0345\u03C2", "\u0391\u0345\u03A3".toLowerCase(), "Expecting sigma preceded by Greek upper-case alpha (0391), combining Greek ypogegrammeni (0345)"); + assert.areEqual("a\u03C2\u0345", "A\u03A3\u0345".toLowerCase(), "Expecting sigma followed by combining Greek ypogegrammeni (0345)"); + } + } + }, ]; testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });