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