Skip to content

Commit b9f1790

Browse files
committed
Breaking: ReflectionObject#toJSON properly omits explicit undefined values
1 parent 6493f52 commit b9f1790

16 files changed

+84
-92
lines changed

src/enum.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ Enum.fromJSON = function fromJSON(name, json) {
7474
* @returns {EnumDescriptor} Enum descriptor
7575
*/
7676
Enum.prototype.toJSON = function toJSON() {
77-
return {
78-
options : this.options,
79-
values : this.values
80-
};
77+
return util.toObject([
78+
"options" , this.options,
79+
"values" , this.values
80+
]);
8181
};
8282

8383
/**

src/field.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,13 @@ Field.prototype.setOption = function setOption(name, value, ifNotSet) {
235235
* @returns {FieldDescriptor} Field descriptor
236236
*/
237237
Field.prototype.toJSON = function toJSON() {
238-
return {
239-
rule : this.rule !== "optional" && this.rule || undefined,
240-
type : this.type,
241-
id : this.id,
242-
extend : this.extend,
243-
options : this.options
244-
};
238+
return util.toObject([
239+
"rule" , this.rule !== "optional" && this.rule || undefined,
240+
"type" , this.type,
241+
"id" , this.id,
242+
"extend" , this.extend,
243+
"options" , this.options
244+
]);
245245
};
246246

247247
/**

src/mapfield.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,13 @@ MapField.fromJSON = function fromJSON(name, json) {
7979
* @returns {MapFieldDescriptor} Map field descriptor
8080
*/
8181
MapField.prototype.toJSON = function toJSON() {
82-
return {
83-
keyType : this.keyType,
84-
type : this.type,
85-
id : this.id,
86-
extend : this.extend,
87-
options : this.options
88-
};
82+
return util.toObject([
83+
"keyType" , this.keyType,
84+
"type" , this.type,
85+
"id" , this.id,
86+
"extend" , this.extend,
87+
"options" , this.options
88+
]);
8989
};
9090

9191
/**

src/method.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,14 @@ Method.fromJSON = function fromJSON(name, json) {
115115
* @returns {MethodDescriptor} Method descriptor
116116
*/
117117
Method.prototype.toJSON = function toJSON() {
118-
return {
119-
type : this.type !== "rpc" && /* istanbul ignore next */ this.type || undefined,
120-
requestType : this.requestType,
121-
requestStream : this.requestStream,
122-
responseType : this.responseType,
123-
responseStream : this.responseStream,
124-
options : this.options
125-
};
118+
return util.toObject([
119+
"type" , this.type !== "rpc" && /* istanbul ignore next */ this.type || undefined,
120+
"requestType" , this.requestType,
121+
"requestStream" , this.requestStream,
122+
"responseType" , this.responseType,
123+
"responseStream" , this.responseStream,
124+
"options" , this.options
125+
]);
126126
};
127127

128128
/**

src/namespace.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,10 @@ Object.defineProperty(Namespace.prototype, "nestedArray", {
131131
* @returns {NamespaceBaseDescriptor} Namespace descriptor
132132
*/
133133
Namespace.prototype.toJSON = function toJSON() {
134-
return {
135-
options : this.options,
136-
nested : arrayToJSON(this.nestedArray)
137-
};
134+
return util.toObject([
135+
"options" , this.options,
136+
"nested" , arrayToJSON(this.nestedArray)
137+
]);
138138
};
139139

140140
/**

src/oneof.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ OneOf.fromJSON = function fromJSON(name, json) {
6666
* @returns {OneOfDescriptor} Oneof descriptor
6767
*/
6868
OneOf.prototype.toJSON = function toJSON() {
69-
return {
70-
oneof : this.oneof,
71-
options : this.options
72-
};
69+
return util.toObject([
70+
"options" , this.options,
71+
"oneof" , this.oneof
72+
]);
7373
};
7474

7575
/**

src/service.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ Service.fromJSON = function fromJSON(name, json) {
6868
*/
6969
Service.prototype.toJSON = function toJSON() {
7070
var inherited = Namespace.prototype.toJSON.call(this);
71-
return {
72-
options : inherited && inherited.options || undefined,
73-
methods : Namespace.arrayToJSON(this.methodsArray) || /* istanbul ignore next */ {},
74-
nested : inherited && inherited.nested || undefined
75-
};
71+
return util.toObject([
72+
"options" , inherited && inherited.options || undefined,
73+
"methods" , Namespace.arrayToJSON(this.methodsArray) || /* istanbul ignore next */ {},
74+
"nested" , inherited && inherited.nested || undefined
75+
]);
7676
};
7777

7878
/**

src/type.js

+9-9
Original file line numberDiff line numberDiff line change
@@ -281,15 +281,15 @@ Type.fromJSON = function fromJSON(name, json) {
281281
*/
282282
Type.prototype.toJSON = function toJSON() {
283283
var inherited = Namespace.prototype.toJSON.call(this);
284-
return {
285-
options : inherited && inherited.options || undefined,
286-
oneofs : Namespace.arrayToJSON(this.oneofsArray),
287-
fields : Namespace.arrayToJSON(this.fieldsArray.filter(function(obj) { return !obj.declaringField; })) || {},
288-
extensions : this.extensions && this.extensions.length ? this.extensions : undefined,
289-
reserved : this.reserved && this.reserved.length ? this.reserved : undefined,
290-
group : this.group || undefined,
291-
nested : inherited && inherited.nested || undefined
292-
};
284+
return util.toObject([
285+
"options" , inherited && inherited.options || undefined,
286+
"oneofs" , Namespace.arrayToJSON(this.oneofsArray),
287+
"fields" , Namespace.arrayToJSON(this.fieldsArray.filter(function(obj) { return !obj.declaringField; })) || {},
288+
"extensions" , this.extensions && this.extensions.length ? this.extensions : undefined,
289+
"reserved" , this.reserved && this.reserved.length ? this.reserved : undefined,
290+
"group" , this.group || undefined,
291+
"nested" , inherited && inherited.nested || undefined
292+
]);
293293
};
294294

295295
/**

src/util.js

+16
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,22 @@ util.toArray = function toArray(object) {
3434
return array;
3535
};
3636

37+
/**
38+
* Converts an array of keys immediately followed by their respective value to an object, omitting undefined values.
39+
* @param {Array.<*>} array Array to convert
40+
* @returns {Object.<string,*>} Converted object
41+
*/
42+
util.toObject = function toObject(array) {
43+
var object = {};
44+
for (var i = 0; i < array.length; i += 2) {
45+
var key = array[i ],
46+
val = array[i + 1];
47+
if (val !== undefined)
48+
object[key] = val;
49+
}
50+
return object;
51+
};
52+
3753
var safePropBackslashRe = /\\/g,
3854
safePropQuoteRe = /"/g;
3955

tests/api_enum.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,11 @@ tape.test("reflected enums", function(test) {
6868
}, "should no longer expose any removed values by id");
6969

7070
test.same(enm.toJSON(), {
71-
options: undefined,
7271
values: {
7372
a: 1,
7473
c: 3
7574
}
76-
}, "should export options and values to JSON");
75+
}, "should export values to JSON");
7776

