1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ecmascript/builtins/builtins_displaynames.h" 17 18#include "ecmascript/global_env.h" 19#include "ecmascript/js_displaynames.h" 20#include "ecmascript/tests/test_helper.h" 21 22using namespace panda::ecmascript; 23using namespace panda::ecmascript::builtins; 24namespace panda::test { 25class BuiltinsDisplayNamesTest : public BaseTestWithScope<true> { 26}; 27 28static JSTaggedValue JSDisplayNamesCreateWithOptionTest(JSThread *thread, JSHandle<JSTaggedValue> &locale, 29 JSHandle<JSTaggedValue> &typeValue) 30{ 31 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 32 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 33 JSHandle<JSFunction> newTarget(env->GetDisplayNamesFunction()); 34 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction(); 35 JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun); 36 37 JSHandle<JSTaggedValue> typeKey = thread->GlobalConstants()->GetHandledTypeString(); 38 JSObject::SetProperty(thread, optionsObj, typeKey, typeValue); 39 40 JSHandle<JSTaggedValue> localesString = locale; 41 std::vector<JSTaggedValue> args{localesString.GetTaggedValue(), optionsObj.GetTaggedValue()}; 42 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, newTarget, args, 8); 43 44 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 45 JSTaggedValue result = BuiltinsDisplayNames::DisplayNamesConstructor(ecmaRuntimeCallInfo); 46 TestHelper::TearDownFrame(thread, prev); 47 48 EXPECT_TRUE(result.IsJSDisplayNames()); 49 return result; 50} 51 52// new DisplayNames(locales, options) 53HWTEST_F_L0(BuiltinsDisplayNamesTest, DisplayNamesConstructor) 54{ 55 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 56 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 57 JSHandle<JSFunction> newTarget(env->GetDisplayNamesFunction()); 58 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction(); 59 60 JSHandle<JSTaggedValue> typeKey = thread->GlobalConstants()->GetHandledTypeString(); 61 JSHandle<JSTaggedValue> styleKey = thread->GlobalConstants()->GetHandledStyleString(); 62 JSHandle<JSTaggedValue> fallbackKey = thread->GlobalConstants()->GetHandledFallbackString(); 63 64 JSHandle<JSTaggedValue> localeString(factory->NewFromASCII("en")); 65 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("language")); 66 JSHandle<JSTaggedValue> styleValue(factory->NewFromASCII("narrow")); 67 JSHandle<JSTaggedValue> fallbackValue(factory->NewFromASCII("code")); 68 69 JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun); 70 JSObject::SetProperty(thread, optionsObj, typeKey, typeValue); 71 JSObject::SetProperty(thread, optionsObj, styleKey, styleValue); 72 JSObject::SetProperty(thread, optionsObj, fallbackKey, fallbackValue); 73 74 std::vector<JSTaggedValue> args{localeString.GetTaggedValue(), optionsObj.GetTaggedValue()}; 75 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, newTarget, args, 8); 76 77 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 78 JSTaggedValue result = BuiltinsDisplayNames::DisplayNamesConstructor(ecmaRuntimeCallInfo); 79 TestHelper::TearDownFrame(thread, prev); 80 EXPECT_TRUE(result.IsJSDisplayNames()); 81} 82 83// Of(fr, type(language)) 84HWTEST_F_L0(BuiltinsDisplayNamesTest, Of_001) 85{ 86 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 87 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en")); 88 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("language")); 89 JSHandle<JSDisplayNames> jsDisplayNames = 90 JSHandle<JSDisplayNames>(thread, JSDisplayNamesCreateWithOptionTest(thread, locale, typeValue)); 91 92 JSHandle<JSTaggedValue> stringValue(factory->NewFromASCII("fr")); 93 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); 94 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 95 ecmaRuntimeCallInfo->SetThis(jsDisplayNames.GetTaggedValue()); 96 ecmaRuntimeCallInfo->SetCallArg(0, stringValue.GetTaggedValue()); 97 98 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 99 JSTaggedValue result = BuiltinsDisplayNames::Of(ecmaRuntimeCallInfo); 100 TestHelper::TearDownFrame(thread, prev); 101 102 EXPECT_TRUE(result.IsString()); 103 JSHandle<EcmaString> handleEcmaStr(thread, result); 104 EXPECT_STREQ("French", EcmaStringAccessor(handleEcmaStr).ToCString().c_str()); 105} 106 107// Of(419, type(region)) 108HWTEST_F_L0(BuiltinsDisplayNamesTest, Of_002) 109{ 110 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 111 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en")); 112 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("region")); 113 JSHandle<JSDisplayNames> jsDisplayNames = 114 JSHandle<JSDisplayNames>(thread, JSDisplayNamesCreateWithOptionTest(thread, locale, typeValue)); 115 116 JSHandle<JSTaggedValue> stringValue(factory->NewFromASCII("419")); 117 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); 118 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 119 ecmaRuntimeCallInfo->SetThis(jsDisplayNames.GetTaggedValue()); 120 ecmaRuntimeCallInfo->SetCallArg(0, stringValue.GetTaggedValue()); 121 122 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 123 JSTaggedValue result = BuiltinsDisplayNames::Of(ecmaRuntimeCallInfo); 124 TestHelper::TearDownFrame(thread, prev); 125 126 EXPECT_TRUE(result.IsString()); 127 JSHandle<EcmaString> handleEcmaStr(thread, result); 128 EXPECT_STREQ("Latin America", EcmaStringAccessor(handleEcmaStr).ToCString().c_str()); 129} 130 131// Of(EUR, type(currency)) 132HWTEST_F_L0(BuiltinsDisplayNamesTest, Of_003) 133{ 134 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 135 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en")); 136 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("currency")); 137 JSHandle<JSDisplayNames> jsDisplayNames = 138 JSHandle<JSDisplayNames>(thread, JSDisplayNamesCreateWithOptionTest(thread, locale, typeValue)); 139 140 JSHandle<JSTaggedValue> stringValue(factory->NewFromASCII("EUR")); 141 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); 142 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 143 ecmaRuntimeCallInfo->SetThis(jsDisplayNames.GetTaggedValue()); 144 ecmaRuntimeCallInfo->SetCallArg(0, stringValue.GetTaggedValue()); 145 146 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 147 JSTaggedValue result = BuiltinsDisplayNames::Of(ecmaRuntimeCallInfo); 148 TestHelper::TearDownFrame(thread, prev); 149 150 EXPECT_TRUE(result.IsString()); 151 JSHandle<EcmaString> handleEcmaStr(thread, result); 152 EXPECT_STREQ("Euro", EcmaStringAccessor(handleEcmaStr).ToCString().c_str()); 153} 154 155// Of(Code Cover) 156HWTEST_F_L0(BuiltinsDisplayNamesTest, Of_004) 157{ 158 // IsNotJSDisplayNames 159 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); 160 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 161 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); 162 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue::Undefined()); 163 164 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 165 JSTaggedValue result = BuiltinsDisplayNames::Of(ecmaRuntimeCallInfo); 166 TestHelper::TearDownFrame(thread, prev); 167 EXPECT_TRUE(thread->HasPendingException()); 168 EXPECT_EQ(result, JSTaggedValue::Exception()); 169 thread->ClearException(); 170} 171 172// SupportedLocalesOf("best fit") 173HWTEST_F_L0(BuiltinsDisplayNamesTest, SupportedLocalesOf_001) 174{ 175 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 176 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("id-u-co-pinyin-de-ID")); 177 178 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); 179 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 180 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); 181 ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue()); 182 // set the tag is default value 183 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined()); 184 185 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 186 JSTaggedValue resultArr = BuiltinsDisplayNames::SupportedLocalesOf(ecmaRuntimeCallInfo); 187 TestHelper::TearDownFrame(thread, prev); 188 189 JSHandle<JSArray> resultHandle(thread, resultArr); 190 JSHandle<TaggedArray> elements(thread, resultHandle->GetElements()); 191 EXPECT_EQ(elements->GetLength(), 1U); 192 JSHandle<EcmaString> handleEcmaStr(thread, elements->Get(0)); 193 EXPECT_STREQ("id-u-co-pinyin-de-id", EcmaStringAccessor(handleEcmaStr).ToCString().c_str()); 194} 195 196// SupportedLocalesOf("look up") 197HWTEST_F_L0(BuiltinsDisplayNamesTest, SupportedLocalesOf_002) 198{ 199 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 200 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 201 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction(); 202 203 JSHandle<JSTaggedValue> localeMatcherKey = thread->GlobalConstants()->GetHandledLocaleMatcherString(); 204 JSHandle<JSTaggedValue> localeMatcherValue(factory->NewFromASCII("lookup")); 205 JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun); 206 JSObject::SetProperty(thread, optionsObj, localeMatcherKey, localeMatcherValue); 207 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("de-DE-u-co-phonebk")); 208 209 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); 210 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 211 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); 212 ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue()); 213 ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue()); 214 215 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 216 JSTaggedValue resultArr = BuiltinsDisplayNames::SupportedLocalesOf(ecmaRuntimeCallInfo); 217 TestHelper::TearDownFrame(thread, prev); 218 219 JSHandle<JSArray> resultHandle(thread, resultArr); 220 JSHandle<TaggedArray> elements(thread, resultHandle->GetElements()); 221 EXPECT_EQ(elements->GetLength(), 1U); 222 JSHandle<EcmaString> handleEcmaStr(thread, elements->Get(0)); 223 EXPECT_STREQ("de-DE-u-co-phonebk", EcmaStringAccessor(handleEcmaStr).ToCString().c_str()); 224} 225 226HWTEST_F_L0(BuiltinsDisplayNamesTest, ResolvedOptions) 227{ 228 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 229 auto globalConst = thread->GlobalConstants(); 230 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("de-DE")); 231 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("currency")); 232 JSHandle<JSDisplayNames> jsDisplayNames = 233 JSHandle<JSDisplayNames>(thread, JSDisplayNamesCreateWithOptionTest( 234 thread, locale, typeValue)); 235 std::vector<JSTaggedValue> args{}; 236 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 4, jsDisplayNames.GetTaggedValue()); 237 238 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 239 JSTaggedValue result = BuiltinsDisplayNames::ResolvedOptions(ecmaRuntimeCallInfo); 240 TestHelper::TearDownFrame(thread, prev); 241 242 JSHandle<JSTaggedValue> resultObj = 243 JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<JSTaggedType>(result.GetRawData()))); 244 // judge whether the properties of the object are the same as those of jsdatetimeformat tag 245 JSHandle<JSTaggedValue> localeKey = globalConst->GetHandledLocaleString(); 246 JSHandle<JSTaggedValue> localeValue(factory->NewFromASCII("de-DE")); 247 EXPECT_EQ(JSTaggedValue::SameValue( 248 JSObject::GetProperty(thread, resultObj, localeKey).GetValue(), localeValue), true); 249 JSHandle<JSTaggedValue> typeKey = globalConst->GetHandledTypeString(); 250 EXPECT_EQ(JSTaggedValue::SameValue( 251 JSObject::GetProperty(thread, resultObj, typeKey).GetValue(), typeValue), true); 252} 253} 254