# chuk-motion/tests/test_token_manager.py
"""
Tests for TokenManager - token import/export functionality.
"""

import json

import pytest


class TestTokenManagerInit:
    """Test TokenManager initialization."""

    @pytest.mark.asyncio
    async def test_init_with_vfs(self, token_manager):
        """Test TokenManager initializes with virtual filesystem."""
        assert token_manager.vfs is not None
        assert token_manager.custom_typography_tokens == {}
        assert token_manager.custom_color_tokens == {}
        assert token_manager.custom_motion_tokens == {}


class TestTypographyTokenExportImport:
    """Test typography token export and import."""

    @pytest.mark.asyncio
    async def test_export_all_typography_tokens(self, token_manager):
        """Test exporting all typography tokens."""
        result = await token_manager.export_typography_tokens(
            file_path="test_typography.json", include_all=True
        )

        assert result == "test_typography.json"

        # Verify file was written
        content = await token_manager.vfs.read_text("test_typography.json")
        data = json.loads(content)

        assert "font_families" in data
        assert "font_sizes" in data
        assert "font_weights" in data

    @pytest.mark.asyncio
    async def test_export_font_families_only(self, token_manager):
        """Test exporting only font families."""
        result = await token_manager.export_typography_tokens(
            file_path="fonts_only.json", include_all=False, font_families_only=True
        )

        assert result == "fonts_only.json"

        content = await token_manager.vfs.read_text("fonts_only.json")
        data = json.loads(content)

        assert "font_families" in data
        assert "text_styles" not in data

    @pytest.mark.asyncio
    async def test_export_text_styles_only(self, token_manager):
        """Test exporting only text styles."""
        result = await token_manager.export_typography_tokens(
            file_path="styles_only.json", include_all=False, text_styles_only=True
        )

        assert result == "styles_only.json"

        content = await token_manager.vfs.read_text("styles_only.json")
        data = json.loads(content)

        assert "text_styles" in data
        assert "font_families" not in data

    @pytest.mark.asyncio
    async def test_export_with_custom_tokens(self, token_manager):
        """Test exporting includes custom tokens."""
        # Add custom tokens
        token_manager.custom_typography_tokens = {"custom_key": "custom_value"}

        await token_manager.export_typography_tokens(file_path="with_custom.json")

        content = await token_manager.vfs.read_text("with_custom.json")
        data = json.loads(content)

        assert "custom" in data
        assert data["custom"]["custom_key"] == "custom_value"

    @pytest.mark.asyncio
    async def test_export_default_filepath(self, token_manager):
        """Test exporting with default file path."""
        result = await token_manager.export_typography_tokens()

        assert result == "typography_tokens.json"
        assert await token_manager.vfs.exists("typography_tokens.json")

    @pytest.mark.asyncio
    async def test_import_typography_tokens(self, token_manager, sample_typography_tokens):
        """Test importing typography tokens."""
        # Create a file to import
        await token_manager.vfs.write_file(
            "import_typography.json", json.dumps(sample_typography_tokens)
        )

        result = await token_manager.import_typography_tokens(file_path="import_typography.json")

        assert "Successfully imported" in result
        assert token_manager.custom_typography_tokens == sample_typography_tokens

    @pytest.mark.asyncio
    async def test_import_typography_tokens_merge(self, token_manager, sample_typography_tokens):
        """Test importing typography tokens with merge."""
        # Set existing custom tokens
        token_manager.custom_typography_tokens = {"existing_key": "existing_value"}

        # Create a file to import
        await token_manager.vfs.write_file(
            "import_typography.json", json.dumps(sample_typography_tokens)
        )

        result = await token_manager.import_typography_tokens(
            file_path="import_typography.json", merge=True
        )

        assert "Successfully imported" in result
        assert "existing_key" in token_manager.custom_typography_tokens
        assert "font_families" in token_manager.custom_typography_tokens

    @pytest.mark.asyncio
    async def test_import_typography_tokens_replace(self, token_manager, sample_typography_tokens):
        """Test importing typography tokens without merge."""
        # Set existing custom tokens
        token_manager.custom_typography_tokens = {"existing_key": "existing_value"}

        # Create a file to import
        await token_manager.vfs.write_file(
            "import_typography.json", json.dumps(sample_typography_tokens)
        )

        result = await token_manager.import_typography_tokens(
            file_path="import_typography.json", merge=False
        )

        assert "Successfully imported" in result
        assert "existing_key" not in token_manager.custom_typography_tokens
        assert token_manager.custom_typography_tokens == sample_typography_tokens

    @pytest.mark.asyncio
    async def test_import_invalid_typography_tokens(self, token_manager):
        """Test importing invalid typography tokens."""
        # Create invalid file
        await token_manager.vfs.write_file("invalid_typography.json", json.dumps("not a dict"))

        result = await token_manager.import_typography_tokens(file_path="invalid_typography.json")

        assert "Error" in result


