diff --git a/tests/test_dagset.py b/tests/test_dagset.py index add5a0e..cf53177 100644 --- a/tests/test_dagset.py +++ b/tests/test_dagset.py @@ -2,84 +2,88 @@ from __future__ import annotations import pytest -from daglib.set import DAGSet +from daglib.set import DAGSetView class TestDAGSetInit: """Test DAGSet initialization.""" - def test_init_empty(self) -> None: - s = DAGSet() + def test_empty(self) -> None: + s = DAGSetView() assert len(s) == 0 + assert set(s) == set() assert list(s) == [] + assert tuple(s) == tuple() - def test_init_from_set(self) -> None: - s = DAGSet({1, 2, 3}) + def test_from_set(self) -> None: + s = DAGSetView({1, 2, 3}) assert len(s) == 3 assert set(s) == {1, 2, 3} - def test_init_from_list(self) -> None: - s = DAGSet([1, 2, 3, 2]) + def test_from_list(self) -> None: + s = DAGSetView([1, 2, 3, 2]) assert len(s) == 3 assert set(s) == {1, 2, 3} - def test_init_from_tuple(self) -> None: - s = DAGSet((4, 5, 6)) + def test_from_tuple(self) -> None: + s = DAGSetView((4, 5, 6)) assert len(s) == 3 - assert 4 in s and 5 in s and 6 in s + assert set(s) == {4, 5, 6} - def test_init_none(self) -> None: - s = DAGSet(None) + def test_from_none(self) -> None: + s = DAGSetView(None) assert len(s) == 0 - def test_init_invalid_type(self) -> None: + def test_from_invalid_type(self) -> None: with pytest.raises(TypeError): - DAGSet(42) # type: ignore + DAGSetView(42) # type: ignore class TestDAGSetBasicOps: """Test basic set operations.""" + def test_len(self) -> None: + s = DAGSetView({1, 2, 3}) + assert len(s) == 3 + def test_contains(self) -> None: - s = DAGSet({1, 2, 3}) + s = DAGSetView({1, 2, 3}) assert 1 in s + assert 2 in s + assert 3 in s assert 4 not in s def test_add(self) -> None: - s = DAGSet() + s = DAGSetView() s.add(1) assert 1 in s assert len(s) == 1 def test_discard(self) -> None: - s = DAGSet({1, 2, 3}) + s = DAGSetView({1, 2, 3}) s.discard(2) assert 2 not in s assert len(s) == 2 def test_discard_missing(self) -> None: - s = DAGSet({1, 2, 3}) - s.discard(99) # should not raise + s = DAGSetView({1, 2, 3}) + s.discard(99) assert len(s) == 3 def test_remove(self) -> None: - s = DAGSet({1, 2, 3}) + s = DAGSetView({1, 2, 3}) s.remove(2) assert 2 not in s def test_remove_missing(self) -> None: - s = DAGSet({1, 2, 3}) + s = DAGSetView({1, 2, 3}) with pytest.raises(KeyError): s.remove(99) def test_iter(self) -> None: - s = DAGSet({1, 2, 3}) - items = set(s) - assert items == {1, 2, 3} - - def test_len(self) -> None: - s = DAGSet({1, 2, 3}) - assert len(s) == 3 + s = DAGSetView({1, 2, 3}) + for i, v in enumerate(s): + assert v == i + 1 class TestDAGSetCallbacks: @@ -87,7 +91,7 @@ class TestDAGSetCallbacks: def test_on_add_callback(self) -> None: added: list[int] = [] - s = DAGSet({1, 2}) + s = DAGSetView({1, 2}) s.on_add = lambda v: added.append(v) s.add(3) assert 3 in added @@ -95,14 +99,14 @@ class TestDAGSetCallbacks: def test_on_remove_callback(self) -> None: removed: list[int] = [] - s = DAGSet({1, 2, 3}) + s = DAGSetView({1, 2, 3}) s.on_remove = lambda v: removed.append(v) s.discard(2) assert 2 in removed assert len(removed) == 1 def test_callbacks_none_by_default(self) -> None: - s = DAGSet() + s = DAGSetView() assert s.on_add is None assert s.on_remove is None @@ -110,68 +114,75 @@ class TestDAGSetCallbacks: class TestDAGSetInPlaceOperators: """Test in-place set operators.""" - def test_ior_with_set(self) -> None: - s = DAGSet({1, 2}) - s |= {3, 4} - assert set(s) == {1, 2, 3, 4} + class TestDAGSetIOR: + def test_set(self) -> None: + s = DAGSetView({1, 2}) + s |= {3, 4} + assert set(s) == {1, 2, 3, 4} - def test_ior_with_list(self) -> None: - s = DAGSet({1}) - s |= [2, 3] - assert set(s) == {1, 2, 3} + def test_list(self) -> None: + s = DAGSetView({1}) + s |= [2, 3] + assert set(s) == {1, 2, 3} - def test_ior_with_string(self) -> None: - s = DAGSet({"a", "b"}) - s |= "c" - assert "c" in s + def test_string(self) -> None: + s = DAGSetView({"abc", "def"}) + s |= "xyz" + assert "xyz" in s + + class TestDAGSetIAdd: + pass + + class TestDAGSetISub: + pass def test_iadd_with_set(self) -> None: - s = DAGSet({1, 2}) + s = DAGSetView({1, 2}) s += {3, 4} assert set(s) == {1, 2, 3, 4} def test_iadd_with_list(self) -> None: - s = DAGSet({1}) + s = DAGSetView({1}) s += [2, 3] assert set(s) == {1, 2, 3} def test_iadd_with_string(self) -> None: - s = DAGSet({"a"}) + s = DAGSetView({"a"}) s += "b" assert "b" in s def test_isub_with_set(self) -> None: - s = DAGSet({1, 2, 3, 4}) + s = DAGSetView({1, 2, 3, 4}) s -= {2, 3} assert set(s) == {1, 4} def test_isub_with_list(self) -> None: - s = DAGSet({1, 2, 3}) + s = DAGSetView({1, 2, 3}) s -= [2] assert set(s) == {1, 3} def test_isub_with_string(self) -> None: - s = DAGSet({"a", "b", "c"}) + s = DAGSetView({"a", "b", "c"}) s -= "b" assert set(s) == {"a", "c"} def test_iand_with_set(self) -> None: - s = DAGSet({1, 2, 3}) + s = DAGSetView({1, 2, 3}) s &= {2, 3, 4} assert set(s) == {2, 3} def test_iand_with_list(self) -> None: - s = DAGSet({1, 2, 3}) + s = DAGSetView({1, 2, 3}) s &= [2, 3] assert set(s) == {2, 3} def test_ixor_with_set(self) -> None: - s = DAGSet({1, 2, 3}) + s = DAGSetView({1, 2, 3}) s ^= {3, 4, 5} assert set(s) == {1, 2, 4, 5} def test_ixor_with_list(self) -> None: - s = DAGSet({1, 2}) + s = DAGSetView({1, 2}) s ^= [2, 3] assert set(s) == {1, 3} @@ -181,7 +192,7 @@ class TestDAGSetCallbacksWithOperators: def test_ior_triggers_callbacks(self) -> None: added: list[int] = [] - s = DAGSet({1}) + s = DAGSetView({1}) s.on_add = lambda v: added.append(v) s |= {2, 3} assert 2 in added @@ -189,7 +200,7 @@ class TestDAGSetCallbacksWithOperators: def test_iadd_triggers_callbacks(self) -> None: added: list[int] = [] - s = DAGSet({1}) + s = DAGSetView({1}) s.on_add = lambda v: added.append(v) s += [2, 3] assert 2 in added @@ -197,26 +208,8 @@ class TestDAGSetCallbacksWithOperators: def test_isub_triggers_callbacks(self) -> None: removed: list[int] = [] - s = DAGSet({1, 2, 3}) + s = DAGSetView({1, 2, 3}) s.on_remove = lambda v: removed.append(v) s -= {2, 3} assert 2 in removed assert 3 in removed - - -class TestDAGSetRepr: - """Test string representation.""" - - def test_repr_empty(self) -> None: - s = DAGSet() - assert repr(s) == "{}" - - def test_repr_with_items(self) -> None: - s = DAGSet({1, 2, 3}) - r = repr(s) - assert r.startswith("{") - assert r.endswith("}") - # items may be in any order - assert "1" in r - assert "2" in r - assert "3" in r