# Path: crowd_anki/anki/adapters/anki_deck.py
# class AnkiDeck:
#     _data: dict
# 
#     deck_name_separator = '::'
# 
#     @property
#     def data(self):
#         return self._data
# 
#     @property
#     def is_dynamic(self):
#         return bool(self.data['dyn'])
# 
#     @property
#     def name(self):
#         return self.data['name']
# 
# Path: crowd_anki/anki/adapters/deck_manager.py
# class AnkiStaticDeckManager(DeckManager):
#     internal_deck_manager: Any
# 
#     def all(self) -> Iterable[AnkiDeck]:
#         return seq(self.internal_deck_manager.all()) \
#             .map(lambda d: AnkiDeck(d)) \
#             .filter(lambda d: not d.is_dynamic) \
#             .to_list()
# 
#     def leaf_decks(self, overrides: Iterable[AnkiDeck] = tuple()) -> Iterable[AnkiDeck]:
#         deck_trie = self.deck_trie()
#         override_keys = [deck.name for deck in overrides]
# 
#         remove_children_of(deck_trie, override_keys)
#         keys = keys_without_children(deck_trie)
# 
#         return [deck_trie[key] for key in keys]
# 
#     def deck_trie(self):
#         return StringTrie(**self.decks_by_name(), separator=AnkiDeck.deck_name_separator)
# 
#     def for_names(self, names: Iterable[str]):
#         """
#         The returned decks are lazy initialized with the actual internal content.
#         """
#         return [NamedLazyDeck(name, lambda name: self.internal_deck_manager.byName)
#                 for name in names]


from expects import expect, contain_only, equal
from mamba import description, it, before
from typing import Iterable
from unittest.mock import MagicMock
from crowd_anki.anki.adapters.anki_deck import AnkiDeck
from crowd_anki.anki.adapters.deck_manager import AnkiStaticDeckManager
        self.internal_manager.all.return_value = data_from_decks(decks)


    with before.each:
        self.internal_manager = MagicMock()
        self.static_deck_manager = AnkiStaticDeckManager(self.internal_manager)
        self.mock_internal_manager(internal_decks + leaf_decks)

    with it('filters out dynamic decks, when you ask for all'):
        self.mock_internal_manager([dynamic_deck, static_deck])
        expect(self.static_deck_manager.all()).to(contain_only(static_deck))

    with it('returns only decks without children, when asked for leaf_decks'):
        expect(self.static_deck_manager.leaf_decks()).to(contain_only(*leaf_decks))

    with it('when overrides are supplied'
            'it returns them as leaf nodes, and does not return their children'):
        expect(self.static_deck_manager.leaf_decks(override_decks)) \
            .to(contain_only(*(override_decks + dummy_deck_for_names(non_overridden_decks))))

    with it('ignores non-existent overrides'):
        expect(self.static_deck_manager
               .leaf_decks(override_decks + [deck_for_name('non_existent_deck')])) \
            .to(contain_only(*(override_decks + dummy_deck_for_names(non_overridden_decks))))

    with it('for_names returns lazy decks without calling internal deck manager'):
        test_name = 'test_name'
        result_decks = self.static_deck_manager.for_names([test_name])

        self.internal_manager.assert_not_called()

# Path: crowd_anki/anki/adapters/anki_deck.py
# class AnkiDeck:
#     _data: dict
# 
#     deck_name_separator = '::'
# 
#     @property
#     def data(self):
#         return self._data
# 
#     @property
#     def is_dynamic(self):
#         return bool(self.data['dyn'])
# 
#     @property
#     def name(self):
#         return self.data['name']
# 
# Path: crowd_anki/anki/adapters/deck_manager.py
# class AnkiStaticDeckManager(DeckManager):
#     internal_deck_manager: Any
# 
#     def all(self) -> Iterable[AnkiDeck]:
#         return seq(self.internal_deck_manager.all()) \
#             .map(lambda d: AnkiDeck(d)) \
#             .filter(lambda d: not d.is_dynamic) \
#             .to_list()
# 
#     def leaf_decks(self, overrides: Iterable[AnkiDeck] = tuple()) -> Iterable[AnkiDeck]:
#         deck_trie = self.deck_trie()
#         override_keys = [deck.name for deck in overrides]
# 
#         remove_children_of(deck_trie, override_keys)
#         keys = keys_without_children(deck_trie)
# 
#         return [deck_trie[key] for key in keys]
# 
#     def deck_trie(self):
#         return StringTrie(**self.decks_by_name(), separator=AnkiDeck.deck_name_separator)
# 
#     def for_names(self, names: Iterable[str]):
#         """
#         The returned decks are lazy initialized with the actual internal content.
#         """
#         return [NamedLazyDeck(name, lambda name: self.internal_deck_manager.byName)
#                 for name in names]


# Path: test/anki/adapters/deck_manager_spec.py
from expects import expect, contain_only, equal
from mamba import description, it, before
from typing import Iterable
from unittest.mock import MagicMock
from crowd_anki.anki.adapters.anki_deck import AnkiDeck
from crowd_anki.anki.adapters.deck_manager import AnkiStaticDeckManager

        self.internal_manager.all.return_value = data_from_decks(decks)


    with before.each:
        self.internal_manager = MagicMock()
        self.static_deck_manager = AnkiStaticDeckManager(self.internal_manager)
        self.mock_internal_manager(internal_decks + leaf_decks)

    with it('filters out dynamic decks, when you ask for all'):
        self.mock_internal_manager([dynamic_deck, static_deck])
        expect(self.static_deck_manager.all()).to(contain_only(static_deck))

    with it('returns only decks without children, when asked for leaf_decks'):
        expect(self.static_deck_manager.leaf_decks()).to(contain_only(*leaf_decks))

    with it('when overrides are supplied'
            'it returns them as leaf nodes, and does not return their children'):
        expect(self.static_deck_manager.leaf_decks(override_decks)) \
            .to(contain_only(*(override_decks + dummy_deck_for_names(non_overridden_decks))))

    with it('ignores non-existent overrides'):
        expect(self.static_deck_manager
               .leaf_decks(override_decks + [deck_for_name('non_existent_deck')])) \
            .to(contain_only(*(override_decks + dummy_deck_for_names(non_overridden_decks))))

    with it('for_names returns lazy decks without calling internal deck manager'):
        test_name = 'test_name'
        result_decks = self.static_deck_manager.for_names([test_name])

        self.internal_manager.assert_not_called()

        expect(result_decks[0].name).to(equal(test_name))