/* * 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/js_arguments.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" #include "ecmascript/js_handle.h" #include "ecmascript/object_factory.h" #include "ecmascript/tests/test_helper.h" using namespace panda::ecmascript; namespace panda::test { class JsArgumentsTest : public BaseTestWithScope { }; static JSFunction *JSObjectTestCreate(JSThread *thread) { EcmaVM *ecmaVM = thread->GetEcmaVM(); JSHandle globalEnv = ecmaVM->GetGlobalEnv(); return globalEnv->GetObjectFunction().GetObject(); } HWTEST_F_L0(JsArgumentsTest, SetProperty) { JSHandle argFunc(thread, JSObjectTestCreate(thread)); JSHandle jsarg = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(argFunc), argFunc); JSHandle arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments(); char array[] = "x"; JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromASCII(array)); JSHandle value(thread, JSTaggedValue(1)); // receive must be jsarg's conversion JSHandle receiver = JSHandle::Cast(jsarg); EXPECT_TRUE(JSArguments::SetProperty(thread, arg, key, value, receiver)); EXPECT_EQ(JSObject::GetProperty(thread, JSHandle(jsarg), key).GetValue()->GetInt(), 1); EXPECT_EQ(JSArguments::GetProperty(thread, jsarg, key).GetValue()->GetInt(), 1); JSHandle value2(thread, JSTaggedValue(2)); EXPECT_TRUE(JSArguments::SetProperty(thread, arg, key, value2, receiver)); EXPECT_EQ(JSObject::GetProperty(thread, JSHandle(jsarg), key).GetValue()->GetInt(), 2); EXPECT_EQ(JSArguments::GetProperty(thread, jsarg, key).GetValue()->GetInt(), 2); } HWTEST_F_L0(JsArgumentsTest, GetProperty) { JSHandle argFunc(thread, JSObjectTestCreate(thread)); JSHandle jsarg = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(argFunc), argFunc); JSHandle arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments(); char array[] = "x"; JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromASCII(array)); JSHandle value(thread, JSTaggedValue(1)); JSHandle receiver = JSHandle::Cast(jsarg); JSArguments::SetProperty(thread, arg, key, value, receiver); EXPECT_EQ(JSObject::GetProperty(thread, JSHandle(jsarg), key).GetValue()->GetInt(), 1); EXPECT_EQ(JSArguments::GetProperty(thread, JSHandle(jsarg), key, receiver).GetValue()->GetInt(), 1); JSHandle value2(thread, JSTaggedValue(2)); JSArguments::SetProperty(thread, arg, key, value2, receiver); EXPECT_EQ(JSArguments::GetProperty(thread, jsarg, key).GetValue()->GetInt(), 2); EXPECT_EQ(JSObject::GetProperty(thread, JSHandle(jsarg), key).GetValue()->GetInt(), 2); } HWTEST_F_L0(JsArgumentsTest, DeleteProperty) { JSHandle argFunc(thread, JSObjectTestCreate(thread)); JSHandle jsarg = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(argFunc), argFunc); JSHandle arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments(); char array[] = "delete"; JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromASCII(array)); JSHandle value(thread, JSTaggedValue(1)); JSHandle receiver = JSHandle::Cast(jsarg); JSArguments::SetProperty(thread, arg, key, value, receiver); EXPECT_EQ(JSArguments::GetProperty(thread, jsarg, key).GetValue()->GetInt(), 1); // test delete bool result = JSArguments::DeleteProperty(thread, JSHandle(jsarg), key); EXPECT_TRUE(result); EXPECT_TRUE(JSObject::GetProperty(thread, JSHandle(jsarg), key).GetValue()->IsUndefined()); } HWTEST_F_L0(JsArgumentsTest, DefineOwnProperty) { JSHandle argFunc(thread, JSObjectTestCreate(thread)); JSHandle jsarg = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(argFunc), argFunc); JSHandle arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments(); JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x")); JSHandle value1(thread, JSTaggedValue(1)); JSHandle value2(thread, JSTaggedValue(2)); JSHandle receiver = JSHandle::Cast(jsarg); JSArguments::SetProperty(thread, arg, key, value2, receiver); EXPECT_EQ(JSObject::GetProperty(thread, JSHandle(jsarg), key).GetValue()->GetInt(), 2); PropertyDescriptor Desc(thread); // set value1 Desc.SetValue(value1); Desc.SetWritable(false); EXPECT_TRUE(JSArguments::DefineOwnProperty(thread, JSHandle(jsarg), key, Desc)); EXPECT_EQ(JSObject::GetProperty(thread, JSHandle(jsarg), key).GetValue()->GetInt(), 1); } HWTEST_F_L0(JsArgumentsTest, GetOwnProperty) { JSHandle argFunc(thread, JSObjectTestCreate(thread)); JSHandle jsarg = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(argFunc), argFunc); JSHandle arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments(); JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x")); JSHandle value(thread, JSTaggedValue(1)); JSHandle receiver = JSHandle::Cast(jsarg); JSArguments::SetProperty(thread, arg, key, value, receiver); PropertyDescriptor Desc(thread); JSHandle caller = thread->GetEcmaVM()->GetFactory()->NewFromASCII("caller"); // key is not caller EXPECT_FALSE(JSTaggedValue::SameValue(key.GetTaggedValue(), caller.GetTaggedValue())); EXPECT_TRUE(JSArguments::GetOwnProperty(thread, JSHandle(jsarg), key, Desc)); EXPECT_EQ(Desc.GetValue()->GetInt(), 1); } } // namespace panda::test