var tape = require("tape"); var protobuf = require(".."); var proto = "syntax = \"proto3\";\ package myservice;\ message DoSomethingRequest {\ }\ message DoSomethingResponse {\ }\ service MyService {\ rpc DoSomething(DoSomethingRequest) returns (DoSomethingResponse) {\ option (google.api.http) = {\ get: \"/v1/dosomething\"\ };\ };\ }"; tape.test("reflected services", function(test) { var root = protobuf.parse(proto).root; var myservice = root.lookup("myservice").resolveAll(), MyService = myservice.MyService, DoSomethingRequest = myservice.DoSomethingRequest, DoSomethingResponse = myservice.DoSomethingResponse, DoSomething = MyService.get("DoSomething"); test.throws(function() { MyService.create(); }, TypeError, "should throw if rpcImpl is not specified"); function rpcImpl(method, requestData, callback) { if (requestData) { test.equal(method, DoSomething, "rpcImpl should reference the correct method"); test.ok(callback, "rpcImpl should provide a callback"); setTimeout(function() { callback(null, DoSomethingResponse.create()); }); } else { test.equal(method, null, "rpcImpl should not reference a method when closed"); test.equal(callback, null, "rpcImpl should not provide a callback when closed"); } } var service = MyService.create(rpcImpl); test.throws(function() { service.doSomething(); }, TypeError, "should throw if request is not specified"); test.test(test.name + " - should propagate errors from rpcImpl", function(test) { var err = Error(); var service2 = MyService.create(function(method, requestData, callback) { callback(err); }); var count = 0; service2.on("error", function(err2) { test.equal(err2, err, "should emit the exact error"); if (++count === 2) test.end(); }); service2.doSomething({}, function(err2) { test.equal(err2, err, "should return the exact error"); if (++count === 2) test.end(); }); }); test.test(test.name + " - should catch errors within rpcImpl", function(test) { var err = Error(); var service2 = MyService.create(function(method, requestData, callback) { throw err; }); var count = 0; service2.on("error", function(err2) { test.equal(err2, err, "should emit the exact error"); if (++count === 2) test.end(); }); service2.doSomething({}, function(err2) { test.equal(err2, err, "should return the exact error"); if (++count === 2) test.end(); }); }); test.test(test.name + " - should return errors from decoding", function(test) { var service2 = MyService.create(function(method, requestData, callback) { callback(null, protobuf.util.newBuffer(0) ); }, true, true); var count = 0; service2.on("error", function(err2) { test.ok(err2, "should emit the error"); if (++count === 2) test.end(); }); service2.doSomething({}, function(err2) { test.ok(err2, "should return the error"); if (++count === 2) test.end(); }); }); var dataEmitted = false; service.on("data", function(responseData) { dataEmitted = true; test.ok(responseData, "should emit the data event"); }); var endCalled = false; service.on("end", function() { test.notOk(endCalled, "should not emit the end event twice"); endCalled = true; test.pass("should call the end event"); service.end(); test.end(); }); service.doSomething(DoSomethingRequest.create(), function(err, res) { test.notOk(err, "should not raise an error"); test.ok(res instanceof DoSomethingResponse.ctor, "should return a properly typed response"); test.ok(dataEmitted, "should have emitted the data event"); service.end(); }); });