Skip to content

Commit ef24ae4

Browse files
feat: accept unknown enum values in fromObject (#1793)
* feat: accept unknown enum values in fromObject * fix: lint
1 parent f36d4e4 commit ef24ae4

File tree

2 files changed

+13
-6
lines changed

2 files changed

+13
-6
lines changed

src/converter.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,14 @@ function genValuePartial_fromObject(gen, field, fieldIndex, prop) {
2323
if (field.resolvedType instanceof Enum) { gen
2424
("switch(d%s){", prop);
2525
for (var values = field.resolvedType.values, keys = Object.keys(values), i = 0; i < keys.length; ++i) {
26-
if (field.repeated && values[keys[i]] === field.typeDefault) gen
27-
("default:");
26+
// enum unknown values passthrough
27+
if (values[keys[i]] === field.typeDefault) { gen
28+
("default:")
29+
("if(typeof(d%s)===\"number\"){m%s=d%s;break}", prop, prop, prop);
30+
if (!field.repeated) gen // fallback to default value only for
31+
// arrays, to avoid leaving holes.
32+
("break"); // for non-repeated fields, just ignore
33+
}
2834
gen
2935
("case%j:", keys[i])
3036
("case %i:", values[keys[i]])
@@ -156,7 +162,7 @@ function genValuePartial_toObject(gen, field, fieldIndex, prop) {
156162
/* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
157163
if (field.resolvedType) {
158164
if (field.resolvedType instanceof Enum) gen
159-
("d%s=o.enums===String?types[%i].values[m%s]:m%s", prop, fieldIndex, prop, prop);
165+
("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);
160166
else gen
161167
("d%s=types[%i].toObject(m%s,o)", prop, fieldIndex, prop);
162168
} else {

tests/api_converters.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ tape.test("converters", function(test) {
103103
bytesVal: buf,
104104
bytesRepeated: [buf, buf],
105105
enumVal: 2,
106-
enumRepeated: [1, 2],
106+
enumRepeated: [1, 100, 2],
107107
int64Map: {
108108
a: protobuf.util.Long.fromNumber(2),
109109
b: protobuf.util.Long.fromNumber(3)
@@ -127,6 +127,7 @@ tape.test("converters", function(test) {
127127
test.ok(Buffer.isBuffer(Message.toObject(msg, { bytes: Buffer }).bytesVal), "bytes to buffers");
128128

129129
test.equal(Message.toObject(msg, { enums: String }).enumVal, "TWO", "enums to strings");
130+
test.equal(Message.toObject(msg, { enums: String }).enumRepeated[1], 100, "enums to strings does not change unknown values");
130131

131132
test.end();
132133
});
@@ -157,7 +158,7 @@ tape.test("converters", function(test) {
157158
bytesVal: "MTEx",
158159
bytesRepeated: ["MTEx", [49, 49, 49]],
159160
enumVal: "ONE",
160-
enumRepeated: [2, "TWO"],
161+
enumRepeated: [2, "TWO", 100],
161162
int64Map: {
162163
a: 2,
163164
b: "3"
@@ -176,7 +177,7 @@ tape.test("converters", function(test) {
176177
test.same(msg.bytesVal, buf, "should set bytesVal from a base64 string");
177178
test.same(msg.bytesRepeated, [ buf, buf ], "should set bytesRepeated from a base64 string and a plain array");
178179
test.equal(msg.enumVal, 1, "should set enumVal from a string");
179-
test.same(msg.enumRepeated, [ 2, 2 ], "should set enumRepeated from a number and a string");
180+
test.same(msg.enumRepeated, [ 2, 2, 100 ], "should set enumRepeated from a number and a string and preserve unknown value");
180181
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");
181182

182183
test.end();

0 commit comments

Comments
 (0)