8000 Test all supported wrapper types. Add xfail test for unwrapping the v… · fixpoint/python-betterproto@35548cb · GitHub
[go: up one dir, main page]

Skip to content

Commit 35548cb

Browse files
Test all supported wrapper types. Add xfail test for unwrapping the value
1 parent b711d1e commit 35548cb

File tree

4 files changed

+92
-35
lines changed

4 files changed

+92
-35
lines changed

betterproto/tests/googletypes_service.proto

Lines changed: 0 additions & 18 deletions
This file was deleted.

betterproto/tests/inputs/googletypes_response/googletypes_response.proto

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@ syntax = "proto3";
22

33
import "google/protobuf/wrappers.proto";
44

5+
// Tests that wrapped return values can be used
6+
57
service Test {
6-
rpc GetInt32 (Input) returns (google.protobuf.Int32Value);
7-
rpc GetAnotherInt32 (Input) returns (google.protobuf.Int32Value);
8+
rpc GetDouble (Input) returns (google.protobuf.DoubleValue);
9+
rpc GetFloat (Input) returns (google.protobuf.FloatValue);
810
rpc GetInt64 (Input) returns (google.protobuf.Int64Value);
9-
rpc GetOutput (Input) returns (Output);
11+
rpc GetUInt64 (Input) returns (google.protobuf.UInt64Value);
12+
rpc GetInt32 (Input) returns (google.protobuf.Int32Value);
13+
rpc GetUInt32 (Input) returns (google.protobuf.UInt32Value);
14+
rpc GetBool (Input) returns (google.protobuf.BoolValue);
15+
rpc GetString (Input) returns (google.protobuf.StringValue);
16+
rpc GetBytes (Input) returns (google.protobuf.BytesValue);
1017
}
1118

1219
message Input {
1320

1421
}
15-
16-
message Output {
17-
google.protobuf.Int64Value int64 = 1;
18-
}
Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,53 @@
1-
from typing import Optional
1+
from typing import Any, Callable, Optional
22

3+
import google.protobuf.wrappers_pb2 as wrappers
34
import pytest
45

6+
from betterproto.tests.mocks import MockChannel
57
from betterproto.tests.output_betterproto.googletypes_response.googletypes_response import (
6-
TestStub
8+
TestStub,
79
)
810

11+
test_cases = [
12+
(TestStub.get_double, wrappers.DoubleValue, 2.5),
13+
(TestStub.get_float, wrappers.FloatValue, 2.5),
14+
(TestStub.get_int64, wrappers.Int64Value, -64),
15+
(TestStub.get_u_int64, wrappers.UInt64Value, 64),
16+
(TestStub.get_int32, wrappers.Int32Value, -32),
17+
(TestStub.get_u_int32, wrappers.UInt32Value, 32),
18+
(TestStub.get_bool, wrappers.BoolValue, True),
19+
(TestStub.get_string, wrappers.StringValue, "string"),
20+
(TestStub.get_bytes, wrappers.BytesValue, bytes(0xFF)[0:4]),
21+
]
922

10-
class TestStubChild(TestStub):
11-
async def _unary_unary(self, route, request, response_type, **kwargs):
12-
self.response_type = response_type
23+
24+
@pytest.mark.asyncio
25+
@pytest.mark.parametrize(["service_method", "wrapper_class", "value"], test_cases)
26+
async def test_channel_receives_wrapped_type(
27+
service_method: Callable[[TestStub], Any], wrapper_class: Callable, value
28+
):
29+
wrapped_value = wrapper_class()
30+
wrapped_value.value = value
31+
channel = MockChannel(responses=[wrapped_value])
32+
service = TestStub(channel)
33+
34+
await service_method(service)
35+
36+
assert channel.requests[0]["response_type"] != Optional[type(value)]
37+
assert channel.requests[0]["response_type"] == type(wrapped_value)
1338

1439

1540
@pytest.mark.asyncio
16-
async def test():
17-
pytest.skip("todo")
18-
stub = TestStubChild(None)
19-
await stub.get_int64()
20-
assert stub.response_type != Optional[int]
41+
@pytest.mark.xfail
42+
@pytest.mark.parametrize(["service_method", "wrapper_class", "value"], test_cases)
43+
async def test_service_unwraps_response(
44+
service_method: Callable[[TestStub], Any], wrapper_class: Callable, value
45+
):
46+
wrapped_value = wrapper_class()
47+
wrapped_value.value = value
48+
service = TestStub(MockChannel(responses=[wrapped_value]))
49+
50+
response_value = await service_method(service)
51+
52+
assert type(response_value) == value
53+
assert type(response_value) == type(value)

betterproto/tests/mocks.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from typing import List
2+
3+
from grpclib.client import Channel
4+
5+
6+
class MockChannel(Channel):
7+
# noinspection PyMissingConstructor
8+
def __init__(self, responses: List) -> None:
9+
self.responses = responses
10+
self.requests = []
11+
12+
def request(self, route, cardinality, request, response_type, **kwargs):
13+
self.requests.append(
14+
{
15+
"route": route,
16+
"cardinality": cardinality,
17+
"request": request,
18+
"response_type": response_type,
19+
}
20+
)
21+
return MockStream(self.responses)
22+
23+
24+
class MockStream:
25+
def __init__(self, responses: List) -> None:
26+
super().__init__()
27+
self.responses = responses
28+
29+
async def recv_message(self):
30+
return next(self.responses)
31+
32+
async def send_message(self, *args, **kwargs):
33+
pass
34+
35+
async def __aexit__(self, exc_type, exc_val, exc_tb):
36+
return True
37+
38+
async def __aenter__(self):
39+
return True

0 commit comments

Comments
 (0)
0