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/builtins/builtins_date_time_format.h"
17
18 #include "ecmascript/builtins/builtins_array.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_date.h"
21 #include "ecmascript/js_date_time_format.h"
22 #include "ecmascript/tests/test_helper.h"
23
24 using namespace panda::ecmascript;
25 using namespace panda::ecmascript::builtins;
26
27 namespace panda::test {
28 using BuiltinsArray = ecmascript::builtins::BuiltinsArray;
29 class BuiltinsDateTimeFormatTest : public testing::Test {
30 public:
SetUpTestCase()31 static void SetUpTestCase()
32 {
33 GTEST_LOG_(INFO) << "SetUpTestCase";
34 }
35
TearDownTestCase()36 static void TearDownTestCase()
37 {
38 GTEST_LOG_(INFO) << "TearDownCase";
39 }
40
SetUp()41 void SetUp() override
42 {
43 JSRuntimeOptions options;
44 #if PANDA_TARGET_LINUX
45 // for consistency requirement, use ohos_icu4j/data as icu-data-path
46 options.SetIcuDataPath(ICU_PATH);
47 #endif
48 options.SetEnableForceGC(true);
49 instance = JSNApi::CreateEcmaVM(options);
50 instance->SetEnableForceGC(true);
51 ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
52 thread = instance->GetJSThread();
53 scope = new EcmaHandleScope(thread);
54 }
55
TearDown()56 void TearDown() override
57 {
58 TestHelper::DestroyEcmaVMWithScope(instance, scope);
59 }
60
61 EcmaVM *instance {nullptr};
62 EcmaHandleScope *scope {nullptr};
63 JSThread *thread {nullptr};
64 };
65
66 // new DateTimeFormat(locale)
HWTEST_F_L0(BuiltinsDateTimeFormatTest,DateTimeFormatConstructor)67 HWTEST_F_L0(BuiltinsDateTimeFormatTest, DateTimeFormatConstructor)
68 {
69 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
70 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
71 JSHandle<JSFunction> newTarget(env->GetDateTimeFormatFunction());
72
73 JSHandle<JSTaggedValue> localesString(factory->NewFromASCII("en-US"));
74 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
75 ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
76 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
77 ecmaRuntimeCallInfo->SetCallArg(0, localesString.GetTaggedValue());
78 // option tag is default value
79 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined());
80
81 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
82 JSTaggedValue result = BuiltinsDateTimeFormat::DateTimeFormatConstructor(ecmaRuntimeCallInfo);
83 TestHelper::TearDownFrame(thread, prev);
84 EXPECT_TRUE(result.IsJSDateTimeFormat());
85 }
86
BuiltinsDateTimeOptionsSet(JSThread * thread)87 static JSTaggedValue BuiltinsDateTimeOptionsSet(JSThread *thread)
88 {
89 auto globalConst = thread->GlobalConstants();
90 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
91 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
92
93 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
94 JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
95
96 JSHandle<JSTaggedValue> weekDay = globalConst->GetHandledWeekdayString();
97 JSHandle<JSTaggedValue> dayPeriod = globalConst->GetHandledDayPeriodString();
98 JSHandle<JSTaggedValue> hourCycle = globalConst->GetHandledHourCycleString();
99 JSHandle<JSTaggedValue> timeZone = globalConst->GetHandledTimeZoneString();
100 JSHandle<JSTaggedValue> numicValue(factory->NewFromASCII("numeric")); // test numeric
101 JSHandle<JSTaggedValue> weekDayValue(factory->NewFromASCII("short")); // test short
102 JSHandle<JSTaggedValue> dayPeriodValue(factory->NewFromASCII("long")); // test long
103 JSHandle<JSTaggedValue> hourCycleValue(factory->NewFromASCII("h24")); // test h24
104 JSHandle<JSTaggedValue> timeZoneValue(factory->NewFromASCII("UTC")); // test UTC
105
106 JSHandle<TaggedArray> keyArray = factory->NewTaggedArray(6); // 6 : 6 length
107 keyArray->Set(thread, 0, globalConst->GetHandledYearString()); // 0 : 0 first position
108 keyArray->Set(thread, 1, globalConst->GetHandledMonthString()); // 1 : 1 second position
109 keyArray->Set(thread, 2, globalConst->GetHandledDayString()); // 2 : 2 third position
110 keyArray->Set(thread, 3, globalConst->GetHandledHourString()); // 3 : 3 fourth position
111 keyArray->Set(thread, 4, globalConst->GetHandledMinuteString()); // 4 : 4 fifth position
112 keyArray->Set(thread, 5, globalConst->GetHandledSecondString()); // 5 : 5 sixth position
113
114 uint32_t arrayLen = keyArray->GetLength();
115 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
116 for (uint32_t i = 0; i < arrayLen; i++) {
117 key.Update(keyArray->Get(thread, i));
118 JSObject::SetProperty(thread, optionsObj, key, numicValue);
119 }
120 JSObject::SetProperty(thread, optionsObj, weekDay, weekDayValue);
121 JSObject::SetProperty(thread, optionsObj, dayPeriod, dayPeriodValue);
122 JSObject::SetProperty(thread, optionsObj, hourCycle, hourCycleValue);
123 JSObject::SetProperty(thread, optionsObj, timeZone, timeZoneValue);
124 return optionsObj.GetTaggedValue();
125 }
126
JSDateTimeFormatCreateWithLocaleTest(JSThread * thread,JSHandle<JSTaggedValue> & locale)127 static JSTaggedValue JSDateTimeFormatCreateWithLocaleTest(JSThread *thread, JSHandle<JSTaggedValue> &locale)
128 {
129 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
130 JSHandle<JSFunction> newTarget(env->GetDateTimeFormatFunction());
131 JSHandle<JSObject> optionsObj = JSHandle<JSObject>(thread, BuiltinsDateTimeOptionsSet(thread));
132
133 JSHandle<JSTaggedValue> localesString = locale;
134 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
135 ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
136 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
137 ecmaRuntimeCallInfo->SetCallArg(0, localesString.GetTaggedValue());
138 ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
139
140 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
141 JSTaggedValue result = BuiltinsDateTimeFormat::DateTimeFormatConstructor(ecmaRuntimeCallInfo);
142 EXPECT_TRUE(result.IsJSDateTimeFormat());
143 TestHelper::TearDownFrame(thread, prev);
144 return result;
145 }
146
BuiltinsDateCreate(const double year,const double month,const double date)147 static double BuiltinsDateCreate(const double year, const double month, const double date)
148 {
149 const double day = JSDate::MakeDay(year, month, date);
150 const double time = JSDate::MakeTime(0, 0, 0, 0); // 24:00:00
151 double days = JSDate::MakeDate(day, time);
152 return days;
153 }
154
155 // Format.Tostring(en-US)
HWTEST_F_L0(BuiltinsDateTimeFormatTest,Format_001)156 HWTEST_F_L0(BuiltinsDateTimeFormatTest, Format_001)
157 {
158 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
159 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
160 JSHandle<JSDateTimeFormat> jsDateTimeFormat =
161 JSHandle<JSDateTimeFormat>(thread, JSDateTimeFormatCreateWithLocaleTest(thread, locale));
162
163 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
164 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
165 ecmaRuntimeCallInfo1->SetThis(jsDateTimeFormat.GetTaggedValue());
166 ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue::Undefined());
167
168 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
169 JSTaggedValue result1 = BuiltinsDateTimeFormat::Format(ecmaRuntimeCallInfo1);
170 TestHelper::TearDownFrame(thread, prev);
171 // jsDate supports zero to eleven, the month should be added with one
172 JSHandle<JSFunction> jsFunction(thread, result1);
173 JSArray *jsArray =
174 JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
175 JSHandle<JSObject> jsObject(thread, jsArray);
176
177 double days = BuiltinsDateCreate(2020, 10, 1);
178 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(static_cast<double>(days)));
179 PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(jsFunction), true, true, true);
180 JSHandle<JSTaggedValue> joinKey(factory->NewFromASCII("join"));
181 JSArray::DefineOwnProperty(thread, jsObject, joinKey, desc);
182
183 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
184 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
185 ecmaRuntimeCallInfo2->SetThis(jsObject.GetTaggedValue());
186 ecmaRuntimeCallInfo2->SetCallArg(0, value.GetTaggedValue());
187
188 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
189 JSTaggedValue result2 = BuiltinsArray::ToString(ecmaRuntimeCallInfo2);
190 TestHelper::TearDownFrame(thread, prev);
191 JSHandle<EcmaString> resultStr(thread, result2);
192 EXPECT_STREQ("Sun, 11/1/2020, 24:00:00", EcmaStringAccessor(resultStr).ToCString().c_str());
193 }
194
195 // Format.Tostring(pt-BR)
HWTEST_F_L0(BuiltinsDateTimeFormatTest,Format_002)196 HWTEST_F_L0(BuiltinsDateTimeFormatTest, Format_002)
197 {
198 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
199 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("pt-BR"));
200 JSHandle<JSDateTimeFormat> jsDateTimeFormat =
201 JSHandle<JSDateTimeFormat>(thread, JSDateTimeFormatCreateWithLocaleTest(thread, locale));
202
203 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
204 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
205 ecmaRuntimeCallInfo1->SetThis(jsDateTimeFormat.GetTaggedValue());
206 ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue::Undefined());
207
208 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
209 JSTaggedValue result1 = BuiltinsDateTimeFormat::Format(ecmaRuntimeCallInfo1);
210 TestHelper::TearDownFrame(thread, prev);
211
212 JSHandle<JSFunction> jsFunction(thread, result1);
213 JSArray *jsArray =
214 JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
215 JSHandle<JSObject> jsObject(thread, jsArray);
216
217 double days = BuiltinsDateCreate(2020, 5, 11);
218 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(static_cast<double>(days)));
219 PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(jsFunction), true, true, true);
220 JSHandle<JSTaggedValue> joinKey(factory->NewFromASCII("join"));
221 JSArray::DefineOwnProperty(thread, jsObject, joinKey, desc);
222
223 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
224 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
225 ecmaRuntimeCallInfo2->SetThis(jsObject.GetTaggedValue());
226 ecmaRuntimeCallInfo2->SetCallArg(0, value.GetTaggedValue());
227
228 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
229 JSTaggedValue result2 = BuiltinsArray::ToString(ecmaRuntimeCallInfo2);
230 TestHelper::TearDownFrame(thread, prev);
231 JSHandle<EcmaString> resultStr(thread, result2);
232 CString resStr = EcmaStringAccessor(resultStr).ToCString();
233 // the index of string "qui" is zero.
234 EXPECT_TRUE(resStr.find("qui") == 0);
235 // the index of string "11/06/2020 24:00:00" is not zero.
236 EXPECT_TRUE(resStr.find("11/06/2020 24:00:00") != 0);
237 }
238
HWTEST_F_L0(BuiltinsDateTimeFormatTest,FormatToParts)239 HWTEST_F_L0(BuiltinsDateTimeFormatTest, FormatToParts)
240 {
241 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
242 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
243 JSHandle<JSDateTimeFormat> jsDateTimeFormat =
244 JSHandle<JSDateTimeFormat>(thread, JSDateTimeFormatCreateWithLocaleTest(thread, locale));
245
246 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
247 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
248 ecmaRuntimeCallInfo->SetThis(jsDateTimeFormat.GetTaggedValue());
249 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
250
251 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
252 JSTaggedValue result = BuiltinsDateTimeFormat::FormatToParts(ecmaRuntimeCallInfo);
253 TestHelper::TearDownFrame(thread, prev);
254
255 JSHandle<JSArray> resultHandle(thread, result);
256 JSHandle<TaggedArray> elements(thread, resultHandle->GetElements());
257 EXPECT_EQ(elements->GetLength(), 16U); // sixteen formatters
258 }
259
260 // FormatRange(zh)
HWTEST_F_L0(BuiltinsDateTimeFormatTest,FormatRange_001)261 HWTEST_F_L0(BuiltinsDateTimeFormatTest, FormatRange_001)
262 {
263 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
264 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("zh"));
265 JSHandle<JSDateTimeFormat> jsDateTimeFormat =
266 JSHandle<JSDateTimeFormat>(thread, JSDateTimeFormatCreateWithLocaleTest(thread, locale));
267
268 double days1 = BuiltinsDateCreate(2020, 10, 1);
269 double days2 = BuiltinsDateCreate(2021, 6, 1);
270 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
271 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
272 ecmaRuntimeCallInfo->SetThis(jsDateTimeFormat.GetTaggedValue());
273 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(days1)));
274 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<double>(days2)));
275
276 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
277 JSTaggedValue result = BuiltinsDateTimeFormat::FormatRange(ecmaRuntimeCallInfo);
278 TestHelper::TearDownFrame(thread, prev);
279
280 JSHandle<EcmaString> handleStr(thread, result);
281 JSHandle<EcmaString> resultStr = factory->NewFromUtf8("2020/11/1周日 24:00:00 – 2021/7/1周四 24:00:00");
282 EXPECT_EQ(EcmaStringAccessor::Compare(*handleStr, *resultStr), 0);
283 }
284
285 // FormatRange(en)
HWTEST_F_L0(BuiltinsDateTimeFormatTest,FormatRange_002)286 HWTEST_F_L0(BuiltinsDateTimeFormatTest, FormatRange_002)
287 {
288 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
289 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
290 JSHandle<JSDateTimeFormat> jsDateTimeFormat =
291 JSHandle<JSDateTimeFormat>(thread, JSDateTimeFormatCreateWithLocaleTest(thread, locale));
292
293 double days1 = BuiltinsDateCreate(2020, 12, 1);
294 double days2 = BuiltinsDateCreate(2021, 2, 1);
295 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
296 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
297 ecmaRuntimeCallInfo->SetThis(jsDateTimeFormat.GetTaggedValue());
298 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(days1)));
299 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<double>(days2)));
300
301 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
302 JSTaggedValue result = BuiltinsDateTimeFormat::FormatRange(ecmaRuntimeCallInfo);
303 TestHelper::TearDownFrame(thread, prev);
304
305 JSHandle<EcmaString> handleStr(thread, result);
306 JSHandle<EcmaString> resultStr = factory->NewFromUtf8("Fri, 1/1/2021, 24:00:00 – Mon, 3/1/2021, 24:00:00");
307 EXPECT_EQ(EcmaStringAccessor::Compare(*handleStr, *resultStr), 0);
308 }
309
HWTEST_F_L0(BuiltinsDateTimeFormatTest,FormatRangeToParts)310 HWTEST_F_L0(BuiltinsDateTimeFormatTest, FormatRangeToParts)
311 {
312 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
313 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-US"));
314 JSHandle<JSDateTimeFormat> jsDateTimeFormat =
315 JSHandle<JSDateTimeFormat>(thread, JSDateTimeFormatCreateWithLocaleTest(thread, locale));
316
317 double days1 = BuiltinsDateCreate(2020, 12, 1);
318 double days2 = BuiltinsDateCreate(2021, 2, 1);
319 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
320 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
321 ecmaRuntimeCallInfo->SetThis(jsDateTimeFormat.GetTaggedValue());
322 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(days1)));
323 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<double>(days2)));
324
325 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
326 JSTaggedValue result = BuiltinsDateTimeFormat::FormatRangeToParts(ecmaRuntimeCallInfo);
327 TestHelper::TearDownFrame(thread, prev);
328
329 JSHandle<JSArray> resultHandle(thread, result);
330 JSHandle<TaggedArray> elements(thread, resultHandle->GetElements());
331 EXPECT_EQ(elements->GetLength(), 39U); // The number of characters of "Fri1/1/202124:00:00–Mon3/1/202124:00:00"
332 }
333
HWTEST_F_L0(BuiltinsDateTimeFormatTest,ResolvedOptions)334 HWTEST_F_L0(BuiltinsDateTimeFormatTest, ResolvedOptions)
335 {
336 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
337 auto globalConst = thread->GlobalConstants();
338 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("de-ID"));
339 JSHandle<JSDateTimeFormat> jsDateTimeFormat =
340 JSHandle<JSDateTimeFormat>(thread, JSDateTimeFormatCreateWithLocaleTest(thread, locale));
341
342 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
343 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
344 ecmaRuntimeCallInfo->SetThis(jsDateTimeFormat.GetTaggedValue());
345
346 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
347 JSTaggedValue result = BuiltinsDateTimeFormat::ResolvedOptions(ecmaRuntimeCallInfo);
348 TestHelper::TearDownFrame(thread, prev);
349
350 JSHandle<JSTaggedValue> resultObj =
351 JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<JSTaggedType>(result.GetRawData())));
352 // judge whether the properties of the object are the same as those of jsdatetimeformat tag
353 JSHandle<JSTaggedValue> localeKey = globalConst->GetHandledLocaleString();
354 JSHandle<JSTaggedValue> localeValue(factory->NewFromASCII("de"));
355 EXPECT_EQ(JSTaggedValue::SameValue(
356 JSObject::GetProperty(thread, resultObj, localeKey).GetValue(), localeValue), true);
357 JSHandle<JSTaggedValue> timeZone = globalConst->GetHandledTimeZoneString();
358 JSHandle<JSTaggedValue> timeZoneValue(factory->NewFromASCII("UTC"));
359 EXPECT_EQ(JSTaggedValue::SameValue(
360 JSObject::GetProperty(thread, resultObj, timeZone).GetValue(), timeZoneValue), true);
361 }
362
363 // SupportedLocalesOf("best fit")
HWTEST_F_L0(BuiltinsDateTimeFormatTest,SupportedLocalesOf_001)364 HWTEST_F_L0(BuiltinsDateTimeFormatTest, SupportedLocalesOf_001)
365 {
366 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
367 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("id-u-co-pinyin-de-ID"));
368
369 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
370 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
371 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
372 ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
373 // set the tag is default value
374 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined());
375
376 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
377 JSTaggedValue resultArr = BuiltinsDateTimeFormat::SupportedLocalesOf(ecmaRuntimeCallInfo);
378 TestHelper::TearDownFrame(thread, prev);
379
380 JSHandle<JSArray> resultHandle(thread, resultArr);
381 JSHandle<TaggedArray> elements(thread, resultHandle->GetElements());
382 EXPECT_EQ(elements->GetLength(), 1U);
383
384 JSHandle<EcmaString> resultStr(thread, elements->Get(0));
385 EXPECT_STREQ("id-u-co-pinyin-de-id", EcmaStringAccessor(resultStr).ToCString().c_str());
386 }
387
388 // SupportedLocalesOf("look up")
HWTEST_F_L0(BuiltinsDateTimeFormatTest,SupportedLocalesOf_002)389 HWTEST_F_L0(BuiltinsDateTimeFormatTest, SupportedLocalesOf_002)
390 {
391 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
392 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
393
394 JSHandle<JSTaggedValue> localeMatcherKey = thread->GlobalConstants()->GetHandledLocaleMatcherString();
395 JSHandle<JSTaggedValue> localeMatcherValue(factory->NewFromASCII("lookup"));
396 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("id-u-co-pinyin-de-DE"));
397
398 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
399 JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
400 JSObject::SetProperty(thread, optionsObj, localeMatcherKey, localeMatcherValue);
401
402 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
403 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
404 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
405 ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
406 ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
407
408 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
409 JSTaggedValue resultArr = BuiltinsDateTimeFormat::SupportedLocalesOf(ecmaRuntimeCallInfo);
410 TestHelper::TearDownFrame(thread, prev);
411
412 JSHandle<JSArray> resultHandle(thread, resultArr);
413 JSHandle<TaggedArray> elements(thread, resultHandle->GetElements());
414 EXPECT_EQ(elements->GetLength(), 1U);
415
416 JSHandle<EcmaString> resultStr(thread, elements->Get(0));
417 EXPECT_STREQ("id-u-co-pinyin-de", EcmaStringAccessor(resultStr).ToCString().c_str());
418 }
419 } // namespace panda::test
420