* Copyright (c) 2021-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecmascript/builtins/builtins_string.h"
#include "ecmascript/base/builtins_base.h"
#include "ecmascript/builtins/builtins_regexp.h"
#include "ecmascript/ecma_runtime_call_info.h"
#include "ecmascript/ecma_string.h"
#include "ecmascript/ecma_vm.h"
#include "ecmascript/global_env.h"
#include "ecmascript/shared_objects/js_shared_array.h"
#include "ecmascript/js_array.h"
#include "ecmascript/js_object-inl.h"
#include "ecmascript/js_primitive_ref.h"
#include "ecmascript/js_regexp.h"
#include "ecmascript/js_tagged_value.h"
#include "ecmascript/object_factory.h"
#include "ecmascript/tests/test_helper.h"
using namespace panda::ecmascript;
using namespace panda::ecmascript::builtins;
namespace panda::test {
class BuiltinsStringTest : public BaseTestWithScope<true> {
};
JSTaggedValue CreateBuiltinsStringRegExpObjByPatternAndFlags(JSThread *thread, const JSHandle<EcmaString> &pattern,
const JSHandle<EcmaString> &flags)
{
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
JSHandle<JSFunction> regexp(env->GetRegExpFunction());
JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, regexp.GetTaggedValue(), 8);
ecmaRuntimeCallInfo->SetFunction(regexp.GetTaggedValue());
ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, pattern.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(1, flags.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsRegExp::RegExpConstructor(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
return result;
}
enum class AlgorithmType {
FROM_CHAR_CODE,
FROM_CODE_POINT,
CHAR_AT,
CHAR_CODE_AT,
CODE_POINT_AT,
CONCAT,
INDEX_OF,
LAST_INDEX_OF,
INCLUDES,
START_WITH,
ENDS_WITH,
TO_STRING,
VALUE_OF,
REPLACE,
SPLIT,
};
JSTaggedValue StringAlgorithmOther(EcmaRuntimeCallInfo*ecmaRuntimeCallInfos, AlgorithmType type)
{
switch (type) {
case AlgorithmType::START_WITH:
return BuiltinsString::StartsWith(ecmaRuntimeCallInfos);
case AlgorithmType::ENDS_WITH:
return BuiltinsString::EndsWith(ecmaRuntimeCallInfos);
case AlgorithmType::TO_STRING:
return BuiltinsString::ToString(ecmaRuntimeCallInfos);
case AlgorithmType::VALUE_OF:
return BuiltinsString::ValueOf(ecmaRuntimeCallInfos);
case AlgorithmType::REPLACE:
return BuiltinsString::Replace(ecmaRuntimeCallInfos);
case AlgorithmType::SPLIT:
return BuiltinsString::Split(ecmaRuntimeCallInfos);
default:
return JSTaggedValue::Undefined();
}
}
JSTaggedValue StringAlgorithm(JSThread *thread, JSTaggedValue thisArg, std::vector<JSTaggedValue>& args,
uint32_t argLen = 8, AlgorithmType type = AlgorithmType::FROM_CHAR_CODE)
{
auto ecmaRuntimeCallInfos = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), argLen);
ecmaRuntimeCallInfos->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfos->SetThis(thisArg);
for (size_t i = 0; i < args.size(); i++) {
ecmaRuntimeCallInfos->SetCallArg(i, args[i]);
}
auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfos);
JSTaggedValue result;
switch (type) {
case AlgorithmType::FROM_CHAR_CODE:
result = BuiltinsString::FromCharCode(ecmaRuntimeCallInfos);
break;
case AlgorithmType::FROM_CODE_POINT:
result = BuiltinsString::FromCodePoint(ecmaRuntimeCallInfos);
break;
case AlgorithmType::CHAR_AT:
result = BuiltinsString::CharAt(ecmaRuntimeCallInfos);
break;
case AlgorithmType::CHAR_CODE_AT:
result = BuiltinsString::CharCodeAt(ecmaRuntimeCallInfos);
break;
case AlgorithmType::CODE_POINT_AT:
result = BuiltinsString::CodePointAt(ecmaRuntimeCallInfos);
break;
case AlgorithmType::CONCAT:
result = BuiltinsString::Concat(ecmaRuntimeCallInfos);
break;
case AlgorithmType::INDEX_OF:
result = BuiltinsString::IndexOf(ecmaRuntimeCallInfos);
break;
case AlgorithmType::LAST_INDEX_OF:
result = BuiltinsString::LastIndexOf(ecmaRuntimeCallInfos);
break;
case AlgorithmType::INCLUDES:
result = BuiltinsString::Includes(ecmaRuntimeCallInfos);
break;
default:
result = StringAlgorithmOther(ecmaRuntimeCallInfos, type);
break;
}
TestHelper::TearDownFrame(thread, prev);
return result;
}
HWTEST_F_L0(BuiltinsStringTest, StringConstructor1)
{
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<JSFunction> string(env->GetStringFunction());
JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
JSHandle<EcmaString> string2 = factory->NewFromASCII("ABC");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, string.GetTaggedValue(), 6);
ecmaRuntimeCallInfo->SetFunction(string.GetTaggedValue());
ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, string2.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::StringConstructor(ecmaRuntimeCallInfo);
JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
ASSERT_TRUE(value.IsECMAObject());
JSHandle<JSPrimitiveRef> ref(thread, JSPrimitiveRef::Cast(value.GetTaggedObject()));
JSHandle<EcmaString> test = factory->NewFromASCII("ABC");
ASSERT_EQ(EcmaStringAccessor::Compare(instance,
JSHandle<EcmaString>(thread, EcmaString::Cast(ref->GetValue(thread))), test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, fromCharCode1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
const double arg1 = 65;
const double arg2 = 66;
const double arg3 = 67;
std::vector<JSTaggedValue> args{JSTaggedValue(arg1), JSTaggedValue(arg2), JSTaggedValue(arg3)};
auto result = StringAlgorithm(thread, JSTaggedValue::Undefined(), args, 10, AlgorithmType::FROM_CHAR_CODE);
ASSERT_TRUE(result.IsString());
JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
JSHandle<JSTaggedValue> valueHandle(thread, JSTaggedValue(value.GetTaggedObject()));
JSHandle<EcmaString> test = factory->NewFromASCII("ABC");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, JSHandle<EcmaString>::Cast(valueHandle), test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, fromCodePoint1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
const double arg1 = 65;
const double arg2 = 66;
const double arg3 = 67;
std::vector<JSTaggedValue> args{JSTaggedValue(arg1), JSTaggedValue(arg2), JSTaggedValue(arg3)};
auto result = StringAlgorithm(thread, JSTaggedValue::Undefined(), args, 10, AlgorithmType::FROM_CODE_POINT);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("ABC");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, charAt1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisVal = factory->NewFromASCII("abcabcabc");
std::vector<JSTaggedValue> args{JSTaggedValue(static_cast<double>(5))};
auto result = StringAlgorithm(thread, thisVal.GetTaggedValue(), args, 6, AlgorithmType::CHAR_AT);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("c");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, charAt2)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisVal = factory->NewFromUtf8("一二三四");
std::vector<JSTaggedValue> args{JSTaggedValue(static_cast<double>(2))};
auto result = StringAlgorithm(thread, thisVal.GetTaggedValue(), args, 6, AlgorithmType::CHAR_AT);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromUtf8("三");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, charAt3)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisVal = factory->NewFromASCII("abcabcabc");
std::vector<JSTaggedValue> args{JSTaggedValue(static_cast<double>(-1))};
auto result = StringAlgorithm(thread, thisVal.GetTaggedValue(), args, 6, AlgorithmType::CHAR_AT);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->GetEmptyString();
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, charCodeAt1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisVal = factory->NewFromASCII("ABC");
std::vector<JSTaggedValue> args{JSTaggedValue(static_cast<double>(0))};
auto result = StringAlgorithm(thread, thisVal.GetTaggedValue(), args, 6, AlgorithmType::CHAR_CODE_AT);
ASSERT_EQ(result.GetRawData(), JSTaggedValue(65).GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, charCodeAt2)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisVal = factory->NewFromASCII("ABC");
std::vector<JSTaggedValue> args{JSTaggedValue(static_cast<double>(-1))};
auto result = StringAlgorithm(thread, thisVal.GetTaggedValue(), args, 6, AlgorithmType::CHAR_CODE_AT);
JSTaggedValue test = BuiltinsString::GetTaggedDouble(base::NAN_VALUE);
ASSERT_EQ(result.GetRawData(), test.GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, codePointAt1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisVal = factory->NewFromASCII("ABC");
std::vector<JSTaggedValue> args{JSTaggedValue(static_cast<double>(1))};
auto result = StringAlgorithm(thread, thisVal.GetTaggedValue(), args, 6, AlgorithmType::CODE_POINT_AT);
ASSERT_EQ(result.GetRawData(), JSTaggedValue(66).GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, concat1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("a");
JSHandle<EcmaString> val1 = factory->NewFromASCII("b");
JSHandle<EcmaString> val2 = factory->NewFromASCII("c");
JSHandle<EcmaString> val3 = factory->NewFromASCII("d");
std::vector<JSTaggedValue> args{val1.GetTaggedValue(), val2.GetTaggedValue(), val3.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 10, AlgorithmType::CONCAT);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("abcd");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, indexof1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
JSHandle<EcmaString> val = factory->NewFromASCII("b");
std::vector<JSTaggedValue> args{val.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::INDEX_OF);
ASSERT_EQ(result.GetRawData(), JSTaggedValue(1).GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, indexof2)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
JSHandle<EcmaString> val = factory->NewFromASCII("b");
std::vector<JSTaggedValue> args{val.GetTaggedValue(), JSTaggedValue(static_cast<double>(2))};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::INDEX_OF);
ASSERT_EQ(result.GetRawData(), JSTaggedValue(4).GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, indexof3)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
JSHandle<EcmaString> val = factory->NewFromASCII("d");
std::vector<JSTaggedValue> args{val.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::INDEX_OF);
ASSERT_EQ(result.GetRawData(), JSTaggedValue(-1).GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, lastIndexOf1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
JSHandle<EcmaString> val = factory->NewFromASCII("b");
std::vector<JSTaggedValue> args{val.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::LAST_INDEX_OF);
ASSERT_EQ(result.GetRawData(), JSTaggedValue(7).GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, lastIndexOf2)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
JSHandle<EcmaString> val = factory->NewFromASCII("b");
std::vector<JSTaggedValue> args{val.GetTaggedValue(), JSTaggedValue(static_cast<double>(2))};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::LAST_INDEX_OF);
ASSERT_EQ(result.GetRawData(), JSTaggedValue(1).GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, lastIndexOf3)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
JSHandle<EcmaString> val = factory->NewFromASCII("d");
std::vector<JSTaggedValue> args{val.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::LAST_INDEX_OF);
ASSERT_EQ(result.GetRawData(), JSTaggedValue(-1).GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, Includes2)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
JSHandle<EcmaString> val = factory->NewFromASCII("b");
std::vector<JSTaggedValue> args{val.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::INCLUDES);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, Includes3)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abccccccc");
JSHandle<EcmaString> val = factory->NewFromASCII("b");
std::vector<JSTaggedValue> args{val.GetTaggedValue(), JSTaggedValue(static_cast<double>(2))};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::INCLUDES);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, Includes4)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromUtf8("一二三四");
JSHandle<EcmaString> val = factory->NewFromUtf8("二");
std::vector<JSTaggedValue> args{val.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::INCLUDES);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, startsWith1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("To be, or not to be, that is the question.");
JSHandle<EcmaString> val = factory->NewFromASCII("To be");
std::vector<JSTaggedValue> args{val.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::START_WITH);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, startsWith2)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("To be, or not to be, that is the question.");
JSHandle<EcmaString> val = factory->NewFromASCII("not to be");
std::vector<JSTaggedValue> args{val.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::START_WITH);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, startsWith3)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("To be, or not to be, that is the question.");
JSHandle<EcmaString> val = factory->NewFromASCII("not to be");
std::vector<JSTaggedValue> args{val.GetTaggedValue(), JSTaggedValue(static_cast<double>(10))};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::START_WITH);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, endsWith1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("To be, or not to be, that is the question.");
JSHandle<EcmaString> val = factory->NewFromASCII("question.");
std::vector<JSTaggedValue> args{val.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::ENDS_WITH);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, endsWith2)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("To be, or not to be, that is the question.");
JSHandle<EcmaString> val = factory->NewFromASCII("to be");
std::vector<JSTaggedValue> args{val.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 6, AlgorithmType::ENDS_WITH);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, endsWith3)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("To be, or not to be, that is the question.");
JSHandle<EcmaString> val = factory->NewFromASCII("to be");
std::vector<JSTaggedValue> args{val.GetTaggedValue(), JSTaggedValue(static_cast<double>(19))};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::ENDS_WITH);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, toLocaleLowerCase2)
{
ASSERT_NE(thread, nullptr);
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromUtf8("有ABC");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::ToLocaleLowerCase(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromUtf8("有abc");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, toLowerCase1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("ABC");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::ToLowerCase(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("abc");
ASSERT_TRUE(JSTaggedValue::SameValue(thread, resultHandle.GetTaggedValue(), test.GetTaggedValue()));
}
HWTEST_F_L0(BuiltinsStringTest, toUpperCase1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abc");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::ToUpperCase(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("ABC");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, localecompare1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abc");
JSHandle<EcmaString> val = factory->NewFromASCII("b");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, val.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::LocaleCompare(ecmaRuntimeCallInfo);
ASSERT_EQ(result.GetRawData(), JSTaggedValue(-1).GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, localecompare2)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abc");
JSHandle<EcmaString> val = factory->NewFromASCII("abc");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, val.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::LocaleCompare(ecmaRuntimeCallInfo);
ASSERT_EQ(result.GetRawData(), JSTaggedValue(0).GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, localecompare3)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abc");
JSHandle<EcmaString> val = factory->NewFromASCII("aa");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, val.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::LocaleCompare(ecmaRuntimeCallInfo);
ASSERT_EQ(result.GetRawData(), JSTaggedValue(1).GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, localecompare4)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
std::string referenceStr = "你好";
std::string compareStr = "辅助";
JSHandle<EcmaString> thisStr = factory->NewFromStdString(referenceStr);
JSHandle<EcmaString> val = factory->NewFromStdString(compareStr);
JSHandle<EcmaString> locale = factory->NewFromASCII("zh-Hans");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, val.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(1, locale.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::LocaleCompare(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_GT(result.GetRawData(), JSTaggedValue(0).GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, localecompare5)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
std::string referenceStr = "ä";
std::string compareStr = "z";
JSHandle<EcmaString> thisStr = factory->NewFromStdString(referenceStr);
JSHandle<EcmaString> val = factory->NewFromStdString(compareStr);
JSHandle<EcmaString> locale = factory->NewFromASCII("de");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, val.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(1, locale.GetTaggedValue());
[[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::LocaleCompare(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev1);
ASSERT_EQ(result.GetRawData(), JSTaggedValue(-1).GetRawData());
auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo1->SetThis(thisStr.GetTaggedValue());
ecmaRuntimeCallInfo1->SetCallArg(0, val.GetTaggedValue());
ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue::Undefined());
[[maybe_unused]] auto prev2 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result1 = BuiltinsString::LocaleCompare(ecmaRuntimeCallInfo1);
TestHelper::TearDownFrame(thread, prev2);
ASSERT_EQ(result1.GetRawData(), JSTaggedValue(-1).GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, normalize1)
{
ASSERT_NE(thread, nullptr);
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abc");
JSHandle<EcmaString> val = factory->NewFromASCII("NFC");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, val.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::Normalize(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("abc");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, repeat1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abc");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(5)));
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::Repeat(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("abcabcabcabcabc");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, slice1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("The morning is upon us.");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(4)));
ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<double>(-2)));
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::Slice(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("morning is upon u");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, slice2)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("The morning is upon us.");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(12)));
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::Slice(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("is upon us.");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, substring1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("Mozilla");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(3)));
ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<double>(-3)));
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::Substring(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("Moz");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, substring2)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("Mozilla");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(7)));
ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<double>(4)));
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::Substring(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("lla");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, trim1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII(" Hello world! ");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisStr.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::Trim(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("Hello world!");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, trim2)
{
auto ecmaVM = thread->GetEcmaVM();
JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII(" Hello world! ");
JSHandle<JSFunction> stringObject(env->GetStringFunction());
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(thisStr.GetTaggedValue().GetTaggedObject()));
JSHandle<JSPrimitiveRef> str = factory->NewJSPrimitiveRef(stringObject, value);
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(str.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::Trim(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("Hello world!");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, trimRight)
{
auto ecmaVM = thread->GetEcmaVM();
JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII(" ");
JSHandle<JSFunction> stringObject(env->GetStringFunction());
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(thisStr.GetTaggedValue().GetTaggedObject()));
JSHandle<JSPrimitiveRef> str = factory->NewJSPrimitiveRef(stringObject, value);
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(str.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::TrimRight(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromASCII("");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, ToString)
{
auto ecmaVM = thread->GetEcmaVM();
JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
JSHandle<JSFunction> stringObject(env->GetStringFunction());
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(thisStr.GetTaggedValue().GetTaggedObject()));
JSHandle<JSPrimitiveRef> str = factory->NewJSPrimitiveRef(stringObject, value);
std::vector<JSTaggedValue> args{};
auto result = StringAlgorithm(thread, str.GetTaggedValue(), args, 4, AlgorithmType::TO_STRING);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSTaggedValue test = JSTaggedValue(*thisStr);
ASSERT_EQ(result.GetRawData(), test.GetRawData());
}
HWTEST_F_L0(BuiltinsStringTest, ValueOf)
{
auto ecmaVM = thread->GetEcmaVM();
JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("abcabcabc");
JSHandle<JSFunction> stringObject(env->GetStringFunction());
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(thisStr.GetTaggedValue().GetTaggedObject()));
JSHandle<JSPrimitiveRef> str = factory->NewJSPrimitiveRef(stringObject, value);
std::vector<JSTaggedValue> args{};
auto result = StringAlgorithm(thread, str.GetTaggedValue(), args, 4, AlgorithmType::VALUE_OF);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSTaggedValue test = JSTaggedValue(*thisStr);
ASSERT_EQ(result.GetRawData(), test.GetRawData());
}
static inline JSFunction *BuiltinsStringTestCreate(JSThread *thread)
{
EcmaVM *ecmaVM = thread->GetEcmaVM();
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
return globalEnv->GetObjectFunction().GetObject<JSFunction>();
}
HWTEST_F_L0(BuiltinsStringTest, Raw)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<JSTaggedValue> foo(factory->NewFromASCII("foo"));
JSHandle<JSTaggedValue> bar(factory->NewFromASCII("bar"));
JSHandle<JSTaggedValue> baz(factory->NewFromASCII("baz"));
JSHandle<JSTaggedValue> rawArray = JSHandle<JSTaggedValue>::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)));
JSHandle<JSObject> obj(rawArray);
JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
PropertyDescriptor desc0(thread, foo);
JSArray::DefineOwnProperty(thread, obj, key0, desc0);
JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
PropertyDescriptor desc1(thread, bar);
JSArray::DefineOwnProperty(thread, obj, key1, desc1);
JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(2));
PropertyDescriptor desc2(thread, baz);
JSArray::DefineOwnProperty(thread, obj, key2, desc2);
JSHandle<JSTaggedValue> constructor(thread, BuiltinsStringTestCreate(thread));
JSHandle<JSTaggedValue> templateString(
factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
JSHandle<JSTaggedValue> rawKey(factory->NewFromASCII("raw"));
JSObject::SetProperty(thread, templateString, rawKey, rawArray);
JSHandle<EcmaString> test = factory->NewFromASCII("foo5barJavaScriptbaz");
JSHandle<EcmaString> javascript = factory->NewFromASCII("JavaScript");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(templateString.GetObject<EcmaString>()));
ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(5)));
ecmaRuntimeCallInfo->SetCallArg(2, javascript.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::Raw(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, reinterpret_cast<EcmaString *>(result.GetRawData()),
*test));
}
HWTEST_F_L0(BuiltinsStringTest, Replace)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("Twas the night before Xmas...");
JSHandle<EcmaString> searchStr = factory->NewFromASCII("Xmas");
JSHandle<EcmaString> replaceStr = factory->NewFromASCII("Christmas");
JSHandle<EcmaString> expected = factory->NewFromASCII("Twas the night before Christmas...");
std::vector<JSTaggedValue> args{searchStr.GetTaggedValue(), replaceStr.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
ASSERT_TRUE(result.IsString());
ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, reinterpret_cast<EcmaString *>(result.GetRawData()),
*expected));
JSHandle<EcmaString> replaceStr1 = factory->NewFromASCII("abc$$");
JSHandle<EcmaString> expected1 = factory->NewFromASCII("Twas the night before abc$...");
args[0] = searchStr.GetTaggedValue();
args[1] = replaceStr1.GetTaggedValue();
auto result1 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
JSHandle<EcmaString> resultString1(thread, result1);
ASSERT_TRUE(result1.IsString());
ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString1, *expected1));
JSHandle<EcmaString> replaceStr2 = factory->NewFromASCII("abc$$dd");
JSHandle<EcmaString> expected2 = factory->NewFromASCII("Twas the night before abc$dd...");
args[0] = searchStr.GetTaggedValue();
args[1] = replaceStr2.GetTaggedValue();
auto result2 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
JSHandle<EcmaString> resultString2(thread, result2);
ASSERT_TRUE(result2.IsString());
ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString2, *expected2));
JSHandle<EcmaString> replaceStr3 = factory->NewFromASCII("abc$&dd");
JSHandle<EcmaString> expected3 = factory->NewFromASCII("Twas the night before abcXmasdd...");
args[0] = searchStr.GetTaggedValue();
args[1] = replaceStr3.GetTaggedValue();
auto result3 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
JSHandle<EcmaString> resultString3(thread, result3);
ASSERT_TRUE(result3.IsString());
ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString3, *expected3));
JSHandle<EcmaString> replaceStr4 = factory->NewFromASCII("abc$`dd");
JSHandle<EcmaString> expected4 =
factory->NewFromASCII("Twas the night before abcTwas the night before dd...");
args[0] = searchStr.GetTaggedValue();
args[1] = replaceStr4.GetTaggedValue();
auto result4 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
JSHandle<EcmaString> resultString4(thread, result4);
ASSERT_TRUE(result4.IsString());
ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString4, *expected4));
}
HWTEST_F_L0(BuiltinsStringTest, Replace2)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("Twas the night before Xmas...");
JSHandle<EcmaString> searchStr = factory->NewFromASCII("Xmas");
JSHandle<EcmaString> replaceStr = factory->NewFromASCII("abc$\'dd");
JSHandle<EcmaString> expected = factory->NewFromASCII("Twas the night before abc...dd...");
std::vector<JSTaggedValue> args{searchStr.GetTaggedValue(), replaceStr.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
ASSERT_TRUE(result.IsString());
ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, reinterpret_cast<EcmaString *>(result.GetRawData()),
*expected));
JSHandle<EcmaString> replaceStr2 = factory->NewFromASCII("abc$`dd$\'$ff");
JSHandle<EcmaString> expected2 =
factory->NewFromASCII("Twas the night before abcTwas the night before dd...$ff...");
args[0] = searchStr.GetTaggedValue();
args[1] = replaceStr2.GetTaggedValue();
auto result2 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
JSHandle<EcmaString> resultString2(thread, result2);
ASSERT_TRUE(result2.IsString());
ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString2, *expected2));
JSHandle<EcmaString> replaceStr3 = factory->NewFromASCII("abc$`dd$\'$");
JSHandle<EcmaString> expected3 =
factory->NewFromASCII("Twas the night before abcTwas the night before dd...$...");
args[0] = searchStr.GetTaggedValue();
args[1] = replaceStr3.GetTaggedValue();
auto result3 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
JSHandle<EcmaString> resultString3(thread, result3);
ASSERT_TRUE(result3.IsString());
ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString3, *expected3));
JSHandle<EcmaString> replaceStr4 = factory->NewFromASCII("abc$`dd$$");
JSHandle<EcmaString> expected4 =
factory->NewFromASCII("Twas the night before abcTwas the night before dd$...");
args[0] = searchStr.GetTaggedValue();
args[1] = replaceStr4.GetTaggedValue();
auto result4 = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
ASSERT_TRUE(result4.IsString());
JSHandle<EcmaString> resultString4(thread, result4);
ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *resultString4, *expected4));
}
HWTEST_F_L0(BuiltinsStringTest, Replace3)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("Twas the night before Xmas...");
JSHandle<EcmaString> searchStr = factory->NewFromASCII("Xmas");
JSHandle<EcmaString> replaceStr = factory->NewFromASCII("$&a $` $\' $2 $01 $$1 $21 $32 a");
JSHandle<EcmaString> expected = factory->NewFromASCII(
"Twas the night before Xmasa Twas the night before ... $2 $01 $1 $21 $32 a...");
std::vector<JSTaggedValue> args{searchStr.GetTaggedValue(), replaceStr.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
ASSERT_TRUE(result.IsString());
ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, reinterpret_cast<EcmaString *>(result.GetRawData()),
*expected));
}
HWTEST_F_L0(BuiltinsStringTest, Replace4)
{
JSHandle<EcmaString> pattern1 =
thread->GetEcmaVM()->GetFactory()->NewFromASCII("quick\\s(brown).+?(jumps)");
JSHandle<EcmaString> flags1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("iug");
JSTaggedValue result1 = CreateBuiltinsStringRegExpObjByPatternAndFlags(thread, pattern1, flags1);
JSHandle<JSRegExp> searchStr(thread, reinterpret_cast<JSRegExp *>(result1.GetRawData()));
JSHandle<EcmaString> expected = thread->GetEcmaVM()->GetFactory()->NewFromASCII(
"The Quick Brown Fox Jumpsa The Over The Lazy Dog Jumps Brown $1 Jumps1 $32 a Over The Lazy Dog");
JSHandle<EcmaString> thisStr =
thread->GetEcmaVM()->GetFactory()->NewFromASCII("The Quick Brown Fox Jumps Over The Lazy Dog");
JSHandle<EcmaString> replaceStr =
thread->GetEcmaVM()->GetFactory()->NewFromASCII("$&a $` $\' $2 $01 $$1 $21 $32 a");
std::vector<JSTaggedValue> args{searchStr.GetTaggedValue(), replaceStr.GetTaggedValue()};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::REPLACE);
ASSERT_TRUE(result.IsString());
ASSERT_TRUE(
EcmaStringAccessor::StringsAreEqual(thread, reinterpret_cast<EcmaString *>(result.GetRawData()), *expected));
}
void SplitCommon(JSThread *thread, std::vector<JSHandle<EcmaString>> expecteds, JSHandle<JSArray> &resultArray)
{
JSHandle<JSTaggedValue> resultObj(resultArray);
for (size_t i = 0; i < expecteds.size(); i++) {
JSHandle<EcmaString> str(
JSObject::GetProperty(thread, resultObj,
JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<int>(i))))
.GetValue());
ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread, *str, *expecteds[i]));
}
}
HWTEST_F_L0(BuiltinsStringTest, Split)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("Hello World. How are you doing?");
JSHandle<EcmaString> separatorStr = factory->NewFromASCII(" ");
JSHandle<JSTaggedValue> limit(thread, JSTaggedValue(3));
JSHandle<EcmaString> expected1 = factory->NewFromASCII("Hello");
JSHandle<EcmaString> expected2 = factory->NewFromASCII("World.");
JSHandle<EcmaString> expected3 = factory->NewFromASCII("How");
std::vector<JSTaggedValue> args{separatorStr.GetTaggedValue(), JSTaggedValue(static_cast<int32_t>(3))};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::SPLIT);
ASSERT_TRUE(result.IsECMAObject());
JSHandle<JSArray> resultArray(thread, reinterpret_cast<JSArray *>(result.GetRawData()));
ASSERT_TRUE(resultArray->IsJSArray());
std::vector<JSHandle<EcmaString>> expecteds{expected1, expected2, expected3};
SplitCommon(thread, expecteds, resultArray);
}
HWTEST_F_L0(BuiltinsStringTest, Split2)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisStr = factory->NewFromASCII("a-b-c");
JSHandle<EcmaString> pattern1 = factory->NewFromASCII("-");
JSHandle<EcmaString> flags1 = factory->NewFromASCII("iug");
JSTaggedValue result1 = CreateBuiltinsStringRegExpObjByPatternAndFlags(thread, pattern1, flags1);
JSHandle<JSRegExp> separatorObj(thread, result1);
JSHandle<JSTaggedValue> limit(thread, JSTaggedValue(3));
JSHandle<EcmaString> expected1 = factory->NewFromASCII("a");
JSHandle<EcmaString> expected2 = factory->NewFromASCII("b");
JSHandle<EcmaString> expected3 = factory->NewFromASCII("c");
std::vector<JSTaggedValue> args{separatorObj.GetTaggedValue(), JSTaggedValue(static_cast<int32_t>(3))};
auto result = StringAlgorithm(thread, thisStr.GetTaggedValue(), args, 8, AlgorithmType::SPLIT);
ASSERT_TRUE(result.IsECMAObject());
JSHandle<JSArray> resultArray(thread, result);
ASSERT_TRUE(resultArray->IsJSArray());
std::vector<JSHandle<EcmaString>> expecteds{expected1, expected2, expected3};
SplitCommon(thread, expecteds, resultArray);
}
HWTEST_F_L0(BuiltinsStringTest, at1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisVal = factory->NewFromUtf8("一二三四");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisVal.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(3)));
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::At(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromUtf8("四");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, at2)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisVal = factory->NewFromUtf8("一二三四");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisVal.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(-2)));
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::At(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsString());
JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
JSHandle<EcmaString> test = factory->NewFromUtf8("三");
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, test), 0);
}
HWTEST_F_L0(BuiltinsStringTest, at3)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisVal = factory->NewFromUtf8("一二三四");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisVal.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(-5)));
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::At(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsUndefined());
}
HWTEST_F_L0(BuiltinsStringTest, at4)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> thisVal = factory->NewFromASCII("abcabcabc");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(thisVal.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(9)));
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsString::At(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsUndefined());
}
HWTEST_F_L0(BuiltinsStringTest, StringToSList)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> str = factory->NewFromASCII("hello");
JSTaggedValue result = BuiltinsString::StringToSList(thread, str);
ASSERT_TRUE(result.IsJSSharedArray());
JSSharedArray *arr = JSSharedArray::Cast(result.GetTaggedObject());
EXPECT_EQ(arr->GetArrayLength(), 5U);
}
HWTEST_F_L0(BuiltinsStringTest, StringToSListAfterStringToList)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> str = factory->NewFromASCII("abc");
JSTaggedValue listResult = BuiltinsString::StringToList(thread, str);
ASSERT_TRUE(listResult.IsECMAObject());
JSTaggedValue sListResult = BuiltinsString::StringToSList(thread, str);
ASSERT_TRUE(sListResult.IsJSSharedArray());
JSSharedArray *arr = JSSharedArray::Cast(sListResult.GetTaggedObject());
EXPECT_EQ(arr->GetArrayLength(), 3U);
}
HWTEST_F_L0(BuiltinsStringTest, StringToSListCacheConsistency)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<EcmaString> str = factory->NewFromASCII("test");
JSTaggedValue sListResult1 = BuiltinsString::StringToSList(thread, str);
ASSERT_TRUE(sListResult1.IsJSSharedArray());
JSTaggedValue sListResult2 = BuiltinsString::StringToSList(thread, str);
ASSERT_TRUE(sListResult2.IsJSSharedArray());
JSSharedArray *arr1 = JSSharedArray::Cast(sListResult1.GetTaggedObject());
JSSharedArray *arr2 = JSSharedArray::Cast(sListResult2.GetTaggedObject());
EXPECT_EQ(arr1->GetArrayLength(), arr2->GetArrayLength());
}
}