mirror of
https://github.com/openharmony/ark_js_runtime.git
synced 2026-07-21 07:05:22 -04:00
82b0916295
Modify gc name and delete class_ in object factory. issue:https://gitee.com/openharmony/ark_js_runtime/issues/I4T5DR Signed-off-by: xiongluo <xiongluo@huawei.com>
849 lines
34 KiB
C++
849 lines
34 KiB
C++
/*
|
|
* 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/tests/test_helper.h"
|
|
|
|
#include <cstddef>
|
|
#include "ecmascript/builtins/builtins_function.h"
|
|
#include "ecmascript/ecma_vm.h"
|
|
#include "ecmascript/global_env.h"
|
|
#include "ecmascript/js_thread.h"
|
|
#include "ecmascript/napi/include/jsnapi.h"
|
|
#include "ecmascript/napi/jsnapi_helper-inl.h"
|
|
#include "ecmascript/object_factory.h"
|
|
|
|
using namespace panda;
|
|
using namespace panda::ecmascript;
|
|
|
|
namespace panda::test {
|
|
using BuiltinsFunction = ecmascript::builtins::BuiltinsFunction;
|
|
class JSNApiTests : public testing::Test {
|
|
public:
|
|
static void SetUpTestCase()
|
|
{
|
|
GTEST_LOG_(INFO) << "SetUpTestCase";
|
|
}
|
|
|
|
static void TearDownTestCase()
|
|
{
|
|
GTEST_LOG_(INFO) << "TearDownCase";
|
|
}
|
|
|
|
void SetUp() override
|
|
{
|
|
RuntimeOption option;
|
|
option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
|
|
vm_ = JSNApi::CreateJSVM(option);
|
|
ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
|
|
thread_ = vm_->GetJSThread();
|
|
vm_->SetEnableForceGC(true);
|
|
}
|
|
|
|
void TearDown() override
|
|
{
|
|
vm_->SetEnableForceGC(false);
|
|
JSNApi::DestroyJSVM(vm_);
|
|
}
|
|
|
|
protected:
|
|
JSThread *thread_ = nullptr;
|
|
EcmaVM *vm_ = nullptr;
|
|
};
|
|
|
|
Local<JSValueRef> FunctionCallback(EcmaVM *vm, Local<JSValueRef>, const Local<JSValueRef> *, int32_t length, void *)
|
|
{
|
|
EscapeLocalScope scope(vm);
|
|
return scope.Escape(ArrayRef::New(vm, length));
|
|
}
|
|
|
|
void ThreadCheck(const EcmaVM *vm)
|
|
{
|
|
EXPECT_TRUE(vm->GetJSThread()->GetThreadId() != JSThread::GetCurrentThreadId());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, GetGlobalObject)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<ObjectRef> globalObject = JSNApi::GetGlobalObject(vm_);
|
|
ASSERT_FALSE(globalObject.IsEmpty());
|
|
ASSERT_TRUE(globalObject->IsObject());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, ThreadIdCheck)
|
|
{
|
|
EXPECT_TRUE(vm_->GetJSThread()->GetThreadId() == JSThread::GetCurrentThreadId());
|
|
#if defined(ECMASCRIPT_ENABLE_THREAD_CHECK) && !ECMASCRIPT_ENABLE_THREAD_CHECK
|
|
std::thread testThread(ThreadCheck, vm_);
|
|
testThread.join();
|
|
#endif
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, RegisterFunction)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<FunctionRef> callback = FunctionRef::New(vm_, FunctionCallback, nullptr);
|
|
ASSERT_TRUE(!callback.IsEmpty());
|
|
std::vector<Local<JSValueRef>> arguments;
|
|
arguments.emplace_back(JSValueRef::Undefined(vm_));
|
|
Local<JSValueRef> result =
|
|
callback->Call(vm_, JSValueRef::Undefined(vm_), arguments.data(), arguments.size());
|
|
ASSERT_TRUE(result->IsArray(vm_));
|
|
Local<ArrayRef> array(result);
|
|
ASSERT_EQ(array->Length(vm_), arguments.size());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, GetProperty)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<ObjectRef> globalObject = JSNApi::GetGlobalObject(vm_);
|
|
ASSERT_FALSE(globalObject.IsEmpty());
|
|
ASSERT_TRUE(globalObject->IsObject());
|
|
|
|
Local<ObjectRef> key = StringRef::NewFromUtf8(vm_, "Number");
|
|
Local<ObjectRef> property = globalObject->Get(vm_, key);
|
|
ASSERT_TRUE(property->IsFunction());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, SetProperty)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<ObjectRef> globalObject = JSNApi::GetGlobalObject(vm_);
|
|
ASSERT_FALSE(globalObject.IsEmpty());
|
|
ASSERT_TRUE(globalObject->IsObject());
|
|
|
|
Local<ArrayRef> property = ArrayRef::New(vm_, 3); // 3 : length
|
|
ASSERT_TRUE(property->IsArray(vm_));
|
|
ASSERT_EQ(property->Length(vm_), 3); // 3 : test case of input
|
|
|
|
Local<ObjectRef> key = StringRef::NewFromUtf8(vm_, "Test");
|
|
bool result = globalObject->Set(vm_, key, property);
|
|
ASSERT_TRUE(result);
|
|
|
|
Local<ObjectRef> propertyGet = globalObject->Get(vm_, key);
|
|
ASSERT_TRUE(propertyGet->IsArray(vm_));
|
|
ASSERT_EQ(Local<ArrayRef>(propertyGet)->Length(vm_), 3); // 3 : test case of input
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, JsonParser)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<ObjectRef> globalObject = JSNApi::GetGlobalObject(vm_);
|
|
ASSERT_FALSE(globalObject.IsEmpty());
|
|
ASSERT_TRUE(globalObject->IsObject());
|
|
|
|
const char *const test{R"({"orientation": "portrait"})"};
|
|
Local<ObjectRef> jsonString = StringRef::NewFromUtf8(vm_, test);
|
|
|
|
Local<JSValueRef> result = JSON::Parse(vm_, jsonString);
|
|
ASSERT_TRUE(result->IsObject());
|
|
|
|
Local<ObjectRef> keyString = StringRef::NewFromUtf8(vm_, "orientation");
|
|
Local<JSValueRef> property = Local<ObjectRef>(result)->Get(vm_, keyString);
|
|
ASSERT_TRUE(property->IsString());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, StrictEqual)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<StringRef> origin = StringRef::NewFromUtf8(vm_, "1");
|
|
Local<StringRef> target1 = StringRef::NewFromUtf8(vm_, "1");
|
|
Local<NumberRef> target = NumberRef::New(vm_, 1);
|
|
|
|
ASSERT_FALSE(origin->IsStrictEquals(vm_, target));
|
|
ASSERT_TRUE(origin->IsStrictEquals(vm_, target1));
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, InstanceOf)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<FunctionRef> target = FunctionRef::New(vm_, nullptr, nullptr);
|
|
Local<ArrayRef> origin = ArrayRef::New(vm_, 1);
|
|
|
|
ASSERT_FALSE(origin->InstanceOf(vm_, target));
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, TypeOf)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<StringRef> origin = StringRef::NewFromUtf8(vm_, "1");
|
|
Local<StringRef> typeString = origin->Typeof(vm_);
|
|
ASSERT_EQ(typeString->ToString(), "string");
|
|
|
|
Local<NumberRef> target = NumberRef::New(vm_, 1);
|
|
typeString = target->Typeof(vm_);
|
|
ASSERT_EQ(typeString->ToString(), "number");
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, Symbol)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<StringRef> description = StringRef::NewFromUtf8(vm_, "test");
|
|
Local<SymbolRef> symbol = SymbolRef::New(vm_, description);
|
|
|
|
ASSERT_FALSE(description->IsSymbol());
|
|
ASSERT_TRUE(symbol->IsSymbol());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, StringUtf8_001)
|
|
{
|
|
LocalScope scope(vm_);
|
|
std::string test = "Hello world";
|
|
Local<StringRef> testString = StringRef::NewFromUtf8(vm_, test.c_str());
|
|
|
|
EXPECT_TRUE(testString->Utf8Length() == 12); // 12 : length of testString("Hello World")
|
|
char buffer[12]; // 12 : length of testString
|
|
EXPECT_TRUE(testString->WriteUtf8(buffer, 12) == 12); // 12 : length of testString("Hello World")
|
|
std::string res(buffer);
|
|
ASSERT_EQ(res, test);
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, StringUtf8_002)
|
|
{
|
|
LocalScope scope(vm_);
|
|
std::string test = "年";
|
|
Local<StringRef> testString = StringRef::NewFromUtf8(vm_, test.c_str());
|
|
|
|
EXPECT_TRUE(testString->Utf8Length() == 4); // 4 : length of testString("年")
|
|
char buffer[4]; // 4 : length of testString
|
|
EXPECT_TRUE(testString->WriteUtf8(buffer, 4) == 4); // 4 : length of testString("年")
|
|
std::string res(buffer);
|
|
ASSERT_EQ(res, test);
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, ToType)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<StringRef> toString = StringRef::NewFromUtf8(vm_, "-123.3");
|
|
Local<JSValueRef> toValue(toString);
|
|
|
|
ASSERT_EQ(toString->ToNumber(vm_)->Value(), -123.3); // -123 : test case of input
|
|
ASSERT_EQ(toString->ToBoolean(vm_)->Value(), true);
|
|
ASSERT_EQ(toValue->ToString(vm_)->ToString(), "-123.3");
|
|
ASSERT_TRUE(toValue->ToObject(vm_)->IsObject());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, TypeValue)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<StringRef> toString = StringRef::NewFromUtf8(vm_, "-123");
|
|
Local<JSValueRef> toValue(toString);
|
|
|
|
ASSERT_EQ(toString->Int32Value(vm_), -123); // -123 : test case of input
|
|
ASSERT_EQ(toString->BooleaValue(), true);
|
|
ASSERT_EQ(toString->Uint32Value(vm_), 4294967173); // 4294967173 : test case of input
|
|
ASSERT_EQ(toString->IntegerValue(vm_), -123); // -123 : test case of input
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, DefineProperty)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<ObjectRef> object = ObjectRef::New(vm_);
|
|
Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey");
|
|
Local<JSValueRef> value = ObjectRef::New(vm_);
|
|
PropertyAttribute attribute(value, true, true, true);
|
|
|
|
ASSERT_TRUE(object->DefineProperty(vm_, key, attribute));
|
|
Local<JSValueRef> value1 = object->Get(vm_, key);
|
|
ASSERT_TRUE(value->IsStrictEquals(vm_, value1));
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, HasProperty)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<ObjectRef> object = ObjectRef::New(vm_);
|
|
Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey");
|
|
Local<JSValueRef> value = ObjectRef::New(vm_);
|
|
PropertyAttribute attribute(value, true, true, true);
|
|
|
|
ASSERT_TRUE(object->DefineProperty(vm_, key, attribute));
|
|
ASSERT_TRUE(object->Has(vm_, key));
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, DeleteProperty)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<ObjectRef> object = ObjectRef::New(vm_);
|
|
Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey");
|
|
Local<JSValueRef> value = ObjectRef::New(vm_);
|
|
PropertyAttribute attribute(value, true, true, true);
|
|
|
|
ASSERT_TRUE(object->DefineProperty(vm_, key, attribute));
|
|
ASSERT_TRUE(object->Delete(vm_, key));
|
|
ASSERT_FALSE(object->Has(vm_, key));
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, GetProtoType)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<FunctionRef> function = FunctionRef::New(vm_, nullptr, nullptr);
|
|
Local<JSValueRef> protoType = function->GetPrototype(vm_);
|
|
ASSERT_TRUE(protoType->IsObject());
|
|
|
|
Local<FunctionRef> object = ObjectRef::New(vm_);
|
|
protoType = object->GetPrototype(vm_);
|
|
ASSERT_TRUE(protoType->IsObject());
|
|
}
|
|
|
|
void CheckReject(EcmaVM *, Local<JSValueRef>, const Local<JSValueRef> argv[], int32_t length, void *)
|
|
{
|
|
ASSERT_EQ(length, 1);
|
|
Local<JSValueRef> reason = argv[0];
|
|
ASSERT_TRUE(reason->IsString());
|
|
ASSERT_EQ(Local<StringRef>(reason)->ToString(), "Reject");
|
|
}
|
|
|
|
Local<JSValueRef> RejectCallback(EcmaVM *vm, Local<JSValueRef> thisArg, const Local<JSValueRef> argv[], int32_t length,
|
|
void *data)
|
|
{
|
|
LocalScope scope(vm);
|
|
CheckReject(vm, thisArg, argv, length, data);
|
|
return JSValueRef::Undefined(vm);
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, PromiseCatch)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<PromiseCapabilityRef> capability = PromiseCapabilityRef::New(vm_);
|
|
|
|
Local<PromiseRef> promise = capability->GetPromise(vm_);
|
|
Local<FunctionRef> reject = FunctionRef::New(vm_, RejectCallback, nullptr);
|
|
Local<PromiseRef> catchPromise = promise->Catch(vm_, reject);
|
|
ASSERT_TRUE(promise->IsPromise());
|
|
ASSERT_TRUE(catchPromise->IsPromise());
|
|
|
|
Local<StringRef> reason = StringRef::NewFromUtf8(vm_, "Reject");
|
|
ASSERT_TRUE(capability->Reject(vm_, reason));
|
|
|
|
vm_->ExecutePromisePendingJob();
|
|
}
|
|
|
|
void CheckResolve(EcmaVM *, Local<JSValueRef>, const Local<JSValueRef> argv[], int32_t length, void *)
|
|
{
|
|
ASSERT_EQ(length, 1);
|
|
Local<JSValueRef> value = argv[0];
|
|
ASSERT_TRUE(value->IsNumber());
|
|
ASSERT_EQ(Local<NumberRef>(value)->Value(), 300.3); // 300.3 : test case of input
|
|
}
|
|
|
|
Local<JSValueRef> ResolvedCallback(EcmaVM *vm, Local<JSValueRef> thisArg, const Local<JSValueRef> argv[],
|
|
int32_t length, void *data)
|
|
{
|
|
LocalScope scope(vm);
|
|
CheckResolve(vm, thisArg, argv, length, data);
|
|
return JSValueRef::Undefined(vm);
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, PromiseThen)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<PromiseCapabilityRef> capability = PromiseCapabilityRef::New(vm_);
|
|
|
|
Local<PromiseRef> promise = capability->GetPromise(vm_);
|
|
Local<FunctionRef> resolve = FunctionRef::New(vm_, ResolvedCallback, nullptr);
|
|
Local<FunctionRef> reject = FunctionRef::New(vm_, RejectCallback, nullptr);
|
|
Local<PromiseRef> thenPromise = promise->Then(vm_, resolve, reject);
|
|
ASSERT_TRUE(promise->IsPromise());
|
|
ASSERT_TRUE(thenPromise->IsPromise());
|
|
|
|
Local<StringRef> value = NumberRef::New(vm_, 300.3); // 300.3 : test case of input
|
|
ASSERT_TRUE(capability->Resolve(vm_, value));
|
|
vm_->ExecutePromisePendingJob();
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, Constructor)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<ObjectRef> object = JSNApi::GetGlobalObject(vm_);
|
|
Local<StringRef> key = StringRef::NewFromUtf8(vm_, "Number");
|
|
Local<FunctionRef> numberConstructor = object->Get(vm_, key);
|
|
Local<JSValueRef> argv[1];
|
|
argv[0] = NumberRef::New(vm_, 1.3); // 1.3 : test case of input
|
|
Local<JSValueRef> result = numberConstructor->Constructor(vm_, argv, 1);
|
|
ASSERT_TRUE(result->IsObject());
|
|
ASSERT_EQ(result->ToNumber(vm_)->Value(), 1.3); // 1.3 : size of arguments
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, ArrayBuffer)
|
|
{
|
|
LocalScope scope(vm_);
|
|
const int32_t length = 15;
|
|
Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
|
|
ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
|
|
ASSERT_EQ(arrayBuffer->ByteLength(vm_), length);
|
|
ASSERT_NE(arrayBuffer->GetBuffer(), nullptr);
|
|
JSNApi::TriggerGC(vm_);
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, ArrayBufferWithBuffer)
|
|
{
|
|
static bool isFree = false;
|
|
struct Data {
|
|
int32_t length;
|
|
};
|
|
const int32_t length = 15;
|
|
Data *data = new Data();
|
|
data->length = length;
|
|
Deleter deleter = [](void *buffer, void *data) -> void {
|
|
delete[] reinterpret_cast<uint8_t *>(buffer);
|
|
Data *currentData = reinterpret_cast<Data *>(data);
|
|
ASSERT_EQ(currentData->length, 15); // 5 : size of arguments
|
|
delete currentData;
|
|
isFree = true;
|
|
};
|
|
{
|
|
LocalScope scope(vm_);
|
|
uint8_t *buffer = new uint8_t[length]();
|
|
Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, buffer, length, deleter, data);
|
|
ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
|
|
ASSERT_EQ(arrayBuffer->ByteLength(vm_), length);
|
|
ASSERT_EQ(arrayBuffer->GetBuffer(), buffer);
|
|
}
|
|
JSNApi::TriggerGC(vm_, JSNApi::TRIGGER_GC_TYPE::FULL_GC);
|
|
ASSERT_TRUE(isFree);
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, DataView)
|
|
{
|
|
LocalScope scope(vm_);
|
|
const int32_t length = 15;
|
|
Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
|
|
JSNApi::TriggerGC(vm_);
|
|
ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
|
|
|
|
// 5 : offset of byte, 7 : length
|
|
Local<DataViewRef> dataView = DataViewRef::New(vm_, arrayBuffer, 5, 7);
|
|
ASSERT_TRUE(dataView->IsDataView());
|
|
ASSERT_EQ(dataView->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
|
|
ASSERT_EQ(dataView->ByteLength(), 7); // 7 : size of arguments
|
|
ASSERT_EQ(dataView->ByteOffset(), 5); // 5 : size of arguments
|
|
|
|
// 5 : offset of byte, 11 : length
|
|
dataView = DataViewRef::New(vm_, arrayBuffer, 5, 11);
|
|
ASSERT_TRUE(dataView->IsException());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, Int8Array)
|
|
{
|
|
LocalScope scope(vm_);
|
|
const int32_t length = 15;
|
|
Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
|
|
ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
|
|
|
|
// 5 : offset of byte, 6 : length
|
|
Local<Int8ArrayRef> typedArray = Int8ArrayRef::New(vm_, arrayBuffer, 5, 6);
|
|
ASSERT_TRUE(typedArray->IsInt8Array());
|
|
ASSERT_EQ(typedArray->ByteLength(vm_), 6); // 6 : length of bytes
|
|
ASSERT_EQ(typedArray->ByteOffset(vm_), 5); // 5 : offset of byte
|
|
ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
|
|
ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, Uint8Array)
|
|
{
|
|
LocalScope scope(vm_);
|
|
const int32_t length = 15;
|
|
Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
|
|
ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
|
|
|
|
// 5 : offset of byte, 6 : length
|
|
Local<Uint8ArrayRef> typedArray = Uint8ArrayRef::New(vm_, arrayBuffer, 5, 6);
|
|
ASSERT_TRUE(typedArray->IsUint8Array());
|
|
ASSERT_EQ(typedArray->ByteLength(vm_), 6); // 6 : length of bytes
|
|
ASSERT_EQ(typedArray->ByteOffset(vm_), 5); // 5 : offset of byte
|
|
ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
|
|
ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, Uint8ClampedArray)
|
|
{
|
|
LocalScope scope(vm_);
|
|
const int32_t length = 15;
|
|
Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
|
|
ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
|
|
|
|
// 5 : offset of byte, 6 : length
|
|
Local<Uint8ClampedArrayRef> typedArray = Uint8ClampedArrayRef::New(vm_, arrayBuffer, 5, 6);
|
|
ASSERT_TRUE(typedArray->IsUint8ClampedArray());
|
|
ASSERT_EQ(typedArray->ByteLength(vm_), 6); // 6 : length of bytes
|
|
ASSERT_EQ(typedArray->ByteOffset(vm_), 5); // 5 : offset of byte
|
|
ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
|
|
ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, Int16Array)
|
|
{
|
|
LocalScope scope(vm_);
|
|
const int32_t length = 30;
|
|
Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
|
|
ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
|
|
|
|
// 4 : offset of byte, 6 : length
|
|
Local<Int16ArrayRef> typedArray = Int16ArrayRef::New(vm_, arrayBuffer, 4, 6);
|
|
ASSERT_TRUE(typedArray->IsInt16Array());
|
|
ASSERT_EQ(typedArray->ByteLength(vm_), 12); // 12 : length of bytes
|
|
ASSERT_EQ(typedArray->ByteOffset(vm_), 4); // 4 : offset of byte
|
|
ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
|
|
ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, Uint16Array)
|
|
{
|
|
LocalScope scope(vm_);
|
|
const int32_t length = 30;
|
|
Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
|
|
ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
|
|
|
|
// 4 : offset of byte, 6 : length
|
|
Local<Uint16ArrayRef> typedArray = Uint16ArrayRef::New(vm_, arrayBuffer, 4, 6);
|
|
ASSERT_TRUE(typedArray->IsUint16Array());
|
|
ASSERT_EQ(typedArray->ByteLength(vm_), 12); // 12 : length of bytes
|
|
ASSERT_EQ(typedArray->ByteOffset(vm_), 4); // 4 : offset of byte
|
|
ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
|
|
ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, Uint32Array)
|
|
{
|
|
LocalScope scope(vm_);
|
|
const int32_t length = 30;
|
|
Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
|
|
ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
|
|
|
|
// 4 : offset of byte, 6 : length
|
|
Local<Uint32ArrayRef> typedArray = Uint32ArrayRef::New(vm_, arrayBuffer, 4, 6);
|
|
ASSERT_TRUE(typedArray->IsUint32Array());
|
|
ASSERT_EQ(typedArray->ByteLength(vm_), 24); // 24 : length of bytes
|
|
ASSERT_EQ(typedArray->ByteOffset(vm_), 4); // 4 : offset of byte
|
|
ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
|
|
ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, Int32Array)
|
|
{
|
|
LocalScope scope(vm_);
|
|
const int32_t length = 30;
|
|
Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
|
|
ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
|
|
|
|
// 4 : offset of byte, 6 : length
|
|
Local<Int32ArrayRef> typedArray = Int32ArrayRef::New(vm_, arrayBuffer, 4, 6);
|
|
ASSERT_TRUE(typedArray->IsInt32Array());
|
|
ASSERT_EQ(typedArray->ByteLength(vm_), 24); // 24 : length of bytes
|
|
ASSERT_EQ(typedArray->ByteOffset(vm_), 4); // 4 : offset of byte
|
|
ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
|
|
ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, Float32Array)
|
|
{
|
|
LocalScope scope(vm_);
|
|
const int32_t length = 30;
|
|
Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
|
|
ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
|
|
|
|
// 4 : offset of byte, 6 : length
|
|
Local<Float32ArrayRef> typedArray = Float32ArrayRef::New(vm_, arrayBuffer, 4, 6);
|
|
ASSERT_TRUE(typedArray->IsFloat32Array());
|
|
ASSERT_EQ(typedArray->ByteLength(vm_), 24); // 24 : length of bytes
|
|
ASSERT_EQ(typedArray->ByteOffset(vm_), 4); // 4 : offset of byte
|
|
ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
|
|
ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, Float64Array)
|
|
{
|
|
LocalScope scope(vm_);
|
|
const int32_t length = 57;
|
|
Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
|
|
ASSERT_TRUE(arrayBuffer->IsArrayBuffer());
|
|
|
|
// 8 : offset of byte, 6 : length
|
|
Local<Float64ArrayRef> typedArray = Float64ArrayRef::New(vm_, arrayBuffer, 8, 6);
|
|
ASSERT_TRUE(typedArray->IsFloat64Array());
|
|
ASSERT_EQ(typedArray->ByteLength(vm_), 48); // 48 : length of bytes
|
|
ASSERT_EQ(typedArray->ByteOffset(vm_), 8); // 8 : offset of byte
|
|
ASSERT_EQ(typedArray->ArrayLength(vm_), 6); // 6 : length of array
|
|
ASSERT_EQ(typedArray->GetArrayBuffer(vm_)->GetBuffer(), arrayBuffer->GetBuffer());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, Error)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
|
|
Local<JSValueRef> error = Exception::Error(vm_, message);
|
|
ASSERT_TRUE(error->IsError());
|
|
|
|
JSNApi::ThrowException(vm_, error);
|
|
ASSERT_TRUE(thread_->HasPendingException());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, RangeError)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
|
|
Local<JSValueRef> error = Exception::RangeError(vm_, message);
|
|
ASSERT_TRUE(error->IsError());
|
|
|
|
JSNApi::ThrowException(vm_, error);
|
|
ASSERT_TRUE(thread_->HasPendingException());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, TypeError)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
|
|
Local<JSValueRef> error = Exception::TypeError(vm_, message);
|
|
ASSERT_TRUE(error->IsError());
|
|
|
|
JSNApi::ThrowException(vm_, error);
|
|
ASSERT_TRUE(thread_->HasPendingException());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, ReferenceError)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
|
|
Local<JSValueRef> error = Exception::ReferenceError(vm_, message);
|
|
ASSERT_TRUE(error->IsError());
|
|
|
|
JSNApi::ThrowException(vm_, error);
|
|
ASSERT_TRUE(thread_->HasPendingException());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, SyntaxError)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
|
|
Local<JSValueRef> error = Exception::SyntaxError(vm_, message);
|
|
ASSERT_TRUE(error->IsError());
|
|
|
|
JSNApi::ThrowException(vm_, error);
|
|
ASSERT_TRUE(thread_->HasPendingException());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, InheritPrototype_001)
|
|
{
|
|
LocalScope scope(vm_);
|
|
JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
|
|
// new with Builtins::Set Prototype
|
|
JSHandle<JSTaggedValue> set = env->GetBuiltinsSetFunction();
|
|
Local<FunctionRef> setLocal = JSNApiHelper::ToLocal<FunctionRef>(set);
|
|
// new with Builtins::Map Prototype
|
|
JSHandle<JSTaggedValue> map = env->GetBuiltinsMapFunction();
|
|
Local<FunctionRef> mapLocal = JSNApiHelper::ToLocal<FunctionRef>(map);
|
|
JSHandle<JSTaggedValue> setPrototype(thread_, JSHandle<JSFunction>::Cast(set)->GetFunctionPrototype());
|
|
JSHandle<JSTaggedValue> mapPrototype(thread_, JSHandle<JSFunction>::Cast(map)->GetFunctionPrototype());
|
|
JSHandle<JSTaggedValue> mapPrototypeProto(thread_, JSHandle<JSObject>::Cast(mapPrototype)->GetPrototype(thread_));
|
|
bool same = JSTaggedValue::SameValue(setPrototype, mapPrototypeProto);
|
|
// before inherit, map.Prototype.__proto__ should be different from set.Prototype
|
|
ASSERT_FALSE(same);
|
|
// before inherit, map.__proto__ should be different from set
|
|
JSHandle<JSTaggedValue> mapProto(thread_, JSHandle<JSObject>::Cast(map)->GetPrototype(thread_));
|
|
bool same1 = JSTaggedValue::SameValue(set, mapProto);
|
|
ASSERT_FALSE(same1);
|
|
|
|
// Set property to Set Function
|
|
auto factory = vm_->GetFactory();
|
|
JSHandle<JSTaggedValue> defaultString = thread_->GlobalConstants()->GetHandledDefaultString();
|
|
PropertyDescriptor desc = PropertyDescriptor(thread_, defaultString);
|
|
bool success = JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(set), defaultString, desc);
|
|
ASSERT_TRUE(success);
|
|
JSHandle<JSTaggedValue> property1String(thread_, factory->NewFromCanBeCompressString("property1").GetTaggedValue());
|
|
JSHandle<JSTaggedValue> func = env->GetTypedArrayFunction();
|
|
PropertyDescriptor desc1 = PropertyDescriptor(thread_, func);
|
|
bool success1 = JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(set), property1String, desc1);
|
|
ASSERT_TRUE(success1);
|
|
|
|
mapLocal->Inherit(vm_, setLocal);
|
|
JSHandle<JSTaggedValue> sonHandle = JSNApiHelper::ToJSHandle(mapLocal);
|
|
JSHandle<JSTaggedValue> sonPrototype(thread_, JSHandle<JSFunction>::Cast(sonHandle)->GetFunctionPrototype());
|
|
JSHandle<JSTaggedValue> sonPrototypeProto(thread_, JSHandle<JSObject>::Cast(sonPrototype)->GetPrototype(thread_));
|
|
bool same2 = JSTaggedValue::SameValue(setPrototype, sonPrototypeProto);
|
|
ASSERT_TRUE(same2);
|
|
JSHandle<JSTaggedValue> sonProto(thread_, JSHandle<JSObject>::Cast(map)->GetPrototype(thread_));
|
|
bool same3 = JSTaggedValue::SameValue(set, sonProto);
|
|
ASSERT_TRUE(same3);
|
|
|
|
// son = new Son(), Son() inherit from Parent(), Test whether son.InstanceOf(Parent) is true
|
|
JSHandle<JSObject> sonObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(sonHandle), sonHandle);
|
|
bool isInstance = JSObject::InstanceOf(thread_, JSHandle<JSTaggedValue>::Cast(sonObj), set);
|
|
ASSERT_TRUE(isInstance);
|
|
|
|
// Test whether son Function can access to property of parent Function
|
|
OperationResult res = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(sonHandle), defaultString);
|
|
bool same4 = JSTaggedValue::SameValue(defaultString, res.GetValue());
|
|
ASSERT_TRUE(same4);
|
|
OperationResult res1 = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(sonHandle), property1String);
|
|
bool same5 = JSTaggedValue::SameValue(func, res1.GetValue());
|
|
ASSERT_TRUE(same5);
|
|
|
|
// new with empty Function Constructor
|
|
Local<FunctionRef> son1 = FunctionRef::New(vm_, FunctionCallback, nullptr);
|
|
son1->Inherit(vm_, mapLocal);
|
|
JSHandle<JSFunction> son1Handle = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(son1));
|
|
ASSERT_TRUE(son1Handle->HasFunctionPrototype());
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, InheritPrototype_002)
|
|
{
|
|
LocalScope scope(vm_);
|
|
JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
|
|
// new with Builtins::weakSet Prototype
|
|
JSHandle<JSTaggedValue> weakSet = env->GetBuiltinsWeakSetFunction();
|
|
Local<FunctionRef> weakSetLocal = JSNApiHelper::ToLocal<FunctionRef>(weakSet);
|
|
// new with Builtins::weakMap Prototype
|
|
JSHandle<JSTaggedValue> weakMap = env->GetBuiltinsWeakMapFunction();
|
|
Local<FunctionRef> weakMapLocal = JSNApiHelper::ToLocal<FunctionRef>(weakMap);
|
|
|
|
weakMapLocal->Inherit(vm_, weakSetLocal);
|
|
|
|
auto factory = vm_->GetFactory();
|
|
JSHandle<JSTaggedValue> property1String(thread_, factory->NewFromCanBeCompressString("property1").GetTaggedValue());
|
|
JSHandle<JSTaggedValue> func = env->GetArrayFunction();
|
|
PropertyDescriptor desc1 = PropertyDescriptor(thread_, func);
|
|
bool success1 = JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(weakMap), property1String, desc1);
|
|
ASSERT_TRUE(success1);
|
|
|
|
JSHandle<JSTaggedValue> sonHandle = JSNApiHelper::ToJSHandle(weakMapLocal);
|
|
JSHandle<JSObject> sonObj =
|
|
factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(sonHandle), sonHandle);
|
|
|
|
JSHandle<JSTaggedValue> fatherHandle = JSNApiHelper::ToJSHandle(weakSetLocal);
|
|
JSHandle<JSObject> fatherObj =
|
|
factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(fatherHandle), fatherHandle);
|
|
|
|
JSHandle<JSTaggedValue> sonMethod =
|
|
JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>(sonObj), property1String);
|
|
JSHandle<JSTaggedValue> fatherMethod =
|
|
JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>(fatherObj), property1String);
|
|
bool same = JSTaggedValue::SameValue(sonMethod, fatherMethod);
|
|
ASSERT_TRUE(same);
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, InheritPrototype_003)
|
|
{
|
|
LocalScope scope(vm_);
|
|
JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
|
|
auto factory = vm_->GetFactory();
|
|
|
|
JSMethod *invokeSelf =
|
|
vm_->GetMethodForNativeFunction(reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf));
|
|
// father type
|
|
JSHandle<JSHClass> protoDynclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithProto());
|
|
JSHandle<JSFunction> protoFunc = factory->NewJSFunctionByDynClass(invokeSelf, protoDynclass);
|
|
Local<FunctionRef> protoLocal = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(protoFunc));
|
|
// son type
|
|
JSHandle<JSHClass> noProtoDynclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutProto());
|
|
JSHandle<JSFunction> noProtoFunc = factory->NewJSFunctionByDynClass(invokeSelf, noProtoDynclass);
|
|
Local<FunctionRef> noProtoLocal = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(noProtoFunc));
|
|
|
|
JSHandle<JSFunction> sonHandle = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(noProtoLocal));
|
|
EXPECT_FALSE(sonHandle->HasFunctionPrototype());
|
|
|
|
JSHandle<JSTaggedValue> defaultString = thread_->GlobalConstants()->GetHandledDefaultString();
|
|
PropertyDescriptor desc = PropertyDescriptor(thread_, defaultString);
|
|
JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(protoFunc), defaultString, desc);
|
|
|
|
noProtoLocal->Inherit(vm_, protoLocal);
|
|
JSHandle<JSFunction> son1Handle = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(noProtoLocal));
|
|
EXPECT_TRUE(son1Handle->HasFunctionPrototype());
|
|
|
|
OperationResult res = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(son1Handle), defaultString);
|
|
EXPECT_EQ(JSTaggedValue::SameValue(defaultString, res.GetValue()), true);
|
|
|
|
JSHandle<JSTaggedValue> propertyString(thread_, factory->NewFromCanBeCompressString("property").GetTaggedValue());
|
|
JSHandle<JSTaggedValue> func = env->GetArrayFunction();
|
|
PropertyDescriptor desc1 = PropertyDescriptor(thread_, func);
|
|
JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(protoFunc), propertyString, desc1);
|
|
OperationResult res1 = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(son1Handle), propertyString);
|
|
EXPECT_EQ(JSTaggedValue::SameValue(func, res1.GetValue()), true);
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, InheritPrototype_004)
|
|
{
|
|
LocalScope scope(vm_);
|
|
JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
|
|
auto factory = vm_->GetFactory();
|
|
|
|
JSHandle<JSTaggedValue> weakSet = env->GetBuiltinsWeakSetFunction();
|
|
JSHandle<JSTaggedValue> deleteString(factory->NewFromCanBeCompressString("delete"));
|
|
JSHandle<JSTaggedValue> addString(factory->NewFromCanBeCompressString("add"));
|
|
JSHandle<JSTaggedValue> defaultString = thread_->GlobalConstants()->GetHandledDefaultString();
|
|
JSHandle<JSTaggedValue> deleteMethod = JSObject::GetMethod(thread_, weakSet, deleteString);
|
|
JSHandle<JSTaggedValue> addMethod = JSObject::GetMethod(thread_, weakSet, addString);
|
|
|
|
JSMethod *invokeSelf =
|
|
vm_->GetMethodForNativeFunction(reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf));
|
|
JSMethod *ctor = vm_->GetMethodForNativeFunction(reinterpret_cast<void *>(BuiltinsFunction::FunctionConstructor));
|
|
|
|
JSHandle<JSHClass> protoDynclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithProto());
|
|
JSHandle<JSFunction> funcFuncPrototype = factory->NewJSFunctionByDynClass(invokeSelf, protoDynclass);
|
|
// add method in funcPrototype
|
|
PropertyDescriptor desc = PropertyDescriptor(thread_, deleteMethod);
|
|
JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(funcFuncPrototype), deleteString, desc);
|
|
JSHandle<JSTaggedValue> funcFuncPrototypeValue(funcFuncPrototype);
|
|
|
|
JSHandle<JSHClass> funcFuncProtoIntanceDynclass =
|
|
factory->NewEcmaDynClass(JSFunction::SIZE, JSType::JS_FUNCTION, funcFuncPrototypeValue);
|
|
// new with NewJSFunctionByDynClass::function DynClass
|
|
JSHandle<JSFunction> protoFunc =
|
|
factory->NewJSFunctionByDynClass(ctor, funcFuncProtoIntanceDynclass, FunctionKind::BUILTIN_CONSTRUCTOR);
|
|
EXPECT_TRUE(*protoFunc != nullptr);
|
|
// add method in funcnction
|
|
PropertyDescriptor desc1 = PropertyDescriptor(thread_, addMethod);
|
|
JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(protoFunc), addString, desc1);
|
|
JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(protoFunc), deleteString, desc);
|
|
// father type
|
|
Local<FunctionRef> protoLocal = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(protoFunc));
|
|
|
|
JSHandle<JSHClass> noProtoDynclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutProto());
|
|
JSHandle<JSFunction> funcFuncNoProtoPrototype = factory->NewJSFunctionByDynClass(invokeSelf, noProtoDynclass);
|
|
JSHandle<JSTaggedValue> funcFuncNoProtoPrototypeValue(funcFuncNoProtoPrototype);
|
|
|
|
JSHandle<JSHClass> funcFuncNoProtoProtoIntanceDynclass =
|
|
factory->NewEcmaDynClass(JSFunction::SIZE, JSType::JS_FUNCTION, funcFuncNoProtoPrototypeValue);
|
|
// new with NewJSFunctionByDynClass::function DynClass
|
|
JSHandle<JSFunction> noProtoFunc =
|
|
factory->NewJSFunctionByDynClass(ctor, funcFuncNoProtoProtoIntanceDynclass, FunctionKind::BUILTIN_CONSTRUCTOR);
|
|
EXPECT_TRUE(*noProtoFunc != nullptr);
|
|
// set property that has same key with fater type
|
|
PropertyDescriptor desc2 = PropertyDescriptor(thread_, defaultString);
|
|
JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(noProtoFunc), addString, desc2);
|
|
// son type
|
|
Local<FunctionRef> noProtoLocal = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(noProtoFunc));
|
|
|
|
noProtoLocal->Inherit(vm_, protoLocal);
|
|
|
|
JSHandle<JSFunction> sonHandle = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(noProtoLocal));
|
|
OperationResult res = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(sonHandle), deleteString);
|
|
EXPECT_EQ(JSTaggedValue::SameValue(deleteMethod, res.GetValue()), true);
|
|
// test if the property value changed after inherit
|
|
OperationResult res1 = JSObject::GetProperty(thread_, JSHandle<JSObject>::Cast(sonHandle), addString);
|
|
EXPECT_EQ(JSTaggedValue::SameValue(defaultString, res1.GetValue()), true);
|
|
}
|
|
|
|
HWTEST_F_L0(JSNApiTests, ClassFunction)
|
|
{
|
|
LocalScope scope(vm_);
|
|
Local<FunctionRef> cls = FunctionRef::NewClassFunction(vm_, nullptr, nullptr, nullptr);
|
|
|
|
JSHandle<JSTaggedValue> clsObj = JSNApiHelper::ToJSHandle(Local<JSValueRef>(cls));
|
|
ASSERT_TRUE(clsObj->IsClassConstructor());
|
|
|
|
JSTaggedValue accessor = JSHandle<JSFunction>(clsObj)->GetPropertyInlinedProps(
|
|
JSFunction::CLASS_PROTOTYPE_INLINE_PROPERTY_INDEX);
|
|
ASSERT_TRUE(accessor.IsInternalAccessor());
|
|
}
|
|
} // namespace panda::test
|