From d9656003a325c4bebaf91c96eff024ec1dc5248a Mon Sep 17 00:00:00 2001 From: Alexander Fenster Date: Fri, 26 Aug 2022 16:45:23 +0000 Subject: [PATCH 1/2] feat: accept unknown enum values in fromObject --- src/converter.js | 12 +++++++++--- tests/api_converters.js | 7 ++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/converter.js b/src/converter.js index d0467dcd2..85c527e80 100644 --- a/src/converter.js +++ b/src/converter.js @@ -23,8 +23,14 @@ function genValuePartial_fromObject(gen, field, fieldIndex, prop) { if (field.resolvedType instanceof Enum) { gen ("switch(d%s){", prop); for (var values = field.resolvedType.values, keys = Object.keys(values), i = 0; i < keys.length; ++i) { - if (field.repeated && values[keys[i]] === field.typeDefault) gen - ("default:"); + // enum unknown values passthrough + if (values[keys[i]] === field.typeDefault) { gen + ("default:") + ("if(typeof(d%s)===\"number\"){m%s=d%s;break}", prop, prop, prop); + if (!field.repeated) gen // fallback to default value only for + // arrays, to avoid leaving holes. + ("break") // for non-repeated fields, just ignore + } gen ("case%j:", keys[i]) ("case %i:", values[keys[i]]) @@ -156,7 +162,7 @@ function genValuePartial_toObject(gen, field, fieldIndex, prop) { /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */ if (field.resolvedType) { if (field.resolvedType instanceof Enum) gen - ("d%s=o.enums===String?types[%i].values[m%s]:m%s", prop, fieldIndex, prop, prop); + ("d%s=o.enums===String?(types[%i].values[m%s]===undefined?m%s:types[%i].values[m%s]):m%s", prop, fieldIndex, prop, prop, fieldIndex, prop, prop); else gen ("d%s=types[%i].toObject(m%s,o)", prop, fieldIndex, prop); } else { diff --git a/tests/api_converters.js b/tests/api_converters.js index ccfd68be6..0ad9010d1 100644 --- a/tests/api_converters.js +++ b/tests/api_converters.js @@ -103,7 +103,7 @@ tape.test("converters", function(test) { bytesVal: buf, bytesRepeated: [buf, buf], enumVal: 2, - enumRepeated: [1, 2], + enumRepeated: [1, 100, 2], int64Map: { a: protobuf.util.Long.fromNumber(2), b: protobuf.util.Long.fromNumber(3) @@ -127,6 +127,7 @@ tape.test("converters", function(test) { test.ok(Buffer.isBuffer(Message.toObject(msg, { bytes: Buffer }).bytesVal), "bytes to buffers"); test.equal(Message.toObject(msg, { enums: String }).enumVal, "TWO", "enums to strings"); + test.equal(Message.toObject(msg, { enums: String }).enumRepeated[1], 100, "enums to strings does not change unknown values"); test.end(); }); @@ -157,7 +158,7 @@ tape.test("converters", function(test) { bytesVal: "MTEx", bytesRepeated: ["MTEx", [49, 49, 49]], enumVal: "ONE", - enumRepeated: [2, "TWO"], + enumRepeated: [2, "TWO", 100], int64Map: { a: 2, b: "3" @@ -176,7 +177,7 @@ tape.test("converters", function(test) { test.same(msg.bytesVal, buf, "should set bytesVal from a base64 string"); test.same(msg.bytesRepeated, [ buf, buf ], "should set bytesRepeated from a base64 string and a plain array"); test.equal(msg.enumVal, 1, "should set enumVal from a string"); - test.same(msg.enumRepeated, [ 2, 2 ], "should set enumRepeated from a number and a string"); + test.same(msg.enumRepeated, [ 2, 2, 100 ], "should set enumRepeated from a number and a string and preserve unknown value"); test.same(msg.int64Map, { a: { low: 2, high: 0, unsigned: false }, b: { low: 3, high: 0, unsigned: false } }, "should set int64Map from a number and a string"); test.end(); From 827c457bd7f370ab0272e2e7daed6b430d0b3e71 Mon Sep 17 00:00:00 2001 From: Alexander Fenster Date: Fri, 26 Aug 2022 17:42:18 +0000 Subject: [PATCH 2/2] fix: lint --- src/converter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/converter.js b/src/converter.js index 85c527e80..a043ceef8 100644 --- a/src/converter.js +++ b/src/converter.js @@ -29,7 +29,7 @@ function genValuePartial_fromObject(gen, field, fieldIndex, prop) { ("if(typeof(d%s)===\"number\"){m%s=d%s;break}", prop, prop, prop); if (!field.repeated) gen // fallback to default value only for // arrays, to avoid leaving holes. - ("break") // for non-repeated fields, just ignore + ("break"); // for non-repeated fields, just ignore } gen ("case%j:", keys[i])