1/* 2 * Copyright (c) 2021 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_plural_rules.h" 17 18#include "ecmascript/global_env.h" 19#include "ecmascript/js_plural_rules.h" 20#include "ecmascript/tests/test_helper.h" 21 22using namespace panda::ecmascript; 23using namespace panda::ecmascript::builtins; 24 25namespace panda::test { 26class BuiltinsPluralRulesTest : public BaseTestWithScope<true> { 27}; 28 29// new DateTimeFormat(newTarget is defined) 30HWTEST_F_L0(BuiltinsPluralRulesTest, PluralRulesConstructor) 31{ 32 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 33 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 34 JSHandle<JSFunction> newTarget(env->GetPluralRulesFunction()); 35 36 JSHandle<JSTaggedValue> localesString(factory->NewFromASCII("en-US")); 37 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8); 38 ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue()); 39 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); 40 ecmaRuntimeCallInfo->SetCallArg(0, localesString.GetTaggedValue()); 41 // option tag is default value 42 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined()); 43 44 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 45 JSTaggedValue result = BuiltinsPluralRules::PluralRulesConstructor(ecmaRuntimeCallInfo); 46 TestHelper::TearDownFrame(thread, prev); 47 48 EXPECT_TRUE(result.IsJSPluralRules()); 49} 50 51static JSTaggedValue JSPluralRulesCreateWithLocaleTest(JSThread *thread, JSHandle<JSTaggedValue> &locale, 52 JSHandle<JSTaggedValue> &typeValue) 53{ 54 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 55 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 56 JSHandle<JSFunction> newTarget(env->GetPluralRulesFunction()); 57 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction(); 58 JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun); 59 60 JSHandle<JSTaggedValue> typeKey = thread->GlobalConstants()->GetHandledTypeString(); 61 JSObject::SetProperty(thread, optionsObj, typeKey, typeValue); 62 63 JSHandle<JSTaggedValue> localesString = locale; 64 std::vector<JSTaggedValue> args{ localesString.GetTaggedValue(), optionsObj.GetTaggedValue()}; 65 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, newTarget, args, 8); 66 67 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 68 JSTaggedValue result = BuiltinsPluralRules::PluralRulesConstructor(ecmaRuntimeCallInfo); 69 TestHelper::TearDownFrame(thread, prev); 70 71 EXPECT_TRUE(result.IsJSPluralRules()); 72 return result; 73} 74 75static void SelectTest(JSThread *thread, std::string_view data, std::string_view expectStr, int v) 76{ 77 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 78 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US")); 79 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII(data)); 80 JSHandle<JSPluralRules> jsPluralRules = 81 JSHandle<JSPluralRules>(thread, JSPluralRulesCreateWithLocaleTest(thread, locale, typeValue)); 82 83 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(v)); 84 auto ecmaRuntimeCallInfo = 85 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 : argv length 86 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 87 ecmaRuntimeCallInfo->SetThis(jsPluralRules.GetTaggedValue()); 88 ecmaRuntimeCallInfo->SetCallArg(0, value.GetTaggedValue()); 89 90 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 91 JSTaggedValue result = BuiltinsPluralRules::Select(ecmaRuntimeCallInfo); 92 TestHelper::TearDownFrame(thread, prev); 93 94 EXPECT_TRUE(result.IsString()); 95 JSHandle<EcmaString> handleEcmaStr(thread, result); 96 EXPECT_STREQ(expectStr.data(), EcmaStringAccessor(handleEcmaStr).ToCString().c_str()); 97} 98 99// select(0, type(cardinal)) 100HWTEST_F_L0(BuiltinsPluralRulesTest, Select_001) 101{ 102 SelectTest(thread, "cardinal", "other", 0); 103} 104 105// select(1, type(cardinal)) 106HWTEST_F_L0(BuiltinsPluralRulesTest, Select_002) 107{ 108 SelectTest(thread, "cardinal", "one", 1); 109} 110 111// select(2, type(cardinal)) 112HWTEST_F_L0(BuiltinsPluralRulesTest, Select_003) 113{ 114 SelectTest(thread, "cardinal", "other", 2); 115} 116 117// select(3, type(ordinal)) 118HWTEST_F_L0(BuiltinsPluralRulesTest, Select_004) 119{ 120 SelectTest(thread, "ordinal", "few", 3); 121} 122 123// select(2, type(ordinal)) 124HWTEST_F_L0(BuiltinsPluralRulesTest, Select_005) 125{ 126 SelectTest(thread, "ordinal", "two", 2); 127} 128 129// select(0, type(ordinal)) 130HWTEST_F_L0(BuiltinsPluralRulesTest, Select_006) 131{ 132 SelectTest(thread, "ordinal", "other", 0); 133} 134 135// select(1, type(ordinal)) 136HWTEST_F_L0(BuiltinsPluralRulesTest, Select_007) 137{ 138 SelectTest(thread, "ordinal", "one", 1); 139} 140 141HWTEST_F_L0(BuiltinsPluralRulesTest, SupportedLocalesOf) 142{ 143 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 144 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("id-u-co-pinyin-de-ID")); 145 146 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); 147 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 148 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); 149 ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue()); 150 // set the tag is default value 151 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined()); 152 153 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 154 JSTaggedValue resultArr = BuiltinsPluralRules::SupportedLocalesOf(ecmaRuntimeCallInfo); 155 TestHelper::TearDownFrame(thread, prev); 156 157 JSHandle<JSArray> resultHandle(thread, resultArr); 158 JSHandle<TaggedArray> elements(thread, resultHandle->GetElements()); 159 EXPECT_EQ(elements->GetLength(), 1U); 160 JSHandle<EcmaString> handleEcmaStr(thread, elements->Get(0)); 161 EXPECT_STREQ("id-u-co-pinyin-de-id", EcmaStringAccessor(handleEcmaStr).ToCString().c_str()); 162} 163 164HWTEST_F_L0(BuiltinsPluralRulesTest, ResolvedOptions) 165{ 166 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 167 auto globalConst = thread->GlobalConstants(); 168 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US")); 169 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("ordinal")); 170 JSHandle<JSPluralRules> jsPluralRules = 171 JSHandle<JSPluralRules>(thread, JSPluralRulesCreateWithLocaleTest(thread, locale, typeValue)); 172 173 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); 174 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 175 ecmaRuntimeCallInfo->SetThis(jsPluralRules.GetTaggedValue()); 176 177 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 178 JSTaggedValue result = BuiltinsPluralRules::ResolvedOptions(ecmaRuntimeCallInfo); 179 TestHelper::TearDownFrame(thread, prev); 180 181 JSHandle<JSTaggedValue> resultObj = 182 JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<JSTaggedType>(result.GetRawData()))); 183 // judge whether the properties of the object are the same as those of jspluralrulesformat tag 184 JSHandle<JSTaggedValue> localeKey = globalConst->GetHandledLocaleString(); 185 JSHandle<JSTaggedValue> localeValue(factory->NewFromASCII("en")); 186 EXPECT_EQ(JSTaggedValue::SameValue( 187 JSObject::GetProperty(thread, resultObj, localeKey).GetValue(), localeValue), true); 188 JSHandle<JSTaggedValue> typeKey = globalConst->GetHandledTypeString(); 189 EXPECT_EQ(JSTaggedValue::SameValue( 190 JSObject::GetProperty(thread, resultObj, typeKey).GetValue(), typeValue), true); 191} 192} // namespace panda::test 193