1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ecmascript/js_regexp.h" 17 18#include "ecmascript/builtins/builtins_regexp.h" 19#include "ecmascript/ecma_runtime_call_info.h" 20#include "ecmascript/ecma_string.h" 21#include "ecmascript/ecma_vm.h" 22#include "ecmascript/global_env.h" 23#include "ecmascript/js_handle.h" 24#include "ecmascript/js_hclass.h" 25#include "ecmascript/js_object-inl.h" 26#include "ecmascript/js_tagged_value.h" 27#include "ecmascript/js_thread.h" 28#include "ecmascript/regexp/regexp_parser_cache.h" 29#include "ecmascript/object_factory.h" 30#include "ecmascript/tests/ecma_test_common.h" 31 32using namespace panda::ecmascript; 33using namespace panda::ecmascript::builtins; 34 35namespace panda::test { 36class BuiltinsRegExpTest : public BaseTestWithScope<false> { 37}; 38 39HWTEST_F_L0(BuiltinsRegExpTest, RegExpConstructor1) 40{ 41 // invoke RegExpConstructor method 42 JSHandle<EcmaString> pattern = thread->GetEcmaVM()->GetFactory()->NewFromASCII("\\w+"); 43 JSHandle<EcmaString> flags = thread->GetEcmaVM()->GetFactory()->NewFromASCII("i"); 44 JSTaggedValue result = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern, flags); 45 46 // ASSERT IsRegExp() 47 JSHandle<JSTaggedValue> regexpObject(thread, result); 48 ASSERT_TRUE(JSObject::IsRegExp(thread, regexpObject)); 49 50 JSHandle<JSRegExp> jsRegexp(thread, JSRegExp::Cast(regexpObject->GetTaggedObject())); 51 JSHandle<JSTaggedValue> originalSource(thread, jsRegexp->GetOriginalSource()); 52 uint8_t flagsBits = static_cast<uint8_t>(jsRegexp->GetOriginalFlags().GetInt()); 53 JSHandle<JSTaggedValue> originalFlags(thread, BuiltinsRegExp::FlagsBitsToString(thread, flagsBits)); 54 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>(originalSource), pattern), 0); 55 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>(originalFlags), flags), 0); 56} 57 58HWTEST_F_L0(BuiltinsRegExpTest, RegExpConstructor2) 59{ 60 // invoke RegExpConstructor method 61 JSHandle<EcmaString> pattern = thread->GetEcmaVM()->GetFactory()->NewFromASCII("\\w+"); 62 JSHandle<EcmaString> flags = thread->GetEcmaVM()->GetFactory()->NewFromASCII("i"); 63 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern, flags); 64 JSHandle<JSRegExp> value(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData())); 65 66 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 67 JSHandle<JSFunction> regexp(env->GetRegExpFunction()); 68 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject()); 69 70 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*regexp), 8); 71 ecmaRuntimeCallInfo->SetFunction(regexp.GetTaggedValue()); 72 ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue()); 73 ecmaRuntimeCallInfo->SetCallArg(0, value.GetTaggedValue()); 74 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined()); 75 76 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 77 // invoke RegExpConstructor method 78 JSTaggedValue result2 = BuiltinsRegExp::RegExpConstructor(ecmaRuntimeCallInfo); 79 TestHelper::TearDownFrame(thread, prev); 80 81 // ASSERT IsRegExp() 82 JSHandle<JSTaggedValue> regexpObject(thread, result2); 83 ASSERT_TRUE(JSObject::IsRegExp(thread, regexpObject)); 84 85 JSHandle<JSRegExp> jsRegexp(thread, JSRegExp::Cast(regexpObject->GetTaggedObject())); 86 JSHandle<JSTaggedValue> originalSource(thread, jsRegexp->GetOriginalSource()); 87 uint8_t flagsBits = static_cast<uint8_t>(jsRegexp->GetOriginalFlags().GetInt()); 88 JSHandle<JSTaggedValue> originalFlags(thread, BuiltinsRegExp::FlagsBitsToString(thread, flagsBits)); 89 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>(originalSource), pattern), 0); 90 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>(originalFlags), flags), 0); 91} 92 93HWTEST_F_L0(BuiltinsRegExpTest, RegExpConstructor3) 94{ 95 // invoke RegExpConstructor method 96 JSHandle<EcmaString> pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("\\w+"); 97 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("i"); 98 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 99 JSHandle<JSRegExp> value(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData())); 100 101 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 102 JSHandle<JSFunction> regexp(env->GetRegExpFunction()); 103 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject()); 104 JSHandle<EcmaString> flags2 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("gi"); 105 106 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*regexp), 8); 107 ecmaRuntimeCallInfo->SetFunction(regexp.GetTaggedValue()); 108 ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue()); 109 ecmaRuntimeCallInfo->SetCallArg(0, value.GetTaggedValue()); 110 ecmaRuntimeCallInfo->SetCallArg(1, flags2.GetTaggedValue()); 111 112 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 113 // invoke RegExpConstructor method 114 JSTaggedValue result2 = BuiltinsRegExp::RegExpConstructor(ecmaRuntimeCallInfo); 115 116 // ASSERT IsRegExp() 117 JSHandle<JSTaggedValue> regexpObject(thread, result2); 118 ASSERT_TRUE(JSObject::IsRegExp(thread, regexpObject)); 119 120 JSHandle<JSRegExp> jsRegexp(thread, JSRegExp::Cast(regexpObject->GetTaggedObject())); 121 JSHandle<JSTaggedValue> originalSource(thread, jsRegexp->GetOriginalSource()); 122 uint8_t flagsBits = static_cast<uint8_t>(jsRegexp->GetOriginalFlags().GetInt()); 123 JSHandle<JSTaggedValue> originalFlags(thread, BuiltinsRegExp::FlagsBitsToString(thread, flagsBits)); 124 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>(originalSource), pattern1), 0); 125 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>(originalFlags), flags2), 0); 126} 127 128HWTEST_F_L0(BuiltinsRegExpTest, GetSource1) 129{ 130 // invoke RegExpConstructor method 131 JSHandle<EcmaString> pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII(""); 132 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("i"); 133 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 134 JSHandle<JSTaggedValue> result1Handle(thread, result1); 135 136 // invoke GetSource method 137 JSHandle<JSTaggedValue> source( 138 thread, thread->GetEcmaVM()->GetFactory()->NewFromASCII("source").GetTaggedValue()); 139 JSHandle<JSTaggedValue> sourceResult(JSObject::GetProperty(thread, result1Handle, source).GetValue()); 140 141 JSHandle<EcmaString> expect = thread->GetEcmaVM()->GetFactory()->NewFromASCII("(?:)"); 142 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>(sourceResult), expect), 0); 143} 144 145HWTEST_F_L0(BuiltinsRegExpTest, GetSource2) 146{ 147 // invoke RegExpConstructor method 148 JSHandle<EcmaString> pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("/w+"); 149 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("i"); 150 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 151 JSHandle<JSTaggedValue> result1Handle(thread, result1); 152 153 // invoke GetSource method 154 JSHandle<JSTaggedValue> source(thread->GetEcmaVM()->GetFactory()->NewFromASCII("source")); 155 JSHandle<JSTaggedValue> sourceResult(JSObject::GetProperty(thread, result1Handle, source).GetValue()); 156 157 JSHandle<EcmaString> expect = thread->GetEcmaVM()->GetFactory()->NewFromASCII("\\/w+"); 158 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>(sourceResult), expect), 0); 159} 160 161HWTEST_F_L0(BuiltinsRegExpTest, Get) 162{ 163 // invoke RegExpConstructor method 164 JSHandle<EcmaString> pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("\\w+"); 165 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("gimuy"); 166 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 167 JSHandle<JSTaggedValue> result1Handle(thread, result1); 168 169 JSHandle<JSTaggedValue> global(thread->GetEcmaVM()->GetFactory()->NewFromASCII("global")); 170 JSTaggedValue taggedGlobalResult = 171 JSTaggedValue(JSObject::GetProperty(thread, result1Handle, global).GetValue().GetTaggedValue()); 172 ASSERT_EQ(taggedGlobalResult.GetRawData(), JSTaggedValue::True().GetRawData()); 173 174 JSHandle<JSTaggedValue> ignoreCase(thread->GetEcmaVM()->GetFactory()->NewFromASCII("ignoreCase")); 175 JSTaggedValue taggedIgnoreCaseResult = 176 JSTaggedValue(JSObject::GetProperty(thread, result1Handle, ignoreCase).GetValue().GetTaggedValue()); 177 ASSERT_EQ(taggedIgnoreCaseResult.GetRawData(), JSTaggedValue::True().GetRawData()); 178 179 JSHandle<JSTaggedValue> multiline(thread->GetEcmaVM()->GetFactory()->NewFromASCII("multiline")); 180 JSTaggedValue taggedMultilineResult = 181 JSTaggedValue(JSObject::GetProperty(thread, result1Handle, multiline).GetValue().GetTaggedValue()); 182 ASSERT_EQ(taggedMultilineResult.GetRawData(), JSTaggedValue::True().GetRawData()); 183 184 JSHandle<JSTaggedValue> sticky(thread->GetEcmaVM()->GetFactory()->NewFromASCII("sticky")); 185 JSTaggedValue taggedStickyResult = 186 JSTaggedValue(JSObject::GetProperty(thread, result1Handle, sticky).GetValue().GetTaggedValue()); 187 ASSERT_EQ(taggedStickyResult.GetRawData(), JSTaggedValue::True().GetRawData()); 188 189 JSHandle<JSTaggedValue> unicode(thread->GetEcmaVM()->GetFactory()->NewFromASCII("unicode")); 190 JSTaggedValue taggedUnicodeResult = 191 JSTaggedValue(JSObject::GetProperty(thread, result1Handle, unicode).GetValue().GetTaggedValue()); 192 ASSERT_EQ(taggedUnicodeResult.GetRawData(), JSTaggedValue::True().GetRawData()); 193} 194 195HWTEST_F_L0(BuiltinsRegExpTest, GetFlags) 196{ 197 // invoke RegExpConstructor method 198 JSHandle<EcmaString> pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("\\w+"); 199 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("imuyg"); 200 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 201 JSHandle<JSTaggedValue> result1Handle(thread, result1); 202 203 // invoke GetFlags method 204 JSHandle<JSTaggedValue> flags(thread->GetEcmaVM()->GetFactory()->NewFromASCII("flags")); 205 JSHandle<JSTaggedValue> flagsResult(JSObject::GetProperty(thread, result1Handle, flags).GetValue()); 206 207 JSHandle<EcmaString> expectResult = thread->GetEcmaVM()->GetFactory()->NewFromASCII("gimuy"); 208 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>(flagsResult), expectResult), 0); 209} 210 211HWTEST_F_L0(BuiltinsRegExpTest, toString) 212{ 213 // invoke RegExpConstructor method 214 JSHandle<EcmaString> pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("\\w+"); 215 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("imuyg"); 216 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 217 JSHandle<JSRegExp> value(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData())); 218 219 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); 220 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 221 ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); 222 223 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 224 // invoke ToString method 225 JSTaggedValue toStringResult = BuiltinsRegExp::ToString(ecmaRuntimeCallInfo); 226 ASSERT_TRUE(toStringResult.IsString()); 227 JSHandle<JSTaggedValue> toStringResultHandle(thread, toStringResult); 228 JSHandle<EcmaString> expectResult = thread->GetEcmaVM()->GetFactory()->NewFromASCII("/\\w+/gimuy"); 229 ASSERT_EQ(EcmaStringAccessor::Compare(instance, 230 JSHandle<EcmaString>(toStringResultHandle), expectResult), 0); 231} 232 233void ExecCommon(JSThread* thread, EcmaVM* instance, JSHandle<JSTaggedValue>& execResult, 234 JSHandle<EcmaString>& inputString, std::vector<JSHandle<EcmaString>>& result) 235{ 236 JSHandle<JSTaggedValue> input(thread->GetEcmaVM()->GetFactory()->NewFromASCII("input")); 237 JSHandle<JSTaggedValue> inputHandle(JSObject::GetProperty(thread, execResult, input).GetValue()); 238 JSHandle<EcmaString> outputInput = JSTaggedValue::ToString(thread, inputHandle); 239 ASSERT_EQ(EcmaStringAccessor::Compare(instance, outputInput, inputString), 0); 240 241 JSHandle<JSTaggedValue> zero(thread->GetEcmaVM()->GetFactory()->NewFromASCII("0")); 242 JSHandle<JSTaggedValue> zeroHandle(JSObject::GetProperty(thread, execResult, zero).GetValue()); 243 JSHandle<EcmaString> outputZero = JSTaggedValue::ToString(thread, zeroHandle); 244 ASSERT_EQ(EcmaStringAccessor::Compare(instance, outputZero, result[0]), 0); 245 246 JSHandle<JSTaggedValue> first(thread->GetEcmaVM()->GetFactory()->NewFromASCII("1")); 247 JSHandle<JSTaggedValue> oneHandle(JSObject::GetProperty(thread, execResult, first).GetValue()); 248 JSHandle<EcmaString> outputOne = JSTaggedValue::ToString(thread, oneHandle); 249 ASSERT_EQ(EcmaStringAccessor::Compare(instance, outputOne, result[1]), 0); // 1: second value 250 251 JSHandle<JSTaggedValue> second(thread->GetEcmaVM()->GetFactory()->NewFromASCII("2")); 252 JSHandle<JSTaggedValue> twoHandle(JSObject::GetProperty(thread, execResult, second).GetValue()); 253 JSHandle<EcmaString> outputTwo = JSTaggedValue::ToString(thread, twoHandle); 254 ASSERT_EQ(EcmaStringAccessor::Compare(instance, outputTwo, result[2]), 0); // 2: third value 255} 256 257HWTEST_F_L0(BuiltinsRegExpTest, Exec1) 258{ 259 // invoke RegExpConstructor method 260 JSHandle<EcmaString> pattern1 = 261 thread->GetEcmaVM()->GetFactory()->NewFromASCII("quick\\s(brown).+?(jumps)"); 262 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("ig"); 263 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 264 JSHandle<JSRegExp> value(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData())); 265 266 JSHandle<EcmaString> inputString = 267 thread->GetEcmaVM()->GetFactory()->NewFromASCII("The Quick Brown Fox Jumps Over The Lazy Dog"); 268 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); 269 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 270 ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); 271 ecmaRuntimeCallInfo->SetCallArg(0, inputString.GetTaggedValue()); 272 273 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 274 // invoke Exec method 275 JSTaggedValue results = BuiltinsRegExp::Exec(ecmaRuntimeCallInfo); 276 277 JSHandle<JSTaggedValue> execResult(thread, results); 278 JSHandle<EcmaString> resultZero = 279 thread->GetEcmaVM()->GetFactory()->NewFromASCII("Quick Brown Fox Jumps"); 280 JSHandle<EcmaString> resultOne = thread->GetEcmaVM()->GetFactory()->NewFromASCII("Brown"); 281 JSHandle<EcmaString> resultTwo = thread->GetEcmaVM()->GetFactory()->NewFromASCII("Jumps"); 282 283 JSHandle<JSTaggedValue> index(thread->GetEcmaVM()->GetFactory()->NewFromASCII("index")); 284 JSHandle<JSTaggedValue> indexHandle(JSObject::GetProperty(thread, execResult, index).GetValue()); 285 uint32_t resultIndex = JSTaggedValue::ToUint32(thread, indexHandle); 286 ASSERT_TRUE(resultIndex == 4U); 287 288 std::vector<JSHandle<EcmaString>> result{resultZero, resultOne, resultTwo}; 289 ExecCommon(thread, instance, execResult, inputString, result); 290 JSHandle<JSTaggedValue> regexp = JSHandle<JSTaggedValue>::Cast(value); 291 JSHandle<JSTaggedValue> lastIndexHandle(thread->GetEcmaVM()->GetFactory()->NewFromASCII("lastIndex")); 292 JSHandle<JSTaggedValue> lastIndexObj(JSObject::GetProperty(thread, regexp, lastIndexHandle).GetValue()); 293 int lastIndex = lastIndexObj->GetInt(); 294 ASSERT_TRUE(lastIndex == 25); 295} 296 297HWTEST_F_L0(BuiltinsRegExpTest, Exec2) 298{ 299 // invoke RegExpConstructor method 300 JSHandle<EcmaString> pattern1 = 301 thread->GetEcmaVM()->GetFactory()->NewFromASCII("((1)|(12))((3)|(23))"); 302 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("ig"); 303 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 304 JSHandle<JSRegExp> value(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData())); 305 306 JSHandle<EcmaString> inputString = thread->GetEcmaVM()->GetFactory()->NewFromASCII("123"); 307 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); 308 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 309 ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); 310 ecmaRuntimeCallInfo->SetCallArg(0, inputString.GetTaggedValue()); 311 312 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 313 // invoke Exec method 314 JSTaggedValue results = BuiltinsRegExp::Exec(ecmaRuntimeCallInfo); 315 316 JSHandle<JSTaggedValue> execResult(thread, results); 317 JSHandle<EcmaString> resultZero = thread->GetEcmaVM()->GetFactory()->NewFromASCII("123"); 318 JSHandle<EcmaString> resultOne = thread->GetEcmaVM()->GetFactory()->NewFromASCII("1"); 319 JSHandle<EcmaString> resultTwo = thread->GetEcmaVM()->GetFactory()->NewFromASCII("1"); 320 JSHandle<EcmaString> resultFour = thread->GetEcmaVM()->GetFactory()->NewFromASCII("23"); 321 JSHandle<EcmaString> resultSix = thread->GetEcmaVM()->GetFactory()->NewFromASCII("23"); 322 323 JSHandle<JSTaggedValue> index(thread->GetEcmaVM()->GetFactory()->NewFromASCII("index")); 324 JSHandle<JSTaggedValue> indexHandle(JSObject::GetProperty(thread, execResult, index).GetValue()); 325 uint32_t resultIndex = JSTaggedValue::ToUint32(thread, indexHandle); 326 ASSERT_TRUE(resultIndex == 0U); 327 328 std::vector<JSHandle<EcmaString>> result{resultZero, resultOne, resultTwo}; 329 ExecCommon(thread, instance, execResult, inputString, result); 330 JSHandle<JSTaggedValue> regexp = JSHandle<JSTaggedValue>::Cast(value); 331 JSHandle<JSTaggedValue> lastIndexHandle(thread->GetEcmaVM()->GetFactory()->NewFromASCII("lastIndex")); 332 JSHandle<JSTaggedValue> lastIndexObj(JSObject::GetProperty(thread, regexp, lastIndexHandle).GetValue()); 333 int lastIndex = lastIndexObj->GetInt(); 334 ASSERT_TRUE(lastIndex == 3); 335 336 JSHandle<JSTaggedValue> third(thread->GetEcmaVM()->GetFactory()->NewFromASCII("3")); 337 JSHandle<JSTaggedValue> thirdHandle(JSObject::GetProperty(thread, execResult, third).GetValue()); 338 ASSERT_TRUE(thirdHandle->IsUndefined()); 339 340 JSHandle<JSTaggedValue> four(thread->GetEcmaVM()->GetFactory()->NewFromASCII("4")); 341 JSHandle<JSTaggedValue> fourHandle(JSObject::GetProperty(thread, execResult, four).GetValue()); 342 JSHandle<EcmaString> outputFour = JSTaggedValue::ToString(thread, fourHandle); 343 ASSERT_EQ(EcmaStringAccessor::Compare(instance, outputFour, resultFour), 0); 344 345 JSHandle<JSTaggedValue> five(thread->GetEcmaVM()->GetFactory()->NewFromASCII("5")); 346 JSHandle<JSTaggedValue> fiveHandle(JSObject::GetProperty(thread, execResult, five).GetValue()); 347 ASSERT_TRUE(fiveHandle->IsUndefined()); 348 349 JSHandle<JSTaggedValue> six(thread->GetEcmaVM()->GetFactory()->NewFromASCII("6")); 350 JSHandle<JSTaggedValue> sixHandle(JSObject::GetProperty(thread, execResult, six).GetValue()); 351 JSHandle<EcmaString> outputSix = JSTaggedValue::ToString(thread, sixHandle); 352 ASSERT_EQ(EcmaStringAccessor::Compare(instance, outputSix, resultSix), 0); 353} 354 355HWTEST_F_L0(BuiltinsRegExpTest, Match1) 356{ 357 // invoke RegExpConstructor method 358 JSHandle<EcmaString> pattern1 = 359 thread->GetEcmaVM()->GetFactory()->NewFromASCII("quick\\s(brown).+?(jumps)"); 360 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("iug"); 361 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 362 JSHandle<JSRegExp> value(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData())); 363 364 JSHandle<EcmaString> inputString = 365 thread->GetEcmaVM()->GetFactory()->NewFromASCII("The Quick Brown Fox Jumps Over The Lazy Dog"); 366 std::vector<JSTaggedValue> args{inputString.GetTaggedValue()}; 367 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6, value.GetTaggedValue()); 368 369 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 370 // invoke Match method 371 JSTaggedValue matchResults = BuiltinsRegExp::Match(ecmaRuntimeCallInfo); 372 373 JSHandle<JSTaggedValue> matchResult(thread, matchResults); 374 JSHandle<JSTaggedValue> zero(thread->GetEcmaVM()->GetFactory()->NewFromASCII("0")); 375 JSHandle<EcmaString> resultZero = 376 thread->GetEcmaVM()->GetFactory()->NewFromASCII("Quick Brown Fox Jumps"); 377 JSHandle<JSTaggedValue> zeroHandle(JSObject::GetProperty(thread, matchResult, zero).GetValue()); 378 JSHandle<EcmaString> outputZero = JSTaggedValue::ToString(thread, zeroHandle); 379 ASSERT_EQ(EcmaStringAccessor::Compare(instance, outputZero, resultZero), 0); 380} 381 382HWTEST_F_L0(BuiltinsRegExpTest, Test1) 383{ 384 // invoke RegExpConstructor method 385 JSHandle<EcmaString> pattern1 = 386 thread->GetEcmaVM()->GetFactory()->NewFromASCII("quick\\s(brown).+?(jumps)"); 387 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("iug"); 388 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 389 JSHandle<JSRegExp> value(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData())); 390 391 JSHandle<EcmaString> inputString = 392 thread->GetEcmaVM()->GetFactory()->NewFromASCII("The Quick Brown Fox Jumps Over The Lazy Dog"); 393 std::vector<JSTaggedValue> args{inputString.GetTaggedValue()}; 394 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6, value.GetTaggedValue()); 395 396 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 397 // invoke Test method 398 JSTaggedValue testResult = BuiltinsRegExp::Test(ecmaRuntimeCallInfo); 399 ASSERT_EQ(testResult.GetRawData(), JSTaggedValue::True().GetRawData()); 400} 401 402HWTEST_F_L0(BuiltinsRegExpTest, Search1) 403{ 404 // invoke RegExpConstructor method 405 JSHandle<EcmaString> pattern1 = 406 thread->GetEcmaVM()->GetFactory()->NewFromASCII("quick\\s(brown).+?(jumps)"); 407 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("iug"); 408 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 409 JSHandle<JSRegExp> value(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData())); 410 411 JSHandle<EcmaString> inputString = 412 thread->GetEcmaVM()->GetFactory()->NewFromASCII("The Quick Brown Fox Jumps Over The Lazy Dog"); 413 std::vector<JSTaggedValue> args{inputString.GetTaggedValue()}; 414 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6, value.GetTaggedValue()); 415 416 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 417 // invoke Search method 418 JSTaggedValue searchResult = BuiltinsRegExp::Search(ecmaRuntimeCallInfo); 419 ASSERT_EQ(searchResult.GetRawData(), JSTaggedValue(4).GetRawData()); 420} 421 422HWTEST_F_L0(BuiltinsRegExpTest, Split1) 423{ 424 // invoke RegExpConstructor method 425 JSHandle<EcmaString> pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("-"); 426 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("iug"); 427 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 428 JSHandle<JSRegExp> value(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData())); 429 430 JSHandle<EcmaString> inputString = thread->GetEcmaVM()->GetFactory()->NewFromASCII(""); 431 432 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); 433 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 434 ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); 435 ecmaRuntimeCallInfo->SetCallArg(0, inputString.GetTaggedValue()); 436 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined()); 437 438 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 439 // invoke Split method 440 JSTaggedValue splitResults = BuiltinsRegExp::Split(ecmaRuntimeCallInfo); 441 JSHandle<JSTaggedValue> splitResult(thread, splitResults); 442 443 JSHandle<JSTaggedValue> zero(thread->GetEcmaVM()->GetFactory()->NewFromASCII("0")); 444 JSHandle<JSTaggedValue> zeroHandle(JSObject::GetProperty(thread, splitResult, zero).GetValue()); 445 JSHandle<EcmaString> outputZero = JSTaggedValue::ToString(thread, zeroHandle); 446 447 ASSERT_EQ(EcmaStringAccessor::Compare(instance, outputZero, inputString), 0); 448} 449 450HWTEST_F_L0(BuiltinsRegExpTest, Split2) 451{ 452 // invoke RegExpConstructor method 453 JSHandle<EcmaString> pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("-"); 454 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("iug"); 455 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 456 JSHandle<JSRegExp> value(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData())); 457 458 JSHandle<EcmaString> inputString = thread->GetEcmaVM()->GetFactory()->NewFromASCII("a-b-c"); 459 460 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); 461 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 462 ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); 463 ecmaRuntimeCallInfo->SetCallArg(0, inputString.GetTaggedValue()); 464 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined()); 465 466 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 467 // invoke Split method 468 JSTaggedValue splitResults = BuiltinsRegExp::Split(ecmaRuntimeCallInfo); 469 JSHandle<JSTaggedValue> splitResult(thread, splitResults); 470 JSHandle<EcmaString> resultZero = thread->GetEcmaVM()->GetFactory()->NewFromASCII("a"); 471 JSHandle<EcmaString> resultOne = thread->GetEcmaVM()->GetFactory()->NewFromASCII("b"); 472 JSHandle<EcmaString> resultTwo = thread->GetEcmaVM()->GetFactory()->NewFromASCII("c"); 473 474 JSHandle<JSTaggedValue> zero(thread->GetEcmaVM()->GetFactory()->NewFromASCII("0")); 475 JSHandle<JSTaggedValue> zeroHandle(JSObject::GetProperty(thread, splitResult, zero).GetValue()); 476 JSHandle<EcmaString> outputZero = JSTaggedValue::ToString(thread, zeroHandle); 477 ASSERT_EQ(EcmaStringAccessor::Compare(instance, outputZero, resultZero), 0); 478 479 JSHandle<JSTaggedValue> first(thread->GetEcmaVM()->GetFactory()->NewFromASCII("1")); 480 JSHandle<JSTaggedValue> oneHandle(JSObject::GetProperty(thread, splitResult, first).GetValue()); 481 JSHandle<EcmaString> outputOne = JSTaggedValue::ToString(thread, oneHandle); 482 ASSERT_EQ(EcmaStringAccessor::Compare(instance, outputOne, resultOne), 0); 483 484 JSHandle<JSTaggedValue> second(thread->GetEcmaVM()->GetFactory()->NewFromASCII("2")); 485 JSHandle<JSTaggedValue> twoHandle(JSObject::GetProperty(thread, splitResult, second).GetValue()); 486 JSHandle<EcmaString> outputTwo = JSTaggedValue::ToString(thread, twoHandle); 487 ASSERT_EQ(EcmaStringAccessor::Compare(instance, outputTwo, resultTwo), 0); 488} 489 490HWTEST_F_L0(BuiltinsRegExpTest, GetSpecies) 491{ 492 // invoke RegExpConstructor method 493 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 494 JSHandle<JSTaggedValue> speciesSymbol = env->GetSpeciesSymbol(); 495 EXPECT_TRUE(!speciesSymbol.GetTaggedValue().IsUndefined()); 496 497 JSHandle<JSFunction> newTarget(env->GetRegExpFunction()); 498 499 JSTaggedValue value = 500 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(newTarget), speciesSymbol).GetValue().GetTaggedValue(); 501 EXPECT_EQ(value, newTarget.GetTaggedValue()); 502} 503 504HWTEST_F_L0(BuiltinsRegExpTest, Replace1) 505{ 506 // invoke RegExpConstructor method 507 JSHandle<EcmaString> pattern1 = 508 thread->GetEcmaVM()->GetFactory()->NewFromASCII("quick\\s(brown).+?(jumps)"); 509 JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("iug"); 510 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 511 JSHandle<JSRegExp> value(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData())); 512 513 JSHandle<EcmaString> inputString = 514 thread->GetEcmaVM()->GetFactory()->NewFromASCII("The Quick Brown Fox Jumps Over The Lazy Dog"); 515 JSHandle<EcmaString> replaceString = 516 thread->GetEcmaVM()->GetFactory()->NewFromASCII("$&a $` $\' $2 $01 $$1 $21 $32 a"); 517 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); 518 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 519 ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); 520 ecmaRuntimeCallInfo->SetCallArg(0, inputString.GetTaggedValue()); 521 ecmaRuntimeCallInfo->SetCallArg(1, replaceString.GetTaggedValue()); 522 523 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 524 // invoke replace method 525 JSTaggedValue results = BuiltinsRegExp::Replace(ecmaRuntimeCallInfo); 526 JSHandle<JSTaggedValue> replaceResult(thread, results); 527 JSHandle<EcmaString> resultZero = thread->GetEcmaVM()->GetFactory()->NewFromASCII( 528 "The Quick Brown Fox Jumpsa The Over The Lazy Dog Jumps Brown $1 Jumps1 $32 a Over The Lazy Dog"); 529 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>(replaceResult), resultZero), 0); 530} 531 532HWTEST_F_L0(BuiltinsRegExpTest, Replace2) 533{ 534 // invoke RegExpConstructor method 535 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 536 JSHandle<EcmaString> pattern1 = factory->NewFromASCII("b(c)(z)?(.)"); 537 JSHandle<EcmaString> flags1 = factory->NewFromASCII(""); 538 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 539 JSHandle<JSRegExp> value(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData())); 540 541 JSHandle<EcmaString> inputString = factory->NewFromASCII("abcde"); 542 JSHandle<EcmaString> replaceString = factory->NewFromASCII("[$01$02$03$04$00]"); 543 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); 544 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 545 ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); 546 ecmaRuntimeCallInfo->SetCallArg(0, inputString.GetTaggedValue()); 547 ecmaRuntimeCallInfo->SetCallArg(1, replaceString.GetTaggedValue()); 548 549 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 550 // invoke replace method 551 JSTaggedValue results = BuiltinsRegExp::Replace(ecmaRuntimeCallInfo); 552 JSHandle<JSTaggedValue> replaceResult(thread, results); 553 JSHandle<EcmaString> resultZero = factory->NewFromASCII("a[cd$04$00]e"); 554 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>(replaceResult), resultZero), 0); 555} 556 557HWTEST_F_L0(BuiltinsRegExpTest, Replace3) 558{ 559 // invoke RegExpConstructor method 560 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 561 JSHandle<EcmaString> pattern1 = factory->NewFromASCII("abc"); 562 JSHandle<EcmaString> flags1 = factory->NewFromASCII("g"); 563 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 564 JSHandle<JSRegExp> value(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData())); 565 566 JSHandle<EcmaString> inputString = factory->NewFromASCII("abcde"); 567 JSHandle<EcmaString> replaceString = factory->NewFromASCII(""); 568 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); 569 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 570 ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); 571 ecmaRuntimeCallInfo->SetCallArg(0, inputString.GetTaggedValue()); 572 ecmaRuntimeCallInfo->SetCallArg(1, replaceString.GetTaggedValue()); 573 574 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 575 // invoke replace method 576 JSTaggedValue results = BuiltinsRegExp::Replace(ecmaRuntimeCallInfo); 577 JSHandle<JSTaggedValue> replaceResult(thread, results); 578 JSHandle<EcmaString> resultZero = factory->NewFromASCII("de"); 579 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>(replaceResult), resultZero), 0); 580} 581 582HWTEST_F_L0(BuiltinsRegExpTest, RegExpParseCache) 583{ 584 RegExpParserCache *regExpParserCache = thread->GetCurrentEcmaContext()->GetRegExpParserCache(); 585 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 586 JSHandle<EcmaString> string1 = factory->NewFromASCII("abc"); 587 JSHandle<EcmaString> string2 = factory->NewFromASCII("abcd"); 588 CVector<CString> vec; 589 regExpParserCache->SetCache(*string1, 0, JSTaggedValue::True(), 2, vec); 590 ASSERT_TRUE(regExpParserCache->GetCache(*string1, 0, vec).first.IsTrue()); 591 ASSERT_TRUE(regExpParserCache->GetCache(*string1, 0, vec).second == 2U); 592 ASSERT_TRUE(regExpParserCache->GetCache(*string1, 593 RegExpParserCache::CACHE_SIZE, vec).first.IsHole()); 594 ASSERT_TRUE(regExpParserCache->GetCache(*string2, 0, vec).first.IsHole()); 595 ASSERT_TRUE(regExpParserCache->GetCache(*string2, UINT32_MAX, vec).first.IsHole()); 596} 597 598HWTEST_F_L0(BuiltinsRegExpTest, FlagD) 599{ 600 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 601 // invoke RegExpConstructor method 602 JSHandle<EcmaString> pattern1 = factory->NewFromASCII("(?<groupname>a)"); 603 JSHandle<EcmaString> flags1 = factory->NewFromASCII("gd"); 604 JSTaggedValue result1 = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern1, flags1); 605 JSHandle<JSTaggedValue> result1Handle(thread, result1); 606 607 // invoke GetFlags method 608 JSHandle<JSTaggedValue> flags(factory->NewFromASCII("flags")); 609 JSHandle<JSTaggedValue> flagsResult(JSObject::GetProperty(thread, result1Handle, flags).GetValue()); 610 JSHandle<EcmaString> expectResult = factory->NewFromASCII("dg"); 611 ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>(flagsResult), expectResult), 0); 612 613 // invoke GetHasIndices method 614 JSHandle<JSTaggedValue> hasIndices(factory->NewFromASCII("hasIndices")); 615 JSTaggedValue taggedHasIndicesResult = 616 JSObject::GetProperty(thread, result1Handle, hasIndices).GetValue().GetTaggedValue(); 617 ASSERT_EQ(taggedHasIndicesResult.GetRawData(), JSTaggedValue::True().GetRawData()); 618 619 JSHandle<EcmaString> inputString = factory->NewFromASCII("babcae"); 620 auto ecmaRuntimeCallInfo = 621 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means 1 call arg 622 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 623 ecmaRuntimeCallInfo->SetThis(result1Handle.GetTaggedValue()); 624 ecmaRuntimeCallInfo->SetCallArg(0, inputString.GetTaggedValue()); 625 626 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 627 // invoke Exec method 628 JSTaggedValue results = BuiltinsRegExp::Exec(ecmaRuntimeCallInfo); 629 TestHelper::TearDownFrame(thread, prev); 630 631 JSHandle<JSTaggedValue> execResult(thread, results); 632 JSHandle<JSTaggedValue> indices(factory->NewFromASCII("indices")); 633 JSHandle<JSTaggedValue> indicesArr = JSObject::GetProperty(thread, execResult, indices).GetValue(); 634 EXPECT_TRUE(indicesArr->IsJSArray()); 635 636 JSHandle<JSTaggedValue> indices0 = JSObject::GetProperty(thread, indicesArr, 0).GetValue(); 637 EXPECT_TRUE(indices0->IsJSArray()); 638 // indices[0] [1, 2] 639 EXPECT_EQ(JSObject::GetProperty(thread, indices0, 0).GetValue()->GetInt(), 1); 640 EXPECT_EQ(JSObject::GetProperty(thread, indices0, 1).GetValue()->GetInt(), 2); 641 JSHandle<JSTaggedValue> indices1 = JSObject::GetProperty(thread, indicesArr, 1).GetValue(); 642 EXPECT_TRUE(indices1->IsJSArray()); 643 // indices[1] [1, 2] 644 EXPECT_EQ(JSObject::GetProperty(thread, indices1, 0).GetValue()->GetInt(), 1); 645 EXPECT_EQ(JSObject::GetProperty(thread, indices1, 1).GetValue()->GetInt(), 2); 646 647 JSHandle<JSTaggedValue> groups(factory->NewFromASCII("groups")); 648 JSHandle<JSTaggedValue> groupsObj = JSObject::GetProperty(thread, indicesArr, groups).GetValue(); 649 EXPECT_TRUE(groupsObj->IsJSObject()); 650 JSHandle<JSTaggedValue> groupName(factory->NewFromASCII("groupname")); 651 JSHandle<JSTaggedValue> groupNameArr = JSObject::GetProperty(thread, groupsObj, groupName).GetValue(); 652 EXPECT_TRUE(groupNameArr->IsJSArray()); 653 // {groupname: [1,2]]} 654 EXPECT_EQ(JSObject::GetProperty(thread, groupNameArr, 0).GetValue()->GetInt(), 1); 655 EXPECT_EQ(JSObject::GetProperty(thread, groupNameArr, 1).GetValue()->GetInt(), 2); 656} 657} // namespace panda::test 658