1/* 2 * Copyright (c) 2022 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_iterator.h" 17#include "ecmascript/builtins/builtins_regexp.h" 18#include "ecmascript/global_env.h" 19#include "ecmascript/js_regexp.h" 20#include "ecmascript/tests/ecma_test_common.h" 21 22using namespace panda::ecmascript; 23using namespace panda::ecmascript::builtins; 24 25namespace panda::test { 26using BuiltinsRegExp = builtins::BuiltinsRegExp; 27class JSRegexpIteratorTest : public BaseTestWithScope<false> { 28}; 29 30HWTEST_F_L0(JSRegexpIteratorTest, CreateRegExpStringIterator) 31{ 32 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 33 JSHandle<EcmaString> pattern = factory->NewFromASCII("\\w+"); 34 JSHandle<EcmaString> flags = factory->NewFromASCII("gim"); 35 36 JSHandle<JSTaggedValue> matchHandle(thread, TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern, flags)); 37 JSHandle<EcmaString> inputStr = factory->NewFromASCII("g"); 38 JSHandle<JSTaggedValue> regExpIterator = 39 JSRegExpIterator::CreateRegExpStringIterator(thread, matchHandle, inputStr, true, false); 40 EXPECT_TRUE(regExpIterator->IsJSRegExpIterator()); 41 regExpIterator = 42 JSRegExpIterator::CreateRegExpStringIterator(thread, matchHandle, inputStr, false, false); 43 EXPECT_TRUE(regExpIterator->IsJSRegExpIterator()); 44} 45 46HWTEST_F_L0(JSRegexpIteratorTest, Next) 47{ 48 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 49 JSHandle<EcmaString> pattern = factory->NewFromASCII("-[0-9]+"); 50 JSHandle<EcmaString> flags = factory->NewFromASCII("g"); 51 JSHandle<EcmaString> inputStr = factory->NewFromASCII("2016-01-02|2019-03-04"); 52 JSHandle<JSTaggedValue> zero(factory->NewFromASCII("0")); 53 JSHandle<JSTaggedValue> barZero(factory->NewFromASCII("-0")); 54 55 JSTaggedValue jsRegExp = TestCommon::CreateJSRegexpByPatternAndFlags(thread, pattern, flags); 56 JSHandle<JSRegExp> ObjValue(thread, reinterpret_cast<JSRegExp *>(jsRegExp.GetRawData())); 57 // create regExp iterator 58 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); 59 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); 60 ecmaRuntimeCallInfo1->SetThis(ObjValue.GetTaggedValue()); 61 ecmaRuntimeCallInfo1->SetCallArg(0, inputStr.GetTaggedValue()); 62 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); 63 JSTaggedValue iteratorValue = BuiltinsRegExp::MatchAll(ecmaRuntimeCallInfo1); 64 TestHelper::TearDownFrame(thread, prev); 65 66 JSHandle<JSRegExpIterator> regExpIterator(thread, reinterpret_cast<JSRegExpIterator *>(iteratorValue.GetRawData())); 67 uint32_t matchLength = 4; // 4 : 4 Number of matches 68 // traversal regExp iterator 69 for (uint32_t i = 0; i <= matchLength; i++) { 70 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); 71 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined()); 72 ecmaRuntimeCallInfo2->SetThis(regExpIterator.GetTaggedValue()); 73 74 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2); 75 JSTaggedValue result = JSRegExpIterator::Next(ecmaRuntimeCallInfo2); 76 TestHelper::TearDownFrame(thread, prev); 77 78 JSHandle<JSTaggedValue> matchObj(thread, result); 79 if (i <= matchLength - 1) { 80 JSHandle<JSTaggedValue> resultValue(thread, JSTaggedValue(i + 1)); 81 JSHandle<EcmaString> compareVal = 82 factory->ConcatFromString(JSHandle<EcmaString>(barZero), JSTaggedValue::ToString(thread, resultValue)); 83 JSHandle<JSTaggedValue> matchResult = JSIterator::IteratorValue(thread, matchObj); 84 JSHandle<JSTaggedValue> zeroHandle(JSObject::GetProperty(thread, matchResult, zero).GetValue()); 85 JSHandle<EcmaString> outputZero = JSTaggedValue::ToString(thread, zeroHandle); 86 EXPECT_EQ(EcmaStringAccessor::Compare(instance, outputZero, compareVal), 0); 87 EXPECT_FALSE(regExpIterator->GetDone()); 88 } 89 else { 90 EXPECT_TRUE(regExpIterator->GetDone()); 91 EXPECT_EQ(JSIterator::IteratorValue(thread, matchObj).GetTaggedValue(), JSTaggedValue::Undefined()); 92 } 93 } 94} 95} // namespace panda::test