"""
╔════════════════════════════════════════════════════════════════════════════╗
║                    VISUAL CONFIRMATION TESTS FOR HEATMAP                   ║
║                         UPDATED - FIXED VERSION                            ║
║                                                                            ║
║  Generated by: GitHub Copilot (Claude 3.5)                                 ║
║  Model: claude-3-5-sonnet-20241022                                         ║
║  Confidence in core logic: ~85-90% (improved with debugging)               ║
║                                                                            ║
║  🔧 FIXES IN THIS VERSION:                                                 ║
║  1. Removed duplicate fixture definitions (using conftest.py now)          ║
║  2. Fixed DataFrame structure to match function's parsing expectations     ║
║  3. Added real_truth_dataframe_small fixture for reliable tests            ║
║  4. Improved error handling and assertions                                 ║
║                                                                            ║
║  ⚠️  KEY CHANGE:                                                           ║
║  The function's column parsing expects:                                    ║
║    - Columns in format: s{stage}_p{ppm}_b{bit}                             ║
║    - But ALSO needs columns NOT matching this pattern at the START         ║
║    - The function finds where 's' columns START, then uses from there      ║
║                                                                            ║
║  The "Invalid shape (0,)" error occurred because:                          ║
║    1. DataFrame had NO non-s columns at the start                          ║
║    2. Function's logic couldn't find "data" section                        ║
║    3. Resulted in empty array passed to matplotlib                         ║
║                                                                            ║
╚════════════════════════════════════════════════════════════════════════════╝
"""

import pytest
import xml.etree.ElementTree as ET
import multiplied as mp


# ============================================================================
# NO FIXTURES DEFINED HERE - using conftest.py instead
# Fixtures used:
#   - sample_heatmap_dataframe (from conftest.py - FIXED)
#   - real_truth_dataframe_small (from conftest.py - RELIABLE)
#   - temp_svg_output (from conftest.py)
# ============================================================================


# ============================================================================
# DEBUGGING UTILITY: Print DataFrame structure
# ============================================================================


def inspect_dataframe(df, name="DataFrame"):
    """
    UTILITY FUNCTION: Debug helper to understand DataFrame structure

    PURPOSE:
        Prints detailed information about DataFrame to diagnose issues.
        Use this when tests fail to understand what data is being used.

    PRINTS:
        - Shape (rows, columns)
        - Column names
        - Data types
        - First few values

    USAGE:
        def test_something(sample_heatmap_dataframe):
            inspect_dataframe(sample_heatmap_dataframe, "Test Data")
            # Will print detailed info
    """
    print(f"\n{'=' * 70}")
    print(f"{name} INSPECTION")
    print(f"{'=' * 70}")
    print(f"Shape: {df.shape}")
    print(f"Columns: {list(df.columns)}")
    print(f"Column count: {len(df.columns)}")
    print("\nFirst row:")
    print(df.iloc[0] if len(df) > 0 else "No data")
    print(f"\nData types:\n{df.dtypes}")
    print(f"{'=' * 70}\n")


# ============================================================================
# VISUAL TEST 1: CODE GENERATES CORRECT STRUCTURE
# ============================================================================


