Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: accept unknown enum values in fromObject #1793

Merged
merged 2 commits into from Aug 26, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/converter.js
Expand Up @@ -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]])
Expand Down Expand Up @@ -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 {
Expand Down
7 changes: 4 additions & 3 deletions tests/api_converters.js
Expand Up @@ -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)
Expand All @@ -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();
});
Expand Down Expand Up @@ -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"
Expand All @@ -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();
Expand Down