* Copyright (c) 2021 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_object.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/js_array.h"
#include "ecmascript/js_handle.h"
#include "ecmascript/js_object-inl.h"
#include "ecmascript/js_primitive_ref.h"
#include "ecmascript/js_tagged_value-inl.h"
#include "ecmascript/js_thread.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 BuiltinsObjectTest : public BaseTestWithScope<false> {
};
JSTaggedValue CreateBuiltinJSObject(JSThread *thread, const CString keyCStr)
{
EcmaVM *ecmaVM = thread->GetEcmaVM();
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
JSHandle<JSTaggedValue> objFun = globalEnv->GetObjectFunction();
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<JSTaggedValue> obj(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
JSHandle<JSTaggedValue> key(factory->NewFromASCII(&keyCStr[0]));
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
JSObject::SetProperty(thread, obj, key, value);
return obj.GetTaggedValue();
}
JSFunction *BuiltinsObjectTestCreate(JSThread *thread)
{
EcmaVM *ecmaVM = thread->GetEcmaVM();
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
return globalEnv->GetObjectFunction().GetObject<JSFunction>();
}
JSObject *TestNewJSObject(JSThread *thread, const JSHandle<JSHClass> &hclass)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSObject *obj = JSObject::Cast(factory->NewObject(hclass));
obj->SetElements<SKIP_BARRIER>(thread, factory->EmptyArray().GetTaggedValue());
return obj;
}
HWTEST_F_L0(BuiltinsObjectTest, ObjectConstructor)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<JSFunction> objectFunc(thread, BuiltinsObjectTestCreate(thread));
JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
JSHandle<JSFunction> objFun(globalEnv->GetObjectFunction());
auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
objCallInfo->SetFunction(JSTaggedValue::Undefined());
objCallInfo->SetThis(JSTaggedValue::Undefined());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
JSTaggedValue result = BuiltinsObject::ObjectConstructor(objCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsECMAObject());
JSHandle<JSObject> jtHandle(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(result.GetRawData())));
JSTaggedValue resultProto = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(jtHandle));
JSTaggedValue funcProto = objectFunc->GetFunctionPrototype(thread);
ASSERT_EQ(resultProto, funcProto);
ASSERT_TRUE(jtHandle->IsExtensible());
JSHandle<JSObject> object =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(function), function);
object->GetJSHClass()->SetCallable(true);
auto tgObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*object), 4);
tgObjCallInfo->SetFunction(JSTaggedValue(*objFun));
tgObjCallInfo->SetThis(JSTaggedValue::Undefined());
tgObjCallInfo->SetNewTarget(JSTaggedValue(*objFun));
prev = TestHelper::SetupFrame(thread, tgObjCallInfo);
JSTaggedValue resultTg = BuiltinsObject::ObjectConstructor(tgObjCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(resultTg.IsObject());
JSHandle<JSObject> jtHandleTg(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(resultTg.GetRawData())));
JSTaggedValue resultProtoTg = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(jtHandleTg));
JSTaggedValue funcProtoTg = objectFunc->GetFunctionPrototype(thread);
ASSERT_EQ(resultProtoTg, funcProtoTg);
ASSERT_TRUE(jtHandleTg->IsExtensible());
JSHandle<JSObject> objectVn =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(function), function);
objectVn->GetJSHClass()->SetCallable(true);
auto vnObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*objectVn), 6);
vnObjCallInfo->SetFunction(JSTaggedValue(*objFun));
vnObjCallInfo->SetThis(JSTaggedValue::Undefined());
vnObjCallInfo->SetCallArg(0, JSTaggedValue::Null());
vnObjCallInfo->SetNewTarget(JSTaggedValue(*objFun));
prev = TestHelper::SetupFrame(thread, vnObjCallInfo);
JSTaggedValue resultVn = BuiltinsObject::ObjectConstructor(vnObjCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(resultVn.IsObject());
JSHandle<JSObject> jtHandleVn(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(resultVn.GetRawData())));
JSTaggedValue resultProtoVn = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(jtHandleVn));
JSTaggedValue funcProtoVn = objectFunc->GetFunctionPrototype(thread);
ASSERT_EQ(resultProtoVn, funcProtoVn);
ASSERT_TRUE(jtHandleVn->IsExtensible());
}
HWTEST_F_L0(BuiltinsObjectTest, Assign)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<JSObject> objHandle1 =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
JSHandle<JSObject> objHandle2 =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
JSHandle<JSTaggedValue> key1(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(objHandle1), key1, value1);
EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(objHandle1), key1).GetValue()->GetInt(), 1);
JSHandle<JSTaggedValue> key2(thread->GetEcmaVM()->GetFactory()->NewFromASCII("y"));
JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(objHandle2), key2, value2);
EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(objHandle2), key2).GetValue()->GetInt(), 2);
auto assignObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
assignObjCallInfo->SetFunction(JSTaggedValue::Undefined());
assignObjCallInfo->SetThis(JSTaggedValue::Undefined());
assignObjCallInfo->SetCallArg(0, objHandle1.GetTaggedValue());
assignObjCallInfo->SetCallArg(1, objHandle2.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, assignObjCallInfo);
JSTaggedValue result = BuiltinsObject::Assign(assignObjCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsECMAObject());
JSHandle<JSTaggedValue> jtHandle(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(result.GetRawData())));
EXPECT_EQ(JSObject::GetProperty(thread, jtHandle, key1).GetValue()->GetInt(), 1);
EXPECT_EQ(JSObject::GetProperty(thread, jtHandle, key2).GetValue()->GetInt(), 2);
}
HWTEST_F_L0(BuiltinsObjectTest, Create)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<JSFunction> objectFunc(thread, BuiltinsObjectTestCreate(thread));
JSHandle<JSTaggedValue> funcProto(thread, objectFunc->GetFunctionPrototype(thread));
auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
objCallInfo->SetFunction(JSTaggedValue::Undefined());
objCallInfo->SetThis(JSTaggedValue::Undefined());
objCallInfo->SetCallArg(0, funcProto.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
JSTaggedValue result = BuiltinsObject::Create(objCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsECMAObject());
JSHandle<JSTaggedValue> jtHandle(thread, result);
JSTaggedValue resultProto = JSTaggedValue::GetPrototype(thread, jtHandle);
ASSERT_EQ(resultProto, funcProto.GetTaggedValue());
JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("prop"));
JSHandle<JSObject> objHandle =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(function), function);
EXPECT_TRUE(*objHandle != nullptr);
PropertyDescriptor desc(thread);
desc.SetWritable(false);
JSHandle<JSObject> descHandle(JSObject::FromPropertyDescriptor(thread, desc));
PropertyDescriptor descNw(thread, JSHandle<JSTaggedValue>::Cast(descHandle), true, true, true);
JSObject::DefineOwnProperty(thread, objHandle, key, descNw);
auto hpObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
hpObjCallInfo->SetFunction(JSTaggedValue::Undefined());
hpObjCallInfo->SetThis(JSTaggedValue::Undefined());
hpObjCallInfo->SetCallArg(0, funcProto.GetTaggedValue());
hpObjCallInfo->SetCallArg(1, objHandle.GetTaggedValue());
prev = TestHelper::SetupFrame(thread, hpObjCallInfo);
JSTaggedValue resultHp = BuiltinsObject::Create(hpObjCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(resultHp.IsObject());
PropertyDescriptor descRes(thread);
bool success = JSObject::GetOwnProperty(thread, JSHandle<JSObject>(thread, resultHp), key, descRes);
EXPECT_TRUE(success);
EXPECT_TRUE(!descRes.IsWritable());
auto unCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
unCallInfo->SetFunction(JSTaggedValue::Undefined());
unCallInfo->SetThis(JSTaggedValue::Undefined());
unCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
prev = TestHelper::SetupFrame(thread, unCallInfo);
JSTaggedValue resultUn = BuiltinsObject::Create(unCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(resultUn.GetRawData(), JSTaggedValue::VALUE_EXCEPTION);
}
HWTEST_F_L0(BuiltinsObjectTest, DefineProperties)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
JSHandle<JSFunction> objFunc(env->GetObjectFunction());
JSHandle<JSObject> objHandle =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("prop"));
JSHandle<JSObject> jsobjHandle =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
PropertyDescriptor desc(thread);
desc.SetWritable(false);
JSHandle<JSObject> descHandle(JSObject::FromPropertyDescriptor(thread, desc));
PropertyDescriptor descNw(thread, JSHandle<JSTaggedValue>::Cast(descHandle), true, true, true);
JSObject::DefineOwnProperty(thread, jsobjHandle, key, descNw);
auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
objCallInfo->SetFunction(JSTaggedValue::Undefined());
objCallInfo->SetThis(JSTaggedValue::Undefined());
objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
objCallInfo->SetCallArg(1, jsobjHandle.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
JSTaggedValue result = BuiltinsObject::DefineProperties(objCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsECMAObject());
JSTaggedValue res(reinterpret_cast<TaggedObject *>(result.GetRawData()));
PropertyDescriptor descRes(thread);
JSObject::GetOwnProperty(thread, JSHandle<JSObject>(thread, res), key, descRes);
EXPECT_TRUE(!descRes.IsWritable());
}
HWTEST_F_L0(BuiltinsObjectTest, DefineProperty)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
JSHandle<JSFunction> objFunc(env->GetObjectFunction());
JSHandle<JSObject> attHandle =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
JSHandle<JSObject> objHandle =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
PropertyDescriptor desc(thread);
desc.SetWritable(true);
JSHandle<JSTaggedValue> writableStr = thread->GlobalConstants()->GetHandledWritableString();
JSHandle<JSTaggedValue> writable(thread, JSTaggedValue(desc.IsWritable()));
JSObject::CreateDataProperty(thread, attHandle, writableStr, writable);
JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
PropertyDescriptor descNw(thread);
JSObject::GetOwnProperty(thread, objHandle, key, descNw);
EXPECT_TRUE(!descNw.HasWritable());
auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
objCallInfo->SetFunction(JSTaggedValue::Undefined());
objCallInfo->SetThis(JSTaggedValue::Undefined());
objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
objCallInfo->SetCallArg(1, key.GetTaggedValue());
objCallInfo->SetCallArg(2, attHandle.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
JSTaggedValue result = BuiltinsObject::DefineProperty(objCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsECMAObject());
JSTaggedValue res(reinterpret_cast<TaggedObject *>(result.GetRawData()));
PropertyDescriptor descRes(thread);
JSObject::GetOwnProperty(thread, JSHandle<JSObject>(thread, res), key, descRes);
EXPECT_TRUE(descRes.HasWritable());
}
HWTEST_F_L0(BuiltinsObjectTest, Freeze)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<JSObject> emptyObj =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
emptyObj->GetJSHClass()->SetExtensible(true);
auto nofreezeObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
nofreezeObjCallInfo->SetFunction(JSTaggedValue::Undefined());
nofreezeObjCallInfo->SetThis(JSTaggedValue::Undefined());
nofreezeObjCallInfo->SetCallArg(0, emptyObj.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, nofreezeObjCallInfo);
JSTaggedValue result = BuiltinsObject::IsFrozen(nofreezeObjCallInfo);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
BuiltinsObject::Freeze(nofreezeObjCallInfo);
JSTaggedValue resultIs = BuiltinsObject::IsFrozen(nofreezeObjCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(resultIs.GetRawData(), JSTaggedValue::True().GetRawData());
}
HWTEST_F_L0(BuiltinsObjectTest, GetOwnPropertyDescriptor)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<JSObject> objHandle =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
PropertyDescriptor descEnum(thread);
descEnum.SetWritable(true);
JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(objHandle), key, descEnum);
auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
objCallInfo->SetFunction(JSTaggedValue::Undefined());
objCallInfo->SetThis(JSTaggedValue::Undefined());
objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
objCallInfo->SetCallArg(1, key.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
JSTaggedValue result = BuiltinsObject::GetOwnPropertyDescriptor(objCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsECMAObject());
JSHandle<JSTaggedValue> writableStr = thread->GlobalConstants()->GetHandledWritableString();
JSTaggedValue jt(reinterpret_cast<TaggedObject *>(result.GetRawData()));
PropertyDescriptor desc(thread);
JSObject::GetOwnProperty(thread, JSHandle<JSObject>(thread, jt), writableStr, desc);
ASSERT_TRUE(JSTaggedValue::SameValue(thread, desc.GetValue().GetTaggedValue(), JSTaggedValue(true)));
}
HWTEST_F_L0(BuiltinsObjectTest, GetOwnPropertyNames)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<JSObject> objHandle =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(objHandle), key, value);
auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
objCallInfo->SetFunction(JSTaggedValue::Undefined());
objCallInfo->SetThis(JSTaggedValue::Undefined());
objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
JSTaggedValue result = BuiltinsObject::GetOwnPropertyNames(objCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsECMAObject());
}
HWTEST_F_L0(BuiltinsObjectTest, GetOwnPropertySymbols)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<JSObject> objHandle =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
JSHandle<JSSymbol> symbolKey = thread->GetEcmaVM()->GetFactory()->NewJSSymbol();
JSHandle<JSTaggedValue> key(symbolKey);
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(objHandle), key, value);
thread->ClearException();
auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
objCallInfo->SetFunction(JSTaggedValue::Undefined());
objCallInfo->SetThis(JSTaggedValue::Undefined());
objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
JSTaggedValue result = BuiltinsObject::GetOwnPropertySymbols(objCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsECMAObject());
}
HWTEST_F_L0(BuiltinsObjectTest, Is)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<JSObject> obj1 =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
JSHandle<JSObject> obj2 =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
auto objCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
objCallInfo1->SetFunction(JSTaggedValue::Undefined());
objCallInfo1->SetThis(JSTaggedValue::Undefined());
objCallInfo1->SetCallArg(0, obj1.GetTaggedValue());
objCallInfo1->SetCallArg(1, obj2.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo1);
JSTaggedValue objResult1 = BuiltinsObject::Is(objCallInfo1);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(objResult1.GetRawData(), JSTaggedValue::False().GetRawData());
objCallInfo1->SetCallArg(1, obj1.GetTaggedValue());
JSTaggedValue objResult2 = BuiltinsObject::Is(objCallInfo1);
ASSERT_EQ(objResult2.GetRawData(), JSTaggedValue::True().GetRawData());
JSHandle<EcmaString> testStrValue1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("helloworld");
JSHandle<EcmaString> testStrValue2 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("helloworld");
auto strCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
strCallInfo->SetFunction(JSTaggedValue::Undefined());
strCallInfo->SetThis(JSTaggedValue::Undefined());
strCallInfo->SetCallArg(0, testStrValue1.GetTaggedValue());
strCallInfo->SetCallArg(1, testStrValue2.GetTaggedValue());
prev = TestHelper::SetupFrame(thread, strCallInfo);
JSTaggedValue strResult = BuiltinsObject::Is(strCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(strResult.GetRawData(), JSTaggedValue::True().GetRawData());
auto boolCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
boolCallInfo->SetFunction(JSTaggedValue::Undefined());
boolCallInfo->SetThis(JSTaggedValue::Undefined());
boolCallInfo->SetCallArg(0, JSTaggedValue::True());
boolCallInfo->SetCallArg(1, JSTaggedValue::False());
prev = TestHelper::SetupFrame(thread, boolCallInfo);
JSTaggedValue boolResult = BuiltinsObject::Is(boolCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(boolResult.GetRawData(), JSTaggedValue::False().GetRawData());
auto numCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
numCallInfo->SetFunction(JSTaggedValue::Undefined());
numCallInfo->SetThis(JSTaggedValue::Undefined());
numCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(0)));
numCallInfo->SetCallArg(1, JSTaggedValue(-0.0));
prev = TestHelper::SetupFrame(thread, numCallInfo);
JSTaggedValue numResult = BuiltinsObject::Is(numCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(numResult.GetRawData(), JSTaggedValue::False().GetRawData());
auto nullCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
nullCallInfo->SetFunction(JSTaggedValue::Undefined());
nullCallInfo->SetThis(JSTaggedValue::Undefined());
nullCallInfo->SetCallArg(0, JSTaggedValue::Null());
nullCallInfo->SetCallArg(1, JSTaggedValue::Null());
prev = TestHelper::SetupFrame(thread, nullCallInfo);
JSTaggedValue nullResult = BuiltinsObject::Is(nullCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(nullResult.GetRawData(), JSTaggedValue::True().GetRawData());
auto undefineCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
undefineCallInfo->SetFunction(JSTaggedValue::Undefined());
undefineCallInfo->SetThis(JSTaggedValue::Undefined());
undefineCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
undefineCallInfo->SetCallArg(1, JSTaggedValue::Undefined());
prev = TestHelper::SetupFrame(thread, undefineCallInfo);
JSTaggedValue undefineResult = BuiltinsObject::Is(undefineCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(undefineResult.GetRawData(), JSTaggedValue::True().GetRawData());
}
HWTEST_F_L0(BuiltinsObjectTest, IsExtensible)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<JSObject> emptyObj =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
emptyObj->GetJSHClass()->SetExtensible(true);
std::vector<JSTaggedValue> args{emptyObj.GetTaggedValue()};
auto emptyObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6);
auto prev = TestHelper::SetupFrame(thread, emptyObjCallInfo);
JSTaggedValue result = BuiltinsObject::IsExtensible(emptyObjCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
emptyObj->GetJSHClass()->SetExtensible(false);
JSTaggedValue result2 = BuiltinsObject::IsExtensible(emptyObjCallInfo);
ASSERT_EQ(result2.GetRawData(), JSTaggedValue::False().GetRawData());
}
HWTEST_F_L0(BuiltinsObjectTest, IsFrozen)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
JSHandle<JSObject> obj =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(function), function);
obj->GetJSHClass()->SetExtensible(true);
auto emptyObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
emptyObjCallInfo->SetFunction(JSTaggedValue::Undefined());
emptyObjCallInfo->SetThis(JSTaggedValue::Undefined());
emptyObjCallInfo->SetCallArg(0, obj.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, emptyObjCallInfo);
JSTaggedValue result = BuiltinsObject::IsFrozen(emptyObjCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
obj->GetJSHClass()->SetExtensible(false);
prev = TestHelper::SetupFrame(thread, emptyObjCallInfo);
JSTaggedValue resultNex = BuiltinsObject::IsFrozen(emptyObjCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(resultNex.GetRawData(), JSTaggedValue::True().GetRawData());
PropertyDescriptor descEnum(thread);
descEnum.SetConfigurable(true);
descEnum.SetWritable(false);
obj->GetJSHClass()->SetExtensible(true);
JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(obj), key, descEnum);
obj->GetJSHClass()->SetExtensible(false);
auto emptyObjCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
emptyObjCallInfo2->SetFunction(JSTaggedValue::Undefined());
emptyObjCallInfo2->SetThis(JSTaggedValue::Undefined());
emptyObjCallInfo2->SetCallArg(0, obj.GetTaggedValue());
prev = TestHelper::SetupFrame(thread, emptyObjCallInfo2);
JSTaggedValue resultNw = BuiltinsObject::IsFrozen(emptyObjCallInfo2);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(resultNw.GetRawData(), JSTaggedValue::False().GetRawData());
descEnum.SetConfigurable(false);
obj->GetJSHClass()->SetExtensible(true);
JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(obj), key, descEnum);
obj->GetJSHClass()->SetExtensible(false);
auto emptyObjCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
emptyObjCallInfo3->SetFunction(JSTaggedValue::Undefined());
emptyObjCallInfo3->SetThis(JSTaggedValue::Undefined());
emptyObjCallInfo3->SetCallArg(0, obj.GetTaggedValue());
prev = TestHelper::SetupFrame(thread, emptyObjCallInfo3);
JSTaggedValue resultNc = BuiltinsObject::IsFrozen(emptyObjCallInfo3);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(resultNc.GetRawData(), JSTaggedValue::True().GetRawData());
}
HWTEST_F_L0(BuiltinsObjectTest, IsSealed)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<JSObject> emptyObj =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
emptyObj->GetJSHClass()->SetExtensible(true);
std::vector<JSTaggedValue> args{emptyObj.GetTaggedValue()};
auto emptyObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6);
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, emptyObjCallInfo);
JSTaggedValue result = BuiltinsObject::IsSealed(emptyObjCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
}
HWTEST_F_L0(BuiltinsObjectTest, Keys)
{
JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsObject::Keys(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsECMAObject());
}
HWTEST_F_L0(BuiltinsObjectTest, Values)
{
JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsObject::Values(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsECMAObject());
}
HWTEST_F_L0(BuiltinsObjectTest, PreventExtensions)
{
JSHandle<JSObject> obj(thread, CreateBuiltinJSObject(thread, "x"));
obj->GetJSHClass()->SetExtensible(true);
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsObject::PreventExtensions(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsECMAObject());
JSTaggedValue jt(reinterpret_cast<TaggedObject *>(result.GetRawData()));
JSHandle<JSObject> jtHandle(thread, jt);
ASSERT_TRUE(!jtHandle->IsExtensible());
}
HWTEST_F_L0(BuiltinsObjectTest, Seal)
{
JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsObject::Seal(ecmaRuntimeCallInfo);
ASSERT_TRUE(result.IsECMAObject());
ASSERT_EQ(result.GetRawData(), obj->GetRawData());
JSTaggedValue res = BuiltinsObject::IsSealed(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(res.GetRawData(), JSTaggedValue::True().GetRawData());
}
HWTEST_F_L0(BuiltinsObjectTest, SetPrototypeOf)
{
JSHandle<JSObject> obj(thread, CreateBuiltinJSObject(thread, "x"));
JSHandle<JSObject> objFather(thread, CreateBuiltinJSObject(thread, "y"));
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(1, objFather.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsObject::SetPrototypeOf(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsECMAObject());
ASSERT_EQ(result.GetRawData(), obj.GetTaggedValue().GetRawData());
JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("y"));
EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue()->GetInt(), 1);
}
HWTEST_F_L0(BuiltinsObjectTest, HasOwnProperty)
{
JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
CString keyCStr = "x";
JSHandle<EcmaString> keyString = thread->GetEcmaVM()->GetFactory()->NewFromASCII(&keyCStr[0]);
JSHandle<JSTaggedValue> key(keyString);
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsObject::HasOwnProperty(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
}
HWTEST_F_L0(BuiltinsObjectTest, IsPrototypeOfFalse)
{
JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
JSHandle<JSTaggedValue> objFather(thread, CreateBuiltinJSObject(thread, "y"));
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(objFather.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result1 = BuiltinsObject::IsPrototypeOf(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(result1.GetRawData(), JSTaggedValue::False().GetRawData());
}
HWTEST_F_L0(BuiltinsObjectTest, IsPrototypeOfTrue)
{
JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
JSHandle<JSTaggedValue> objFather(thread, CreateBuiltinJSObject(thread, "y"));
auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo1->SetCallArg(0, obj.GetTaggedValue());
ecmaRuntimeCallInfo1->SetCallArg(1, objFather.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
JSTaggedValue result1 = BuiltinsObject::SetPrototypeOf(ecmaRuntimeCallInfo1);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result1.IsObject());
ASSERT_EQ(result1.GetRawData(), obj->GetRawData());
auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo2->SetThis(objFather.GetTaggedValue());
ecmaRuntimeCallInfo2->SetCallArg(0, obj.GetTaggedValue());
prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
JSTaggedValue result2 = BuiltinsObject::IsPrototypeOf(ecmaRuntimeCallInfo2);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(result2.GetRawData(), JSTaggedValue::True().GetRawData());
}
HWTEST_F_L0(BuiltinsObjectTest, PropertyIsEnumerable)
{
JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsObject::PropertyIsEnumerable(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
}
HWTEST_F_L0(BuiltinsObjectTest, ToLocaleString)
{
JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
JSHandle<JSFunction> calleeFunc = thread->GetEcmaVM()->GetFactory()->NewJSFunction(
thread->GetEcmaVM()->GetGlobalEnv(), reinterpret_cast<void *>(BuiltinsObject::ToString));
calleeFunc->GetClass()->SetCallable(true);
JSHandle<JSTaggedValue> calleeValue(calleeFunc);
JSHandle<JSTaggedValue> calleeKey(thread->GetEcmaVM()->GetFactory()->NewFromASCII("toString"));
JSObject::SetProperty(thread, obj, calleeKey, calleeValue);
JSHandle<EcmaString> resultValue = thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Object]");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsObject::ToLocaleString(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsString());
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultValue, JSHandle<EcmaString>(thread, result)), 0);
}
HWTEST_F_L0(BuiltinsObjectTest, ToString)
{
JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(thread, CreateBuiltinJSObject(thread, "x"));
JSHandle<EcmaString> resultValue = thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Object]");
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsObject::ToString(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsString());
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultValue, JSHandle<EcmaString>(thread, result)), 0);
JSHandle<JSArray> arr = thread->GetEcmaVM()->GetFactory()->NewJSArray();
JSHandle<EcmaString> resultArrValue =
thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Array]");
auto arrEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
arrEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
arrEcmaRuntimeCallInfo->SetThis(arr.GetTaggedValue());
prev = TestHelper::SetupFrame(thread, arrEcmaRuntimeCallInfo);
JSTaggedValue resultArr = BuiltinsObject::ToString(arrEcmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(resultArr.IsString());
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultArrValue, JSHandle<EcmaString>(thread, resultArr)), 0);
JSHandle<EcmaString> str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("hello");
JSHandle<EcmaString> resultStrValue =
thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object String]");
auto strEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
strEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
strEcmaRuntimeCallInfo->SetThis(str.GetTaggedValue());
prev = TestHelper::SetupFrame(thread, strEcmaRuntimeCallInfo);
JSTaggedValue resultStr = BuiltinsObject::ToString(strEcmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(resultStr.IsString());
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultStrValue, JSHandle<EcmaString>(thread, resultStr)), 0);
JSHandle<JSFunction> func = thread->GetEcmaVM()->GetFactory()->NewJSFunction(thread->GetEcmaVM()->GetGlobalEnv());
JSHandle<EcmaString> resultFuncValue =
thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Function]");
auto funcEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
funcEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
funcEcmaRuntimeCallInfo->SetThis(func.GetTaggedValue());
prev = TestHelper::SetupFrame(thread, funcEcmaRuntimeCallInfo);
JSTaggedValue resultFunc = BuiltinsObject::ToString(funcEcmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(resultFunc.IsString());
ASSERT_EQ(EcmaStringAccessor::Compare(instance,
resultFuncValue, JSHandle<EcmaString>(thread, resultFunc)), 0);
auto ecmaVM = thread->GetEcmaVM();
JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
JSHandle<JSTaggedValue> errorObject = env->GetErrorFunction();
JSHandle<JSObject> error =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(errorObject), errorObject);
JSHandle<EcmaString> errorValue = thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Error]");
auto errorEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
errorEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
errorEcmaRuntimeCallInfo->SetThis(error.GetTaggedValue());
prev = TestHelper::SetupFrame(thread, errorEcmaRuntimeCallInfo);
JSTaggedValue resultError = BuiltinsObject::ToString(errorEcmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(resultError.IsString());
ASSERT_EQ(EcmaStringAccessor::Compare(instance, errorValue, JSHandle<EcmaString>(thread, resultError)), 0);
JSHandle<JSTaggedValue> value(thread, JSTaggedValue::False());
JSHandle<JSFunction> booleanObject(env->GetBooleanFunction());
JSHandle<JSPrimitiveRef> boolean = thread->GetEcmaVM()->GetFactory()->NewJSPrimitiveRef(booleanObject, value);
JSHandle<EcmaString> resultBoolValue =
thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Boolean]");
auto boolEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
boolEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
boolEcmaRuntimeCallInfo->SetThis(boolean.GetTaggedValue());
prev = TestHelper::SetupFrame(thread, boolEcmaRuntimeCallInfo);
JSTaggedValue resultBool = BuiltinsObject::ToString(boolEcmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(resultBool.IsString());
ASSERT_EQ(EcmaStringAccessor::Compare(instance,
resultBoolValue, JSHandle<EcmaString>(thread, resultBool)), 0);
JSHandle<EcmaString> resultNumValue =
thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Number]");
auto numEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
numEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
numEcmaRuntimeCallInfo->SetThis(JSTaggedValue(static_cast<double>(0)));
prev = TestHelper::SetupFrame(thread, numEcmaRuntimeCallInfo);
JSTaggedValue resultNum = BuiltinsObject::ToString(numEcmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(resultNum.IsString());
ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultNumValue, JSHandle<EcmaString>(thread, resultNum)), 0);
}
HWTEST_F_L0(BuiltinsObjectTest, ValueOf)
{
JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsObject::ValueOf(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_TRUE(result.IsECMAObject());
}
HWTEST_F_L0(BuiltinsObjectTest, HasOwn)
{
JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
JSHandle<JSObject> object =
thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(object), key, value);
EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(object), key).GetValue()->GetInt(), 1);
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
ecmaRuntimeCallInfo->SetCallArg(0, object.GetTaggedValue());
ecmaRuntimeCallInfo->SetCallArg(1, key.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
JSTaggedValue result = BuiltinsObject::HasOwn(ecmaRuntimeCallInfo);
TestHelper::TearDownFrame(thread, prev);
ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
}
}