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