• 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/global_env.h"
18 #include "ecmascript/js_date.h"
19 #include "ecmascript/js_date_time_format.h"
20 #include "ecmascript/js_locale.h"
21 #include "ecmascript/object_factory-inl.h"
22 #include "ecmascript/tests/ecma_test_common.h"
23 
24 using namespace panda;
25 using namespace panda::ecmascript;
26 using namespace panda::ecmascript::base;
27 using LocaleHelper = panda::ecmascript::intl::LocaleHelper;
28 
29 namespace panda::test {
30 class JSDateTimeFormatTest : public BaseTestWithScope<true> {
31 };
32 
HWTEST_F_L0(JSDateTimeFormatTest,FormatDateTime_002)33 HWTEST_F_L0(JSDateTimeFormatTest, FormatDateTime_002)
34 {
35     auto vm = thread->GetEcmaVM();
36     auto factory = vm->GetFactory();
37     auto env = vm->GetGlobalEnv();
38     auto globalConst = thread->GlobalConstants();
39 
40     icu::Locale icuLocale("zh", "Hans", "Cn");
41     JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
42     JSHandle<JSObject> options = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
43     JSHandle<JSTaggedValue> hourCycleKey = globalConst->GetHandledHourCycleString();
44     JSHandle<JSTaggedValue> hourCycleValue(factory->NewFromASCII("h12"));
45     JSHandle<JSTaggedValue> timeZoneKey = globalConst->GetHandledTimeZoneString();
46     JSHandle<JSTaggedValue> timeZoneValue(factory->NewFromASCII("ETC/GMT-8"));
47     JSObject::SetProperty(thread, options, timeZoneKey, timeZoneValue);
48     JSObject::SetProperty(thread, options, hourCycleKey, hourCycleValue);
49     options = JSDateTimeFormat::ToDateTimeOptions(
50         thread, JSHandle<JSTaggedValue>::Cast(options), RequiredOption::ANY, DefaultsOption::ALL);
51     JSHandle<JSDateTimeFormat> dtf = EcmaTestCommon::CreateDateTimeFormatTest(thread, icuLocale, options);
52 
53     double timeStamp1 = 1653448174000; // test "2022-05-25 11:09:34.000"
54     double timeStamp2 = 1653921012999; // test "2022-05-30 22:30:12.999"
55 
56     // Format to include all options by "DefaultsOption::ALL".
57     JSHandle<EcmaString> dateTimeEcamStr1 = JSDateTimeFormat::FormatDateTime(thread, dtf, timeStamp1);
58     EXPECT_STREQ(LocaleHelper::ConvertToStdString(thread, dateTimeEcamStr1).c_str(), "2022/5/25 上午11:09:34");
59     JSHandle<EcmaString> dateTimeEcamStr2 = JSDateTimeFormat::FormatDateTime(thread, dtf, timeStamp2);
60     EXPECT_STREQ(LocaleHelper::ConvertToStdString(thread, dateTimeEcamStr2).c_str(), "2022/5/30 下午10:30:12");
61 }
62 
FormatCommonSet(JSThread * thread,JSHandle<JSObject> & options,icu::Locale & icuLocale,std::map<std::string,std::string> & dateOptionsMap)63 static JSHandle<JSDateTimeFormat> FormatCommonSet(JSThread *thread, JSHandle<JSObject>& options, icu::Locale& icuLocale,
64     std::map<std::string, std::string>& dateOptionsMap)
65 {
66     std::map<std::string, std::string> timeOptionsMap {
67         { "dayPeriod", "long" },
68         { "hour", "2-digit" },
69         { "minute", "2-digit" },
70         { "second", "2-digit" },
71         { "fractionalSecond", "3" }
72     };
73     EcmaTestCommon::SetDateOptionsTest(thread, options, dateOptionsMap);
74     EcmaTestCommon::SetTimeOptionsTest(thread, options, timeOptionsMap);
75     options = JSDateTimeFormat::ToDateTimeOptions(
76         thread, JSHandle<JSTaggedValue>::Cast(options), RequiredOption::ANY, DefaultsOption::ALL);
77     JSHandle<JSDateTimeFormat> dtf = EcmaTestCommon::CreateDateTimeFormatTest(thread, icuLocale, options);
78     return dtf;
79 }
80 
FormatDateTimeCommon(JSThread * thread,icu::Locale & icuLocale)81 static JSHandle<JSDateTimeFormat> FormatDateTimeCommon(JSThread *thread, icu::Locale& icuLocale)
82 {
83     std::string cycle("h12");
84     std::string zone("ETC/GMT-8");
85     auto options = EcmaTestCommon::SetHourCycleKeyValue(thread, cycle, zone);
86 
87     // Set custom date time format.
88     std::map<std::string, std::string> dateOptionsMap {
89         { "weekday", "long" },
90         { "year", "2-digit" },
91         { "month", "2-digit" },
92         { "day", "2-digit" }
93     };
94     auto dtf = FormatCommonSet(thread, options, icuLocale, dateOptionsMap);
95     return dtf;
96 }
97 
HWTEST_F_L0(JSDateTimeFormatTest,FormatDateTime_003)98 HWTEST_F_L0(JSDateTimeFormatTest, FormatDateTime_003)
99 {
100     icu::Locale icuLocale("zh", "Hans", "Cn");
101 
102     auto dtf = FormatDateTimeCommon(thread, icuLocale);
103     double timeStamp1 = 1653448174000; // test "2022-05-25 11:09:34.000"
104     double timeStamp2 = 1653921012999; // test "2022-05-30 22:30:12.999"
105 
106     JSHandle<EcmaString> dateTimeEcamStr1 = JSDateTimeFormat::FormatDateTime(thread, dtf, timeStamp1);
107     EXPECT_STREQ(LocaleHelper::ConvertToStdString(thread, dateTimeEcamStr1).c_str(),
108         "22年05月25日星期三 上午11:09:34.000");
109     JSHandle<EcmaString> dateTimeEcamStr2 = JSDateTimeFormat::FormatDateTime(thread, dtf, timeStamp2);
110     EXPECT_STREQ(LocaleHelper::ConvertToStdString(thread, dateTimeEcamStr2).c_str(), "22年05月30日星期一 晚上10:30:12.999");
111 }
112 
HWTEST_F_L0(JSDateTimeFormatTest,FormatDateTime_004)113 HWTEST_F_L0(JSDateTimeFormatTest, FormatDateTime_004)
114 {
115     icu::Locale icuLocale("en", "Latn", "US");
116     auto dtf = FormatDateTimeCommon(thread, icuLocale);
117 
118     double timeStamp1 = 1653448174000; // test "2022-05-25 11:09:34.000"
119     double timeStamp2 = 1653921012999; // test "2022-05-30 22:30:12.999"
120 
121     JSHandle<EcmaString> dateTimeEcamStr1 = JSDateTimeFormat::FormatDateTime(thread, dtf, timeStamp1);
122     EXPECT_STREQ(LocaleHelper::ConvertToStdString(thread, dateTimeEcamStr1).c_str(),
123         "Wednesday, 05/25/22, 11:09:34.000 in the morning");
124     JSHandle<EcmaString> dateTimeEcamStr2 = JSDateTimeFormat::FormatDateTime(thread, dtf, timeStamp2);
125     EXPECT_STREQ(LocaleHelper::ConvertToStdString(thread, dateTimeEcamStr2).c_str(),
126         "Monday, 05/30/22, 10:30:12.999 at night");
127 }
128 
GetDateTimePartStringTest(JSThread * thread,JSHandle<JSTaggedValue> key,JSHandle<JSTaggedValue> part)129 std::string GetDateTimePartStringTest(JSThread *thread, JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> part)
130 {
131     JSHandle<JSObject> partObj = JSHandle<JSObject>::Cast(part);
132     JSHandle<JSTaggedValue> partValue = JSObject::GetProperty(thread, partObj, key).GetValue();
133     JSHandle<EcmaString> partEcmaStr = JSHandle<EcmaString>::Cast(partValue);
134     std::string partStr = LocaleHelper::ConvertToStdString(thread, partEcmaStr);
135     return partStr;
136 }
137 
138 /**
139  * @tc.name: FormatDateTimeToParts
140  * @tc.desc: Convert floating-point timestamp to fixed format time date through time date format.
141  *           The "FormatDateTimeToParts" method converts the output result into an array containing various time and
142  *           date attributes.
143  * @tc.type: FUNC
144  * @tc.require:
145  */
HWTEST_F_L0(JSDateTimeFormatTest,FormatDateTimeToParts_001)146 HWTEST_F_L0(JSDateTimeFormatTest, FormatDateTimeToParts_001)
147 {
148     auto globalConst = thread->GlobalConstants();
149 
150     JSHandle<JSTaggedValue> typeKey = globalConst->GetHandledTypeString();
151     JSHandle<JSTaggedValue> valueKey = globalConst->GetHandledValueString();
152 
153     icu::Locale icuLocale("zh", "Hans", "Cn");
154     std::string cycle("h12");
155     std::string zone("ETC/GMT-8");
156     auto options = EcmaTestCommon::SetHourCycleKeyValue(thread, cycle, zone);
157     JSHandle<JSDateTimeFormat> dtf = EcmaTestCommon::CreateDateTimeFormatTest(thread, icuLocale, options);
158 
159     double timeStamp = 1653448174123; // test "2022-05-25 11:09:34.123"
160     // Use default date time format and format date and time to parts.
161     JSHandle<EcmaString> dateTimeEcamStr1 = JSDateTimeFormat::FormatDateTime(thread, dtf, timeStamp);
162     EXPECT_STREQ(LocaleHelper::ConvertToStdString(thread, dateTimeEcamStr1).c_str(), "2022/5/25");
163     JSHandle<JSArray> dateTimeArray1 = JSDateTimeFormat::FormatDateTimeToParts(thread, dtf, timeStamp);
164     auto year = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray1), 0).GetValue();
165     auto literal1 = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray1), 1).GetValue();
166     auto month = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray1), 2).GetValue();
167     auto literal2 = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray1), 3).GetValue();
168     auto day = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray1), 4).GetValue();
169     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, year).c_str(), "year");
170     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, year).c_str(), "2022");
171     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, literal1).c_str(), "literal");
172     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, literal1).c_str(), "/");
173     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, month).c_str(), "month");
174     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, month).c_str(), "5");
175     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, literal2).c_str(), "literal");
176     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, literal2).c_str(), "/");
177     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, day).c_str(), "day");
178     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, day).c_str(), "25");
179 }
180 
CheckOther(JSThread * thread,JSHandle<JSArray> & dateTimeArray,JSHandle<JSTaggedValue> & typeKey,JSHandle<JSTaggedValue> & valueKey)181 void CheckOther(JSThread *thread, JSHandle<JSArray>& dateTimeArray, JSHandle<JSTaggedValue>& typeKey,
182     JSHandle<JSTaggedValue>& valueKey)
183 {
184     auto month = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 2).GetValue();
185     auto literal2 = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 3).GetValue();
186     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, month).c_str(), "month");
187     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, month).c_str(), "05");
188     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, literal2).c_str(), "literal");
189     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, literal2).c_str(), "月");
190 
191     auto day = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 4).GetValue();
192     auto literal3 = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 5).GetValue();
193     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, day).c_str(), "day");
194     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, day).c_str(), "25");
195     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, literal3).c_str(), "literal");
196     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, literal3).c_str(), "日");
197 
198     auto weekday = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 6).GetValue();
199     auto literal4 = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 7).GetValue();
200     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, weekday).c_str(), "weekday");
201     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, weekday).c_str(), "星期三");
202     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, literal4).c_str(), "literal");
203     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, literal4).c_str(), " ");
204 
205     auto dayPeriod = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 8).GetValue();
206     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, dayPeriod).c_str(), "dayPeriod");
207     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, dayPeriod).c_str(), "上午");
208 
209     auto hour = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 9).GetValue();
210     auto literal5 = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 10).GetValue();
211     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, hour).c_str(), "hour");
212     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, hour).c_str(), "11");
213     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, literal5).c_str(), "literal");
214     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, literal5).c_str(), ":");
215     auto minute = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 11).GetValue();
216     auto literal6 = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 12).GetValue();
217     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, minute).c_str(), "minute");
218     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, minute).c_str(), "09");
219     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, literal6).c_str(), "literal");
220     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, literal6).c_str(), ":");
221     auto second = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 13).GetValue();
222     auto literal7 = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 14).GetValue();
223     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, second).c_str(), "second");
224     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, second).c_str(), "34");
225     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, literal7).c_str(), "literal");
226     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, literal7).c_str(), ".");
227     auto fracSec = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 15).GetValue();
228     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, fracSec).c_str(), "fractionalSecond");
229     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, fracSec).c_str(), "123");
230 }
231 
HWTEST_F_L0(JSDateTimeFormatTest,FormatDateTimeToParts_002)232 HWTEST_F_L0(JSDateTimeFormatTest, FormatDateTimeToParts_002)
233 {
234     auto globalConst = thread->GlobalConstants();
235 
236     JSHandle<JSTaggedValue> typeKey = globalConst->GetHandledTypeString();
237     JSHandle<JSTaggedValue> valueKey = globalConst->GetHandledValueString();
238     icu::Locale icuLocale("zh", "Hans", "Cn");
239     std::string cycle("h12");
240     std::string zone("ETC/GMT-8");
241     auto options = EcmaTestCommon::SetHourCycleKeyValue(thread, cycle, zone);
242 
243     double timeStamp = 1653448174123; // test "2022-05-25 11:09:34.123"
244     // Set custom date time format and format date and time to parts.
245     std::map<std::string, std::string> dateOptionsMap {
246         { "weekday", "long" },
247         { "year", "2-digit" },
248         { "month", "2-digit" },
249         { "day", "2-digit" }
250     };
251     std::map<std::string, std::string> timeOptionsMap {
252         { "dayPeriod", "long" },
253         { "hour", "2-digit" },
254         { "minute", "2-digit" },
255         { "second", "2-digit" },
256         { "fractionalSecond", "3" }
257     };
258     EcmaTestCommon::SetDateOptionsTest(thread, options, dateOptionsMap);
259     EcmaTestCommon::SetTimeOptionsTest(thread, options, timeOptionsMap);
260     options = JSDateTimeFormat::ToDateTimeOptions(
261         thread, JSHandle<JSTaggedValue>::Cast(options), RequiredOption::ANY, DefaultsOption::ALL);
262     JSHandle<JSDateTimeFormat> dtf = EcmaTestCommon::CreateDateTimeFormatTest(thread, icuLocale, options);
263     JSHandle<EcmaString> dateTimeEcamStr = JSDateTimeFormat::FormatDateTime(thread, dtf, timeStamp);
264     EXPECT_STREQ(LocaleHelper::ConvertToStdString(thread, dateTimeEcamStr).c_str(),
265         "22年05月25日星期三 上午11:09:34.123");
266 
267     JSHandle<JSArray> dateTimeArray = JSDateTimeFormat::FormatDateTimeToParts(thread, dtf, timeStamp);
268     auto year = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 0).GetValue();
269     auto literal1 = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(dateTimeArray), 1).GetValue();
270     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, year).c_str(), "year");
271     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, year).c_str(), "22");
272     EXPECT_STREQ(GetDateTimePartStringTest(thread, typeKey, literal1).c_str(), "literal");
273     EXPECT_STREQ(GetDateTimePartStringTest(thread, valueKey, literal1).c_str(), "年");
274     CheckOther(thread, dateTimeArray, typeKey, valueKey);
275 }
276 /**
277  * @tc.name: GainAvailableLocales
278  * @tc.desc: Get the available localized label array. If the global time date localized label is not set, return an
279  *           array containing all available labels. Otherwise, return an array containing self-defined labels.
280  * @tc.type: FUNC
281  * @tc.require:
282  */
HWTEST_F_L0(JSDateTimeFormatTest,GainAvailableLocales)283 HWTEST_F_L0(JSDateTimeFormatTest, GainAvailableLocales)
284 {
285     auto vm = thread->GetEcmaVM();
286     auto factory = vm->GetFactory();
287     auto env = vm->GetGlobalEnv();
288 
289     // The date and time format locales is not initialized,
290     // then get all available locales and save them in a 'TaggedArray'.
291     JSHandle<JSTaggedValue> dateTimeFormatLocales = env->GetDateTimeFormatLocales();
292     EXPECT_EQ(dateTimeFormatLocales.GetTaggedValue(), JSTaggedValue::Undefined());
293 
294     const char *key = "calendar";
295     const char *path = nullptr;
296     std::vector<std::string> availableStringLocales = intl::LocaleHelper::GetAvailableLocales(thread, key, path);
297     JSHandle<TaggedArray> availableLocales = JSLocale::ConstructLocaleList(thread, availableStringLocales);
298     env->SetDateTimeFormatLocales(thread, availableLocales);
299     JSHandle<TaggedArray> gainLocales1 = JSDateTimeFormat::GainAvailableLocales(thread);
300     EXPECT_EQ(JSHandle<JSTaggedValue>::Cast(gainLocales1).GetTaggedValue().GetRawData(),
301         JSHandle<JSTaggedValue>::Cast(availableLocales).GetTaggedValue().GetRawData());
302 
303     // The date and time format locales has already been initialized,
304     // then get custom locale and save it in a 'TaggedArray'.
305     JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
306     JSHandle<JSTaggedValue> localeCtor = env->GetLocaleFunction();
307     JSHandle<JSTaggedValue> dtfCtor = env->GetDateTimeFormatFunction();
308 
309     JSHandle<JSLocale> locales =
310         JSHandle<JSLocale>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(localeCtor), localeCtor));
311     icu::Locale icuLocale("zh", "Hans", "Cn", "calendar=chinese");
312     factory->NewJSIntlIcuData(locales, icuLocale, JSLocale::FreeIcuLocale);
313     JSHandle<JSObject> options = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
314     options = JSDateTimeFormat::ToDateTimeOptions(
315         thread, JSHandle<JSTaggedValue>::Cast(options), RequiredOption::ANY, DefaultsOption::ALL);
316     JSHandle<JSDateTimeFormat> dtf =
317         JSHandle<JSDateTimeFormat>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(dtfCtor), dtfCtor));
318     dtf = JSDateTimeFormat::InitializeDateTimeFormat(
319         thread, dtf, JSHandle<JSTaggedValue>::Cast(locales), JSHandle<JSTaggedValue>::Cast(options));
320 
321     JSHandle<JSTaggedValue> localeTagVal(thread, dtf->GetLocale(thread));
322     JSHandle<TaggedArray> localesTagArr = factory->NewTaggedArray(1);
323     localesTagArr->Set(thread, 0, localeTagVal);
324     env->SetDateTimeFormatLocales(thread, localesTagArr);
325     JSHandle<TaggedArray> gainLocales2 = JSDateTimeFormat::GainAvailableLocales(thread);
326     EXPECT_EQ(gainLocales2->GetLength(), 1U);
327     EXPECT_STREQ(EcmaStringAccessor(gainLocales2->Get(thread, 0)).ToCString(thread).c_str(),
328         "zh-Hans-CN-u-ca-chinese");
329 }
330 } // namespace panda::test