# Test Fixtures Guide

This document describes the pytest fixtures available in `conftest.py` for testing the Ghostty Settings TUI.

## Data Fixtures

### `sample_schema_path`
Returns the Path to the sample schema file (`sample_data/ghostty_schema_sample.txt`).

```python
def test_schema_location(sample_schema_path):
    assert sample_schema_path.exists()
```

### `sample_schema`
Returns the raw content of the sample schema file as a string.

```python
def test_schema_content(sample_schema):
    assert "font-size" in sample_schema
```

### `parser`
Returns a configured `GhosttyParser` instance.

```python
def test_parsing(parser, sample_schema):
    options = parser.parse(sample_schema)
    assert len(options) > 0
```

### `parsed_options`
Returns a list of `OptionDefinition` objects parsed from the sample schema.

```python
def test_option_types(parsed_options):
    assert all(isinstance(opt, OptionDefinition) for opt in parsed_options)
```

### `options_dict`
Returns parsed options as a dictionary keyed by option name.

```python
def test_option_lookup(options_dict):
    assert "font-size" in options_dict
    assert options_dict["font-size"].option_type == OptionType.INTEGER
```

### `mock_ghostty_output`
Returns sample Ghostty CLI output for testing the parser.

```python
def test_parser_with_mock(parser, mock_ghostty_output):
    options = parser.parse(mock_ghostty_output)
    assert len(options) == 4
```

### `sample_options_dict`
Returns a complete dictionary of `OptionModel` instances for testing.

```python
def test_option_models(sample_options_dict):
    font_opt = sample_options_dict["font-size"]
    assert font_opt.current.value == "14"
    assert font_opt.current.is_modified is True
```

## Temporary File Fixtures

### `tmp_config_file`
Creates a temporary config file with sample content. Automatically cleaned up after the test.

```python
def test_config_reading(tmp_config_file):
    content = tmp_config_file.read_text()
    assert "font-size = 14" in content
    # File is automatically deleted after test
```

**Cleanup behavior:**
- Deletes the temporary config file
- Deletes any `.bak` backup files created

### `tmp_config_dir`
Creates a temporary directory for testing. Automatically cleaned up after the test.

```python
def test_config_directory(tmp_config_dir):
    config_file = tmp_config_dir / "config"
    config_file.write_text("test-option = value")
    assert config_file.exists()
    # Directory and contents are automatically deleted after test
```

## Factory Fixtures

### `option_factory`
Factory function for creating `OptionDefinition` instances with default values.

```python
def test_custom_option(option_factory):
    opt = option_factory(
        name="my-option",
        option_type=OptionType.BOOLEAN,
        default_value="true",
        description="My custom option",
        category="Test"
    )
    assert opt.name == "my-option"
    assert opt.option_type == OptionType.BOOLEAN
```

**Default parameters:**
- `name`: "test-option"
- `option_type`: `OptionType.STRING`
- `default_value`: `None`
- `description`: "Test description"
- `category`: "Other"
- `enum_values`: `()`

### `config_value_factory`
Factory function for creating `ConfigValue` instances.

```python
def test_config_value(config_value_factory):
    val = config_value_factory(
        name="my-option",
        value="my-value",
        line_number=10,
        is_modified=True
    )
    assert val.value == "my-value"
    assert val.line_number == 10
```

**Default parameters:**
- `name`: "test-option"
- `value`: `None`
- `line_number`: `None`
- `is_modified`: `False`

### `option_model_factory`
Factory function for creating complete `OptionModel` instances.

```python
def test_option_model(option_model_factory):
    model = option_model_factory(
        name="font-size",
        option_type=OptionType.INTEGER,
        default_value="12",
        current_value="14",
        is_modified=True
    )
    assert model.definition.default_value == "12"
    assert model.current.value == "14"
    assert model.is_modified is True
```

**Default parameters:**
- `name`: "test-option"
- `option_type`: `OptionType.STRING`
- `default_value`: `None`
- `current_value`: `None`
- `is_modified`: `False`

## Usage Examples

### Testing Parser Functionality

```python
def test_parser_handles_enums(parser, mock_ghostty_output):
    options = parser.parse(mock_ghostty_output)
    cursor_style = next(opt for opt in options if opt.name == "cursor-style")
    assert cursor_style.option_type == OptionType.ENUM
    assert "block" in cursor_style.enum_values
```

### Testing Config File Operations

```python
def test_config_backup(tmp_config_file):
    # Original file exists
    assert tmp_config_file.exists()

    # Create backup
    backup_path = tmp_config_file.with_suffix(".config.bak")
    backup_path.write_text(tmp_config_file.read_text())

    assert backup_path.exists()
    # Both files are cleaned up automatically
```

### Creating Test Data

```python
def test_option_modification(option_model_factory):
    # Create a model in default state
    model = option_model_factory(
        name="cursor-blink",
        option_type=OptionType.BOOLEAN,
        default_value="false"
    )

    assert model.is_default is True

    # Modify it
    model.current.value = "true"
    model.current.is_modified = True

    assert model.is_default is False
    assert model.is_modified is True
```

## Best Practices

1. **Use factories for custom test data**: Instead of manually creating objects, use the factory fixtures.
2. **Leverage temporary files**: Use `tmp_config_file` and `tmp_config_dir` for tests that need file I/O.
3. **Don't worry about cleanup**: All fixtures automatically clean up after themselves.
4. **Combine fixtures**: You can use multiple fixtures in a single test.

```python
def test_combined(parser, tmp_config_file, option_factory):
    # Parse from temp file
    options = parser.parse_from_file(tmp_config_file)

    # Create custom option for comparison
    custom = option_factory(name="font-size", option_type=OptionType.INTEGER)

    # Test logic here
```