class TestVisual1_CorrectStructure:
    """
    TEST GROUP: Code generates correct SVG structure

    PURPOSE:
        Verify that the heatmap function:
        1. Creates valid SVG file
        2. SVG contains expected element types
        3. Structure matches matplotlib's heatmap output

    SCENARIOS TESTED:
        ✓ SVG file is valid XML
        ✓ Contains <svg> root element
        ✓ Contains <image> element (the actual heatmap)
        ✓ Contains <g> elements (groups for organizing graphics)

    WHY THIS MATTERS:
        SVG is XML-based. If structure is wrong, the file won't render.
        This validates the "skeleton" without checking pixels.

    AI CONFIDENCE: ~90%
        SVG structure from matplotlib is consistent.

    🔧 FIXES:
        - Now uses real_truth_dataframe_small instead of synthetic data
        - This fixture uses actual Multiplied algorithm output
        - More reliable and matches production data format
    """

    def test_svg_is_valid_xml(self, real_truth_dataframe_small, temp_svg_output):
        """
        TEST: SVG file is valid, parseable XML

        WHAT IT DOES:
            1. Create heatmap file using real algorithm data
            2. Try to parse as XML using ElementTree
            3. If parsing fails, XML is corrupted

        EXPECTED RESULT:
            Should parse without exception

        WHY IT MATTERS:
            If XML isn't valid, file won't render anywhere.
            This is the most basic structure check.

        AI CONFIDENCE: ~95%
            ElementTree.parse() will definitely catch invalid XML.

        🔧 CHANGED:
            - Uses real_truth_dataframe_small (reliable fixture)
            - No more synthetic data issues
        """
        df = real_truth_dataframe_small

        # Create the heatmap
        # ⚠️ IMPORTANT: Using real data, not synthetic
        mp.df_global_heatmap(str(temp_svg_output), "Test Heatmap", df)

        # Try to parse as XML
        # If this succeeds, XML is valid
        # If it fails, ET.ParseError will be raised
        try:
            tree = ET.parse(temp_svg_output)
            root = tree.getroot()

            # If we get here, parsing succeeded
            assert root is not None, "XML parsing returned None"

        except ET.ParseError as e:
            pytest.fail(
                f"SVG file is not valid XML. ParseError: {e}\n"
                f"File may be corrupted or not actually SVG format.\n"
                f"Check that DataFrame structure is correct."
            )

    def test_svg_has_root_element(self, real_truth_dataframe_small, temp_svg_output):
        """
        TEST: SVG has <svg> root element

        WHAT IT DOES:
            1. Parse SVG as XML
            2. Check that root element is <svg>

        EXPECTED RESULT:
            root.tag should contain 'svg'

        WHY IT MATTERS:
            SVG files must have <svg> as root. This confirms it's actually SVG.

        AI CONFIDENCE: ~95%

        🔧 CHANGED:
            - Uses real_truth_dataframe_small
        """
        df = real_truth_dataframe_small

        mp.df_global_heatmap(str(temp_svg_output), "Test Heatmap", df)

        # Parse the file
        tree = ET.parse(temp_svg_output)
        root = tree.getroot()

        # ASSERTION: Root tag should be 'svg'
        # (May have namespace, so check if 'svg' is in the tag)
        assert "svg" in root.tag.lower(), (
            f"Root element is '{root.tag}', expected 'svg' or namespaced svg"
        )

    def test_svg_contains_image_element(
        self, real_truth_dataframe_small, temp_svg_output
    ):
        """
        TEST: SVG contains <image> element for heatmap

        WHAT IT DOES:
            1. Parse SVG
            2. Search for <image> elements
            3. Verify at least one exists

        EXPECTED RESULT:
            Should find at least 1 <image> element

        WHY IT MATTERS:
            The heatmap data is rendered as an <image> element.
            If it's missing, no actual heatmap data is shown.

        AI CONFIDENCE: ~90%
            matplotlib.imshow() generates <image> elements reliably.

        🔧 CHANGED:
            - Uses real_truth_dataframe_small
            - Better error messages for debugging
        """
        df = real_truth_dataframe_small

        mp.df_global_heatmap(str(temp_svg_output), "Test Heatmap", df)

        tree = ET.parse(temp_svg_output)
        root = tree.getroot()

        # Define SVG namespace (some SVG files use it, some don't)
        namespaces = {
            "svg": "http://www.w3.org/2000/svg",
        }

        # Search for <image> elements with namespace
        images = root.findall(".//{http://www.w3.org/2000/svg}image")

        # If namespace didn't work, try without
        if len(images) == 0:
            images = root.findall(".//image")

        # ASSERTION: At least one image element should exist
        assert len(images) > 0, (
            f"SVG should contain at least 1 <image> element for the heatmap. "
            f"Found {len(images)}. Check DataFrame structure is being parsed correctly."
        )

    def test_svg_contains_group_elements(
        self, real_truth_dataframe_small, temp_svg_output
    ):
        """
        TEST: SVG contains group (<g>) elements

        WHAT IT DOES:
            1. Parse SVG
            2. Count <g> (group) elements
            3. Verify reasonable number exist

        EXPECTED RESULT:
            Should have multiple <g> elements (axes, labels, etc.)

        WHY IT MATTERS:
            matplotlib organizes graphics in groups for structure.
            Few/no groups suggests incomplete rendering.

        AI CONFIDENCE: ~90%

        🔧 CHANGED:
            - Uses real_truth_dataframe_small
        """
        df = real_truth_dataframe_small

        mp.df_global_heatmap(str(temp_svg_output), "Test Heatmap", df)

        tree = ET.parse(temp_svg_output)
        root = tree.getroot()

        # Find all group elements
        groups = root.findall(".//{http://www.w3.org/2000/svg}g")
        if len(groups) == 0:
            groups = root.findall(".//g")

        # ASSERTION: Should have multiple groups
        assert len(groups) >= 2, (
            f"SVG should contain multiple <g> elements for structure. "
            f"Found only {len(groups)}. SVG structure may be incomplete."
        )


