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_locale.h"
17 
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/js_locale.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 BuiltinsLocaleTest : public BaseTestWithScope<true> {
27 };
28 
29 // new locale( [ options ] )
HWTEST_F_L0(BuiltinsLocaleTest, LocaleConstructor)30 HWTEST_F_L0(BuiltinsLocaleTest, LocaleConstructor)
31 {
32     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
33     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
34     JSHandle<JSFunction> newTarget(env->GetLocaleFunction());
35     JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
36 
37     JSHandle<JSTaggedValue> languageKey = thread->GlobalConstants()->GetHandledLanguageString();
38     JSHandle<JSTaggedValue> regionKey = thread->GlobalConstants()->GetHandledRegionString();
39     JSHandle<JSTaggedValue> numericKey = thread->GlobalConstants()->GetHandledNumericString();
40     JSHandle<JSTaggedValue> scriptKey = thread->GlobalConstants()->GetHandledScriptString();
41     JSHandle<JSTaggedValue> languageValue(factory->NewFromASCII("cn"));
42     JSHandle<JSTaggedValue> regionValue(factory->NewFromASCII("CN"));
43     JSHandle<JSTaggedValue> scriptValue(factory->NewFromASCII("Chin"));
44     JSHandle<JSTaggedValue> numericValue(thread, JSTaggedValue::True());
45     JSHandle<JSTaggedValue> localeString(factory->NewFromASCII("zh-Hans-CN"));
46 
47     JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
48     JSObject::SetProperty(thread, optionsObj, numericKey, numericValue);
49     JSObject::SetProperty(thread, optionsObj, regionKey, regionValue);
50     JSObject::SetProperty(thread, optionsObj, languageKey, languageValue);
51     JSObject::SetProperty(thread, optionsObj, scriptKey, scriptValue);
52 
53     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
54     ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
55     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
56     ecmaRuntimeCallInfo->SetCallArg(0, localeString.GetTaggedValue());
57     ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
58 
59     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
60     JSTaggedValue result = BuiltinsLocale::LocaleConstructor(ecmaRuntimeCallInfo);
61     TestHelper::TearDownFrame(thread, prev);
62 
63     EXPECT_TRUE(result.IsJSLocale());
64 }
65 
JSLocaleCreateWithOptionTest(JSThread *thread)66 static JSTaggedValue JSLocaleCreateWithOptionTest(JSThread *thread)
67 {
68     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
69     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
70     JSHandle<JSFunction> newTarget(env->GetLocaleFunction());
71     JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
72 
73     JSHandle<JSTaggedValue> languageKey = thread->GlobalConstants()->GetHandledLanguageString();
74     JSHandle<JSTaggedValue> regionKey = thread->GlobalConstants()->GetHandledRegionString();
75     JSHandle<JSTaggedValue> scriptKey = thread->GlobalConstants()->GetHandledScriptString();
76     JSHandle<JSTaggedValue> languageValue(factory->NewFromASCII("en"));
77     JSHandle<JSTaggedValue> regionValue(factory->NewFromASCII("US"));
78     JSHandle<JSTaggedValue> scriptValue(factory->NewFromASCII("Latn"));
79     JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-Latn-US"));
80     // set option(language, region, script)
81     JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
82     JSObject::SetProperty(thread, optionsObj, languageKey, languageValue);
83     JSObject::SetProperty(thread, optionsObj, regionKey, regionValue);
84     JSObject::SetProperty(thread, optionsObj, scriptKey, scriptValue);
85 
86     JSHandle<JSTaggedValue> calendarValue(factory->NewFromASCII("chinese"));
87     JSHandle<JSTaggedValue> calendarKey = thread->GlobalConstants()->GetHandledCalendarString();
88     JSObject::SetProperty(thread, optionsObj, calendarKey, calendarValue); // test chinese calendar
89 
90     JSHandle<JSTaggedValue> hourCycleKey = thread->GlobalConstants()->GetHandledHourCycleString();
91     JSHandle<JSTaggedValue> hourCycleValue(factory->NewFromASCII("h24"));
92     JSObject::SetProperty(thread, optionsObj, hourCycleKey, hourCycleValue); // test h24
93 
94     JSHandle<JSTaggedValue> numericKey = thread->GlobalConstants()->GetHandledNumericString();
95     JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("true"));
96     JSObject::SetProperty(thread, optionsObj, numericKey, numericValue); // test true
97 
98     JSHandle<JSTaggedValue> numberingSystemKey = thread->GlobalConstants()->GetHandledNumberingSystemString();
99     JSHandle<JSTaggedValue> numberingSystemValue(factory->NewFromASCII("mong"));
100     JSObject::SetProperty(thread, optionsObj, numberingSystemKey, numberingSystemValue); // test mong
101 
102     JSHandle<JSTaggedValue> collationKey = thread->GlobalConstants()->GetHandledCollationString();
103     JSHandle<JSTaggedValue> collationValue(factory->NewFromASCII("compat"));
104     JSObject::SetProperty(thread, optionsObj, collationKey, collationValue); // test compat
105 
106     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
107     ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
108     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
109     ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
110     ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
111 
112     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
113     JSTaggedValue result = BuiltinsLocale::LocaleConstructor(ecmaRuntimeCallInfo);
114     TestHelper::TearDownFrame(thread, prev);
115     return result;
116 }
117 
118 enum class AlgorithmType {
119     TO_STRING,
120     GET_BASE_NAME,
121     GET_HOUR_CYCLE,
122     GET_CALENDAR,
123     GET_CASE_FIRST,
124     GET_COLLATION,
125     GET_NUMERIC,
126     GET_NUMBERING_SYSTEM,
127     GET_LANGUAGE,
128     GET_SCRIPT,
129     GET_REGION,
130     MAXI_MIZE,
131     MINI_MIZE,
132 };
133 
AlgorithmOther(EcmaRuntimeCallInfo *ecmaRuntimeCallInfo, AlgorithmType type)134 JSTaggedValue AlgorithmOther(EcmaRuntimeCallInfo *ecmaRuntimeCallInfo, AlgorithmType type)
135 {
136     switch (type) {
137         case AlgorithmType::TO_STRING:
138             return BuiltinsLocale::ToString(ecmaRuntimeCallInfo);
139         case AlgorithmType::MAXI_MIZE:
140             return BuiltinsLocale::Maximize(ecmaRuntimeCallInfo);
141         case AlgorithmType::MINI_MIZE:
142             return BuiltinsLocale::Minimize(ecmaRuntimeCallInfo);
143         default:
144             return JSTaggedValue();
145     }
146 }
147 
LocaleAlgorithm(JSThread *thread, JSTaggedValue thisArg, std::vector<JSTaggedValue>& args, int32_t argLen, AlgorithmType type)148 JSTaggedValue LocaleAlgorithm(JSThread *thread, JSTaggedValue thisArg, std::vector<JSTaggedValue>& args,
149     int32_t argLen, AlgorithmType type)
150 {
151     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), argLen);
152     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
153     ecmaRuntimeCallInfo->SetThis(thisArg);
154     for (size_t i = 0; i < args.size(); i++) {
155         ecmaRuntimeCallInfo->SetCallArg(i, args[i]);
156     }
157     auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
158     JSTaggedValue result;
159     switch (type) {
160         case AlgorithmType::GET_BASE_NAME:
161             result = BuiltinsLocale::GetBaseName(ecmaRuntimeCallInfo);
162             break;
163         case AlgorithmType::GET_HOUR_CYCLE:
164             result = BuiltinsLocale::GetHourCycle(ecmaRuntimeCallInfo);
165             break;
166         case AlgorithmType::GET_CALENDAR:
167             result = BuiltinsLocale::GetCalendar(ecmaRuntimeCallInfo);
168             break;
169         case AlgorithmType::GET_CASE_FIRST:
170             result = BuiltinsLocale::GetCaseFirst(ecmaRuntimeCallInfo);
171             break;
172         case AlgorithmType::GET_COLLATION:
173             result = BuiltinsLocale::GetCollation(ecmaRuntimeCallInfo);
174             break;
175         case AlgorithmType::GET_NUMERIC:
176             result = BuiltinsLocale::GetNumeric(ecmaRuntimeCallInfo);
177             break;
178         case AlgorithmType::GET_NUMBERING_SYSTEM:
179             result = BuiltinsLocale::GetNumberingSystem(ecmaRuntimeCallInfo);
180             break;
181         case AlgorithmType::GET_LANGUAGE:
182             result = BuiltinsLocale::GetLanguage(ecmaRuntimeCallInfo);
183             break;
184         case AlgorithmType::GET_SCRIPT:
185             result = BuiltinsLocale::GetScript(ecmaRuntimeCallInfo);
186             break;
187         case AlgorithmType::GET_REGION:
188             result = BuiltinsLocale::GetRegion(ecmaRuntimeCallInfo);
189             break;
190         default:
191             result = AlgorithmOther(ecmaRuntimeCallInfo, type);
192             break;
193     }
194     TestHelper::TearDownFrame(thread, prev);
195     return result;
196 }
197 
HWTEST_F_L0(BuiltinsLocaleTest, ToString)198 HWTEST_F_L0(BuiltinsLocaleTest, ToString)
199 {
200     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
201     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionTest(thread));
202     std::vector<JSTaggedValue> args{};
203     auto result = LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::TO_STRING); // 4 : arg len
204 
205     EXPECT_TRUE(result.IsString());
206     JSHandle<EcmaString> handleEcmaStr(thread, result);
207     JSHandle<EcmaString> resultStr(
208         factory->NewFromASCII("en-Latn-US-u-ca-chinese-co-compat-hc-h24-kn-nu-mong"));
209     EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr, resultStr), 0);
210 }
211 
HWTEST_F_L0(BuiltinsLocaleTest, GetBaseName)212 HWTEST_F_L0(BuiltinsLocaleTest, GetBaseName)
213 {
214     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionTest(thread));
215 
216     std::vector<JSTaggedValue> args{};
217     auto result =
218         LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::GET_BASE_NAME);  // 4 : arg len
219 
220     EXPECT_TRUE(result.IsString());
221     JSHandle<EcmaString> handleEcmaStr(thread, result);
222     EXPECT_STREQ("en-Latn-US", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
223 }
224 
HWTEST_F_L0(BuiltinsLocaleTest, GetHourCycle)225 HWTEST_F_L0(BuiltinsLocaleTest, GetHourCycle)
226 {
227     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionTest(thread));
228 
229     std::vector<JSTaggedValue> args{};
230     auto result =
231         LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::GET_HOUR_CYCLE);  // 4 : arg len
232 
233     EXPECT_TRUE(result.IsString());
234     JSHandle<EcmaString> handleEcmaStr(thread, result);
235     EXPECT_STREQ("h24", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
236 }
237 
HWTEST_F_L0(BuiltinsLocaleTest, GetCalendar)238 HWTEST_F_L0(BuiltinsLocaleTest, GetCalendar)
239 {
240     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionTest(thread));
241     std::vector<JSTaggedValue> args{};
242     auto result =
243         LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::GET_CALENDAR);  // 4 : arg len
244 
245     EXPECT_TRUE(result.IsString());
246     JSHandle<EcmaString> handleEcmaStr(thread, result);
247     EXPECT_STREQ("chinese", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
248 }
249 
HWTEST_F_L0(BuiltinsLocaleTest, GetCaseFirst)250 HWTEST_F_L0(BuiltinsLocaleTest, GetCaseFirst)
251 {
252     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionTest(thread));
253 
254     std::vector<JSTaggedValue> args{};
255     auto result =
256         LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::GET_CASE_FIRST);  // 4 : arg len
257 
258     EXPECT_TRUE(result.IsUndefined());
259 }
260 
HWTEST_F_L0(BuiltinsLocaleTest, GetCollation)261 HWTEST_F_L0(BuiltinsLocaleTest, GetCollation)
262 {
263     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionTest(thread));
264 
265     std::vector<JSTaggedValue> args{};
266     auto result =
267         LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::GET_COLLATION);  // 4 : arg len
268 
269     EXPECT_TRUE(result.IsString());
270     JSHandle<EcmaString> handleEcmaStr(thread, result);
271     EXPECT_STREQ("compat", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
272 }
273 
HWTEST_F_L0(BuiltinsLocaleTest, GetNumeric)274 HWTEST_F_L0(BuiltinsLocaleTest, GetNumeric)
275 {
276     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionTest(thread));
277 
278     std::vector<JSTaggedValue> args{};
279     auto result =
280         LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::GET_NUMERIC);  // 4 : arg len
281 
282     EXPECT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
283 }
284 
HWTEST_F_L0(BuiltinsLocaleTest, GetNumberingSystem)285 HWTEST_F_L0(BuiltinsLocaleTest, GetNumberingSystem)
286 {
287     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionTest(thread));
288 
289     std::vector<JSTaggedValue> args{};
290     auto result = LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4,
291                                   AlgorithmType::GET_NUMBERING_SYSTEM);  // 4 : arg len
292 
293     EXPECT_TRUE(result.IsString());
294     JSHandle<EcmaString> handleEcmaStr(thread, result);
295     EXPECT_STREQ("mong", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
296 }
297 
HWTEST_F_L0(BuiltinsLocaleTest, GetLanguage)298 HWTEST_F_L0(BuiltinsLocaleTest, GetLanguage)
299 {
300     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionTest(thread));
301 
302     std::vector<JSTaggedValue> args{};
303     auto result =
304         LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::GET_LANGUAGE);  // 4 : arg len
305 
306     EXPECT_TRUE(result.IsString());
307     JSHandle<EcmaString> handleEcmaStr(thread, result);
308     EXPECT_STREQ("en", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
309 }
310 
HWTEST_F_L0(BuiltinsLocaleTest, GetScript)311 HWTEST_F_L0(BuiltinsLocaleTest, GetScript)
312 {
313     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionTest(thread));
314 
315     std::vector<JSTaggedValue> args{};
316     auto result = LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::GET_SCRIPT); // 4 : arg len
317 
318     EXPECT_TRUE(result.IsString());
319     JSHandle<EcmaString> handleEcmaStr(thread, result);
320     EXPECT_STREQ("Latn", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
321 }
322 
HWTEST_F_L0(BuiltinsLocaleTest, GetRegion)323 HWTEST_F_L0(BuiltinsLocaleTest, GetRegion)
324 {
325     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionTest(thread));
326 
327     std::vector<JSTaggedValue> args{};
328     auto result = LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::GET_REGION); // 4 : arg len
329 
330     EXPECT_TRUE(result.IsString());
331     JSHandle<EcmaString> handleEcmaStr(thread, result);
332     EXPECT_STREQ("US", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
333 }
334 
JSLocaleCreateWithOptionsTagsTest(JSThread *thread, JSHandle<JSTaggedValue> &value)335 static JSTaggedValue JSLocaleCreateWithOptionsTagsTest(JSThread *thread, JSHandle<JSTaggedValue> &value)
336 {
337     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
338     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
339     JSHandle<JSFunction> newTarget(env->GetLocaleFunction());
340     JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
341 
342     JSHandle<JSTaggedValue> languageKey = thread->GlobalConstants()->GetHandledLanguageString();
343     JSHandle<JSTaggedValue> languageValue = JSHandle<JSTaggedValue>(value);
344     JSHandle<EcmaString> locale = factory->NewFromASCII("zh");
345     // set option(language)
346     JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
347     JSObject::SetProperty(thread, optionsObj, languageKey, languageValue);
348 
349     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
350     ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
351     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
352     ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
353     ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
354 
355     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
356     JSTaggedValue result = BuiltinsLocale::LocaleConstructor(ecmaRuntimeCallInfo);
357     EXPECT_TRUE(result.IsJSLocale());
358     TestHelper::TearDownFrame(thread, prev);
359     return result;
360 }
361 
HWTEST_F_L0(BuiltinsLocaleTest, Maximize_001)362 HWTEST_F_L0(BuiltinsLocaleTest, Maximize_001)
363 {
364     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
365     // set language,then call Maximize function get language,script and region
366     JSHandle<JSTaggedValue> languageValue(factory->NewFromASCII("zh"));
367     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionsTagsTest(thread, languageValue));
368 
369     std::vector<JSTaggedValue> args{};
370     auto resultObj =
371         LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::MAXI_MIZE);  // 4 : arg len
372 
373     JSHandle<JSLocale> resultLocale(thread, resultObj);
374     auto result =
375         LocaleAlgorithm(thread, resultLocale.GetTaggedValue(), args, 4, AlgorithmType::GET_BASE_NAME);  // 4 : arg len
376 
377     EXPECT_TRUE(result.IsString());
378     JSHandle<EcmaString> handleEcmaStr(thread, result);
379     EXPECT_STREQ("zh-Hans-CN", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
380 }
381 
HWTEST_F_L0(BuiltinsLocaleTest, Maximize_002)382 HWTEST_F_L0(BuiltinsLocaleTest, Maximize_002)
383 {
384     // set language,script,region and numeric and it's maximized
385     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionTest(thread));
386 
387     std::vector<JSTaggedValue> args{};
388     auto resultObj =
389         LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::MAXI_MIZE);  // 4 : arg len
390     JSHandle<JSLocale> resultLocale(thread, resultObj);
391     auto result =
392         LocaleAlgorithm(thread, resultLocale.GetTaggedValue(), args, 4, AlgorithmType::GET_BASE_NAME);  // 4 : arg len
393 
394     EXPECT_TRUE(result.IsString());
395     JSHandle<EcmaString> handleEcmaStr(thread, result);
396     EXPECT_STREQ("en-Latn-US", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
397 }
398 
HWTEST_F_L0(BuiltinsLocaleTest, Minimize_001)399 HWTEST_F_L0(BuiltinsLocaleTest, Minimize_001)
400 {
401     // set language, script, region, and it's maximized,then call Minimize function get language
402     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionTest(thread));
403 
404     std::vector<JSTaggedValue> args{};
405     auto resultObj =
406         LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::MINI_MIZE);  // 4 : arg len
407 
408     JSHandle<JSLocale> resultLocale(thread, resultObj);
409     auto result =
410         LocaleAlgorithm(thread, resultLocale.GetTaggedValue(), args, 4, AlgorithmType::GET_BASE_NAME);  // 4 : arg len
411 
412     EXPECT_TRUE(result.IsString());
413     JSHandle<EcmaString> handleEcmaStr(thread, result);
414     EXPECT_STREQ("en", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
415 }
416 
HWTEST_F_L0(BuiltinsLocaleTest, Minimize_002)417 HWTEST_F_L0(BuiltinsLocaleTest, Minimize_002)
418 {
419     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
420     // set language and it's minimized
421     JSHandle<JSTaggedValue> languageValue(factory->NewFromASCII("zh"));
422     JSHandle<JSLocale> jsLocale = JSHandle<JSLocale>(thread, JSLocaleCreateWithOptionsTagsTest(thread, languageValue));
423 
424     std::vector<JSTaggedValue> args{};
425     auto resultObj =
426         LocaleAlgorithm(thread, jsLocale.GetTaggedValue(), args, 4, AlgorithmType::MINI_MIZE);  // 4 : arg len
427 
428     JSHandle<JSLocale> resultLocale(thread, resultObj);
429     auto result =
430         LocaleAlgorithm(thread, resultLocale.GetTaggedValue(), args, 4, AlgorithmType::TO_STRING);  // 4 : arg len
431 
432     EXPECT_TRUE(result.IsString());
433     JSHandle<EcmaString> handleEcmaStr(thread, result);
434     EXPECT_STREQ("zh", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
435 }
436 
437 // test NormalizeKeywordValue(kf is not setted "yes")
HWTEST_F_L0(BuiltinsLocaleTest, NormalizeKeywordValue)438 HWTEST_F_L0(BuiltinsLocaleTest, NormalizeKeywordValue)
439 {
440     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
441     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
442     JSHandle<JSFunction> newTarget(env->GetLocaleFunction());
443     JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
444 
445     JSHandle<JSTaggedValue> caseFirstKey = thread->GlobalConstants()->GetHandledCaseFirstString();
446     JSHandle<JSTaggedValue> caseFirstValue(factory->NewFromASCII("false"));
447     JSHandle<EcmaString> locale = factory->NewFromASCII("en-US");
448 
449     JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
450     JSObject::SetProperty(thread, optionsObj, caseFirstKey, caseFirstValue);
451 
452     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
453     ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
454     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
455     ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
456     ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
457 
458     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
459     JSTaggedValue result = BuiltinsLocale::LocaleConstructor(ecmaRuntimeCallInfo);
460     TestHelper::TearDownFrame(thread, prev);
461 
462     JSHandle<JSLocale> jsInitLocale(thread, result);
463     JSTaggedValue keyWords = JSLocale::NormalizeKeywordValue(thread, jsInitLocale, "kf");
464     EXPECT_STREQ("false", EcmaStringAccessor(keyWords).ToCString().c_str());
465 }
466 }  // namespace panda::test
467