diff --git a/ecmascript/tests/BUILD.gn b/ecmascript/tests/BUILD.gn index 99ea6cc25a54105bbc9d1aa4f344146431912b92..653a46d87acb86f6beaa0b5da6b19117b015d4ae 100644 --- a/ecmascript/tests/BUILD.gn +++ b/ecmascript/tests/BUILD.gn @@ -583,6 +583,33 @@ host_unittest_action("HugeObjectTest") { } } +host_unittest_action("JsArgumentsTest") { + module_out_path = module_output_path + + sources = [ + # test file + "js_arguments_test.cpp", + ] + + configs = [ + "//ark/js_runtime:ecma_test_config", + "//ark/js_runtime:ark_jsruntime_public_config", # should add before + # arkruntime_public_config + "//ark/js_runtime:ark_jsruntime_config", + "$ark_root/runtime:arkruntime_public_config", + ] + + deps = [ + "$ark_root/libpandabase:libarkbase", + "//ark/js_runtime:libark_jsruntime_test", + sdk_libc_secshared_dep, + ] + + if (!is_standard_system) { + deps += [ "$ark_root/runtime:libarkruntime" ] + } +} + host_unittest_action("LexicalEnvTest") { module_out_path = module_output_path @@ -866,6 +893,7 @@ group("unittest") { ":GcTest", ":GlueRegsTest", ":HugeObjectTest", + ":JsArgumentsTest", ":JsArrayTest", ":JsDateTest", ":JsForinIteratorTest", @@ -905,6 +933,7 @@ group("host_unittest") { ":GcTestAction", ":GlueRegsTestAction", ":HugeObjectTestAction", + ":JsArgumentsTestAction", ":JsArrayTestAction", ":JsDateTestAction", ":JsForinIteratorTestAction", diff --git a/ecmascript/tests/js_arguments_test.cpp b/ecmascript/tests/js_arguments_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5e5f06d8e6f47e4a74d13596d175810cb17b89e4 --- /dev/null +++ b/ecmascript/tests/js_arguments_test.cpp @@ -0,0 +1,165 @@ +/* + * 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 testing::Test { +public: + static void SetUpTestCase() + { + GTEST_LOG_(INFO) << "SetUpTestCase"; + } + + static void TearDownTestCase() + { + GTEST_LOG_(INFO) << "TearDownCase"; + } + + void SetUp() override + { + TestHelper::CreateEcmaVMWithScope(instance, thread, scope); + } + + void TearDown() override + { + TestHelper::DestroyEcmaVMWithScope(instance, scope); + } + ecmascript::EcmaHandleScope *scope {nullptr}; + PandaVM *instance {nullptr}; + JSThread *thread {nullptr}; +}; + +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()->NewFromCanBeCompressString(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()->NewFromCanBeCompressString(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()->NewFromCanBeCompressString(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()->NewFromCanBeCompressString("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()->NewFromCanBeCompressString("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()->NewFromCanBeCompressString("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