Files
zig-fetch-py/tests/test_parser.py
crosstyan fd29f7e3af Enhance ZON parser to support tuples and update documentation
- Modify parser to handle ZON tuples (`.{ 1, 2, 3 }`) as arrays
- Update README with more detailed explanation of ZON tuple syntax
- Add multiple example ZON files demonstrating tuple usage
- Implement tuple parsing in `parser.py`
- Add test case for tuple parsing
2025-03-07 17:01:12 +08:00

208 lines
5.8 KiB
Python

"""
Unit tests for the ZON parser.
"""
import json
import pytest
from pathlib import Path
from zig_fetch_py.parser import ZonParser, parse_zon_file, zon_to_json
class TestZonParser:
"""Test cases for the ZonParser class."""
def test_parse_empty_object(self):
"""Test parsing an empty object."""
parser = ZonParser(".{}")
result = parser.parse()
assert result == {}
def test_parse_simple_object(self):
"""Test parsing a simple object with string values."""
parser = ZonParser(
""".{
.name = "test",
.version = "1.0.0",
}"""
)
result = parser.parse()
assert result == {"name": "test", "version": "1.0.0"}
def test_parse_nested_object(self):
"""Test parsing a nested object."""
parser = ZonParser(
""".{
.metadata = .{
.name = "test",
.version = "1.0.0",
},
}"""
)
result = parser.parse()
assert result == {"metadata": {"name": "test", "version": "1.0.0"}}
def test_parse_array(self):
"""Test parsing an array."""
parser = ZonParser(
""".{
.tags = .["tag1", "tag2", "tag3"],
}"""
)
result = parser.parse()
assert result == {"tags": ["tag1", "tag2", "tag3"]}
def test_parse_numbers(self):
"""Test parsing different number formats."""
parser = ZonParser(
""".{
.integer = 42,
.negative = -10,
.float = 3.14,
.hex = 0xDEADBEEF,
}"""
)
result = parser.parse()
assert result == {
"integer": 42,
"negative": -10,
"float": 3.14,
"hex": 0xDEADBEEF,
}
def test_parse_boolean(self):
"""Test parsing boolean values."""
parser = ZonParser(
""".{
.is_true = true,
.is_false = false,
}"""
)
result = parser.parse()
assert result == {"is_true": True, "is_false": False}
def test_parse_null(self):
"""Test parsing null values."""
parser = ZonParser(
""".{
.nothing = null,
}"""
)
result = parser.parse()
assert result == {"nothing": None}
def test_parse_comments(self):
"""Test parsing with comments."""
parser = ZonParser(
""".{
// This is a comment
.name = "test", // Inline comment
// Another comment
.version = "1.0.0",
}"""
)
result = parser.parse()
assert result == {"name": "test", "version": "1.0.0"}
def test_parse_special_identifiers(self):
"""Test parsing special identifiers with @ symbol."""
parser = ZonParser(
""".{
.@"special-name" = "value",
}"""
)
result = parser.parse()
assert result == {"special-name": "value"}
def test_parse_shorthand_notation(self):
"""Test parsing shorthand notation where key is the same as value."""
parser = ZonParser(
""".{
.name,
.version,
}"""
)
result = parser.parse()
assert result == {"name": "name", "version": "version"}
def test_parse_escaped_strings(self):
"""Test parsing strings with escape sequences."""
parser = ZonParser(
""".{
.escaped = "Line 1\\nLine 2\\tTabbed\\r\\n",
}"""
)
result = parser.parse()
assert result == {"escaped": "Line 1\nLine 2\tTabbed\r\n"}
def test_parse_error_invalid_syntax(self):
"""Test that parser raises an error for invalid syntax."""
with pytest.raises(ValueError):
parser = ZonParser(".{,}")
parser.parse()
def test_parse_error_unterminated_string(self):
"""Test that parser raises an error for unterminated strings."""
with pytest.raises(ValueError):
parser = ZonParser(
""".{
.name = "unterminated,
}"""
)
parser.parse()
def test_parse_tuple(self):
"""Test parsing tuples."""
parser = ZonParser(
""".{
.simple_tuple = .{1, 2, 3},
.string_tuple = .{"one", "two", "three"},
.empty_tuple = .{""},
.mixed_tuple = .{1, "two", true},
}"""
)
result = parser.parse()
assert result == {
"simple_tuple": [1, 2, 3],
"string_tuple": ["one", "two", "three"],
"empty_tuple": [""],
"mixed_tuple": [1, "two", True],
}
class TestZonFileParser:
"""Test cases for the file parsing functions."""
def test_zon_to_json(self, tmp_path):
"""Test converting ZON to JSON."""
zon_content = """.{
.name = "test",
.version = "1.0.0",
}"""
# Test without indentation
json_str = zon_to_json(zon_content)
parsed_json = json.loads(json_str)
assert parsed_json == {"name": "test", "version": "1.0.0"}
# Test with indentation
json_str_pretty = zon_to_json(zon_content, indent=2)
assert " " in json_str_pretty # Should have indentation
parsed_json = json.loads(json_str_pretty)
assert parsed_json == {"name": "test", "version": "1.0.0"}
def test_parse_zon_file(self, tmp_path):
"""Test parsing a ZON file."""
# Create a temporary ZON file
zon_file = tmp_path / "test.zon"
zon_file.write_text(
""".{
.name = "test",
.version = "1.0.0",
}"""
)
# Parse the file
result = parse_zon_file(str(zon_file))
assert result == {"name": "test", "version": "1.0.0"}