class TestColorTokenExportImport:
    """Test color token export and import."""

    @pytest.mark.asyncio
    async def test_export_all_color_tokens(self, token_manager):
        """Test exporting all color tokens."""
        result = await token_manager.export_color_tokens(file_path="test_colors.json")

        assert result == "test_colors.json"

        content = await token_manager.vfs.read_text("test_colors.json")
        data = json.loads(content)

        assert "tech" in data
        assert "finance" in data
        assert "education" in data

    @pytest.mark.asyncio
    async def test_export_specific_theme_colors(self, token_manager):
        """Test exporting specific theme colors."""
        result = await token_manager.export_color_tokens(
            file_path="tech_colors.json", theme_name="tech"
        )

        assert result == "tech_colors.json"

        content = await token_manager.vfs.read_text("tech_colors.json")
        data = json.loads(content)

        assert "tech" in data
        assert "finance" not in data

    @pytest.mark.asyncio
    async def test_export_nonexistent_theme(self, token_manager):
        """Test exporting nonexistent theme."""
        result = await token_manager.export_color_tokens(
            file_path="invalid_theme.json", theme_name="nonexistent"
        )

        assert "Error" in result
        assert "not found" in result

    @pytest.mark.asyncio
    async def test_import_color_tokens(self, token_manager, sample_color_tokens):
        """Test importing color tokens."""
        # Create a file to import
        await token_manager.vfs.write_file("import_colors.json", json.dumps(sample_color_tokens))

        result = await token_manager.import_color_tokens(file_path="import_colors.json")

        assert "Successfully imported" in result
        assert token_manager.custom_color_tokens == sample_color_tokens

    @pytest.mark.asyncio
    async def test_import_invalid_color_tokens(self, token_manager):
        """Test importing invalid color tokens."""
        await token_manager.vfs.write_file(
            "invalid_colors.json",
            json.dumps([1, 2, 3]),  # Not a dict
        )

        result = await token_manager.import_color_tokens(file_path="invalid_colors.json")

        assert "Error" in result

    @pytest.mark.asyncio
    async def test_export_color_tokens_default_filepath(self, token_manager):
        """Test exporting color tokens with default file path."""
        result = await token_manager.export_color_tokens()

        assert result == "color_tokens.json"
        assert await token_manager.vfs.exists("color_tokens.json")

    @pytest.mark.asyncio
    async def test_export_color_tokens_with_custom(self, token_manager):
        """Test exporting color tokens includes custom tokens."""
        token_manager.custom_color_tokens = {"custom_theme": {"primary": ["#FF0000"]}}

        await token_manager.export_color_tokens(file_path="colors_with_custom.json")

        content = await token_manager.vfs.read_text("colors_with_custom.json")
        data = json.loads(content)

        assert "custom" in data
        assert "custom_theme" in data["custom"]

    @pytest.mark.asyncio
    async def test_export_color_tokens_exception(self, token_manager):
        """Test export color tokens handles exceptions."""

        # Mock vfs to raise exception
        async def raise_exception(path, content):
            raise OSError("Write failed")

        token_manager.vfs.write_file = raise_exception

        result = await token_manager.export_color_tokens()

        assert "Error exporting color tokens" in result


