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())), 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(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(reinterpret_cast<EcmaString *>(result.GetRawData()), *test));
930 }
931
HWTEST_F_L0(BuiltinsStringTest, Replace)932 HWTEST_F_L0(BuiltinsStringTest, Replace)
933 {
934 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
935 JSHandle<EcmaString> thisStr = factory->NewFromASCII("Twas the night before Xmas...");
936 JSHandle<EcmaString> searchStr = factory->NewFromASCII("Xmas");
937 JSHandle<EcmaString> replaceStr = factory->NewFromASCII("Christmas");
938 JSHandle<EcmaString> expected = factory->NewFromASCII("Twas the night before Christmas...");
939
940 std::vector<JSTaggedValue> args{searchStr.GetTaggedValue(), replaceStr.GetTaggedValue()};
941 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
942
943 ASSERT_TRUE(result.IsString());
944 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(reinterpret_cast<EcmaString *>(result.GetRawData()), *expected));
945
946 JSHandle<EcmaString> replaceStr1 = factory->NewFromASCII("abc$$");
947 JSHandle<EcmaString> expected1 = factory->NewFromASCII("Twas the night before abc$...");
948 args[0] = searchStr.GetTaggedValue();
949 args[1] = replaceStr1.GetTaggedValue();
950 auto result1 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
951
952 JSHandle<EcmaString> resultString1(thread, result1);
953 ASSERT_TRUE(result1.IsString());
954 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*resultString1, *expected1));
955
956 JSHandle<EcmaString> replaceStr2 = factory->NewFromASCII("abc$$dd");
957 JSHandle<EcmaString> expected2 = factory->NewFromASCII("Twas the night before abc$dd...");
958 args[0] = searchStr.GetTaggedValue();
959 args[1] = replaceStr2.GetTaggedValue();
960 auto result2 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
961
962 JSHandle<EcmaString> resultString2(thread, result2);
963 ASSERT_TRUE(result2.IsString());
964 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*resultString2, *expected2));
965
966 JSHandle<EcmaString> replaceStr3 = factory->NewFromASCII("abc$&dd");
967 JSHandle<EcmaString> expected3 = factory->NewFromASCII("Twas the night before abcXmasdd...");
968 args[0] = searchStr.GetTaggedValue();
969 args[1] = replaceStr3.GetTaggedValue();
970 auto result3 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
971
972 JSHandle<EcmaString> resultString3(thread, result3);
973 ASSERT_TRUE(result3.IsString());
974 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*resultString3, *expected3));
975
976 JSHandle<EcmaString> replaceStr4 = factory->NewFromASCII("abc$`dd");
977 JSHandle<EcmaString> expected4 =
978 factory->NewFromASCII("Twas the night before abcTwas the night before dd...");
979 args[0] = searchStr.GetTaggedValue();
980 args[1] = replaceStr4.GetTaggedValue();
981 auto result4 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
982
983 JSHandle<EcmaString> resultString4(thread, result4);
984 ASSERT_TRUE(result4.IsString());
985 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*resultString4, *expected4));
986 }
987
HWTEST_F_L0(BuiltinsStringTest, Replace2)988 HWTEST_F_L0(BuiltinsStringTest, Replace2)
989 {
990 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
991 JSHandle<EcmaString> thisStr = factory->NewFromASCII("Twas the night before Xmas...");
992 JSHandle<EcmaString> searchStr = factory->NewFromASCII("Xmas");
993 JSHandle<EcmaString> replaceStr = factory->NewFromASCII("abc$\'dd");
994 JSHandle<EcmaString> expected = factory->NewFromASCII("Twas the night before abc...dd...");
995
996 std::vector<JSTaggedValue> args{searchStr.GetTaggedValue(), replaceStr.GetTaggedValue()};
997 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
998
999 ASSERT_TRUE(result.IsString());
1000 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(reinterpret_cast<EcmaString *>(result.GetRawData()), *expected));
1001
1002 JSHandle<EcmaString> replaceStr2 = factory->NewFromASCII("abc$`dd$\'$ff");
1003 JSHandle<EcmaString> expected2 =
1004 factory->NewFromASCII("Twas the night before abcTwas the night before dd...$ff...");
1005 args[0] = searchStr.GetTaggedValue();
1006 args[1] = replaceStr2.GetTaggedValue();
1007 auto result2 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
1008
1009
1010 JSHandle<EcmaString> resultString2(thread, result2);
1011 ASSERT_TRUE(result2.IsString());
1012 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*resultString2, *expected2));
1013
1014 JSHandle<EcmaString> replaceStr3 = factory->NewFromASCII("abc$`dd$\'$");
1015 JSHandle<EcmaString> expected3 =
1016 factory->NewFromASCII("Twas the night before abcTwas the night before dd...$...");
1017 args[0] = searchStr.GetTaggedValue();
1018 args[1] = replaceStr3.GetTaggedValue();
1019 auto result3 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
1020
1021 JSHandle<EcmaString> resultString3(thread, result3);
1022 ASSERT_TRUE(result3.IsString());
1023 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*resultString3, *expected3));
1024
1025 JSHandle<EcmaString> replaceStr4 = factory->NewFromASCII("abc$`dd$$");
1026 JSHandle<EcmaString> expected4 =
1027 factory->NewFromASCII("Twas the night before abcTwas the night before dd$...");
1028 args[0] = searchStr.GetTaggedValue();
1029 args[1] = replaceStr4.GetTaggedValue();
1030 auto result4 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
1031
1032 ASSERT_TRUE(result4.IsString());
1033 JSHandle<EcmaString> resultString4(thread, result4);
1034 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*resultString4, *expected4));
1035 }
1036
HWTEST_F_L0(BuiltinsStringTest, Replace3)1037 HWTEST_F_L0(BuiltinsStringTest, Replace3)
1038 {
1039 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1040 JSHandle<EcmaString> thisStr = factory->NewFromASCII("Twas the night before Xmas...");
1041 JSHandle<EcmaString> searchStr = factory->NewFromASCII("Xmas");
1042 JSHandle<EcmaString> replaceStr = factory->NewFromASCII("$&a $` $\' $2 $01 $$1 $21 $32 a");
1043 JSHandle<EcmaString> expected = factory->NewFromASCII(
1044 "Twas the night before Xmasa Twas the night before ... $2 $01 $1 $21 $32 a...");
1045
1046 std::vector<JSTaggedValue> args{searchStr.GetTaggedValue(), replaceStr.GetTaggedValue()};
1047 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
1048
1049 ASSERT_TRUE(result.IsString());
1050 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(reinterpret_cast<EcmaString *>(result.GetRawData()), *expected));
1051 }
1052
HWTEST_F_L0(BuiltinsStringTest, Replace4)1053 HWTEST_F_L0(BuiltinsStringTest, Replace4)
1054 {
1055 // invoke RegExpConstructor method
1056 JSHandle<EcmaString> pattern1 =
1057 thread->GetEcmaVM()->GetFactory()->NewFromASCII("quick\\s(brown).+?(jumps)");
1058 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("iug");
1059 JSTaggedValue result1 = CreateBuiltinsStringRegExpObjByPatternAndFlags(thread, pattern1, flags1);
1060 JSHandle<JSRegExp> searchStr(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData()));
1061 JSHandle<EcmaString> expected = thread->GetEcmaVM()->GetFactory()->NewFromASCII(
1062 "The Quick Brown Fox Jumpsa The Over The Lazy Dog Jumps Brown $1 Jumps1 $32 a Over The Lazy Dog");
1063
1064 // make ecma_runtime_call_info2
1065 JSHandle<EcmaString> thisStr =
1066 thread->GetEcmaVM()->GetFactory()->NewFromASCII("The Quick Brown Fox Jumps Over The Lazy Dog");
1067 JSHandle<EcmaString> replaceStr =
1068 thread->GetEcmaVM()->GetFactory()->NewFromASCII("$&a $` $\' $2 $01 $$1 $21 $32 a");
1069
1070 std::vector<JSTaggedValue> args{searchStr.GetTaggedValue(), replaceStr.GetTaggedValue()};
1071 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
1072
1073 ASSERT_TRUE(result.IsString());
1074 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(reinterpret_cast<EcmaString *>(result.GetRawData()), *expected));
1075 }
1076
SplitCommon(JSThread *thread, std::vector<JSHandle<EcmaString>> expecteds, JSHandle<JSArray> &resultArray)1077 void SplitCommon(JSThread *thread, std::vector<JSHandle<EcmaString>> expecteds, JSHandle<JSArray> &resultArray)
1078 {
1079 JSHandle<JSTaggedValue> resultObj(resultArray);
1080 for (size_t i = 0; i < expecteds.size(); i++) {
1081 JSHandle<EcmaString> str(
1082 JSObject::GetProperty(thread, resultObj,
1083 JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<int>(i))))
1084 .GetValue());
1085 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*str, *expecteds[i]));
1086 }
1087 }
1088
HWTEST_F_L0(BuiltinsStringTest, Split)1089 HWTEST_F_L0(BuiltinsStringTest, Split)
1090 {
1091 // invoke RegExpConstructor method
1092 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1093 JSHandle<EcmaString> thisStr = factory->NewFromASCII("Hello World. How are you doing?");
1094 JSHandle<EcmaString> separatorStr = factory->NewFromASCII(" ");
1095 JSHandle<JSTaggedValue> limit(thread, JSTaggedValue(3));
1096 JSHandle<EcmaString> expected1 = factory->NewFromASCII("Hello");
1097 JSHandle<EcmaString> expected2 = factory->NewFromASCII("World.");
1098 JSHandle<EcmaString> expected3 = factory->NewFromASCII("How");
1099
1100 std::vector<JSTaggedValue> args{separatorStr.GetTaggedValue(), JSTaggedValue(static_cast<int32_t>(3))};
1101 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::SPLIT);
1102
1103 ASSERT_TRUE(result.IsECMAObject());
1104 JSHandle<JSArray> resultArray(thread, reinterpret_cast<JSArray *>(result.GetRawData()));
1105 ASSERT_TRUE(resultArray->IsJSArray());
1106 std::vector<JSHandle<EcmaString>> expecteds{expected1, expected2, expected3};
1107 SplitCommon(thread, expecteds, resultArray);
1108 }
1109
HWTEST_F_L0(BuiltinsStringTest, Split2)1110 HWTEST_F_L0(BuiltinsStringTest, Split2)
1111 {
1112 // invoke RegExpConstructor method
1113 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1114 JSHandle<EcmaString> thisStr = factory->NewFromASCII("a-b-c");
1115 JSHandle<EcmaString> pattern1 = factory->NewFromASCII("-");
1116 JSHandle<EcmaString> flags1 = factory->NewFromASCII("iug");
1117 JSTaggedValue result1 = CreateBuiltinsStringRegExpObjByPatternAndFlags(thread, pattern1, flags1);
1118 JSHandle<JSRegExp> separatorObj(thread, result1);
1119
1120 JSHandle<JSTaggedValue> limit(thread, JSTaggedValue(3));
1121 JSHandle<EcmaString> expected1 = factory->NewFromASCII("a");
1122 JSHandle<EcmaString> expected2 = factory->NewFromASCII("b");
1123 JSHandle<EcmaString> expected3 = factory->NewFromASCII("c");
1124
1125 std::vector<JSTaggedValue> args{separatorObj.GetTaggedValue(), JSTaggedValue(static_cast<int32_t>(3))};
1126 auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::SPLIT);
1127
1128 ASSERT_TRUE(result.IsECMAObject());
1129 JSHandle<JSArray> resultArray(thread, result);
1130 ASSERT_TRUE(resultArray->IsJSArray());
1131 std::vector<JSHandle<EcmaString>> expecteds{expected1, expected2, expected3};
1132 SplitCommon(thread, expecteds, resultArray);
1133 }
1134
1135 // "一二三四".at(3)
HWTEST_F_L0(BuiltinsStringTest, at1)1136 HWTEST_F_L0(BuiltinsStringTest, at1)
1137 {
1138 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1139 JSHandle<EcmaString> thisVal = factory->NewFromUtf8("一二三四");
1140
1141 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1142 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
1143 ecmaRuntimeCallInfo->SetThis(thisVal.GetTaggedValue());
1144 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(3)));
1145
1146 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
1147 JSTaggedValue result = BuiltinsString::At(ecmaRuntimeCallInfo);
1148 ASSERT_TRUE(result.IsString());
1149 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
1150 JSHandle<EcmaString> test = factory->NewFromUtf8("四");
1151 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
1152 }
1153
1154 // "一二三四".at(-2)
HWTEST_F_L0(BuiltinsStringTest, at2)1155 HWTEST_F_L0(BuiltinsStringTest, at2)
1156 {
1157 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1158 JSHandle<EcmaString> thisVal = factory->NewFromUtf8("一二三四");
1159
1160 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1161 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
1162 ecmaRuntimeCallInfo->SetThis(thisVal.GetTaggedValue());
1163 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(-2)));
1164
1165 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
1166 JSTaggedValue result = BuiltinsString::At(ecmaRuntimeCallInfo);
1167 ASSERT_TRUE(result.IsString());
1168 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
1169 JSHandle<EcmaString> test = factory->NewFromUtf8("三");
1170 ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
1171 }
1172
1173 // "一二三四".at(-5)
HWTEST_F_L0(BuiltinsStringTest, at3)1174 HWTEST_F_L0(BuiltinsStringTest, at3)
1175 {
1176 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1177 JSHandle<EcmaString> thisVal = factory->NewFromUtf8("一二三四");
1178
1179 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1180 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
1181 ecmaRuntimeCallInfo->SetThis(thisVal.GetTaggedValue());
1182 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(-5)));
1183
1184 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
1185 JSTaggedValue result = BuiltinsString::At(ecmaRuntimeCallInfo);
1186 ASSERT_TRUE(result.IsUndefined());
1187 }
1188
1189 // "abcabcabc".at(9)
HWTEST_F_L0(BuiltinsStringTest, at4)1190 HWTEST_F_L0(BuiltinsStringTest, at4)
1191 {
1192 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1193 JSHandle<EcmaString> thisVal = factory->NewFromASCII("abcabcabc");
1194
1195 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1196 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
1197 ecmaRuntimeCallInfo->SetThis(thisVal.GetTaggedValue());
1198 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(9)));
1199
1200 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
1201 JSTaggedValue result = BuiltinsString::At(ecmaRuntimeCallInfo);
1202 ASSERT_TRUE(result.IsUndefined());
1203 }
1204 } // namespace panda::test
1205