Files
OpenBB/cli/tests/test_outputs_json.py
Danglewood 9a30186174 [V5] CLI 2.0 - Pluggable Backends, Non-TTY Default, HTTP Dispatcher, Spec Files + Codegen (#7433)
* stash some changes

* add more robust testing

* mypy

* point PR at V5

* introduce spec file

* codespell

* test fix

* fix workflow environment setup

* fix workflow environment setup

* fix workflow environment setup

* add pyyaml to dependencies

* split lint jobs

* fix workflow environment setup

* fix workflow environment setup

* workflow env setup

* workflow env setup

* clean up code comments

* add auth hook entrypoints

* codespell

* add codegen feature

* codespell

* move _unpack into dispatchers for consistency with codegen packages

* surface nested models in the response

* fix missing coverage in CI

* socrata updates

* test fix

* detect plotly output

* add --include and --exclude flags from generate-extension command

* cap test matrix at python 3.14

* no useless comments

* platform controller command description split

* merge URL overloads from path params

* exclude none and unset from model dump

---------

Co-authored-by: deeleeramone <>
Co-authored-by: Copilot <copilot@github.com>
2026-06-01 19:14:38 +03:00

104 lines
2.8 KiB
Python

"""Tests for JsonOutput adapter."""
import json
from unittest.mock import Mock
import pandas as pd
import pytest
from openbb_cli.outputs.json import JsonOutput, _to_serializable
@pytest.fixture()
def json_output():
return JsonOutput()
def _captured_json(capsys):
out = capsys.readouterr().out.strip()
return json.loads(out) if out else None
def test_export_true_produces_no_output(json_output, capsys):
json_output.display(data={"key": "val"}, export=True)
assert capsys.readouterr().out == ""
def test_obbject_with_list_results(json_output, capsys):
mock_obj = Mock()
mock_obj.model_dump.return_value = {"results": [{"a": 1}, {"b": 2}]}
json_output.display(data=mock_obj)
assert _captured_json(capsys) == [{"a": 1}, {"b": 2}]
def test_obbject_with_dict_results(json_output, capsys):
mock_obj = Mock()
mock_obj.model_dump.return_value = {"results": {"x": 10}}
json_output.display(data=mock_obj)
assert _captured_json(capsys) == {"x": 10}
def test_dataframe(json_output, capsys):
df = pd.DataFrame({"col": [1, 2]})
json_output.display(data=df)
assert _captured_json(capsys) == [{"col": 1}, {"col": 2}]
def test_series(json_output, capsys):
s = pd.Series({"a": 1, "b": 2})
json_output.display(data=s)
assert _captured_json(capsys) == {"a": 1, "b": 2}
def test_scalar(json_output, capsys):
json_output.display(data=42)
assert _captured_json(capsys) == 42
def test_none_data(json_output, capsys):
json_output.display(data=None)
assert capsys.readouterr().out.strip() == "null"
def test_serialization_failure_emits_error_envelope(json_output, capsys):
"""First dumps() raises → error envelope is dumped via the original."""
bad = {"k": object()}
import openbb_cli.outputs.json as mod
original = mod.json.dumps
calls = {"n": 0}
def maybe_failing(*args, **kwargs):
calls["n"] += 1
if calls["n"] == 1:
raise TypeError("not serializable")
return original(*args, **kwargs)
mod.json.dumps = maybe_failing
try:
json_output.display(data=bad)
finally:
mod.json.dumps = original
payload = json.loads(capsys.readouterr().out.strip())
assert payload["error"]["type"] == "TypeError"
assert "not serializable" in payload["error"]["message"]
def test_no_ansi_in_output(json_output, capsys):
json_output.display(data={"a": 1})
assert "\x1b[" not in capsys.readouterr().out
def test_to_serializable_passthrough_primitives():
assert _to_serializable(42) == 42
assert _to_serializable(None) is None
assert _to_serializable("x") == "x"
def test_to_serializable_obbject_extracts_results():
mock_obj = Mock()
mock_obj.model_dump.return_value = {"results": [1, 2, 3]}
assert _to_serializable(mock_obj) == [1, 2, 3]