14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/builtins/builtins_plural_rules.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include "ecmascript/global_env.h"
194514f5e3Sopenharmony_ci#include "ecmascript/js_plural_rules.h"
204514f5e3Sopenharmony_ci#include "ecmascript/tests/test_helper.h"
214514f5e3Sopenharmony_ci
224514f5e3Sopenharmony_ciusing namespace panda::ecmascript;
234514f5e3Sopenharmony_ciusing namespace panda::ecmascript::builtins;
244514f5e3Sopenharmony_ci
254514f5e3Sopenharmony_cinamespace panda::test {
264514f5e3Sopenharmony_ciclass BuiltinsPluralRulesTest : public BaseTestWithScope<true> {
274514f5e3Sopenharmony_ci};
284514f5e3Sopenharmony_ci
294514f5e3Sopenharmony_ci// new DateTimeFormat(newTarget is defined)
304514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsPluralRulesTest, PluralRulesConstructor)
314514f5e3Sopenharmony_ci{
324514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
334514f5e3Sopenharmony_ci    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
344514f5e3Sopenharmony_ci    JSHandle<JSFunction> newTarget(env->GetPluralRulesFunction());
354514f5e3Sopenharmony_ci
364514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> localesString(factory->NewFromASCII("en-US"));
374514f5e3Sopenharmony_ci    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
384514f5e3Sopenharmony_ci    ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
394514f5e3Sopenharmony_ci    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
404514f5e3Sopenharmony_ci    ecmaRuntimeCallInfo->SetCallArg(0, localesString.GetTaggedValue());
414514f5e3Sopenharmony_ci    // option tag is default value
424514f5e3Sopenharmony_ci    ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined());
434514f5e3Sopenharmony_ci
444514f5e3Sopenharmony_ci    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
454514f5e3Sopenharmony_ci    JSTaggedValue result = BuiltinsPluralRules::PluralRulesConstructor(ecmaRuntimeCallInfo);
464514f5e3Sopenharmony_ci    TestHelper::TearDownFrame(thread, prev);
474514f5e3Sopenharmony_ci
484514f5e3Sopenharmony_ci    EXPECT_TRUE(result.IsJSPluralRules());
494514f5e3Sopenharmony_ci}
504514f5e3Sopenharmony_ci
514514f5e3Sopenharmony_cistatic JSTaggedValue JSPluralRulesCreateWithLocaleTest(JSThread *thread, JSHandle<JSTaggedValue> &locale,
524514f5e3Sopenharmony_ci                                                       JSHandle<JSTaggedValue> &typeValue)
534514f5e3Sopenharmony_ci{
544514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
554514f5e3Sopenharmony_ci    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
564514f5e3Sopenharmony_ci    JSHandle<JSFunction> newTarget(env->GetPluralRulesFunction());
574514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
584514f5e3Sopenharmony_ci    JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
594514f5e3Sopenharmony_ci
604514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> typeKey = thread->GlobalConstants()->GetHandledTypeString();
614514f5e3Sopenharmony_ci    JSObject::SetProperty(thread, optionsObj, typeKey, typeValue);
624514f5e3Sopenharmony_ci
634514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> localesString = locale;
644514f5e3Sopenharmony_ci    std::vector<JSTaggedValue> args{ localesString.GetTaggedValue(), optionsObj.GetTaggedValue()};
654514f5e3Sopenharmony_ci    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, newTarget, args, 8);
664514f5e3Sopenharmony_ci
674514f5e3Sopenharmony_ci    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
684514f5e3Sopenharmony_ci    JSTaggedValue result = BuiltinsPluralRules::PluralRulesConstructor(ecmaRuntimeCallInfo);
694514f5e3Sopenharmony_ci    TestHelper::TearDownFrame(thread, prev);
704514f5e3Sopenharmony_ci
714514f5e3Sopenharmony_ci    EXPECT_TRUE(result.IsJSPluralRules());
724514f5e3Sopenharmony_ci    return result;
734514f5e3Sopenharmony_ci}
744514f5e3Sopenharmony_ci
754514f5e3Sopenharmony_cistatic void SelectTest(JSThread *thread, std::string_view data, std::string_view expectStr, int v)
764514f5e3Sopenharmony_ci{
774514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
784514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
794514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII(data));
804514f5e3Sopenharmony_ci    JSHandle<JSPluralRules> jsPluralRules =
814514f5e3Sopenharmony_ci        JSHandle<JSPluralRules>(thread, JSPluralRulesCreateWithLocaleTest(thread, locale, typeValue));
824514f5e3Sopenharmony_ci
834514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> value(thread, JSTaggedValue(v));
844514f5e3Sopenharmony_ci    auto ecmaRuntimeCallInfo =
854514f5e3Sopenharmony_ci        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);  // 6 : argv length
864514f5e3Sopenharmony_ci    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
874514f5e3Sopenharmony_ci    ecmaRuntimeCallInfo->SetThis(jsPluralRules.GetTaggedValue());
884514f5e3Sopenharmony_ci    ecmaRuntimeCallInfo->SetCallArg(0, value.GetTaggedValue());
894514f5e3Sopenharmony_ci
904514f5e3Sopenharmony_ci    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
914514f5e3Sopenharmony_ci    JSTaggedValue result = BuiltinsPluralRules::Select(ecmaRuntimeCallInfo);
924514f5e3Sopenharmony_ci    TestHelper::TearDownFrame(thread, prev);
934514f5e3Sopenharmony_ci
944514f5e3Sopenharmony_ci    EXPECT_TRUE(result.IsString());
954514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleEcmaStr(thread, result);
964514f5e3Sopenharmony_ci    EXPECT_STREQ(expectStr.data(), EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
974514f5e3Sopenharmony_ci}
984514f5e3Sopenharmony_ci
994514f5e3Sopenharmony_ci// select(0, type(cardinal))
1004514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsPluralRulesTest, Select_001)
1014514f5e3Sopenharmony_ci{
1024514f5e3Sopenharmony_ci    SelectTest(thread, "cardinal", "other", 0);
1034514f5e3Sopenharmony_ci}
1044514f5e3Sopenharmony_ci
1054514f5e3Sopenharmony_ci// select(1, type(cardinal))
1064514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsPluralRulesTest, Select_002)
1074514f5e3Sopenharmony_ci{
1084514f5e3Sopenharmony_ci    SelectTest(thread, "cardinal", "one", 1);
1094514f5e3Sopenharmony_ci}
1104514f5e3Sopenharmony_ci
1114514f5e3Sopenharmony_ci// select(2, type(cardinal))
1124514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsPluralRulesTest, Select_003)
1134514f5e3Sopenharmony_ci{
1144514f5e3Sopenharmony_ci    SelectTest(thread, "cardinal", "other", 2);
1154514f5e3Sopenharmony_ci}
1164514f5e3Sopenharmony_ci
1174514f5e3Sopenharmony_ci// select(3, type(ordinal))
1184514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsPluralRulesTest, Select_004)
1194514f5e3Sopenharmony_ci{
1204514f5e3Sopenharmony_ci    SelectTest(thread, "ordinal", "few", 3);
1214514f5e3Sopenharmony_ci}
1224514f5e3Sopenharmony_ci
1234514f5e3Sopenharmony_ci// select(2, type(ordinal))
1244514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsPluralRulesTest, Select_005)
1254514f5e3Sopenharmony_ci{
1264514f5e3Sopenharmony_ci    SelectTest(thread, "ordinal", "two", 2);
1274514f5e3Sopenharmony_ci}
1284514f5e3Sopenharmony_ci
1294514f5e3Sopenharmony_ci// select(0, type(ordinal))
1304514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsPluralRulesTest, Select_006)
1314514f5e3Sopenharmony_ci{
1324514f5e3Sopenharmony_ci    SelectTest(thread, "ordinal", "other", 0);
1334514f5e3Sopenharmony_ci}
1344514f5e3Sopenharmony_ci
1354514f5e3Sopenharmony_ci// select(1, type(ordinal))
1364514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsPluralRulesTest, Select_007)
1374514f5e3Sopenharmony_ci{
1384514f5e3Sopenharmony_ci    SelectTest(thread, "ordinal", "one", 1);
1394514f5e3Sopenharmony_ci}
1404514f5e3Sopenharmony_ci
1414514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsPluralRulesTest, SupportedLocalesOf)
1424514f5e3Sopenharmony_ci{
1434514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1444514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> locale(factory->NewFromASCII("id-u-co-pinyin-de-ID"));
1454514f5e3Sopenharmony_ci
1464514f5e3Sopenharmony_ci    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1474514f5e3Sopenharmony_ci    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
1484514f5e3Sopenharmony_ci    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
1494514f5e3Sopenharmony_ci    ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
1504514f5e3Sopenharmony_ci    // set the tag is default value
1514514f5e3Sopenharmony_ci    ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined());
1524514f5e3Sopenharmony_ci
1534514f5e3Sopenharmony_ci    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
1544514f5e3Sopenharmony_ci    JSTaggedValue resultArr = BuiltinsPluralRules::SupportedLocalesOf(ecmaRuntimeCallInfo);
1554514f5e3Sopenharmony_ci    TestHelper::TearDownFrame(thread, prev);
1564514f5e3Sopenharmony_ci
1574514f5e3Sopenharmony_ci    JSHandle<JSArray> resultHandle(thread, resultArr);
1584514f5e3Sopenharmony_ci    JSHandle<TaggedArray> elements(thread, resultHandle->GetElements());
1594514f5e3Sopenharmony_ci    EXPECT_EQ(elements->GetLength(), 1U);
1604514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleEcmaStr(thread, elements->Get(0));
1614514f5e3Sopenharmony_ci    EXPECT_STREQ("id-u-co-pinyin-de-id", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
1624514f5e3Sopenharmony_ci}
1634514f5e3Sopenharmony_ci
1644514f5e3Sopenharmony_ciHWTEST_F_L0(BuiltinsPluralRulesTest, ResolvedOptions)
1654514f5e3Sopenharmony_ci{
1664514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1674514f5e3Sopenharmony_ci    auto globalConst = thread->GlobalConstants();
1684514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
1694514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("ordinal"));
1704514f5e3Sopenharmony_ci    JSHandle<JSPluralRules> jsPluralRules =
1714514f5e3Sopenharmony_ci        JSHandle<JSPluralRules>(thread, JSPluralRulesCreateWithLocaleTest(thread, locale, typeValue));
1724514f5e3Sopenharmony_ci
1734514f5e3Sopenharmony_ci    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1744514f5e3Sopenharmony_ci    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
1754514f5e3Sopenharmony_ci    ecmaRuntimeCallInfo->SetThis(jsPluralRules.GetTaggedValue());
1764514f5e3Sopenharmony_ci
1774514f5e3Sopenharmony_ci    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
1784514f5e3Sopenharmony_ci    JSTaggedValue result = BuiltinsPluralRules::ResolvedOptions(ecmaRuntimeCallInfo);
1794514f5e3Sopenharmony_ci    TestHelper::TearDownFrame(thread, prev);
1804514f5e3Sopenharmony_ci
1814514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> resultObj =
1824514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<JSTaggedType>(result.GetRawData())));
1834514f5e3Sopenharmony_ci    // judge whether the properties of the object are the same as those of jspluralrulesformat tag
1844514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> localeKey = globalConst->GetHandledLocaleString();
1854514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> localeValue(factory->NewFromASCII("en"));
1864514f5e3Sopenharmony_ci    EXPECT_EQ(JSTaggedValue::SameValue(
1874514f5e3Sopenharmony_ci        JSObject::GetProperty(thread, resultObj, localeKey).GetValue(), localeValue), true);
1884514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> typeKey = globalConst->GetHandledTypeString();
1894514f5e3Sopenharmony_ci    EXPECT_EQ(JSTaggedValue::SameValue(
1904514f5e3Sopenharmony_ci        JSObject::GetProperty(thread, resultObj, typeKey).GetValue(), typeValue), true);
1914514f5e3Sopenharmony_ci}
1924514f5e3Sopenharmony_ci} // namespace panda::test
193