ポーカーの役を判定する（単体テスト編）

[こちらの記事](https://qiita.com/gawawa124/items/42b4f05d312605c105fc)の単体テストも書いたので。

```poker_checker.spec.ts
import {
  Card, Suit,
  isRoyalFlush, isStraightFlush, isFlush, isStraight,
  isFourOfAKind, isFullHouse, isThreeOfAKind, isTwoPair, isOnePair,
  isHighCard, validate, counter, customSort
} from "#/poker_checker"

test('isRoyalFlush', () => {
  const cards: Card[] = [
    new Card(Suit.heart, 11),
    new Card(Suit.heart, 10),
    new Card(Suit.heart, 12),
    new Card(Suit.heart, 13),
    new Card(Suit.heart, 1)
  ]
  customSort(cards)

  expect(isRoyalFlush(cards)).toBe(true)
})

test('isStraightFlush', () => {
  const cards: Card[] = [
    new Card(Suit.heart, 11),
    new Card(Suit.heart, 10),
    new Card(Suit.heart, 12),
    new Card(Suit.heart, 13),
    new Card(Suit.heart, 9)
  ]
  customSort(cards)

  expect(isRoyalFlush(cards)).toBe(false)
  expect(isStraightFlush(cards)).toBe(true)
})

test('isFlush', () => {
  const cards: Card[] = [
    new Card(Suit.heart, 11),
    new Card(Suit.heart, 7),
    new Card(Suit.heart, 12),
    new Card(Suit.heart, 13),
    new Card(Suit.heart, 9)
  ]
  customSort(cards)

  expect(isRoyalFlush(cards)).toBe(false)
  expect(isStraightFlush(cards)).toBe(false)
  expect(isFlush(cards)).toBe(true)
})

test('isStraight', () => {
  const cards: Card[] = [
    new Card(Suit.heart, 11),
    new Card(Suit.club, 10),
    new Card(Suit.heart, 12),
    new Card(Suit.heart, 13),
    new Card(Suit.heart, 9)
  ]
  customSort(cards)

  expect(isRoyalFlush(cards)).toBe(false)
  expect(isStraightFlush(cards)).toBe(false)
  expect(isStraight(cards)).toBe(true)
})

test('isFourOfAKind', () => {
  const cards: Card[] = [
    new Card(Suit.heart, 10),
    new Card(Suit.club, 10),
    new Card(Suit.diamond, 10),
    new Card(Suit.spade, 10),
    new Card(Suit.heart, 9)
  ]
  customSort(cards)

  expect(isFourOfAKind(cards)).toBe(true)
})

test('isFullHouse', () => {
  const cards: Card[] = [
    new Card(Suit.heart, 10),
    new Card(Suit.club, 10),
    new Card(Suit.diamond, 10),
    new Card(Suit.spade, 9),
    new Card(Suit.heart, 9)
  ]
  customSort(cards)

  expect(isFullHouse(cards)).toBe(true)
})

test('isThreeOfAKind', () => {
  const cards: Card[] = [
    new Card(Suit.heart, 10),
    new Card(Suit.club, 10),
    new Card(Suit.diamond, 10),
    new Card(Suit.spade, 8),
    new Card(Suit.heart, 9)
  ]
  customSort(cards)

  expect(isFullHouse(cards)).toBe(false)
  expect(isThreeOfAKind(cards)).toBe(true)
})

test('isTwoPair', () => {
  const cards: Card[] = [
    new Card(Suit.heart, 10),
    new Card(Suit.club, 10),
    new Card(Suit.diamond, 8),
    new Card(Suit.spade, 8),
    new Card(Suit.heart, 9)
  ]
  customSort(cards)

  expect(isFullHouse(cards)).toBe(false)
  expect(isThreeOfAKind(cards)).toBe(false)
  expect(isTwoPair(cards)).toBe(true)
})

test('isOnePair', () => {
  const cards: Card[] = [
    new Card(Suit.heart, 10),
    new Card(Suit.club, 10),
    new Card(Suit.diamond, 6),
    new Card(Suit.spade, 8),
    new Card(Suit.heart, 9)
  ]
  customSort(cards)

  expect(isOnePair(cards)).toBe(true)
})

test('isHighCard', () => {
  const cards: Card[] = [
    new Card(Suit.heart, 10),
    new Card(Suit.club, 2),
    new Card(Suit.diamond, 6),
    new Card(Suit.spade, 8),
    new Card(Suit.heart, 9)
  ]
  customSort(cards)

  expect(isHighCard(cards)).toBe(true)
})

test('validate cards Length', () => {
  const cards: Card[] = [
    new Card(Suit.heart, 10),
    new Card(Suit.club, 10),
    new Card(Suit.diamond, 10),
    new Card(Suit.spade, 8)
  ]
  customSort(cards)

  function invalidCardLength() {
    validate(cards)
  }

  expect(invalidCardLength).toThrowError(new Error('CardsLength is not 5.'))
})

test('validate within 1-13', () => {
  function invalidNumeral() {
    validate(cards)
  }

  let cards: Card[] = [
    new Card(Suit.heart, 1),
    new Card(Suit.club, 2),
    new Card(Suit.diamond, 11),
    new Card(Suit.spade, 13),
    new Card(Suit.spade, 0)
  ]
  customSort(cards)

  expect(invalidNumeral).toThrowError(new Error('Some numeral is not within 1-13.'))

  cards[0] = new Card(Suit.spade, 14)
  customSort(cards)
  expect(invalidNumeral).toThrowError(new Error('Some numeral is not within 1-13.'))

  cards[4] = new Card(Suit.spade, 5)
  customSort(cards)
  expect(validate(cards)).toBeNull()
})

test('validate no duplicate cards', () => {
  function isDuplicate() {
    validate(cards)
  }

  const cards: Card[] = [
    new Card(Suit.heart, 1),
    new Card(Suit.club, 2),
    new Card(Suit.diamond, 11),
    new Card(Suit.spade, 13),
    new Card(Suit.spade, 13)
  ]
  customSort(cards)

  expect(isDuplicate).toThrowError(new Error('There are duplicate cards.'))
})

test('counter', () => {
  const cards: Card[] = [
    new Card(Suit.heart, 7),
    new Card(Suit.club, 2),
    new Card(Suit.diamond, 3),
    new Card(Suit.spade, 7),
    new Card(Suit.spade, 3)
  ]
  customSort(cards)

  const c = counter(cards)
  expect(c[2]).toBe(1)
  expect(c[3]).toBe(2)
  expect(c[7]).toBe(2)
})

test('customSort', () => {
  const cards: Card[] = [
    new Card(Suit.heart, 7),
    new Card(Suit.club, 2),
    new Card(Suit.diamond, 3),
    new Card(Suit.spade, 3),
    new Card(Suit.club, 9)
  ]
  customSort(cards)

  const cards2: Card[] = [
    new Card(Suit.club, 2),
    new Card(Suit.spade, 3),
    new Card(Suit.diamond, 3),
    new Card(Suit.heart, 7),
    new Card(Suit.club, 9)
  ]

  expect(JSON.stringify(cards)).toBe(JSON.stringify(cards2))
})
```