feat(phase-10): add DeckBuilderAdapter unit tests
This commit is contained in:
1 parent
72107df2ae
commit
9fd39e42c7
1 file changed
+104
@@ -0,0 +1,104 @@
|
||||
"""Tests for DeckBuilderAdapter — the bridge between Ollama pipeline and legacy API."""
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
from types import SimpleNamespace
|
||||
|
||||
from src.commander_ai_lab.deck_builder.adapter import DeckBuilderAdapter
|
||||
from src.commander_ai_lab.deck_builder.core.models import (
|
||||
BuildResult,
|
||||
CardEntry,
|
||||
CommanderDeck,
|
||||
DeckRatios,
|
||||
)
|
||||
|
||||
|
||||
def _fake_build_result():
|
||||
"""Return a minimal BuildResult for mocking build_deck."""
|
||||
cmdr = CardEntry(name="Atraxa", color_identity=["W", "U", "B", "G"])
|
||||
basics = ["Plains", "Island", "Swamp", "Mountain", "Forest"]
|
||||
cards = [
|
||||
CardEntry(name=basics[i % 5], quantity=1, category="lands", color_identity={"W", "U", "B", "G"})
|
||||
for i in range(99)
|
||||
]
|
||||
deck = CommanderDeck(commander=cmdr, cards=cards)
|
||||
return BuildResult(
|
||||
deck=deck,
|
||||
warnings=["test warning"],
|
||||
sources_consulted=["scryfall", "edhrec"],
|
||||
build_time_seconds=1.23,
|
||||
)
|
||||
|
||||
|
||||
class TestDeckBuilderAdapter:
|
||||
def test_init_defaults(self):
|
||||
adapter = DeckBuilderAdapter()
|
||||
assert adapter.model == "gpt-oss:20b"
|
||||
assert adapter.db_conn_factory is None
|
||||
|
||||
@patch("src.commander_ai_lab.deck_builder.adapter.build_deck")
|
||||
def test_generate_deck_returns_expected_shape(self, mock_build):
|
||||
mock_build.return_value = _fake_build_result()
|
||||
adapter = DeckBuilderAdapter()
|
||||
result = adapter.generate_deck("Atraxa", strategy="superfriends")
|
||||
|
||||
assert "commander" in result
|
||||
assert result["commander"]["name"] == "Atraxa"
|
||||
assert "cards" in result
|
||||
assert "stats" in result
|
||||
assert result["model"] == "gpt-oss:20b"
|
||||
assert result["build_time_seconds"] == 1.23
|
||||
assert "scryfall" in result["reasoning"]["sources"]
|
||||
|
||||
@patch("src.commander_ai_lab.deck_builder.adapter.build_deck")
|
||||
def test_generate_deck_fills_to_100(self, mock_build):
|
||||
mock_build.return_value = _fake_build_result()
|
||||
adapter = DeckBuilderAdapter()
|
||||
result = adapter.generate_deck("Atraxa")
|
||||
total = sum(c.get("count", 1) for c in result["cards"])
|
||||
assert total == 100 # 99 cards + commander fills to 100
|
||||
|
||||
@patch("src.commander_ai_lab.deck_builder.adapter.build_deck")
|
||||
def test_ownership_without_db(self, mock_build):
|
||||
mock_build.return_value = _fake_build_result()
|
||||
adapter = DeckBuilderAdapter(db_conn_factory=None)
|
||||
result = adapter.generate_deck("Atraxa")
|
||||
for card in result["cards"]:
|
||||
assert card["owned"] is False
|
||||
assert card["from_collection"] is False
|
||||
|
||||
|
||||
class TestRunSubstitution:
|
||||
def test_no_op_returns_namespace(self):
|
||||
adapter = DeckBuilderAdapter()
|
||||
cards = [
|
||||
{"name": "Sol Ring", "owned": True},
|
||||
{"name": "Mana Crypt", "owned": False},
|
||||
]
|
||||
result = adapter.run_substitution(cards, commander="Atraxa")
|
||||
assert isinstance(result, SimpleNamespace)
|
||||
assert result.owned_count == 1
|
||||
assert result.substituted_count == 0
|
||||
assert result.missing_count == 1
|
||||
|
||||
|
||||
class TestHelpers:
|
||||
def test_fill_basic_lands_adds_missing(self):
|
||||
cards = [{"name": "Sol Ring", "count": 1, "category": "ramp"}]
|
||||
filled = DeckBuilderAdapter._fill_basic_lands(cards, ["W", "U"], target_total=5)
|
||||
total = sum(c.get("count", 1) for c in filled)
|
||||
assert total == 5
|
||||
|
||||
def test_fill_basic_lands_no_excess(self):
|
||||
cards = [{"name": f"Card{i}", "count": 1} for i in range(100)]
|
||||
filled = DeckBuilderAdapter._fill_basic_lands(cards, ["W"], target_total=100)
|
||||
assert len(filled) == 100
|
||||
|
||||
def test_compute_stats(self):
|
||||
cards = [
|
||||
{"name": "Sol Ring", "count": 1, "category": "ramp", "cmc": 1},
|
||||
{"name": "Plains", "count": 36, "category": "lands", "cmc": 0},
|
||||
]
|
||||
stats = DeckBuilderAdapter._compute_stats(cards)
|
||||
assert stats["total_cards"] == 37
|
||||
assert stats["land_count"] == 36
|
||||
assert stats["average_cmc"] == 1.0
|
||||
Reference in new issue
Block a user