1 /*
2 * Copyright (c) 2021-2024 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_string.h"
17
18 #include "ecmascript/base/builtins_base.h"
19 #include "ecmascript/builtins/builtins_regexp.h"
20 #include "ecmascript/ecma_runtime_call_info.h"
21 #include "ecmascript/ecma_string.h"
22 #include "ecmascript/ecma_vm.h"
23 #include "ecmascript/global_env.h"
24 #include "ecmascript/js_array.h"
25 #include "ecmascript/js_object-inl.h"
26 #include "ecmascript/js_primitive_ref.h"
27 #include "ecmascript/js_regexp.h"
28 #include "ecmascript/js_tagged_value.h"
29 #include "ecmascript/object_factory.h"
30 #include "ecmascript/tests/test_helper.h"
31
32 using namespace panda::ecmascript;
33 using namespace panda::ecmascript::builtins;
34
35 namespace panda::test {
36 class BuiltinsStringTest : public BaseTestWithScope<true> {
37 };
38
CreateBuiltinsStringRegExpObjByPatternAndFlags(JSThread * thread,const JSHandle<EcmaString> & pattern,const JSHandle<EcmaString> & flags)39 JSTaggedValue CreateBuiltinsStringRegExpObjByPatternAndFlags(JSThread *thread, const JSHandle<EcmaString> &pattern,
40 const JSHandle<EcmaString> &flags)
41 {
42 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
43 JSHandle<JSFunction> regexp(env->GetRegExpFunction());
44 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
45
46 // 8 : test case
47 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, regexp.GetTaggedValue(), 8);
48 ecmaRuntimeCallInfo->SetFunction(regexp.GetTaggedValue());
49 ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
50 ecmaRuntimeCallInfo->SetCallArg(0, pattern.GetTaggedValue());
51 ecmaRuntimeCallInfo->SetCallArg(1, flags.GetTaggedValue());
52
53 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
54 JSTaggedValue result = BuiltinsRegExp::RegExpConstructor(ecmaRuntimeCallInfo);
55 TestHelper::TearDownFrame(thread, prev);
56 return result;
57 }
58
59 enum class AlgorithmType {
60 FROM_CHAR_CODE,
61 FROM_CODE_POINT,
62 CHAR_AT,
63 CHAR_CODE_AT,
64 CODE_POINT_AT,
65 CONCAT,
66 INDEX_OF,
67 LAST_INDEX_OF,
68 INCLUDES,
69 START_WITH,
70 ENDS_WITH,
71 TO_STRING,
72 VALUE_OF,
73 REPLACE,
74 SPLIT,
75 };
76
StringAlgorithmOther(EcmaRuntimeCallInfo * ecmaRuntimeCallInfos,AlgorithmType type)77 JSTaggedValue StringAlgorithmOther(EcmaRuntimeCallInfo*ecmaRuntimeCallInfos, AlgorithmType type)
78 {
79 switch (type) {
80 case AlgorithmType::START_WITH:
81 return BuiltinsString::StartsWith(ecmaRuntimeCallInfos);
82 case AlgorithmType::ENDS_WITH:
83 return BuiltinsString::EndsWith(ecmaRuntimeCallInfos);
84 case AlgorithmType::TO_STRING:
85 return BuiltinsString::ToString(ecmaRuntimeCallInfos);
86 case AlgorithmType::VALUE_OF:
87 return BuiltinsString::ValueOf(ecmaRuntimeCallInfos);
88 case AlgorithmType::REPLACE:
89 return BuiltinsString::Replace(ecmaRuntimeCallInfos);
90 case AlgorithmType::SPLIT:
91 return BuiltinsString::Split(ecmaRuntimeCallInfos);
92 default:
93 return JSTaggedValue::Undefined();
94 }
95 }
96
StringAlgorithm(JSThread * thread,JSTaggedValue thisArg,std::vector<JSTaggedValue> & args,uint32_t argLen=8,AlgorithmType type=AlgorithmType::FROM_CHAR_CODE)97 JSTaggedValue StringAlgorithm(JSThread *thread, JSTaggedValue thisArg, std::vector<JSTaggedValue>& args,
98 uint32_t argLen = 8, AlgorithmType type = AlgorithmType::FROM_CHAR_CODE)
99 {
100 auto ecmaRuntimeCallInfos = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), argLen);
101 ecmaRuntimeCallInfos->SetFunction(JSTaggedValue::Undefined());
102 ecmaRuntimeCallInfos->SetThis(thisArg);
103 for (size_t i = 0; i < args.size(); i++) {
104 ecmaRuntimeCallInfos->SetCallArg(i, args[i]);
105 }
106 auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfos);
107 JSTaggedValue result;
108 switch (type) {
109 case AlgorithmType::FROM_CHAR_CODE:
110 result = BuiltinsString::FromCharCode(ecmaRuntimeCallInfos);
111 break;
112 case AlgorithmType::FROM_CODE_POINT:
113 result = BuiltinsString::FromCodePoint(ecmaRuntimeCallInfos);
114 break;
115 case AlgorithmType::CHAR_AT:
116 result = BuiltinsString::CharAt(ecmaRuntimeCallInfos);
117 break;
118 case AlgorithmType::CHAR_CODE_AT:
119 result = BuiltinsString::CharCodeAt(ecmaRuntimeCallInfos);
120 break;
121 case AlgorithmType::CODE_POINT_AT:
122 result = BuiltinsString::CodePointAt(ecmaRuntimeCallInfos);
123 break;
124 case AlgorithmType::CONCAT:
125 result = BuiltinsString::Concat(ecmaRuntimeCallInfos);
126 break;
127 case AlgorithmType::INDEX_OF:
128 result = BuiltinsString::IndexOf(ecmaRuntimeCallInfos);
129 break;
130 case AlgorithmType::LAST_INDEX_OF:
131 result = BuiltinsString::LastIndexOf(ecmaRuntimeCallInfos);
132 break;
133 case AlgorithmType::INCLUDES:
134 result = BuiltinsString::Includes(ecmaRuntimeCallInfos);
135 break;
136 default:
137 result = StringAlgorithmOther(ecmaRuntimeCallInfos, type);
138 break;
139 }
140 TestHelper::TearDownFrame(thread, prev);
141 return result;
142 }
143
HWTEST_F_L0(BuiltinsStringTest,StringConstructor1)144 HWTEST_F_L0(BuiltinsStringTest, StringConstructor1)
145 {
146 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
147
148 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
149 JSHandle<JSFunction> string(env->GetStringFunction());
150 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
151 JSHandle<EcmaString> string2 = factory->NewFromASCII("ABC");
152
153 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, string.GetTaggedValue(), 6);
154 ecmaRuntimeCallInfo->SetFunction(string.GetTaggedValue());
155 ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
156 ecmaRuntimeCallInfo->SetCallArg(0, string2.GetTaggedValue());
157
158 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
159 JSTaggedValue result = BuiltinsString::StringConstructor(ecmaRuntimeCallInfo);
160 JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
161 ASSERT_TRUE(value.IsECMAObject());
162 JSHandle<JSPrimitiveRef> ref(thread, JSPrimitiveRef::Cast(value.GetTaggedObject()));
163 JSHandle<EcmaString> test = factory->NewFromASCII("ABC");
164 ASSERT_EQ(EcmaStringAccessor::Compare(instance,
165 JSHandle<EcmaString>(thread, EcmaString::Cast(ref->GetValue(thread))), test), 0);
166 }
167
168 // String.fromCharCode(65, 66, 67)
HWTEST_F_L0(BuiltinsStringTest,fromCharCode1)169 HWTEST_F_L0(BuiltinsStringTest, fromCharCode1)
170 {
171 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
172 const double arg1 = 65;
173 const double arg2 = 66;
174 const double arg3 = 67;
175
176 std::vector<JSTaggedValue> args{JSTaggedValue(arg1), JSTaggedValue(arg2), JSTaggedValue(arg3)};
177 auto result = StringAlgorithm(thread, JSTaggedValue::Undefined(), args, 10, AlgorithmType::FROM_CHAR_CODE);
178
179 ASSERT_TRUE(result.IsString());
180 JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
181 JSHandle<JSTaggedValue> valueHandle(thread, JSTaggedValue(value.GetTaggedObject()));
182 JSHandle<EcmaString> test = factory->NewFromASCII("ABC");
183 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>::Cast(valueHandle), test), 0);
184 }
185
186 // String.fromCodePoint(65, 66, 67)
HWTEST_F_L0(BuiltinsStringTest,fromCodePoint1)187 HWTEST_F_L0(BuiltinsStringTest, fromCodePoint1)
188 {
189 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
190 const double arg1 = 65;
191 const double arg2 = 66;
192 const double arg3 = 67;
193
194 std::vector<JSTaggedValue> args{JSTaggedValue(arg1), JSTaggedValue(arg2), JSTaggedValue(arg3)};
195 auto result = StringAlgorithm(thread, JSTaggedValue::Undefined(), args, 10, AlgorithmType::FROM_CODE_POINT);
196
197 ASSERT_TRUE(result.IsString());
198 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
199 JSHandle<EcmaString> test = factory->NewFromASCII("ABC");
200 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
201 }
202
203 // "abcabcabc".charAt(5)
HWTEST_F_L0(BuiltinsStringTest,charAt1)204 HWTEST_F_L0(BuiltinsStringTest, charAt1)
205 {
206 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
207 JSHandle<EcmaString> thisVal = factory->NewFromASCII("abcabcabc");
208
209 std::vector<JSTaggedValue> args{JSTaggedValue(static_cast<double>(5))};
210 auto result = StringAlgorithm(thread, thisVal.GetTaggedValue(), args, 6, AlgorithmType::CHAR_AT);
211
212 ASSERT_TRUE(result.IsString());
213 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
214 JSHandle<EcmaString> test = factory->NewFromASCII("c");
215 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
216 }
217
218 // "一二三四".charAt(2)
HWTEST_F_L0(BuiltinsStringTest,charAt2)219 HWTEST_F_L0(BuiltinsStringTest, charAt2)
220 {
221 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
222 JSHandle<EcmaString> thisVal = factory->NewFromUtf8("一二三四");
223
224 std::vector<JSTaggedValue> args{JSTaggedValue(static_cast<double>(2))};
225 auto result = StringAlgorithm(thread, thisVal.GetTaggedValue(), args, 6, AlgorithmType::CHAR_AT);
226
227 ASSERT_TRUE(result.IsString());
228 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
229 JSHandle<EcmaString> test = factory->NewFromUtf8("三");
230 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
231 }
232
233 // "abcabcabc".charAt(-1)
HWTEST_F_L0(BuiltinsStringTest,charAt3)234 HWTEST_F_L0(BuiltinsStringTest, charAt3)
235 {
236 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
237 JSHandle<EcmaString> thisVal = factory->NewFromASCII("abcabcabc");
238
239 std::vector<JSTaggedValue> args{JSTaggedValue(static_cast<double>(-1))};
240 auto result = StringAlgorithm(thread, thisVal.GetTaggedValue(), args, 6, AlgorithmType::CHAR_AT);
241
242 ASSERT_TRUE(result.IsString());
243 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
244 JSHandle<EcmaString> test = factory->GetEmptyString();
245 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
246 }
247
248 // "ABC".charCodeAt(0)
HWTEST_F_L0(BuiltinsStringTest,charCodeAt1)249 HWTEST_F_L0(BuiltinsStringTest, charCodeAt1)
250 {
251 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
252 JSHandle<EcmaString> thisVal = factory->NewFromASCII("ABC");
253
254 std::vector<JSTaggedValue> args{JSTaggedValue(static_cast<double>(0))};
255 auto result = StringAlgorithm(thread, thisVal.GetTaggedValue(), args, 6, AlgorithmType::CHAR_CODE_AT);
256
257 ASSERT_EQ(result.GetRawData(), JSTaggedValue(65).GetRawData());
258 }
259
260 // "ABC".charCodeAt(-1)
HWTEST_F_L0(BuiltinsStringTest,charCodeAt2)261 HWTEST_F_L0(BuiltinsStringTest, charCodeAt2)
262 {
263 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
264 JSHandle<EcmaString> thisVal = factory->NewFromASCII("ABC");
265
266 std::vector<JSTaggedValue> args{JSTaggedValue(static_cast<double>(-1))};
267 auto result = StringAlgorithm(thread, thisVal.GetTaggedValue(), args, 6, AlgorithmType::CHAR_CODE_AT);
268
269 JSTaggedValue test = BuiltinsString::GetTaggedDouble(base::NAN_VALUE);
270 ASSERT_EQ(result.GetRawData(), test.GetRawData());
271 }
272
273 // "ABC".codePointAt(1)
HWTEST_F_L0(BuiltinsStringTest,codePointAt1)274 HWTEST_F_L0(BuiltinsStringTest, codePointAt1)
275 {
276 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
277 JSHandle<EcmaString> thisVal = factory->NewFromASCII("ABC");
278
279 std::vector<JSTaggedValue> args{JSTaggedValue(static_cast<double>(1))};
280 auto result = StringAlgorithm(thread, thisVal.GetTaggedValue(), args, 6, AlgorithmType::CODE_POINT_AT);
281
282 ASSERT_EQ(result.GetRawData(), JSTaggedValue(66).GetRawData());
283 }
284
285 // 'a'.concat('b', 'c', 'd')
HWTEST_F_L0(BuiltinsStringTest,concat1)286 HWTEST_F_L0(BuiltinsStringTest, concat1)
287 {
288 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
289 JSHandle<EcmaString> thisStr = factory->NewFromASCII("a");
290 JSHandle<EcmaString> val1 = factory->NewFromASCII("b");
291 JSHandle<EcmaString> val2 = factory->NewFromASCII("c");
292 JSHandle<EcmaString> val3 = factory->NewFromASCII("d");
293
294 std::vector<JSTaggedValue> args{val1.GetTaggedValue(), val2.GetTaggedValue(), val3.GetTaggedValue()};
295 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 10, AlgorithmType::CONCAT);
296
297 ASSERT_TRUE(result.IsString());
298 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
299 JSHandle<EcmaString> test = factory->NewFromASCII("abcd");
300 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
301 }
302
303 // "abcabcabc".indexof('b')
HWTEST_F_L0(BuiltinsStringTest,indexof1)304 HWTEST_F_L0(BuiltinsStringTest, indexof1)
305 {
306 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
307 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
308 JSHandle<EcmaString> val = factory->NewFromASCII("b");
309
310 std::vector<JSTaggedValue> args{val.GetTaggedValue()};
311 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::INDEX_OF);
312
313 ASSERT_EQ(result.GetRawData(), JSTaggedValue(1).GetRawData());
314 }
315
316 // "abcabcabc".indexof('b', 2)
HWTEST_F_L0(BuiltinsStringTest,indexof2)317 HWTEST_F_L0(BuiltinsStringTest, indexof2)
318 {
319 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
320 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
321 JSHandle<EcmaString> val = factory->NewFromASCII("b");
322
323 std::vector<JSTaggedValue> args{val.GetTaggedValue(), JSTaggedValue(static_cast<double>(2))};
324 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::INDEX_OF);
325
326 ASSERT_EQ(result.GetRawData(), JSTaggedValue(4).GetRawData());
327 }
328
329 // "abcabcabc".indexof('d')
HWTEST_F_L0(BuiltinsStringTest,indexof3)330 HWTEST_F_L0(BuiltinsStringTest, indexof3)
331 {
332 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
333 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
334 JSHandle<EcmaString> val = factory->NewFromASCII("d");
335
336 std::vector<JSTaggedValue> args{val.GetTaggedValue()};
337 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::INDEX_OF);
338
339 ASSERT_EQ(result.GetRawData(), JSTaggedValue(-1).GetRawData());
340 }
341
342 // "abcabcabc".lastIndexOf('b')
HWTEST_F_L0(BuiltinsStringTest,lastIndexOf1)343 HWTEST_F_L0(BuiltinsStringTest, lastIndexOf1)
344 {
345 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
346 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
347 JSHandle<EcmaString> val = factory->NewFromASCII("b");
348
349 std::vector<JSTaggedValue> args{val.GetTaggedValue()};
350 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::LAST_INDEX_OF);
351
352 ASSERT_EQ(result.GetRawData(), JSTaggedValue(7).GetRawData());
353 }
354 // "abcabcabc".lastIndexOf('b', 2)
HWTEST_F_L0(BuiltinsStringTest,lastIndexOf2)355 HWTEST_F_L0(BuiltinsStringTest, lastIndexOf2)
356 {
357 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
358 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
359 JSHandle<EcmaString> val = factory->NewFromASCII("b");
360
361 std::vector<JSTaggedValue> args{val.GetTaggedValue(), JSTaggedValue(static_cast<double>(2))};
362 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::LAST_INDEX_OF);
363
364 ASSERT_EQ(result.GetRawData(), JSTaggedValue(1).GetRawData());
365 }
366
367 // "abcabcabc".lastIndexOf('d')
HWTEST_F_L0(BuiltinsStringTest,lastIndexOf3)368 HWTEST_F_L0(BuiltinsStringTest, lastIndexOf3)
369 {
370 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
371 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
372 JSHandle<EcmaString> val = factory->NewFromASCII("d");
373
374 std::vector<JSTaggedValue> args{val.GetTaggedValue()};
375 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::LAST_INDEX_OF);
376
377 ASSERT_EQ(result.GetRawData(), JSTaggedValue(-1).GetRawData());
378 }
379
380 // "abcabcabc".includes('b')
HWTEST_F_L0(BuiltinsStringTest,Includes2)381 HWTEST_F_L0(BuiltinsStringTest, Includes2)
382 {
383 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
384 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
385 JSHandle<EcmaString> val = factory->NewFromASCII("b");
386
387 std::vector<JSTaggedValue> args{val.GetTaggedValue()};
388 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::INCLUDES);
389
390 ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
391 }
392
393 // "abccccccc".includes('b',2)
HWTEST_F_L0(BuiltinsStringTest,Includes3)394 HWTEST_F_L0(BuiltinsStringTest, Includes3)
395 {
396 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
397 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abccccccc");
398 JSHandle<EcmaString> val = factory->NewFromASCII("b");
399
400 std::vector<JSTaggedValue> args{val.GetTaggedValue(), JSTaggedValue(static_cast<double>(2))};
401 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::INCLUDES);
402
403 ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
404 }
405
406 // "一二三四".includes('二')
HWTEST_F_L0(BuiltinsStringTest,Includes4)407 HWTEST_F_L0(BuiltinsStringTest, Includes4)
408 {
409 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
410 JSHandle<EcmaString> thisStr = factory->NewFromUtf8("一二三四");
411 JSHandle<EcmaString> val = factory->NewFromUtf8("二");
412
413 std::vector<JSTaggedValue> args{val.GetTaggedValue()};
414 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::INCLUDES);
415
416 ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
417 }
418
419 // "To be, or not to be, that is the question.".startsWith('To be')
HWTEST_F_L0(BuiltinsStringTest,startsWith1)420 HWTEST_F_L0(BuiltinsStringTest, startsWith1)
421 {
422 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
423 JSHandle<EcmaString> thisStr = factory->NewFromASCII("To be, or not to be, that is the question.");
424 JSHandle<EcmaString> val = factory->NewFromASCII("To be");
425
426 std::vector<JSTaggedValue> args{val.GetTaggedValue()};
427 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::START_WITH);
428
429 ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
430 }
431
432 // "To be, or not to be, that is the question.".startsWith('not to be')
HWTEST_F_L0(BuiltinsStringTest,startsWith2)433 HWTEST_F_L0(BuiltinsStringTest, startsWith2)
434 {
435 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
436 JSHandle<EcmaString> thisStr = factory->NewFromASCII("To be, or not to be, that is the question.");
437 JSHandle<EcmaString> val = factory->NewFromASCII("not to be");
438
439 std::vector<JSTaggedValue> args{val.GetTaggedValue()};
440 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::START_WITH);
441
442 ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
443 }
444
445 // "To be, or not to be, that is the question.".startsWith('not to be', 10)
HWTEST_F_L0(BuiltinsStringTest,startsWith3)446 HWTEST_F_L0(BuiltinsStringTest, startsWith3)
447 {
448 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
449 JSHandle<EcmaString> thisStr = factory->NewFromASCII("To be, or not to be, that is the question.");
450 JSHandle<EcmaString> val = factory->NewFromASCII("not to be");
451
452 std::vector<JSTaggedValue> args{val.GetTaggedValue(), JSTaggedValue(static_cast<double>(10))};
453 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::START_WITH);
454
455 ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
456 }
457
458 // "To be, or not to be, that is the question.".endsWith('question.')
HWTEST_F_L0(BuiltinsStringTest,endsWith1)459 HWTEST_F_L0(BuiltinsStringTest, endsWith1)
460 {
461 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
462 JSHandle<EcmaString> thisStr = factory->NewFromASCII("To be, or not to be, that is the question.");
463 JSHandle<EcmaString> val = factory->NewFromASCII("question.");
464
465 std::vector<JSTaggedValue> args{val.GetTaggedValue()};
466 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::ENDS_WITH);
467
468 ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
469 }
470
471 // "To be, or not to be, that is the question.".endsWith('to be')
HWTEST_F_L0(BuiltinsStringTest,endsWith2)472 HWTEST_F_L0(BuiltinsStringTest, endsWith2)
473 {
474 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
475 JSHandle<EcmaString> thisStr = factory->NewFromASCII("To be, or not to be, that is the question.");
476 JSHandle<EcmaString> val = factory->NewFromASCII("to be");
477
478 std::vector<JSTaggedValue> args{val.GetTaggedValue()};
479 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::ENDS_WITH);
480
481 ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
482 }
483
484 // "To be, or not to be, that is the question.".endsWith('to be', 19)
HWTEST_F_L0(BuiltinsStringTest,endsWith3)485 HWTEST_F_L0(BuiltinsStringTest, endsWith3)
486 {
487 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
488 JSHandle<EcmaString> thisStr = factory->NewFromASCII("To be, or not to be, that is the question.");
489 JSHandle<EcmaString> val = factory->NewFromASCII("to be");
490
491 std::vector<JSTaggedValue> args{val.GetTaggedValue(), JSTaggedValue(static_cast<double>(19))};
492 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::ENDS_WITH);
493
494 ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
495 }
496
497 // "有ABC".toLocaleLowerCase()
HWTEST_F_L0(BuiltinsStringTest,toLocaleLowerCase2)498 HWTEST_F_L0(BuiltinsStringTest, toLocaleLowerCase2)
499 {
500 ASSERT_NE(thread, nullptr);
501 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
502 JSHandle<EcmaString> thisStr = factory->NewFromUtf8("有ABC");
503
504 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
505 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
506 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
507
508 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
509 JSTaggedValue result = BuiltinsString::ToLocaleLowerCase(ecmaRuntimeCallInfo);
510 ASSERT_TRUE(result.IsString());
511 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
512 JSHandle<EcmaString> test = factory->NewFromUtf8("有abc");
513 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
514 }
515
516 // "ABC".toLowerCase()
HWTEST_F_L0(BuiltinsStringTest,toLowerCase1)517 HWTEST_F_L0(BuiltinsStringTest, toLowerCase1)
518 {
519 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
520 JSHandle<EcmaString> thisStr = factory->NewFromASCII("ABC");
521
522 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
523 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
524 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
525
526 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
527 JSTaggedValue result = BuiltinsString::ToLowerCase(ecmaRuntimeCallInfo);
528 ASSERT_TRUE(result.IsString());
529 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
530 JSHandle<EcmaString> test = factory->NewFromASCII("abc");
531 ASSERT_TRUE(JSTaggedValue::SameValue(thread, resultHandle.GetTaggedValue(), test.GetTaggedValue()));
532 }
533
534 // "abc".toUpperCase()
HWTEST_F_L0(BuiltinsStringTest,toUpperCase1)535 HWTEST_F_L0(BuiltinsStringTest, toUpperCase1)
536 {
537 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
538 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abc");
539
540 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
541 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
542 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
543
544 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
545 JSTaggedValue result = BuiltinsString::ToUpperCase(ecmaRuntimeCallInfo);
546 ASSERT_TRUE(result.IsString());
547 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
548 JSHandle<EcmaString> test = factory->NewFromASCII("ABC");
549 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
550 }
551
552 // "abc".localecompare('b')
HWTEST_F_L0(BuiltinsStringTest,localecompare1)553 HWTEST_F_L0(BuiltinsStringTest, localecompare1)
554 {
555 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
556 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abc");
557 JSHandle<EcmaString> val = factory->NewFromASCII("b");
558
559 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
560 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
561 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
562 ecmaRuntimeCallInfo->SetCallArg(0, val.GetTaggedValue());
563
564 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
565 JSTaggedValue result = BuiltinsString::LocaleCompare(ecmaRuntimeCallInfo);
566
567 ASSERT_EQ(result.GetRawData(), JSTaggedValue(-1).GetRawData());
568 }
569
570 // "abc".localecompare('abc')
HWTEST_F_L0(BuiltinsStringTest,localecompare2)571 HWTEST_F_L0(BuiltinsStringTest, localecompare2)
572 {
573 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
574 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abc");
575 JSHandle<EcmaString> val = factory->NewFromASCII("abc");
576
577 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
578 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
579 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
580 ecmaRuntimeCallInfo->SetCallArg(0, val.GetTaggedValue());
581
582 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
583 JSTaggedValue result = BuiltinsString::LocaleCompare(ecmaRuntimeCallInfo);
584
585 ASSERT_EQ(result.GetRawData(), JSTaggedValue(0).GetRawData());
586 }
587
588 // "abc".localecompare('aa')
HWTEST_F_L0(BuiltinsStringTest,localecompare3)589 HWTEST_F_L0(BuiltinsStringTest, localecompare3)
590 {
591 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
592 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abc");
593 JSHandle<EcmaString> val = factory->NewFromASCII("aa");
594
595 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
596 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
597 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
598 ecmaRuntimeCallInfo->SetCallArg(0, val.GetTaggedValue());
599
600 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
601 JSTaggedValue result = BuiltinsString::LocaleCompare(ecmaRuntimeCallInfo);
602
603 ASSERT_EQ(result.GetRawData(), JSTaggedValue(1).GetRawData());
604 }
605
606 // "你好".localecompare('辅助')
HWTEST_F_L0(BuiltinsStringTest,localecompare4)607 HWTEST_F_L0(BuiltinsStringTest, localecompare4)
608 {
609 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
610 std::string referenceStr = "你好";
611 std::string compareStr = "辅助";
612 JSHandle<EcmaString> thisStr = factory->NewFromStdString(referenceStr);
613 JSHandle<EcmaString> val = factory->NewFromStdString(compareStr);
614 JSHandle<EcmaString> locale = factory->NewFromASCII("zh-Hans");
615
616 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
617 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
618 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
619 ecmaRuntimeCallInfo->SetCallArg(0, val.GetTaggedValue());
620 ecmaRuntimeCallInfo->SetCallArg(1, locale.GetTaggedValue());
621
622 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
623 JSTaggedValue result = BuiltinsString::LocaleCompare(ecmaRuntimeCallInfo);
624 TestHelper::TearDownFrame(thread, prev);
625
626 ASSERT_GT(result.GetRawData(), JSTaggedValue(0).GetRawData());
627 }
628
629 // Test localeCompare when locales changed
HWTEST_F_L0(BuiltinsStringTest,localecompare5)630 HWTEST_F_L0(BuiltinsStringTest, localecompare5)
631 {
632 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
633 std::string referenceStr = "ä";
634 std::string compareStr = "z";
635 JSHandle<EcmaString> thisStr = factory->NewFromStdString(referenceStr);
636 JSHandle<EcmaString> val = factory->NewFromStdString(compareStr);
637 JSHandle<EcmaString> locale = factory->NewFromASCII("de");
638
639 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
640 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
641 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
642 ecmaRuntimeCallInfo->SetCallArg(0, val.GetTaggedValue());
643 ecmaRuntimeCallInfo->SetCallArg(1, locale.GetTaggedValue());
644
645 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
646 JSTaggedValue result = BuiltinsString::LocaleCompare(ecmaRuntimeCallInfo);
647 TestHelper::TearDownFrame(thread, prev1);
648 ASSERT_EQ(result.GetRawData(), JSTaggedValue(-1).GetRawData());
649
650 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
651 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
652 ecmaRuntimeCallInfo1->SetThis(thisStr.GetTaggedValue());
653 ecmaRuntimeCallInfo1->SetCallArg(0, val.GetTaggedValue());
654 // change locale
655 ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue::Undefined());
656 [[maybe_unused]] auto prev2 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
657 JSTaggedValue result1 = BuiltinsString::LocaleCompare(ecmaRuntimeCallInfo1);
658 TestHelper::TearDownFrame(thread, prev2);
659 ASSERT_EQ(result1.GetRawData(), JSTaggedValue(-1).GetRawData());
660 }
661
662 // "abc".normalize('NFC')
HWTEST_F_L0(BuiltinsStringTest,normalize1)663 HWTEST_F_L0(BuiltinsStringTest, normalize1)
664 {
665 ASSERT_NE(thread, nullptr);
666 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
667 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abc");
668 JSHandle<EcmaString> val = factory->NewFromASCII("NFC");
669
670 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
671 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
672 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
673 ecmaRuntimeCallInfo->SetCallArg(0, val.GetTaggedValue());
674
675 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
676 JSTaggedValue result = BuiltinsString::Normalize(ecmaRuntimeCallInfo);
677 ASSERT_TRUE(result.IsString());
678 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
679 JSHandle<EcmaString> test = factory->NewFromASCII("abc");
680 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
681 }
682
683 // "abc".repeat(5)
HWTEST_F_L0(BuiltinsStringTest,repeat1)684 HWTEST_F_L0(BuiltinsStringTest, repeat1)
685 {
686 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
687 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abc");
688
689 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
690 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
691 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
692 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(5)));
693
694 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
695 JSTaggedValue result = BuiltinsString::Repeat(ecmaRuntimeCallInfo);
696 ASSERT_TRUE(result.IsString());
697 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
698 JSHandle<EcmaString> test = factory->NewFromASCII("abcabcabcabcabc");
699 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
700 }
701
702 // 'The morning is upon us.'.slice(4, -2)
HWTEST_F_L0(BuiltinsStringTest,slice1)703 HWTEST_F_L0(BuiltinsStringTest, slice1)
704 {
705 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
706 JSHandle<EcmaString> thisStr = factory->NewFromASCII("The morning is upon us.");
707
708 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
709 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
710 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
711 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(4)));
712 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<double>(-2)));
713
714 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
715 JSTaggedValue result = BuiltinsString::Slice(ecmaRuntimeCallInfo);
716 ASSERT_TRUE(result.IsString());
717 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
718 JSHandle<EcmaString> test = factory->NewFromASCII("morning is upon u");
719 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
720 }
721
722 // 'The morning is upon us.'.slice(12)
HWTEST_F_L0(BuiltinsStringTest,slice2)723 HWTEST_F_L0(BuiltinsStringTest, slice2)
724 {
725 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
726 JSHandle<EcmaString> thisStr = factory->NewFromASCII("The morning is upon us.");
727
728 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
729 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
730 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
731 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(12)));
732
733 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
734 JSTaggedValue result = BuiltinsString::Slice(ecmaRuntimeCallInfo);
735 ASSERT_TRUE(result.IsString());
736 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
737 JSHandle<EcmaString> test = factory->NewFromASCII("is upon us.");
738 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
739 }
740
741 // 'Mozilla'.substring(3, -3)
HWTEST_F_L0(BuiltinsStringTest,substring1)742 HWTEST_F_L0(BuiltinsStringTest, substring1)
743 {
744 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
745 JSHandle<EcmaString> thisStr = factory->NewFromASCII("Mozilla");
746
747 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
748 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
749 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
750 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(3)));
751 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<double>(-3)));
752
753 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
754 JSTaggedValue result = BuiltinsString::Substring(ecmaRuntimeCallInfo);
755 ASSERT_TRUE(result.IsString());
756 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
757 JSHandle<EcmaString> test = factory->NewFromASCII("Moz");
758 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
759 }
760
761 // 'Mozilla'.substring(7, 4)
HWTEST_F_L0(BuiltinsStringTest,substring2)762 HWTEST_F_L0(BuiltinsStringTest, substring2)
763 {
764 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
765 JSHandle<EcmaString> thisStr = factory->NewFromASCII("Mozilla");
766
767 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
768 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
769 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
770 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(7)));
771 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<double>(4)));
772
773 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
774 JSTaggedValue result = BuiltinsString::Substring(ecmaRuntimeCallInfo);
775 ASSERT_TRUE(result.IsString());
776 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
777 JSHandle<EcmaString> test = factory->NewFromASCII("lla");
778 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
779 }
780
781 // " Hello world! ".trim()
HWTEST_F_L0(BuiltinsStringTest,trim1)782 HWTEST_F_L0(BuiltinsStringTest, trim1)
783 {
784 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
785 JSHandle<EcmaString> thisStr = factory->NewFromASCII(" Hello world! ");
786
787 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
788 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
789 ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
790
791 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
792 JSTaggedValue result = BuiltinsString::Trim(ecmaRuntimeCallInfo);
793 ASSERT_TRUE(result.IsString());
794 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
795 JSHandle<EcmaString> test = factory->NewFromASCII("Hello world!");
796 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
797 }
798
HWTEST_F_L0(BuiltinsStringTest,trim2)799 HWTEST_F_L0(BuiltinsStringTest, trim2)
800 {
801 auto ecmaVM = thread->GetEcmaVM();
802 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
803
804 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
805 JSHandle<EcmaString> thisStr = factory->NewFromASCII(" Hello world! ");
806 JSHandle<JSFunction> stringObject(env->GetStringFunction());
807 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(thisStr.GetTaggedValue().GetTaggedObject()));
808 JSHandle<JSPrimitiveRef> str = factory->NewJSPrimitiveRef(stringObject, value);
809
810 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
811 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
812 ecmaRuntimeCallInfo->SetThis(str.GetTaggedValue());
813
814 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
815 JSTaggedValue result = BuiltinsString::Trim(ecmaRuntimeCallInfo);
816 ASSERT_TRUE(result.IsString());
817 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
818 JSHandle<EcmaString> test = factory->NewFromASCII("Hello world!");
819 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
820 }
821
HWTEST_F_L0(BuiltinsStringTest,trimRight)822 HWTEST_F_L0(BuiltinsStringTest, trimRight)
823 {
824 auto ecmaVM = thread->GetEcmaVM();
825 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
826
827 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
828 JSHandle<EcmaString> thisStr = factory->NewFromASCII(" ");
829 JSHandle<JSFunction> stringObject(env->GetStringFunction());
830 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(thisStr.GetTaggedValue().GetTaggedObject()));
831 JSHandle<JSPrimitiveRef> str = factory->NewJSPrimitiveRef(stringObject, value);
832
833 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
834 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
835 ecmaRuntimeCallInfo->SetThis(str.GetTaggedValue());
836
837 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
838 JSTaggedValue result = BuiltinsString::TrimRight(ecmaRuntimeCallInfo);
839 ASSERT_TRUE(result.IsString());
840 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
841 JSHandle<EcmaString> test = factory->NewFromASCII("");
842 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
843 }
844
HWTEST_F_L0(BuiltinsStringTest,ToString)845 HWTEST_F_L0(BuiltinsStringTest, ToString)
846 {
847 auto ecmaVM = thread->GetEcmaVM();
848 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
849
850 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
851 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
852 JSHandle<JSFunction> stringObject(env->GetStringFunction());
853 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(thisStr.GetTaggedValue().GetTaggedObject()));
854 JSHandle<JSPrimitiveRef> str = factory->NewJSPrimitiveRef(stringObject, value);
855
856 std::vector<JSTaggedValue> args{};
857 auto result = StringAlgorithm(thread, str.GetTaggedValue(), args, 4, AlgorithmType::TO_STRING);
858
859 ASSERT_TRUE(result.IsString());
860 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
861 JSTaggedValue test = JSTaggedValue(*thisStr);
862 ASSERT_EQ(result.GetRawData(), test.GetRawData());
863 }
864
HWTEST_F_L0(BuiltinsStringTest,ValueOf)865 HWTEST_F_L0(BuiltinsStringTest, ValueOf)
866 {
867 auto ecmaVM = thread->GetEcmaVM();
868 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
869
870 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
871 JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
872 JSHandle<JSFunction> stringObject(env->GetStringFunction());
873 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(thisStr.GetTaggedValue().GetTaggedObject()));
874 JSHandle<JSPrimitiveRef> str = factory->NewJSPrimitiveRef(stringObject, value);
875
876 std::vector<JSTaggedValue> args{};
877 auto result = StringAlgorithm(thread, str.GetTaggedValue(), args, 4, AlgorithmType::VALUE_OF);
878
879 ASSERT_TRUE(result.IsString());
880 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
881 JSTaggedValue test = JSTaggedValue(*thisStr);
882 ASSERT_EQ(result.GetRawData(), test.GetRawData());
883 }
884
BuiltinsStringTestCreate(JSThread * thread)885 static inline JSFunction *BuiltinsStringTestCreate(JSThread *thread)
886 {
887 EcmaVM *ecmaVM = thread->GetEcmaVM();
888 JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
889 return globalEnv->GetObjectFunction().GetObject<JSFunction>();
890 }
891
HWTEST_F_L0(BuiltinsStringTest,Raw)892 HWTEST_F_L0(BuiltinsStringTest, Raw)
893 {
894 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
895 JSHandle<JSTaggedValue> foo(factory->NewFromASCII("foo"));
896 JSHandle<JSTaggedValue> bar(factory->NewFromASCII("bar"));
897 JSHandle<JSTaggedValue> baz(factory->NewFromASCII("baz"));
898 JSHandle<JSTaggedValue> rawArray = JSHandle<JSTaggedValue>::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)));
899 JSHandle<JSObject> obj(rawArray);
900 JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
901 PropertyDescriptor desc0(thread, foo);
902 JSArray::DefineOwnProperty(thread, obj, key0, desc0);
903 JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
904 PropertyDescriptor desc1(thread, bar);
905 JSArray::DefineOwnProperty(thread, obj, key1, desc1);
906 JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(2));
907 PropertyDescriptor desc2(thread, baz);
908 JSArray::DefineOwnProperty(thread, obj, key2, desc2);
909
910 JSHandle<JSTaggedValue> constructor(thread, BuiltinsStringTestCreate(thread));
911 JSHandle<JSTaggedValue> templateString(
912 factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
913 JSHandle<JSTaggedValue> rawKey(factory->NewFromASCII("raw"));
914 JSObject::SetProperty(thread, templateString, rawKey, rawArray);
915 JSHandle<EcmaString> test = factory->NewFromASCII("foo5barJavaScriptbaz");
916
917 JSHandle<EcmaString> javascript = factory->NewFromASCII("JavaScript");
918
919 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
920 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
921 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
922 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(templateString.GetObject<EcmaString>()));
923 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(5)));
924 ecmaRuntimeCallInfo->SetCallArg(2, javascript.GetTaggedValue());
925
926 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
927 JSTaggedValue result = BuiltinsString::Raw(ecmaRuntimeCallInfo);
928 ASSERT_TRUE(result.IsString());
929 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, reinterpret_cast<EcmaString *>(result.GetRawData()),
930 *test));
931 }
932
HWTEST_F_L0(BuiltinsStringTest,Replace)933 HWTEST_F_L0(BuiltinsStringTest, Replace)
934 {
935 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
936 JSHandle<EcmaString> thisStr = factory->NewFromASCII("Twas the night before Xmas...");
937 JSHandle<EcmaString> searchStr = factory->NewFromASCII("Xmas");
938 JSHandle<EcmaString> replaceStr = factory->NewFromASCII("Christmas");
939 JSHandle<EcmaString> expected = factory->NewFromASCII("Twas the night before Christmas...");
940
941 std::vector<JSTaggedValue> args{searchStr.GetTaggedValue(), replaceStr.GetTaggedValue()};
942 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
943
944 ASSERT_TRUE(result.IsString());
945 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, reinterpret_cast<EcmaString *>(result.GetRawData()),
946 *expected));
947
948 JSHandle<EcmaString> replaceStr1 = factory->NewFromASCII("abc$$");
949 JSHandle<EcmaString> expected1 = factory->NewFromASCII("Twas the night before abc$...");
950 args[0] = searchStr.GetTaggedValue();
951 args[1] = replaceStr1.GetTaggedValue();
952 auto result1 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
953
954 JSHandle<EcmaString> resultString1(thread, result1);
955 ASSERT_TRUE(result1.IsString());
956 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString1, *expected1));
957
958 JSHandle<EcmaString> replaceStr2 = factory->NewFromASCII("abc$$dd");
959 JSHandle<EcmaString> expected2 = factory->NewFromASCII("Twas the night before abc$dd...");
960 args[0] = searchStr.GetTaggedValue();
961 args[1] = replaceStr2.GetTaggedValue();
962 auto result2 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
963
964 JSHandle<EcmaString> resultString2(thread, result2);
965 ASSERT_TRUE(result2.IsString());
966 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString2, *expected2));
967
968 JSHandle<EcmaString> replaceStr3 = factory->NewFromASCII("abc$&dd");
969 JSHandle<EcmaString> expected3 = factory->NewFromASCII("Twas the night before abcXmasdd...");
970 args[0] = searchStr.GetTaggedValue();
971 args[1] = replaceStr3.GetTaggedValue();
972 auto result3 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
973
974 JSHandle<EcmaString> resultString3(thread, result3);
975 ASSERT_TRUE(result3.IsString());
976 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString3, *expected3));
977
978 JSHandle<EcmaString> replaceStr4 = factory->NewFromASCII("abc$`dd");
979 JSHandle<EcmaString> expected4 =
980 factory->NewFromASCII("Twas the night before abcTwas the night before dd...");
981 args[0] = searchStr.GetTaggedValue();
982 args[1] = replaceStr4.GetTaggedValue();
983 auto result4 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
984
985 JSHandle<EcmaString> resultString4(thread, result4);
986 ASSERT_TRUE(result4.IsString());
987 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString4, *expected4));
988 }
989
HWTEST_F_L0(BuiltinsStringTest,Replace2)990 HWTEST_F_L0(BuiltinsStringTest, Replace2)
991 {
992 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
993 JSHandle<EcmaString> thisStr = factory->NewFromASCII("Twas the night before Xmas...");
994 JSHandle<EcmaString> searchStr = factory->NewFromASCII("Xmas");
995 JSHandle<EcmaString> replaceStr = factory->NewFromASCII("abc$\'dd");
996 JSHandle<EcmaString> expected = factory->NewFromASCII("Twas the night before abc...dd...");
997
998 std::vector<JSTaggedValue> args{searchStr.GetTaggedValue(), replaceStr.GetTaggedValue()};
999 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
1000
1001 ASSERT_TRUE(result.IsString());
1002 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, reinterpret_cast<EcmaString *>(result.GetRawData()),
1003 *expected));
1004
1005 JSHandle<EcmaString> replaceStr2 = factory->NewFromASCII("abc$`dd$\'$ff");
1006 JSHandle<EcmaString> expected2 =
1007 factory->NewFromASCII("Twas the night before abcTwas the night before dd...$ff...");
1008 args[0] = searchStr.GetTaggedValue();
1009 args[1] = replaceStr2.GetTaggedValue();
1010 auto result2 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
1011
1012
1013 JSHandle<EcmaString> resultString2(thread, result2);
1014 ASSERT_TRUE(result2.IsString());
1015 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString2, *expected2));
1016
1017 JSHandle<EcmaString> replaceStr3 = factory->NewFromASCII("abc$`dd$\'$");
1018 JSHandle<EcmaString> expected3 =
1019 factory->NewFromASCII("Twas the night before abcTwas the night before dd...$...");
1020 args[0] = searchStr.GetTaggedValue();
1021 args[1] = replaceStr3.GetTaggedValue();
1022 auto result3 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
1023
1024 JSHandle<EcmaString> resultString3(thread, result3);
1025 ASSERT_TRUE(result3.IsString());
1026 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString3, *expected3));
1027
1028 JSHandle<EcmaString> replaceStr4 = factory->NewFromASCII("abc$`dd$$");
1029 JSHandle<EcmaString> expected4 =
1030 factory->NewFromASCII("Twas the night before abcTwas the night before dd$...");
1031 args[0] = searchStr.GetTaggedValue();
1032 args[1] = replaceStr4.GetTaggedValue();
1033 auto result4 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
1034
1035 ASSERT_TRUE(result4.IsString());
1036 JSHandle<EcmaString> resultString4(thread, result4);
1037 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString4, *expected4));
1038 }
1039
HWTEST_F_L0(BuiltinsStringTest,Replace3)1040 HWTEST_F_L0(BuiltinsStringTest, Replace3)
1041 {
1042 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1043 JSHandle<EcmaString> thisStr = factory->NewFromASCII("Twas the night before Xmas...");
1044 JSHandle<EcmaString> searchStr = factory->NewFromASCII("Xmas");
1045 JSHandle<EcmaString> replaceStr = factory->NewFromASCII("$&a $` $\' $2 $01 $$1 $21 $32 a");
1046 JSHandle<EcmaString> expected = factory->NewFromASCII(
1047 "Twas the night before Xmasa Twas the night before ... $2 $01 $1 $21 $32 a...");
1048
1049 std::vector<JSTaggedValue> args{searchStr.GetTaggedValue(), replaceStr.GetTaggedValue()};
1050 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
1051
1052 ASSERT_TRUE(result.IsString());
1053 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, reinterpret_cast<EcmaString *>(result.GetRawData()),
1054 *expected));
1055 }
1056
HWTEST_F_L0(BuiltinsStringTest,Replace4)1057 HWTEST_F_L0(BuiltinsStringTest, Replace4)
1058 {
1059 // invoke RegExpConstructor method
1060 JSHandle<EcmaString> pattern1 =
1061 thread->GetEcmaVM()->GetFactory()->NewFromASCII("quick\\s(brown).+?(jumps)");
1062 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("iug");
1063 JSTaggedValue result1 = CreateBuiltinsStringRegExpObjByPatternAndFlags(thread, pattern1, flags1);
1064 JSHandle<JSRegExp> searchStr(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData()));
1065 JSHandle<EcmaString> expected = thread->GetEcmaVM()->GetFactory()->NewFromASCII(
1066 "The Quick Brown Fox Jumpsa The Over The Lazy Dog Jumps Brown $1 Jumps1 $32 a Over The Lazy Dog");
1067
1068 // make ecma_runtime_call_info2
1069 JSHandle<EcmaString> thisStr =
1070 thread->GetEcmaVM()->GetFactory()->NewFromASCII("The Quick Brown Fox Jumps Over The Lazy Dog");
1071 JSHandle<EcmaString> replaceStr =
1072 thread->GetEcmaVM()->GetFactory()->NewFromASCII("$&a $` $\' $2 $01 $$1 $21 $32 a");
1073
1074 std::vector<JSTaggedValue> args{searchStr.GetTaggedValue(), replaceStr.GetTaggedValue()};
1075 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
1076
1077 ASSERT_TRUE(result.IsString());
1078 ASSERT_TRUE(
1079 EcmaStringAccessor::StringsAreEqual(thread, reinterpret_cast<EcmaString *>(result.GetRawData()), *expected));
1080 }
1081
SplitCommon(JSThread * thread,std::vector<JSHandle<EcmaString>> expecteds,JSHandle<JSArray> & resultArray)1082 void SplitCommon(JSThread *thread, std::vector<JSHandle<EcmaString>> expecteds, JSHandle<JSArray> &resultArray)
1083 {
1084 JSHandle<JSTaggedValue> resultObj(resultArray);
1085 for (size_t i = 0; i < expecteds.size(); i++) {
1086 JSHandle<EcmaString> str(
1087 JSObject::GetProperty(thread, resultObj,
1088 JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<int>(i))))
1089 .GetValue());
1090 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *str, *expecteds[i]));
1091 }
1092 }
1093
HWTEST_F_L0(BuiltinsStringTest,Split)1094 HWTEST_F_L0(BuiltinsStringTest, Split)
1095 {
1096 // invoke RegExpConstructor method
1097 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1098 JSHandle<EcmaString> thisStr = factory->NewFromASCII("Hello World. How are you doing?");
1099 JSHandle<EcmaString> separatorStr = factory->NewFromASCII(" ");
1100 JSHandle<JSTaggedValue> limit(thread, JSTaggedValue(3));
1101 JSHandle<EcmaString> expected1 = factory->NewFromASCII("Hello");
1102 JSHandle<EcmaString> expected2 = factory->NewFromASCII("World.");
1103 JSHandle<EcmaString> expected3 = factory->NewFromASCII("How");
1104
1105 std::vector<JSTaggedValue> args{separatorStr.GetTaggedValue(), JSTaggedValue(static_cast<int32_t>(3))};
1106 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::SPLIT);
1107
1108 ASSERT_TRUE(result.IsECMAObject());
1109 JSHandle<JSArray> resultArray(thread, reinterpret_cast<JSArray *>(result.GetRawData()));
1110 ASSERT_TRUE(resultArray->IsJSArray());
1111 std::vector<JSHandle<EcmaString>> expecteds{expected1, expected2, expected3};
1112 SplitCommon(thread, expecteds, resultArray);
1113 }
1114
HWTEST_F_L0(BuiltinsStringTest,Split2)1115 HWTEST_F_L0(BuiltinsStringTest, Split2)
1116 {
1117 // invoke RegExpConstructor method
1118 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1119 JSHandle<EcmaString> thisStr = factory->NewFromASCII("a-b-c");
1120 JSHandle<EcmaString> pattern1 = factory->NewFromASCII("-");
1121 JSHandle<EcmaString> flags1 = factory->NewFromASCII("iug");
1122 JSTaggedValue result1 = CreateBuiltinsStringRegExpObjByPatternAndFlags(thread, pattern1, flags1);
1123 JSHandle<JSRegExp> separatorObj(thread, result1);
1124
1125 JSHandle<JSTaggedValue> limit(thread, JSTaggedValue(3));
1126 JSHandle<EcmaString> expected1 = factory->NewFromASCII("a");
1127 JSHandle<EcmaString> expected2 = factory->NewFromASCII("b");
1128 JSHandle<EcmaString> expected3 = factory->NewFromASCII("c");
1129
1130 std::vector<JSTaggedValue> args{separatorObj.GetTaggedValue(), JSTaggedValue(static_cast<int32_t>(3))};
1131 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::SPLIT);
1132
1133 ASSERT_TRUE(result.IsECMAObject());
1134 JSHandle<JSArray> resultArray(thread, result);
1135 ASSERT_TRUE(resultArray->IsJSArray());
1136 std::vector<JSHandle<EcmaString>> expecteds{expected1, expected2, expected3};
1137 SplitCommon(thread, expecteds, resultArray);
1138 }
1139
1140 // "一二三四".at(3)
HWTEST_F_L0(BuiltinsStringTest,at1)1141 HWTEST_F_L0(BuiltinsStringTest, at1)
1142 {
1143 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1144 JSHandle<EcmaString> thisVal = factory->NewFromUtf8("一二三四");
1145
1146 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1147 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
1148 ecmaRuntimeCallInfo->SetThis(thisVal.GetTaggedValue());
1149 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(3)));
1150
1151 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
1152 JSTaggedValue result = BuiltinsString::At(ecmaRuntimeCallInfo);
1153 ASSERT_TRUE(result.IsString());
1154 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
1155 JSHandle<EcmaString> test = factory->NewFromUtf8("四");
1156 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
1157 }
1158
1159 // "一二三四".at(-2)
HWTEST_F_L0(BuiltinsStringTest,at2)1160 HWTEST_F_L0(BuiltinsStringTest, at2)
1161 {
1162 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1163 JSHandle<EcmaString> thisVal = factory->NewFromUtf8("一二三四");
1164
1165 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1166 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
1167 ecmaRuntimeCallInfo->SetThis(thisVal.GetTaggedValue());
1168 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(-2)));
1169
1170 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
1171 JSTaggedValue result = BuiltinsString::At(ecmaRuntimeCallInfo);
1172 ASSERT_TRUE(result.IsString());
1173 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
1174 JSHandle<EcmaString> test = factory->NewFromUtf8("三");
1175 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
1176 }
1177
1178 // "一二三四".at(-5)
HWTEST_F_L0(BuiltinsStringTest,at3)1179 HWTEST_F_L0(BuiltinsStringTest, at3)
1180 {
1181 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1182 JSHandle<EcmaString> thisVal = factory->NewFromUtf8("一二三四");
1183
1184 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1185 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
1186 ecmaRuntimeCallInfo->SetThis(thisVal.GetTaggedValue());
1187 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(-5)));
1188
1189 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
1190 JSTaggedValue result = BuiltinsString::At(ecmaRuntimeCallInfo);
1191 ASSERT_TRUE(result.IsUndefined());
1192 }
1193
1194 // "abcabcabc".at(9)
HWTEST_F_L0(BuiltinsStringTest,at4)1195 HWTEST_F_L0(BuiltinsStringTest, at4)
1196 {
1197 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1198 JSHandle<EcmaString> thisVal = factory->NewFromASCII("abcabcabc");
1199
1200 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1201 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
1202 ecmaRuntimeCallInfo->SetThis(thisVal.GetTaggedValue());
1203 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(9)));
1204
1205 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
1206 JSTaggedValue result = BuiltinsString::At(ecmaRuntimeCallInfo);
1207 ASSERT_TRUE(result.IsUndefined());
1208 }
1209 } // namespace panda::test
1210