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