7877
enm_allow_alias.add( 'b', 0 );
7978
test.same( enm_allow_alias.values, {

tests/api_field.js

-2
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,8 @@ tape.test("reflected fields", function(test) {
4343
field = new protobuf.Field("a", 1, "uint32", /* rule */ undefined, /* skipped extend, */ /* options */ {});
4444

4545
test.same(field.toJSON(), {
46-
rule: undefined,
4746
type: "uint32",
4847
id: 1,
49-
extend: undefined,
5048
options: {}
5149
}, "should export to JSON");
5250

tests/api_mapfield.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ var protobuf = require("..");
55
var def = {
66
keyType: "bytes",
77
type: "string",
8-
id: 1,
9-
extend: undefined,
10-
options: undefined
8+
id: 1
119
};
1210

1311
tape.test("reflected map fields", function(test) {

tests/api_namespace.js

+7-11
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ var tape = require("tape");
22

33
var protobuf = require("..");
44

5-
var def = {
6-
nested: undefined,
7-
options: undefined
8-
};
5+
var def = {};
96

107
var proto = "package ns;\
118
enum Enm {\
@@ -124,13 +121,12 @@ tape.test("reflected namespaces", function(test) {
124121
});
125122
test.same(ns.toJSON(), {
126123
nested: {
127-
Message: { extensions: undefined, fields: {}, group: undefined, nested: undefined, oneofs: undefined, options: undefined, reserved: undefined },
128-
Enum: { options: undefined, values: {} },
129-
Service: { methods: {}, nested: undefined, options: undefined },
130-
extensionField: { extend: "Message", id: 1000, options: undefined, rule: undefined, type: "string" },
131-
Other: { nested: undefined, options: undefined }
132-
},
133-
options: undefined
124+
Message: { fields: {} },
125+
Enum: { values: {} },
126+
Service: { methods: {} },
127+
extensionField: { extend: "Message", id: 1000, type: "string" },
128+
Other: { }
129+
}
134130
}, "should create from Type, Enum, Service, extension Field and Namespace JSON");
135131

136132
test.end();

tests/api_oneof.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,13 @@ tape.test("reflected oneofs", function(test) {
3131

3232
kind.add(field);
3333
test.same(kind.toJSON(), {
34-
oneof: ["a", "b", "c"],
35-
options: undefined
34+
oneof: ["a", "b", "c"]
3635
}, "should allow adding fields");
3736
test.ok(Test.get("c"), "should still have the field on the parent");
3837

3938
kind.remove(field);
4039
test.same(kind.toJSON(), {
41-
oneof: ["a", "b"],
42-
options: undefined
40+
oneof: ["a", "b"]
4341
}, "should allow removing fields");
4442
test.ok(Test.get("c"), "should still have the field on the parent");
4543

tests/api_service.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,12 @@ var def = {
66
methods: {},
77
nested: {
88
SomeEnum: {
9-
options: undefined,
109
values: {}
1110
}
12-
},
13-
options: undefined
11+
}
1412
};
1513

1614
var methodDef = {
17-
type: undefined,
1815
requestType: "MyRequest",
1916
requestStream: true,
2017
responseType: "MyResponse",

tests/api_type.js

+8-18
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,7 @@ var tape = require("tape");
33
var protobuf = require("..");
44

55
var def = {
6-
fields: {},
7-
oneofs: undefined,
8-
extensions: undefined,
9-
reserved: undefined,
10-
group: undefined,
11-
nested: undefined,
12-
options: undefined,
6+
fields: {}
137
};
148

159
var def2 = {
@@ -75,20 +69,16 @@ tape.test("reflected types", function(test) {
7569
});
7670
test.same(type.toJSON(), {
7771
fields: {
78-
a: { extend: undefined, id: 1, options: undefined, rule: undefined, type: "string" }
72+
a: { id: 1, type: "string" }
7973
},
80-
oneofs: undefined,
81-
extensions: undefined,
8274
reserved: [[900, 999], "b"],
83-
group: undefined,
8475
nested: {
85-
Type: { extensions: undefined, fields: {}, group: undefined, nested: undefined, oneofs: undefined, options: undefined, reserved: undefined },
86-
Enum: { options: undefined, values: {} },
87-
Service: { methods: {}, nested: undefined, options: undefined },
88-
extensionField: { extend: "Message", id: 1000, options: undefined, rule: undefined, type: "string" },
89-
Other: { nested: undefined, options: undefined }
90-
},
91-
options: undefined
76+
Type: { fields: {} },
77+
Enum: { values: {} },
78+
Service: { methods: {} },
79+
extensionField: { extend: "Message", id: 1000, type: "string" },
80+
Other: { }
81+
}
9282
}, "should create from Field, Type, Enum, Service, extension Field and Namespace JSON");
9383

9484
test.throws(function() {

0 commit comments

Comments
 (0)