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

V2: Make DescField.presence available for all fields #822

Merged
merged 1 commit into from
Apr 30, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/protobuf-bench/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ server would usually do.

| code generator | bundle size | minified | compressed |
|---------------------|------------------------:|-----------------------:|-------------------:|
| protobuf-es | 126,937 b | 65,433 b | 15,946 b |
| protobuf-es | 126,590 b | 65,292 b | 15,928 b |
| protobuf-javascript | 394,384 b | 288,654 b | 45,122 b |
7 changes: 7 additions & 0 deletions packages/protobuf-test/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ export async function compileField(proto: string) {
return firstField;
}

export async function compileExtension(proto: string) {
const file = await compileFile(proto);
const firstExt = file.extensions[0];
assert(firstExt);
return firstExt;
}

export async function compileService(proto: string) {
const file = await compileFile(proto);
const firstService = file.services[0];
Expand Down
112 changes: 112 additions & 0 deletions packages/protobuf-test/src/json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@ import {
} from "@bufbuild/protobuf/wkt";
import * as ext_proto2 from "./gen/ts/extra/extensions-proto2_pb.js";
import * as ext_proto3 from "./gen/ts/extra/extensions-proto3_pb.js";
import * as proto3_ts from "./gen/ts/extra/proto3_pb.js";
import { OneofMessageDesc } from "./gen/ts/extra/msg-oneof_pb.js";
import { JsonNamesMessageDesc } from "./gen/ts/extra/msg-json-names_pb.js";
import { JSTypeProto2NormalMessageDesc } from "./gen/ts/extra/jstype-proto2_pb.js";
import { TestAllTypesProto3Desc } from "./gen/ts/google/protobuf/test_messages_proto3_pb.js";
import { compileMessage } from "./helpers.js";

describe("JSON serialization", () => {
testJson(
Expand Down Expand Up @@ -702,6 +704,116 @@ describe("extensions in JSON", () => {
});
});

describe("JsonWriteOptions", () => {
describe("emitDefaultValues", () => {
Comment on lines +707 to +708
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding coverage because the logic for deciding when to emit changed.

test("emits proto3 implicit fields", async () => {
const descMessage = await compileMessage(`
syntax="proto3";
message M {
int32 int32_field = 1;
bool bool_field = 2;
repeated int32 list_field = 3;
map<int32, int32> map_field = 4;
}
`);
const json = toJson(descMessage, create(descMessage), {
emitDefaultValues: true,
});
expect(json).toStrictEqual({
int32Field: 0,
boolField: false,
listField: [],
mapField: {},
});
});
test("does not emit proto3 explicit fields", async () => {
const descMessage = await compileMessage(`
syntax="proto3";
message M {
oneof kind {
int32 int32_field = 1;
}
optional int32 optional_field = 2;
}
`);
const json = toJson(descMessage, create(descMessage), {
emitDefaultValues: true,
});
expect(json).toStrictEqual({});
});
test("emits proto2 implicit fields", async () => {
const descMessage = await compileMessage(`
syntax="proto2";
message M {
optional int32 optional_field = 1;
repeated int32 list_field = 2;
map<int32, int32> map_field = 3;
}
`);
const json = toJson(descMessage, create(descMessage), {
emitDefaultValues: true,
});
expect(json).toStrictEqual({
listField: [],
mapField: {},
});
});
});
test("enumAsInteger", () => {
const msg = create(proto3_ts.Proto3MessageDesc, {
singularEnumField: proto3_ts.Proto3Enum.YES,
optionalEnumField: proto3_ts.Proto3Enum.UNSPECIFIED,
repeatedEnumField: [proto3_ts.Proto3Enum.YES, proto3_ts.Proto3Enum.NO],
mapInt32EnumField: {
1: proto3_ts.Proto3Enum.YES,
2: proto3_ts.Proto3Enum.NO,
},
singularMessageField: {
singularEnumField: proto3_ts.Proto3Enum.YES,
},
});
const json = toJson(proto3_ts.Proto3MessageDesc, msg, {
enumAsInteger: true,
});
expect(json).toStrictEqual({
singularEnumField: 1,
optionalEnumField: 0,
repeatedEnumField: [1, 2],
mapInt32EnumField: {
1: 1,
2: 2,
},
singularMessageField: {
singularEnumField: 1,
},
});
});
describe("useProtoFieldName", () => {
test("prefers proto field name", () => {
const msg = create(proto3_ts.Proto3MessageDesc, {
singularStringField: "a",
});
const json = toJson(proto3_ts.Proto3MessageDesc, msg, {
useProtoFieldName: true,
});
expect(json).toStrictEqual({
singular_string_field: "a",
});
});
test("prefers proto field name over json_name", () => {
const msg = create(JsonNamesMessageDesc, {
scalarField: "a",
});
const json = toJson(JsonNamesMessageDesc, msg, {
useProtoFieldName: true,
});
expect(json).toStrictEqual({
scalar_field: "a",
});
});
});
});

// Coverage for JSON parse errors to guard against regressions.
// We do not cover all cases here. Map fields and oneofs are incomplete,
// and bytes, string, and other scalar types are not tested.
Expand Down
Loading
Loading