• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 testing::Test {
27 public:
SetUpTestCase()28     static void SetUpTestCase()
29     {
30         GTEST_LOG_(INFO) << "SetUpTestCase";
31     }
32 
TearDownTestCase()33     static void TearDownTestCase()
34     {
35         GTEST_LOG_(INFO) << "TearDownCase";
36     }
37 
SetUp()38     void SetUp() override
39     {
40         JSRuntimeOptions options;
41 #if PANDA_TARGET_LINUX
42         // for consistency requirement, use ohos_icu4j/data/icudt67l.dat as icu-data-path
43         options.SetIcuDataPath(ICU_PATH);
44 #endif
45         options.SetEnableForceGC(true);
46         instance = JSNApi::CreateEcmaVM(options);
47         instance->SetEnableForceGC(true);
48         ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
49         thread = instance->GetJSThread();
50         scope = new EcmaHandleScope(thread);
51     }
52 
TearDown()53     void TearDown() override
54     {
55         TestHelper::DestroyEcmaVMWithScope(instance, scope);
56     }
57 
58     EcmaVM *instance {nullptr};
59     ecmascript::EcmaHandleScope *scope {nullptr};
60     JSThread *thread {nullptr};
61 };
62 
HWTEST_F_L0(JSPluralRulesTest,GetIcuPluralRules)63 HWTEST_F_L0(JSPluralRulesTest, GetIcuPluralRules)
64 {
65     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
66     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
67 
68     JSHandle<JSTaggedValue> ctor = env->GetPluralRulesFunction();
69     JSHandle<JSPluralRules> pluralRules =
70         JSHandle<JSPluralRules>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
71     // Create PluralRules
72     icu::Locale icuLocale("en", "US");
73     UErrorCode status = U_ZERO_ERROR;
74     UPluralType icuType = UPLURAL_TYPE_CARDINAL; // Plural rules for cardinal numbers
75     icu::PluralRules *icuPluralRules(icu::PluralRules::forLocale(icuLocale, icuType, status));
76     icu::UnicodeString result1 = icuPluralRules->select(0);
77     JSHandle<EcmaString> stringValue1 = intl::LocaleHelper::UStringToString(thread, result1);
78 
79     JSPluralRules::SetIcuPluralRules(thread, pluralRules, *icuPluralRules, JSPluralRules::FreeIcuPluralRules);
80     icu::PluralRules *getPluralRules = pluralRules->GetIcuPluralRules();
81     icu::UnicodeString result2 = getPluralRules->select(0);
82     JSHandle<EcmaString> stringValue2 = intl::LocaleHelper::UStringToString(thread, result2);
83     EXPECT_EQ(EcmaStringAccessor::StringsAreEqual(*stringValue1, *stringValue2), true);
84     delete icuPluralRules;
85 }
86 
HWTEST_F_L0(JSPluralRulesTest,BuildLocaleSet)87 HWTEST_F_L0(JSPluralRulesTest, BuildLocaleSet)
88 {
89     std::set<std::string> icuAvailableLocales {
90         "en-Latn-US",
91         "zh-Hans-CN",
92         "pt-PT",
93         "de-DE",
94     };
95     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
96     JSHandle<EcmaString> resultStr;
97     JSHandle<EcmaString> localeStr1 = factory->NewFromStdString("en-Latn-US");
98     JSHandle<EcmaString> localeStr2 = factory->NewFromStdString("zh-Hans-CN");
99     JSHandle<EcmaString> localeStr3 = factory->NewFromStdString("pt-PT");
100     JSHandle<EcmaString> localeStr4 = factory->NewFromStdString("de-DE");
101     JSHandle<TaggedArray> localeSet = JSPluralRules::BuildLocaleSet(thread, icuAvailableLocales);
102     EXPECT_EQ(localeSet->GetLength(), 4U);
103 
104     resultStr = JSHandle<EcmaString>(thread, localeSet->Get(0).GetTaggedObject());
105     EXPECT_EQ(EcmaStringAccessor::StringsAreEqual(*resultStr, *localeStr4), true);
106     resultStr = JSHandle<EcmaString>(thread, localeSet->Get(1).GetTaggedObject());
107     EXPECT_EQ(EcmaStringAccessor::StringsAreEqual(*resultStr, *localeStr1), true);
108     resultStr = JSHandle<EcmaString>(thread, localeSet->Get(2).GetTaggedObject());
109     EXPECT_EQ(EcmaStringAccessor::StringsAreEqual(*resultStr, *localeStr3), true);
110     resultStr = JSHandle<EcmaString>(thread, localeSet->Get(3).GetTaggedObject());
111     EXPECT_EQ(EcmaStringAccessor::StringsAreEqual(*resultStr, *localeStr2), true);
112 }
113 
HWTEST_F_L0(JSPluralRulesTest,InitializePluralRules)114 HWTEST_F_L0(JSPluralRulesTest, InitializePluralRules)
115 {
116     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
117     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
118     JSHandle<JSTaggedValue> optionHandle(thread, JSTaggedValue::Undefined());
119 
120     JSHandle<JSTaggedValue> ctor = env->GetPluralRulesFunction();
121     JSHandle<JSPluralRules> pluralRules =
122         JSHandle<JSPluralRules>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
123     JSHandle<JSTaggedValue> localeStr(factory->NewFromASCII("en-GB"));
124     JSHandle<JSPluralRules> initPluralRules =
125         JSPluralRules::InitializePluralRules(thread, pluralRules, localeStr, optionHandle);
126     EXPECT_TRUE(*initPluralRules != nullptr);
127 
128     JSHandle<EcmaString> resultLocaleStr(thread, initPluralRules->GetLocale().GetTaggedObject());
129     EXPECT_STREQ("en", EcmaStringAccessor(resultLocaleStr).ToCString().c_str());
130     EXPECT_EQ(initPluralRules->GetType(), TypeOption::CARDINAL);
131     EXPECT_EQ(initPluralRules->GetRoundingType(), RoundingType::FRACTIONDIGITS);
132     EXPECT_EQ(initPluralRules->GetMinimumIntegerDigits().GetInt(), 1); // 1 : 1 default minimum integer
133     EXPECT_EQ(initPluralRules->GetMinimumFractionDigits().GetInt(), 0); // 0 : 0 default minimum fraction
134     EXPECT_EQ(initPluralRules->GetMaximumFractionDigits().GetInt(), 3); // 3 : 3 default maximum fraction
135     EXPECT_EQ(initPluralRules->GetMinimumSignificantDigits().GetInt(), 0); // 0 : 0 default minimum sigfraction
136     EXPECT_EQ(initPluralRules->GetMaximumSignificantDigits().GetInt(), 0); // 0 : 0 default maximum sigfraction
137 }
138 
HWTEST_F_L0(JSPluralRulesTest,ResolvePlural)139 HWTEST_F_L0(JSPluralRulesTest, ResolvePlural)
140 {
141     double n = base::NAN_VALUE;
142     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
143     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
144     auto globalConst = thread->GlobalConstants();
145     JSHandle<JSTaggedValue> optionHandle(thread, JSTaggedValue::Undefined());
146     JSHandle<JSTaggedValue> typeKey = globalConst->GetHandledStyleString();
147     JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("ordinal"));
148     JSHandle<JSTaggedValue> localeStr(factory->NewFromASCII("en-US"));
149 
150     JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
151     JSHandle<JSTaggedValue> ctor = env->GetPluralRulesFunction();
152     JSHandle<JSPluralRules> pluralRules =
153         JSHandle<JSPluralRules>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
154     JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
155     JSObject::SetProperty(thread, optionsObj, typeKey, typeValue);
156     // initialize pluralRules
157     JSHandle<JSPluralRules> initPluralRules =
158         JSPluralRules::InitializePluralRules(thread, pluralRules, localeStr, optionHandle);
159     EXPECT_TRUE(*initPluralRules != nullptr);
160     // resolve plural nan
161     JSHandle<EcmaString> resolveRules = JSPluralRules::ResolvePlural(thread, initPluralRules, n);
162     EXPECT_STREQ("other", EcmaStringAccessor(resolveRules).ToCString().c_str());
163 }
164 } // namespace panda::test
165