-
Notifications
You must be signed in to change notification settings - Fork 49
feat: Add JSON indentation option to decode() method #37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
e35585f
fd4c793
44ffada
9f906f9
41a8da5
aa992fd
25ca310
16bfa8f
7f854b5
239e9d2
28dc1ea
089fa56
f4e54ed
c7bdbcf
b53ca61
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -52,12 +52,26 @@ class DecodeOptions: | |||||||||||||||
| Attributes: | ||||||||||||||||
| indent: Number of spaces per indentation level (default: 2) | ||||||||||||||||
| Used for parsing TOON format. | ||||||||||||||||
| strict: Enable strict validation (default: True) | ||||||||||||||||
| Enforces spec conformance checks. | ||||||||||||||||
|
Comment on lines
54
to
+57
|
||||||||||||||||
| indent: Number of spaces per indentation level (default: 2) | |
| Used for parsing TOON format. | |
| strict: Enable strict validation (default: True) | |
| Enforces spec conformance checks. | |
| indent: Number of spaces per indentation level (default: 2). | |
| strict: Enable strict validation (default: True). | |
| Enforces TOON specification conformance checks. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,10 +10,14 @@ | |
| Python type normalization is tested in test_normalization.py. | ||
| """ | ||
|
|
||
| import json | ||
| from typing import Any, Dict, List | ||
|
|
||
| import pytest | ||
|
|
||
| from toon_format import ToonDecodeError, decode, encode | ||
| from toon_format.types import DecodeOptions, EncodeOptions | ||
| from tests.test_spec_fixtures import get_all_decode_fixtures | ||
|
|
||
|
|
||
| class TestEncodeAPI: | ||
|
|
@@ -286,3 +290,111 @@ def test_roundtrip_with_length_marker(self): | |
| toon = encode(original, {"lengthMarker": "#"}) | ||
| decoded = decode(toon) | ||
| assert decoded == original | ||
|
|
||
|
|
||
| class TestDecodeJSONIndentation: | ||
| """Test decode() JSON indentation feature (Issue #10). | ||
|
|
||
| Comprehensive tests for the json_indent feature are in TestDecodeJSONIndentationWithSpecFixtures, | ||
| which validates against official TOON specification fixtures. | ||
| """ | ||
|
|
||
jreakin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| pass | ||
|
|
||
|
|
||
| def _get_sample_decode_fixtures() -> List[tuple]: | ||
|
||
| """Get a sample of decode test cases from fixture files for json_indent testing. | ||
|
|
||
| Selects a few representative test cases from the official TOON spec fixtures. | ||
| """ | ||
| all_fixtures = get_all_decode_fixtures() | ||
|
|
||
| # Select a few representative test cases from different fixture categories | ||
| selected_files = {"primitives.json", "arrays-primitive.json", "objects.json"} | ||
| test_cases = [] | ||
|
|
||
| for test_id, test_data, fixture_name in all_fixtures: | ||
| if f"{fixture_name}.json" in selected_files and len(test_cases) < 9: | ||
| test_cases.append((test_id, test_data)) | ||
|
Comment on lines
+323
to
+325
|
||
|
|
||
| return test_cases | ||
|
|
||
|
|
||
| class TestDecodeJSONIndentationWithSpecFixtures: | ||
| """Test json_indent feature against spec fixtures to ensure comprehensive coverage. | ||
|
|
||
| These tests validate that the json_indent feature works correctly with various | ||
| TOON format patterns defined in the official specification fixtures. | ||
| """ | ||
|
|
||
| @pytest.mark.parametrize("test_id,test_data", _get_sample_decode_fixtures()) | ||
| def test_json_indent_produces_valid_json(self, test_id: str, test_data: Dict[str, Any]): | ||
| """Verify that json_indent produces valid JSON that can be parsed.""" | ||
| input_str = test_data["input"] | ||
| expected = test_data.get("expected") | ||
| should_error = test_data.get("shouldError", False) | ||
|
|
||
| if should_error: | ||
| pytest.skip(f"Skipping error case: {test_id}") | ||
| return | ||
|
|
||
| # Decode with json_indent=2 | ||
| result = decode(input_str, DecodeOptions(json_indent=2)) | ||
|
|
||
| # Result should be a string (JSON) | ||
| assert isinstance(result, str), f"Expected string, got {type(result)} for {test_id}" | ||
|
|
||
| # Result should be valid JSON | ||
| parsed = json.loads(result) | ||
|
|
||
| # Parsed JSON should match the expected output from spec | ||
| assert parsed == expected, ( | ||
| f"JSON mismatch in {test_id}\n" | ||
| f"Input: {input_str!r}\n" | ||
| f"Expected: {expected!r}\n" | ||
| f"Got: {parsed!r}" | ||
| ) | ||
|
|
||
| @pytest.mark.parametrize("test_id,test_data", _get_sample_decode_fixtures()) | ||
| def test_json_indent_with_different_indent_sizes( | ||
| self, test_id: str, test_data: Dict[str, Any] | ||
| ): | ||
| """Verify that json_indent respects different indent sizes.""" | ||
| input_str = test_data["input"] | ||
| expected = test_data.get("expected") | ||
| should_error = test_data.get("shouldError", False) | ||
|
|
||
| if should_error: | ||
| pytest.skip(f"Skipping error case: {test_id}") | ||
| return | ||
|
|
||
| # Test with indent=2 | ||
| result_2 = decode(input_str, DecodeOptions(json_indent=2)) | ||
| parsed_2 = json.loads(result_2) | ||
| assert parsed_2 == expected | ||
|
|
||
| # Test with indent=4 | ||
| result_4 = decode(input_str, DecodeOptions(json_indent=4)) | ||
| parsed_4 = json.loads(result_4) | ||
| assert parsed_4 == expected | ||
|
|
||
| # Different indent sizes should produce different strings (unless single line) | ||
| if "\n" in result_2 and "\n" in result_4: | ||
| # Multi-line results should differ in formatting | ||
| # (indentation characters will be different) | ||
| assert result_2 != result_4 or result_2.count(" ") == result_4.count(" ") | ||
jreakin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| def test_json_indent_consistency_with_plain_decode(self): | ||
| """Verify that json_indent=None produces same data as plain decode.""" | ||
| toon = "user:\n name: Alice\n age: 30" | ||
|
|
||
| # Decode as plain object | ||
| result_object = decode(toon) | ||
|
|
||
| # Decode with json_indent=None | ||
| result_none = decode(toon, DecodeOptions(json_indent=None)) | ||
|
|
||
| # Both should return the same dict | ||
| assert result_object == result_none | ||
| assert isinstance(result_object, dict) | ||
| assert isinstance(result_none, dict) | ||
Uh oh!
There was an error while loading. Please reload this page.