/* * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ecmascript/js_displaynames.h" #include "ecmascript/intl/locale_helper.h" #include "ecmascript/tests/test_helper.h" using namespace panda; using namespace panda::ecmascript; namespace panda::test { class JSDisplayNamesTest : public BaseTestWithScope { }; /** * @tc.name: GetIcuLocaleDisplayNames * @tc.desc: Call "SetIcuLocaleDisplayNames" function Set IcuLocale DisplayNames,check whether the IcuLocale * DisplayNames through "GetIcuLocaleDisplayNames" function is within expectations then call "getLocale" * function display locale and check the locale is within expectations. * @tc.type: FUNC * @tc.require: */ HWTEST_F_L0(JSDisplayNamesTest, GetIcuLocaleDisplayNames) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle ctor = env->GetDisplayNamesFunction(); JSHandle displayNames = JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(ctor), ctor)); icu::Locale icuLocale("en"); UDisplayContext display_context[] = {UDISPCTX_LENGTH_SHORT}; icu::LocaleDisplayNames* iculocaledisplaynames = icu::LocaleDisplayNames::createInstance(icuLocale, display_context, 1); EXPECT_TRUE(iculocaledisplaynames != nullptr); JSDisplayNames::SetIcuLocaleDisplayNames( thread, displayNames, iculocaledisplaynames, JSDisplayNames::FreeIcuLocaleDisplayNames); icu::LocaleDisplayNames *resultIculocaledisplaynames = displayNames->GetIcuLocaleDisplayNames(thread); EXPECT_TRUE(iculocaledisplaynames == resultIculocaledisplaynames); JSHandle localeStr = intl::LocaleHelper::ToLanguageTag(thread, resultIculocaledisplaynames->getLocale()); EXPECT_STREQ(EcmaStringAccessor(localeStr).ToCString(thread).c_str(), "en"); } /** * @tc.name: GetAvailableLocales * @tc.desc: Call function "GetAvailableLocales" to obtain the available locale from the ICU library and * check whether the obtained locale is empty. * @tc.type: FUNC * @tc.require: */ HWTEST_F_L0(JSDisplayNamesTest, GetAvailableLocales) { JSHandle displayLocale = JSDisplayNames::GetAvailableLocales(thread); uint32_t localeLen = displayLocale->GetLength(); EXPECT_NE(localeLen, 0U); for (uint32_t i = 0; i < localeLen; i++) { EXPECT_FALSE(displayLocale->Get(thread, i).IsHole()); } } void SetOptionProperties(JSThread *thread, JSHandle &optionsObj, std::map &displayOptions) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); auto globalConst = thread->GlobalConstants(); // display options keys JSHandle styleKey = globalConst->GetHandledStyleString(); JSHandle typeKey = globalConst->GetHandledTypeString(); JSHandle fallBackKey = globalConst->GetHandledFallbackString(); // display options value JSHandle styleValue(factory->NewFromASCII(displayOptions["style"].c_str())); JSHandle typeValue(factory->NewFromASCII(displayOptions["type"].c_str())); JSHandle fallBackValue(factory->NewFromASCII(displayOptions["fallback"].c_str())); JSObject::SetProperty(thread, optionsObj, styleKey, styleValue); JSObject::SetProperty(thread, optionsObj, typeKey, typeValue); JSObject::SetProperty(thread, optionsObj, fallBackKey, fallBackValue); } /** * @tc.name: InitializeDisplayNames * @tc.desc: Call function "InitializeDisplayNames" to initialize the jsdisplaynames class object and check whether the * properties of the object is within expectations. * @tc.type: FUNC * @tc.require: */ HWTEST_F_L0(JSDisplayNamesTest, InitializeDisplayNames) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle ctor = env->GetDisplayNamesFunction(); JSHandle displayNames = JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(ctor), ctor)); JSHandle objFun = env->GetObjectFunction(); JSHandle displayOptions = factory->NewJSObjectByConstructor(JSHandle(objFun), objFun); JSHandle localeStr(factory->NewFromASCII("en-US")); // options is empty JSDisplayNames::InitializeDisplayNames(thread, displayNames, localeStr, JSHandle(displayOptions)); // Default attribute value and type is undefiend throw a expection EXPECT_EQ(displayNames->GetStyle(), StyOption::LONG); EXPECT_EQ(displayNames->GetType(), TypednsOption::EXCEPTION); EXPECT_EQ(displayNames->GetFallback(), FallbackOption::EXCEPTION); EXPECT_TRUE(thread->HasPendingException()); thread->ClearException(); // options of the key and value std::map displayOptionsProperty { { "style", "short" }, { "type", "script" }, { "fallback", "none" }, }; SetOptionProperties(thread, displayOptions, displayOptionsProperty); // options is not empty JSDisplayNames::InitializeDisplayNames(thread, displayNames, localeStr, JSHandle(displayOptions)); JSHandle setlocale(thread, displayNames->GetLocale(thread)); EXPECT_EQ(displayNames->GetStyle(), StyOption::SHORT); EXPECT_EQ(displayNames->GetType(), TypednsOption::SCRIPT); EXPECT_EQ(displayNames->GetFallback(), FallbackOption::NONE); EXPECT_STREQ(EcmaStringAccessor(setlocale).ToCString(thread).c_str(), "en-US"); EXPECT_TRUE(displayNames->GetIcuLocaleDisplayNames(thread) != nullptr); } /** * @tc.name: CanonicalCodeForDisplayNames * @tc.desc: Display the language region and script of the locale according to the display configuration of * different regions. * @tc.type: FUNC * @tc.require: */ HWTEST_F_L0(JSDisplayNamesTest, CanonicalCodeForDisplayNames) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle ctor = env->GetDisplayNamesFunction(); JSHandle displayNames = JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(ctor), ctor)); JSHandle objFun = env->GetObjectFunction(); JSHandle displayOptions = factory->NewJSObjectByConstructor(JSHandle(objFun), objFun); JSHandle locale(factory->NewFromASCII("zh-Hant")); // test UDISPCTX_LENGTH_SHORT std::map displayOptionsProperty { { "style", "narrow" }, { "type", "script" }, { "fallback", "none" }, }; SetOptionProperties(thread, displayOptions, displayOptionsProperty); JSHandle initDisplayNames = JSDisplayNames::InitializeDisplayNames(thread, displayNames, locale, JSHandle(displayOptions)); // CanonicalCode for script JSHandle code = factory->NewFromASCII("Kana"); JSHandle resultDisplay = JSDisplayNames::CanonicalCodeForDisplayNames(thread, initDisplayNames, initDisplayNames->GetType(), code); EXPECT_STREQ(EcmaStringAccessor(resultDisplay).ToCString(thread).c_str(), "片假名"); // CanonicalCode for languege code = factory->NewFromASCII("fr"); initDisplayNames->SetType(TypednsOption::LANGUAGE); resultDisplay = JSDisplayNames::CanonicalCodeForDisplayNames(thread, initDisplayNames, initDisplayNames->GetType(), code); EXPECT_STREQ(EcmaStringAccessor(resultDisplay).ToCString(thread).c_str(), "法文"); // CanonicalCode for region code = factory->NewFromASCII("US"); initDisplayNames->SetType(TypednsOption::REGION); resultDisplay = JSDisplayNames::CanonicalCodeForDisplayNames(thread, initDisplayNames, initDisplayNames->GetType(), code); EXPECT_STREQ(EcmaStringAccessor(resultDisplay).ToCString(thread).c_str(), "美國"); } /** * @tc.name: ResolvedOptions * @tc.desc: Call function "InitializeDisplayNames" to initialize the jsdisplaynames class object and Copy the * properties of jsdisplaynames class to a new object. * @tc.type: FUNC * @tc.require: */ HWTEST_F_L0(JSDisplayNamesTest, ResolvedOptions) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); auto globalConst = thread->GlobalConstants(); JSHandle localeKey = globalConst->GetHandledLocaleString(); JSHandle styleKey = globalConst->GetHandledStyleString(); JSHandle typeKey = globalConst->GetHandledTypeString(); JSHandle fallBackKey = globalConst->GetHandledFallbackString(); JSHandle ctor = env->GetDisplayNamesFunction(); JSHandle displayNames = JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(ctor), ctor)); JSHandle objFun = env->GetObjectFunction(); JSHandle displayOptions = factory->NewJSObjectByConstructor(JSHandle(objFun), objFun); JSHandle locale(factory->NewFromASCII("zh-Hant")); std::map displayOptionsProperty { { "style", "short" }, { "type", "region" }, { "fallback", "code" }, }; JSHandle styleValue(factory->NewFromASCII(displayOptionsProperty["style"].c_str())); JSHandle typeValue(factory->NewFromASCII(displayOptionsProperty["type"].c_str())); JSHandle fallBackValue(factory->NewFromASCII(displayOptionsProperty["fallback"].c_str())); SetOptionProperties(thread, displayOptions, displayOptionsProperty); JSHandle initDisplayNames = JSDisplayNames::InitializeDisplayNames(thread, displayNames, locale, JSHandle(displayOptions)); JSDisplayNames::ResolvedOptions(thread, initDisplayNames, displayOptions); EXPECT_EQ(JSTaggedValue::SameValue(thread, JSObject::GetProperty(thread, displayOptions, styleKey).GetValue(), styleValue), true); EXPECT_EQ(JSTaggedValue::SameValue(thread, JSObject::GetProperty(thread, displayOptions, localeKey).GetValue(), locale), true); EXPECT_EQ(JSTaggedValue::SameValue(thread, JSObject::GetProperty(thread, displayOptions, fallBackKey).GetValue(), fallBackValue), true); EXPECT_EQ(JSTaggedValue::SameValue(thread, JSObject::GetProperty(thread, displayOptions, typeKey).GetValue(), typeValue), true); } } // namespace panda::test