# ============================================================================
# VISUAL TEST 2: SVG STRUCTURE IS VALID
# ============================================================================


class TestVisual2_SVGStructureValidity:
    """
    TEST GROUP: SVG structure is valid and complete

    PURPOSE:
        Verify that SVG has expected elements for a complete plot:
        1. Text elements (for labels, title)
        2. Proper dimensions (width, height attributes)
        3. Title information

    SCENARIOS TESTED:
        ✓ SVG has text elements (labels, axes)
        ✓ SVG has width/height attributes
        ✓ SVG dimensions are reasonable

    WHY THIS MATTERS:
        These elements are necessary for a complete, renderable plot.
        Missing elements = incomplete visualization.

    AI CONFIDENCE: ~85%
        matplotlib consistently generates these.

    🔧 FIXES:
        - All tests updated to use real_truth_dataframe_small
        - Removed synthetic data that was causing empty array errors
    """

    def test_svg_contains_text_elements(
        self, real_truth_dataframe_small, temp_svg_output
    ):
        """
        TEST: SVG contains text elements (labels, title, etc.)

        WHAT IT DOES:
            1. Parse SVG
            2. Search for <text> elements
            3. Verify at least some exist

        EXPECTED RESULT:
            Should find text elements for axis labels

        WHY IT MATTERS:
            Text elements provide context (axis labels, title).
            Without them, the heatmap is unlabeled and confusing.

        AI CONFIDENCE: ~90%

        🔧 CHANGED:
            - Uses real_truth_dataframe_small
        """
        df = real_truth_dataframe_small

        mp.df_global_heatmap(str(temp_svg_output), "Test Heatmap", df)

        tree = ET.parse(temp_svg_output)
        root = tree.getroot()

        # Find text elements
        text_elements = root.findall(".//{http://www.w3.org/2000/svg}text")
        if len(text_elements) == 0:
            text_elements = root.findall(".//text")

        # ASSERTION: Should have text elements
        assert len(text_elements) > 0, (
            f"SVG should contain <text> elements for labels/axes. "
            f"Found {len(text_elements)}. Plot may be missing labels."
        )

    def test_svg_has_dimensions(self, real_truth_dataframe_small, temp_svg_output):
        """
        TEST: SVG specifies width and height

        WHAT IT DOES:
            1. Parse SVG
            2. Check for width and height attributes on root
            3. Verify they're present and non-zero

        EXPECTED RESULT:
            SVG root should have width="..." and height="..."

        WHY IT MATTERS:
            Dimensions tell viewers how large the image should be.
            Missing dimensions can cause rendering issues.

        AI CONFIDENCE: ~95%

        🔧 CHANGED:
            - Uses real_truth_dataframe_small
        """
        df = real_truth_dataframe_small

        mp.df_global_heatmap(str(temp_svg_output), "Test Heatmap", df)

        tree = ET.parse(temp_svg_output)
        root = tree.getroot()

        # Get width and height attributes
        width = root.get("width")
        height = root.get("height")

        # ASSERTION: Both should exist
        assert width is not None, "SVG missing 'width' attribute"
        assert height is not None, "SVG missing 'height' attribute"

        # ASSERTION: Both should be non-zero
        # Dimensions are typically like "1024pt" or "1024"
        assert len(width) > 0, "SVG width attribute is empty"
        assert len(height) > 0, "SVG height attribute is empty"

    def test_svg_dimensions_are_reasonable(
        self, real_truth_dataframe_small, temp_svg_output
    ):
        """
        TEST: SVG dimensions are in reasonable range

        WHAT IT DOES:
            1. Parse width/height attributes
            2. Extract numeric values
            3. Check they're in expected range

        EXPECTED RESULT:
            Dimensions should be > 100 and < 100,000 (in pt/px)

        WHY IT MATTERS:
            Suspiciously small (<100) or large (>100k) dimensions
            suggest rendering problems or misconfiguration.

        AI CONFIDENCE: ~80%
            Depends on matplotlib's figure size settings (figsize=(16, 9), dpi=200).

        🔧 CHANGED:
            - Uses real_truth_dataframe_small
            - Adjusted expected ranges based on actual function parameters
        """
        df = real_truth_dataframe_small

        mp.df_global_heatmap(str(temp_svg_output), "Test Heatmap", df)

        tree = ET.parse(temp_svg_output)
        root = tree.getroot()

        width_str = root.get("width")
        height_str = root.get("height")

        # Extract numeric part (remove 'pt', 'px', etc.)
        try:
            width = float("".join(c for c in width_str if c.isdigit() or c == "."))
            height = float("".join(c for c in height_str if c.isdigit() or c == "."))
        except (ValueError, AttributeError) as e:
            pytest.fail(f"Couldn't parse dimensions: {e}")

        # ASSERTION: Dimensions should be reasonable
        # figsize=(16, 9) at 200dpi = ~3200x1800
        # With tolerance for matplotlib versions
        assert 500 < width < 10000, (
            f"Width {width}pt seems unreasonable. "
            f"Expected ~3200 for figsize=(16,9), dpi=200."
        )

        assert 300 < height < 10000, (
            f"Height {height}pt seems unreasonable. "
            f"Expected ~1800 for figsize=(16,9), dpi=200."
        )


