# Path: tests/base_unittest.py
# class BaseUnitTest(unittest.TestCase):
# 
#   def eq(self, expected, target):
#     return self.assertEqual(expected, target)
# 
#   def neq(self, expected, target):
#     return self.assertNotEqual(expected, target)
# 
#   def true(self, target):
#     return self.assertTrue(target)
# 
#   def false(self, target):
#     return self.assertFalse(target)
# 
# Path: pypokerengine/engine/card.py
# class Card:
# 
#   CLUB = 2
#   DIAMOND = 4
#   HEART = 8
#   SPADE = 16
# 
#   SUIT_MAP = {
#       2  : 'C',
#       4  : 'D',
#       8  : 'H',
#       16 : 'S'
#   }
# 
#   RANK_MAP = {
#       2  :  '2',
#       3  :  '3',
#       4  :  '4',
#       5  :  '5',
#       6  :  '6',
#       7  :  '7',
#       8  :  '8',
#       9  :  '9',
#       10 : 'T',
#       11 : 'J',
#       12 : 'Q',
#       13 : 'K',
#       14 : 'A'
#   }
# 
# 
#   def __init__(self, suit, rank):
#     self.suit = suit
#     self.rank = 14 if rank == 1 else rank
# 
#   def __eq__(self, other):
#     return self.suit == other.suit and self.rank == other.rank
# 
#   def __str__(self):
#     suit = self.SUIT_MAP[self.suit]
#     rank = self.RANK_MAP[self.rank]
#     return "{0}{1}".format(suit, rank)
# 
#   def to_id(self):
#     rank = 1 if self.rank == 14 else self.rank
#     num = 0
#     tmp = self.suit >> 1
#     while tmp&1 != 1:
#       num += 1
#       tmp >>= 1
# 
#     return rank + 13 * num
# 
#   @classmethod
#   def from_id(cls, card_id):
#     suit, rank = 2, card_id
#     while rank > 13:
#       suit <<= 1
#       rank -= 13
# 
#     return cls(suit, rank)
# 
#   @classmethod
#   def from_str(cls, str_card):
#     assert(len(str_card)==2)
#     inverse = lambda hsh: {v:k for k,v in hsh.items()}
#     suit = inverse(cls.SUIT_MAP)[str_card[0].upper()]
#     rank = inverse(cls.RANK_MAP)[str_card[1]]
#     return cls(suit, rank)
# 
# Path: pypokerengine/engine/deck.py
# class Deck:
# 
#   def __init__(self, deck_ids=None, cheat=False, cheat_card_ids=[]):
#     self.cheat = cheat
#     self.cheat_card_ids = cheat_card_ids
#     self.deck = [Card.from_id(cid) for cid in deck_ids] if deck_ids else self.__setup()
# 
#   def draw_card(self):
#     return self.deck.pop()
# 
#   def draw_cards(self, num):
#     return reduce(lambda acc, _: acc + [self.draw_card()], range(num), [])
# 
#   def size(self):
#     return len(self.deck)
# 
#   def restore(self):
#     self.deck = self.__setup()
# 
#   def shuffle(self):
#     if not self.cheat:
#       random.shuffle(self.deck)
# 
#   # serialize format : [cheat_flg, chat_card_ids, deck_card_ids]
#   def serialize(self):
#     return [self.cheat, self.cheat_card_ids, [card.to_id() for card in self.deck]]
# 
#   @classmethod
#   def deserialize(self, serial):
#     cheat, cheat_card_ids, deck_ids = serial
#     return self(deck_ids=deck_ids, cheat=cheat, cheat_card_ids=cheat_card_ids)
# 
#   def __setup(self):
#     return self.__setup_cheat_deck() if self.cheat else self.__setup_52_cards()
# 
#   def __setup_52_cards(self):
#     return [Card.from_id(cid) for cid in range(1,53)]
# 
#   def __setup_cheat_deck(self):
#     cards = [Card.from_id(cid) for cid in self.cheat_card_ids]
#     return cards[::-1]


from tests.base_unittest import BaseUnitTest
from pypokerengine.engine.card import Card
from pypokerengine.engine.deck import Deck

class DeckTest(BaseUnitTest):

  def setUp(self):
    self.deck = Deck()

  def test_draw_card(self):
    card = self.deck.draw_card()
    self.eq("SK", str(card))
    self.eq(51, self.deck.size())

  def test_draw_cards(self):
    cards = self.deck.draw_cards(3)
    self.eq("SJ", str(cards[2]))
    self.eq(49, self.deck.size())

  def test_restore(self):
    self.deck.draw_cards(5)
    self.deck.restore()
    self.eq(52, self.deck.size())

  def test_serialization(self):
    self.deck.draw_cards(5)
    self.deck.shuffle()
    serial = self.deck.serialize()
    restored = Deck.deserialize(serial)
    self.eq(self.deck.cheat, restored.cheat)
    self.eq(self.deck.deck, restored.deck)

  def test_cheat_draw(self):

