Coverage for app/pycardgame/tests/base/test_deck.py: 100.0%
121 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-04-07 20:57 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-04-07 20:57 +0000
1# PyCardGame - A base library for creating card games in Python
2# Copyright (C) 2025 Popa-42
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <https://www.gnu.org/licenses/>.
17from typing import Literal
19import pytest
21from ...src.base import CardMeta, DeckMeta, GenericCard, GenericDeck
23T_Ranks = Literal["1", "2", "3"]
24T_Suits = Literal["Red", "Green", "Blue"]
27class DummyCard(
28 GenericCard[T_Ranks, T_Suits],
29 metaclass=CardMeta,
30 rank_type=T_Ranks,
31 suit_type=T_Suits
32):
33 def effect(self, game, player, *args): # pragma: no cover
34 pass
37class DummyDeck(
38 GenericDeck[DummyCard],
39 metaclass=DeckMeta,
40 card_type=DummyCard
41):
42 pass
45def test_deck_init():
46 deck1 = DummyDeck()
47 assert len(deck1.cards) == 9
48 assert all(isinstance(card, DummyCard) for card in deck1)
50 cards = [DummyCard(0, 0)]
51 deck2 = DummyDeck(cards)
52 assert deck2.cards == cards
55def test_deck_count():
56 deck = DummyDeck()
57 assert deck.count(DummyCard(0, 0)) == 1
58 assert deck.count("2") == 3 # type: ignore
59 assert deck.count("Blue") == 3 # type: ignore
61 with pytest.raises(ValueError):
62 deck.count("InvalidName") # type: ignore
64 with pytest.raises(TypeError):
65 deck.count(["InvalidType"]) # type: ignore
68def test_deck_sort():
69 deck = DummyDeck().shuffle()
70 deck.sort(by="rank")
71 assert deck.cards == sorted(deck.cards, key=lambda c: (
72 not c.trump, c.rank if c.rank is not None else -1,
73 c.suit if c.suit is not None else -1))
75 deck.sort(by="suit")
76 assert deck.cards == sorted(deck.cards)
78 with pytest.raises(ValueError):
79 deck.sort(by="invalid_key") # type: ignore
82def test_deck_shuffle():
83 deck1 = DummyDeck()
84 original_deck1 = deck1.__copy__()
85 deck1.shuffle()
86 assert deck1.cards != original_deck1.cards
87 assert len(deck1.cards) == len(original_deck1.cards)
88 assert all(isinstance(card, DummyCard) for card in deck1.cards)
90 # Test shuffle with a seed
91 deck2 = DummyDeck()
92 original_deck2 = deck2.__copy__()
93 deck2.shuffle(seed=42)
94 assert deck2.cards != original_deck2.cards
95 assert len(deck2.cards) == len(original_deck2.cards)
96 assert all(isinstance(card, DummyCard) for card in deck2.cards)
97 original_deck2.shuffle(seed=42)
98 assert deck2.cards == original_deck2.cards
101def test_deck_draw():
102 deck = DummyDeck()
103 cards = deck.draw(5)
104 assert len(cards) == 5
105 assert len(deck.cards) == 4
107 cards = deck.draw(2)
108 assert len(cards) == 2
109 assert len(deck.cards) == 2
111 with pytest.raises(ValueError):
112 deck.draw(3)
115def test_deck_add():
116 deck = DummyDeck()
117 cards = [DummyCard(0, 0), DummyCard(1, 1)]
118 deck.add(*cards)
119 assert deck.cards[-1] == cards[-1]
121 deck.add(*cards, to_top=True)
122 assert deck.cards[0] == cards[0]
124 with pytest.raises(TypeError):
125 deck.add(*cards, "InvalidCard") # type: ignore
128def test_deck_remove():
129 deck = DummyDeck()
130 card = DummyCard(0, 0)
131 deck.remove(card)
132 assert card not in deck.cards
134 with pytest.raises(TypeError):
135 deck.remove("InvalidCard") # type: ignore
138def test_deck_get_index():
139 deck = DummyDeck()
140 card = DummyCard(0, 0)
141 assert deck.get_index(card) == [0]
143 with pytest.raises(TypeError):
144 deck.get_index("Red 1") # type: ignore
147def test_deck_get_cards():
148 deck = DummyDeck()
149 assert deck.get_cards() == deck.cards
152def test_deck_get_top_card():
153 deck = DummyDeck()
154 assert deck.get_top_card() == deck.cards[0]
157def test_deck_str():
158 deck = DummyDeck()
159 assert str(deck) == "Deck of 9 cards. Top card: Red 1"
162def test_deck_repr():
163 deck = DummyDeck()
164 deck_repr = repr(deck)
165 assert deck_repr.startswith("DummyDeck(card_type=<class")
166 assert "cards=[DummyCard(rank=0, suit=0)," in deck_repr
167 assert deck_repr.endswith("DummyCard(rank=2, suit=2)])")
170def test_deck_copy():
171 deck1 = DummyDeck()
172 deck2 = deck1.__copy__()
173 assert deck1 is not deck2
174 assert deck1.cards == deck2.cards
175 assert deck1.cards is not deck2.cards
176 assert isinstance(deck2, DummyDeck)
179def test_deck_equalities():
180 deck1 = DummyDeck()
181 deck2 = DummyDeck()
182 assert deck1 == deck2
183 assert not deck1 != deck2
185 deck3 = DummyDeck([DummyCard(0, 0)])
186 assert not deck1 == deck3
187 assert deck1 != deck3
189 assert not deck1 == "InvalidType" # type: ignore
190 assert deck1 != "InvalidType" # type: ignore
193def test_deck_contains():
194 deck = DummyDeck()
195 card = DummyCard(0, 0)
196 assert card in deck
198 assert "InvalidType" not in deck # type: ignore
201def test_deck_getitem():
202 deck = DummyDeck()
203 assert deck[0] == deck.cards[0]
204 assert deck[1:-1:-1] == deck.cards[1:-1:-1]
205 assert not deck == "InvalidType" # type: ignore