@@ -1,116 +1,226 @@
|
||||
"""Tests for the converter module."""
|
||||
"""Tests for format converters."""
|
||||
|
||||
import json
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from configconverter.converters import Converter
|
||||
from configconverter.exceptions import ParseError, InvalidFormatError, UnsupportedConversionError
|
||||
from config_converter.converters import (
|
||||
JsonConverter,
|
||||
YamlConverter,
|
||||
TomlConverter,
|
||||
IniConverter,
|
||||
BaseConverter,
|
||||
ConversionError,
|
||||
)
|
||||
|
||||
|
||||
class TestConverter:
|
||||
"""Tests for the Converter class."""
|
||||
class TestJsonConverter:
|
||||
"""Tests for JSON converter."""
|
||||
|
||||
@pytest.fixture
|
||||
def converter(self):
|
||||
return Converter()
|
||||
def setup_method(self) -> None:
|
||||
self.converter = JsonConverter()
|
||||
|
||||
def test_detect_json_format(self, converter):
|
||||
content = '{"name": "test", "value": 123}'
|
||||
assert converter.detect_format(content) == "json"
|
||||
def test_read_valid_json(self) -> None:
|
||||
"""Test reading valid JSON file."""
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
|
||||
json.dump({"key": "value", "number": 42}, f)
|
||||
f.flush()
|
||||
result = self.converter.read(f.name)
|
||||
assert result == {"key": "value", "number": 42}
|
||||
|
||||
def test_detect_json_array(self, converter):
|
||||
content = '[{"id": 1}, {"id": 2}]'
|
||||
assert converter.detect_format(content) == "json"
|
||||
def test_read_invalid_json(self) -> None:
|
||||
"""Test reading invalid JSON raises error."""
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
|
||||
f.write("{invalid json}")
|
||||
f.flush()
|
||||
with pytest.raises(ConversionError):
|
||||
self.converter.read(f.name)
|
||||
|
||||
def test_detect_yaml_format(self, converter):
|
||||
content = 'name: test\nvalue: 123\n'
|
||||
assert converter.detect_format(content) == "yaml"
|
||||
def test_read_file_not_found(self) -> None:
|
||||
"""Test reading non-existent file raises error."""
|
||||
with pytest.raises(ConversionError):
|
||||
self.converter.read("/nonexistent/path/file.json")
|
||||
|
||||
def test_detect_toml_format(self, converter):
|
||||
content = 'name = "test"\nvalue = 123\n'
|
||||
result = converter.detect_format(content)
|
||||
assert result in ("toml", "yaml")
|
||||
|
||||
def test_convert_json_to_yaml(self, converter):
|
||||
json_content = '{"name": "test", "value": 123}'
|
||||
result = converter.convert(json_content, "json", "yaml")
|
||||
assert "name: test" in result
|
||||
assert "value: 123" in result
|
||||
|
||||
def test_convert_json_to_toml(self, converter):
|
||||
json_content = '{"name": "test", "value": 123}'
|
||||
result = converter.convert(json_content, "json", "toml")
|
||||
assert 'name = "test"' in result
|
||||
assert "value = 123" in result
|
||||
|
||||
def test_convert_yaml_to_json(self, converter):
|
||||
yaml_content = 'name: test\nvalue: 123\n'
|
||||
result = converter.convert(yaml_content, "yaml", "json")
|
||||
data = json.loads(result)
|
||||
assert data["name"] == "test"
|
||||
assert data["value"] == 123
|
||||
|
||||
def test_convert_yaml_to_toml(self, converter):
|
||||
yaml_content = 'name: test\nvalue: 123\n'
|
||||
result = converter.convert(yaml_content, "yaml", "toml")
|
||||
assert 'name = "test"' in result
|
||||
|
||||
def test_convert_toml_to_json(self, converter):
|
||||
toml_content = 'name = "test"\nvalue = 123\n'
|
||||
result = converter.convert(toml_content, "toml", "json")
|
||||
data = json.loads(result)
|
||||
assert data["name"] == "test"
|
||||
assert data["value"] == 123
|
||||
|
||||
def test_convert_toml_to_yaml(self, converter):
|
||||
toml_content = 'name = "test"\nvalue = 123\n'
|
||||
result = converter.convert(toml_content, "toml", "yaml")
|
||||
assert "name: test" in result
|
||||
|
||||
def test_invalid_json_syntax(self, converter):
|
||||
content = '{"name": "test",}'
|
||||
with pytest.raises(ParseError):
|
||||
converter.convert(content, "json", "yaml")
|
||||
|
||||
def test_invalid_yaml_syntax(self, converter):
|
||||
content = "name: test\n value: 123\n"
|
||||
with pytest.raises(ParseError):
|
||||
converter.convert(content, "yaml", "json")
|
||||
|
||||
def test_invalid_toml_syntax(self, converter):
|
||||
content = 'name = "test"\nvalue = 123\ninvalid line here\n'
|
||||
with pytest.raises(ParseError):
|
||||
converter.convert(content, "toml", "json")
|
||||
|
||||
def test_unsupported_format(self, converter):
|
||||
content = "some random text that is not valid"
|
||||
def test_write_json(self) -> None:
|
||||
"""Test writing JSON file."""
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
|
||||
output_path = f.name
|
||||
try:
|
||||
converter.detect_format(content)
|
||||
except (InvalidFormatError, Exception):
|
||||
pass
|
||||
self.converter.write({"test": "data"}, output_path)
|
||||
with open(output_path, "r") as f:
|
||||
result = json.load(f)
|
||||
assert result == {"test": "data"}
|
||||
finally:
|
||||
Path(output_path).unlink(missing_ok=True)
|
||||
|
||||
def test_unsupported_conversion_direction(self, converter):
|
||||
content = '{"name": "test"}'
|
||||
with pytest.raises(UnsupportedConversionError):
|
||||
converter.convert(content, "json", "xml")
|
||||
def test_parse_json_string(self) -> None:
|
||||
"""Test parsing JSON string."""
|
||||
result = self.converter.parse('{"key": "value"}')
|
||||
assert result == {"key": "value"}
|
||||
|
||||
def test_nested_structure_json_to_yaml(self, converter):
|
||||
json_content = json.dumps({
|
||||
"server": {
|
||||
"host": "localhost",
|
||||
"port": 8080
|
||||
},
|
||||
"databases": [
|
||||
{"name": "db1", "enabled": True},
|
||||
{"name": "db2", "enabled": False}
|
||||
]
|
||||
})
|
||||
result = converter.convert(json_content, "json", "yaml")
|
||||
assert "server:" in result
|
||||
assert "host: localhost" in result
|
||||
assert "databases:" in result
|
||||
def test_format_json_string(self) -> None:
|
||||
"""Test formatting data to JSON string."""
|
||||
result = self.converter.format({"key": "value"})
|
||||
assert result == '{\n "key": "value"\n}'
|
||||
|
||||
def test_case_insensitive_format(self, converter):
|
||||
json_content = '{"name": "test"}'
|
||||
result = converter.convert(json_content, "JSON", "YAML")
|
||||
assert "name: test" in result
|
||||
|
||||
class TestYamlConverter:
|
||||
"""Tests for YAML converter."""
|
||||
|
||||
def setup_method(self) -> None:
|
||||
self.converter = YamlConverter()
|
||||
|
||||
def test_read_valid_yaml(self) -> None:
|
||||
"""Test reading valid YAML file."""
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
|
||||
f.write("key: value\nnumber: 42\n")
|
||||
f.flush()
|
||||
result = self.converter.read(f.name)
|
||||
assert result == {"key": "value", "number": 42}
|
||||
|
||||
def test_read_yaml_with_yml_extension(self) -> None:
|
||||
"""Test reading YAML file with yml extension."""
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".yml", delete=False) as f:
|
||||
f.write("key: value\n")
|
||||
f.flush()
|
||||
result = self.converter.read(f.name)
|
||||
assert result == {"key": "value"}
|
||||
|
||||
def test_write_yaml(self) -> None:
|
||||
"""Test writing YAML file."""
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
|
||||
output_path = f.name
|
||||
try:
|
||||
self.converter.write({"test": "data"}, output_path)
|
||||
with open(output_path, "r") as f:
|
||||
result = f.read()
|
||||
assert "test: data" in result
|
||||
finally:
|
||||
Path(output_path).unlink(missing_ok=True)
|
||||
|
||||
def test_parse_yaml_string(self) -> None:
|
||||
"""Test parsing YAML string."""
|
||||
result = self.converter.parse("key: value")
|
||||
assert result == {"key": "value"}
|
||||
|
||||
|
||||
class TestTomlConverter:
|
||||
"""Tests for TOML converter."""
|
||||
|
||||
def setup_method(self) -> None:
|
||||
self.converter = TomlConverter()
|
||||
|
||||
def test_read_valid_toml(self) -> None:
|
||||
"""Test reading valid TOML file."""
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f:
|
||||
f.write('key = "value"\nnumber = 42\n')
|
||||
f.flush()
|
||||
result = self.converter.read(f.name)
|
||||
assert result["key"] == "value"
|
||||
assert result["number"] == 42
|
||||
|
||||
def test_write_toml(self) -> None:
|
||||
"""Test writing TOML file."""
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f:
|
||||
output_path = f.name
|
||||
try:
|
||||
self.converter.write({"test": "data"}, output_path)
|
||||
with open(output_path, "r") as f:
|
||||
result = f.read()
|
||||
assert 'test = "data"' in result
|
||||
finally:
|
||||
Path(output_path).unlink(missing_ok=True)
|
||||
|
||||
def test_parse_toml_string(self) -> None:
|
||||
"""Test parsing TOML string."""
|
||||
result = self.converter.parse('key = "value"')
|
||||
assert result["key"] == "value"
|
||||
|
||||
|
||||
class TestIniConverter:
|
||||
"""Tests for INI converter."""
|
||||
|
||||
def setup_method(self) -> None:
|
||||
self.converter = IniConverter()
|
||||
|
||||
def test_read_valid_ini(self) -> None:
|
||||
"""Test reading valid INI file."""
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".ini", delete=False) as f:
|
||||
f.write("[section]\nkey = value\n")
|
||||
f.flush()
|
||||
result = self.converter.read(f.name)
|
||||
assert "section" in result
|
||||
assert result["section"]["key"] == "value"
|
||||
|
||||
def test_write_ini(self) -> None:
|
||||
"""Test writing INI file."""
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".ini", delete=False) as f:
|
||||
output_path = f.name
|
||||
try:
|
||||
self.converter.write({"section": {"key": "value"}}, output_path)
|
||||
with open(output_path, "r") as f:
|
||||
result = f.read()
|
||||
assert "[section]" in result
|
||||
finally:
|
||||
Path(output_path).unlink(missing_ok=True)
|
||||
|
||||
def test_parse_ini_string(self) -> None:
|
||||
"""Test parsing INI string."""
|
||||
result = self.converter.parse("[section]\nkey = value")
|
||||
assert "section" in result
|
||||
|
||||
|
||||
class TestBaseConverter:
|
||||
"""Tests for base converter."""
|
||||
|
||||
def test_get_converter_json(self) -> None:
|
||||
"""Test getting JSON converter."""
|
||||
converter = BaseConverter.get_converter("json")
|
||||
assert isinstance(converter, JsonConverter)
|
||||
|
||||
def test_get_converter_yaml(self) -> None:
|
||||
"""Test getting YAML converter."""
|
||||
converter = BaseConverter.get_converter("yaml")
|
||||
assert isinstance(converter, YamlConverter)
|
||||
|
||||
def test_get_converter_toml(self) -> None:
|
||||
"""Test getting TOML converter."""
|
||||
converter = BaseConverter.get_converter("toml")
|
||||
assert isinstance(converter, TomlConverter)
|
||||
|
||||
def test_get_converter_ini(self) -> None:
|
||||
"""Test getting INI converter."""
|
||||
converter = BaseConverter.get_converter("ini")
|
||||
assert isinstance(converter, IniConverter)
|
||||
|
||||
def test_get_converter_unsupported(self) -> None:
|
||||
"""Test getting unsupported converter raises error."""
|
||||
with pytest.raises(ConversionError):
|
||||
BaseConverter.get_converter("unsupported")
|
||||
|
||||
def test_guess_format_json(self) -> None:
|
||||
"""Test guessing JSON format from extension."""
|
||||
assert BaseConverter.guess_format("file.json") == "json"
|
||||
|
||||
def test_guess_format_yaml(self) -> None:
|
||||
"""Test guessing YAML format from extension."""
|
||||
assert BaseConverter.guess_format("file.yaml") == "yaml"
|
||||
assert BaseConverter.guess_format("file.yml") == "yaml"
|
||||
|
||||
def test_guess_format_toml(self) -> None:
|
||||
"""Test guessing TOML format from extension."""
|
||||
assert BaseConverter.guess_format("file.toml") == "toml"
|
||||
|
||||
def test_guess_format_ini(self) -> None:
|
||||
"""Test guessing INI format from extension."""
|
||||
assert BaseConverter.guess_format("file.ini") == "ini"
|
||||
|
||||
def test_get_supported_formats(self) -> None:
|
||||
"""Test getting supported formats."""
|
||||
formats = BaseConverter.get_supported_formats()
|
||||
assert "json" in formats
|
||||
assert "yaml" in formats
|
||||
assert "toml" in formats
|
||||
assert "ini" in formats
|
||||
|
||||
Reference in New Issue
Block a user