# ============================================================================
# VISUAL TEST 3: DARK THEME APPLIES CORRECTLY
# ============================================================================


class TestVisual3_DarkThemeApplication:
    """
    TEST GROUP: Dark theme styling is applied

    PURPOSE:
        When dark=True is passed, matplotlib applies 'dark_background' style.
        This should affect:
        1. Background color
        2. Text colors (light on dark)
        3. Overall appearance

    SCENARIOS TESTED:
        ✓ Dark theme SVG is different from light theme
        ✓ Dark theme style is referenced in SVG
        ✓ Dark SVG has expected styling attributes

    WHY THIS MATTERS:
        Dark theme is an important feature. Verify it actually works.

    AI CONFIDENCE: ~85%

    🔧 FIXES:
        - All tests use real_truth_dataframe_small
        - More robust comparisons
    """

    def test_dark_theme_creates_different_svg(
        self, real_truth_dataframe_small, tmp_path
    ):
        """
        TEST: Dark theme produces visually different SVG

        WHAT IT DOES:
            1. Generate SVG with dark=False (light theme)
            2. Generate SVG with dark=True (dark theme)
            3. Compare file contents
            4. They should be different (different styling)

        EXPECTED RESULT:
            SVG content should differ significantly

        WHY IT MATTERS:
            If both modes produce identical SVG, theme isn't working.

        AI CONFIDENCE: ~90%

        🔧 CHANGED:
            - Uses real_truth_dataframe_small
            - Better error messages
        """
        df = real_truth_dataframe_small

        light_path = tmp_path / "light.svg"
        dark_path = tmp_path / "dark.svg"

        # Generate light theme
        mp.df_global_heatmap(str(light_path), "Test", df, dark=False)

        # Generate dark theme
        mp.df_global_heatmap(str(dark_path), "Test", df, dark=True)

        # Read both files
        with open(light_path, "r") as f:
            light_content = f.read()

        with open(dark_path, "r") as f:
            dark_content = f.read()

        # ASSERTION: Content should be different
        assert light_content != dark_content, (
            "Dark and light theme SVGs are identical. Theme setting may not be applied."
        )

        # ASSERTION: Difference should be significant (not just whitespace)
        # Calculate similarity: count matching characters
        matching_chars = sum(1 for a, b in zip(light_content, dark_content) if a == b)
        similarity = matching_chars / max(len(light_content), len(dark_content))

        assert similarity < 0.95, (
            f"SVGs are {similarity * 100:.1f}% similar. "
            f"Expected more significant differences between light/dark themes."
        )

    def test_dark_theme_svg_contains_style_info(
        self, real_truth_dataframe_small, temp_svg_output
    ):
        """
        TEST: Dark theme SVG contains style information

        WHAT IT DOES:
            1. Generate dark theme SVG
            2. Read file content as text
            3. Check for style-related content

        EXPECTED RESULT:
            SVG should contain <style> tags or style attributes

        WHY IT MATTERS:
            Styling is applied via CSS in <style> tags or style attributes.
            Without them, theming doesn't work.

        AI CONFIDENCE: ~80%

        🔧 CHANGED:
            - Uses real_truth_dataframe_small
        """
        df = real_truth_dataframe_small

        mp.df_global_heatmap(str(temp_svg_output), "Test", df, dark=True)

        # Read as text
        with open(temp_svg_output, "r") as f:
            content = f.read()

        # Check for style-related content
        has_style_tag = "<style" in content
        has_style_attr = "style=" in content

        # ASSERTION: Should have some styling
        assert has_style_tag or has_style_attr, (
            "Dark theme SVG doesn't contain style information. "
            "Theming may not be applied."
        )

    def test_dark_theme_affects_colors(
        self, real_truth_dataframe_small, temp_svg_output
    ):
        """
        TEST: Dark theme uses different color scheme

        WHAT IT DOES:
            1. Generate dark theme SVG
            2. Parse XML and look for color attributes
            3. Verify colors are present

        EXPECTED RESULT:
            SVG should have color specifications (#RRGGBB format)

        WHY IT MATTERS:
            Color specification proves styling is actually applied.

        AI CONFIDENCE: ~85%

        🔧 CHANGED:
            - Uses real_truth_dataframe_small
        """
        df = real_truth_dataframe_small

        mp.df_global_heatmap(str(temp_svg_output), "Test", df, dark=True)

        with open(temp_svg_output, "r") as f:
            content = f.read()

        # Look for hex color codes (#RRGGBB or #RGB)
        import re

        color_pattern = r"#[0-9a-fA-F]{3,6}"
        colors_found = re.findall(color_pattern, content)

        # ASSERTION: Should have color specifications
        assert len(colors_found) > 0, (
            "Dark theme SVG doesn't contain color specifications. "
            "Colors should be in #RRGGBB format."
        )

        # ASSERTION: Should have variety of colors (not just one)
        unique_colors = set(colors_found)
        assert len(unique_colors) > 2, (
            f"Dark theme has only {len(unique_colors)} unique colors. "
            f"Expected more variety for proper styling."
        )


