Skip to content

Latest commit

 

History

History
128 lines (85 loc) · 4.94 KB

CONTRIBUTING.md

File metadata and controls

128 lines (85 loc) · 4.94 KB

Contributing

Reporting Bugs

Please open an issue and explain the problem.

Do you have a question?

Just start a discussion.

Building this project

Building and testing this project requires node (14.5.0), npm, protoc (3.12.3), make, bazel, git, go.

  • go is required for the Twirp transport client compatibility test suite
  • protoc is required for test fixtures
  • git and bazel are required to checkout and compile the protobuf conformance test suite

The entire project can be built by running make, but if you do not have all required tooling installed, you can still build all of the TypeScript packages.

Not all packages are public, or even JavaScript projects. There are also examples, benchmarks and fixtures in the packages/ directory. They can be built with their respective Makefiles.

Testing

Testing the runtime

The runtime is tested without generating any code. For example, to test the ReflectionJsonReader, we simply pass reflection field information to the constructor of a ReflectionJsonReader, and can test whether it reads and writes JSON as expected.

This even works with the MessageType, which implements the public API of each protobuf message in TypeScript. We just don't have a TypeScript interface for the message in question.

To test only the runtime, run:

cd packages/runtime
npm install
make 

The make compiles TypeScript to Javascript and runs all test cases (in spec/) in nodejs (using jasmine) and in a headless browser (using karma and jasmine).

Some test cases use test fixtures from packages/test-fixtures.

Test fixtures

packages/test-fixtures/index.ts exports a FixtureRegistry. This registry provides access to a collection of message type fixtures.

A message type fixture is basically a set of test data for a specific protobuf message. It has a type name (the qualified protobuf message type name) and reflection field information. It can also provide message instances.

The only purpose of the fixtures is to isolate test data from test code to make test cases more readable.

packages/test-fixtures also contains a large number of .proto files. These files are used to test code generation and functionality of the generated code.

For each fixture, there should also be a corresponding .proto file. This makes it possible to compare the field information generated by the plugin to the field information in the fixture data, asserting that the plugin generates expected data.

packages/test-fixtures/all.descriptorset is a binary protobuf message of type FileDescriptorSet (defined in google/protobuf/descriptor.proto). It contains file descriptors for all .proto files in test-fixtures. The descriptor set is generated using protoc (see packages/plugin/Makefile and packages/plugin-framework/Makefile). A FileDescriptorSet can be used to run the plugin during testing without invoking protoc.

Testing the plugin

All protobuf plugins work with CodeGeneratorRequest and CodeGeneratorResponse messages (defined in google/protobuf/compiler/plugin.proto).

The protocol buffer compiler parses .proto files and creates a CodeGeneratorRequest, then passes it to a plugin. Because invoking protoc during testing is difficult, we generate a FileDescriptorSet in packages/test-fixtures/all.descriptorset ahead of time. The FileDescriptorSet contains all information necessary to create the CodeGeneratorRequests we need for testing the plugin.

packages/plugin and packages/plugin-framework are both tested using the FileDescriptorSet. In spec/helpers.ts, the function getFixtureCodeGeneratorRequest can be used to create a CodeGeneratorRequest from the fixture file descriptors.

The plugin itself has only very basic test coverage. We generate TypeScript (in memory) for all .proto files in packages/test-fixture and compile the generated code using the TypeScript Compiler API, checking for static errors.

Adding a feature or fixing a bug in the plugin can cumbersome. Instead of building the plugin and running it with protoc, you can let a test case spit out the generated code for you. spec/protobufts-plugin.spec.ts contains the necessary code to do this (commented out). If you enable the code, you can simply run make test after your change to see the generated code. There should probably be a separate script for this, but at the moment, we do not have one. Please remember not to commit unintentional changes to the spec file.

Testing generated code

The plugin generates speed optimized methods as well as custom method for well-known types. This code is not part of the runtime and can only be tested by testing the actual generated code.

packages/test-generated/ is responsible to test the generated code.
See the README.md for details.