Changes message initialization (`__post_init__`) so that default values are no longer eagerly created to prevent infinite recursion when initializing recursive messages. As a result, `PLACEHOLDER` will be present in the message for any uninitialized fields. So, an implementation of `__get_attribute__` is added that checks for `PLACEHOLDER` and lazily creates and stores default field values. And, because `PLACEHOLDER` values don't compare equal with zero values, a custom implementation of `__eq__` is provided, and the code generation template is updated so that messages generate with `@dataclass(eq=False)`. Also add new Message __repr__ implementation that skips PLACEHOLDER values and orders keys by number from the proto. Co-authored-by: Christopher Chambers <chris@peanutcode.com> Co-authored-by: nat <n@natn.me> Co-authored-by: James <50501825+Gobot1234@users.noreply.github.com>
Standard Tests Development Guide
Standard test cases are found in betterproto/tests/inputs, where each subdirectory represents a testcase, that is verified in isolation.
inputs/
bool/
double/
int32/
...
Test case directory structure
Each testcase has a <name>.proto
file with a message called Test
, and optionally a matching .json
file and a custom test called test_*.py
.
bool/
bool.proto
bool.json # optional
test_bool.py # optional
proto
<name>.proto
— The protobuf message to test
syntax = "proto3";
message Test {
bool value = 1;
}
You can add multiple .proto
files to the test case, as long as one file matches the directory name.
json
<name>.json
— Test-data to validate the message with
{
"value": true
}
pytest
test_<name>.py
— Custom test to validate specific aspects of the generated class
from tests.output_betterproto.bool.bool import Test
def test_value():
message = Test()
assert not message.value, "Boolean is False by default"
Standard tests
The following tests are automatically executed for all cases:
- Can the generated python code be imported?
- Can the generated message class be instantiated?
- Is the generated code compatible with the Google's
grpc_tools.protoc
implementation?- when
.json
is present
- when
Running the tests
pipenv run generate
This generates:betterproto/tests/output_betterproto
— the plugin generated python classesbetterproto/tests/output_reference
— reference implementation classes
pipenv run test
Intentionally Failing tests
The standard test suite includes tests that fail by intention. These tests document known bugs and missing features that are intended to be corrected in the future.
When running pytest
, they show up as x
or X
in the test results.
betterproto/tests/test_inputs.py ..x...x..x...x.X........xx........x.....x.......x.xx....x...................... [ 84%]
.
— PASSEDx
— XFAIL: expected failureX
— XPASS: expected failure, but still passed
Test cases marked for expected failure are declared in inputs/config.py