# ============================================================================
# INTEGRATION TEST: All Three Scenarios Together
# ============================================================================


class TestVisual_Integration:
    """
    TEST GROUP: All visual aspects together

    PURPOSE:
        Real-world use combines all three aspects:
        1. Structure is correct
        2. SVG is valid
        3. Themes work

        This test exercises all at once with REAL data.

    AI CONFIDENCE: ~90%

    🔧 FIXES:
        - All tests now use real_truth_dataframe_small
        - Integration tests are now reliable
    """

    def test_complete_heatmap_generation_light_theme(
        self, real_truth_dataframe_small, temp_svg_output
    ):
        """
        TEST: Complete light theme heatmap - integration

        WHAT IT DOES:
            1. Generate complete heatmap with real data
            2. Verify file exists
            3. Verify XML is valid
            4. Verify structure is complete

        EXPECTED RESULT:
            All checks should pass

        WHY IT MATTERS:
            Real-world scenario: user creates heatmap with light theme.

        AI CONFIDENCE: ~95%

        🔧 CHANGED:
            - Uses real_truth_dataframe_small
        """
        df = real_truth_dataframe_small

        # Generate heatmap
        mp.df_global_heatmap(
            str(temp_svg_output), "Complete Test Heatmap", df, dark=False
        )

        # Verify: File exists
        assert temp_svg_output.exists(), "Output file was not created"

        # Verify: Valid XML
        try:
            tree = ET.parse(temp_svg_output)
            root = tree.getroot()
            assert "svg" in root.tag.lower(), f"Root element is not SVG: {root.tag}"
        except ET.ParseError as e:
            pytest.fail(f"SVG is not valid XML: {e}")

        # Verify: Has expected elements
        images = root.findall(".//{http://www.w3.org/2000/svg}image")
        if not images:
            images = root.findall(".//image")
        assert len(images) > 0, "No image elements found in SVG"

        # Verify: Has text labels
        text = root.findall(".//{http://www.w3.org/2000/svg}text")
        if not text:
            text = root.findall(".//text")
        assert len(text) > 0, "No text elements found in SVG"

    def test_complete_heatmap_generation_dark_theme(
        self, real_truth_dataframe_small, temp_svg_output
    ):
        """
        TEST: Complete dark theme heatmap - integration

        WHAT IT DOES:
            1. Generate complete heatmap with dark theme
            2. Run all structure checks

        EXPECTED RESULT:
            All checks pass + dark theme styling present

        AI CONFIDENCE: ~95%

        🔧 CHANGED:
            - Uses real_truth_dataframe_small
        """
        df = real_truth_dataframe_small

        # Generate heatmap
        mp.df_global_heatmap(
            str(temp_svg_output), "Complete Test Heatmap", df, dark=True
        )

        # Verify: File exists
        assert temp_svg_output.exists(), "Output file was not created"

        # Verify: Valid XML
        try:
            tree = ET.parse(temp_svg_output)
            root = tree.getroot()
            assert "svg" in root.tag.lower()
        except ET.ParseError as e:
            pytest.fail(f"SVG is not valid XML: {e}")

        # Verify: Has expected elements
        images = root.findall(".//{http://www.w3.org/2000/svg}image")
        if not images:
            images = root.findall(".//image")
        assert len(images) > 0

        # Verify: Has text labels
        text = root.findall(".//{http://www.w3.org/2000/svg}text")
        if not text:
            text = root.findall(".//text")
        assert len(text) > 0

        # Verify: Has styling (dark theme specific)
        with open(temp_svg_output, "r") as f:
            content = f.read()
        assert "<style" in content or "style=" in content, (
            "Dark theme styling not found in SVG"
        )


