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