blob: 1ee0c9ad72cb0cc6a2ca2712e027e2c56113a6e1 [file] [log] [blame] [edit]
#include <napi.h>
#include "test_helper.h"
Napi::ObjectReference testStaticContextRef;
Napi::Value StaticGetter(const Napi::CallbackInfo& /*info*/) {
return MaybeUnwrap(testStaticContextRef.Value().Get("value"));
}
void StaticSetter(const Napi::CallbackInfo& /*info*/,
const Napi::Value& value) {
testStaticContextRef.Value().Set("value", value);
}
void StaticMethodVoidCb(const Napi::CallbackInfo& info) {
StaticSetter(info, info[0].As<Napi::Number>());
}
Napi::Value TestStaticMethod(const Napi::CallbackInfo& info) {
std::string str = MaybeUnwrap(info[0].ToString());
return Napi::String::New(info.Env(), str + " static");
}
Napi::Value TestStaticMethodInternal(const Napi::CallbackInfo& info) {
std::string str = MaybeUnwrap(info[0].ToString());
return Napi::String::New(info.Env(), str + " static internal");
}
class Test : public Napi::ObjectWrap<Test> {
public:
Test(const Napi::CallbackInfo& info) : Napi::ObjectWrap<Test>(info) {
if (info.Length() > 0) {
finalizeCb_ = Napi::Persistent(info[0].As<Napi::Function>());
}
// Create an own instance property.
info.This().As<Napi::Object>().DefineProperty(
Napi::PropertyDescriptor::Accessor(info.Env(),
info.This().As<Napi::Object>(),
"ownProperty",
OwnPropertyGetter,
napi_enumerable,
this));
// Create an own instance property with a templated function.
info.This().As<Napi::Object>().DefineProperty(
Napi::PropertyDescriptor::Accessor<OwnPropertyGetter>(
"ownPropertyT", napi_enumerable, this));
bufref_ = Napi::Persistent(Napi::Buffer<uint8_t>::New(
Env(),
static_cast<uint8_t*>(malloc(1)),
1,
[](Napi::Env, uint8_t* bufaddr) { free(bufaddr); }));
}
static Napi::Value OwnPropertyGetter(const Napi::CallbackInfo& info) {
return static_cast<Test*>(info.Data())->Getter(info);
}
static Napi::Value CanUnWrap(const Napi::CallbackInfo& info) {
Napi::Object wrappedObject = info[0].As<Napi::Object>();
std::string expectedString = info[1].As<Napi::String>();
Test* nativeObject = Test::Unwrap(wrappedObject);
std::string strVal = MaybeUnwrap(nativeObject->Getter(info).ToString());
return Napi::Boolean::New(info.Env(), strVal == expectedString);
}
void Setter(const Napi::CallbackInfo& /*info*/, const Napi::Value& value) {
value_ = MaybeUnwrap(value.ToString());
}
Napi::Value Getter(const Napi::CallbackInfo& info) {
return Napi::String::New(info.Env(), value_);
}
Napi::Value TestMethod(const Napi::CallbackInfo& info) {
std::string str = MaybeUnwrap(info[0].ToString());
return Napi::String::New(info.Env(), str + " instance");
}
Napi::Value TestMethodInternal(const Napi::CallbackInfo& info) {
std::string str = MaybeUnwrap(info[0].ToString());
return Napi::String::New(info.Env(), str + " instance internal");
}
Napi::Value ToStringTag(const Napi::CallbackInfo& info) {
return Napi::String::From(info.Env(), "TestTag");
}
// creates dummy array, returns `([value])[Symbol.iterator]()`
Napi::Value Iterator(const Napi::CallbackInfo& info) {
Napi::Array array = Napi::Array::New(info.Env());
array.Set(array.Length(), Napi::String::From(info.Env(), value_));
return MaybeUnwrap(
MaybeUnwrap(array.Get(MaybeUnwrap(
Napi::Symbol::WellKnown(info.Env(), "iterator"))))
.As<Napi::Function>()
.Call(array, {}));
}
void TestVoidMethodT(const Napi::CallbackInfo& info) {
value_ = MaybeUnwrap(info[0].ToString());
}
Napi::Value TestMethodT(const Napi::CallbackInfo& info) {
return Napi::String::New(info.Env(), value_);
}
static Napi::Value TestStaticMethodT(const Napi::CallbackInfo& info) {
return Napi::String::New(info.Env(), s_staticMethodText);
}
static void TestStaticVoidMethodT(const Napi::CallbackInfo& info) {
s_staticMethodText = MaybeUnwrap(info[0].ToString());
}
static void Initialize(Napi::Env env, Napi::Object exports) {
Napi::Symbol kTestStaticValueInternal =
Napi::Symbol::New(env, "kTestStaticValueInternal");
Napi::Symbol kTestStaticAccessorInternal =
Napi::Symbol::New(env, "kTestStaticAccessorInternal");
Napi::Symbol kTestStaticAccessorTInternal =
Napi::Symbol::New(env, "kTestStaticAccessorTInternal");
Napi::Symbol kTestStaticMethodInternal =
Napi::Symbol::New(env, "kTestStaticMethodInternal");
Napi::Symbol kTestStaticMethodTInternal =
Napi::Symbol::New(env, "kTestStaticMethodTInternal");
Napi::Symbol kTestStaticVoidMethodTInternal =
Napi::Symbol::New(env, "kTestStaticVoidMethodTInternal");
Napi::Symbol kTestStaticVoidMethodInternal =
Napi::Symbol::New(env, "kTestStaticVoidMethodInternal");
Napi::Symbol kTestValueInternal =
Napi::Symbol::New(env, "kTestValueInternal");
Napi::Symbol kTestAccessorInternal =
Napi::Symbol::New(env, "kTestAccessorInternal");
Napi::Symbol kTestAccessorTInternal =
Napi::Symbol::New(env, "kTestAccessorTInternal");
Napi::Symbol kTestMethodInternal =
Napi::Symbol::New(env, "kTestMethodInternal");
Napi::Symbol kTestMethodTInternal =
Napi::Symbol::New(env, "kTestMethodTInternal");
Napi::Symbol kTestVoidMethodTInternal =
Napi::Symbol::New(env, "kTestVoidMethodTInternal");
exports.Set(
"Test",
DefineClass(
env,
"Test",
{
// expose symbols for testing
StaticValue("kTestStaticValueInternal",
kTestStaticValueInternal),
StaticValue("kTestStaticAccessorInternal",
kTestStaticAccessorInternal),
StaticValue("kTestStaticAccessorTInternal",
kTestStaticAccessorTInternal),
StaticValue("kTestStaticMethodInternal",
kTestStaticMethodInternal),
StaticValue("kTestStaticMethodTInternal",
kTestStaticMethodTInternal),
StaticValue("kTestStaticVoidMethodInternal",
kTestStaticVoidMethodInternal),
StaticValue("kTestStaticVoidMethodTInternal",
kTestStaticVoidMethodTInternal),
StaticValue("kTestValueInternal", kTestValueInternal),
StaticValue("kTestAccessorInternal", kTestAccessorInternal),
StaticValue("kTestAccessorTInternal", kTestAccessorTInternal),
StaticValue("kTestMethodInternal", kTestMethodInternal),
StaticValue("kTestMethodTInternal", kTestMethodTInternal),
StaticValue("kTestVoidMethodTInternal",
kTestVoidMethodTInternal),
// test data
StaticValue("testStaticValue",
Napi::String::New(env, "value"),
napi_enumerable),
StaticValue(kTestStaticValueInternal,
Napi::Number::New(env, 5),
napi_default),
StaticAccessor("testStaticGetter",
&StaticGetter,
nullptr,
napi_enumerable),
StaticAccessor(
"testStaticSetter", nullptr, &StaticSetter, napi_default),
StaticAccessor("testStaticGetSet",
&StaticGetter,
&StaticSetter,
napi_enumerable),
StaticAccessor(kTestStaticAccessorInternal,
&StaticGetter,
&StaticSetter,
napi_enumerable),
StaticAccessor<&StaticGetter>("testStaticGetterT"),
StaticAccessor<&StaticGetter, &StaticSetter>(
"testStaticGetSetT"),
StaticAccessor<&StaticGetter, &StaticSetter>(
kTestStaticAccessorTInternal),
StaticMethod(
"testStaticVoidMethod", &StaticMethodVoidCb, napi_default),
StaticMethod(kTestStaticVoidMethodInternal,
&StaticMethodVoidCb,
napi_default),
StaticMethod(
"testStaticMethod", &TestStaticMethod, napi_enumerable),
StaticMethod(kTestStaticMethodInternal,
&TestStaticMethodInternal,
napi_default),
StaticMethod<&TestStaticVoidMethodT>("testStaticVoidMethodT"),
StaticMethod<&TestStaticMethodT>("testStaticMethodT"),
StaticMethod<&TestStaticVoidMethodT>(
kTestStaticVoidMethodTInternal),
StaticMethod<&TestStaticMethodT>(kTestStaticMethodTInternal),
StaticMethod("canUnWrap", &CanUnWrap, napi_enumerable),
InstanceValue("testValue",
Napi::Boolean::New(env, true),
napi_enumerable),
InstanceValue(kTestValueInternal,
Napi::Boolean::New(env, false),
napi_enumerable),
InstanceAccessor(
"testGetter", &Test::Getter, nullptr, napi_enumerable),
InstanceAccessor(
"testSetter", nullptr, &Test::Setter, napi_default),
InstanceAccessor("testGetSet",
&Test::Getter,
&Test::Setter,
napi_enumerable),
InstanceAccessor(kTestAccessorInternal,
&Test::Getter,
&Test::Setter,
napi_enumerable),
InstanceAccessor<&Test::Getter>("testGetterT"),
InstanceAccessor<&Test::Getter, &Test::Setter>("testGetSetT"),
InstanceAccessor<&Test::Getter, &Test::Setter>(
kTestAccessorInternal),
InstanceMethod(
"testMethod", &Test::TestMethod, napi_enumerable),
InstanceMethod(kTestMethodInternal,
&Test::TestMethodInternal,
napi_default),
InstanceMethod<&Test::TestMethodT>("testMethodT"),
InstanceMethod<&Test::TestVoidMethodT>("testVoidMethodT"),
InstanceMethod<&Test::TestMethodT>(kTestMethodTInternal),
InstanceMethod<&Test::TestVoidMethodT>(
kTestVoidMethodTInternal),
// conventions
InstanceAccessor(
MaybeUnwrap(Napi::Symbol::WellKnown(env, "toStringTag")),
&Test::ToStringTag,
nullptr,
napi_enumerable),
InstanceMethod(
MaybeUnwrap(Napi::Symbol::WellKnown(env, "iterator")),
&Test::Iterator,
napi_default),
}));
}
void Finalize(Napi::Env env) {
if (finalizeCb_.IsEmpty()) {
return;
}
finalizeCb_.Call(env.Global(), {Napi::Boolean::New(env, true)});
finalizeCb_.Unref();
}
private:
std::string value_;
Napi::FunctionReference finalizeCb_;
static std::string s_staticMethodText;
Napi::Reference<Napi::Buffer<uint8_t>> bufref_;
};
std::string Test::s_staticMethodText;
Napi::Object InitObjectWrap(Napi::Env env) {
testStaticContextRef = Napi::Persistent(Napi::Object::New(env));
testStaticContextRef.SuppressDestruct();
Napi::Object exports = Napi::Object::New(env);
Test::Initialize(env, exports);
return exports;
}