class TestMotionTokenExportImport:
    """Test motion token export and import."""

    @pytest.mark.asyncio
    async def test_export_all_motion_tokens(self, token_manager):
        """Test exporting all motion tokens."""
        result = await token_manager.export_motion_tokens(file_path="test_motion.json")

        assert result == "test_motion.json"

        content = await token_manager.vfs.read_text("test_motion.json")
        data = json.loads(content)

        assert "spring_configs" in data
        assert "easing" in data
        assert "duration" in data

    @pytest.mark.asyncio
    async def test_export_springs_only(self, token_manager):
        """Test exporting only spring configs."""
        result = await token_manager.export_motion_tokens(
            file_path="springs_only.json", springs_only=True
        )

        assert result == "springs_only.json"

        content = await token_manager.vfs.read_text("springs_only.json")
        data = json.loads(content)

        assert "spring_configs" in data
        assert "easing_curves" not in data

    @pytest.mark.asyncio
    async def test_export_easings_only(self, token_manager):
        """Test exporting only easing curves."""
        result = await token_manager.export_motion_tokens(
            file_path="easings_only.json", easings_only=True
        )

        assert result == "easings_only.json"

        content = await token_manager.vfs.read_text("easings_only.json")
        data = json.loads(content)

        assert "easing" in data
        assert "spring_configs" not in data

    @pytest.mark.asyncio
    async def test_export_presets_only(self, token_manager):
        """Test exporting only animation presets."""
        result = await token_manager.export_motion_tokens(
            file_path="presets_only.json", presets_only=True
        )

        assert result == "presets_only.json"

        content = await token_manager.vfs.read_text("presets_only.json")
        data = json.loads(content)

        assert "enter" in data
        assert "exit" in data
        assert "spring_configs" not in data

    @pytest.mark.asyncio
    async def test_import_motion_tokens(self, token_manager, sample_motion_tokens):
        """Test importing motion tokens."""
        await token_manager.vfs.write_file("import_motion.json", json.dumps(sample_motion_tokens))

        result = await token_manager.import_motion_tokens(file_path="import_motion.json")

        assert "Successfully imported" in result
        assert token_manager.custom_motion_tokens == sample_motion_tokens

    @pytest.mark.asyncio
    async def test_export_motion_tokens_default_filepath(self, token_manager):
        """Test exporting motion tokens with default file path."""
        result = await token_manager.export_motion_tokens()

        assert result == "motion_tokens.json"
        assert await token_manager.vfs.exists("motion_tokens.json")

    @pytest.mark.asyncio
    async def test_export_motion_tokens_with_custom(self, token_manager):
        """Test exporting motion tokens includes custom tokens."""
        token_manager.custom_motion_tokens = {"custom_spring": {"stiffness": 100}}

        await token_manager.export_motion_tokens(file_path="motion_with_custom.json")

        content = await token_manager.vfs.read_text("motion_with_custom.json")
        data = json.loads(content)

        assert "custom" in data
        assert "custom_spring" in data["custom"]

    @pytest.mark.asyncio
    async def test_import_invalid_motion_tokens(self, token_manager):
        """Test importing invalid motion tokens."""
        await token_manager.vfs.write_file("invalid_motion.json", json.dumps([1, 2, 3]))

        result = await token_manager.import_motion_tokens(file_path="invalid_motion.json")

        assert "Error" in result


class TestExportAllTokens:
    """Test exporting all token types."""

    @pytest.mark.asyncio
    async def test_export_all_tokens(self, token_manager):
        """Test exporting all token types to directory."""
        result = await token_manager.export_all_tokens(output_dir="all_tokens")

        assert "typography" in result
        assert "colors" in result
        assert "motion" in result

        # Verify all files exist
        typo_content = await token_manager.vfs.read_text(result["typography"])
        color_content = await token_manager.vfs.read_text(result["colors"])
        motion_content = await token_manager.vfs.read_text(result["motion"])

        assert json.loads(typo_content)
        assert json.loads(color_content)
        assert json.loads(motion_content)


