Skip to content

Commit

Permalink
Fix the prettier configuration (#616)
Browse files Browse the repository at this point in the history
  • Loading branch information
timostamm authored Nov 16, 2023
1 parent f7375ad commit fd56d4c
Show file tree
Hide file tree
Showing 13 changed files with 347 additions and 191 deletions.
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/node_modules
/packages/*/bin
/packages/*/.tmp
/packages/*/dist
/packages/*/src/gen
/packages/protobuf/src/google
Expand Down
3 changes: 2 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

153 changes: 48 additions & 105 deletions packages/protobuf-test/src/json-names.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,115 +13,58 @@
// limitations under the License.

import { expect, test } from "@jest/globals";
import { mkdtempSync, readFileSync, writeFileSync } from "fs";
import { join } from "path";
import { tmpdir } from "os";
import { spawnSync } from "child_process";
import { FileDescriptorSet, proto3, ScalarType } from "@bufbuild/protobuf";
import { UpstreamProtobuf } from "upstream-protobuf";

test("JSON names equal protoc", () => {
expect(getProtocJsonName("foo_bar")).toBe("fooBar");
expectRuntimeJsonNameEqualsProtocJsonName("foo_bar");
expectRuntimeJsonNameEqualsProtocJsonName("__proto__");
expectRuntimeJsonNameEqualsProtocJsonName("fieldname1");
expectRuntimeJsonNameEqualsProtocJsonName("field_name2");
expectRuntimeJsonNameEqualsProtocJsonName("_field_name3");
expectRuntimeJsonNameEqualsProtocJsonName("field__name4_");
expectRuntimeJsonNameEqualsProtocJsonName("field0name5");
expectRuntimeJsonNameEqualsProtocJsonName("field_0_name6");
expectRuntimeJsonNameEqualsProtocJsonName("fieldName7");
expectRuntimeJsonNameEqualsProtocJsonName("FieldName8");
expectRuntimeJsonNameEqualsProtocJsonName("field_Name9");
expectRuntimeJsonNameEqualsProtocJsonName("Field_Name10");
expectRuntimeJsonNameEqualsProtocJsonName("FIELD_NAME11");
expectRuntimeJsonNameEqualsProtocJsonName("FIELD_name12");
expectRuntimeJsonNameEqualsProtocJsonName("__field_name13");
expectRuntimeJsonNameEqualsProtocJsonName("__Field_name14");
expectRuntimeJsonNameEqualsProtocJsonName("field__name15");
expectRuntimeJsonNameEqualsProtocJsonName("field__Name16");
expectRuntimeJsonNameEqualsProtocJsonName("field_name17__");
expectRuntimeJsonNameEqualsProtocJsonName("Field_name18__");
test("JSON names equal protoc", async () => {
const names = [
"foo_bar",
"__proto__",
"fieldname1",
"field_name2",
"_field_name3",
"field__name4_",
"field0name5",
"field_0_name6",
"fieldName7",
"FieldName8",
"field_Name9",
"Field_Name10",
"FIELD_NAME11",
"FIELD_name12",
"__field_name13",
"__Field_name14",
"field__name15",
"field__Name16",
"field_name17__",
"Field_name18__",
];
const protocNames = await getProtocJsonNames(names);
const runtimeNames = getRuntimeJsonNames(names);
expect(runtimeNames).toStrictEqual(protocNames);
});

// expectRuntimeJsonNameEqualsProtocJsonName takes the given proto field name
// and runs it through protoc to get the JSON name.
// The result is compared to our own implementation of the algorithm.
// It is important that the implementations in JS and Go match the protoc
// implementation.
export function expectRuntimeJsonNameEqualsProtocJsonName(protoName: string) {
const want = getProtocJsonName(protoName);
const got = getRuntimeJsonName(protoName);
if (want === false) {
return;
}
expect(want).toBe(got);
}

function getRuntimeJsonName(name: string): string {
const mt = proto3.makeMessageType("Fuzz", [
{ no: 1, kind: "scalar", T: ScalarType.BOOL, name: name },
]);
const fi = mt.fields.find(1);
if (!fi) {
throw new Error();
}
return fi.jsonName;
function getRuntimeJsonNames(protoFieldNames: string[]) {
const mt = proto3.makeMessageType(
"M",
protoFieldNames.map(
(n, i) =>
({ no: i + 1, kind: "scalar", T: ScalarType.INT32, name: n }) as const,
),
);
return mt.fields.list().map((f) => f.jsonName);
}

// getProtocJsonName runs protoc to get the "json name" for a field
function getProtocJsonName(protoName: string): string | false {
if (protoName.trim() !== protoName) {
return false;
}
const tempDir = mkdtempSync(join(tmpdir(), "node-protoc-workdir-"));
const inFilename = join(tempDir, "i.proto");
const outFilename = join(tempDir, "o");
const inData = [
`syntax = "proto3";`,
`message I {`,
` int32 ${protoName} = 1;`,
`}`,
].join("\n");
writeFileSync(inFilename, inData, { encoding: "utf-8" });
const result = spawnSync(
"protoc",
["-I", tempDir, inFilename, "--descriptor_set_out", outFilename],
{
encoding: "utf-8",
},
);
if (result.stderr.length > 0) {
if (result.stderr.indexOf("Expected field name.") >= 0) {
return false;
}
if (result.stderr.indexOf("Expected field number.") >= 0) {
return false;
}
if (result.stderr.indexOf('Expected ";".') >= 0) {
return false;
}
if (result.stderr.indexOf("Missing field number.") >= 0) {
return false;
}
if (
result.stderr.indexOf(
"Invalid control characters encountered in text.",
) >= 0
) {
return false;
}
throw new Error(result.stderr);
}
if (result.error) {
throw result.error;
}
if (result.status !== 0) {
throw new Error("exit code " + String(result.status));
}
const fds = FileDescriptorSet.fromBinary(readFileSync(outFilename));
const jsonName = fds.file[0].messageType[0].field[0].jsonName;
if (jsonName === undefined) {
throw new Error("missing json name");
}
return jsonName;
async function getProtocJsonNames(protoFieldNames: string[]) {
const upstream = new UpstreamProtobuf();
const bytes = await upstream.compileToDescriptorSet({
"i.proto": [
`syntax="proto3";`,
`message M {`,
...protoFieldNames.map((n, i) => `int32 ${n} = ${i + 1};`),
`}`,
].join("\n"),
});
const fds = FileDescriptorSet.fromBinary(bytes);
return fds.file[0].messageType[0].field.map((f) => f.jsonName);
}
5 changes: 3 additions & 2 deletions packages/upstream-protobuf/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Upstream protobuf

This package provides `protoc`, `conformance_test_runner`, and related proto
files via npm "binaries".
This package provides `protoc`, `conformance_test_runner`, related proto files,
and feature-set defaults for editions via npm "binaries", and via an exported
class.

To update this project to use a new version, update the version number in
version.txt and run `make`.
22 changes: 12 additions & 10 deletions packages/upstream-protobuf/bin/conformance_test_runner.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,20 @@

import { execFileSync } from "node:child_process";
import { argv, exit, stderr } from "node:process";
import { UpstreamProtobuf } from "../lib.mjs";
import { UpstreamProtobuf } from "../index.mjs";

const upstream = new UpstreamProtobuf();

upstream.getConformanceTestRunnerPath()
.then(path => {
execFileSync(path, argv.slice(2), {
shell: false,
stdio: "inherit",
maxBuffer: 1024 * 1024 * 100,
});
}).catch(reason => {
upstream
.getConformanceTestRunnerPath()
.then((path) => {
execFileSync(path, argv.slice(2), {
shell: false,
stdio: "inherit",
maxBuffer: 1024 * 1024 * 100,
});
})
.catch((reason) => {
stderr.write(String(reason) + "\n");
exit(1);
});
});
22 changes: 12 additions & 10 deletions packages/upstream-protobuf/bin/protoc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,20 @@

import { execFileSync } from "node:child_process";
import { argv, exit, stderr } from "node:process";
import { UpstreamProtobuf } from "../lib.mjs";
import { UpstreamProtobuf } from "../index.mjs";

const upstream = new UpstreamProtobuf();

upstream.getProtocPath()
.then(path => {
execFileSync(path, argv.slice(2), {
shell: false,
stdio: "inherit",
maxBuffer: 1024 * 1024 * 100,
});
}).catch(reason => {
upstream
.getProtocPath()
.then((path) => {
execFileSync(path, argv.slice(2), {
shell: false,
stdio: "inherit",
maxBuffer: 1024 * 1024 * 100,
});
})
.catch((reason) => {
stderr.write(String(reason) + "\n");
exit(1);
});
});
52 changes: 26 additions & 26 deletions packages/upstream-protobuf/bin/upstream-files.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,41 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {argv, exit, stderr, stdout} from "node:process";
import {UpstreamProtobuf} from "../lib.mjs";
import { argv, exit, stderr, stdout } from "node:process";
import { UpstreamProtobuf } from "../index.mjs";

void main(argv.slice(2));

async function main(args) {
/**
* @typedef ProtoInclude
* @property {string} dir
* @property {string[]} files
*/
/**
* @typedef ProtoInclude
* @property {string} dir
* @property {string[]} files
*/

const upstream = new UpstreamProtobuf();
/** @type ProtoInclude */
let protoInclude;
switch (args[0]) {
case "wkt":
protoInclude = await upstream.getWktProtoInclude();
break;
case "conformance":
protoInclude = await upstream.getConformanceProtoInclude();
break;
case "test":
protoInclude = await upstream.getTestProtoInclude();
break;
default:
exitUsage();
}
stdout.write(protoInclude.files.join(" "));
const upstream = new UpstreamProtobuf();
/** @type ProtoInclude */
let protoInclude;
switch (args[0]) {
case "wkt":
protoInclude = await upstream.getWktProtoInclude();
break;
case "conformance":
protoInclude = await upstream.getConformanceProtoInclude();
break;
case "test":
protoInclude = await upstream.getTestProtoInclude();
break;
default:
exitUsage();
}
stdout.write(protoInclude.files.join(" "));
}

/**
* @return never
*/
function exitUsage() {
stderr.write(`USAGE: upstream-files wkt|conformance|test\n`);
exit(1);
stderr.write(`USAGE: upstream-files wkt|conformance|test\n`);
exit(1);
}
52 changes: 26 additions & 26 deletions packages/upstream-protobuf/bin/upstream-include.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,41 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {argv, exit, stderr, stdout} from "node:process";
import {UpstreamProtobuf} from "../lib.mjs";
import { argv, exit, stderr, stdout } from "node:process";
import { UpstreamProtobuf } from "../index.mjs";

void main(argv.slice(2));

async function main(args) {
/**
* @typedef ProtoInclude
* @property {string} dir
* @property {string[]} files
*/
/**
* @typedef ProtoInclude
* @property {string} dir
* @property {string[]} files
*/

const upstream = new UpstreamProtobuf();
/** @type ProtoInclude */
let protoInclude;
switch (args[0]) {
case "wkt":
protoInclude = await upstream.getWktProtoInclude();
break;
case "conformance":
protoInclude = await upstream.getConformanceProtoInclude();
break;
case "test":
protoInclude = await upstream.getTestProtoInclude();
break;
default:
exitUsage();
}
stdout.write(protoInclude.dir);
const upstream = new UpstreamProtobuf();
/** @type ProtoInclude */
let protoInclude;
switch (args[0]) {
case "wkt":
protoInclude = await upstream.getWktProtoInclude();
break;
case "conformance":
protoInclude = await upstream.getConformanceProtoInclude();
break;
case "test":
protoInclude = await upstream.getTestProtoInclude();
break;
default:
exitUsage();
}
stdout.write(protoInclude.dir);
}

/**
* @return never
*/
function exitUsage() {
stderr.write(`USAGE: upstream-include wkt|conformance|test\n`);
exit(1);
stderr.write(`USAGE: upstream-include wkt|conformance|test\n`);
exit(1);
}
Loading

0 comments on commit fd56d4c

Please sign in to comment.