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 32using namespace panda::ecmascript; 33using namespace panda::ecmascript::builtins; 34 35namespace panda::test { 36class BuiltinsStringTest : public BaseTestWithScope<true> { 37}; 38 39JSTaggedValue 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 59enum 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 77JSTaggedValue 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 97JSTaggedValue 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 144HWTEST_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) 169HWTEST_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) 187HWTEST_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) 204HWTEST_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) 219HWTEST_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) 234HWTEST_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) 249HWTEST_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) 261HWTEST_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) 274HWTEST_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') 286HWTEST_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') 304HWTEST_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) 317HWTEST_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') 330HWTEST_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') 343HWTEST_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) 355HWTEST_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') 368HWTEST_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') 381HWTEST_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) 394HWTEST_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('二') 407HWTEST_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') 420HWTEST_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') 433HWTEST_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) 446HWTEST_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.') 459HWTEST_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') 472HWTEST_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) 485HWTEST_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() 498HWTEST_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() 517HWTEST_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() 535HWTEST_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') 553HWTEST_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') 571HWTEST_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') 589HWTEST_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('辅助') 607HWTEST_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 630HWTEST_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') 663HWTEST_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) 684HWTEST_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) 703HWTEST_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) 723HWTEST_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) 742HWTEST_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) 762HWTEST_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() 782HWTEST_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 799HWTEST_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 822HWTEST_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 845HWTEST_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 865HWTEST_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 885static 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 892HWTEST_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 932HWTEST_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 988HWTEST_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 1037HWTEST_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 1053HWTEST_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 1077void 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 1089HWTEST_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 1110HWTEST_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) 1136HWTEST_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) 1155HWTEST_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) 1174HWTEST_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) 1190HWTEST_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