class TestTokenGetters:
    """Test token getter methods."""

    @pytest.mark.asyncio
    async def test_get_typography_token_from_default(self, token_manager):
        """Test getting typography token from defaults."""
        result = token_manager.get_typography_token("font_families", "display")

        assert result is not None
        assert "name" in result
        assert result["name"] == "Display"

    @pytest.mark.asyncio
    async def test_get_typography_token_from_custom(self, token_manager):
        """Test getting typography token from custom tokens."""
        token_manager.custom_typography_tokens = {
            "font_families": {"custom": {"name": "Custom Font"}}
        }

        result = token_manager.get_typography_token("font_families", use_custom=True)

        assert result is not None
        assert "custom" in result

    @pytest.mark.asyncio
    async def test_get_color_token_from_default(self, token_manager):
        """Test getting color token from defaults."""
        result = token_manager.get_color_token("tech", "primary")

        assert result is not None
        assert isinstance(result, list)
        assert len(result) == 3

    @pytest.mark.asyncio
    async def test_get_motion_token_from_default(self, token_manager):
        """Test getting motion token from defaults."""
        result = token_manager.get_motion_token("spring_configs", "smooth")

        assert result is not None
        assert "config" in result

    @pytest.mark.asyncio
    async def test_get_typography_token_invalid_category(self, token_manager):
        """Test getting typography token with invalid category."""
        result = token_manager.get_typography_token("nonexistent_category")

        assert result is None

    @pytest.mark.asyncio
    async def test_get_typography_token_custom_with_key(self, token_manager):
        """Test getting typography token from custom with specific key."""
        token_manager.custom_typography_tokens = {
            "font_families": {"custom_font": {"name": "CustomFont"}}
        }

        result = token_manager.get_typography_token("font_families", "custom_font", use_custom=True)

        assert result is not None
        assert result["name"] == "CustomFont"

    @pytest.mark.asyncio
    async def test_get_typography_token_no_model_dump(self, token_manager):
        """Test getting typography token when value is plain dict."""
        result = token_manager.get_typography_token("font_families")

        assert result is not None
        assert isinstance(result, dict)

    @pytest.mark.asyncio
    async def test_get_color_token_invalid_theme(self, token_manager):
        """Test getting color token with invalid theme."""
        result = token_manager.get_color_token("nonexistent_theme")

        assert result is None

    @pytest.mark.asyncio
    async def test_get_color_token_custom_with_type(self, token_manager):
        """Test getting color token from custom with specific color type."""
        token_manager.custom_color_tokens = {"tech": {"custom_primary": ["#FF0000"]}}

        result = token_manager.get_color_token("tech", "custom_primary", use_custom=True)

        assert result is not None
        assert result == ["#FF0000"]

    @pytest.mark.asyncio
    async def test_get_color_token_custom_whole_theme(self, token_manager):
        """Test getting entire custom color theme."""
        token_manager.custom_color_tokens = {"custom_theme": {"primary": ["#FF0000"]}}

        result = token_manager.get_color_token("custom_theme", use_custom=True)

        assert result is not None
        assert "primary" in result

    @pytest.mark.asyncio
    async def test_get_motion_token_invalid_category(self, token_manager):
        """Test getting motion token with invalid category."""
        result = token_manager.get_motion_token("nonexistent_category")

        assert result is None

    @pytest.mark.asyncio
    async def test_get_motion_token_custom_with_key(self, token_manager):
        """Test getting motion token from custom with specific key."""
        token_manager.custom_motion_tokens = {
            "spring_configs": {"custom_spring": {"stiffness": 100}}
        }

        result = token_manager.get_motion_token("spring_configs", "custom_spring", use_custom=True)

        assert result is not None
        assert result["stiffness"] == 100

    @pytest.mark.asyncio
    async def test_get_motion_token_custom_whole_category(self, token_manager):
        """Test getting entire custom motion category."""
        token_manager.custom_motion_tokens = {"easing": {"custom_ease": "ease-in"}}

        result = token_manager.get_motion_token("easing", use_custom=True)

        assert result is not None
        assert "custom_ease" in result

    @pytest.mark.asyncio
    async def test_get_spacing_token_invalid_type(self, token_manager):
        """Test getting spacing token with invalid type."""
        result = token_manager.get_spacing_token("nonexistent_type")

        assert result is None

    @pytest.mark.asyncio
    async def test_get_spacing_token_custom_with_key(self, token_manager):
        """Test getting spacing token from custom with specific key."""
        token_manager.custom_spacing_tokens = {"spacing": {"custom_xxl": 128}}

        result = token_manager.get_spacing_token("spacing", "custom_xxl", use_custom=True)

        assert result is not None
        assert result == 128

    @pytest.mark.asyncio
    async def test_get_typography_token_dict_value_with_key(self, token_manager):
        """Test getting typography token when value is dict with key."""
        # Set up custom typography tokens where value is a dict
        token_manager.custom_typography_tokens = {
            "font_families": {"custom_family": {"name": "CustomFont", "fallback": "sans-serif"}}
        }

        result = token_manager.get_typography_token(
            "font_families", "custom_family", use_custom=True
        )

        assert result is not None
        assert isinstance(result, dict)

    @pytest.mark.asyncio
    async def test_get_typography_token_dict_value_no_key(self, token_manager):
        """Test getting typography token when value is dict without key."""
        # Set up custom typography tokens where value is a dict
        token_manager.custom_typography_tokens = {
            "font_families": {"name": "CustomFont", "fallback": "sans-serif"}
        }

        result = token_manager.get_typography_token("font_families", use_custom=True)

        assert result is not None
        assert isinstance(result, dict)
        assert result.get("name") == "CustomFont"

    @pytest.mark.asyncio
    async def test_get_color_token_whole_theme(self, token_manager):
        """Test getting entire color theme without specifying color_type."""
        result = token_manager.get_color_token("tech", use_custom=False)

        assert result is not None
        assert isinstance(result, dict)
        assert "text" in result or "background" in result or "primary" in result

    @pytest.mark.asyncio
    async def test_get_motion_token_value_without_key(self, token_manager):
        """Test getting motion token value without specifying key."""
        # This tests the path where we return the value directly without extracting a key
        result = token_manager.get_motion_token("spring_configs")

        assert result is not None


