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 BaseTestWithScope<false> {
27 };
28
JSObjectTestCreate(JSThread * thread)29 static JSFunction *JSObjectTestCreate(JSThread *thread)
30 {
31 EcmaVM *ecmaVM = thread->GetEcmaVM();
32 JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
33 return globalEnv->GetObjectFunction().GetObject<JSFunction>();
34 }
35
HWTEST_F_L0(JsArgumentsTest,SetProperty)36 HWTEST_F_L0(JsArgumentsTest, SetProperty)
37 {
38 JSHandle<JSTaggedValue> argFunc(thread, JSObjectTestCreate(thread));
39 JSHandle<JSObject> jsarg =
40 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(argFunc), argFunc);
41 JSHandle<JSArguments> arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments();
42
43 char array[] = "x";
44 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII(array));
45 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
46
47 // receive must be jsarg's conversion
48 JSHandle<JSTaggedValue> receiver = JSHandle<JSTaggedValue>::Cast(jsarg);
49 EXPECT_TRUE(JSArguments::SetProperty(thread, arg, key, value, receiver));
50 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->GetInt(), 1);
51 EXPECT_EQ(JSArguments::GetProperty(thread, jsarg, key).GetValue()->GetInt(), 1);
52
53 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
54 EXPECT_TRUE(JSArguments::SetProperty(thread, arg, key, value2, receiver));
55 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->GetInt(), 2);
56 EXPECT_EQ(JSArguments::GetProperty(thread, jsarg, key).GetValue()->GetInt(), 2);
57 }
58
HWTEST_F_L0(JsArgumentsTest,GetProperty)59 HWTEST_F_L0(JsArgumentsTest, GetProperty)
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()->NewFromASCII(array));
68 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
69
70 JSHandle<JSTaggedValue> receiver = JSHandle<JSTaggedValue>::Cast(jsarg);
71 JSArguments::SetProperty(thread, arg, key, value, receiver);
72 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->GetInt(), 1);
73 EXPECT_EQ(JSArguments::GetProperty(thread, JSHandle<JSArguments>(jsarg), key, receiver).GetValue()->GetInt(), 1);
74
75 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
76 JSArguments::SetProperty(thread, arg, key, value2, receiver);
77 EXPECT_EQ(JSArguments::GetProperty(thread, jsarg, key).GetValue()->GetInt(), 2);
78 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->GetInt(), 2);
79 }
80
HWTEST_F_L0(JsArgumentsTest,DeleteProperty)81 HWTEST_F_L0(JsArgumentsTest, DeleteProperty)
82 {
83 JSHandle<JSTaggedValue> argFunc(thread, JSObjectTestCreate(thread));
84 JSHandle<JSObject> jsarg =
85 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(argFunc), argFunc);
86 JSHandle<JSArguments> arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments();
87
88 char array[] = "delete";
89 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII(array));
90 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
91 JSHandle<JSTaggedValue> receiver = JSHandle<JSTaggedValue>::Cast(jsarg);
92 JSArguments::SetProperty(thread, arg, key, value, receiver);
93 EXPECT_EQ(JSArguments::GetProperty(thread, jsarg, key).GetValue()->GetInt(), 1);
94
95 // test delete
96 bool result = JSArguments::DeleteProperty(thread, JSHandle<JSArguments>(jsarg), key);
97 EXPECT_TRUE(result);
98 EXPECT_TRUE(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->IsUndefined());
99 }
100
HWTEST_F_L0(JsArgumentsTest,DefineOwnProperty)101 HWTEST_F_L0(JsArgumentsTest, DefineOwnProperty)
102 {
103 JSHandle<JSTaggedValue> argFunc(thread, JSObjectTestCreate(thread));
104 JSHandle<JSObject> jsarg =
105 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(argFunc), argFunc);
106 JSHandle<JSArguments> arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments();
107
108 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
109 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
110 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
111 JSHandle<JSTaggedValue> receiver = JSHandle<JSTaggedValue>::Cast(jsarg);
112 JSArguments::SetProperty(thread, arg, key, value2, receiver);
113 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->GetInt(), 2);
114
115 PropertyDescriptor Desc(thread);
116 // set value1
117 Desc.SetValue(value1);
118 Desc.SetWritable(false);
119 EXPECT_TRUE(JSArguments::DefineOwnProperty(thread, JSHandle<JSArguments>(jsarg), key, Desc));
120 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsarg), key).GetValue()->GetInt(), 1);
121 }
122
HWTEST_F_L0(JsArgumentsTest,GetOwnProperty)123 HWTEST_F_L0(JsArgumentsTest, GetOwnProperty)
124 {
125 JSHandle<JSTaggedValue> argFunc(thread, JSObjectTestCreate(thread));
126 JSHandle<JSObject> jsarg =
127 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(argFunc), argFunc);
128 JSHandle<JSArguments> arg = thread->GetEcmaVM()->GetFactory()->NewJSArguments();
129
130 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
131 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
132 JSHandle<JSTaggedValue> receiver = JSHandle<JSTaggedValue>::Cast(jsarg);
133 JSArguments::SetProperty(thread, arg, key, value, receiver);
134
135 PropertyDescriptor Desc(thread);
136 JSHandle<EcmaString> caller = thread->GetEcmaVM()->GetFactory()->NewFromASCII("caller");
137 // key is not caller
138 EXPECT_FALSE(JSTaggedValue::SameValue(key.GetTaggedValue(), caller.GetTaggedValue()));
139 EXPECT_TRUE(JSArguments::GetOwnProperty(thread, JSHandle<JSArguments>(jsarg), key, Desc));
140 EXPECT_EQ(Desc.GetValue()->GetInt(), 1);
141 }
142 } // namespace panda::test
143