Add tests, fixtures, and CI/CD workflow
Some checks failed
CI / test (ubuntu-latest, 3.10) (push) Has been cancelled
CI / test (ubuntu-latest, 3.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (push) Has been cancelled
CI / test (ubuntu-latest, 3.8) (push) Has been cancelled
CI / test (ubuntu-latest, 3.9) (push) Has been cancelled
CI / test-minimal (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / build (push) Has been cancelled
CI / release (push) Has been cancelled
Some checks failed
CI / test (ubuntu-latest, 3.10) (push) Has been cancelled
CI / test (ubuntu-latest, 3.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (push) Has been cancelled
CI / test (ubuntu-latest, 3.8) (push) Has been cancelled
CI / test (ubuntu-latest, 3.9) (push) Has been cancelled
CI / test-minimal (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / build (push) Has been cancelled
CI / release (push) Has been cancelled
This commit is contained in:
185
tests/test_dataforge_commands.py
Normal file
185
tests/test_dataforge_commands.py
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
"""Tests for CLI commands."""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from click.testing import CliRunner
|
||||||
|
|
||||||
|
from dataforge.cli import main
|
||||||
|
from dataforge.commands import convert, validate, batch_validate, typecheck
|
||||||
|
|
||||||
|
|
||||||
|
FIXTURES_DIR = os.path.join(os.path.dirname(__file__), "dataforge_fixtures")
|
||||||
|
|
||||||
|
|
||||||
|
class TestConvertCommand:
|
||||||
|
"""Tests for convert command."""
|
||||||
|
|
||||||
|
def test_convert_json_to_yaml(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
input_file = os.path.join(FIXTURES_DIR, "sample.json")
|
||||||
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
|
||||||
|
output_file = f.name
|
||||||
|
try:
|
||||||
|
result = runner.invoke(convert, [input_file, output_file, "--to", "yaml"])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
with open(output_file, "r") as f:
|
||||||
|
content = f.read()
|
||||||
|
assert "name:" in content
|
||||||
|
assert "test-project" in content
|
||||||
|
finally:
|
||||||
|
os.unlink(output_file)
|
||||||
|
|
||||||
|
def test_convert_yaml_to_toml(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
input_file = os.path.join(FIXTURES_DIR, "sample.yaml")
|
||||||
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f:
|
||||||
|
output_file = f.name
|
||||||
|
try:
|
||||||
|
result = runner.invoke(convert, [input_file, output_file, "--to", "toml"])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
with open(output_file, "r") as f:
|
||||||
|
content = f.read()
|
||||||
|
assert "name =" in content
|
||||||
|
finally:
|
||||||
|
os.unlink(output_file)
|
||||||
|
|
||||||
|
def test_convert_with_explicit_format(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
input_file = os.path.join(FIXTURES_DIR, "sample.json")
|
||||||
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
|
||||||
|
output_file = f.name
|
||||||
|
try:
|
||||||
|
result = runner.invoke(convert, [input_file, output_file, "--from", "json", "--to", "yaml"])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
finally:
|
||||||
|
os.unlink(output_file)
|
||||||
|
|
||||||
|
def test_convert_invalid_format(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
input_file = os.path.join(FIXTURES_DIR, "sample.json")
|
||||||
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as f:
|
||||||
|
output_file = f.name
|
||||||
|
try:
|
||||||
|
result = runner.invoke(convert, [input_file, output_file, "--to", "invalid"])
|
||||||
|
assert result.exit_code != 0
|
||||||
|
finally:
|
||||||
|
os.unlink(output_file)
|
||||||
|
|
||||||
|
def test_convert_compact_output(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
input_file = os.path.join(FIXTURES_DIR, "sample.json")
|
||||||
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
|
||||||
|
output_file = f.name
|
||||||
|
try:
|
||||||
|
result = runner.invoke(convert, [input_file, output_file, "--to", "json", "--indent", "0"])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
with open(output_file, "r") as f:
|
||||||
|
content = f.read()
|
||||||
|
assert "\n" not in content
|
||||||
|
finally:
|
||||||
|
os.unlink(output_file)
|
||||||
|
|
||||||
|
|
||||||
|
class TestValidateCommand:
|
||||||
|
"""Tests for validate command."""
|
||||||
|
|
||||||
|
def test_validate_valid_file(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
input_file = os.path.join(FIXTURES_DIR, "sample.json")
|
||||||
|
schema_file = os.path.join(FIXTURES_DIR, "valid_schema.json")
|
||||||
|
result = runner.invoke(validate, [input_file, "--schema", schema_file])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "passed" in result.output
|
||||||
|
|
||||||
|
def test_validate_invalid_file(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
schema_file = os.path.join(FIXTURES_DIR, "valid_schema.json")
|
||||||
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
|
||||||
|
json.dump({"name": "test", "version": "invalid"}, f)
|
||||||
|
invalid_file = f.name
|
||||||
|
try:
|
||||||
|
result = runner.invoke(validate, [invalid_file, "--schema", schema_file])
|
||||||
|
assert result.exit_code != 0
|
||||||
|
finally:
|
||||||
|
os.unlink(invalid_file)
|
||||||
|
|
||||||
|
def test_validate_without_schema(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
input_file = os.path.join(FIXTURES_DIR, "sample.json")
|
||||||
|
result = runner.invoke(validate, [input_file])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
def test_validate_quiet_mode(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
input_file = os.path.join(FIXTURES_DIR, "sample.json")
|
||||||
|
schema_file = os.path.join(FIXTURES_DIR, "valid_schema.json")
|
||||||
|
result = runner.invoke(validate, [input_file, "--schema", schema_file, "--quiet"])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "passed" not in result.output
|
||||||
|
|
||||||
|
|
||||||
|
class TestBatchValidateCommand:
|
||||||
|
"""Tests for batch validate command."""
|
||||||
|
|
||||||
|
def test_batch_validate_multiple_files(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
schema_file = os.path.join(FIXTURES_DIR, "valid_schema.json")
|
||||||
|
input_files = [
|
||||||
|
os.path.join(FIXTURES_DIR, "sample.json"),
|
||||||
|
os.path.join(FIXTURES_DIR, "sample.yaml"),
|
||||||
|
]
|
||||||
|
result = runner.invoke(batch_validate, ["--schema", schema_file, *input_files])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "Valid" in result.output or "valid" in result.output
|
||||||
|
|
||||||
|
def test_batch_validate_pattern(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
schema_file = os.path.join(FIXTURES_DIR, "valid_schema.json")
|
||||||
|
json_file = os.path.join(FIXTURES_DIR, "sample.json")
|
||||||
|
result = runner.invoke(batch_validate, ["--schema", schema_file, json_file])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeCheckCommand:
|
||||||
|
"""Tests for typecheck command."""
|
||||||
|
|
||||||
|
def test_typecheck_simple_file(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
input_file = os.path.join(FIXTURES_DIR, "sample.json")
|
||||||
|
result = runner.invoke(typecheck, [input_file])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "object" in result.output
|
||||||
|
|
||||||
|
def test_typecheck_infer_schema(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
input_file = os.path.join(FIXTURES_DIR, "sample.json")
|
||||||
|
result = runner.invoke(typecheck, [input_file, "--infer"])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert '"type"' in result.output or "'type'" in result.output
|
||||||
|
|
||||||
|
def test_typecheck_quiet_mode(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
input_file = os.path.join(FIXTURES_DIR, "sample.json")
|
||||||
|
result = runner.invoke(typecheck, [input_file, "--quiet"])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
|
||||||
|
class TestMainCLI:
|
||||||
|
"""Tests for main CLI entry point."""
|
||||||
|
|
||||||
|
def test_main_help(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
result = runner.invoke(main, ["--help"])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "DataForge" in result.output
|
||||||
|
assert "convert" in result.output
|
||||||
|
assert "validate" in result.output
|
||||||
|
|
||||||
|
def test_main_version(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
result = runner.invoke(main, ["--version"])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "1.0.0" in result.output
|
||||||
Reference in New Issue
Block a user