class TestUtilityMethods:
    """Test utility methods."""

    @pytest.mark.asyncio
    async def test_list_custom_tokens(self, token_manager):
        """Test listing custom tokens."""
        token_manager.custom_typography_tokens = {"key1": "value1"}
        token_manager.custom_color_tokens = {"key2": "value2"}
        token_manager.custom_motion_tokens = {"key3": "value3"}

        result = token_manager.list_custom_tokens()

        assert "typography" in result
        assert "colors" in result
        assert "motion" in result
        assert "key1" in result["typography"]
        assert "key2" in result["colors"]
        assert "key3" in result["motion"]

    @pytest.mark.asyncio
    async def test_clear_typography_tokens(self, token_manager):
        """Test clearing typography tokens."""
        token_manager.custom_typography_tokens = {"key": "value"}

        token_manager.clear_custom_tokens("typography")

        assert token_manager.custom_typography_tokens == {}

    @pytest.mark.asyncio
    async def test_clear_all_tokens(self, token_manager):
        """Test clearing all custom tokens."""
        token_manager.custom_typography_tokens = {"key1": "value1"}
        token_manager.custom_color_tokens = {"key2": "value2"}
        token_manager.custom_motion_tokens = {"key3": "value3"}

        token_manager.clear_custom_tokens()

        assert token_manager.custom_typography_tokens == {}
        assert token_manager.custom_color_tokens == {}
        assert token_manager.custom_motion_tokens == {}


