Initial upload: regex-humanizer-cli with CI/CD workflow
This commit is contained in:
253
tests/test_cli.py
Normal file
253
tests/test_cli.py
Normal file
@@ -0,0 +1,253 @@
|
||||
"""Tests for the CLI interface."""
|
||||
|
||||
import json
|
||||
import pytest
|
||||
from click.testing import CliRunner
|
||||
from regex_humanizer.cli import main, explain, test, flavors, validate, convert
|
||||
|
||||
|
||||
class TestCLIMain:
|
||||
"""Test the main CLI entry point."""
|
||||
|
||||
def test_main_help(self):
|
||||
"""Test that main help works."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, ["--help"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Regex Humanizer" in result.output
|
||||
assert "explain" in result.output
|
||||
assert "test" in result.output
|
||||
assert "interactive" in result.output
|
||||
|
||||
|
||||
class TestCLIExplain:
|
||||
"""Test the explain command."""
|
||||
|
||||
def test_explain_simple_literal(self):
|
||||
"""Test explaining a simple literal."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(explain, ["hello"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Pattern" in result.output or "hello" in result.output
|
||||
|
||||
def test_explain_with_flavor_option(self):
|
||||
"""Test explaining with a flavor option."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(explain, ["--flavor", "javascript", "test"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Flavor" in result.output or "javascript" in result.output
|
||||
|
||||
def test_explain_with_json_output(self):
|
||||
"""Test explaining with JSON output."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(explain, ["--output", "json", "\\d+"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "{", "}" in result.output
|
||||
|
||||
def test_explain_with_verbose(self):
|
||||
"""Test explaining with verbose flag."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(explain, ["--verbose", "\\d+"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Features" in result.output or "digit" in result.output.lower()
|
||||
|
||||
def test_explain_complex_pattern(self):
|
||||
"""Test explaining a complex pattern."""
|
||||
runner = CliRunner()
|
||||
pattern = r"^(?:http|https)://[\w.-]+\.(?:com|org|net)$"
|
||||
result = runner.invoke(explain, [pattern])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Pattern" in result.output
|
||||
|
||||
def test_explain_phone_pattern(self):
|
||||
"""Test explaining a phone pattern."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(explain, [r"\d{3}-\d{4}"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
def test_explain_character_class(self):
|
||||
"""Test explaining a character class."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(explain, ["[a-zA-Z]+"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
|
||||
class TestCLITest:
|
||||
"""Test the test command."""
|
||||
|
||||
def test_test_simple_literal(self):
|
||||
"""Test generating test cases for a simple literal."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(test, ["hello"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Matching" in result.output or "hello" in result.output
|
||||
assert "Non-matching" in result.output
|
||||
|
||||
def test_test_with_count_option(self):
|
||||
"""Test generating a specific number of test cases."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(test, ["--count", "3", "a"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
def test_test_with_json_output(self):
|
||||
"""Test generating test cases with JSON output."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(test, ["--output", "json", "test"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
data = json.loads(result.output)
|
||||
assert "matching" in data
|
||||
assert "non_matching" in data
|
||||
|
||||
def test_test_phone_pattern(self):
|
||||
"""Test generating test cases for a phone pattern."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(test, [r"\d{3}-\d{4}"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Matching" in result.output
|
||||
|
||||
def test_test_email_pattern(self):
|
||||
"""Test generating test cases for an email pattern."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(test, [r"[a-z]+@[a-z]+\.[a-z]+"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
def test_test_quantifier_pattern(self):
|
||||
"""Test generating test cases for a quantifier pattern."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(test, ["a{2,4}"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
|
||||
class TestCLIFlavors:
|
||||
"""Test the flavors command."""
|
||||
|
||||
def test_flavors_list(self):
|
||||
"""Test listing available flavors."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(flavors)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "pcre" in result.output.lower()
|
||||
assert "javascript" in result.output.lower()
|
||||
assert "python" in result.output.lower()
|
||||
|
||||
|
||||
class TestCLIValidate:
|
||||
"""Test the validate command."""
|
||||
|
||||
def test_validate_valid_pattern(self):
|
||||
"""Test validating a valid pattern."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(validate, ["hello"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "PASSED" in result.output or "Validation" in result.output
|
||||
|
||||
def test_validate_with_flavor(self):
|
||||
"""Test validating with a specific flavor."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(validate, ["--flavor", "javascript", "test"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
def test_validate_complex_pattern(self):
|
||||
"""Test validating a complex pattern."""
|
||||
runner = CliRunner()
|
||||
pattern = r"^(?:http|https)://[\w.-]+\.(?:com|org|net)$"
|
||||
result = runner.invoke(validate, [pattern])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
|
||||
class TestCLIConvert:
|
||||
"""Test the convert command."""
|
||||
|
||||
def test_convert_pcre_to_js(self):
|
||||
"""Test converting a pattern from PCRE to JavaScript."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(convert, ["(?P<test>hello)", "--from-flavor", "pcre", "--to-flavor", "javascript"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Converted" in result.output
|
||||
|
||||
def test_convert_with_defaults(self):
|
||||
"""Test converting with default flavors."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(convert, ["test"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Original" in result.output
|
||||
assert "Converted" in result.output
|
||||
|
||||
|
||||
class TestCLIInteractive:
|
||||
"""Test the interactive command."""
|
||||
|
||||
def test_interactive_command_exists(self):
|
||||
"""Test that interactive command is available."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, ["interactive", "--help"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "interactive" in result.output.lower()
|
||||
|
||||
def test_interactive_with_flavor(self):
|
||||
"""Test interactive mode with a specific flavor."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, ["interactive", "--flavor", "python"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
|
||||
class TestCLIIntegration:
|
||||
"""Integration tests for CLI."""
|
||||
|
||||
def test_flavor_option_global(self):
|
||||
"""Test that global flavor option works."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, ["--flavor", "python", "explain", "test"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
def test_error_handling_invalid_pattern(self):
|
||||
"""Test error handling for invalid patterns."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(explain, ["["])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
def test_output_json_structure(self):
|
||||
"""Test JSON output has correct structure."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(explain, ["--output", "json", "\\d+"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
data = json.loads(result.output)
|
||||
assert "pattern" in data
|
||||
assert "flavor" in data
|
||||
assert "explanation" in data
|
||||
|
||||
def test_output_test_json_structure(self):
|
||||
"""Test JSON test output has correct structure."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(test, ["--output", "json", "\\d"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
data = json.loads(result.output)
|
||||
assert "pattern" in data
|
||||
assert "matching" in data
|
||||
assert "non_matching" in data
|
||||
Reference in New Issue
Block a user