Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions gapic/schema/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ class Field:
)
oneof: Optional[str] = None

# Arbitrary cap set via heuristic rule of thumb.
MAX_MOCK_DEPTH: int = 20

def __getattr__(self, name):
return getattr(self.field_pb, name)

Expand Down Expand Up @@ -85,6 +88,17 @@ def map(self) -> bool:

@utils.cached_property
def mock_value(self) -> str:
depth = 0
stack = [self]
answer = "{}"
while stack:
expr = stack.pop()
answer = answer.format(expr.inner_mock(stack, depth))
depth += 1

return answer

def inner_mock(self, stack, depth):
"""Return a repr of a valid, usually truthy mock value."""
# For primitives, send a truthy value computed from the
# field name.
Expand Down Expand Up @@ -113,9 +127,18 @@ def mock_value(self) -> str:
answer = f'{self.type.ident}.{mock_value.name}'

# If this is another message, set one value on the message.
if isinstance(self.type, MessageType) and len(self.type.fields):
if (
not self.map # Maps are handled separately
and isinstance(self.type, MessageType)
and len(self.type.fields)
# Nested message types need to terminate eventually
and depth < self.MAX_MOCK_DEPTH
):
sub = next(iter(self.type.fields.values()))
answer = f'{self.type.ident}({sub.name}={sub.mock_value})'
stack.append(sub)
# Don't do the recursive rendering here, just set up
# where the nested value should go with the double {}.
answer = f'{self.type.ident}({sub.name}={{}})'

if self.map:
# Maps are a special case beacuse they're represented internally as
Expand Down