"""Tests for {{ module_name }} instrument interface.

These tests use the fake interface to validate the interface contract
without requiring actual hardware.

Generated by: madsci new module --template module/instrument
Template version: {{ template_version }}
"""

import pytest

from {{ module_name }}_fake_interface import {{ module_name | pascal_case }}FakeInterface


class Test{{ module_name | pascal_case }}FakeInterface:
    """Test cases for the {{ module_name }} fake instrument interface."""

    @pytest.fixture
    def interface(self) -> {{ module_name | pascal_case }}FakeInterface:
        """Create a test interface instance with low latency."""
        return {{ module_name | pascal_case }}FakeInterface(simulated_latency=0.01)

    def test_initial_state(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test that interface starts disconnected and uninitialized."""
        assert not interface.is_connected
        assert not interface.is_initialized
        assert not interface.is_calibrated
        assert interface.operation_count == 0
        assert interface.readings == []

    def test_connect(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test connection."""
        interface.connect()
        assert interface.is_connected
        assert not interface.is_initialized

    def test_disconnect(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test disconnection."""
        interface.connect()
        interface.disconnect()
        assert not interface.is_connected

    def test_initialize(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test instrument initialization."""
        interface.connect()
        interface.initialize()
        assert interface.is_initialized

    def test_initialize_requires_connection(
        self, interface: {{ module_name | pascal_case }}FakeInterface
    ) -> None:
        """Test that initialization requires connection."""
        with pytest.raises(RuntimeError, match="Not connected"):
            interface.initialize()

    def test_shutdown(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test instrument shutdown."""
        interface.connect()
        interface.initialize()
        interface.shutdown()
        assert not interface.is_initialized
        assert interface.is_connected

    def test_measure(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test taking a measurement."""
        interface.connect()
        interface.initialize()
        reading = interface.measure()

        assert reading.value is not None
        assert reading.units == "counts"
        assert reading.timestamp is not None
        assert interface.operation_count == 1
        assert len(interface.readings) == 1

    def test_measure_with_channel(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test taking a measurement on a specific channel."""
        interface.connect()
        interface.initialize()
        reading = interface.measure(channel="ch1")

        assert reading.channel == "ch1"

    def test_measure_requires_initialization(
        self, interface: {{ module_name | pascal_case }}FakeInterface
    ) -> None:
        """Test that measurement requires initialization."""
        interface.connect()
        with pytest.raises(RuntimeError, match="not initialized"):
            interface.measure()

    def test_calibrate(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test calibration."""
        interface.connect()
        interface.initialize()
        result = interface.calibrate(reference_value=42.0)

        assert result.calibrated is True
        assert result.calibration_timestamp is not None
        assert result.calibration_parameters == {"reference_value": 42.0}
        assert interface.is_calibrated

    def test_calibrate_requires_initialization(
        self, interface: {{ module_name | pascal_case }}FakeInterface
    ) -> None:
        """Test that calibration requires initialization."""
        interface.connect()
        with pytest.raises(RuntimeError, match="not initialized"):
            interface.calibrate()

    def test_get_status(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test status retrieval."""
        interface.connect()
        interface.initialize()
        status = interface.get_status()

        assert status["connected"] is True
        assert status["initialized"] is True
        assert status["calibrated"] is False

    def test_get_status_requires_connection(
        self, interface: {{ module_name | pascal_case }}FakeInterface
    ) -> None:
        """Test that status retrieval requires connection."""
        with pytest.raises(RuntimeError, match="Not connected"):
            interface.get_status()

    def test_reset_state(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test state reset."""
        interface.connect()
        interface.initialize()
        interface.measure()
        interface.calibrate()
        interface.reset_state()

        assert interface.operation_count == 0
        assert interface.readings == []
        assert not interface.is_calibrated

    def test_multiple_readings(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test taking multiple readings."""
        interface.connect()
        interface.initialize()

        for _ in range(3):
            interface.measure()

        assert interface.operation_count == 3
        assert len(interface.readings) == 3
