
import asyncio
from slyme.context.core import Context, Ref
from slyme.utils.pytree import MappingKey

def test_mutate_validation():
    ctx = Context({"a": 1})
    
    # Valid mutation
    ctx.mutate(updates={Ref("a"): 2})
    print("Valid mutation passed")

    # Invalid mutation (single)
    try:
        r = Ref("a", key_path=(MappingKey("k"),))
        ctx.mutate(updates={r: 2})
    except ValueError as e:
        print(f"Caught expected error: {e}")
        assert "Ref.key_path must be empty" in str(e)
        assert repr([r]) in str(e) or repr(r) in str(e)

    # Invalid mutation (multiple)
    try:
        r1 = Ref("a", key_path=(MappingKey("k1"),))
        r2 = Ref("b", key_path=(MappingKey("k2"),))
        ctx.mutate(updates={r1: 1}, drops=[r2])
    except ValueError as e:
        print(f"Caught expected error multiple: {e}")
        assert "Ref.key_path must be empty" in str(e)
        assert repr(r1) in str(e)
        assert repr(r2) in str(e)

async def test_mutate_async_validation():
    ctx = Context({"a": 1})
    
    # Valid mutation
    await ctx.async_mutate(updates={Ref("a"): 2})
    print("Valid async mutation passed")

    # Invalid mutation
    try:
        r = Ref("a", key_path=(MappingKey("k"),))
        await ctx.async_mutate(updates={r: 2})
    except ValueError as e:
        print(f"Caught expected async error: {e}")
        assert "Ref.key_path must be empty" in str(e)

if __name__ == "__main__":
    test_mutate_validation()
    asyncio.run(test_mutate_async_validation())
