1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ecmascript/js_arguments.h"
17 #include "ecmascript/ecma_vm.h"
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/js_handle.h"
20 #include "ecmascript/object_factory.h"
21 #include "ecmascript/tests/test_helper.h"
22
23 using namespace panda::ecmascript;
24
25 namespace panda::test {
26 class JsArgumentsTest : public testing::Test {
27 public:
SetUpTestCase()28 static void SetUpTestCase()
29 {
30 GTEST_LOG_(INFO) << "SetUpTestCase";
31 }
32
TearDownTestCase()33 static void TearDownTestCase()
34 {
35 GTEST_LOG_(INFO) << "TearDownCase";
36 }
37
SetUp()38 void SetUp() override
39 {
40 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
41 }
42
TearDown()43 void TearDown() override
44 {
45 TestHelper::DestroyEcmaVMWithScope(instance, scope);
46 }
47 ecmascript::EcmaHandleScope *scope {nullptr};
48 PandaVM *instance {nullptr};
49 JSThread *thread {nullptr};
50 };
51
JSObjectTestCreate(JSThread * thread)52 static JSFunction *JSObjectTestCreate(JSThread *thread)
53 {
54 EcmaVM *ecmaVM = thread->GetEcmaVM();
55 JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
56 return globalEnv->GetObjectFunction().GetObject<JSFunction>();
57 }
58
HWTEST_F_L0(JsArgumentsTest,SetProperty)59 HWTEST_F_L0(JsArgumentsTest, SetProperty)
60 {
61 JSHandle<JSTaggedValue> argFunc(thread, JSObjectTestCreate(thread));
62 JSHandle<JSObject> jsarg =
63 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(argFunc), argFunc);
64 JSHandle<JSArguments> arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments();
65
66 char array[] = "x";
67 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(array));
68 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
69
70 // receive must be jsarg's conversion
71 JSHandle<JSTaggedValue> receiver = JSHandle<JSTaggedValue>::Cast(jsarg);
72 EXPECT_TRUE(JSArguments::SetProperty(thread, arg, key, value, receiver));
73 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->GetInt(), 1);
74 EXPECT_EQ(JSArguments::GetProperty(thread, jsarg, key).GetValue()->GetInt(), 1);
75
76 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
77 EXPECT_TRUE(JSArguments::SetProperty(thread, arg, key, value2, receiver));
78 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->GetInt(), 2);
79 EXPECT_EQ(JSArguments::GetProperty(thread, jsarg, key).GetValue()->GetInt(), 2);
80 }
81
HWTEST_F_L0(JsArgumentsTest,GetProperty)82 HWTEST_F_L0(JsArgumentsTest, GetProperty)
83 {
84 JSHandle<JSTaggedValue> argFunc(thread, JSObjectTestCreate(thread));
85 JSHandle<JSObject> jsarg =
86 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(argFunc), argFunc);
87 JSHandle<JSArguments> arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments();
88
89 char array[] = "x";
90 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(array));
91 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
92
93 JSHandle<JSTaggedValue> receiver = JSHandle<JSTaggedValue>::Cast(jsarg);
94 JSArguments::SetProperty(thread, arg, key, value, receiver);
95 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->GetInt(), 1);
96 EXPECT_EQ(JSArguments::GetProperty(thread, JSHandle<JSArguments>(jsarg), key, receiver).GetValue()->GetInt(), 1);
97
98 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
99 JSArguments::SetProperty(thread, arg, key, value2, receiver);
100 EXPECT_EQ(JSArguments::GetProperty(thread, jsarg, key).GetValue()->GetInt(), 2);
101 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->GetInt(), 2);
102 }
103
HWTEST_F_L0(JsArgumentsTest,DeleteProperty)104 HWTEST_F_L0(JsArgumentsTest, DeleteProperty)
105 {
106 JSHandle<JSTaggedValue> argFunc(thread, JSObjectTestCreate(thread));
107 JSHandle<JSObject> jsarg =
108 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(argFunc), argFunc);
109 JSHandle<JSArguments> arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments();
110
111 char array[] = "delete";
112 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(array));
113 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
114 JSHandle<JSTaggedValue> receiver = JSHandle<JSTaggedValue>::Cast(jsarg);
115 JSArguments::SetProperty(thread, arg, key, value, receiver);
116 EXPECT_EQ(JSArguments::GetProperty(thread, jsarg, key).GetValue()->GetInt(), 1);
117
118 // test delete
119 bool result = JSArguments::DeleteProperty(thread, JSHandle<JSArguments>(jsarg), key);
120 EXPECT_TRUE(result);
121 EXPECT_TRUE(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->IsUndefined());
122 }
123
HWTEST_F_L0(JsArgumentsTest,DefineOwnProperty)124 HWTEST_F_L0(JsArgumentsTest, DefineOwnProperty)
125 {
126 JSHandle<JSTaggedValue> argFunc(thread, JSObjectTestCreate(thread));
127 JSHandle<JSObject> jsarg =
128 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(argFunc), argFunc);
129 JSHandle<JSArguments> arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments();
130
131 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("x"));
132 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
133 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
134 JSHandle<JSTaggedValue> receiver = JSHandle<JSTaggedValue>::Cast(jsarg);
135 JSArguments::SetProperty(thread, arg, key, value2, receiver);
136 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->GetInt(), 2);
137
138 PropertyDescriptor Desc(thread);
139 // set value1
140 Desc.SetValue(value1);
141 Desc.SetWritable(false);
142 EXPECT_TRUE(JSArguments::DefineOwnProperty(thread, JSHandle<JSArguments>(jsarg), key, Desc));
143 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->GetInt(), 1);
144 }
145
HWTEST_F_L0(JsArgumentsTest,GetOwnProperty)146 HWTEST_F_L0(JsArgumentsTest, GetOwnProperty)
147 {
148 JSHandle<JSTaggedValue> argFunc(thread, JSObjectTestCreate(thread));
149 JSHandle<JSObject> jsarg =
150 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(argFunc), argFunc);
151 JSHandle<JSArguments> arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments();
152
153 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("x"));
154 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
155 JSHandle<JSTaggedValue> receiver = JSHandle<JSTaggedValue>::Cast(jsarg);
156 JSArguments::SetProperty(thread, arg, key, value, receiver);
157
158 PropertyDescriptor Desc(thread);
159 JSHandle<EcmaString> caller = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("caller");
160 // key is not caller
161 EXPECT_FALSE(JSTaggedValue::SameValue(key.GetTaggedValue(), caller.GetTaggedValue()));
162 EXPECT_TRUE(JSArguments::GetOwnProperty(thread, JSHandle<JSArguments>(jsarg), key, Desc));
163 EXPECT_EQ(Desc.GetValue()->GetInt(), 1);
164 }
165 } // namespace panda::test
166