mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-09-22 04:50:46 +02:00

Enhanced CLI with type-safe help text, 8 ideal count flags (--land-count, etc), and theme selection by name (--primary-tag)
137 lines
5.3 KiB
Python
137 lines
5.3 KiB
Python
"""
|
|
Test CLI include/exclude functionality (M4: CLI Parity).
|
|
"""
|
|
|
|
import pytest
|
|
import subprocess
|
|
import json
|
|
import os
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
|
|
class TestCLIIncludeExclude:
|
|
"""Test CLI include/exclude argument parsing and functionality."""
|
|
|
|
def test_cli_argument_parsing(self):
|
|
"""Test that CLI arguments are properly parsed."""
|
|
# Test help output includes new arguments
|
|
result = subprocess.run(
|
|
['python', 'code/headless_runner.py', '--help'],
|
|
capture_output=True,
|
|
text=True,
|
|
cwd=Path(__file__).parent.parent.parent
|
|
)
|
|
|
|
assert result.returncode == 0
|
|
help_text = result.stdout
|
|
assert '--include-cards' in help_text
|
|
assert '--exclude-cards' in help_text
|
|
assert '--enforcement-mode' in help_text
|
|
assert '--allow-illegal' in help_text
|
|
assert '--fuzzy-matching' in help_text
|
|
assert 'semicolons' in help_text # Check for comma warning
|
|
|
|
def test_cli_dry_run_with_include_exclude(self):
|
|
"""Test dry run output includes include/exclude configuration."""
|
|
result = subprocess.run([
|
|
'python', 'code/headless_runner.py',
|
|
'--commander', 'Krenko, Mob Boss',
|
|
'--include-cards', 'Sol Ring;Lightning Bolt',
|
|
'--exclude-cards', 'Chaos Orb',
|
|
'--enforcement-mode', 'strict',
|
|
'--dry-run'
|
|
], capture_output=True, text=True, cwd=Path(__file__).parent.parent.parent)
|
|
|
|
assert result.returncode == 0
|
|
|
|
# Parse the JSON output
|
|
config = json.loads(result.stdout)
|
|
|
|
assert config['command_name'] == 'Krenko, Mob Boss'
|
|
assert config['include_cards'] == ['Sol Ring', 'Lightning Bolt']
|
|
assert config['exclude_cards'] == ['Chaos Orb']
|
|
assert config['enforcement_mode'] == 'strict'
|
|
|
|
def test_cli_semicolon_parsing(self):
|
|
"""Test semicolon separation for card names with commas."""
|
|
result = subprocess.run([
|
|
'python', 'code/headless_runner.py',
|
|
'--include-cards', 'Krenko, Mob Boss;Jace, the Mind Sculptor',
|
|
'--exclude-cards', 'Teferi, Hero of Dominaria',
|
|
'--dry-run'
|
|
], capture_output=True, text=True, cwd=Path(__file__).parent.parent.parent)
|
|
|
|
assert result.returncode == 0
|
|
|
|
config = json.loads(result.stdout)
|
|
assert config['include_cards'] == ['Krenko, Mob Boss', 'Jace, the Mind Sculptor']
|
|
assert config['exclude_cards'] == ['Teferi, Hero of Dominaria']
|
|
|
|
def test_cli_comma_parsing_simple_names(self):
|
|
"""Test comma separation for simple card names without commas."""
|
|
result = subprocess.run([
|
|
'python', 'code/headless_runner.py',
|
|
'--include-cards', 'Sol Ring,Lightning Bolt,Counterspell',
|
|
'--exclude-cards', 'Island,Mountain',
|
|
'--dry-run'
|
|
], capture_output=True, text=True, cwd=Path(__file__).parent.parent.parent)
|
|
|
|
assert result.returncode == 0
|
|
|
|
config = json.loads(result.stdout)
|
|
assert config['include_cards'] == ['Sol Ring', 'Lightning Bolt', 'Counterspell']
|
|
assert config['exclude_cards'] == ['Island', 'Mountain']
|
|
|
|
def test_cli_json_priority(self):
|
|
"""Test that CLI arguments override JSON config values."""
|
|
# Create a temporary JSON config
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
|
|
json.dump({
|
|
'commander': 'Atraxa, Praetors\' Voice',
|
|
'include_cards': ['Doubling Season'],
|
|
'exclude_cards': ['Winter Orb'],
|
|
'enforcement_mode': 'warn'
|
|
}, f, indent=2)
|
|
temp_config = f.name
|
|
|
|
try:
|
|
result = subprocess.run([
|
|
'python', 'code/headless_runner.py',
|
|
'--config', temp_config,
|
|
'--include-cards', 'Sol Ring', # Override JSON
|
|
'--enforcement-mode', 'strict', # Override JSON
|
|
'--dry-run'
|
|
], capture_output=True, text=True, cwd=Path(__file__).parent.parent.parent)
|
|
|
|
assert result.returncode == 0
|
|
|
|
config = json.loads(result.stdout)
|
|
# CLI should override JSON
|
|
assert config['include_cards'] == ['Sol Ring'] # CLI override
|
|
assert config['exclude_cards'] == ['Winter Orb'] # From JSON (no CLI override)
|
|
assert config['enforcement_mode'] == 'strict' # CLI override
|
|
|
|
finally:
|
|
os.unlink(temp_config)
|
|
|
|
def test_cli_empty_values(self):
|
|
"""Test handling of empty/missing include/exclude values."""
|
|
result = subprocess.run([
|
|
'python', 'code/headless_runner.py',
|
|
'--commander', 'Krenko, Mob Boss',
|
|
'--dry-run'
|
|
], capture_output=True, text=True, cwd=Path(__file__).parent.parent.parent)
|
|
|
|
assert result.returncode == 0
|
|
|
|
config = json.loads(result.stdout)
|
|
assert config['include_cards'] == []
|
|
assert config['exclude_cards'] == []
|
|
assert config['enforcement_mode'] == 'warn' # Default
|
|
assert config['allow_illegal'] is False # Default
|
|
assert config['fuzzy_matching'] is True # Default
|
|
|
|
|
|
if __name__ == '__main__':
|
|
pytest.main([__file__])
|