• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
22 using namespace panda::ecmascript;
23 using namespace panda::ecmascript::builtins;
24 
25 namespace panda::test {
26 class BuiltinsPluralRulesTest : 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 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     EcmaHandleScope *scope {nullptr};
60     JSThread *thread {nullptr};
61 };
62 
63 // new DateTimeFormat(newTarget is defined)
HWTEST_F_L0(BuiltinsPluralRulesTest,PluralRulesConstructor)64 HWTEST_F_L0(BuiltinsPluralRulesTest, PluralRulesConstructor)
65 {
66     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
67     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
68     JSHandle<JSFunction> newTarget(env->GetPluralRulesFunction());
69 
70     JSHandle<JSTaggedValue> localesString(factory->NewFromASCII("en-US"));
71     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
72     ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
73     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
74     ecmaRuntimeCallInfo->SetCallArg(0, localesString.GetTaggedValue());
75     // option tag is default value
76     ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined());
77 
78     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
79     JSTaggedValue result = BuiltinsPluralRules::PluralRulesConstructor(ecmaRuntimeCallInfo);
80     TestHelper::TearDownFrame(thread, prev);
81 
82     EXPECT_TRUE(result.IsJSPluralRules());
83 }
84 
JSPluralRulesCreateWithLocaleTest(JSThread * thread,JSHandle<JSTaggedValue> & locale,JSHandle<JSTaggedValue> & typeValue)85 static JSTaggedValue JSPluralRulesCreateWithLocaleTest(JSThread *thread, JSHandle<JSTaggedValue> &locale,
86                                                        JSHandle<JSTaggedValue> &typeValue)
87 {
88     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
89     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
90     JSHandle<JSFunction> newTarget(env->GetPluralRulesFunction());
91     JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
92     JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
93 
94     JSHandle<JSTaggedValue> typeKey = thread->GlobalConstants()->GetHandledTypeString();
95     JSObject::SetProperty(thread, optionsObj, typeKey, typeValue);
96 
97     JSHandle<JSTaggedValue> localesString = locale;
98     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
99     ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
100     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
101     ecmaRuntimeCallInfo->SetCallArg(0, localesString.GetTaggedValue());
102     ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
103 
104     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
105     JSTaggedValue result = BuiltinsPluralRules::PluralRulesConstructor(ecmaRuntimeCallInfo);
106     TestHelper::TearDownFrame(thread, prev);
107 
108     EXPECT_TRUE(result.IsJSPluralRules());
109     return result;
110 }
111 
112 // select(0, type(cardinal))
HWTEST_F_L0(BuiltinsPluralRulesTest,Select_001)113 HWTEST_F_L0(BuiltinsPluralRulesTest, Select_001)
114 {
115     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
116     JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
117     JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("cardinal"));
118     JSHandle<JSPluralRules> jsPluralRules =
119         JSHandle<JSPluralRules>(thread, JSPluralRulesCreateWithLocaleTest(thread, locale, typeValue));
120 
121     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(0));
122     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
123     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
124     ecmaRuntimeCallInfo->SetThis(jsPluralRules.GetTaggedValue());
125     ecmaRuntimeCallInfo->SetCallArg(0, value.GetTaggedValue());
126 
127     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
128     JSTaggedValue result = BuiltinsPluralRules::Select(ecmaRuntimeCallInfo);
129     TestHelper::TearDownFrame(thread, prev);
130 
131     EXPECT_TRUE(result.IsString());
132     JSHandle<EcmaString> handleEcmaStr(thread, result);
133     EXPECT_STREQ("other", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
134 }
135 
136 // select(1, type(cardinal))
HWTEST_F_L0(BuiltinsPluralRulesTest,Select_002)137 HWTEST_F_L0(BuiltinsPluralRulesTest, Select_002)
138 {
139     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
140     JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
141     JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("cardinal"));
142     JSHandle<JSPluralRules> jsPluralRules =
143         JSHandle<JSPluralRules>(thread, JSPluralRulesCreateWithLocaleTest(thread, locale, typeValue));
144 
145     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
146     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
147     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
148     ecmaRuntimeCallInfo->SetThis(jsPluralRules.GetTaggedValue());
149     ecmaRuntimeCallInfo->SetCallArg(0, value.GetTaggedValue());
150 
151     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
152     JSTaggedValue result = BuiltinsPluralRules::Select(ecmaRuntimeCallInfo);
153     TestHelper::TearDownFrame(thread, prev);
154 
155     EXPECT_TRUE(result.IsString());
156     JSHandle<EcmaString> handleEcmaStr(thread, result);
157     EXPECT_STREQ("one", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
158 }
159 
160 // select(2, type(cardinal))
HWTEST_F_L0(BuiltinsPluralRulesTest,Select_003)161 HWTEST_F_L0(BuiltinsPluralRulesTest, Select_003)
162 {
163     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
164     JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
165     JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("cardinal"));
166     JSHandle<JSPluralRules> jsPluralRules =
167         JSHandle<JSPluralRules>(thread, JSPluralRulesCreateWithLocaleTest(thread, locale, typeValue));
168 
169     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(2));
170     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
171     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
172     ecmaRuntimeCallInfo->SetThis(jsPluralRules.GetTaggedValue());
173     ecmaRuntimeCallInfo->SetCallArg(0, value.GetTaggedValue());
174 
175     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
176     JSTaggedValue result = BuiltinsPluralRules::Select(ecmaRuntimeCallInfo);
177     TestHelper::TearDownFrame(thread, prev);
178 
179     EXPECT_TRUE(result.IsString());
180     JSHandle<EcmaString> handleEcmaStr(thread, result);
181     EXPECT_STREQ("other", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
182 }
183 
184 // select(3, type(ordinal))
HWTEST_F_L0(BuiltinsPluralRulesTest,Select_004)185 HWTEST_F_L0(BuiltinsPluralRulesTest, Select_004)
186 {
187     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
188     JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
189     JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("ordinal"));
190     JSHandle<JSPluralRules> jsPluralRules =
191         JSHandle<JSPluralRules>(thread, JSPluralRulesCreateWithLocaleTest(thread, locale, typeValue));
192 
193     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(3));
194     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
195     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
196     ecmaRuntimeCallInfo->SetThis(jsPluralRules.GetTaggedValue());
197     ecmaRuntimeCallInfo->SetCallArg(0, value.GetTaggedValue());
198 
199     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
200     JSTaggedValue result = BuiltinsPluralRules::Select(ecmaRuntimeCallInfo);
201     TestHelper::TearDownFrame(thread, prev);
202 
203     EXPECT_TRUE(result.IsString());
204     JSHandle<EcmaString> handleEcmaStr(thread, result);
205     EXPECT_STREQ("few", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
206 }
207 
208 // select(2, type(ordinal))
HWTEST_F_L0(BuiltinsPluralRulesTest,Select_005)209 HWTEST_F_L0(BuiltinsPluralRulesTest, Select_005)
210 {
211     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
212     JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
213     JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("ordinal"));
214     JSHandle<JSPluralRules> jsPluralRules =
215         JSHandle<JSPluralRules>(thread, JSPluralRulesCreateWithLocaleTest(thread, locale, typeValue));
216 
217     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(2));
218     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
219     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
220     ecmaRuntimeCallInfo->SetThis(jsPluralRules.GetTaggedValue());
221     ecmaRuntimeCallInfo->SetCallArg(0, value.GetTaggedValue());
222 
223     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
224     JSTaggedValue result = BuiltinsPluralRules::Select(ecmaRuntimeCallInfo);
225     TestHelper::TearDownFrame(thread, prev);
226 
227     EXPECT_TRUE(result.IsString());
228     JSHandle<EcmaString> handleEcmaStr(thread, result);
229     EXPECT_STREQ("two", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
230 }
231 
232 // select(0, type(ordinal))
HWTEST_F_L0(BuiltinsPluralRulesTest,Select_006)233 HWTEST_F_L0(BuiltinsPluralRulesTest, Select_006)
234 {
235     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
236     JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
237     JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("ordinal"));
238     JSHandle<JSPluralRules> jsPluralRules =
239         JSHandle<JSPluralRules>(thread, JSPluralRulesCreateWithLocaleTest(thread, locale, typeValue));
240 
241     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(0));
242     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
243     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
244     ecmaRuntimeCallInfo->SetThis(jsPluralRules.GetTaggedValue());
245     ecmaRuntimeCallInfo->SetCallArg(0, value.GetTaggedValue());
246 
247     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
248     JSTaggedValue result = BuiltinsPluralRules::Select(ecmaRuntimeCallInfo);
249     TestHelper::TearDownFrame(thread, prev);
250 
251     EXPECT_TRUE(result.IsString());
252     JSHandle<EcmaString> handleEcmaStr(thread, result);
253     EXPECT_STREQ("other", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
254 }
255 
256 // select(1, type(ordinal))
HWTEST_F_L0(BuiltinsPluralRulesTest,Select_007)257 HWTEST_F_L0(BuiltinsPluralRulesTest, Select_007)
258 {
259     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
260     JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
261     JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("ordinal"));
262     JSHandle<JSPluralRules> jsPluralRules =
263         JSHandle<JSPluralRules>(thread, JSPluralRulesCreateWithLocaleTest(thread, locale, typeValue));
264 
265     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
266     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
267     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
268     ecmaRuntimeCallInfo->SetThis(jsPluralRules.GetTaggedValue());
269     ecmaRuntimeCallInfo->SetCallArg(0, value.GetTaggedValue());
270 
271     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
272     JSTaggedValue result = BuiltinsPluralRules::Select(ecmaRuntimeCallInfo);
273     TestHelper::TearDownFrame(thread, prev);
274 
275     EXPECT_TRUE(result.IsString());
276     JSHandle<EcmaString> handleEcmaStr(thread, result);
277     EXPECT_STREQ("one", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
278 }
279 
HWTEST_F_L0(BuiltinsPluralRulesTest,SupportedLocalesOf)280 HWTEST_F_L0(BuiltinsPluralRulesTest, SupportedLocalesOf)
281 {
282     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
283     JSHandle<JSTaggedValue> locale(factory->NewFromASCII("id-u-co-pinyin-de-ID"));
284 
285     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
286     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
287     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
288     ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
289     // set the tag is default value
290     ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined());
291 
292     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
293     JSTaggedValue resultArr = BuiltinsPluralRules::SupportedLocalesOf(ecmaRuntimeCallInfo);
294     TestHelper::TearDownFrame(thread, prev);
295 
296     JSHandle<JSArray> resultHandle(thread, resultArr);
297     JSHandle<TaggedArray> elements(thread, resultHandle->GetElements());
298     EXPECT_EQ(elements->GetLength(), 1U);
299     JSHandle<EcmaString> handleEcmaStr(thread, elements->Get(0));
300     EXPECT_STREQ("id-u-co-pinyin-de-id", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
301 }
302 
HWTEST_F_L0(BuiltinsPluralRulesTest,ResolvedOptions)303 HWTEST_F_L0(BuiltinsPluralRulesTest, ResolvedOptions)
304 {
305     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
306     auto globalConst = thread->GlobalConstants();
307     JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
308     JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("ordinal"));
309     JSHandle<JSPluralRules> jsPluralRules =
310         JSHandle<JSPluralRules>(thread, JSPluralRulesCreateWithLocaleTest(thread, locale, typeValue));
311 
312     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
313     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
314     ecmaRuntimeCallInfo->SetThis(jsPluralRules.GetTaggedValue());
315 
316     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
317     JSTaggedValue result = BuiltinsPluralRules::ResolvedOptions(ecmaRuntimeCallInfo);
318     TestHelper::TearDownFrame(thread, prev);
319 
320     JSHandle<JSTaggedValue> resultObj =
321         JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<JSTaggedType>(result.GetRawData())));
322     // judge whether the properties of the object are the same as those of jspluralrulesformat tag
323     JSHandle<JSTaggedValue> localeKey = globalConst->GetHandledLocaleString();
324     JSHandle<JSTaggedValue> localeValue(factory->NewFromASCII("en"));
325     EXPECT_EQ(JSTaggedValue::SameValue(
326         JSObject::GetProperty(thread, resultObj, localeKey).GetValue(), localeValue), true);
327     JSHandle<JSTaggedValue> typeKey = globalConst->GetHandledTypeString();
328     EXPECT_EQ(JSTaggedValue::SameValue(
329         JSObject::GetProperty(thread, resultObj, typeKey).GetValue(), typeValue), true);
330 }
331 } // namespace panda::test
332