From 3d29969865f2119550d9dc88391846469da9fa7f Mon Sep 17 00:00:00 2001 From: Alexander Fenster Date: Fri, 13 Nov 2020 15:51:07 -0800 Subject: [PATCH] fix: make parsedOptions appear in method JSON representation (#1506) --- src/method.js | 15 +++++++++++--- tests/comp_options-parse.js | 39 +++++++++++++++++++++++++++++++++++ tests/data/options_test.proto | 34 +++++++++++++++++++++++++++++- 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/src/method.js b/src/method.js index f5159225f..18a6ab2cf 100644 --- a/src/method.js +++ b/src/method.js @@ -20,8 +20,9 @@ var util = require("./util"); * @param {boolean|Object.} [responseStream] Whether the response is streamed * @param {Object.} [options] Declared options * @param {string} [comment] The comment for this method + * @param {Object.} [parsedOptions] Declared options, properly parsed into an object */ -function Method(name, type, requestType, responseType, requestStream, responseStream, options, comment) { +function Method(name, type, requestType, responseType, requestStream, responseStream, options, comment, parsedOptions) { /* istanbul ignore next */ if (util.isObject(requestStream)) { @@ -93,6 +94,11 @@ function Method(name, type, requestType, responseType, requestStream, responseSt * @type {string|null} */ this.comment = comment; + + /** + * Options properly parsed into an object + */ + this.parsedOptions = parsedOptions; } /** @@ -104,6 +110,8 @@ function Method(name, type, requestType, responseType, requestStream, responseSt * @property {boolean} [requestStream=false] Whether requests are streamed * @property {boolean} [responseStream=false] Whether responses are streamed * @property {Object.} [options] Method options + * @property {string} comment Method comments + * @property {Object.} [parsedOptions] Method options properly parsed into an object */ /** @@ -114,7 +122,7 @@ function Method(name, type, requestType, responseType, requestStream, responseSt * @throws {TypeError} If arguments are invalid */ Method.fromJSON = function fromJSON(name, json) { - return new Method(name, json.type, json.requestType, json.responseType, json.requestStream, json.responseStream, json.options, json.comment); + return new Method(name, json.type, json.requestType, json.responseType, json.requestStream, json.responseStream, json.options, json.comment, json.parsedOptions); }; /** @@ -131,7 +139,8 @@ Method.prototype.toJSON = function toJSON(toJSONOptions) { "responseType" , this.responseType, "responseStream" , this.responseStream, "options" , this.options, - "comment" , keepComments ? this.comment : undefined + "comment" , keepComments ? this.comment : undefined, + "parsedOptions" , this.parsedOptions, ]); }; diff --git a/tests/comp_options-parse.js b/tests/comp_options-parse.js index 90c4299c0..a173caf67 100644 --- a/tests/comp_options-parse.js +++ b/tests/comp_options-parse.js @@ -117,5 +117,44 @@ tape.test("Options", function (test) { test.end(); }); + test.test(test.name + " - rpc options (Nested)", function (test) { + var TestOptionsRpc = root.lookup("TestOptionsRpc"); + test.equal(TestOptionsRpc.options["(method_rep_msg).value"], 1, "should merge repeated options messages"); + test.equal(TestOptionsRpc.options["(method_rep_msg).rep_value"], 3, "should parse in any order"); + test.equal(TestOptionsRpc.options["(method_rep_msg).nested.nested.value"], "x", "should correctly parse nested field options"); + test.equal(TestOptionsRpc.options["(method_rep_msg).rep_nested.value"], "z", "should take second repeated nested options"); + test.equal(TestOptionsRpc.options["(method_rep_msg).nested.value"], "w", "should merge nested options"); + + test.equal(TestOptionsRpc.options["(method_single_msg).nested.value"], "x", "should correctly parse nested property name"); + test.equal(TestOptionsRpc.options["(method_single_msg).rep_nested.value"], "y", "should take second repeated nested options"); + test.equal(TestOptionsRpc.options["(method_single_msg).rep_nested.nested.nested.value"], "y", "should correctly parse several nesting levels"); + + var expectedParsedOptions = [ + { + "(method_rep_msg)": { + value: 1, + nested: {nested: {value: "x"}}, + rep_nested: [{value: "y"}, {value: "z"}], + rep_value: 3 + } + }, + {"(method_rep_msg)": {nested: {value: "w"}}}, + { + "(method_single_msg)": { + nested: {value: "x"}, + rep_nested: [{value: "x", nested: {nested: {value: "y"}}}, {value: "y"}] + } + } + ]; + + test.same(TestOptionsRpc.parsedOptions, expectedParsedOptions, "should correctly parse all nested message options"); + var jsonTestOptionsRpc = TestOptionsRpc.toJSON(); + test.same(jsonTestOptionsRpc.parsedOptions, expectedParsedOptions, "should correctly store all nested method options in JSON"); + var rootFromJson = protobuf.Root.fromJSON(root.toJSON()); + var TestOptionsRpcFromJson = rootFromJson.lookup("TestOptionsRpc"); + test.same(TestOptionsRpcFromJson.parsedOptions, expectedParsedOptions, "should correctly read all nested method options from JSON"); + test.end(); + }); + test.end(); }); diff --git a/tests/data/options_test.proto b/tests/data/options_test.proto index 1bdc0e470..15ba65282 100644 --- a/tests/data/options_test.proto +++ b/tests/data/options_test.proto @@ -53,6 +53,11 @@ extend google.protobuf.MessageOptions { Msg mo_single_msg = 50003; } +extend google.protobuf.MethodOptions { + repeated Msg method_rep_msg = 50002; + Msg method_single_msg = 50003; +} + message TestFieldOptionsMsg { string field1 = 1 [(fo_rep_msg) = {value: 1 rep_value: 2 rep_value: 3}, (fo_rep_msg) = {value: 4 rep_value: 5 rep_value: 6}]; string field2 = 2 [(fo_single_msg).value = 7, (fo_single_msg).rep_value = 8, (fo_single_msg).rep_value = 9]; @@ -80,7 +85,6 @@ message TestFieldOptionsNested { string field3 = 3 [(fo_single_msg).nested = {value: "x" nested {nested{value: "y"}}}]; } - message TestMessageOptionsNested { option (mo_rep_msg) = { value: 1 @@ -106,3 +110,31 @@ message TestMessageOptionsNested { option (mo_single_msg).rep_nested = {value : "x" nested {nested{value: "y"}}}; option (mo_single_msg).rep_nested = {value : "y"}; } + +service TestOptionsService { + rpc TestOptionsRpc(Msg) returns (Msg) { + option (method_rep_msg) = { + value: 1 + nested { + nested { + value: "x" + } + } + rep_nested { + value: "y" + } + rep_nested { + value: "z" + } + rep_value: 3 + }; + option (method_rep_msg) = { + nested { + value: "w" + } + }; + option (method_single_msg).nested.value = "x"; + option (method_single_msg).rep_nested = {value : "x" nested {nested{value: "y"}}}; + option (method_single_msg).rep_nested = {value : "y"}; + } +}