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_collator.h"
17
18 #include "ecmascript/builtins/builtins_array.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_collator.h"
21 #include "ecmascript/tests/test_helper.h"
22
23 using namespace panda::ecmascript;
24 using namespace panda::ecmascript::builtins;
25
26 namespace panda::test {
27 using BuiltinsArray = ecmascript::builtins::BuiltinsArray;
28 class BuiltinsCollatorTest : public testing::Test {
29 public:
SetUpTestCase()30 static void SetUpTestCase()
31 {
32 GTEST_LOG_(INFO) << "SetUpTestCase";
33 }
34
TearDownTestCase()35 static void TearDownTestCase()
36 {
37 GTEST_LOG_(INFO) << "TearDownCase";
38 }
39
SetUp()40 void SetUp() override
41 {
42 JSRuntimeOptions options;
43 #if PANDA_TARGET_LINUX
44 // for consistency requirement, use ohos_icu4j/data as icu-data-path
45 options.SetIcuDataPath(ICU_PATH);
46 #endif
47 options.SetEnableForceGC(true);
48 instance = JSNApi::CreateEcmaVM(options);
49 instance->SetEnableForceGC(true);
50 ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
51 thread = instance->GetJSThread();
52 scope = new EcmaHandleScope(thread);
53 }
54
TearDown()55 void TearDown() override
56 {
57 TestHelper::DestroyEcmaVMWithScope(instance, scope);
58 }
59
60 EcmaVM *instance {nullptr};
61 EcmaHandleScope *scope {nullptr};
62 JSThread *thread {nullptr};
63 };
64
HWTEST_F_L0(BuiltinsCollatorTest,CollatorConstructor)65 HWTEST_F_L0(BuiltinsCollatorTest, CollatorConstructor)
66 {
67 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
68 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
69 JSHandle<JSFunction> newTarget(env->GetCollatorFunction());
70 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
71
72 JSHandle<JSTaggedValue> usageKey = thread->GlobalConstants()->GetHandledUsageString();
73 JSHandle<JSTaggedValue> localeMatcherKey = thread->GlobalConstants()->GetHandledLocaleMatcherString();
74 JSHandle<JSTaggedValue> numericKey = thread->GlobalConstants()->GetHandledNumericString();
75 JSHandle<JSTaggedValue> caseFirstKey = thread->GlobalConstants()->GetHandledCaseFirstString();
76 JSHandle<JSTaggedValue> sensitivityKey = thread->GlobalConstants()->GetHandledSensitivityString();
77 JSHandle<JSTaggedValue> ignorePunctuationKey = thread->GlobalConstants()->GetHandledIgnorePunctuationString();
78
79 JSHandle<JSTaggedValue> usageValue(factory->NewFromASCII("search"));
80 JSHandle<JSTaggedValue> localeMatcherValue(factory->NewFromASCII("lookup"));
81 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("true"));
82 JSHandle<JSTaggedValue> caseFirstValue(factory->NewFromASCII("lower"));
83 JSHandle<JSTaggedValue> sensitivityValue(factory->NewFromASCII("variant"));
84 JSHandle<JSTaggedValue> ignorePunctuationValue(factory->NewFromASCII("true"));
85 JSHandle<JSTaggedValue> localesString(factory->NewFromASCII("en-Latn-US"));
86
87 JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
88 JSObject::SetProperty(thread, optionsObj, usageKey, usageValue);
89 JSObject::SetProperty(thread, optionsObj, localeMatcherKey, localeMatcherValue);
90 JSObject::SetProperty(thread, optionsObj, caseFirstKey, caseFirstValue);
91 JSObject::SetProperty(thread, optionsObj, sensitivityKey, sensitivityValue);
92 JSObject::SetProperty(thread, optionsObj, ignorePunctuationKey, ignorePunctuationValue);
93 JSObject::SetProperty(thread, optionsObj, numericKey, numericValue);
94
95 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
96 ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
97 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
98 ecmaRuntimeCallInfo->SetCallArg(0, localesString.GetTaggedValue());
99 ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue()); // set option tag
100
101 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
102 JSTaggedValue result = BuiltinsCollator::CollatorConstructor(ecmaRuntimeCallInfo);
103 TestHelper::TearDownFrame(thread, prev);
104
105 EXPECT_TRUE(result.IsJSCollator());
106 }
107
JSCollatorCreateWithLocaleTest(JSThread * thread,JSHandle<JSTaggedValue> & locale)108 static JSTaggedValue JSCollatorCreateWithLocaleTest(JSThread *thread, JSHandle<JSTaggedValue> &locale)
109 {
110 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
111 JSHandle<JSFunction> newTarget(env->GetCollatorFunction());
112
113 JSHandle<JSTaggedValue> localesString = locale;
114 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
115 ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
116 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
117 ecmaRuntimeCallInfo->SetCallArg(0, localesString.GetTaggedValue());
118 // set no options
119 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined());
120
121 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
122 JSTaggedValue result = BuiltinsCollator::CollatorConstructor(ecmaRuntimeCallInfo);
123 EXPECT_TRUE(result.IsJSCollator());
124 TestHelper::TearDownFrame(thread, prev);
125 return result;
126 }
127
JSCollatorCreateWithLocaleAndOptionsTest(JSThread * thread,JSHandle<JSTaggedValue> & locale)128 static JSTaggedValue JSCollatorCreateWithLocaleAndOptionsTest(JSThread *thread, JSHandle<JSTaggedValue> &locale)
129 {
130 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
131 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
132 JSHandle<JSFunction> newTarget(env->GetCollatorFunction());
133 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
134
135 JSHandle<JSTaggedValue> localesString = locale;
136 JSHandle<JSTaggedValue> usageKey = thread->GlobalConstants()->GetHandledUsageString();
137 JSHandle<JSTaggedValue> sensitivityKey = thread->GlobalConstants()->GetHandledSensitivityString();
138 JSHandle<JSTaggedValue> usageValue(factory->NewFromASCII("search"));
139 JSHandle<JSTaggedValue> sensitivityValue(factory->NewFromASCII("base"));
140
141 JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
142 JSObject::SetProperty(thread, optionsObj, usageKey, usageValue);
143 JSObject::SetProperty(thread, optionsObj, sensitivityKey, sensitivityValue);
144
145 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
146 ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
147 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
148 ecmaRuntimeCallInfo->SetCallArg(0, localesString.GetTaggedValue());
149 ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
150
151 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
152 JSTaggedValue result = BuiltinsCollator::CollatorConstructor(ecmaRuntimeCallInfo);
153 EXPECT_TRUE(result.IsJSCollator());
154 TestHelper::TearDownFrame(thread, prev);
155 return result;
156 }
157
158 // compare with sort(de)
HWTEST_F_L0(BuiltinsCollatorTest,Compare_001)159 HWTEST_F_L0(BuiltinsCollatorTest, Compare_001)
160 {
161 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
162 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("de"));
163 JSHandle<JSCollator> jsCollator = JSHandle<JSCollator>(thread, JSCollatorCreateWithLocaleTest(thread, locale));
164
165 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
166 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
167 ecmaRuntimeCallInfo1->SetThis(jsCollator.GetTaggedValue());
168
169 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
170 JSTaggedValue result1 = BuiltinsCollator::Compare(ecmaRuntimeCallInfo1);
171 TestHelper::TearDownFrame(thread, prev);
172 JSHandle<JSFunction> jsFunction(thread, result1);
173
174 JSArray *jsArray =
175 JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
176 JSHandle<JSObject> jsObject(thread, jsArray);
177
178 JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
179 JSHandle<JSTaggedValue> value0(factory->NewFromASCII("Z"));
180 PropertyDescriptor desc0(thread, value0, true, true, true);
181 JSArray::DefineOwnProperty(thread, jsObject, key0, desc0);
182 JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
183 JSHandle<JSTaggedValue> value1(factory->NewFromASCII("a"));
184 PropertyDescriptor desc1(thread, value1, true, true, true);
185 JSArray::DefineOwnProperty(thread, jsObject, key1, desc1);
186 JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(2));
187 JSHandle<JSTaggedValue> value2(factory->NewFromUtf8("ä"));
188 PropertyDescriptor desc2(thread, value2, true, true, true);
189 JSArray::DefineOwnProperty(thread, jsObject, key2, desc2);
190
191 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
192 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
193 ecmaRuntimeCallInfo2->SetThis(jsObject.GetTaggedValue());
194 ecmaRuntimeCallInfo2->SetCallArg(0, jsFunction.GetTaggedValue());
195
196 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
197 JSTaggedValue result2 = BuiltinsArray::Sort(ecmaRuntimeCallInfo2); // sort in language(de)
198 TestHelper::TearDownFrame(thread, prev);
199
200 JSHandle<JSTaggedValue> resultArr =
201 JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<JSTaggedType>(result2.GetRawData())));
202 EXPECT_EQ(JSTaggedValue::SameValue(JSArray::GetProperty(thread, resultArr, key0).GetValue(), value1), true);
203 EXPECT_EQ(JSTaggedValue::SameValue(JSArray::GetProperty(thread, resultArr, key1).GetValue(), value2), true);
204 EXPECT_EQ(JSTaggedValue::SameValue(JSArray::GetProperty(thread, resultArr, key2).GetValue(), value0), true);
205 }
206
207 // // compare with sort(sv)
HWTEST_F_L0(BuiltinsCollatorTest,Compare_002)208 HWTEST_F_L0(BuiltinsCollatorTest, Compare_002)
209 {
210 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
211 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("sv"));
212 JSHandle<JSCollator> jsCollator = JSHandle<JSCollator>(thread, JSCollatorCreateWithLocaleTest(thread, locale));
213
214 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
215 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
216 ecmaRuntimeCallInfo1->SetThis(jsCollator.GetTaggedValue());
217
218 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
219 JSTaggedValue result1 = BuiltinsCollator::Compare(ecmaRuntimeCallInfo1);
220 TestHelper::TearDownFrame(thread, prev);
221
222 JSHandle<JSFunction> jsFunction(thread, result1);
223 JSArray *jsArray =
224 JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
225 JSHandle<JSObject> jsObject(thread, jsArray);
226
227 JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
228 JSHandle<JSTaggedValue> value0(factory->NewFromASCII("Z"));
229 PropertyDescriptor desc0(thread, value0, true, true, true);
230 JSArray::DefineOwnProperty(thread, jsObject, key0, desc0);
231 JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
232 JSHandle<JSTaggedValue> value1(factory->NewFromASCII("a"));
233 PropertyDescriptor desc1(thread, value1, true, true, true);
234 JSArray::DefineOwnProperty(thread, jsObject, key1, desc1);
235 JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(2));
236 JSHandle<JSTaggedValue> value2(factory->NewFromUtf8("ä"));
237 PropertyDescriptor desc2(thread, value2, true, true, true);
238 JSArray::DefineOwnProperty(thread, jsObject, key2, desc2);
239
240 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
241 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
242 ecmaRuntimeCallInfo2->SetThis(jsObject.GetTaggedValue());
243 ecmaRuntimeCallInfo2->SetCallArg(0, jsFunction.GetTaggedValue());
244
245 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
246 JSTaggedValue result2 = BuiltinsArray::Sort(ecmaRuntimeCallInfo2); // sort in language(sv)
247 TestHelper::TearDownFrame(thread, prev);
248 JSHandle<JSObject> resultObj(thread, result2);
249
250 JSHandle<EcmaString> str = thread->GetEcmaVM()->GetFactory()->NewFromUtf8("a,Z,ä");
251 auto ecmaRuntimeCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
252 ecmaRuntimeCallInfo3->SetFunction(JSTaggedValue::Undefined());
253 ecmaRuntimeCallInfo3->SetThis(resultObj.GetTaggedValue());
254
255 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo3);
256 JSTaggedValue result = BuiltinsArray::Join(ecmaRuntimeCallInfo3);
257 TestHelper::TearDownFrame(thread, prev);
258 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
259 EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, str), 0);
260 }
261
262 // compare with options("search")
HWTEST_F_L0(BuiltinsCollatorTest,Compare_003)263 HWTEST_F_L0(BuiltinsCollatorTest, Compare_003)
264 {
265 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
266 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("sv"));
267 JSHandle<JSCollator> jsCollator =
268 JSHandle<JSCollator>(thread, JSCollatorCreateWithLocaleAndOptionsTest(thread, locale));
269
270 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
271 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
272 ecmaRuntimeCallInfo1->SetThis(jsCollator.GetTaggedValue());
273
274 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
275 JSTaggedValue result1 = BuiltinsCollator::Compare(ecmaRuntimeCallInfo1);
276 TestHelper::TearDownFrame(thread, prev);
277
278 JSHandle<JSFunction> jsFunction(thread, result1);
279 JSArray *jsArray =
280 JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
281 JSHandle<JSObject> jsObject(thread, jsArray);
282
283 JSHandle<JSTaggedValue> value0(factory->NewFromUtf8("Congrès"));
284 JSHandle<JSTaggedValue> value1(factory->NewFromASCII("congres"));
285 PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(jsFunction), true, true, true);
286 JSHandle<JSTaggedValue> joinKey(factory->NewFromASCII("join"));
287 JSArray::DefineOwnProperty(thread, jsObject, joinKey, desc);
288
289 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
290 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
291 ecmaRuntimeCallInfo2->SetThis(jsObject.GetTaggedValue());
292 ecmaRuntimeCallInfo2->SetCallArg(0, value0.GetTaggedValue());
293 ecmaRuntimeCallInfo2->SetCallArg(1, value1.GetTaggedValue());
294
295 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
296 JSTaggedValue result2 = BuiltinsArray::ToString(ecmaRuntimeCallInfo2); // search in language(sv)
297 TestHelper::TearDownFrame(thread, prev);
298 JSHandle<JSTaggedValue> resultHandle(thread, result2);
299 EXPECT_EQ(resultHandle->GetInt(), 0); // Congrès and congres is matching
300 }
301
HWTEST_F_L0(BuiltinsCollatorTest,ResolvedOptions)302 HWTEST_F_L0(BuiltinsCollatorTest, ResolvedOptions)
303 {
304 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
305 auto globalConst = thread->GlobalConstants();
306 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("de"));
307 JSHandle<JSCollator> jsCollator = JSHandle<JSCollator>(thread, JSCollatorCreateWithLocaleTest(thread, locale));
308
309 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
310 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
311 ecmaRuntimeCallInfo->SetThis(jsCollator.GetTaggedValue());
312
313 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
314 JSTaggedValue result = BuiltinsCollator::ResolvedOptions(ecmaRuntimeCallInfo);
315 TestHelper::TearDownFrame(thread, prev);
316
317 JSHandle<JSTaggedValue> resultObj =
318 JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<JSTaggedType>(result.GetRawData())));
319 // judge whether the properties of the object are the same as those of jscollator tag
320 JSHandle<JSTaggedValue> localeKey = globalConst->GetHandledLocaleString();
321 EXPECT_EQ(JSTaggedValue::SameValue(JSObject::GetProperty(thread, resultObj, localeKey).GetValue(), locale), true);
322 JSHandle<JSTaggedValue> usageKey = globalConst->GetHandledUsageString();
323 JSHandle<JSTaggedValue> defaultUsageValue(factory->NewFromASCII("sort"));
324 EXPECT_EQ(JSTaggedValue::SameValue(
325 JSObject::GetProperty(thread, resultObj, usageKey).GetValue(), defaultUsageValue), true);
326 JSHandle<JSTaggedValue> handledCaseFirstKey = globalConst->GetHandledCaseFirstString();
327 JSHandle<JSTaggedValue> handledCaseFirstValue(factory->NewFromASCII("upper"));
328 EXPECT_EQ(JSTaggedValue::SameValue(JSObject::GetProperty(thread, resultObj, handledCaseFirstKey).GetValue(),
329 handledCaseFirstValue), true);
330 }
331
HWTEST_F_L0(BuiltinsCollatorTest,SupportedLocalesOf)332 HWTEST_F_L0(BuiltinsCollatorTest, SupportedLocalesOf)
333 {
334 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
335 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
336 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
337
338 JSHandle<JSTaggedValue> localeMatcherKey = thread->GlobalConstants()->GetHandledLocaleMatcherString();
339 JSHandle<JSTaggedValue> localeMatcherValue(factory->NewFromASCII("lookup"));
340 JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
341 JSObject::SetProperty(thread, optionsObj, localeMatcherKey, localeMatcherValue);
342 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("id-u-co-pinyin-de-ID"));
343
344 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
345 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
346 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
347 ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
348 ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
349
350 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
351 JSTaggedValue resultArr = BuiltinsCollator::SupportedLocalesOf(ecmaRuntimeCallInfo);
352 TestHelper::TearDownFrame(thread, prev);
353
354 JSHandle<JSArray> resultHandle(thread, resultArr);
355 JSHandle<TaggedArray> elements(thread, resultHandle->GetElements());
356 EXPECT_EQ(elements->GetLength(), 1U);
357 JSHandle<EcmaString> handleEcmaStr(thread, elements->Get(0));
358 EXPECT_STREQ("id-u-co-pinyin-de-id", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
359 }
360 } // namespace panda::test
361