test_output.py
1 # Copyright 2026 Alibaba Group Holding Ltd. 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 15 """Tests for opensandbox_cli.output — table, JSON, YAML rendering.""" 16 17 from __future__ import annotations 18 19 import json 20 21 import pytest 22 from pydantic import BaseModel 23 24 from opensandbox_cli.output import OutputFormatter 25 26 # --------------------------------------------------------------------------- 27 # Test models 28 # --------------------------------------------------------------------------- 29 30 31 class FakeItem(BaseModel): 32 id: str 33 name: str 34 score: int 35 36 37 # --------------------------------------------------------------------------- 38 # JSON output 39 # --------------------------------------------------------------------------- 40 41 42 class TestJsonOutput: 43 def test_print_dict(self, capsys: pytest.CaptureFixture[str]) -> None: 44 fmt = OutputFormatter("json", color=False) 45 fmt.print_dict({"key": "value", "num": 42}) 46 captured = capsys.readouterr() 47 data = json.loads(captured.out) 48 assert data == {"key": "value", "num": 42} 49 50 def test_print_model(self, capsys: pytest.CaptureFixture[str]) -> None: 51 fmt = OutputFormatter("json", color=False) 52 item = FakeItem(id="abc", name="test", score=100) 53 fmt.print_model(item) 54 captured = capsys.readouterr() 55 data = json.loads(captured.out) 56 assert data["id"] == "abc" 57 assert data["name"] == "test" 58 assert data["score"] == 100 59 60 def test_print_models(self, capsys: pytest.CaptureFixture[str]) -> None: 61 fmt = OutputFormatter("json", color=False) 62 items = [ 63 FakeItem(id="1", name="a", score=10), 64 FakeItem(id="2", name="b", score=20), 65 ] 66 fmt.print_models(items, columns=["id", "name", "score"]) 67 captured = capsys.readouterr() 68 data = json.loads(captured.out) 69 assert len(data) == 2 70 assert data[0]["id"] == "1" 71 assert data[1]["name"] == "b" 72 73 def test_success_renders_structured_json(self, capsys: pytest.CaptureFixture[str]) -> None: 74 fmt = OutputFormatter("json", color=False) 75 fmt.success("done") 76 captured = capsys.readouterr() 77 data = json.loads(captured.out) 78 assert data == {"status": "ok", "message": "done"} 79 80 81 # --------------------------------------------------------------------------- 82 # YAML output 83 # --------------------------------------------------------------------------- 84 85 86 class TestYamlOutput: 87 def test_print_dict(self, capsys: pytest.CaptureFixture[str]) -> None: 88 fmt = OutputFormatter("yaml", color=False) 89 fmt.print_dict({"key": "value"}) 90 captured = capsys.readouterr() 91 assert "key: value" in captured.out 92 93 def test_print_model(self, capsys: pytest.CaptureFixture[str]) -> None: 94 fmt = OutputFormatter("yaml", color=False) 95 item = FakeItem(id="x", name="y", score=5) 96 fmt.print_model(item) 97 captured = capsys.readouterr() 98 assert "id: x" in captured.out 99 assert "name: y" in captured.out 100 assert "score: 5" in captured.out 101 102 103 # --------------------------------------------------------------------------- 104 # Table output 105 # --------------------------------------------------------------------------- 106 107 108 class TestTableOutput: 109 def test_print_dict_contains_values(self, capsys: pytest.CaptureFixture[str]) -> None: 110 fmt = OutputFormatter("table", color=False) 111 fmt.print_dict({"host": "example.com", "port": 8080}, title="Config") 112 captured = capsys.readouterr() 113 assert "example.com" in captured.out 114 assert "8080" in captured.out 115 assert "Config" in captured.out 116 117 def test_print_dict_none_renders_dash(self, capsys: pytest.CaptureFixture[str]) -> None: 118 fmt = OutputFormatter("table", color=False) 119 fmt.print_dict({"key": None}) 120 captured = capsys.readouterr() 121 assert "-" in captured.out 122 123 def test_print_models_shows_headers(self, capsys: pytest.CaptureFixture[str]) -> None: 124 fmt = OutputFormatter("table", color=False) 125 items = [FakeItem(id="1", name="a", score=10)] 126 fmt.print_models(items, columns=["id", "name", "score"], title="Items") 127 captured = capsys.readouterr() 128 assert "ID" in captured.out 129 assert "NAME" in captured.out 130 assert "SCORE" in captured.out 131 132 def test_print_text_ignores_format(self, capsys: pytest.CaptureFixture[str]) -> None: 133 fmt = OutputFormatter("json", color=False) 134 fmt.print_text("hello world") 135 captured = capsys.readouterr() 136 assert captured.out.strip() == "hello world"