#include #include "napi.h" #include "test_helper.h" using namespace Napi; namespace { int testData = 1; Boolean EmptyConstructor(const CallbackInfo& info) { auto env = info.Env(); bool isEmpty = info[0].As(); Function function = isEmpty ? Function() : Function(env, Object::New(env)); return Boolean::New(env, function.IsEmpty()); } void VoidCallback(const CallbackInfo& info) { auto env = info.Env(); Object obj = info[0].As(); obj["foo"] = String::New(env, "bar"); } Value ValueCallback(const CallbackInfo& info) { auto env = info.Env(); Object obj = Object::New(env); obj["foo"] = String::New(env, "bar"); return obj; } void VoidCallbackWithData(const CallbackInfo& info) { auto env = info.Env(); Object obj = info[0].As(); obj["foo"] = String::New(env, "bar"); int* data = static_cast(info.Data()); obj["data"] = Number::New(env, *data); } Value ValueCallbackWithData(const CallbackInfo& info) { auto env = info.Env(); Object obj = Object::New(env); obj["foo"] = String::New(env, "bar"); int* data = static_cast(info.Data()); obj["data"] = Number::New(env, *data); return obj; } Value CallWithArgs(const CallbackInfo& info) { Function func = info[0].As(); return MaybeUnwrap( func.Call(std::initializer_list{info[1], info[2], info[3]})); } Value CallWithVector(const CallbackInfo& info) { Function func = info[0].As(); std::vector args; args.reserve(3); args.push_back(info[1]); args.push_back(info[2]); args.push_back(info[3]); return MaybeUnwrap(func.Call(args)); } Value CallWithVectorUsingCppWrapper(const CallbackInfo& info) { Function func = info[0].As(); std::vector args; args.reserve(3); args.push_back(info[1]); args.push_back(info[2]); args.push_back(info[3]); return MaybeUnwrap(func.Call(args)); } Value CallWithCStyleArray(const CallbackInfo& info) { Function func = info[0].As(); std::vector args; args.reserve(3); args.push_back(info[1]); args.push_back(info[2]); args.push_back(info[3]); return MaybeUnwrap(func.Call(args.size(), args.data())); } Value CallWithReceiverAndCStyleArray(const CallbackInfo& info) { Function func = info[0].As(); Value receiver = info[1]; std::vector args; args.reserve(3); args.push_back(info[2]); args.push_back(info[3]); args.push_back(info[4]); return MaybeUnwrap(func.Call(receiver, args.size(), args.data())); } Value CallWithReceiverAndArgs(const CallbackInfo& info) { Function func = info[0].As(); Value receiver = info[1]; return MaybeUnwrap(func.Call( receiver, std::initializer_list{info[2], info[3], info[4]})); } Value CallWithReceiverAndVector(const CallbackInfo& info) { Function func = info[0].As(); Value receiver = info[1]; std::vector args; args.reserve(3); args.push_back(info[2]); args.push_back(info[3]); args.push_back(info[4]); return MaybeUnwrap(func.Call(receiver, args)); } Value CallWithReceiverAndVectorUsingCppWrapper(const CallbackInfo& info) { Function func = info[0].As(); Value receiver = info[1]; std::vector args; args.reserve(3); args.push_back(info[2]); args.push_back(info[3]); args.push_back(info[4]); return MaybeUnwrap(func.Call(receiver, args)); } Value CallWithInvalidReceiver(const CallbackInfo& info) { Function func = info[0].As(); return MaybeUnwrapOr(func.Call(Value(), std::initializer_list{}), Value()); } Value CallConstructorWithArgs(const CallbackInfo& info) { Function func = info[0].As(); return MaybeUnwrap( func.New(std::initializer_list{info[1], info[2], info[3]})); } Value CallConstructorWithVector(const CallbackInfo& info) { Function func = info[0].As(); std::vector args; args.reserve(3); args.push_back(info[1]); args.push_back(info[2]); args.push_back(info[3]); return MaybeUnwrap(func.New(args)); } Value CallConstructorWithCStyleArray(const CallbackInfo& info) { Function func = info[0].As(); std::vector args; args.reserve(3); args.push_back(info[1]); args.push_back(info[2]); args.push_back(info[3]); return MaybeUnwrap(func.New(args.size(), args.data())); } void IsConstructCall(const CallbackInfo& info) { Function callback = info[0].As(); bool isConstructCall = info.IsConstructCall(); callback({Napi::Boolean::New(info.Env(), isConstructCall)}); } void MakeCallbackWithArgs(const CallbackInfo& info) { Env env = info.Env(); Function callback = info[0].As(); Object resource = info[1].As(); AsyncContext context(env, "function_test_context", resource); callback.MakeCallback( resource, std::initializer_list{info[2], info[3], info[4]}, context); } void MakeCallbackWithVector(const CallbackInfo& info) { Env env = info.Env(); Function callback = info[0].As(); Object resource = info[1].As(); AsyncContext context(env, "function_test_context", resource); std::vector args; args.reserve(3); args.push_back(info[2]); args.push_back(info[3]); args.push_back(info[4]); callback.MakeCallback(resource, args, context); } void MakeCallbackWithCStyleArray(const CallbackInfo& info) { Env env = info.Env(); Function callback = info[0].As(); Object resource = info[1].As(); AsyncContext context(env, "function_test_context", resource); std::vector args; args.reserve(3); args.push_back(info[2]); args.push_back(info[3]); args.push_back(info[4]); callback.MakeCallback(resource, args.size(), args.data(), context); } void MakeCallbackWithInvalidReceiver(const CallbackInfo& info) { Function callback = info[0].As(); callback.MakeCallback(Value(), std::initializer_list{}); } Value CallWithFunctionOperator(const CallbackInfo& info) { Function func = info[0].As(); return MaybeUnwrap(func({info[1], info[2], info[3]})); } } // end anonymous namespace Object InitFunction(Env env) { Object result = Object::New(env); Object exports = Object::New(env); exports["emptyConstructor"] = Function::New(env, EmptyConstructor); exports["voidCallback"] = Function::New(env, VoidCallback, "voidCallback"); exports["valueCallback"] = Function::New(env, ValueCallback, std::string("valueCallback")); exports["voidCallbackWithData"] = Function::New(env, VoidCallbackWithData, nullptr, &testData); exports["valueCallbackWithData"] = Function::New(env, ValueCallbackWithData, nullptr, &testData); exports["callWithArgs"] = Function::New(env, CallWithArgs); exports["callWithVector"] = Function::New(env, CallWithVector); exports["callWithVectorUsingCppWrapper"] = Function::New(env, CallWithVectorUsingCppWrapper); exports["callWithCStyleArray"] = Function::New(env, CallWithCStyleArray); exports["callWithReceiverAndCStyleArray"] = Function::New(env, CallWithReceiverAndCStyleArray); exports["callWithReceiverAndArgs"] = Function::New(env, CallWithReceiverAndArgs); exports["callWithReceiverAndVector"] = Function::New(env, CallWithReceiverAndVector); exports["callWithReceiverAndVectorUsingCppWrapper"] = Function::New(env, CallWithReceiverAndVectorUsingCppWrapper); exports["callWithInvalidReceiver"] = Function::New(env, CallWithInvalidReceiver); exports["callConstructorWithArgs"] = Function::New(env, CallConstructorWithArgs); exports["callConstructorWithVector"] = Function::New(env, CallConstructorWithVector); exports["callConstructorWithCStyleArray"] = Function::New(env, CallConstructorWithCStyleArray); exports["isConstructCall"] = Function::New(env, IsConstructCall); exports["makeCallbackWithArgs"] = Function::New(env, MakeCallbackWithArgs); exports["makeCallbackWithVector"] = Function::New(env, MakeCallbackWithVector); exports["makeCallbackWithCStyleArray"] = Function::New(env, MakeCallbackWithCStyleArray); exports["makeCallbackWithInvalidReceiver"] = Function::New(env, MakeCallbackWithInvalidReceiver); exports["callWithFunctionOperator"] = Function::New(env, CallWithFunctionOperator); result["plain"] = exports; exports = Object::New(env); exports["emptyConstructor"] = Function::New(env, EmptyConstructor); exports["voidCallback"] = Function::New(env, "voidCallback"); exports["valueCallback"] = Function::New(env, std::string("valueCallback")); exports["voidCallbackWithData"] = Function::New(env, nullptr, &testData); exports["valueCallbackWithData"] = Function::New(env, nullptr, &testData); exports["callWithArgs"] = Function::New(env); exports["callWithVector"] = Function::New(env); exports["callWithVectorUsingCppWrapper"] = Function::New(env); exports["callWithCStyleArray"] = Function::New(env); exports["callWithReceiverAndCStyleArray"] = Function::New(env); exports["callWithReceiverAndArgs"] = Function::New(env); exports["callWithReceiverAndVector"] = Function::New(env); exports["callWithReceiverAndVectorUsingCppWrapper"] = Function::New(env); exports["callWithInvalidReceiver"] = Function::New(env); exports["callConstructorWithArgs"] = Function::New(env); exports["callConstructorWithVector"] = Function::New(env); exports["callConstructorWithCStyleArray"] = Function::New(env); exports["isConstructCall"] = Function::New(env); exports["makeCallbackWithArgs"] = Function::New(env); exports["makeCallbackWithVector"] = Function::New(env); exports["makeCallbackWithCStyleArray"] = Function::New(env); exports["makeCallbackWithInvalidReceiver"] = Function::New(env); exports["callWithFunctionOperator"] = Function::New(env); result["templated"] = exports; exports = Object::New(env); exports["lambdaWithNoCapture"] = Function::New(env, [](const CallbackInfo& info) { auto env = info.Env(); return Boolean::New(env, true); }); exports["lambdaWithCapture"] = Function::New(env, [data = 42](const CallbackInfo& info) { auto env = info.Env(); return Boolean::New(env, data == 42); }); exports["lambdaWithMoveOnlyCapture"] = Function::New( env, [data = std::make_unique(42)](const CallbackInfo& info) { auto env = info.Env(); return Boolean::New(env, *data == 42); }); result["lambda"] = exports; return result; }