class TestSpacingTokenExportImport:
    """Test spacing token export and import."""

    @pytest.mark.asyncio
    async def test_export_all_spacing_tokens(self, token_manager):
        """Test exporting all spacing tokens."""
        result = await token_manager.export_spacing_tokens(file_path="test_spacing.json")

        assert result == "test_spacing.json"

        content = await token_manager.vfs.read_text("test_spacing.json")
        data = json.loads(content)

        assert "spacing" in data
        assert "safe_area" in data

    @pytest.mark.asyncio
    async def test_export_spacing_only(self, token_manager):
        """Test exporting only spacing scale."""
        result = await token_manager.export_spacing_tokens(
            file_path="spacing_only.json", spacing_only=True
        )

        assert result == "spacing_only.json"

        content = await token_manager.vfs.read_text("spacing_only.json")
        data = json.loads(content)

        assert "spacing" in data
        assert "safe_area" not in data

    @pytest.mark.asyncio
    async def test_export_safe_margins_only(self, token_manager):
        """Test exporting only safe margins."""
        result = await token_manager.export_spacing_tokens(
            file_path="safe_margins_only.json", safe_margins_only=True
        )

        assert result == "safe_margins_only.json"

        content = await token_manager.vfs.read_text("safe_margins_only.json")
        data = json.loads(content)

        assert "safe_area" in data
        assert "spacing" not in data

    @pytest.mark.asyncio
    async def test_export_spacing_with_custom_tokens(self, token_manager):
        """Test exporting includes custom spacing tokens."""
        token_manager.custom_spacing_tokens = {"custom_spacing": "custom_value"}

        await token_manager.export_spacing_tokens(file_path="with_custom_spacing.json")

        content = await token_manager.vfs.read_text("with_custom_spacing.json")
        data = json.loads(content)

        assert "custom" in data
        assert data["custom"]["custom_spacing"] == "custom_value"

    @pytest.mark.asyncio
    async def test_import_spacing_tokens(self, token_manager):
        """Test importing spacing tokens."""
        sample_spacing_tokens = {
            "spacing": {"custom_xs": 4, "custom_sm": 8},
            "safe_area": {"custom_margin": 20},
        }

        await token_manager.vfs.write_file("import_spacing.json", json.dumps(sample_spacing_tokens))

        result = await token_manager.import_spacing_tokens(file_path="import_spacing.json")

        assert "Successfully imported" in result
        assert token_manager.custom_spacing_tokens == sample_spacing_tokens

    @pytest.mark.asyncio
    async def test_import_spacing_tokens_merge(self, token_manager):
        """Test importing spacing tokens with merge."""
        token_manager.custom_spacing_tokens = {"existing_key": "existing_value"}

        sample_spacing_tokens = {"spacing": {"custom_xs": 4}}

        await token_manager.vfs.write_file("import_spacing.json", json.dumps(sample_spacing_tokens))

        result = await token_manager.import_spacing_tokens(
            file_path="import_spacing.json", merge=True
        )

        assert "Successfully imported" in result
        assert "existing_key" in token_manager.custom_spacing_tokens
        assert "spacing" in token_manager.custom_spacing_tokens

    @pytest.mark.asyncio
    async def test_import_spacing_tokens_replace(self, token_manager):
        """Test importing spacing tokens without merge."""
        token_manager.custom_spacing_tokens = {"existing_key": "existing_value"}

        sample_spacing_tokens = {"spacing": {"custom_xs": 4}}

        await token_manager.vfs.write_file("import_spacing.json", json.dumps(sample_spacing_tokens))

        result = await token_manager.import_spacing_tokens(
            file_path="import_spacing.json", merge=False
        )

        assert "Successfully imported" in result
        assert "existing_key" not in token_manager.custom_spacing_tokens
        assert token_manager.custom_spacing_tokens == sample_spacing_tokens

    @pytest.mark.asyncio
    async def test_import_invalid_spacing_tokens(self, token_manager):
        """Test importing invalid spacing tokens."""
        await token_manager.vfs.write_file("invalid_spacing.json", json.dumps("not a dict"))

        result = await token_manager.import_spacing_tokens(file_path="invalid_spacing.json")

        assert "Error" in result

    @pytest.mark.asyncio
    async def test_get_spacing_token_from_default(self, token_manager):
        """Test getting spacing token from defaults."""
        result = token_manager.get_spacing_token("spacing", "xs")

        assert result is not None
        # Spacing tokens can be strings like "8px" or numbers
        assert isinstance(result, (int, float, str))

    @pytest.mark.asyncio
    async def test_get_spacing_token_from_custom(self, token_manager):
        """Test getting spacing token from custom tokens."""
        token_manager.custom_spacing_tokens = {"spacing": {"custom_xl": 64}}

        result = token_manager.get_spacing_token("spacing", use_custom=True)

        assert result is not None
        assert "custom_xl" in result

    @pytest.mark.asyncio
    async def test_get_spacing_token_category_only(self, token_manager):
        """Test getting entire spacing category."""
        result = token_manager.get_spacing_token("spacing")

        assert result is not None
        assert isinstance(result, dict)
        assert "xs" in result or "sm" in result

    @pytest.mark.asyncio
    async def test_clear_spacing_tokens(self, token_manager):
        """Test clearing spacing tokens."""
        token_manager.custom_spacing_tokens = {"key": "value"}

        token_manager.clear_custom_tokens("spacing")

        assert token_manager.custom_spacing_tokens == {}

    @pytest.mark.asyncio
    async def test_export_all_tokens_includes_spacing(self, token_manager):
        """Test that export_all_tokens includes spacing tokens."""
        result = await token_manager.export_all_tokens(output_dir="all_tokens_with_spacing")

        assert "spacing" in result
        assert "all_tokens_with_spacing/spacing_tokens.json" in result["spacing"]

        # Verify the spacing file was created
        spacing_content = await token_manager.vfs.read_text(result["spacing"])
        spacing_data = json.loads(spacing_content)
        assert "spacing" in spacing_data or "safe_area" in spacing_data

    @pytest.mark.asyncio
    async def test_export_spacing_default_filepath(self, token_manager):
        """Test exporting spacing tokens with default file path."""
        result = await token_manager.export_spacing_tokens()

        assert result == "spacing_tokens.json"
        assert await token_manager.vfs.exists("spacing_tokens.json")

    @pytest.mark.asyncio
    async def test_export_spacing_exception(self, token_manager):
        """Test export spacing tokens handles exceptions."""

        # Mock vfs to raise exception
        async def raise_exception(path, content):
            raise OSError("Write failed")

        token_manager.vfs.write_file = raise_exception

        result = await token_manager.export_spacing_tokens()

        assert "Error exporting spacing tokens" in result

    @pytest.mark.asyncio
    async def test_import_spacing_exception(self, token_manager):
        """Test import spacing tokens handles exceptions."""
        # Try to import nonexistent file
        result = await token_manager.import_spacing_tokens(file_path="nonexistent.json")

        assert "Error" in result  # Either "Error importing" or "Error: File is empty"
