# Copyright Kevin Deldycke <kevin@deldycke.com> and contributors.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
from __future__ import annotations
import pytest
from extra_platforms import (
AIX,
ALL_CI,
ALL_PLATFORMS,
ANY_WINDOWS,
BSD,
BSD_WITHOUT_MACOS,
LINUX,
LINUX_LAYERS,
PIDORA,
RHEL,
UNIX,
UNIX_LAYERS,
UNIX_WITHOUT_MACOS,
Group,
)
[docs]
def test_simple_union():
new_group = ANY_WINDOWS.union(LINUX_LAYERS)
assert ANY_WINDOWS.issubset(new_group)
assert LINUX_LAYERS.issubset(new_group)
assert new_group.issuperset(ANY_WINDOWS)
assert new_group.issuperset(LINUX_LAYERS)
assert new_group.id == ANY_WINDOWS.id
assert new_group.id != LINUX_LAYERS.id
assert new_group.name == ANY_WINDOWS.name
assert new_group.name != LINUX_LAYERS.name
assert new_group.icon == ANY_WINDOWS.icon
assert new_group.icon != LINUX_LAYERS.icon
assert set(new_group.members) != set(ANY_WINDOWS.members)
assert set(new_group.member_ids) != set(ANY_WINDOWS.member_ids)
assert set(new_group.members) != set(LINUX_LAYERS.members)
assert set(new_group.member_ids) != set(LINUX_LAYERS.member_ids)
assert set(new_group.members) == set(ANY_WINDOWS.members).union(
LINUX_LAYERS.members
)
assert set(new_group.member_ids) == set(ANY_WINDOWS.member_ids).union(
LINUX_LAYERS.member_ids
)
[docs]
def test_multiple_union():
new_group = ANY_WINDOWS.union(LINUX_LAYERS, UNIX_LAYERS)
assert new_group.member_ids == frozenset(("windows", "wsl1", "wsl2", "cygwin"))
assert ANY_WINDOWS.issubset(new_group)
assert LINUX_LAYERS.issubset(new_group)
assert UNIX_LAYERS.issubset(new_group)
assert new_group.issuperset(ANY_WINDOWS)
assert new_group.issuperset(LINUX_LAYERS)
assert new_group.issuperset(UNIX_LAYERS)
assert new_group.id == ANY_WINDOWS.id
assert new_group.id != LINUX_LAYERS.id
assert new_group.id != UNIX_LAYERS.id
assert new_group.name == ANY_WINDOWS.name
assert new_group.name != LINUX_LAYERS.name
assert new_group.name != UNIX_LAYERS.name
assert new_group.icon == ANY_WINDOWS.icon
assert new_group.icon != LINUX_LAYERS.icon
assert new_group.icon != UNIX_LAYERS.icon
assert set(new_group.members) != set(ANY_WINDOWS.members)
assert set(new_group.member_ids) != set(ANY_WINDOWS.member_ids)
assert set(new_group.members) != set(LINUX_LAYERS.members)
assert set(new_group.member_ids) != set(LINUX_LAYERS.member_ids)
assert set(new_group.members) != set(UNIX_LAYERS.members)
assert set(new_group.member_ids) != set(UNIX_LAYERS.member_ids)
assert set(new_group.members) == set(ANY_WINDOWS.members).union(
LINUX_LAYERS.members
).union(UNIX_LAYERS.members)
assert set(new_group.member_ids) == set(ANY_WINDOWS.member_ids).union(
LINUX_LAYERS.member_ids
).union(UNIX_LAYERS.member_ids)
[docs]
def test_single_intersection():
new_group = ALL_PLATFORMS.intersection(ANY_WINDOWS)
assert new_group.member_ids == frozenset(("windows",))
assert ANY_WINDOWS.issubset(new_group)
assert not ALL_PLATFORMS.issubset(new_group)
assert new_group.issuperset(ANY_WINDOWS)
assert not new_group.issuperset(ALL_PLATFORMS)
assert new_group.id == ALL_PLATFORMS.id
assert new_group.id != ANY_WINDOWS.id
assert new_group.name == ALL_PLATFORMS.name
assert new_group.name != ANY_WINDOWS.name
assert new_group.icon == ALL_PLATFORMS.icon
assert new_group.icon != ANY_WINDOWS.icon
assert set(new_group.members) != set(ALL_PLATFORMS.members)
assert set(new_group.member_ids) != set(ALL_PLATFORMS.member_ids)
assert set(new_group.members) == set(ANY_WINDOWS.members)
assert set(new_group.member_ids) == set(ANY_WINDOWS.member_ids)
[docs]
def test_multiple_intersection():
new_group = ALL_PLATFORMS.intersection(UNIX_WITHOUT_MACOS, BSD_WITHOUT_MACOS)
assert new_group.member_ids == frozenset((
"freebsd",
"midnightbsd",
"netbsd",
"openbsd",
"sunos",
))
assert new_group.issubset(ALL_PLATFORMS)
assert new_group.issubset(UNIX_WITHOUT_MACOS)
assert new_group.issubset(BSD_WITHOUT_MACOS)
assert ALL_PLATFORMS.issuperset(new_group)
assert UNIX_WITHOUT_MACOS.issuperset(new_group)
assert BSD_WITHOUT_MACOS.issuperset(new_group)
assert new_group.id == ALL_PLATFORMS.id
assert new_group.id != UNIX_WITHOUT_MACOS.id
assert new_group.id != BSD_WITHOUT_MACOS.id
assert new_group.name == ALL_PLATFORMS.name
assert new_group.name != UNIX_WITHOUT_MACOS.name
assert new_group.name != BSD_WITHOUT_MACOS.name
assert new_group.icon == ALL_PLATFORMS.icon
assert new_group.icon != UNIX_WITHOUT_MACOS.icon
assert new_group.icon != BSD_WITHOUT_MACOS.icon
assert set(new_group.members) != set(ALL_PLATFORMS.members)
assert set(new_group.member_ids) != set(ALL_PLATFORMS.member_ids)
assert set(new_group.members) != set(UNIX_WITHOUT_MACOS.members)
assert set(new_group.member_ids) != set(UNIX_WITHOUT_MACOS.member_ids)
assert set(new_group.members) == set(BSD_WITHOUT_MACOS.members)
assert set(new_group.member_ids) == set(BSD_WITHOUT_MACOS.member_ids)
[docs]
def test_single_difference():
new_group = BSD.difference(BSD_WITHOUT_MACOS)
assert new_group.member_ids == frozenset(("macos",))
assert not BSD.issubset(new_group)
assert BSD.issuperset(new_group)
assert not BSD_WITHOUT_MACOS.issubset(new_group)
assert not BSD_WITHOUT_MACOS.issuperset(new_group)
assert not new_group.issuperset(BSD)
assert not new_group.issuperset(BSD_WITHOUT_MACOS)
assert new_group.issubset(BSD)
assert not new_group.issubset(BSD_WITHOUT_MACOS)
assert new_group.id == BSD.id
assert new_group.id != BSD_WITHOUT_MACOS.id
assert new_group.name == BSD.name
assert new_group.name != BSD_WITHOUT_MACOS.name
assert new_group.icon == BSD.icon
assert new_group.icon != BSD_WITHOUT_MACOS.icon
assert set(new_group.members) != set(BSD.members)
assert set(new_group.member_ids) != set(BSD.member_ids)
assert set(new_group.members) != set(BSD_WITHOUT_MACOS.members)
assert set(new_group.member_ids) != set(BSD_WITHOUT_MACOS.member_ids)
assert set(new_group.members) == set(BSD.members).difference(
BSD_WITHOUT_MACOS.members
)
assert set(new_group.member_ids) == set(BSD.member_ids).difference(
BSD_WITHOUT_MACOS.member_ids
)
[docs]
def test_multiple_difference():
new_group = ALL_PLATFORMS.difference(LINUX, UNIX, ALL_CI)
assert new_group.member_ids == frozenset(("windows",))
assert not ALL_PLATFORMS.issubset(new_group)
assert ALL_PLATFORMS.issuperset(new_group)
assert not LINUX.issubset(new_group)
assert not LINUX.issuperset(new_group)
assert not UNIX.issubset(new_group)
assert not UNIX.issuperset(new_group)
assert not new_group.issuperset(ALL_PLATFORMS)
assert not new_group.issuperset(LINUX)
assert not new_group.issuperset(UNIX)
assert new_group.issubset(ALL_PLATFORMS)
assert not new_group.issubset(LINUX)
assert not new_group.issubset(UNIX)
assert new_group.id == ALL_PLATFORMS.id
assert new_group.id != LINUX.id
assert new_group.id != UNIX.id
assert new_group.name == ALL_PLATFORMS.name
assert new_group.name != LINUX.name
assert new_group.name != UNIX.name
assert new_group.icon == ALL_PLATFORMS.icon
assert new_group.icon != LINUX.icon
assert new_group.icon != UNIX.icon
assert set(new_group.members) != set(ALL_PLATFORMS.members)
assert set(new_group.member_ids) != set(ALL_PLATFORMS.member_ids)
assert set(new_group.members) != set(LINUX.members)
assert set(new_group.member_ids) != set(LINUX.member_ids)
assert set(new_group.members) != set(UNIX.members)
assert set(new_group.member_ids) != set(UNIX.member_ids)
assert set(new_group.members) == set(ALL_PLATFORMS.members).difference(
LINUX.members
).difference(UNIX.members).difference(ALL_CI.members)
assert set(new_group.member_ids) == set(ALL_PLATFORMS.member_ids).difference(
LINUX.member_ids
).difference(UNIX.member_ids).difference(ALL_CI.member_ids)
[docs]
def test_symmetric_difference():
win_and_bsd = ANY_WINDOWS.union(BSD_WITHOUT_MACOS)
new_group = win_and_bsd.symmetric_difference(BSD)
assert new_group.member_ids == frozenset((("macos", "windows")))
assert not win_and_bsd.issubset(new_group)
assert not win_and_bsd.issuperset(new_group)
assert not BSD.issubset(new_group)
assert not BSD.issuperset(new_group)
assert not new_group.issuperset(win_and_bsd)
assert not new_group.issuperset(BSD)
assert not new_group.issubset(win_and_bsd)
assert not new_group.issubset(BSD)
assert new_group.id == win_and_bsd.id
assert new_group.id != BSD.id
assert new_group.name == win_and_bsd.name
assert new_group.name != BSD.name
assert new_group.icon == win_and_bsd.icon
assert new_group.icon != BSD.icon
assert set(new_group.members) != set(BSD.members)
assert set(new_group.member_ids) != set(BSD.member_ids)
assert set(new_group.members) != set(win_and_bsd.members)
assert set(new_group.member_ids) != set(win_and_bsd.member_ids)
assert set(new_group.members) == set(win_and_bsd.members).symmetric_difference(
BSD.members
)
assert set(new_group.member_ids) == set(
win_and_bsd.member_ids
).symmetric_difference(BSD.member_ids)
[docs]
def test_copy():
my_group = Group("my_group", "My Group", "β
", (AIX, AIX))
my_group_copy1 = my_group.copy()
assert my_group == my_group_copy1
assert my_group is not my_group_copy1
my_group_copy2 = my_group.copy(
id="my_group_copy2", name="My Group Copy 2", icon="π"
)
assert my_group_copy2 != my_group
assert my_group_copy2 is not my_group
assert my_group_copy2 != my_group_copy1
assert my_group_copy2 is not my_group_copy1
assert my_group_copy2.id == "my_group_copy2"
assert my_group_copy2.name == "My Group Copy 2"
assert my_group_copy2.icon == "π"
assert my_group_copy2.members == my_group.members
assert my_group_copy2.member_ids == my_group.member_ids
assert my_group_copy2.members == my_group_copy1.members
assert my_group_copy2.member_ids == my_group_copy1.member_ids
[docs]
def test_bool():
"""Test __bool__() method for truth value testing."""
# Empty group should be falsy.
empty_group = Group("empty", "Empty Group", "β", tuple())
assert not empty_group
assert bool(empty_group) is False
# Non-empty group should be truthy.
non_empty_group = Group("non_empty", "Non-Empty Group", "β
", (AIX, PIDORA))
assert non_empty_group
assert bool(non_empty_group) is True
# Group with one member should be truthy.
single_member = Group("single", "Single Member", "β
", (AIX,))
assert single_member
assert bool(single_member) is True
[docs]
def test_add():
"""Test add() method for adding a single trait."""
my_group = Group("my_group", "My Group", "β
", (AIX,))
# Add a new trait.
new_group = my_group.add(PIDORA)
assert PIDORA in new_group
assert AIX in new_group
assert len(new_group) == 2
assert new_group.member_ids == frozenset({"aix", "pidora"})
# Original group should be unchanged.
assert len(my_group) == 1
assert PIDORA not in my_group
# Add a trait that already exists (should return unchanged copy).
same_group = new_group.add(AIX)
assert len(same_group) == 2
assert same_group.member_ids == new_group.member_ids
# Add by trait ID string.
with_rhel = my_group.add("rhel")
assert RHEL in with_rhel
assert "rhel" in with_rhel
assert len(with_rhel) == 2
# Add invalid trait ID should raise ValueError.
with pytest.raises(ValueError, match="Unrecognized group or trait IDs"):
my_group.add("invalid_trait_id")
[docs]
def test_remove():
"""Test remove() method for removing a trait with error checking."""
my_group = Group("my_group", "My Group", "β
", (AIX, PIDORA, RHEL))
# Remove a trait by object.
new_group = my_group.remove(PIDORA)
assert PIDORA not in new_group
assert AIX in new_group
assert RHEL in new_group
assert len(new_group) == 2
assert new_group.member_ids == frozenset({"aix", "rhel"})
# Original group should be unchanged.
assert len(my_group) == 3
assert PIDORA in my_group
# Remove by trait ID string.
without_aix = my_group.remove("aix")
assert AIX not in without_aix
assert "aix" not in without_aix
assert len(without_aix) == 2
# Remove non-existent trait should raise KeyError.
with pytest.raises(KeyError, match="Trait 'invalid' is not in the group"):
my_group.remove("invalid")
with pytest.raises(KeyError, match="is not in the group"):
new_group.remove(PIDORA)
[docs]
def test_discard():
"""Test discard() method for removing a trait without error."""
my_group = Group("my_group", "My Group", "β
", (AIX, PIDORA, RHEL))
# Discard a trait by object.
new_group = my_group.discard(PIDORA)
assert PIDORA not in new_group
assert AIX in new_group
assert RHEL in new_group
assert len(new_group) == 2
# Original group should be unchanged.
assert len(my_group) == 3
assert PIDORA in my_group
# Discard by trait ID string.
without_aix = my_group.discard("aix")
assert AIX not in without_aix
assert len(without_aix) == 2
# Discard non-existent trait should NOT raise error.
same_group = my_group.discard("invalid")
assert len(same_group) == 3
assert same_group.member_ids == my_group.member_ids
# Discard already removed trait should NOT raise error.
still_same = new_group.discard(PIDORA)
assert len(still_same) == 2
[docs]
def test_pop():
"""Test pop() method for removing and returning a trait."""
my_group = Group("my_group", "My Group", "β
", (AIX, PIDORA, RHEL))
# Pop a specific trait by ID.
popped_trait, new_group = my_group.pop("pidora")
assert popped_trait == PIDORA
assert PIDORA not in new_group
assert AIX in new_group
assert RHEL in new_group
assert len(new_group) == 2
# Original group should be unchanged.
assert len(my_group) == 3
assert PIDORA in my_group
# Pop arbitrary trait (first in iteration order).
trait, smaller_group = new_group.pop()
assert trait in {AIX, RHEL}
assert trait not in smaller_group
assert len(smaller_group) == 1
# Pop from empty group should raise KeyError.
empty_group = Group("empty", "Empty", "β", tuple())
with pytest.raises(KeyError, match="pop from an empty group"):
empty_group.pop()
# Pop non-existent trait ID should raise KeyError.
with pytest.raises(KeyError, match="Trait 'invalid' is not in the group"):
my_group.pop("invalid")
[docs]
def test_clear():
"""Test clear() method for emptying a group."""
my_group = Group("my_group", "My Group", "β
", (AIX, PIDORA, RHEL))
# Clear the group.
empty_group = my_group.clear()
assert len(empty_group) == 0
assert not empty_group
assert empty_group.member_ids == frozenset()
# Metadata should be preserved.
assert empty_group.id == my_group.id
assert empty_group.name == my_group.name
assert empty_group.icon == my_group.icon
# Original group should be unchanged.
assert len(my_group) == 3
# Clear an already empty group.
still_empty = empty_group.clear()
assert len(still_empty) == 0
assert still_empty.id == empty_group.id
[docs]
def test_in_place_operators():
"""Test in-place operators that return new instances."""
group_a = Group("group_a", "Group A", "π
°οΈ", (AIX, PIDORA))
group_b = Group("group_b", "Group B", "π
±οΈ", (RHEL, PIDORA))
# Test |= (union).
result = group_a | group_b
result_inplace = group_a.copy()
result_inplace |= group_b
assert result.member_ids == result_inplace.member_ids
assert result.member_ids == frozenset({"aix", "pidora", "rhel"})
# Test &= (intersection).
result = group_a & group_b
result_inplace = group_a.copy()
result_inplace &= group_b
assert result.member_ids == result_inplace.member_ids
assert result.member_ids == frozenset({"pidora"})
# Test -= (difference).
result = group_a - group_b
result_inplace = group_a.copy()
result_inplace -= group_b
assert result.member_ids == result_inplace.member_ids
assert result.member_ids == frozenset({"aix"})
# Test ^= (symmetric difference).
result = group_a ^ group_b
result_inplace = group_a.copy()
result_inplace ^= group_b
assert result.member_ids == result_inplace.member_ids
assert result.member_ids == frozenset({"aix", "rhel"})
# Verify original groups are unchanged.
assert group_a.member_ids == frozenset({"aix", "pidora"})
assert group_b.member_ids == frozenset({"rhel", "pidora"})
[docs]
def test_set_operations_with_new_methods():
"""Test combining new methods with existing set operations."""
base_group = Group("base", "Base Group", "π΅", (AIX, PIDORA))
# Add, then union.
with_rhel = base_group.add(RHEL)
union_result = with_rhel.union(BSD_WITHOUT_MACOS)
assert RHEL in union_result
assert AIX in union_result
assert PIDORA in union_result
assert len(union_result) > 3
# Remove, then intersection.
without_aix = base_group.remove(AIX)
intersection_result = without_aix.intersection(ALL_PLATFORMS)
assert AIX not in intersection_result
assert PIDORA in intersection_result
# Clear, then add.
empty = base_group.clear()
with_one = empty.add(RHEL)
assert len(with_one) == 1
assert RHEL in with_one
# Pop, then discard.
popped_trait, remaining = base_group.pop("aix")
assert popped_trait == AIX
after_discard = remaining.discard("pidora")
assert len(after_discard) == 0