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/intl/locale_helper.h"
17 #include "ecmascript/js_plural_rules.h"
18 #include "ecmascript/base/number_helper.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/tests/test_helper.h"
21
22 using namespace panda::ecmascript;
23 using namespace panda::ecmascript::base;
24
25 namespace panda::test {
26 class JSPluralRulesTest : public BaseTestWithScope<true> {
27 };
28
HWTEST_F_L0(JSPluralRulesTest,GetIcuPluralRules)29 HWTEST_F_L0(JSPluralRulesTest, GetIcuPluralRules)
30 {
31 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
32 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
33
34 JSHandle<JSTaggedValue> ctor = env->GetPluralRulesFunction();
35 JSHandle<JSPluralRules> pluralRules =
36 JSHandle<JSPluralRules>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
37 // Create PluralRules
38 icu::Locale icuLocale("en", "US");
39 UErrorCode status = U_ZERO_ERROR;
40 UPluralType icuType = UPLURAL_TYPE_CARDINAL; // Plural rules for cardinal numbers
41 icu::PluralRules *icuPluralRules(icu::PluralRules::forLocale(icuLocale, icuType, status));
42 icu::UnicodeString result1 = icuPluralRules->select(0);
43 JSHandle<EcmaString> stringValue1 = intl::LocaleHelper::UStringToString(thread, result1);
44
45 JSPluralRules::SetIcuPluralRules(thread, pluralRules, *icuPluralRules, JSPluralRules::FreeIcuPluralRules);
46 icu::PluralRules *getPluralRules = pluralRules->GetIcuPluralRules();
47 icu::UnicodeString result2 = getPluralRules->select(0);
48 JSHandle<EcmaString> stringValue2 = intl::LocaleHelper::UStringToString(thread, result2);
49 EXPECT_EQ(EcmaStringAccessor::StringsAreEqual(*stringValue1, *stringValue2), true);
50 delete icuPluralRules;
51 }
52
HWTEST_F_L0(JSPluralRulesTest,BuildLocaleSet)53 HWTEST_F_L0(JSPluralRulesTest, BuildLocaleSet)
54 {
55 std::set<std::string> icuAvailableLocales {
56 "en-Latn-US",
57 "zh-Hans-CN",
58 "pt-PT",
59 "de-DE",
60 };
61 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
62 JSHandle<EcmaString> resultStr;
63 JSHandle<EcmaString> localeStr1 = factory->NewFromStdString("en-Latn-US");
64 JSHandle<EcmaString> localeStr2 = factory->NewFromStdString("zh-Hans-CN");
65 JSHandle<EcmaString> localeStr3 = factory->NewFromStdString("pt-PT");
66 JSHandle<EcmaString> localeStr4 = factory->NewFromStdString("de-DE");
67 JSHandle<TaggedArray> localeSet = JSPluralRules::BuildLocaleSet(thread, icuAvailableLocales);
68 EXPECT_EQ(localeSet->GetLength(), 4U);
69
70 resultStr = JSHandle<EcmaString>(thread, localeSet->Get(0).GetTaggedObject());
71 EXPECT_EQ(EcmaStringAccessor::StringsAreEqual(*resultStr, *localeStr4), true);
72 resultStr = JSHandle<EcmaString>(thread, localeSet->Get(1).GetTaggedObject());
73 EXPECT_EQ(EcmaStringAccessor::StringsAreEqual(*resultStr, *localeStr1), true);
74 resultStr = JSHandle<EcmaString>(thread, localeSet->Get(2).GetTaggedObject());
75 EXPECT_EQ(EcmaStringAccessor::StringsAreEqual(*resultStr, *localeStr3), true);
76 resultStr = JSHandle<EcmaString>(thread, localeSet->Get(3).GetTaggedObject());
77 EXPECT_EQ(EcmaStringAccessor::StringsAreEqual(*resultStr, *localeStr2), true);
78 }
79
HWTEST_F_L0(JSPluralRulesTest,InitializePluralRules)80 HWTEST_F_L0(JSPluralRulesTest, InitializePluralRules)
81 {
82 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
83 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
84 JSHandle<JSTaggedValue> optionHandle(thread, JSTaggedValue::Undefined());
85
86 JSHandle<JSTaggedValue> ctor = env->GetPluralRulesFunction();
87 JSHandle<JSPluralRules> pluralRules =
88 JSHandle<JSPluralRules>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
89 JSHandle<JSTaggedValue> localeStr(factory->NewFromASCII("en-GB"));
90 JSHandle<JSPluralRules> initPluralRules =
91 JSPluralRules::InitializePluralRules(thread, pluralRules, localeStr, optionHandle);
92 EXPECT_TRUE(*initPluralRules != nullptr);
93
94 JSHandle<EcmaString> resultLocaleStr(thread, initPluralRules->GetLocale().GetTaggedObject());
95 EXPECT_STREQ("en", EcmaStringAccessor(resultLocaleStr).ToCString().c_str());
96 EXPECT_EQ(initPluralRules->GetType(), TypeOption::CARDINAL);
97 EXPECT_EQ(initPluralRules->GetRoundingType(), RoundingType::FRACTIONDIGITS);
98 EXPECT_EQ(initPluralRules->GetMinimumIntegerDigits().GetInt(), 1); // 1 : 1 default minimum integer
99 EXPECT_EQ(initPluralRules->GetMinimumFractionDigits().GetInt(), 0); // 0 : 0 default minimum fraction
100 EXPECT_EQ(initPluralRules->GetMaximumFractionDigits().GetInt(), 3); // 3 : 3 default maximum fraction
101 EXPECT_EQ(initPluralRules->GetMinimumSignificantDigits().GetInt(), 0); // 0 : 0 default minimum sigfraction
102 EXPECT_EQ(initPluralRules->GetMaximumSignificantDigits().GetInt(), 0); // 0 : 0 default maximum sigfraction
103 }
104
HWTEST_F_L0(JSPluralRulesTest,ResolvePlural)105 HWTEST_F_L0(JSPluralRulesTest, ResolvePlural)
106 {
107 double n = base::NAN_VALUE;
108 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
109 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
110 auto globalConst = thread->GlobalConstants();
111 JSHandle<JSTaggedValue> optionHandle(thread, JSTaggedValue::Undefined());
112 JSHandle<JSTaggedValue> typeKey = globalConst->GetHandledStyleString();
113 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("ordinal"));
114 JSHandle<JSTaggedValue> localeStr(factory->NewFromASCII("en-US"));
115
116 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
117 JSHandle<JSTaggedValue> ctor = env->GetPluralRulesFunction();
118 JSHandle<JSPluralRules> pluralRules =
119 JSHandle<JSPluralRules>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
120 JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
121 JSObject::SetProperty(thread, optionsObj, typeKey, typeValue);
122 // initialize pluralRules
123 JSHandle<JSPluralRules> initPluralRules =
124 JSPluralRules::InitializePluralRules(thread, pluralRules, localeStr, optionHandle);
125 EXPECT_TRUE(*initPluralRules != nullptr);
126 // resolve plural nan
127 JSHandle<EcmaString> resolveRules = JSPluralRules::ResolvePlural(thread, initPluralRules, n);
128 EXPECT_STREQ("other", EcmaStringAccessor(resolveRules).ToCString().c_str());
129 }
130 } // namespace panda::test
131