Brady Kieffer c1a76a5f5e
Serialize default values in oneofs when calling to_dict() or to_json() (#110)
* Serialize default values in oneofs when calling to_dict() or to_json()

This change is consistent with the official protobuf implementation. If
a default value is set when using a oneof, and then a message is
translated from message -> JSON -> message, the default value is kept in
tact. Also, if no default value is set, they remain null.

* Some cleanup + testing for nested messages with oneofs

* Cleanup oneof_enum test cases, they should be fixed

This _should_ address:
https://github.com/danielgtaylor/python-betterproto/issues/63

* Include default value oneof fields when serializing to bytes

This will cause oneof fields with default values to explicitly be sent
to clients. Note that does not mean that all fields are serialized and
sent to clients, just those that _could_ be null and are not.

* Remove assignment when populating a sub-message within a proto

Also, move setattr out one indentation level

* Properly transform proto with empty string in oneof to bytes

Also, updated tests to ensure that which_one_of picks up the set field

* Formatting betterproto/__init__.py

* Adding test cases demonstrating equivalent behaviour with google impl

* Removing a temporary file I made locally

* Adding some clarifying comments

* Fixing tests for python38
2020-07-25 19:51:40 +02:00
..
2020-07-11 19:51:01 +02:00
2020-07-11 19:51:01 +02:00
2020-07-11 19:51:01 +02:00
2020-07-11 19:51:01 +02:00
2020-07-11 19:51:01 +02:00
2020-07-11 19:51:01 +02:00

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>.protoThe 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>.pyCustom 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

Running the tests

  • pipenv run generate
    This generates:
    • betterproto/tests/output_betterproto — the plugin generated python classes
    • betterproto/tests/output_referencereference 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%]
  • . — PASSED
  • x — XFAIL: expected failure
  • X — XPASS: expected failure, but still passed

Test cases marked for expected failure are declared in inputs/config.py