Skip to content

Commit

Permalink
Generalize the special case for RemoteSettingsChanged.
Browse files Browse the repository at this point in the history
Stop sorting dicts.

See #1.
  • Loading branch information
nmlorg committed Oct 29, 2024
1 parent c053729 commit 7525d95
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 38 deletions.
70 changes: 53 additions & 17 deletions nh2/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,30 +75,66 @@ async def flush(self):
await self.s.send(data)


def _format(obj, indent=0):
return '\n'.join(_do_format(obj, indent)).replace(' \n', '\n')
def _format(obj):
return ''.join(_do_format(obj, 0))


def _do_format(obj, indent):
def _simple(obj):
return obj is None or isinstance(obj, (bytes, int, str))


def _do_format(obj, indent, name=''): # pylint: disable=too-many-branches
prefix = ' ' * indent
if isinstance(obj, h2.events.RemoteSettingsChanged):
yield '[RemoteSettingsChanged]'
yield prefix + ' '.join(f'{setting.setting.name.lower()}={setting.new_value}'
for setting in obj.changed_settings.values())
elif isinstance(obj, dict):
yield ''
for k, v in sorted(obj.items()):
k = f'{k}'

if isinstance(obj, dict):
multiline = False
items = []
for k, v in obj.items():
if not k.startswith('_'):
yield f'{prefix}{k}: {_format(v, indent + 1)}'
items.append((k, v))
if not multiline and not _simple(v):
multiline = True
if not multiline:
yield ' ['
if name:
yield f'{name} '
yield ' '.join(f'{k}={repr(v)}' for k, v in items) + ']\n'
else:
if name:
yield f' [{name}]'
yield '\n'
for k, v in items:
yield f'{prefix}{k}:'
yield from _do_format(v, indent + 1)
elif isinstance(obj, list):
yield ''
multiline = False
for v in obj:
yield f'{prefix}- {_format(v, indent + 1)}'
elif obj is None or isinstance(obj, (bytes, int, str, tuple)):
yield f'{repr(obj)}'
if not _simple(v):
multiline = True
break
if not multiline:
yield ' ['
if name:
yield f'{name} '
yield ' '.join(repr(v) for v in obj) + ']\n'
else:
if name:
yield f' [{name}]'
yield '\n'
for v in obj:
yield f'{prefix}-'
yield from _do_format(v, indent + 1)
elif _simple(obj) or isinstance(obj, tuple):
if name:
name = f'[{name}] '
yield f' {name}{repr(obj)}\n'
else:
yield f'[{obj.__class__.__qualname__}] {_format(obj.__dict__, indent)}'
name = obj.__class__.__qualname__
if isinstance(obj, h2.events.RemoteSettingsChanged):
obj = {chg.setting.name.lower(): chg.new_value for chg in obj.changed_settings.values()}
else:
obj = obj.__dict__
yield from _do_format(obj, indent, name=name)


class _DedentingString(str):
Expand Down
33 changes: 12 additions & 21 deletions nh2/test_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,27 @@ async def test_simple():
mock_server = await nh2.mock.expect_connect('example.com', 443)
conn = await nh2.connection.Connection('example.com', 443)
assert await mock_server.read() == """
- [RemoteSettingsChanged]
header_table_size=4096 enable_push=1 initial_window_size=65535 max_frame_size=16384 enable_connect_protocol=0 max_concurrent_streams=100 max_header_list_size=65536
- [RemoteSettingsChanged header_table_size=4096 enable_push=1 initial_window_size=65535 max_frame_size=16384 enable_connect_protocol=0 max_concurrent_streams=100 max_header_list_size=65536]
"""

live_request = await conn.request('POST', '/dummy', json={'a': 1})
assert await mock_server.read() == """
- [RequestReceived]
stream_id: 1
headers:
- (':method', 'POST')
- (':path', '/dummy')
- (':authority', 'example.com')
- (':scheme', 'https')
- ('content-type', 'application/json; charset=utf-8')
priority_updated: None
stream_ended: None
stream_id: 1
priority_updated: None
- [DataReceived]
stream_id: 1
data: b'{"a":1}'
flow_controlled_length: 7
stream_ended: [StreamEnded]
stream_id: 1
stream_id: 1
- [StreamEnded]
stream_id: 1
stream_ended: [StreamEnded stream_id=1]
- [StreamEnded stream_id=1]
"""

mock_server.c.send_headers(1, [(':status', '200')])
Expand All @@ -49,15 +46,12 @@ async def test_simple():
assert response.body == 'dummy response'
assert await mock_server.read() == """
- [SettingsAcknowledged]
changed_settings:
changed_settings: []
"""

await conn.close()
assert await mock_server.read() == """
- [ConnectionTerminated]
additional_data: None
error_code: <ErrorCodes.NO_ERROR: 0>
last_stream_id: 0
- [ConnectionTerminated error_code=<ErrorCodes.NO_ERROR: 0> last_stream_id=0 additional_data=None]
"""
assert await mock_server.read() == """
SOCKET CLOSED
Expand All @@ -79,23 +73,20 @@ async def opaque_workflow():
future = tg.start_soon(opaque_workflow)

assert await mock_server.read() == """
- [RemoteSettingsChanged]
header_table_size=4096 enable_push=1 initial_window_size=65535 max_frame_size=16384 enable_connect_protocol=0 max_concurrent_streams=100 max_header_list_size=65536
- [RemoteSettingsChanged header_table_size=4096 enable_push=1 initial_window_size=65535 max_frame_size=16384 enable_connect_protocol=0 max_concurrent_streams=100 max_header_list_size=65536]
"""

assert await mock_server.read() == """
- [RequestReceived]
stream_id: 1
headers:
- (':method', 'GET')
- (':path', '/dummy')
- (':authority', 'example.com')
- (':scheme', 'https')
stream_ended: [StreamEnded stream_id=1]
priority_updated: None
stream_ended: [StreamEnded]
stream_id: 1
stream_id: 1
- [StreamEnded]
stream_id: 1
- [StreamEnded stream_id=1]
"""

mock_server.c.send_headers(1, [(':status', '200')])
Expand Down

0 comments on commit 7525d95

Please sign in to comment.