"""
═══════════════════════════════════════════════════════════════════════════════
VISUAL TESTS - FIXED VERSION SUMMARY
═══════════════════════════════════════════════════════════════════════════════

🔧 MAJOR CHANGES FROM PREVIOUS VERSION:

1. REMOVED DUPLICATE FIXTURES
   - No longer defining fixtures in this file
   - All fixtures come from conftest.py
   - Eliminates fixture conflicts and confusion

2. FIXED "Invalid shape (0,)" ERROR
   - Root cause: synthetic sample_heatmap_dataframe had wrong structure
   - Solution: Use real_truth_dataframe_small from conftest.py
   - This fixture uses actual Multiplied algorithm output
   - Much more reliable and matches production format

3. IMPROVED ALL TESTS
   - All tests now use real_truth_dataframe_small
   - Consistent, reliable behavior
   - Better error messages for debugging
   - Clear docstrings explaining changes

4. BETTER ERROR HANDLING
   - More descriptive assertions
   - Clearer failure messages
   - Easier to diagnose test failures

═══════════════════════════════════════════════════════════════════════════════
HOW TO RUN NOW:
═══════════════════════════════════════════════════════════════════════════════

Run all visual tests:
  pytest tests/test_heatmap_visual.py -v

Run specific test:
  pytest tests/test_heatmap_visual.py::TestVisual1_CorrectStructure::test_svg_is_valid_xml -v

Run with print output (useful for debugging):
  pytest tests/test_heatmap_visual.py -v -s

Run and stop on first failure:
  pytest tests/test_heatmap_visual.py -x

═══════════════════════════════════════════════════════════════════════════════
WHAT'S TESTED (3 Scenarios):
════════════════════════════���══════════════════════════════════════════════════

Scenario 1: Code generates correct structure (4 tests)
  ✓ SVG is valid XML
  ✓ Contains <svg> root element
  ✓ Contains <image> element (heatmap data)
  ✓ Contains <g> elements (structure)

Scenario 2: SVG structure is valid (3 tests)
  ✓ Contains <text> elements (labels)
  ✓ Has width/height attributes
  ✓ Dimensions are reasonable

Scenario 3: Dark theme applies (3 tests)
  ✓ Dark SVG differs from light SVG
  ✓ Dark SVG contains style information
  ✓ Colors are specified

Integration Tests (2 tests)
  ✓ Light theme: complete end-to-end
  ✓ Dark theme: complete end-to-end

TOTAL: 12 tests

═══════════════════════════════════════════════════════════════════════════════
IF TESTS STILL FAIL:
═══════════════════════════════════════════════════════════════════════════════

1. Check conftest.py is in tests/ directory:
   ls tests/conftest.py

2. Verify __init__.py exists:
   ls tests/__init__.py

3. Check basic_algorithm fixture works:
   pytest tests/conftest.py::basic_algorithm -v

4. Check real_truth_dataframe_small generates data:
   pytest tests/test_heatmap_basic.py::TestTier1_FileOutputBasics -v

5. If still failing, inspect the DataFrame:
   - Uncomment inspect_dataframe(df, "Debug") in a test
   - Run: pytest tests/test_heatmap_visual.py -v -s
   - Look at printed output to see DataFrame structure

═══════════════════════════════════════════════════════════════════════════════
"""
