File: test_path_step.py

package info (click to toggle)
psygnal 0.15.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 752 kB
  • sloc: python: 9,252; makefile: 8
file content (127 lines) | stat: -rw-r--r-- 3,824 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""Tests to cover missing lines in path/emission functionality."""

from inspect import Signature

import pytest

from psygnal import EmissionInfo, PathStep, Signal, SignalGroup, SignalInstance


def test_pathstep_validation():
    """Test PathStep validation error conditions."""
    # Test empty PathStep (should fail)
    with pytest.raises(ValueError, match="exactly one of attr, index, or key"):
        PathStep()

    # Test multiple fields set (should fail)
    with pytest.raises(ValueError, match="exactly one of attr, index, or key"):
        PathStep(attr="test", index=1)


def test_pathstep_repr():
    """Test PathStep repr formatting, including long key truncation."""
    # Test attr
    assert repr(PathStep(attr="test")) == ".test"

    # Test index
    assert repr(PathStep(index=5)) == "[5]"

    # Test short key
    assert repr(PathStep(key="short")) == "['short']"

    # Test long key truncation
    class CrazyHashable:
        """A class with a long __repr__."""

        def __repr__(self):
            return "a" * 100

    ps = PathStep(key=CrazyHashable())
    result = repr(ps)
    assert "..." in result
    assert len(result) <= 25  # should be truncated


def test_emission_info_path_validation():
    """Test EmissionInfo path validation."""
    # Create a SignalInstance properly
    instance = SignalInstance(Signature())

    # Valid paths should work
    EmissionInfo(instance, (1,), (PathStep(attr="test"),))
    EmissionInfo(instance, (1,), (PathStep(index=0), PathStep(key="key")))

    # Invalid path types should fail
    with pytest.raises(TypeError):
        EmissionInfo(instance, (1,), (object(),))  # type: ignore


def test_signal_relay_no_emitter():
    """Test SignalRelay when no current emitter."""

    class TestGroup(SignalGroup):
        test_signal = Signal(int)

    group = TestGroup()

    # Test that _slot_relay returns early when no current emitter
    # This should not raise an error and should not emit anything
    relay = group.all
    relay._slot_relay(1, 2, 3)  # Should return early due to no emitter


def test_signal_group_repr_without_instance():
    """Test SignalGroup repr when instance is None."""

    class TestGroup(SignalGroup):
        test_signal = Signal(int)

    # Create group without instance
    group = TestGroup()
    repr_str = repr(group)
    assert "TestGroup" in repr_str
    assert "instance at" not in repr_str  # Should not have instance info


def test_signal_group_repr_with_instance():
    """Test SignalGroup repr when instance is not None."""

    class TestGroup(SignalGroup):
        test_signal = Signal(int)

    class TestObj:
        def __init__(self):
            self.events = TestGroup(instance=self)

    # Create group with instance
    obj = TestObj()
    repr_str = repr(obj.events)
    assert "TestGroup" in repr_str
    assert "instance at" in repr_str  # Should have instance info
    assert "TestObj" in repr_str


def test_list_signal_instance_relocate_empty_args():
    """Test ListSignalInstance _psygnal_relocate_info_ with empty args."""
    from psygnal.containers._evented_list import ListSignalInstance

    # Create a signal instance
    list_sig = ListSignalInstance((int,))

    # Test with empty args
    info = EmissionInfo(list_sig, ())
    result = list_sig._psygnal_relocate_info_(info)
    assert result is info  # Should return unchanged


def test_dict_signal_instance_relocate_empty_args():
    """Test DictSignalInstance _psygnal_relocate_info_ with empty args."""
    from psygnal.containers._evented_dict import DictSignalInstance

    # Create a signal instance
    dict_sig = DictSignalInstance((str,))

    # Test with empty args
    info = EmissionInfo(dict_sig, ())
    result = dict_sig._psygnal_relocate_info_(info)
    assert result is info  # Should return unchanged