Test and fix AsyncWorker by jasongin · Pull Request #30 · nodejs/node-addon-api · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 39 additions & 53 deletions napi-inl.h
25 changes: 10 additions & 15 deletions napi.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef SRC_NAPI_H_
#ifndef SRC_NAPI_H_
#define SRC_NAPI_H_

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -401,8 +401,6 @@ namespace Napi {
Value Call(napi_value recv, const std::initializer_list<napi_value>& args) const;
Value Call(napi_value recv, const std::vector<napi_value>& args) const;

Value MakeCallback(const std::initializer_list<napi_value>& args) const;
Value MakeCallback(const std::vector<napi_value>& args) const;
Value MakeCallback(napi_value recv, const std::initializer_list<napi_value>& args) const;
Value MakeCallback(napi_value recv, const std::vector<napi_value>& args) const;

Expand Down Expand Up @@ -548,8 +546,6 @@ namespace Napi {
Napi::Value Call(napi_value recv, const std::initializer_list<napi_value>& args) const;
Napi::Value Call(napi_value recv, const std::vector<napi_value>& args) const;

Napi::Value MakeCallback(const std::initializer_list<napi_value>& args) const;
Napi::Value MakeCallback(const std::vector<napi_value>& args) const;
Napi::Value MakeCallback(napi_value recv, const std::initializer_list<napi_value>& args) const;
Napi::Value MakeCallback(napi_value recv, const std::vector<napi_value>& args) const;

Expand Down Expand Up @@ -966,21 +962,18 @@ namespace Napi {
void Queue();
void Cancel();

virtual void Execute() = 0;
virtual void WorkComplete();

ObjectReference& Persistent();
ObjectReference& Receiver();
FunctionReference& Callback();

protected:
explicit AsyncWorker(const Function& callback);
explicit AsyncWorker(const Object& receiver, const Function& callback);

virtual void Execute() = 0;
virtual void OnOK();
virtual void OnError(Error e);
virtual void OnError(Error& e);

void SetError(Error error);

FunctionReference _callback;
ObjectReference _persistent;
void SetError(const std::string& error);

private:
static void OnExecute(napi_env env, void* this_pointer);
Expand All @@ -990,7 +983,9 @@ namespace Napi {

napi_env _env;
napi_async_work _work;
Error _error;
ObjectReference _receiver;
FunctionReference _callback;
std::string _error;
};

} // namespace Napi
Expand Down
34 changes: 34 additions & 0 deletions test/asyncworker.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "napi.h"

using namespace Napi;

class TestWorker : public AsyncWorker {
public:
static void DoWork(const CallbackInfo& info) {
bool succeed = info[0].As<Boolean>();
Function cb = info[1].As<Function>();
Value data = info[2];

TestWorker* worker = new TestWorker(cb);
worker->Receiver().Set("data", data);
worker->_succeed = succeed;
worker->Queue();
}

protected:
void Execute() override {
if (!_succeed) {
SetError("test error");
}
}

private:
TestWorker(Function cb) : AsyncWorker(cb) {}
bool _succeed;
};

Object InitAsyncWorker(Env env) {
Object exports = Object::New(env);
exports["doWork"] = Function::New(env, TestWorker::DoWork);
return exports;
}
25 changes: 25 additions & 0 deletions test/asyncworker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;
const binding = require(`./build/${buildType}/binding.node`);
const assert = require('assert');

// Use setTimeout() when asserting after async callbacks because
// unhandled JS exceptions in async callbacks are currently ignored.
// See the TODO comment in AsyncWorker::OnWorkComplete().

binding.asyncworker.doWork(true, function (e) {
setTimeout(() => {
assert.strictEqual(typeof e, 'undefined');
assert.strictEqual(typeof this, 'object');
assert.strictEqual(this.data, 'test data');
});
}, 'test data');

binding.asyncworker.doWork(false, function (e) {
setTimeout(() => {
assert.ok(e instanceof Error);
assert.strictEqual(e.message, 'test error');
assert.strictEqual(typeof this, 'object');
assert.strictEqual(this.data, 'test data');
});
}, 'test data');
2 changes: 2 additions & 0 deletions test/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using namespace Napi;

Object InitArrayBuffer(Env env);
Object InitAsyncWorker(Env env);
Object InitBuffer(Env env);
Object InitError(Env env);
Object InitExternal(Env env);
Expand All @@ -12,6 +13,7 @@ Object InitObject(Env env);

void Init(Env env, Object exports, Object module) {
exports.Set("arraybuffer", InitArrayBuffer(env));
exports.Set("asyncworker", InitAsyncWorker(env));
exports.Set("buffer", InitBuffer(env));
exports.Set("error", InitError(env));
exports.Set("external", InitExternal(env));
Expand Down
1 change: 1 addition & 0 deletions test/binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
'target_name': 'binding',
'sources': [
'arraybuffer.cc',
'asyncworker.cc',
'binding.cc',
'buffer.cc',
'error.cc',
Expand Down
1 change: 1 addition & 0 deletions test/index.js