Restore testdata-cli with proper CI/CD and tests
This commit is contained in:
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
3
tests/conftest.py
Normal file
3
tests/conftest.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""Pytest configuration for testdatagen tests."""
|
||||
|
||||
import pytest
|
||||
135
tests/test_cli.py
Normal file
135
tests/test_cli.py
Normal file
@@ -0,0 +1,135 @@
|
||||
"""Tests for CLI commands."""
|
||||
|
||||
import json
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from click.testing import CliRunner
|
||||
|
||||
from testdatagen.cli import main
|
||||
|
||||
|
||||
class TestCLI:
|
||||
"""Tests for CLI commands."""
|
||||
|
||||
def test_cli_version(self):
|
||||
"""Test that CLI shows version."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, ["--version"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "0.1.0" in result.output
|
||||
|
||||
def test_generate_help(self):
|
||||
"""Test generate command help."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, ["generate", "--help"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "--schema" in result.output
|
||||
assert "--count" in result.output
|
||||
assert "--format" in result.output
|
||||
|
||||
def test_from_ts_help(self):
|
||||
"""Test from-ts command help."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, ["from-ts", "--help"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "--input" in result.output
|
||||
|
||||
def test_from_sample_help(self):
|
||||
"""Test from-sample command help."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, ["from-sample", "--help"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "--input" in result.output
|
||||
|
||||
def test_generate_requires_schema(self):
|
||||
"""Test that generate requires schema option."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, ["generate"])
|
||||
|
||||
assert result.exit_code != 0
|
||||
|
||||
def test_generate_with_schema(self):
|
||||
"""Test generate with valid schema."""
|
||||
runner = CliRunner()
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
|
||||
json.dump({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"}
|
||||
}
|
||||
}, f)
|
||||
schema_path = f.name
|
||||
|
||||
try:
|
||||
result = runner.invoke(main, ["generate", "--schema", schema_path, "--count", "1"])
|
||||
assert result.exit_code == 0
|
||||
finally:
|
||||
Path(schema_path).unlink()
|
||||
|
||||
def test_generate_csv_format(self):
|
||||
"""Test generate with CSV format."""
|
||||
runner = CliRunner()
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
|
||||
json.dump({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"}
|
||||
}
|
||||
}, f)
|
||||
schema_path = f.name
|
||||
|
||||
try:
|
||||
result = runner.invoke(main, ["generate", "--schema", schema_path, "--count", "1", "--format", "csv"])
|
||||
assert result.exit_code == 0
|
||||
assert "name" in result.output
|
||||
finally:
|
||||
Path(schema_path).unlink()
|
||||
|
||||
def test_generate_sql_format(self):
|
||||
"""Test generate with SQL format."""
|
||||
runner = CliRunner()
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
|
||||
json.dump({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"}
|
||||
}
|
||||
}, f)
|
||||
schema_path = f.name
|
||||
|
||||
try:
|
||||
result = runner.invoke(main, ["generate", "--schema", schema_path, "--count", "1", "--format", "sql"])
|
||||
assert result.exit_code == 0
|
||||
assert "INSERT" in result.output
|
||||
finally:
|
||||
Path(schema_path).unlink()
|
||||
|
||||
def test_generate_invalid_json(self):
|
||||
"""Test generate with invalid JSON schema."""
|
||||
runner = CliRunner()
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
|
||||
f.write("{ invalid json }")
|
||||
schema_path = f.name
|
||||
|
||||
try:
|
||||
result = runner.invoke(main, ["generate", "--schema", schema_path, "--count", "1"])
|
||||
assert result.exit_code != 0
|
||||
finally:
|
||||
Path(schema_path).unlink()
|
||||
|
||||
def test_generate_nonexistent_file(self):
|
||||
"""Test generate with nonexistent schema file."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, ["generate", "--schema", "/nonexistent/path.json"])
|
||||
|
||||
assert result.exit_code != 0
|
||||
126
tests/test_formatters.py
Normal file
126
tests/test_formatters.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""Tests for output formatters."""
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from testdatagen.formatters.json_formatter import JSONFormatter
|
||||
from testdatagen.formatters.csv_formatter import CSVFormatter
|
||||
from testdatagen.formatters.sql_formatter import SQLFormatter
|
||||
|
||||
|
||||
class TestJSONFormatter:
|
||||
"""Tests for JSONFormatter class."""
|
||||
|
||||
def test_format_single_record(self):
|
||||
"""Test formatting a single record."""
|
||||
records = [{"name": "John", "age": 30}]
|
||||
formatter = JSONFormatter()
|
||||
result = formatter.format(records)
|
||||
|
||||
parsed = json.loads(result)
|
||||
assert parsed == {"name": "John", "age": 30}
|
||||
|
||||
def test_format_multiple_records(self):
|
||||
"""Test formatting multiple records."""
|
||||
records = [{"name": "John"}, {"name": "Jane"}]
|
||||
formatter = JSONFormatter()
|
||||
result = formatter.format(records)
|
||||
|
||||
parsed = json.loads(result)
|
||||
assert len(parsed) == 2
|
||||
assert parsed[0]["name"] == "John"
|
||||
assert parsed[1]["name"] == "Jane"
|
||||
|
||||
def test_format_with_indent(self):
|
||||
"""Test formatting with indentation."""
|
||||
records = [{"name": "John"}]
|
||||
formatter = JSONFormatter(indent=2)
|
||||
result = formatter.format(records)
|
||||
|
||||
assert "\n" in result
|
||||
assert " " in result
|
||||
|
||||
def test_format_empty_records(self):
|
||||
"""Test formatting empty records."""
|
||||
formatter = JSONFormatter()
|
||||
result = formatter.format([])
|
||||
|
||||
assert result == "[]"
|
||||
|
||||
def test_format_with_special_characters(self):
|
||||
"""Test formatting with special characters."""
|
||||
records = [{"name": "John \"Jack\" Doe"}]
|
||||
formatter = JSONFormatter()
|
||||
result = formatter.format(records)
|
||||
|
||||
parsed = json.loads(result)
|
||||
assert parsed[0]["name"] == "John \"Jack\" Doe"
|
||||
|
||||
|
||||
class TestCSVFormatter:
|
||||
"""Tests for CSVFormatter class."""
|
||||
|
||||
def test_format_single_record(self):
|
||||
"""Test formatting a single record."""
|
||||
records = [{"name": "John", "age": 30}]
|
||||
formatter = CSVFormatter()
|
||||
result = formatter.format(records)
|
||||
|
||||
lines = result.strip().split("\n")
|
||||
assert len(lines) == 2
|
||||
assert "name" in lines[0]
|
||||
assert "John" in lines[1]
|
||||
|
||||
def test_format_multiple_records(self):
|
||||
"""Test formatting multiple records."""
|
||||
records = [{"name": "John"}, {"name": "Jane"}]
|
||||
formatter = CSVFormatter()
|
||||
result = formatter.format(records)
|
||||
|
||||
lines = result.strip().split("\n")
|
||||
assert len(lines) == 3
|
||||
|
||||
def test_format_empty_records(self):
|
||||
"""Test formatting empty records."""
|
||||
formatter = CSVFormatter()
|
||||
result = formatter.format([])
|
||||
|
||||
assert "name" in result
|
||||
|
||||
|
||||
class TestSQLFormatter:
|
||||
"""Tests for SQLFormatter class."""
|
||||
|
||||
def test_format_single_record(self):
|
||||
"""Test formatting a single record."""
|
||||
records = [{"name": "John", "age": 30}]
|
||||
formatter = SQLFormatter(table_name="users")
|
||||
result = formatter.format(records)
|
||||
|
||||
assert "INSERT" in result
|
||||
assert "users" in result
|
||||
assert "John" in result
|
||||
|
||||
def test_format_multiple_records(self):
|
||||
"""Test formatting multiple records."""
|
||||
records = [{"name": "John"}, {"name": "Jane"}]
|
||||
formatter = SQLFormatter(table_name="users")
|
||||
result = formatter.format(records)
|
||||
|
||||
assert result.count("INSERT") == 2
|
||||
|
||||
def test_format_empty_records(self):
|
||||
"""Test formatting empty records."""
|
||||
formatter = SQLFormatter(table_name="users")
|
||||
result = formatter.format([])
|
||||
|
||||
assert "INSERT" not in result
|
||||
|
||||
def test_custom_table_name(self):
|
||||
"""Test with custom table name."""
|
||||
records = [{"name": "John"}]
|
||||
formatter = SQLFormatter(table_name="custom_table")
|
||||
result = formatter.format(records)
|
||||
|
||||
assert "custom_table" in result
|
||||
169
tests/test_generators.py
Normal file
169
tests/test_generators.py
Normal file
@@ -0,0 +1,169 @@
|
||||
"""Tests for JSON Schema Generator."""
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from testdatagen.generators.json_schema_generator import JSONSchemaGenerator
|
||||
|
||||
|
||||
class TestJSONSchemaGenerator:
|
||||
"""Tests for JSONSchemaGenerator class."""
|
||||
|
||||
def test_generate_simple_string(self):
|
||||
"""Test generating a simple string field."""
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"}
|
||||
}
|
||||
}
|
||||
generator = JSONSchemaGenerator(seed=42)
|
||||
records = generator.generate(schema, count=1)
|
||||
|
||||
assert len(records) == 1
|
||||
assert "name" in records[0]
|
||||
assert isinstance(records[0]["name"], str)
|
||||
|
||||
def test_generate_string_with_format_email(self):
|
||||
"""Test generating an email field."""
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"email": {"type": "string", "format": "email"}
|
||||
}
|
||||
}
|
||||
generator = JSONSchemaGenerator(seed=42)
|
||||
records = generator.generate(schema, count=1)
|
||||
|
||||
assert len(records) == 1
|
||||
assert "@" in records[0]["email"]
|
||||
assert "." in records[0]["email"]
|
||||
|
||||
def test_generate_string_with_format_uuid(self):
|
||||
"""Test generating a UUID field."""
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "string", "format": "uuid"}
|
||||
}
|
||||
}
|
||||
generator = JSONSchemaGenerator(seed=42)
|
||||
records = generator.generate(schema, count=1)
|
||||
|
||||
assert len(records) == 1
|
||||
assert "-" in records[0]["id"]
|
||||
|
||||
def test_generate_integer(self):
|
||||
"""Test generating an integer field."""
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"age": {"type": "integer"}
|
||||
}
|
||||
}
|
||||
generator = JSONSchemaGenerator(seed=42)
|
||||
records = generator.generate(schema, count=1)
|
||||
|
||||
assert len(records) == 1
|
||||
assert isinstance(records[0]["age"], int)
|
||||
|
||||
def test_generate_boolean(self):
|
||||
"""Test generating a boolean field."""
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"active": {"type": "boolean"}
|
||||
}
|
||||
}
|
||||
generator = JSONSchemaGenerator(seed=42)
|
||||
records = generator.generate(schema, count=1)
|
||||
|
||||
assert len(records) == 1
|
||||
assert isinstance(records[0]["active"], bool)
|
||||
|
||||
def test_generate_multiple_records(self):
|
||||
"""Test generating multiple records."""
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"}
|
||||
}
|
||||
}
|
||||
generator = JSONSchemaGenerator(seed=42)
|
||||
records = generator.generate(schema, count=5)
|
||||
|
||||
assert len(records) == 5
|
||||
for record in records:
|
||||
assert "name" in record
|
||||
|
||||
def test_generate_nested_object(self):
|
||||
"""Test generating nested objects."""
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"email": {"type": "string", "format": "email"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
generator = JSONSchemaGenerator(seed=42)
|
||||
records = generator.generate(schema, count=1)
|
||||
|
||||
assert len(records) == 1
|
||||
assert "user" in records[0]
|
||||
assert "name" in records[0]["user"]
|
||||
assert "email" in records[0]["user"]
|
||||
|
||||
def test_generate_with_seed(self):
|
||||
"""Test that seed produces reproducible results."""
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"}
|
||||
}
|
||||
}
|
||||
|
||||
generator1 = JSONSchemaGenerator(seed=123)
|
||||
records1 = generator1.generate(schema, count=1)
|
||||
|
||||
generator2 = JSONSchemaGenerator(seed=123)
|
||||
records2 = generator2.generate(schema, count=1)
|
||||
|
||||
assert records1[0]["name"] == records2[0]["name"]
|
||||
|
||||
def test_generate_array_of_strings(self):
|
||||
"""Test generating array of strings."""
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"}
|
||||
}
|
||||
}
|
||||
}
|
||||
generator = JSONSchemaGenerator(seed=42)
|
||||
records = generator.generate(schema, count=1)
|
||||
|
||||
assert len(records) == 1
|
||||
assert isinstance(records[0]["tags"], list)
|
||||
|
||||
def test_generate_with_enum(self):
|
||||
"""Test generating with enum constraint."""
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "enum": ["active", "inactive", "pending"]}
|
||||
}
|
||||
}
|
||||
generator = JSONSchemaGenerator(seed=42)
|
||||
records = generator.generate(schema, count=10)
|
||||
|
||||
assert len(records) == 10
|
||||
for record in records:
|
||||
assert record["status"] in ["active", "inactive", "pending"]
|
||||
95
tests/test_providers.py
Normal file
95
tests/test_providers.py
Normal file
@@ -0,0 +1,95 @@
|
||||
"""Tests for Faker providers."""
|
||||
|
||||
import pytest
|
||||
from faker import Faker
|
||||
|
||||
from testdatagen.providers.testdata_provider import TestDataProvider
|
||||
|
||||
|
||||
class TestTestDataProvider:
|
||||
"""Tests for TestDataProvider class."""
|
||||
|
||||
def test_json_schema_type_boolean(self):
|
||||
"""Test boolean type generation."""
|
||||
faker = Faker()
|
||||
provider = TestDataProvider(faker)
|
||||
|
||||
result = provider.json_schema_type({"type": "boolean"}, faker)
|
||||
assert isinstance(result, bool)
|
||||
|
||||
def test_json_schema_type_integer(self):
|
||||
"""Test integer type generation."""
|
||||
faker = Faker()
|
||||
provider = TestDataProvider(faker)
|
||||
|
||||
result = provider.json_schema_type({"type": "integer"}, faker)
|
||||
assert isinstance(result, int)
|
||||
|
||||
def test_json_schema_type_integer_with_constraints(self):
|
||||
"""Test integer with min/max constraints."""
|
||||
faker = Faker()
|
||||
provider = TestDataProvider(faker)
|
||||
|
||||
result = provider.json_schema_type({"type": "integer", "minimum": 10, "maximum": 20}, faker)
|
||||
assert isinstance(result, int)
|
||||
assert 10 <= result <= 20
|
||||
|
||||
def test_json_schema_type_string(self):
|
||||
"""Test string type generation."""
|
||||
faker = Faker()
|
||||
provider = TestDataProvider(faker)
|
||||
|
||||
result = provider.json_schema_type({"type": "string"}, faker)
|
||||
assert isinstance(result, str)
|
||||
|
||||
def test_json_schema_type_string_with_format_email(self):
|
||||
"""Test string with email format."""
|
||||
faker = Faker()
|
||||
provider = TestDataProvider(faker)
|
||||
|
||||
result = provider.json_schema_type({"type": "string", "format": "email"}, faker)
|
||||
assert isinstance(result, str)
|
||||
assert "@" in result
|
||||
|
||||
def test_json_schema_type_string_with_format_uuid(self):
|
||||
"""Test string with uuid format."""
|
||||
faker = Faker()
|
||||
provider = TestDataProvider(faker)
|
||||
|
||||
result = provider.json_schema_type({"type": "string", "format": "uuid"}, faker)
|
||||
assert isinstance(result, str)
|
||||
assert "-" in result
|
||||
|
||||
def test_json_schema_type_string_with_format_date(self):
|
||||
"""Test string with date format."""
|
||||
faker = Faker()
|
||||
provider = TestDataProvider(faker)
|
||||
|
||||
result = provider.json_schema_type({"type": "string", "format": "date-time"}, faker)
|
||||
assert isinstance(result, str)
|
||||
|
||||
def test_json_schema_type_with_enum(self):
|
||||
"""Test type with enum constraint."""
|
||||
faker = Faker()
|
||||
provider = TestDataProvider(faker)
|
||||
|
||||
schema = {"type": "string", "enum": ["red", "green", "blue"]}
|
||||
result = provider.json_schema_type(schema, faker)
|
||||
|
||||
assert result in ["red", "green", "blue"]
|
||||
|
||||
def test_json_schema_type_with_pattern(self):
|
||||
"""Test type with pattern constraint."""
|
||||
faker = Faker()
|
||||
provider = TestDataProvider(faker)
|
||||
|
||||
result = provider.json_schema_type({"type": "string", "pattern": "^[a-z]+$"}, faker)
|
||||
assert isinstance(result, str)
|
||||
|
||||
def test_provider_is_registered(self):
|
||||
"""Test that provider can be added to Faker."""
|
||||
faker = Faker()
|
||||
assert TestDataProvider not in faker.providers
|
||||
|
||||
faker.add_provider(TestDataProvider)
|
||||
assert TestDataProvider in faker.providers
|
||||
Reference in New Issue
Block a user