154 lines
5.2 KiB
Python
154 lines
5.2 KiB
Python
"""Tests for configuration loading and parsing."""
|
|
|
|
import pytest
|
|
import json
|
|
import yaml
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
from generate import load_config, parse_range
|
|
|
|
|
|
class TestConfigLoading:
|
|
"""Test configuration file loading."""
|
|
|
|
def test_load_yaml_config(self, temp_dir):
|
|
"""Test loading YAML configuration files."""
|
|
config_data = {
|
|
'range': '0-9',
|
|
'cards_per_page': 4,
|
|
'bead_shape': 'circle'
|
|
}
|
|
|
|
config_file = temp_dir / 'test.yaml'
|
|
with open(config_file, 'w') as f:
|
|
yaml.dump(config_data, f)
|
|
|
|
loaded = load_config(str(config_file))
|
|
assert loaded == config_data
|
|
|
|
def test_load_json_config(self, temp_dir):
|
|
"""Test loading JSON configuration files."""
|
|
config_data = {
|
|
'range': '0-99',
|
|
'color_scheme': 'place-value',
|
|
'margins': {'top': '1in', 'bottom': '1in'}
|
|
}
|
|
|
|
config_file = temp_dir / 'test.json'
|
|
with open(config_file, 'w') as f:
|
|
json.dump(config_data, f)
|
|
|
|
loaded = load_config(str(config_file))
|
|
assert loaded == config_data
|
|
|
|
def test_load_nonexistent_config(self):
|
|
"""Test handling of nonexistent config files."""
|
|
with pytest.raises(FileNotFoundError):
|
|
load_config('nonexistent.yaml')
|
|
|
|
|
|
class TestRangeParsing:
|
|
"""Test number range parsing functionality."""
|
|
|
|
def test_parse_simple_range(self):
|
|
"""Test parsing simple ranges like '0-9'."""
|
|
result = parse_range('0-9')
|
|
expected = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
assert result == expected
|
|
|
|
def test_parse_range_with_step(self):
|
|
"""Test parsing ranges with custom steps."""
|
|
result = parse_range('0-10', step=2)
|
|
expected = [0, 2, 4, 6, 8, 10]
|
|
assert result == expected
|
|
|
|
result = parse_range('0-20', step=5)
|
|
expected = [0, 5, 10, 15, 20]
|
|
assert result == expected
|
|
|
|
def test_parse_comma_list(self):
|
|
"""Test parsing comma-separated number lists."""
|
|
result = parse_range('1,5,10,25')
|
|
expected = [1, 5, 10, 25]
|
|
assert result == expected
|
|
|
|
def test_parse_mixed_list_and_ranges(self):
|
|
"""Test parsing mixed comma-separated values with ranges."""
|
|
result = parse_range('1,5-7,10')
|
|
expected = [1, 5, 6, 7, 10]
|
|
assert result == expected
|
|
|
|
def test_parse_single_number(self):
|
|
"""Test parsing single numbers."""
|
|
result = parse_range('42')
|
|
expected = [42]
|
|
assert result == expected
|
|
|
|
def test_parse_negative_numbers(self):
|
|
"""Test handling of negative numbers (edge case)."""
|
|
# Note: The current implementation might not handle this correctly
|
|
# This test documents the expected behavior
|
|
with pytest.raises(ValueError):
|
|
parse_range('-5-5')
|
|
|
|
def test_parse_invalid_range(self):
|
|
"""Test handling of invalid range strings."""
|
|
with pytest.raises(ValueError):
|
|
parse_range('invalid')
|
|
|
|
# Range where start > end results in empty list (valid behavior)
|
|
result = parse_range('10-5')
|
|
assert result == []
|
|
|
|
def test_parse_large_range(self):
|
|
"""Test parsing large ranges."""
|
|
result = parse_range('0-100', step=25)
|
|
expected = [0, 25, 50, 75, 100]
|
|
assert result == expected
|
|
|
|
def test_parse_step_ignored_for_lists(self):
|
|
"""Test that step parameter is ignored for comma-separated lists."""
|
|
result = parse_range('1,2,3,4', step=10) # Step should be ignored
|
|
expected = [1, 2, 3, 4]
|
|
assert result == expected
|
|
|
|
|
|
class TestConfigIntegration:
|
|
"""Integration tests for configuration handling."""
|
|
|
|
def test_real_config_files(self, project_root):
|
|
"""Test loading real configuration files from the project."""
|
|
config_dir = project_root / 'config'
|
|
|
|
# Test default config
|
|
default_config = config_dir / 'default.yaml'
|
|
if default_config.exists():
|
|
config = load_config(str(default_config))
|
|
assert 'range' in config
|
|
assert 'cards_per_page' in config
|
|
|
|
def test_config_with_range_parsing(self, temp_dir):
|
|
"""Test integration of config loading with range parsing."""
|
|
config_data = {
|
|
'range': '5-15',
|
|
'step': 2,
|
|
'cards_per_page': 8
|
|
}
|
|
|
|
config_file = temp_dir / 'test.yaml'
|
|
with open(config_file, 'w') as f:
|
|
yaml.dump(config_data, f)
|
|
|
|
config = load_config(str(config_file))
|
|
numbers = parse_range(config['range'], config.get('step', 1))
|
|
|
|
expected = [5, 7, 9, 11, 13, 15]
|
|
assert numbers == expected
|
|
|
|
def test_config_defaults(self, sample_config):
|
|
"""Test that sample config has reasonable defaults."""
|
|
assert sample_config['cards_per_page'] > 0
|
|
assert sample_config['scale_factor'] > 0
|
|
assert sample_config['bead_shape'] in ['diamond', 'circle', 'square']
|
|
assert sample_config['color_scheme'] in ['monochrome', 'place-value', 'heaven-earth', 'alternating'] |