# Path: tests/base_unittest.py
# class BaseUnitTest(unittest.TestCase):
# 
#   def eq(self, expected, target):
#     return self.assertEqual(expected, target)
# 
#   def neq(self, expected, target):
#     return self.assertNotEqual(expected, target)
# 
#   def true(self, target):
#     return self.assertTrue(target)
# 
#   def false(self, target):
#     return self.assertFalse(target)
# 
# Path: pypokerengine/engine/card.py
# class Card:
# 
#   CLUB = 2
#   DIAMOND = 4
#   HEART = 8
#   SPADE = 16
# 
#   SUIT_MAP = {
#       2  : 'C',
#       4  : 'D',
#       8  : 'H',
#       16 : 'S'
#   }
# 
#   RANK_MAP = {
#       2  :  '2',
#       3  :  '3',
#       4  :  '4',
#       5  :  '5',
#       6  :  '6',
#       7  :  '7',
#       8  :  '8',
#       9  :  '9',
#       10 : 'T',
#       11 : 'J',
#       12 : 'Q',
#       13 : 'K',
#       14 : 'A'
#   }
# 
# 
#   def __init__(self, suit, rank):
#     self.suit = suit
#     self.rank = 14 if rank == 1 else rank
# 
#   def __eq__(self, other):
#     return self.suit == other.suit and self.rank == other.rank
# 
#   def __str__(self):
#     suit = self.SUIT_MAP[self.suit]
#     rank = self.RANK_MAP[self.rank]
#     return "{0}{1}".format(suit, rank)
# 
#   def to_id(self):
#     rank = 1 if self.rank == 14 else self.rank
#     num = 0
#     tmp = self.suit >> 1
#     while tmp&1 != 1:
#       num += 1
#       tmp >>= 1
# 
#     return rank + 13 * num
# 
#   @classmethod
#   def from_id(cls, card_id):
#     suit, rank = 2, card_id
#     while rank > 13:
#       suit <<= 1
#       rank -= 13
# 
#     return cls(suit, rank)
# 
#   @classmethod
#   def from_str(cls, str_card):
#     assert(len(str_card)==2)
#     inverse = lambda hsh: {v:k for k,v in hsh.items()}
#     suit = inverse(cls.SUIT_MAP)[str_card[0].upper()]
#     rank = inverse(cls.RANK_MAP)[str_card[1]]
#     return cls(suit, rank)
# 
# Path: pypokerengine/engine/deck.py
# class Deck:
# 
#   def __init__(self, deck_ids=None, cheat=False, cheat_card_ids=[]):
#     self.cheat = cheat
#     self.cheat_card_ids = cheat_card_ids
#     self.deck = [Card.from_id(cid) for cid in deck_ids] if deck_ids else self.__setup()
# 
#   def draw_card(self):
#     return self.deck.pop()
# 
#   def draw_cards(self, num):
#     return reduce(lambda acc, _: acc + [self.draw_card()], range(num), [])
# 
#   def size(self):
#     return len(self.deck)
# 
#   def restore(self):
#     self.deck = self.__setup()
# 
#   def shuffle(self):
#     if not self.cheat:
#       random.shuffle(self.deck)
# 
#   # serialize format : [cheat_flg, chat_card_ids, deck_card_ids]
#   def serialize(self):
#     return [self.cheat, self.cheat_card_ids, [card.to_id() for card in self.deck]]
# 
#   @classmethod
#   def deserialize(self, serial):
#     cheat, cheat_card_ids, deck_ids = serial
#     return self(deck_ids=deck_ids, cheat=cheat, cheat_card_ids=cheat_card_ids)
# 
#   def __setup(self):
#     return self.__setup_cheat_deck() if self.cheat else self.__setup_52_cards()
# 
#   def __setup_52_cards(self):
#     return [Card.from_id(cid) for cid in range(1,53)]
# 
#   def __setup_cheat_deck(self):
#     cards = [Card.from_id(cid) for cid in self.cheat_card_ids]
#     return cards[::-1]


# Path: tests/pypokerengine/engine/deck_test.py
from tests.base_unittest import BaseUnitTest
from pypokerengine.engine.card import Card
from pypokerengine.engine.deck import Deck


class DeckTest(BaseUnitTest):

  def setUp(self):
    self.deck = Deck()

  def test_draw_card(self):
    card = self.deck.draw_card()
    self.eq("SK", str(card))
    self.eq(51, self.deck.size())

  def test_draw_cards(self):
    cards = self.deck.draw_cards(3)
    self.eq("SJ", str(cards[2]))
    self.eq(49, self.deck.size())

  def test_restore(self):
    self.deck.draw_cards(5)
    self.deck.restore()
    self.eq(52, self.deck.size())

  def test_serialization(self):
    self.deck.draw_cards(5)
    self.deck.shuffle()
    serial = self.deck.serialize()
    restored = Deck.deserialize(serial)
    self.eq(self.deck.cheat, restored.cheat)
    self.eq(self.deck.deck, restored.deck)

  def test_cheat_draw(self):

    cards = [Card.from_id(cid) for cid in [12, 15, 17]]