Coverage for lintro / formatters / styles / json.py: 100%
23 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""JSON output style implementation."""
3import json
4from datetime import datetime
5from typing import Any
7from lintro.formatters.core.format_registry import OutputStyle
10class JsonStyle(OutputStyle):
11 """Output format that renders data as structured JSON."""
13 def format(
14 self,
15 columns: list[str],
16 rows: list[list[Any]],
17 tool_name: str | None = None,
18 **kwargs: Any,
19 ) -> str:
20 """Format a table given columns and rows as structured JSON.
22 Args:
23 columns: List of column names.
24 rows: List of row values (each row is a list of cell values).
25 tool_name: Name of the tool that generated the data.
26 **kwargs: Additional metadata; `metadata` can be provided here.
28 Returns:
29 Formatted data as structured JSON string.
30 """
31 metadata: dict[str, Any] | None = kwargs.pop("metadata", None)
32 # Convert column names to standardized format
33 normalized_columns = [col.lower().replace(" ", "_") for col in columns]
35 # Convert rows to list of dictionaries with proper data types
36 issues: list[dict[str, Any]] = []
37 for row in rows:
38 issue_dict: dict[str, Any] = {}
39 for i, value in enumerate(row):
40 if i < len(normalized_columns):
41 issue_dict[normalized_columns[i]] = value
42 issues.append(issue_dict)
44 # Create the final JSON structure
45 result: dict[str, Any] = {
46 "tool": tool_name,
47 "timestamp": datetime.now().isoformat(),
48 "total_issues": len(issues),
49 "issues": issues,
50 }
52 # Add metadata if provided
53 if metadata:
54 result["metadata"] = metadata
56 # Add any additional kwargs as metadata
57 if kwargs:
58 if "metadata" not in result:
59 result["metadata"] = {}
60 result["metadata"].update(kwargs)
62 return json.dumps(result, indent=2, ensure_ascii=False)