File size: 2,605 Bytes
16eaadc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""TDD for spaceutil.plot - the deck-builder figures."""

from __future__ import annotations

import numpy as np


def _matrix(cards):
    return np.stack(
        [np.asarray(c["embedding"], dtype=np.float32) for c in cards], axis=0
    )


def _strip_emb(cards):
    return [{k: v for k, v in c.items() if k != "embedding"} for c in cards]


def _build_a_deck(synthetic_cards):
    from spaceutil.deck import build_deck

    idx = next(i for i, c in enumerate(synthetic_cards) if c["card_type"] == "Leader")
    return build_deck(idx, _strip_emb(synthetic_cards), _matrix(synthetic_cards))


class TestEmptyState:
    def test_cost_curve_with_no_deck(self):
        import plotly.graph_objects as go

        from spaceutil.plot import build_cost_curve_figure

        fig = build_cost_curve_figure(None)
        assert isinstance(fig, go.Figure)
        assert len(fig.data) == 0
        assert any("build a deck" in a.text.lower() for a in fig.layout.annotations)

    def test_type_breakdown_with_no_deck(self):
        from spaceutil.plot import build_type_breakdown_figure

        fig = build_type_breakdown_figure(None)
        assert len(fig.data) == 0

    def test_color_breakdown_with_no_deck(self):
        from spaceutil.plot import build_color_breakdown_figure

        fig = build_color_breakdown_figure(None)
        assert len(fig.data) == 0


class TestBuiltDeck:
    def test_cost_curve_has_two_bars(self, synthetic_cards):
        from spaceutil.plot import build_cost_curve_figure

        deck = _build_a_deck(synthetic_cards)
        fig = build_cost_curve_figure(deck)
        # actual + target traces
        assert len(fig.data) == 2
        names = {trace.name for trace in fig.data}
        assert names == {"Actual", "Target"}

    def test_type_breakdown_returns_one_trace(self, synthetic_cards):
        from spaceutil.plot import build_type_breakdown_figure

        deck = _build_a_deck(synthetic_cards)
        fig = build_type_breakdown_figure(deck)
        assert len(fig.data) == 1
        # Should include at least one type
        assert sum(fig.data[0].y) > 0

    def test_color_breakdown_includes_leader_color(self, synthetic_cards):
        from spaceutil.plot import build_color_breakdown_figure

        deck = _build_a_deck(synthetic_cards)
        fig = build_color_breakdown_figure(deck)
        assert len(fig.data) == 1
        # Every color appearing on the chart should appear on at least one card
        on_chart_colors = set(fig.data[0].x)
        actual_colors = set(deck.color_distribution.keys())
        assert on_chart_colors == actual_colors