Skip to content

Commit e87b9d3

Browse files
committedApr 29, 2021
fix: fromObject should not initialize oneof members (#1597)
* test: adding test for pbjs static code generation * fix: fromObject should not initialize oneof members
1 parent c39195c commit e87b9d3

File tree

3 files changed

+92
-5
lines changed

3 files changed

+92
-5
lines changed
 

‎cli/targets/static.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,7 @@ function buildType(ref, type) {
390390
if (config.comments) {
391391
push("");
392392
var jsType = toJsType(field);
393-
if (field.optional && !field.map && !field.repeated && field.resolvedType instanceof Type ||
394-
field.options && field.options.proto3_optional)
393+
if (field.optional && !field.map && !field.repeated && field.resolvedType instanceof Type || field.partOf)
395394
jsType = jsType + "|null|undefined";
396395
pushComment([
397396
field.comment || type.name + " " + field.name + ".",
@@ -407,9 +406,8 @@ function buildType(ref, type) {
407406
push(escapeName(type.name) + ".prototype" + prop + " = $util.emptyArray;"); // overwritten in constructor
408407
else if (field.map)
409408
push(escapeName(type.name) + ".prototype" + prop + " = $util.emptyObject;"); // overwritten in constructor
410-
else if (field.options && field.options.proto3_optional) {
411-
push(escapeName(type.name) + ".prototype" + prop + " = null;"); // do not set default value for proto3 optional fields
412-
}
409+
else if (field.partOf)
410+
push(escapeName(type.name) + ".prototype" + prop + " = null;"); // do not set default value for oneof members
413411
else if (field.long)
414412
push(escapeName(type.name) + ".prototype" + prop + " = $util.Long ? $util.Long.fromBits("
415413
+ JSON.stringify(field.typeDefault.low) + ","

‎tests/cli.js

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// A minimal test for pbjs tool targets.
2+
3+
var tape = require("tape");
4+
var path = require("path");
5+
var Module = require("module");
6+
var protobuf = require("..");
7+
8+
tape.test("pbjs generates static code", function(test) {
9+
// pbjs does not seem to work with Node v4, so skip this test if we're running on it
10+
if (process.versions.node.match(/^4\./)) {
11+
test.end();
12+
return;
13+
}
14+
15+
// Alter the require cache to make the cli/targets/static work since it requires "protobufjs"
16+
// and we don't want to mess with "npm link"
17+
var savedResolveFilename = Module._resolveFilename;
18+
Module._resolveFilename = function(request, parent) {
19+
if (request.startsWith("protobufjs")) {
20+
return request;
21+
}
22+
return savedResolveFilename(request, parent);
23+
};
24+
require.cache.protobufjs = require.cache[path.resolve("index.js")];
25+
26+
var staticTarget = require("../cli/targets/static");
27+
28+
var root = protobuf.loadSync("tests/data/cli/test.proto");
29+
root.resolveAll();
30+
31+
staticTarget(root, {
32+
create: true,
33+
decode: true,
34+
encode: true,
35+
convert: true,
36+
}, function(err, jsCode) {
37+
test.error(err, 'static code generation worked');
38+
39+
// jsCode is the generated code; we'll eval it
40+
// (since this is what we normally does with the code, right?)
41+
// This is a test code. Do not use this in production.
42+
var $protobuf = protobuf;
43+
eval(jsCode);
44+
45+
var OneofContainer = protobuf.roots.default.OneofContainer;
46+
var Message = protobuf.roots.default.Message;
47+
test.ok(OneofContainer, "type is loaded");
48+
test.ok(Message, "type is loaded");
49+
50+
// Check that fromObject and toObject work for plain object
51+
var obj = {
52+
messageInOneof: {
53+
value: 42,
54+
},
55+
regularField: "abc",
56+
};
57+
var obj1 = OneofContainer.toObject(OneofContainer.fromObject(obj));
58+
test.deepEqual(obj, obj1, "fromObject and toObject work for plain object");
59+
60+
// Check that dynamic fromObject and toObject work for static instance
61+
var root = protobuf.loadSync("tests/data/cli/test.proto");
62+
var OneofContainerDynamic = root.lookup("OneofContainer");
63+
var instance = new OneofContainer();
64+
instance.messageInOneof = new Message();
65+
instance.messageInOneof.value = 42;
66+
instance.regularField = "abc";
67+
var instance1 = OneofContainerDynamic.toObject(OneofContainerDynamic.fromObject(instance));
68+
test.deepEqual(instance, instance1, "fromObject and toObject work for instance of the static type");
69+
70+
test.end();
71+
});
72+
73+
// Rollback all the require() related mess we made
74+
delete require.cache.protobufjs;
75+
Module._resolveFilename = savedResolveFilename;
76+
});

‎tests/data/cli/test.proto

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
syntax = "proto3";
2+
3+
message Message {
4+
int32 value = 1;
5+
}
6+
7+
message OneofContainer {
8+
oneof some_oneof {
9+
string string_in_oneof = 1;
10+
Message message_in_oneof = 2;
11+
}
12+
string regular_field = 3;
13+
}

0 commit comments

Comments
 (0)
Please sign in to comment.