Ctrl K
ComunidadGuías…

test/events/test_field.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Copyright (c) 2026, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
#
# SPDX-License-Identifier: Apache-2.0

import pytest

from ag2.events import BaseEvent, Field


class TestFieldBasics:
    def test_event_with_field(self):
        class Event(BaseEvent):
            a: str = Field()
            b: int

        assert Event.a.name == "a"
        assert Event.b.name == "b"

        obj = Event(a="1", b=1)
        assert obj.a == "1"
        assert obj.b == 1

    def test_event_with_value_field(self):
        class Event(BaseEvent):
            a: str = "1"

        obj = Event()
        assert obj.a == "1"

    def test_event_with_falsy_value_field(self):
        # A plain (non-Field) default that is falsy must still be applied;
        # 0 / False / "" / () are real defaults, not "no default".
        class Event(BaseEvent):
            count: int = 0
            flag: bool = False
            label: str = ""
            items: tuple = ()

        obj = Event()
        assert obj.count == 0
        assert obj.flag is False
        assert obj.label == ""
        assert obj.items == ()

    def test_falsy_value_field_is_serialized(self):
        class Event(BaseEvent):
            count: int = 0

        assert Event().to_dict()["count"] == 0

    def test_event_with_default_field(self):
        class Event(BaseEvent):
            a: str = Field("1")

        obj = Event()
        assert obj.a == "1"

    def test_event_with_default_factory(self):
        class Event(BaseEvent):
            a: str = Field(default_factory=lambda: "1")

        obj = Event()
        assert obj.a == "1"


class TestFieldInit:
    def test_init_true_accepts_value(self):
        class Event(BaseEvent):
            a: str = Field(init=True)

        obj = Event(a="hello")
        assert obj.a == "hello"

    def test_init_false_applies_default(self):
        class Event(BaseEvent):
            a: str
            _internal: int = Field(default=0, init=False)

        obj = Event(a="hello")
        assert obj.a == "hello"
        assert obj._internal == 0

    def test_init_false_with_default_factory(self):
        class Event(BaseEvent):
            items: list = Field(default_factory=list, init=False)

        obj = Event()
        assert obj.items == []

    def test_init_false_separate_instances(self):
        class Event(BaseEvent):
            items: list = Field(default_factory=list, init=False)

        a = Event()
        b = Event()
        a.items.append(1)
        assert b.items == []


class TestFieldRepr:
    def test_repr_true_shows_field(self):
        class Event(BaseEvent):
            a: str

        obj = Event(a="hello")
        assert "a='hello'" in repr(obj)

    def test_repr_false_hides_field(self):
        class Event(BaseEvent):
            a: str
            secret: str = Field(default="hidden", repr=False)

        obj = Event(a="visible")
        assert "a='visible'" in repr(obj)
        assert "secret" not in repr(obj)

    def test_repr_false_field_still_accessible(self):
        class Event(BaseEvent):
            secret: str = Field(default="hidden", repr=False)

        obj = Event()
        assert obj.secret == "hidden"

    def test_repr_mixed_fields(self):
        class Event(BaseEvent):
            public: str
            internal: str = Field(default="x", repr=False)
            also_public: int = 42

        obj = Event(public="hello")
        r = repr(obj)
        assert "public='hello'" in r
        assert "also_public=42" in r
        assert "internal" not in r


class TestFieldCompare:
    def test_compare_true_includes_field(self):
        class Event(BaseEvent):
            a: str
            b: int

        assert Event(a="x", b=1) == Event(a="x", b=1)
        assert Event(a="x", b=1) != Event(a="x", b=2)

    def test_compare_false_excludes_field(self):
        class Event(BaseEvent):
            a: str
            timestamp: int = Field(default=0, compare=False)

        assert Event(a="x", timestamp=1) == Event(a="x", timestamp=2)
        assert Event(a="x", timestamp=1) != Event(a="y", timestamp=1)

    def test_compare_false_all_fields(self):
        class Event(BaseEvent):
            a: str = Field(compare=False)
            b: int = Field(compare=False)

        assert Event(a="x", b=1) == Event(a="y", b=2)

    def test_compare_different_types(self):
        class EventA(BaseEvent):
            a: str

        class EventB(BaseEvent):
            a: str

        assert EventA(a="x") != EventB(a="x")

    def test_compare_with_custom_eq_override(self):
        class Event(BaseEvent):
            a: str
            b: int

            def __eq__(self, other: object) -> bool:
                if not isinstance(other, Event):
                    return NotImplemented
                return self.a == other.a

        assert Event(a="x", b=1) == Event(a="x", b=99)
        assert Event(a="x", b=1) != Event(a="y", b=1)

    def test_compare_inherited_fields(self):
        class Parent(BaseEvent):
            a: str

        class Child(Parent):
            b: int = Field(compare=False)

        assert Child(a="x", b=1) == Child(a="x", b=2)
        assert Child(a="x", b=1) != Child(a="y", b=1)


class TestFieldPositionalArgs:
    def test_positional_arg(self):
        class Event(BaseEvent):
            a: str = Field(kw_only=False)

        obj = Event("hello")
        assert obj.a == "hello"

    def test_positional_and_kwarg(self):
        class Event(BaseEvent):
            a: str = Field(kw_only=False)
            b: int

        obj = Event("hello", b=1)
        assert obj.a == "hello"
        assert obj.b == 1

    def test_multiple_positional(self):
        class Event(BaseEvent):
            a: str = Field(kw_only=False)
            b: int = Field(kw_only=False)

        obj = Event("hello", 42)
        assert obj.a == "hello"
        assert obj.b == 42

    def test_positional_still_accepts_kwarg(self):
        class Event(BaseEvent):
            a: str = Field(kw_only=False)

        obj = Event(a="hello")
        assert obj.a == "hello"

    def test_too_many_positional_raises(self):
        class Event(BaseEvent):
            a: str = Field(kw_only=False)

        with pytest.raises(TypeError, match="1 positional argument"):
            Event("hello", "extra")

    def test_duplicate_positional_and_kwarg_raises(self):
        class Event(BaseEvent):
            a: str = Field(kw_only=False)

        with pytest.raises(TypeError, match="multiple values"):
            Event("hello", a="world")

    def test_inherited_positional(self):
        class Parent(BaseEvent):
            a: str = Field(kw_only=False)

        class Child(Parent):
            b: int

        obj = Child("hello", b=1)
        assert obj.a == "hello"
        assert obj.b == 1