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/builtins/builtins_proxy.h" 17 18#include "ecmascript/ecma_runtime_call_info.h" 19#include "ecmascript/ecma_string.h" 20#include "ecmascript/ecma_vm.h" 21#include "ecmascript/global_env.h" 22#include "ecmascript/js_array.h" 23#include "ecmascript/js_handle.h" 24#include "ecmascript/js_tagged_value-inl.h" 25#include "ecmascript/js_thread.h" 26#include "ecmascript/object_factory.h" 27#include "ecmascript/tests/test_helper.h" 28 29using namespace panda::ecmascript; 30using namespace panda::ecmascript::builtins; 31 32namespace panda::test { 33class BuiltinsProxyTest : public BaseTestWithScope<false> { 34}; 35 36JSHandle<JSObject> BuiltinsTestProxyCreate(JSThread *thread) 37{ 38 EcmaVM *ecmaVM = thread->GetEcmaVM(); 39 JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv(); 40 JSHandle<JSTaggedValue> objFun(globalEnv->GetObjectFunction()); 41 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 42 43 JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun); 44 return obj; 45} 46 47// 26.2.1.1 Proxy( [ value ] ) 48HWTEST_F_L0(BuiltinsProxyTest, ProxyConstructor) 49{ 50 JSHandle<JSObject> target = BuiltinsTestProxyCreate(thread); 51 JSHandle<JSObject> handler = BuiltinsTestProxyCreate(thread); 52 53 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Null(), 8); 54 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 55 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); 56 ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue()); 57 ecmaRuntimeCallInfo->SetCallArg(1, handler.GetTaggedValue()); 58 59 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 60 JSTaggedValue result = BuiltinsProxy::ProxyConstructor(ecmaRuntimeCallInfo); 61 ASSERT_TRUE(result.IsECMAObject()); 62 JSHandle<JSTaggedValue> resultHandle(thread, result); 63 EXPECT_TRUE(resultHandle->IsJSProxy()); 64 TestHelper::TearDownFrame(thread, prev); 65} 66 67// 26.2.2.1 Proxy.revocable ( target, handler ) 68HWTEST_F_L0(BuiltinsProxyTest, Revocable) 69{ 70 JSHandle<JSObject> target = BuiltinsTestProxyCreate(thread); 71 JSHandle<JSObject> handler = BuiltinsTestProxyCreate(thread); 72 73 JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); 74 JSHandle<JSFunction> proxyFun(globalEnv->GetProxyFunction()); 75 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("prop")); 76 PropertyDescriptor desc(thread); 77 desc.SetWritable(false); 78 JSObject::DefineOwnProperty(thread, handler, key, desc); 79 80 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); 81 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); 82 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); 83 ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue()); 84 ecmaRuntimeCallInfo->SetCallArg(1, handler.GetTaggedValue()); 85 ecmaRuntimeCallInfo->SetNewTarget(JSTaggedValue(*proxyFun)); 86 87 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); 88 JSTaggedValue result = BuiltinsProxy::Revocable(ecmaRuntimeCallInfo); 89 ASSERT_TRUE(result.IsECMAObject()); 90 JSHandle<JSObject> resultHandle(thread, result); 91 92 auto globalConst = thread->GlobalConstants(); 93 JSHandle<JSTaggedValue> proxyKey = globalConst->GetHandledProxyString(); 94 JSHandle<JSTaggedValue> revokeKey = globalConst->GetHandledRevokeString(); 95 96 JSHandle<TaggedArray> keys = JSObject::GetOwnPropertyKeys(thread, resultHandle); 97 bool pflag = false; 98 bool rflag = false; 99 for (uint32_t i = 0; i < keys->GetLength(); i++) { 100 if (JSTaggedValue::SameValue(keys->Get(i), proxyKey.GetTaggedValue())) { 101 pflag = true; 102 } 103 if (JSTaggedValue::SameValue(keys->Get(i), revokeKey.GetTaggedValue())) { 104 rflag = true; 105 } 106 } 107 EXPECT_TRUE(pflag); 108 EXPECT_TRUE(rflag); 109 110 PropertyDescriptor descRes(thread); 111 JSObject::GetOwnProperty(thread, resultHandle, revokeKey, descRes); 112 EXPECT_TRUE(descRes.GetValue()->IsProxyRevocFunction()); 113 TestHelper::TearDownFrame(thread, prev); 114} 115} // namespace panda::test 116