#!/usr/bin/env python3 """ Unit and integration tests for chart.py """ import json import os import subprocess import sys import unittest from pathlib import Path # Add scripts directory to path SCRIPTS_DIR = Path(__file__).resolve().parent sys.path.insert(0, str(SCRIPTS_DIR)) from chart import parse_input_data class TestChartParser(unittest.TestCase): def test_list_of_dicts(self): raw = json.dumps([ {"day": "Mo", "temp": 18}, {"day": "Di", "temp": 22}, {"day": "Mi", "temp": 19}, ]) cols, rows, x, y = parse_input_data(raw) self.assertEqual(cols, ["day", "temp"]) self.assertEqual(len(rows), 3) self.assertEqual(x, "day") self.assertEqual(y, "temp") def test_dict_key_value(self): raw = json.dumps({"Bier": 4.5, "Pizza": 12.0, "Kaffee": 3.2}) cols, rows, x, y = parse_input_data(raw) self.assertEqual(cols, ["category", "value"]) self.assertEqual(len(rows), 3) self.assertEqual(x, "category") self.assertEqual(y, "value") def test_explicit_columns_values(self): raw = json.dumps({ "columns": ["Monat", "Umsatz"], "values": [["Jan", 100], ["Feb", 150]] }) cols, rows, x, y = parse_input_data(raw) self.assertEqual(cols, ["Monat", "Umsatz"]) self.assertEqual(len(rows), 2) self.assertEqual(x, "Monat") self.assertEqual(y, "Umsatz") class TestChartCLI(unittest.TestCase): def run_cli(self, args, stdin_input=None): cmd = [sys.executable, str(SCRIPTS_DIR / "chart.py")] + args res = subprocess.run( cmd, input=stdin_input, capture_output=True, text=True, timeout=30, ) return res def test_bar_chart_generation(self): data = json.dumps([ {"label": "Projekt A", "stunden": 14}, {"label": "Projekt B", "stunden": 28}, {"label": "Projekt C", "stunden": 8}, ]) out_path = Path("/tmp/charts/test_bar.png") if out_path.exists(): out_path.unlink() res = self.run_cli(["--type", "bar", "--title", "Projektstunden", "--data", data, "--output", str(out_path)]) self.assertEqual(res.returncode, 0, f"Stderr: {res.stderr}") self.assertTrue(res.stdout.strip().startswith("MEDIA:")) self.assertTrue(out_path.exists()) self.assertGreater(out_path.stat().st_size, 1000) def test_line_chart_stdin(self): data = json.dumps([ {"datum": "2026-09-10", "puls": 62}, {"datum": "2026-09-11", "puls": 58}, {"datum": "2026-09-12", "puls": 65}, {"datum": "2026-09-13", "puls": 59}, ]) out_path = Path("/tmp/charts/test_line.png") if out_path.exists(): out_path.unlink() res = self.run_cli(["--type", "line", "--title", "Ruhepuls Verlauf", "--data", "-", "--output", str(out_path)], stdin_input=data) self.assertEqual(res.returncode, 0, f"Stderr: {res.stderr}") self.assertTrue(res.stdout.strip().startswith("MEDIA:")) self.assertTrue(out_path.exists()) self.assertGreater(out_path.stat().st_size, 1000) def test_donut_chart(self): data = json.dumps([ {"bereich": "Wohnen", "kosten": 950}, {"bereich": "Essen", "kosten": 450}, {"bereich": "Mobilität", "kosten": 120}, {"bereich": "Freizeit", "kosten": 200}, ]) out_path = Path("/tmp/charts/test_donut.png") if out_path.exists(): out_path.unlink() res = self.run_cli(["--type", "donut", "--title", "Ausgaben", "--data", data, "--output", str(out_path)]) self.assertEqual(res.returncode, 0, f"Stderr: {res.stderr}") self.assertTrue(res.stdout.strip().startswith("MEDIA:")) self.assertTrue(out_path.exists()) self.assertGreater(out_path.stat().st_size, 1000) def test_quickchart_fallback_engine(self): data = json.dumps([ {"fach": "Mathe", "note": 1.7}, {"fach": "Physik", "note": 2.0}, {"fach": "Informatik", "note": 1.0}, ]) out_path = Path("/tmp/charts/test_quickchart.png") if out_path.exists(): out_path.unlink() res = self.run_cli(["--engine", "quickchart", "--type", "bar", "--title", "Notenspiegel", "--data", data, "--output", str(out_path)]) self.assertEqual(res.returncode, 0, f"Stderr: {res.stderr}") self.assertTrue(res.stdout.strip().startswith("MEDIA:")) self.assertTrue(out_path.exists()) self.assertGreater(out_path.stat().st_size, 1000) if __name__ == "__main__": unittest.main()