mirror of
https://github.com/protobufjs/protobuf.js.git
synced 2025-12-08 20:58:55 +00:00
219 lines
8.5 KiB
JavaScript
219 lines
8.5 KiB
JavaScript
var tape = require("tape");
|
|
|
|
var protobuf = require("..");
|
|
|
|
var def = {
|
|
fields: {}
|
|
};
|
|
|
|
var def2 = {
|
|
fields: {
|
|
a: {
|
|
type: "uint32",
|
|
id: 1
|
|
}
|
|
},
|
|
oneofs: {
|
|
kind: {
|
|
oneof: ["a"]
|
|
}
|
|
},
|
|
extensions: [[1000, 2000]],
|
|
reserved: [[900, 999], "b"],
|
|
nested: {
|
|
Type: {
|
|
values: { ONE: 1, TWO: 2 }
|
|
},
|
|
Service: {
|
|
methods: {}
|
|
}
|
|
},
|
|
options: {
|
|
custom: true
|
|
}
|
|
};
|
|
|
|
tape.test("reflected types", function(test) {
|
|
|
|
var type = protobuf.Type.fromJSON("Test", def);
|
|
test.same(type.toJSON(), def, "should construct from and convert back to JSON");
|
|
type = protobuf.Type.fromJSON("Test", def2);
|
|
test.same(JSON.parse(JSON.stringify(type)), JSON.parse(JSON.stringify(def2)), "should construct from and convert back to JSON (complex parsed)");
|
|
|
|
function MyMessageAuto() {}
|
|
type.ctor = MyMessageAuto;
|
|
test.ok(MyMessageAuto.prototype instanceof protobuf.Message, "should properly register a constructor through assignment");
|
|
test.ok(typeof MyMessageAuto.encode === "function", "should populate static methods on assigned constructors");
|
|
|
|
function MyMessageManual() {}
|
|
MyMessageManual.prototype = Object.create(protobuf.Message.prototype);
|
|
type.ctor = MyMessageManual;
|
|
test.ok(MyMessageManual.prototype instanceof protobuf.Message, "should properly register a constructor through assignment if already extending message");
|
|
test.ok(typeof MyMessageManual.encode === "function", "should populate static methods on assigned constructors");
|
|
|
|
type = protobuf.Type.fromJSON("My", {
|
|
fields: {
|
|
a: {
|
|
type: "string",
|
|
id: 1
|
|
}
|
|
},
|
|
reserved: [[900, 999], "b"],
|
|
nested: {
|
|
Type: { fields: {} },
|
|
Enum: { values: {} },
|
|
Service: { methods: {} },
|
|
extensionField: { type: "string", id: 1000, extend: "Message" },
|
|
Other: { nested: {} }
|
|
}
|
|
});
|
|
test.same(type.toJSON(), {
|
|
fields: {
|
|
a: { id: 1, type: "string" }
|
|
},
|
|
reserved: [[900, 999], "b"],
|
|
nested: {
|
|
Type: { fields: {} },
|
|
Enum: { values: {} },
|
|
Service: { methods: {} },
|
|
extensionField: { extend: "Message", id: 1000, type: "string" },
|
|
Other: { }
|
|
}
|
|
}, "should create from Field, Type, Enum, Service, extension Field and Namespace JSON");
|
|
|
|
test.throws(function() {
|
|
type.add(new protobuf.Enum("Enum"));
|
|
}, Error, "should throw when trying to add duplicate names");
|
|
|
|
test.throws(function() {
|
|
type.add(new protobuf.Field("c", 1, "uint32"));
|
|
}, Error, "should throw when trying to add duplicate ids");
|
|
|
|
test.throws(function() {
|
|
type.add(new protobuf.Field("c", 900, "uint32"));
|
|
}, Error, "should throw when trying to add reserved ids");
|
|
|
|
test.throws(function() {
|
|
type.add(new protobuf.Field("b", 2, "uint32"));
|
|
}, Error, "should throw when trying to add reserved names");
|
|
|
|
|
|
test.end();
|
|
});
|
|
|
|
tape.test("feature resolution legacy proto3", function(test) {
|
|
var json = {
|
|
fields: {
|
|
regular: { type: "string", id: 1 },
|
|
packed: { type: "int32", id: 2, rule: "repeated" },
|
|
unpacked: { type: "int32", id: 3, rule: "repeated", options: { packed: false } }
|
|
},
|
|
nested: { Nested: { fields: {
|
|
regular: { type: "string", id: 1 },
|
|
packed: { type: "int32", id: 2, rule: "repeated" },
|
|
unpacked: { type: "int32", id: 3, rule: "repeated", options: { packed: false } }
|
|
} } }
|
|
};
|
|
var root = new protobuf.Root();
|
|
var Type = protobuf.Type.fromJSON("My", json);
|
|
root.add(Type).resolveAll();
|
|
|
|
var Nested = Type.nested.Nested;
|
|
|
|
test.same(Type.toJSON(), json, "JSON should roundtrip");
|
|
test.same(Nested.toJSON(), json.nested.Nested, "nested JSON should roundtrip");
|
|
|
|
test.equal(Type._edition, "proto3", "should infer proto3 syntax");
|
|
test.notOk(Type.fields.regular.hasPresence, "should have implicit presence by default");
|
|
test.ok(Type.fields.packed.packed, "should have packed encoding by default");
|
|
test.notOk(Type.fields.unpacked.packed, "should override expanded encoding");
|
|
|
|
test.equal(Nested._edition, null, "should not infer proto3 syntax");
|
|
test.notOk(Nested.fields.regular.hasPresence, "nested should have implicit presence by default");
|
|
test.ok(Nested.fields.packed.packed, "nested should have packed encoding by default");
|
|
test.notOk(Nested.fields.unpacked.packed, "nested should override expanded encoding");
|
|
|
|
test.end();
|
|
});
|
|
|
|
tape.test("feature resolution proto2", function(test) {
|
|
var json = {
|
|
edition: "proto2",
|
|
fields: {
|
|
regular: { type: "string", id: 1 },
|
|
required: { type: "string", id: 2, rule: "required" },
|
|
packed: { type: "int32", id: 3, rule: "repeated", options: { packed: true } },
|
|
unpacked: { type: "int32", id: 4, rule: "repeated"}
|
|
},
|
|
nested: { Nested: { fields: {
|
|
regular: { type: "string", id: 1 },
|
|
packed: { type: "int32", id: 2, rule: "repeated", options: { packed: true } },
|
|
unpacked: { type: "int32", id: 3, rule: "repeated" }
|
|
} } }
|
|
};
|
|
var root = new protobuf.Root();
|
|
var Type = protobuf.Type.fromJSON("My", json);
|
|
root.add(Type).resolveAll();
|
|
|
|
var Nested = Type.nested.Nested;
|
|
|
|
test.same(Type.toJSON(), json, "JSON should roundtrip");
|
|
test.same(Nested.toJSON(), json.nested.Nested, "nested JSON should roundtrip");
|
|
|
|
test.equal(Type._edition, "proto2", "should set edition");
|
|
test.ok(Type.fields.regular.hasPresence, "should have explicit presence by default");
|
|
test.ok(Type.fields.required.required, "should have required fields");
|
|
test.ok(Type.fields.packed.packed, "should override packed encoding");
|
|
test.notOk(Type.fields.unpacked.packed, "should have expanded encoding by default");
|
|
|
|
test.equal(Nested._edition, null, "should not set edition");
|
|
test.ok(Nested.fields.regular.hasPresence, "nested should have explicit presence by default");
|
|
test.notOk(Nested.fields.unpacked.packed, "nested should have expanded encoding by default");
|
|
test.ok(Nested.fields.packed.packed, "nested should override packed encoding");
|
|
|
|
test.end();
|
|
});
|
|
|
|
|
|
tape.test("feature resolution edition 2023", function(test) {
|
|
var json = {
|
|
edition: "2023",
|
|
fields: {
|
|
explicit: { type: "string", id: 1 },
|
|
implicit: { type: "string", id: 2, options: { "features": { "field_presence": "IMPLICIT" } } },
|
|
required: { type: "string", id: 3, rule: "required", options: { "features": { "field_presence": "LEGACY_REQUIRED" } } },
|
|
packed: { type: "int32", id: 4, rule: "repeated" },
|
|
unpacked: { type: "int32", id: 5, rule: "repeated", options: { "features": { "repeated_field_encoding": "EXPANDED" } } }
|
|
},
|
|
nested: { Nested: { fields: {
|
|
explicit: { type: "string", id: 1 },
|
|
implicit: { type: "string", id: 2, options: { "features": { "field_presence": "IMPLICIT" } } },
|
|
packed: { type: "int32", id: 3, rule: "repeated" },
|
|
unpacked: { type: "int32", id: 4, rule: "repeated", options: { "features": { "repeated_field_encoding": "EXPANDED" } } }
|
|
} } }
|
|
};
|
|
var root = new protobuf.Root();
|
|
var Type = protobuf.Type.fromJSON("My", json);
|
|
root.add(Type).resolveAll();
|
|
|
|
var Nested = Type.nested.Nested;
|
|
|
|
test.same(Type.toJSON(), json, "JSON should roundtrip");
|
|
test.same(Nested.toJSON(), json.nested.Nested, "nested JSON should roundtrip");
|
|
|
|
test.equal(Type._edition, "2023", "should set edition");
|
|
test.ok(Type.fields.explicit.hasPresence, "should have explicit presence");
|
|
test.notOk(Type.fields.implicit.hasPresence, "should have implicit presence");
|
|
test.ok(Type.fields.required.required, "should have required presence");
|
|
test.ok(Type.fields.packed.packed, "should have packed encoding");
|
|
test.notOk(Type.fields.unpacked.packed, "should have expanded encoding");
|
|
|
|
test.equal(Nested._edition, null, "should not set edition");
|
|
test.ok(Nested.fields.explicit.hasPresence, "nested should have explicit presence");
|
|
test.notOk(Nested.fields.implicit.hasPresence, "nested should have implicit presence");
|
|
test.ok(Nested.fields.packed.packed, "nested should have packed encoding");
|
|
test.notOk(Nested.fields.unpacked.packed, "nested should have expanded encoding");
|
|
|
|
test.end();
|
|
});
|