httpie-cli/tests/test_stream.py

151 lines
4.4 KiB
Python
Raw Normal View History

import json
import pytest
import responses
from unittest.mock import Mock
2014-04-24 14:07:31 +02:00
from httpie.compat import is_windows
from httpie.cli.constants import PRETTY_MAP
from httpie.output.streams import BINARY_SUPPRESSED_NOTICE
from httpie.plugins import ConverterPlugin
from httpie.plugins.registry import plugin_manager
from .utils import StdinBytesIO, http, MockEnvironment, DUMMY_URL
from .fixtures import (
ASCII_FILE_CONTENT,
BIN_FILE_CONTENT,
BIN_FILE_PATH,
FILE_CONTENT as UNICODE_FILE_CONTENT
)
2014-04-24 14:07:31 +02:00
PRETTY_OPTIONS = list(PRETTY_MAP.keys())
class SortJSONConverterPlugin(ConverterPlugin):
@classmethod
def supports(cls, mime):
return mime == 'json/bytes'
def convert(self, body):
body = body.lstrip(b'\x00')
data = json.loads(body)
return 'application/json', json.dumps(data, sort_keys=True)
2014-04-24 14:07:31 +02:00
2016-03-03 11:47:12 +01:00
# GET because httpbin 500s with binary POST body.
@pytest.mark.skipif(is_windows,
reason='Pretty redirect not supported under Windows')
def test_pretty_redirected_stream(httpbin):
"""Test that --stream works with prettified redirected output."""
env = MockEnvironment(
colors=256,
stdin=StdinBytesIO(BIN_FILE_PATH.read_bytes()),
stdin_isatty=False,
stdout_isatty=False,
)
r = http('--verbose', '--pretty=all', '--stream', 'GET',
2024-03-04 18:12:18 +01:00
httpbin + '/get', env=env)
2016-03-03 11:47:12 +01:00
assert BINARY_SUPPRESSED_NOTICE.decode() in r
def test_pretty_stream_ensure_full_stream_is_retrieved(httpbin):
env = MockEnvironment(
stdin=StdinBytesIO(),
stdin_isatty=False,
stdout_isatty=False,
)
r = http('--pretty=format', '--stream', 'GET',
2024-03-04 18:12:18 +01:00
httpbin + '/stream/3', env=env)
assert r.count('/stream/3') == 3
@pytest.mark.parametrize('pretty', PRETTY_OPTIONS)
@pytest.mark.parametrize('stream', [True, False])
@responses.activate
def test_pretty_options_with_and_without_stream_with_converter(pretty, stream):
plugin_manager.register(SortJSONConverterPlugin)
try:
# Cover PluginManager.__repr__()
assert 'SortJSONConverterPlugin' in str(plugin_manager)
body = b'\x00{"foo":42,\n"bar":"baz"}'
responses.add(responses.GET, DUMMY_URL, body=body,
stream=True, content_type='json/bytes')
args = ['--pretty=' + pretty, 'GET', DUMMY_URL]
if stream:
args.insert(0, '--stream')
r = http(*args)
assert 'json/bytes' in r
if pretty == 'none':
assert BINARY_SUPPRESSED_NOTICE.decode() in r
else:
# Ensure the plugin was effectively used and the resulting JSON is sorted
assert '"bar": "baz",' in r
assert '"foo": 42' in r
finally:
plugin_manager.unregister(SortJSONConverterPlugin)
2016-03-03 11:47:12 +01:00
def test_encoded_stream(httpbin):
"""Test that --stream works with non-prettified
redirected terminal output."""
env = MockEnvironment(
stdin=StdinBytesIO(BIN_FILE_PATH.read_bytes()),
stdin_isatty=False,
)
r = http('--pretty=none', '--stream', '--verbose', 'GET',
2024-03-04 18:12:18 +01:00
httpbin + '/get', env=env)
2016-03-03 11:47:12 +01:00
assert BINARY_SUPPRESSED_NOTICE.decode() in r
def test_redirected_stream(httpbin):
"""Test that --stream works with non-prettified
redirected terminal output."""
env = MockEnvironment(
stdout_isatty=False,
stdin_isatty=False,
stdin=StdinBytesIO(BIN_FILE_PATH.read_bytes()),
)
r = http('--pretty=none', '--stream', '--verbose', 'GET',
2024-03-04 18:12:18 +01:00
httpbin + '/get', env=env)
2016-03-03 11:47:12 +01:00
assert BIN_FILE_CONTENT in r
# /drip endpoint produces 3 individual lines,
# if we set text/event-stream HTTPie should stream
# it by default. Otherwise, it will buffer and then
# print.
@pytest.mark.parametrize('extras, expected', [
(
['Accept:text/event-stream'],
3
),
(
['Accept:text/event-stream; charset=utf-8'],
3
),
(
['Accept:text/plain'],
1
)
])
def test_auto_streaming(http_server, extras, expected):
env = MockEnvironment()
env.stdout.write = Mock()
http(http_server + '/drip', *extras, env=env)
assert len([
call_arg
for call_arg in env.stdout.write.call_args_list
[Major] UI Enhancements (#1321) * Refactor tests to use a text-based standard output. (#1318) * Implement new style `--help` (#1316) * Implement man page generation (#1317) * Implement rich progress bars. (#1324) * Man page deployment & isolation. (#1325) * Remove all unsorted usages in the CLI docs * Implement isolated mode for man page generation * Add a CI job for autogenerated files * Distribute man pages through PyPI * Pin the date for man pages. (#1326) * Hide suppressed arguments from --help/man pages (#1329) * Change download spinner to line (#1328) * Regenerate autogenerated files when pushed against to master. (#1339) * Highlight options (#1340) * Additional man page enhancements (#1341) * Group options by the parent category & highlight -o/--o * Display (and underline) the METAVAR on man pages. * Make help message processing more robust (#1342) * Inherit `help` from `short_help` * Don't mirror short_help directly. * Fixup the serialization * Use `pager` and `man` on `--manual` when applicable (#1343) * Run `man $program` on --manual * Page the output of `--manual` for systems that lack man pages * Improvements over progress bars (separate bar, status line, etc.) (#1346) * Redesign the --help layout. * Make our usage of rich compatible with 9.10.0 * Add `HTTPIE_NO_MAN_PAGES` * Make tests also patch os.get_terminal_size * Generate CLI spec from HTTPie & Man Page Hook (#1354) * Generate CLI spec from HTTPie & add man page hook * Use the full command space for the option headers
2022-04-14 16:43:10 +02:00
if 'test' in call_arg[0][0]
]) == expected
def test_streaming_encoding_detection(http_server):
r = http('--stream', http_server + '/stream/encoding/random')
assert ASCII_FILE_CONTENT in r
assert UNICODE_FILE_CONTENT in r