diff --git a/README.md b/README.md index 3bcfc25784..26a14be9b8 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,78 @@ 블랙잭 게임 미션 저장소 ## 우아한테크코스 코드리뷰 -* [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) \ No newline at end of file +* [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) + +
+ +## 기능 구현 목록 +- 참가자 추상 클래스 구현 + - 플레이어 구현 + - 손에 카드를 가지고 있다 + - 카드를 받는다, 안받는다 + - [x] y, n 이 아닌 다른 값 입력 + - [x] 공백 또는 NULL + - 이름을 가지고 있는다 + - [x] 공백 또는 NULL + - 딜러 구현 + - 손에 카드를 가지고 있다 + - 점수 총합이 16 이하일시 카드를 받는다 + - 카드를 플레이어들에게 나눠준다 +- 카드덱 구현 Deque + - 카드 구현 Card 클래스 + - 카드 숫자 Enum + - 카드 무늬 Enum + - +- 블랙잭 구현 + - 플레이어들의 이름을 받는다 + - [x] 플레이어의 이름 개수가 7개 초과 + - 점수를 계산하여 승자를 판단한다 + - 점수가 21을 초과할 경우 패배시킨다 + +
+ +## 테스트 구상 목록 +- 카드덱 뭉치 + - [x] 사이즈가 52인지 + - [x] 중복 카드가 입력 되었는지 + - [x] 무늬별 13장씩 있는지 + - [x] 무늬가 총 4개로 분류되는지 + - [x] 덱에서 카드가 잘 나오는지 +- 카드 + - [x] 카드가 잘 생성 되는지 +- 승패 테스트 + - [x] 플레이어 승패 잘 판단되는지 + - [x] 딜러 승패 잘 반환 되는지 + +
+ +## 질문 리스트 +- 카드 셔플을 딜러가 아닌 카드가 해도 되는지 +- 제네레이터 클래스를 만든것에 대해. +- Number Enum 클래스가 번호별 출력양식을 가진 것에 대하여. + - 만일 OutputView 쪽에서 Enum별 출력 양식을 가지면 그건 도메인 역할을 침범하는게 아닌가? + +
+ +## 리팩토링 구상 목록 +- `BlackjackManager`가 꼭 유틸 클래스일 필요가 있는가? + - `BlackjackManager` 가 꼭 유틸 클래스이지 말라는 법은 없지만, 꼭 유틸 클래스일 필요도 없다. + - 게다가, 대부분의 경우 유틸 클래스를 지양하라는 피드백을 받았었다. + - 대안 1. `BlackjackManager` 클래스를 제거한다. + - 미립이 `BlackjackManager` 존재의 필요성에 대해 의문을 표시해주셨다. + - "현재 컨트롤러가 `BlackjackManager`의 역할을 모두 수행하고 있는 것이 아닌가?" + - 대안 2. `BlackjackManager`가 덱을 갖도록 한다. + - 딜러가 카드를 꼭 나눠줄 필요가 없다. 객체지향은 현실세계 모방일뿐. + - 카드가 직접 딜러와 플레이어에게 나눠주는 행동을 하자. + +- Dto 변경 + - `BlackjackManager` 를 서비스레이어처럼 생각하고 Dto를 만드는 역할 추가 + +- 블랙잭 승패 비교를 GameResult Enum 클래스가 아닌 딜러가 하도록 + +- `InputView` 이름 파싱 조금 더 여유롭게 (정규표현식 사용) + +- Controller 쪽으로 Player, Players, Dealer가 빠져나가지 않도록 + - 핵심은 `BlackjackManager` 혹은 `Players` 쪽에 현재 플레이어를 기억할 방법을 찾는 것. + +- 도메인(`BlackjackManager`)이 Dto 로직을 모르도록 diff --git a/src/main/java/blackjack/Application.java b/src/main/java/blackjack/Application.java new file mode 100644 index 0000000000..524cbbd98a --- /dev/null +++ b/src/main/java/blackjack/Application.java @@ -0,0 +1,11 @@ +package blackjack; + +import blackjack.controller.BlackjackController; + +public class Application { + + public static void main(String[] args) { + BlackjackController blackjackController = new BlackjackController(); + blackjackController.play(); + } +} diff --git a/src/main/java/blackjack/controller/BlackjackController.java b/src/main/java/blackjack/controller/BlackjackController.java new file mode 100644 index 0000000000..74d7ff9e2c --- /dev/null +++ b/src/main/java/blackjack/controller/BlackjackController.java @@ -0,0 +1,84 @@ +package blackjack.controller; + +import blackjack.domain.BlackjackManager; +import blackjack.domain.DtoAssembler; +import blackjack.domain.participant.Dealer; +import blackjack.domain.participant.Players; +import blackjack.view.InputView; +import blackjack.view.OutputView; +import blackjack.view.dto.ParticipantDto; +import blackjack.view.dto.ResultDto; +import java.util.List; + +public class BlackjackController { + + public void play() { + Dealer dealer = new Dealer(); + Players players = new Players(InputView.getPlayerNames()); + BlackjackManager blackjackManager = new BlackjackManager(dealer, players); + + initDrawCardsDealerAndAllPlayers(blackjackManager); + hitOrStayAllPlayers(blackjackManager); + hitDealerUntilOverLimitScore(blackjackManager); + printCardsWithScoreOfDealerAndAllPlayers(blackjackManager); + printBlackjackResult(blackjackManager); + } + + private void initDrawCardsDealerAndAllPlayers(BlackjackManager blackjackManager) { + blackjackManager.initDrawCards(); + ParticipantDto dealerInitStatus = DtoAssembler + .createDealerInitStatusDto(blackjackManager.getDealer()); + List playerStatuses = DtoAssembler + .createPlayerStatusDtos(blackjackManager.getPlayers()); + OutputView.printInitStatuses(dealerInitStatus, playerStatuses); + } + + private void hitOrStayAllPlayers(BlackjackManager blackjackManager) { + while (!blackjackManager.isFinishedAllPlayers()) { + hitOrStayCurrentPlayer(blackjackManager); + blackjackManager.passTurnToNextPlayer(); + } + blackjackManager.passTurnToNextPlayer(); + } + + private void hitOrStayCurrentPlayer(BlackjackManager blackjackManager) { + if (!blackjackManager.isFinishedCurrentPlayer()) { + blackjackManager.hitOrStayCurrentPlayer( + InputView.getHitOrStay(blackjackManager.getCurrentPlayerName())); + OutputView.printPlayerStatus( + DtoAssembler.createPlayerStatusDto(blackjackManager.getCurrentPlayer())); + } + } + + private void hitDealerUntilOverLimitScore(BlackjackManager blackjackManager) { + OutputView.printNewLine(); + while (!blackjackManager.isFinishedDealer()) { + hitOrStayDealer(blackjackManager); + } + OutputView.printNewLine(); + } + + private void hitOrStayDealer(BlackjackManager blackjackManager) { + if (blackjackManager.isDealerScoreOverThenLimit()) { + blackjackManager.stayDealer(); + return; + } + blackjackManager.hitDealer(); + OutputView.printDealerHit(); + } + + private void printCardsWithScoreOfDealerAndAllPlayers(BlackjackManager blackjackManager) { + OutputView + .printStatusWithScore(DtoAssembler.createDealerStatusDto(blackjackManager.getDealer())); + DtoAssembler.createPlayerStatusDtos(blackjackManager.getPlayers()) + .forEach(OutputView::printStatusWithScore); + } + + private void printBlackjackResult(BlackjackManager blackjackManager) { + Dealer dealer = blackjackManager.getDealer(); + Players players = blackjackManager.getPlayers(); + ResultDto dealerResult = DtoAssembler.createDealerResultDto(dealer, players); + List playerResultDtos = DtoAssembler.createPlayerResultDtos(dealer, players); + OutputView.printBlackjackResult(dealerResult, playerResultDtos); + } +} diff --git a/src/main/java/blackjack/domain/BlackjackManager.java b/src/main/java/blackjack/domain/BlackjackManager.java new file mode 100644 index 0000000000..759f88df7b --- /dev/null +++ b/src/main/java/blackjack/domain/BlackjackManager.java @@ -0,0 +1,80 @@ +package blackjack.domain; + +import blackjack.domain.carddeck.CardDeck; +import blackjack.domain.participant.Dealer; +import blackjack.domain.participant.Player; +import blackjack.domain.participant.Players; + +public class BlackjackManager { + + private final CardDeck cardDeck; + private final Dealer dealer; + private final Players players; + + public BlackjackManager(final Dealer dealer, final Players players) { + this(CardDeck.newShuffledDeck(), dealer, players); + } + + public BlackjackManager(final CardDeck cardDeck, final Dealer dealer, final Players players) { + this.cardDeck = cardDeck; + this.dealer = dealer; + this.players = players; + } + + public void initDrawCards() { + this.dealer.initDraw(this.cardDeck); + this.players.initDraw(this.cardDeck); + } + + public void hitOrStayCurrentPlayer(boolean isPlayerHit) { + if (isPlayerHit) { + this.players.drawFirstOrderPlayer(this.cardDeck.draw()); + return; + } + this.players.stayFirstOrderPlayer(); + } + + public void passTurnToNextPlayer() { + this.players.passTurnToNextPlayer(); + } + + public boolean isFinishedCurrentPlayer() { + return this.players.isFinishedCurrentPlayer(); + } + + public boolean isFinishedAllPlayers() { + return this.players.isAllPlayerFinished(); + } + + public void hitDealer() { + this.dealer.draw(this.cardDeck.draw()); + } + + public void stayDealer() { + this.dealer.stay(); + } + + public boolean isDealerScoreOverThenLimit() { + return this.dealer.isOverThenLimitScore(); + } + + public boolean isFinishedDealer() { + return this.dealer.isFinished(); + } + + public Players getPlayers() { + return this.players; + } + + public Player getCurrentPlayer() { + return this.players.getFirstOrderPlayer(); + } + + public String getCurrentPlayerName() { + return this.players.getFirstOrderPlayerName(); + } + + public Dealer getDealer() { + return this.dealer; + } +} diff --git a/src/main/java/blackjack/domain/DtoAssembler.java b/src/main/java/blackjack/domain/DtoAssembler.java new file mode 100644 index 0000000000..8f59744988 --- /dev/null +++ b/src/main/java/blackjack/domain/DtoAssembler.java @@ -0,0 +1,85 @@ +package blackjack.domain; + +import blackjack.domain.carddeck.Card; +import blackjack.domain.participant.Dealer; +import blackjack.domain.participant.Player; +import blackjack.domain.participant.Players; +import blackjack.view.dto.CardDto; +import blackjack.view.dto.ParticipantDto; +import blackjack.view.dto.ResultDto; +import java.util.List; +import java.util.stream.Collectors; + +public class DtoAssembler { + + private static final String DELIMITER = ", "; + + public static ParticipantDto createDealerInitStatusDto(final Dealer dealer) { + return new ParticipantDto( + createCardDtos(dealer.getInitCard()), + dealer.getScoreToInt() + ); + } + + public static ParticipantDto createDealerStatusDto(Dealer dealer) { + return new ParticipantDto( + createCardDtos(dealer.getCards()), + dealer.getScoreToInt() + ); + } + + public static List createPlayerStatusDtos(final Players players) { + return players.toList() + .stream() + .map(DtoAssembler::createPlayerStatusDto) + .collect(Collectors.toList()) + ; + } + + public static ParticipantDto createPlayerStatusDto(final Player player) { + return new ParticipantDto( + player.getName(), + createCardDtos(player.getCards()), + player.getScoreToInt() + ); + } + + private static List createCardDtos(final List cards) { + return cards.stream() + .map(card -> new CardDto(card.getNumberName() + card.getPatternName())) + .collect(Collectors.toList()) + ; + } + + public static ResultDto createDealerResultDto(final Dealer dealer, Players players) { + List results = getResults(dealer, players); + return new ResultDto( + getResultString(results, Result.WIN) + DELIMITER + + getResultString(results, Result.LOSE) + DELIMITER + + getResultString(results, Result.DRAW) + ); + } + + private static List getResults(final Dealer dealer, final Players players) { + return players.toList() + .stream() + .map(player -> player.judgeByDealerState(dealer)) + .map(Result::reverse) + .collect(Collectors.toList()); + } + + private static String getResultString(final List results, final Result result) { + return results.stream() + .filter(compareResult -> compareResult.equals(result)) + .count() + result.getResult(); + } + + public static List createPlayerResultDtos(final Dealer dealer, + final Players players) { + return players.toList() + .stream() + .map(player -> new ResultDto(player.getName(), + player.judgeByDealerState(dealer).getResult())) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/blackjack/domain/Result.java b/src/main/java/blackjack/domain/Result.java new file mode 100644 index 0000000000..8db9919c87 --- /dev/null +++ b/src/main/java/blackjack/domain/Result.java @@ -0,0 +1,28 @@ +package blackjack.domain; + +public enum Result { + + WIN("승"), + LOSE("패"), + DRAW("무"); + + private final String result; + + Result(final String result) { + this.result = result; + } + + public Result reverse() { + if (this == WIN) { + return LOSE; + } + if (this == LOSE) { + return WIN; + } + return DRAW; + } + + public String getResult() { + return this.result; + } +} diff --git a/src/main/java/blackjack/domain/carddeck/Card.java b/src/main/java/blackjack/domain/carddeck/Card.java new file mode 100644 index 0000000000..ce09f59420 --- /dev/null +++ b/src/main/java/blackjack/domain/carddeck/Card.java @@ -0,0 +1,83 @@ +package blackjack.domain.carddeck; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class Card { + + private static final List CACHE_DECK = new ArrayList<>(); + + static { + for (Pattern pattern : Pattern.values()) { + for (Number number : Number.values()) { + CACHE_DECK.add(new Card(pattern, number)); + } + } + } + + private final Pattern pattern; + private final Number number; + + private Card(final Pattern pattern, final Number number) { + this.pattern = pattern; + this.number = number; + } + + public static Card valueOf(final Pattern pattern, final Number number) { + Card card = CACHE_DECK.stream() + .filter(cardPatterns -> cardPatterns.hasPattern(pattern)) + .filter(cardNumbers -> cardNumbers.hasNumber(number)) + .findAny() + .get(); + if (Objects.isNull(card)) { + throw new IllegalArgumentException("해당 카드가 존재하지 않습니다."); + } + return card; + } + + public static List generate() { + return new ArrayList<>(CACHE_DECK); + } + + private boolean hasNumber(final Number number) { + return this.number.equals(number); + } + + private boolean hasPattern(final Pattern pattern) { + return this.pattern.equals(pattern); + } + + public boolean isAce() { + return this.number.isAce(); + } + + public int getScore() { + return this.number.getScore(); + } + + public String getPatternName() { + return this.pattern.getPattern(); + } + + public String getNumberName() { + return this.number.getName(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Card card = (Card) o; + return pattern == card.pattern && number == card.number; + } + + @Override + public int hashCode() { + return Objects.hash(pattern, number); + } +} diff --git a/src/main/java/blackjack/domain/carddeck/CardDeck.java b/src/main/java/blackjack/domain/carddeck/CardDeck.java new file mode 100644 index 0000000000..2ec61f73f4 --- /dev/null +++ b/src/main/java/blackjack/domain/carddeck/CardDeck.java @@ -0,0 +1,29 @@ +package blackjack.domain.carddeck; + +import java.util.ArrayDeque; +import java.util.Collections; +import java.util.Deque; +import java.util.List; + +public class CardDeck { + + private final Deque deck; + + private CardDeck(final Deque cards) { + this.deck = cards; + } + + public static CardDeck newShuffledDeck() { + List cards = Card.generate(); + Collections.shuffle(cards); + return new CardDeck(new ArrayDeque<>(cards)); + } + + public static CardDeck customDeck(final List cards) { + return new CardDeck(new ArrayDeque<>(cards)); + } + + public Card draw() { + return this.deck.pop(); + } +} diff --git a/src/main/java/blackjack/domain/carddeck/Number.java b/src/main/java/blackjack/domain/carddeck/Number.java new file mode 100644 index 0000000000..799cb0abf6 --- /dev/null +++ b/src/main/java/blackjack/domain/carddeck/Number.java @@ -0,0 +1,37 @@ +package blackjack.domain.carddeck; + +public enum Number { + ACE(11, "A"), + TWO(2, "2"), + THREE(3, "3"), + FOUR(4, "4"), + FIVE(5, "5"), + SIX(6, "6"), + SEVEN(7, "7"), + EIGHT(8, "8"), + NINE(9, "9"), + TEN(10, "10"), + JACK(10, "J"), + QUEEN(10, "Q"), + KING(10, "K"); + + private final int score; + private final String name; + + Number(final int score, final String name) { + this.score = score; + this.name = name; + } + + public int getScore() { + return this.score; + } + + public String getName() { + return this.name; + } + + public boolean isAce() { + return this.score == ACE.score; + } +} diff --git a/src/main/java/blackjack/domain/carddeck/Pattern.java b/src/main/java/blackjack/domain/carddeck/Pattern.java new file mode 100644 index 0000000000..9cd214ae79 --- /dev/null +++ b/src/main/java/blackjack/domain/carddeck/Pattern.java @@ -0,0 +1,19 @@ +package blackjack.domain.carddeck; + +public enum Pattern { + + SPADE("스페이드"), + DIAMOND("다이아몬드"), + CLOVER("클로버"), + HEART("하트"); + + private final String pattern; + + Pattern(final String pattern) { + this.pattern = pattern; + } + + public String getPattern() { + return this.pattern; + } +} diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java new file mode 100644 index 0000000000..ad330c6e1a --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -0,0 +1,21 @@ +package blackjack.domain.participant; + +import blackjack.domain.carddeck.Card; +import java.util.Collections; +import java.util.List; + +public class Dealer extends Participant { + + private static final int LIMIT_SCORE = 17; + + public Dealer() { + } + + public boolean isOverThenLimitScore() { + return getScoreToInt() >= LIMIT_SCORE; + } + + public List getInitCard() { + return Collections.singletonList(getCards().get(0)); + } +} diff --git a/src/main/java/blackjack/domain/participant/Name.java b/src/main/java/blackjack/domain/participant/Name.java new file mode 100644 index 0000000000..8c91e516b6 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Name.java @@ -0,0 +1,46 @@ +package blackjack.domain.participant; + +import java.util.Objects; + +public class Name { + + private static final String BLANK = " "; + private final String value; + + public Name(final String value) { + this.value = value; + validateNull(this.value); + validateBlank(this.value); + } + + private void validateNull(final String name) { + Objects.requireNonNull(name, "이름은 null 일수 없습니다."); + } + + private void validateBlank(final String name) { + if (name.isEmpty() || name.contains(BLANK)) { + throw new IllegalArgumentException("이름은 공백을 포함할 수 없습니다."); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Name name1 = (Name) o; + return Objects.equals(value, name1.value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + public String getValue() { + return this.value; + } +} diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java new file mode 100644 index 0000000000..7547fb2968 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -0,0 +1,53 @@ +package blackjack.domain.participant; + +import blackjack.domain.carddeck.Card; +import blackjack.domain.carddeck.CardDeck; +import blackjack.domain.participant.state.Init; +import blackjack.domain.participant.state.Score; +import blackjack.domain.participant.state.State; +import java.util.Collections; +import java.util.List; + +public abstract class Participant { + + protected State state; + + protected Participant() { + } + + public void initDraw(final CardDeck cardDeck) { + this.state = Init.draw(cardDeck.draw(), cardDeck.draw()); + } + + public void draw(final Card card) { + this.state = this.state.draw(card); + } + + public void stay() { + this.state = this.state.stay(); + } + + public boolean isFinished() { + return this.state.isFinished(); + } + + public Score score() { + return this.state.score(); + } + + public int getScoreToInt() { + return score().getValue(); + } + + public List getCards() { + return Collections.unmodifiableList(this.state.cards()); + } + + public boolean isBlackjack() { + return score().isBlackjack(); + } + + public boolean isBust() { + return score().isBust(); + } +} diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java new file mode 100644 index 0000000000..5b2e3b845c --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -0,0 +1,20 @@ +package blackjack.domain.participant; + +import blackjack.domain.Result; + +public class Player extends Participant { + + private final Name name; + + public Player(final Name name) { + this.name = name; + } + + public Result judgeByDealerState(final Dealer dealer) { + return this.state.calculatePlayerResult(dealer.state); + } + + public String getName() { + return this.name.getValue(); + } +} diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java new file mode 100644 index 0000000000..f696fc628d --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -0,0 +1,85 @@ +package blackjack.domain.participant; + +import blackjack.domain.carddeck.Card; +import blackjack.domain.carddeck.CardDeck; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.stream.Collectors; + +public class Players { + + public static final int MAX_PLAYER = 7; + + private final Queue players; + + public Players(final List names) { + this.players = convertToPlayers(names); + validatePlayerCount(this.players); + validateDuplicate(this.players); + } + + private Queue convertToPlayers(final List names) { + Queue players = new LinkedList<>(); + for (String name : names) { + players.offer(new Player(new Name(name))); + } + return players; + } + + private void validatePlayerCount(final Queue players) { + if (players.size() > MAX_PLAYER) { + throw new IllegalArgumentException("최대 참여 플레이어는 " + MAX_PLAYER + "명입니다."); + } + } + + private void validateDuplicate(final Queue players) { + int setSize = this.players.stream() + .map(Player::getName) + .collect(Collectors.toSet()) + .size(); + if (setSize != players.size()) { + throw new IllegalArgumentException("중복된 이름은 사용할 수 없습니다."); + } + } + + public void initDraw(final CardDeck cardDeck) { + this.players.forEach(player -> player.initDraw(cardDeck)); + } + + public boolean isAllPlayerFinished() { + return this.players + .stream() + .filter(Player::isFinished) + .count() == this.players.size(); + } + + public void passTurnToNextPlayer() { + this.players.offer(this.players.poll()); + } + + public void drawFirstOrderPlayer(final Card card) { + getFirstOrderPlayer().draw(card); + } + + public void stayFirstOrderPlayer() { + getFirstOrderPlayer().stay(); + } + + public Player getFirstOrderPlayer() { + return this.players.peek(); + } + + public boolean isFinishedCurrentPlayer() { + return getFirstOrderPlayer().isFinished(); + } + + public String getFirstOrderPlayerName() { + return getFirstOrderPlayer().getName(); + } + + public List toList() { + return new ArrayList<>(this.players); + } +} diff --git a/src/main/java/blackjack/domain/participant/state/AfterInit.java b/src/main/java/blackjack/domain/participant/state/AfterInit.java new file mode 100644 index 0000000000..2d59826877 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/state/AfterInit.java @@ -0,0 +1,23 @@ +package blackjack.domain.participant.state; + +import blackjack.domain.carddeck.Card; +import java.util.List; + +public abstract class AfterInit implements State { + + protected final Hand hand; + + public AfterInit(final Hand hand) { + this.hand = hand; + } + + @Override + public List cards() { + return this.hand.getCards(); + } + + @Override + public Score score() { + return this.hand.score(); + } +} diff --git a/src/main/java/blackjack/domain/participant/state/Blackjack.java b/src/main/java/blackjack/domain/participant/state/Blackjack.java new file mode 100644 index 0000000000..77fe1edb52 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/state/Blackjack.java @@ -0,0 +1,18 @@ +package blackjack.domain.participant.state; + +import blackjack.domain.Result; + +public class Blackjack extends Finished { + + public Blackjack(final Hand hand) { + super(hand); + } + + @Override + public Result calculatePlayerResult(final State dealerState) { + if (dealerState.score().isBlackjack()) { + return Result.DRAW; + } + return Result.WIN; + } +} diff --git a/src/main/java/blackjack/domain/participant/state/Bust.java b/src/main/java/blackjack/domain/participant/state/Bust.java new file mode 100644 index 0000000000..16c9569dcd --- /dev/null +++ b/src/main/java/blackjack/domain/participant/state/Bust.java @@ -0,0 +1,15 @@ +package blackjack.domain.participant.state; + +import blackjack.domain.Result; + +public class Bust extends Finished { + + public Bust(final Hand hand) { + super(hand); + } + + @Override + public Result calculatePlayerResult(State dealerState) { + return Result.LOSE; + } +} diff --git a/src/main/java/blackjack/domain/participant/state/Finished.java b/src/main/java/blackjack/domain/participant/state/Finished.java new file mode 100644 index 0000000000..e98f7c4f8b --- /dev/null +++ b/src/main/java/blackjack/domain/participant/state/Finished.java @@ -0,0 +1,25 @@ +package blackjack.domain.participant.state; + +import blackjack.domain.carddeck.Card; + +public abstract class Finished extends AfterInit { + + public Finished(final Hand hand) { + super(hand); + } + + @Override + public State draw(Card card) { + throw new IllegalStateException(); + } + + @Override + public State stay() { + throw new IllegalStateException(); + } + + @Override + public boolean isFinished() { + return true; + } +} diff --git a/src/main/java/blackjack/domain/participant/state/Hand.java b/src/main/java/blackjack/domain/participant/state/Hand.java new file mode 100644 index 0000000000..791ba84e66 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/state/Hand.java @@ -0,0 +1,58 @@ +package blackjack.domain.participant.state; + +import blackjack.domain.carddeck.Card; +import java.util.ArrayList; +import java.util.List; + +public class Hand { + + private final List cards; + + public Hand(final List cards) { + this.cards = new ArrayList<>(cards); + } + + public void addCard(final Card card) { + this.cards.add(card); + } + + public Score score() { + Score score = sumScores(); + int countOfAce = getCountOfAce(); + for (int i = 0; i < countOfAce; i++) { + score = score.reduceScoreIfBust(); + } + return score; + } + + private Score sumScores() { + return new Score(this.cards + .stream() + .mapToInt(Card::getScore) + .sum() + ); + } + + public int getScoreToInt() { + return score().getValue(); + } + + public boolean isBlackjack() { + return cards.size() == 2 && score().isBlackjack(); + } + + public boolean isBust() { + return score().isBust(); + } + + private int getCountOfAce() { + return (int) this.cards + .stream() + .filter(Card::isAce) + .count(); + } + + public List getCards() { + return new ArrayList<>(this.cards); + } +} diff --git a/src/main/java/blackjack/domain/participant/state/Hit.java b/src/main/java/blackjack/domain/participant/state/Hit.java new file mode 100644 index 0000000000..22039b4eaa --- /dev/null +++ b/src/main/java/blackjack/domain/participant/state/Hit.java @@ -0,0 +1,22 @@ +package blackjack.domain.participant.state; + +import blackjack.domain.carddeck.Card; + +public class Hit extends Running { + + public Hit(final Hand hand) { + super(hand); + } + + public State draw(final Card card) { + this.hand.addCard(card); + if (this.hand.isBust()) { + return new Bust(this.hand); + } + return new Hit(this.hand); + } + + public State stay() { + return new Stay(this.hand); + } +} diff --git a/src/main/java/blackjack/domain/participant/state/Init.java b/src/main/java/blackjack/domain/participant/state/Init.java new file mode 100644 index 0000000000..545a41962a --- /dev/null +++ b/src/main/java/blackjack/domain/participant/state/Init.java @@ -0,0 +1,15 @@ +package blackjack.domain.participant.state; + +import blackjack.domain.carddeck.Card; +import java.util.Arrays; + +public class Init { + + public static State draw(final Card firstCard, final Card secondCard) { + Hand hand = new Hand(Arrays.asList(firstCard, secondCard)); + if (hand.isBlackjack()) { + return new Blackjack(hand); + } + return new Hit(hand); + } +} diff --git a/src/main/java/blackjack/domain/participant/state/Running.java b/src/main/java/blackjack/domain/participant/state/Running.java new file mode 100644 index 0000000000..477fed38be --- /dev/null +++ b/src/main/java/blackjack/domain/participant/state/Running.java @@ -0,0 +1,20 @@ +package blackjack.domain.participant.state; + +import blackjack.domain.Result; + +public abstract class Running extends AfterInit { + + public Running(final Hand hand) { + super(hand); + } + + @Override + public boolean isFinished() { + return false; + } + + @Override + public Result calculatePlayerResult(final State state) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/blackjack/domain/participant/state/Score.java b/src/main/java/blackjack/domain/participant/state/Score.java new file mode 100644 index 0000000000..814f8091d8 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/state/Score.java @@ -0,0 +1,44 @@ +package blackjack.domain.participant.state; + +import blackjack.domain.Result; + +public class Score { + + private static final int BLACKJACK = 21; + private static final int TEN = 10; + + private final int value; + + public Score(final int value) { + this.value = value; + } + + public Score reduceScoreIfBust() { + if (this.isBust()) { + return new Score(this.value - TEN); + } + return this; + } + + public boolean isBust() { + return this.value > BLACKJACK; + } + + public boolean isBlackjack() { + return this.value == BLACKJACK; + } + + public Result compare(final Score score) { + if (this.value > score.value) { + return Result.WIN; + } + if (this.value < score.value) { + return Result.LOSE; + } + return Result.DRAW; + } + + public int getValue() { + return this.value; + } +} diff --git a/src/main/java/blackjack/domain/participant/state/State.java b/src/main/java/blackjack/domain/participant/state/State.java new file mode 100644 index 0000000000..e977afb3d2 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/state/State.java @@ -0,0 +1,20 @@ +package blackjack.domain.participant.state; + +import blackjack.domain.Result; +import blackjack.domain.carddeck.Card; +import java.util.List; + +public interface State { + + State draw(final Card card); + + State stay(); + + List cards(); + + boolean isFinished(); + + Score score(); + + Result calculatePlayerResult(final State state); +} diff --git a/src/main/java/blackjack/domain/participant/state/Stay.java b/src/main/java/blackjack/domain/participant/state/Stay.java new file mode 100644 index 0000000000..898b94e6af --- /dev/null +++ b/src/main/java/blackjack/domain/participant/state/Stay.java @@ -0,0 +1,21 @@ +package blackjack.domain.participant.state; + +import blackjack.domain.Result; + +public class Stay extends Finished { + + public Stay(final Hand hand) { + super(hand); + } + + @Override + public Result calculatePlayerResult(State dealerState) { + if (dealerState.score().isBlackjack()) { + return Result.LOSE; + } + if (dealerState.score().isBust()) { + return Result.WIN; + } + return this.score().compare(dealerState.score()); + } +} diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java new file mode 100644 index 0000000000..9d492dc428 --- /dev/null +++ b/src/main/java/blackjack/view/InputView.java @@ -0,0 +1,35 @@ +package blackjack.view; + +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +public class InputView { + + private final static String NEW_LINE = System.lineSeparator(); + private final static Scanner SCANNER = new Scanner(System.in); + + + public static List getPlayerNames() { + System.out.println("게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리)"); + return splitNames(SCANNER.nextLine()); + } + + private static List splitNames(final String inputString) { + return Arrays.asList(inputString.split(",")); + } + + public static boolean getHitOrStay(final String name) { + System.out.printf("%s(은)는 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)", name); + System.out.print(NEW_LINE); + String input = SCANNER.nextLine().toLowerCase(); + validateHitOrStay(input); + return input.equals("y"); + } + + private static void validateHitOrStay(final String input) { + if (!input.equals("y") && !input.equals("n")) { + throw new IllegalArgumentException("요청은 y(Y) 또는 n(N) 이어야 합니다."); + } + } +} diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java new file mode 100644 index 0000000000..a9497b63bf --- /dev/null +++ b/src/main/java/blackjack/view/OutputView.java @@ -0,0 +1,92 @@ +package blackjack.view; + +import static java.util.stream.Collectors.joining; + +import blackjack.view.dto.CardDto; +import blackjack.view.dto.ParticipantDto; +import blackjack.view.dto.ResultDto; +import java.util.List; + +public class OutputView { + + private static final String NEW_LINE = System.lineSeparator(); + private static final String DELIMITER = ", "; + private static final String INIT_GAME_FORMAT = "%s와 %s에게 2장을 나누었습니다."; + private static final String HAND_FORMAT = "%s 카드: %s"; + private static final String SCORE_FORMAT = " - 결과: %d"; + private static final String PARTICIPANT_BURST_FORMAT = "%s(은)는 21점을 넘어 버스트 되었습니다."; + private static final String DEALER_HIT_IF_UNDER_LIMIT_SCORE = "딜러는 16이하라 한장의 카드를 더 받았습니다."; + private static final String TOTAL_GAME_RESULT_MESSAGE = "## 최종 승패"; + private static final String TOTAL_GAME_RESULT_FORMAT = "%s: %s"; + + public static void printInitStatuses(final ParticipantDto dealer, + final List players) { + System.out.print(NEW_LINE); + System.out.printf(INIT_GAME_FORMAT, dealer.getName(), getPlayerNames(players)); + System.out.print(NEW_LINE); + printInitDealerHand(dealer); + players.forEach(OutputView::printPlayerStatus); + System.out.print(NEW_LINE); + } + + private static String getPlayerNames(final List players) { + return players.stream() + .map(ParticipantDto::getName) + .collect(joining(DELIMITER)); + } + + private static void printInitDealerHand(final ParticipantDto dealer) { + System.out.printf(HAND_FORMAT, dealer.getName(), dealer.getCards().get(0).getName()); + System.out.print(NEW_LINE); + } + + public static void printPlayerStatus(final ParticipantDto player) { + System.out.printf(HAND_FORMAT, player.getName(), player.getCards() + .stream() + .map(CardDto::getName) + .collect(joining(DELIMITER)) + ); + System.out.print(NEW_LINE); + } + + public static void printStatusWithScore(ParticipantDto participant) { + System.out.printf(HAND_FORMAT, participant.getName(), participant.getCards() + .stream() + .map(CardDto::getName) + .collect(joining(DELIMITER)) + ); + System.out.printf(SCORE_FORMAT, participant.getScore()); + System.out.print(NEW_LINE); + } + + public static void printDealerHit() { + System.out.println(DEALER_HIT_IF_UNDER_LIMIT_SCORE); + } + + private static void printDealerHandWithScore(final ParticipantDto dealer) { + System.out.printf(HAND_FORMAT, dealer.getName(), dealer.getCards() + .stream() + .map(CardDto::getName) + .collect(joining(DELIMITER)) + ); + System.out.printf(SCORE_FORMAT, dealer.getScore()); + System.out.print(NEW_LINE); + } + + public static void printBlackjackResult(final ResultDto dealerResult, + final List playerResultDtos) { + System.out.print(NEW_LINE); + System.out.println(TOTAL_GAME_RESULT_MESSAGE); + printResult(dealerResult); + playerResultDtos.forEach(OutputView::printResult); + } + + private static void printResult(final ResultDto result) { + System.out.printf(TOTAL_GAME_RESULT_FORMAT, result.getName(), result.getResult()); + System.out.print(NEW_LINE); + } + + public static void printNewLine() { + System.out.print(NEW_LINE); + } +} diff --git a/src/main/java/blackjack/view/dto/CardDto.java b/src/main/java/blackjack/view/dto/CardDto.java new file mode 100644 index 0000000000..9241e05e91 --- /dev/null +++ b/src/main/java/blackjack/view/dto/CardDto.java @@ -0,0 +1,14 @@ +package blackjack.view.dto; + +public class CardDto { + + private final String name; + + public CardDto(final String name) { + this.name = name; + } + + public String getName() { + return this.name; + } +} diff --git a/src/main/java/blackjack/view/dto/ParticipantDto.java b/src/main/java/blackjack/view/dto/ParticipantDto.java new file mode 100644 index 0000000000..61f1ee6a3a --- /dev/null +++ b/src/main/java/blackjack/view/dto/ParticipantDto.java @@ -0,0 +1,34 @@ +package blackjack.view.dto; + +import java.util.List; + +public class ParticipantDto { + + public static final String DEALER_NAME = "딜러"; + + private final String name; + private final List cards; + private final int score; + + public ParticipantDto(final List cards, final int score) { + this(DEALER_NAME, cards, score); + } + + public ParticipantDto(final String name, final List cards, final int score) { + this.name = name; + this.cards = cards; + this.score = score; + } + + public String getName() { + return this.name; + } + + public List getCards() { + return this.cards; + } + + public int getScore() { + return this.score; + } +} diff --git a/src/main/java/blackjack/view/dto/ResultDto.java b/src/main/java/blackjack/view/dto/ResultDto.java new file mode 100644 index 0000000000..7a0f3b9e24 --- /dev/null +++ b/src/main/java/blackjack/view/dto/ResultDto.java @@ -0,0 +1,26 @@ +package blackjack.view.dto; + +public class ResultDto { + + public static final String DEALER_NAME = "딜러"; + + private final String name; + private final String result; + + public ResultDto(final String result) { + this(DEALER_NAME, result); + } + + public ResultDto(final String name, final String result) { + this.name = name; + this.result = result; + } + + public String getName() { + return this.name; + } + + public String getResult() { + return this.result; + } +} diff --git a/src/main/java/empty.txt b/src/main/java/empty.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/rentcar/abstractcar/Avante.java b/src/main/java/rentcar/abstractcar/Avante.java new file mode 100644 index 0000000000..09dd96d053 --- /dev/null +++ b/src/main/java/rentcar/abstractcar/Avante.java @@ -0,0 +1,20 @@ +package rentcar.abstractcar; + +public class Avante extends Car { + + private final double tripDistance; + + public Avante(final double tripDistance) { + this.tripDistance = tripDistance; + } + + @Override + double getDistancePerLiter() { + return 15; + } + + @Override + double getTripDistance() { + return this.tripDistance; + } +} diff --git a/src/main/java/rentcar/abstractcar/Car.java b/src/main/java/rentcar/abstractcar/Car.java new file mode 100644 index 0000000000..5744bfe4c8 --- /dev/null +++ b/src/main/java/rentcar/abstractcar/Car.java @@ -0,0 +1,17 @@ +package rentcar.abstractcar; + +public abstract class Car { + + abstract double getDistancePerLiter(); + + abstract double getTripDistance(); + + double getChargeQuantity() { + return getTripDistance() / getDistancePerLiter(); + } + + public String getName() { + return this.getClass().getSimpleName(); + } + +} \ No newline at end of file diff --git a/src/main/java/rentcar/abstractcar/K5.java b/src/main/java/rentcar/abstractcar/K5.java new file mode 100644 index 0000000000..924b8a1255 --- /dev/null +++ b/src/main/java/rentcar/abstractcar/K5.java @@ -0,0 +1,20 @@ +package rentcar.abstractcar; + +public class K5 extends Car { + + private final double tripDistance; + + public K5(final double tripDistance) { + this.tripDistance = tripDistance; + } + + @Override + double getDistancePerLiter() { + return 13; + } + + @Override + double getTripDistance() { + return this.tripDistance; + } +} diff --git a/src/main/java/rentcar/abstractcar/RentCompany.java b/src/main/java/rentcar/abstractcar/RentCompany.java new file mode 100644 index 0000000000..05bfc73839 --- /dev/null +++ b/src/main/java/rentcar/abstractcar/RentCompany.java @@ -0,0 +1,32 @@ +package rentcar.abstractcar; + +import java.util.ArrayList; +import java.util.List; + +public class RentCompany { + + private static final String REPORT_FORMAT = + "%s : %.0f리터" + System.getProperty("line.separator"); + + private final List cars; + + private RentCompany() { + this.cars = new ArrayList<>(); + } + + public static RentCompany create() { + return new RentCompany(); + } + + public void addCar(final Car car) { + this.cars.add(car); + } + + public String generateReport() { + StringBuilder sb = new StringBuilder(); + for (Car car : this.cars) { + sb.append(String.format(REPORT_FORMAT, car.getName(), car.getChargeQuantity())); + } + return sb.toString(); + } +} diff --git a/src/main/java/rentcar/abstractcar/Sonata.java b/src/main/java/rentcar/abstractcar/Sonata.java new file mode 100644 index 0000000000..d39924ba29 --- /dev/null +++ b/src/main/java/rentcar/abstractcar/Sonata.java @@ -0,0 +1,20 @@ +package rentcar.abstractcar; + +public class Sonata extends Car { + + private final double tripDistance; + + public Sonata(final double tripDistance) { + this.tripDistance = tripDistance; + } + + @Override + double getDistancePerLiter() { + return 10; + } + + @Override + double getTripDistance() { + return this.tripDistance; + } +} diff --git a/src/main/java/rentcar/interfacecar/Avante.java b/src/main/java/rentcar/interfacecar/Avante.java new file mode 100644 index 0000000000..0312e7ae75 --- /dev/null +++ b/src/main/java/rentcar/interfacecar/Avante.java @@ -0,0 +1,20 @@ +package rentcar.interfacecar; + +public class Avante implements Car { + + private final double tripDistance; + + public Avante(final double tripDistance) { + this.tripDistance = tripDistance; + } + + @Override + public double getDistancePerLiter() { + return 15; + } + + @Override + public double getTripDistance() { + return this.tripDistance; + } +} diff --git a/src/main/java/rentcar/interfacecar/Car.java b/src/main/java/rentcar/interfacecar/Car.java new file mode 100644 index 0000000000..552c1c9e66 --- /dev/null +++ b/src/main/java/rentcar/interfacecar/Car.java @@ -0,0 +1,16 @@ +package rentcar.interfacecar; + +public interface Car { + + double getDistancePerLiter(); + + double getTripDistance(); + + default double getChargeQuantity() { + return getTripDistance() / getDistancePerLiter(); + } + + default String getName() { + return this.getClass().getSimpleName(); + } +} \ No newline at end of file diff --git a/src/main/java/rentcar/interfacecar/K5.java b/src/main/java/rentcar/interfacecar/K5.java new file mode 100644 index 0000000000..9fa4318def --- /dev/null +++ b/src/main/java/rentcar/interfacecar/K5.java @@ -0,0 +1,20 @@ +package rentcar.interfacecar; + +public class K5 implements Car { + + private final double tripDistance; + + public K5(final double tripDistance) { + this.tripDistance = tripDistance; + } + + @Override + public double getDistancePerLiter() { + return 13; + } + + @Override + public double getTripDistance() { + return this.tripDistance; + } +} diff --git a/src/main/java/rentcar/interfacecar/RentCompany.java b/src/main/java/rentcar/interfacecar/RentCompany.java new file mode 100644 index 0000000000..f0a2e98790 --- /dev/null +++ b/src/main/java/rentcar/interfacecar/RentCompany.java @@ -0,0 +1,32 @@ +package rentcar.interfacecar; + +import java.util.ArrayList; +import java.util.List; + +public class RentCompany { + + private static final String REPORT_FORMAT = + "%s : %.0f리터" + System.getProperty("line.separator"); + + private final List cars; + + private RentCompany() { + this.cars = new ArrayList<>(); + } + + public static RentCompany create() { + return new RentCompany(); + } + + public void addCar(final Car car) { + this.cars.add(car); + } + + public String generateReport() { + StringBuilder sb = new StringBuilder(); + for (Car car : this.cars) { + sb.append(String.format(REPORT_FORMAT, car.getName(), car.getChargeQuantity())); + } + return sb.toString(); + } +} diff --git a/src/main/java/rentcar/interfacecar/Sonata.java b/src/main/java/rentcar/interfacecar/Sonata.java new file mode 100644 index 0000000000..c49ef07505 --- /dev/null +++ b/src/main/java/rentcar/interfacecar/Sonata.java @@ -0,0 +1,20 @@ +package rentcar.interfacecar; + +public class Sonata implements Car { + + private final double tripDistance; + + public Sonata(final double tripDistance) { + this.tripDistance = tripDistance; + } + + @Override + public double getDistancePerLiter() { + return 10; + } + + @Override + public double getTripDistance() { + return this.tripDistance; + } +} diff --git a/src/test/java/blackjack/domain/BlackjackManagerTest.java b/src/test/java/blackjack/domain/BlackjackManagerTest.java new file mode 100644 index 0000000000..b4303776a3 --- /dev/null +++ b/src/test/java/blackjack/domain/BlackjackManagerTest.java @@ -0,0 +1,128 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.domain.carddeck.Card; +import blackjack.domain.carddeck.CardDeck; +import blackjack.domain.carddeck.Number; +import blackjack.domain.carddeck.Pattern; +import blackjack.domain.participant.Dealer; +import blackjack.domain.participant.Players; +import java.util.Arrays; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class BlackjackManagerTest { + + private Dealer dealer; + private Players players; + private BlackjackManager blackjackManager; + + @BeforeEach + void setUp() { + this.dealer = new Dealer(); + this.players = new Players(Arrays.asList("pobi", "jason")); + this.blackjackManager = new BlackjackManager( + getDrawTestCardDeck(), + this.dealer, + this.players + ); + } + + private CardDeck getDrawTestCardDeck() { + return CardDeck.customDeck(Arrays.asList( + Card.valueOf(Pattern.HEART, Number.SIX), + Card.valueOf(Pattern.HEART, Number.TEN), + Card.valueOf(Pattern.HEART, Number.JACK), + Card.valueOf(Pattern.HEART, Number.TEN), + Card.valueOf(Pattern.HEART, Number.QUEEN), + Card.valueOf(Pattern.HEART, Number.KING), + Card.valueOf(Pattern.DIAMOND, Number.KING) + )); + } + + @Test + @DisplayName("각 플레이어가 초기 2장씩 소지한다.") + void testAllPlayersGetTwoCards() { + this.blackjackManager.initDrawCards(); + + assertThat(this.players + .toList() + .stream() + .filter(player -> player.getCards().size() == 2) + .count()) + .isEqualTo(2); + } + + @Test + @DisplayName("한 명의 플레이어 카드뽑기 완료 테스트") + void testOnePlayerCompleteHit() { + this.blackjackManager.initDrawCards(); + this.blackjackManager.hitOrStayCurrentPlayer(true); + assertThat(this.blackjackManager.isFinishedCurrentPlayer()).isTrue(); + } + + @Test + @DisplayName("한 명의 플레이어가 stay 상태 변화 완료") + void testOnePlayerCompleteToStay() { + this.blackjackManager.initDrawCards(); + this.blackjackManager.hitOrStayCurrentPlayer(false); + assertThat(this.blackjackManager.isFinishedCurrentPlayer()).isTrue(); + } + + @Test + @DisplayName("플레이어 턴 넘기기 완료") + void testPassTurnToNextPlayer() { + assertThat(this.blackjackManager.getCurrentPlayerName()).isEqualTo("pobi"); + this.blackjackManager.passTurnToNextPlayer(); + assertThat(this.blackjackManager.getCurrentPlayerName()).isEqualTo("jason"); + } + + @Test + @DisplayName("한 플레이어의 차례가 끝났는지 확인 테스트") + void testOnePlayerFinished() { + this.blackjackManager.initDrawCards(); + this.blackjackManager.hitOrStayCurrentPlayer(true); + assertThat(this.blackjackManager.isFinishedCurrentPlayer()).isTrue(); + } + + @Test + @DisplayName("전체 플레이어의 차례가 끝났는지 확인 테스트") + void testAllPlayersFinished() { + this.blackjackManager.initDrawCards(); + this.blackjackManager.hitOrStayCurrentPlayer(false); + this.blackjackManager.passTurnToNextPlayer(); + this.blackjackManager.hitOrStayCurrentPlayer(false); + assertThat(this.blackjackManager.isFinishedAllPlayers()).isTrue(); + } + + @Test + @DisplayName("딜러 카드 뽑기 테스트") + void testDealerDraw() { + this.blackjackManager.initDrawCards(); + assertThat(this.blackjackManager.getDealer().getScoreToInt()).isEqualTo(16); + this.blackjackManager.hitDealer(); + assertThat(this.blackjackManager.getDealer().getScoreToInt()).isEqualTo(26); + } + + @Test + @DisplayName("딜러 Stay 상태변화 테스트") + void testDealerToStay() { + this.blackjackManager.initDrawCards(); + assertThat(this.blackjackManager.isFinishedDealer()).isFalse(); + this.blackjackManager.stayDealer(); + assertThat(this.blackjackManager.isFinishedDealer()).isTrue(); + } + + @Test + @DisplayName("딜러 카드뽑기 후 17점 이상시 상태전환 테스트") + void testDealerToStayIfScoreOverThenLimit() { + this.blackjackManager.initDrawCards(); + assertThat(this.blackjackManager.isFinishedDealer()).isFalse(); + assertThat(this.blackjackManager.isDealerScoreOverThenLimit()).isFalse(); + this.blackjackManager.hitDealer(); + assertThat(this.blackjackManager.isFinishedDealer()).isTrue(); + assertThat(this.blackjackManager.isDealerScoreOverThenLimit()).isTrue(); + } +} diff --git a/src/test/java/blackjack/domain/ResultTest.java b/src/test/java/blackjack/domain/ResultTest.java new file mode 100644 index 0000000000..f517d0901f --- /dev/null +++ b/src/test/java/blackjack/domain/ResultTest.java @@ -0,0 +1,74 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.domain.carddeck.Card; +import blackjack.domain.carddeck.CardDeck; +import blackjack.domain.carddeck.Number; +import blackjack.domain.carddeck.Pattern; +import blackjack.domain.participant.Dealer; +import blackjack.domain.participant.Player; +import blackjack.domain.participant.Players; +import java.util.Arrays; +import java.util.Collections; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class ResultTest { + + private BlackjackManager blackjackManager; + private Dealer dealer; + + @BeforeEach + void setUp() { + CardDeck cardDeck = getDrawTestCardDeck(); + this.dealer = new Dealer(); + Players players = new Players(Collections.singletonList("미립")); + this.blackjackManager = new BlackjackManager(cardDeck, this.dealer, players); + this.blackjackManager.initDrawCards(); + } + + private CardDeck getDrawTestCardDeck() { + return CardDeck.customDeck(Arrays.asList( + Card.valueOf(Pattern.HEART, Number.SEVEN), + Card.valueOf(Pattern.HEART, Number.TEN), + Card.valueOf(Pattern.HEART, Number.FOUR), + Card.valueOf(Pattern.HEART, Number.FIVE), + Card.valueOf(Pattern.DIAMOND, Number.EIGHT), + Card.valueOf(Pattern.DIAMOND, Number.TWO) + )); + } + + @Test + @DisplayName("플레이어의 승 / 딜러 패 테스트") + void testPlayerWinAndDealerLose() { + this.blackjackManager.hitOrStayCurrentPlayer(true); + this.blackjackManager.hitOrStayCurrentPlayer(true); + this.blackjackManager.hitOrStayCurrentPlayer(false); + Player player = this.blackjackManager.getCurrentPlayer(); + assertThat(player.judgeByDealerState(this.dealer)).isEqualTo(Result.WIN); + assertThat(player.judgeByDealerState(this.dealer).reverse()).isEqualTo(Result.LOSE); + } + + @Test + @DisplayName("플레이어의 패 / 딜러 승 테스트") + void testPlayerLoseAndDealerWin() { + this.blackjackManager.hitOrStayCurrentPlayer(false); + Player player = this.blackjackManager.getCurrentPlayer(); + assertThat(player.judgeByDealerState(this.dealer)).isEqualTo(Result.LOSE); + assertThat(player.judgeByDealerState(this.dealer).reverse()).isEqualTo(Result.WIN); + } + + @Test + @DisplayName("무승부 테스트") + void testPlayerAndDealerDraw() { + this.blackjackManager.hitOrStayCurrentPlayer(true); + this.blackjackManager.hitOrStayCurrentPlayer(false); + Player player = this.blackjackManager.getCurrentPlayer(); + assertThat(player.judgeByDealerState(this.dealer)).isEqualTo(Result.DRAW); + assertThat(player.judgeByDealerState(this.dealer).reverse()).isEqualTo(Result.DRAW); + } + + +} diff --git a/src/test/java/blackjack/domain/carddeck/CardDeckTest.java b/src/test/java/blackjack/domain/carddeck/CardDeckTest.java new file mode 100644 index 0000000000..63c560e69b --- /dev/null +++ b/src/test/java/blackjack/domain/carddeck/CardDeckTest.java @@ -0,0 +1,75 @@ +package blackjack.domain.carddeck; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.HashSet; +import java.util.NoSuchElementException; +import java.util.Set; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class CardDeckTest { + + private CardDeck cardDeck; + + @BeforeEach + void setUp() { + this.cardDeck = CardDeck.newShuffledDeck(); + } + + @Test + @DisplayName("카드를 한장 뽑는다.") + void testCardDeckDraw() { + assertThat(this.cardDeck.draw()).isInstanceOf(Card.class); + } + + @Test + @DisplayName("카드는 52장이다.") + void testCardDeckSize() { + for (int i = 0; i < 52; i++) { + this.cardDeck.draw(); + } + assertThatThrownBy(this.cardDeck::draw) + .isInstanceOf(NoSuchElementException.class); + } + + @Test + @DisplayName("카드 52장은 중복이 없다.") + void testCardDuplicate() { + Set cards = new HashSet<>(); + for (int i = 0; i < 52; i++) { + cards.add(this.cardDeck.draw()); + } + assertThat(cards).hasSize(52); + } + + @Test + @DisplayName("문양별 카드는 각각 13장씩 존재한다.") + void testCountOfCardPatterns() { + Set cloverCards = new HashSet<>(); + Set spadeCards = new HashSet<>(); + Set heartCards = new HashSet<>(); + Set diamondCards = new HashSet<>(); + + for (int i = 0; i < 52; i++) { + Card card = this.cardDeck.draw(); + compareCardPattern(cloverCards, card, Pattern.CLOVER); + compareCardPattern(spadeCards, card, Pattern.SPADE); + compareCardPattern(heartCards, card, Pattern.HEART); + compareCardPattern(diamondCards, card, Pattern.DIAMOND); + } + + assertThat(cloverCards).hasSize(13); + assertThat(spadeCards).hasSize(13); + assertThat(heartCards).hasSize(13); + assertThat(diamondCards).hasSize(13); + } + + private void compareCardPattern(final Set cards, final Card card, final Pattern pattern) { + if (card.getPatternName().equals(pattern.getPattern())) { + cards.add(card); + } + } +} diff --git a/src/test/java/blackjack/domain/carddeck/CardTest.java b/src/test/java/blackjack/domain/carddeck/CardTest.java new file mode 100644 index 0000000000..86eef7f1d0 --- /dev/null +++ b/src/test/java/blackjack/domain/carddeck/CardTest.java @@ -0,0 +1,29 @@ +package blackjack.domain.carddeck; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class CardTest { + + @Test + @DisplayName("카드캐싱 테스트") + void testCreateCard() { + Card card = Card.valueOf(Pattern.CLOVER, Number.ACE); + + assertThat(card).isEqualTo(Card.valueOf(Pattern.CLOVER, Number.ACE)); + assertThat(card).isNotEqualTo(Card.valueOf(Pattern.HEART, Number.ACE)); + assertThat(card).isNotEqualTo(Card.valueOf(Pattern.CLOVER, Number.KING)); + } + + @Test + @DisplayName("자신이 ACE 카드인지 확인한다.") + void testIsAceCard() { + Card card1 = Card.valueOf(Pattern.CLOVER, Number.ACE); + Card card2 = Card.valueOf(Pattern.CLOVER, Number.TWO); + + assertThat(card1.isAce()).isTrue(); + assertThat(card2.isAce()).isFalse(); + } +} diff --git a/src/test/java/blackjack/domain/carddeck/NumberTest.java b/src/test/java/blackjack/domain/carddeck/NumberTest.java new file mode 100644 index 0000000000..809f2f3965 --- /dev/null +++ b/src/test/java/blackjack/domain/carddeck/NumberTest.java @@ -0,0 +1,27 @@ +package blackjack.domain.carddeck; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class NumberTest { + + @Test + @DisplayName("카드 숫자별 점수 테스트") + void testCarNumberScore() { + assertThat(Number.ACE.getScore()).isEqualTo(11); + assertThat(Number.TWO.getScore()).isEqualTo(2); + assertThat(Number.THREE.getScore()).isEqualTo(3); + assertThat(Number.FOUR.getScore()).isEqualTo(4); + assertThat(Number.FIVE.getScore()).isEqualTo(5); + assertThat(Number.SIX.getScore()).isEqualTo(6); + assertThat(Number.SEVEN.getScore()).isEqualTo(7); + assertThat(Number.EIGHT.getScore()).isEqualTo(8); + assertThat(Number.NINE.getScore()).isEqualTo(9); + assertThat(Number.TEN.getScore()).isEqualTo(10); + assertThat(Number.JACK.getScore()).isEqualTo(10); + assertThat(Number.QUEEN.getScore()).isEqualTo(10); + assertThat(Number.KING.getScore()).isEqualTo(10); + } +} diff --git a/src/test/java/blackjack/domain/carddeck/PatternTest.java b/src/test/java/blackjack/domain/carddeck/PatternTest.java new file mode 100644 index 0000000000..1d204392aa --- /dev/null +++ b/src/test/java/blackjack/domain/carddeck/PatternTest.java @@ -0,0 +1,19 @@ +package blackjack.domain.carddeck; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class PatternTest { + + @Test + @DisplayName("카드 문양별 출력형태 테스트") + void testCardPatternPrintFormat() { + assertThat(Pattern.CLOVER.getPattern()).isEqualTo("클로버"); + assertThat(Pattern.DIAMOND.getPattern()).isEqualTo("다이아몬드"); + assertThat(Pattern.SPADE.getPattern()).isEqualTo("스페이드"); + assertThat(Pattern.HEART.getPattern()).isEqualTo("하트"); + } + +} diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java new file mode 100644 index 0000000000..b16a26058f --- /dev/null +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -0,0 +1,52 @@ +package blackjack.domain.participant; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.domain.carddeck.Card; +import blackjack.domain.carddeck.CardDeck; +import blackjack.domain.carddeck.Number; +import blackjack.domain.carddeck.Pattern; +import java.util.Arrays; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class DealerTest { + + private Dealer dealer; + + @BeforeEach + void setUp() { + this.dealer = new Dealer(); + } + + @Test + @DisplayName("딜러는 총점수 17이상일시 카드 뽑기를 멈춘다.") + void testStopDrawDealerWhenTotalScoreOverSeventeen() { + CardDeck cardDeck = getCustomCardDeck(); + this.dealer.initDraw(cardDeck); + + for (int i = 0; i < 999999; i++) { + while (!this.dealer.isOverThenLimitScore()) { + this.dealer.draw(cardDeck.draw()); + } + assertThat(this.dealer.getScoreToInt()).isEqualTo(17); + } + } + + @Test + @DisplayName("초기 출력을 위한 카드 요청시 첫 1장만 반환한다.") + void testGetInitFirstOneCard() { + this.dealer.initDraw(getCustomCardDeck()); + assertThat(this.dealer.getInitCard()).hasSize(1); + assertThat(this.dealer.getInitCard().get(0).getScore()).isEqualTo(11); + } + + private CardDeck getCustomCardDeck() { + Card firstCard = Card.valueOf(Pattern.HEART, Number.ACE); + Card secondCard = Card.valueOf(Pattern.HEART, Number.SIX); + Card thirdCard = Card.valueOf(Pattern.HEART, Number.TEN); + Card fourthCard = Card.valueOf(Pattern.HEART, Number.KING); + return CardDeck.customDeck(Arrays.asList(firstCard, secondCard, thirdCard, fourthCard)); + } +} diff --git a/src/test/java/blackjack/domain/participant/NameTest.java b/src/test/java/blackjack/domain/participant/NameTest.java new file mode 100644 index 0000000000..2970a2ff28 --- /dev/null +++ b/src/test/java/blackjack/domain/participant/NameTest.java @@ -0,0 +1,34 @@ +package blackjack.domain.participant; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; + +public class NameTest { + + @Test + @DisplayName("이름 생성된다.") + void testCreateName() { + String nameString = "pobi"; + Name name = new Name(nameString); + assertThat(name).isEqualTo(new Name(nameString)); + } + + @ParameterizedTest + @NullSource + void testValidateNull(String name) { + assertThatThrownBy(() -> new Name(name)).isInstanceOf(NullPointerException.class); + } + + @ParameterizedTest + @ValueSource(strings = {"", " ", " "}) + void testCreateName(String name) { + assertThatThrownBy(() -> new Name(name)).isInstanceOf(IllegalArgumentException.class); + } + +} diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java new file mode 100644 index 0000000000..274ae8244e --- /dev/null +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -0,0 +1,23 @@ +package blackjack.domain.participant; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class PlayerTest { + + private Player player; + + @BeforeEach + void setUp() { + this.player = new Player(new Name("pobi")); + } + + @Test + @DisplayName("플레이어 이름 반환 테스트") + void testPlayerName() { + assertThat(this.player.getName()).isEqualTo("pobi"); + } +} diff --git a/src/test/java/blackjack/domain/participant/PlayersTest.java b/src/test/java/blackjack/domain/participant/PlayersTest.java new file mode 100644 index 0000000000..7b448f9abe --- /dev/null +++ b/src/test/java/blackjack/domain/participant/PlayersTest.java @@ -0,0 +1,127 @@ +package blackjack.domain.participant; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import blackjack.domain.BlackjackManager; +import blackjack.domain.carddeck.Card; +import blackjack.domain.carddeck.CardDeck; +import blackjack.domain.carddeck.Number; +import blackjack.domain.carddeck.Pattern; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class PlayersTest { + + @Test + @DisplayName("이름들을 입력받아서 플레이어들을 생성") + void testCreatePlayers() { + List names = Arrays.asList("pobi", "brown", "jason"); + Players players = new Players(names); + assertThat(players.toList()).hasSize(3); + } + + @Test + @DisplayName("중복된 이름 입력시 예외처리") + void testDuplicateException() { + List names = Arrays.asList("pobi", "pobi", "jason"); + assertThatThrownBy(() -> new Players(names)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("NULL 혹은 공백을 입력했을 시 예외처리") + void testNullOrBlankException() { + List blank1 = Collections.singletonList(""); + assertThatThrownBy(() -> new Players(blank1)) + .isInstanceOf(IllegalArgumentException.class); + List blank2 = Collections.singletonList(" "); + assertThatThrownBy(() -> new Players(blank2)) + .isInstanceOf(IllegalArgumentException.class); + List nullList = null; + assertThatThrownBy(() -> new Players(nullList)) + .isInstanceOf(NullPointerException.class); + } + + @Test + @DisplayName("각 플레이어가 초기 2장씩 소지한다.") + void testAllPlayersGetTwoCards() { + List names = Arrays.asList("pobi", "jason"); + Dealer dealer = new Dealer(); + Players players = new Players(names); + BlackjackManager blackjackManager = new BlackjackManager(dealer, players); + blackjackManager.initDrawCards(); + + assertThat(players.toList() + .stream() + .filter(player -> player.getCards().size() == 2) + .count()) + .isEqualTo(2); + } + + @Test + @DisplayName("모든 플레이어가 플레이를 완료했는지 확인한다.") + void testIsAllPlayerPlayedBlackJack() { + List names = Arrays.asList("미립", "현구막"); + Players players = new Players(names); + players.initDraw(getCustomCardDeck()); + + players.drawFirstOrderPlayer(Card.valueOf(Pattern.SPADE, Number.JACK)); + players.passTurnToNextPlayer(); + players.drawFirstOrderPlayer(Card.valueOf(Pattern.DIAMOND, Number.JACK)); + + assertThat(players.isAllPlayerFinished()).isTrue(); + } + + private CardDeck getCustomCardDeck() { + Card firstCard = Card.valueOf(Pattern.HEART, Number.TEN); + Card secondCard = Card.valueOf(Pattern.HEART, Number.KING); + Card thirdCard = Card.valueOf(Pattern.HEART, Number.QUEEN); + Card fourthCard = Card.valueOf(Pattern.HEART, Number.JACK); + return CardDeck.customDeck(Arrays.asList(firstCard, secondCard, thirdCard, fourthCard)); + } + + @Test + @DisplayName("가장 앞 차례 플레이어 턴이 넘어갔는지 확인한다.") + void testIsSuccessPassThePlayerTurn() { + List names = Arrays.asList("미립", "현구막"); + Players players = new Players(names); + players.initDraw(getCustomCardDeck()); + + assertThat(players.getFirstOrderPlayerName()).isEqualTo("미립"); + players.passTurnToNextPlayer(); + assertThat(players.getFirstOrderPlayerName()).isEqualTo("현구막"); + } + + @Test + @DisplayName("가장 앞 차례 플레이어가 카드를 뽑았는지 확인한다.") + void testPlayerDrawCard() { + List name = Collections.singletonList("미립"); + Players players = new Players(name); + players.initDraw(getDrawTestCardDeck()); + + assertThat(players.getFirstOrderPlayer().getScoreToInt()).isEqualTo(12); + players.drawFirstOrderPlayer(Card.valueOf(Pattern.DIAMOND, Number.THREE)); + assertThat(players.getFirstOrderPlayer().getScoreToInt()).isEqualTo(15); + } + + @Test + @DisplayName("가장 앞 차례 플레이어가 Stay 상태로 변화에 성공했는지 확인한다.") + void testPlayerStateToStay() { + List name = Collections.singletonList("미립"); + Players players = new Players(name); + players.initDraw(getDrawTestCardDeck()); + players.stayFirstOrderPlayer(); + + assertThat(players.isFinishedCurrentPlayer()).isTrue(); + } + + private CardDeck getDrawTestCardDeck() { + Card firstCard = Card.valueOf(Pattern.HEART, Number.TWO); + Card secondCard = Card.valueOf(Pattern.HEART, Number.KING); + return CardDeck.customDeck(Arrays.asList(firstCard, secondCard)); + } +} \ No newline at end of file diff --git a/src/test/java/blackjack/domain/participant/state/BlackjackTest.java b/src/test/java/blackjack/domain/participant/state/BlackjackTest.java new file mode 100644 index 0000000000..313a3cc1e5 --- /dev/null +++ b/src/test/java/blackjack/domain/participant/state/BlackjackTest.java @@ -0,0 +1,87 @@ +package blackjack.domain.participant.state; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import blackjack.domain.Result; +import blackjack.domain.carddeck.Card; +import blackjack.domain.carddeck.Number; +import blackjack.domain.carddeck.Pattern; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class BlackjackTest { + + private Card card; + private State blackjack; + + @BeforeEach + void setUp() { + this.card = Card.valueOf(Pattern.HEART, Number.KING); + Card firstCard = Card.valueOf(Pattern.HEART, Number.ACE); + Card secondCard = Card.valueOf(Pattern.DIAMOND, Number.KING); + this.blackjack = Init.draw(firstCard, secondCard); + } + + @Test + @DisplayName("첫 2장을 받은 후 상태가 Blackjack인지 테스트") + void testFromInitDrawToHit() { + assertThat(this.blackjack).isInstanceOf(Blackjack.class); + } + + @Test + @DisplayName("Blackjack 에서 draw 요청시 에러처리") + void testDrawException() { + assertThatThrownBy(() -> this.blackjack.draw(this.card)) + .isInstanceOf(IllegalStateException.class); + } + + @Test + @DisplayName("Blackjack 에서 stay 요청시 에러처리") + void testStayException() { + assertThatThrownBy(() -> this.blackjack.stay()) + .isInstanceOf(IllegalStateException.class); + } + + @Test + @DisplayName("Blackjack 가 종료된 상태임을 확인") + void testIsFinishedTrue() { + assertThat(this.blackjack.isFinished()).isTrue(); + } + + @Test + @DisplayName("Blackjack 에서 카드목록을 요구했을 시 가져갔던 카드개수가 맞는지 확인") + void testHitCards() { + assertThat(this.blackjack.cards()).hasSize(2); + } + + @Test + @DisplayName("플레이어 Blackjack기준 딜러의 Blackjack을 받았을 때 무승부 반환") + void testPlayerBlackjackVersusDealerBlackjack() { + Card firstCard = Card.valueOf(Pattern.DIAMOND, Number.ACE); + Card secondCard = Card.valueOf(Pattern.DIAMOND, Number.TEN); + State dealerBlackjack = Init.draw(firstCard, secondCard); + assertThat(this.blackjack.calculatePlayerResult(dealerBlackjack)).isEqualTo(Result.DRAW); + } + + @Test + @DisplayName("플레이어 Blackjack기준 딜러의 Stay를 받았을 때 승리 반환") + void testPlayerBlackjackVersusDealerStay() { + Card firstCard = Card.valueOf(Pattern.DIAMOND, Number.TWO); + Card secondCard = Card.valueOf(Pattern.DIAMOND, Number.TEN); + State dealerHit = Init.draw(firstCard, secondCard); + State dealerStay = dealerHit.stay(); + assertThat(this.blackjack.calculatePlayerResult(dealerStay)).isEqualTo(Result.WIN); + } + + @Test + @DisplayName("플레이어 Blackjack기준 딜러의 Bust를 받았을 때 승리 반환") + void testPlayerBlackjackVersusDealerBust() { + Card firstCard = Card.valueOf(Pattern.DIAMOND, Number.KING); + Card secondCard = Card.valueOf(Pattern.DIAMOND, Number.TEN); + State dealerHit = Init.draw(firstCard, secondCard); + State dealerBust = dealerHit.draw(Card.valueOf(Pattern.HEART, Number.JACK)); + assertThat(this.blackjack.calculatePlayerResult(dealerBust)).isEqualTo(Result.WIN); + } +} \ No newline at end of file diff --git a/src/test/java/blackjack/domain/participant/state/BustTest.java b/src/test/java/blackjack/domain/participant/state/BustTest.java new file mode 100644 index 0000000000..74fe6f20ee --- /dev/null +++ b/src/test/java/blackjack/domain/participant/state/BustTest.java @@ -0,0 +1,82 @@ +package blackjack.domain.participant.state; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import blackjack.domain.Result; +import blackjack.domain.carddeck.Card; +import blackjack.domain.carddeck.Number; +import blackjack.domain.carddeck.Pattern; +import java.util.Arrays; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class BustTest { + + private State bust; + private Card card; + + @BeforeEach + void setUp() { + Card firstCard = Card.valueOf(Pattern.HEART, Number.TEN); + Card secondCard = Card.valueOf(Pattern.HEART, Number.KING); + this.card = Card.valueOf(Pattern.HEART, Number.FIVE); + this.bust = new Bust(new Hand(Arrays.asList(firstCard, secondCard))); + } + + @Test + @DisplayName("Bust 에서 draw 요청시 에러처리") + void testDrawException() { + assertThatThrownBy(() -> this.bust.draw(this.card)) + .isInstanceOf(IllegalStateException.class); + } + + @Test + @DisplayName("Bust 에서 stay 요청시 에러처리") + void testStayException() { + assertThatThrownBy(() -> this.bust.stay()) + .isInstanceOf(IllegalStateException.class); + } + + @Test + @DisplayName("Bust 가 종료된 상태임을 확인") + void testIsFinishedTrue() { + assertThat(this.bust.isFinished()).isTrue(); + } + + @Test + @DisplayName("Bust 에서 카드목록을 요구했을 시 가져갔던 카드개수가 맞는지 확인") + void testHitCards() { + assertThat(this.bust.cards()).hasSize(2); + } + + @Test + @DisplayName("플레이어 Bust기준 딜러의 Blackjack을 받았을 때 패배 반환") + void testPlayerBlackjackVersusDealerBlackjack() { + Card firstCard = Card.valueOf(Pattern.DIAMOND, Number.ACE); + Card secondCard = Card.valueOf(Pattern.DIAMOND, Number.TEN); + State dealerBlackjack = Init.draw(firstCard, secondCard); + assertThat(this.bust.calculatePlayerResult(dealerBlackjack)).isEqualTo(Result.LOSE); + } + + @Test + @DisplayName("플레이어 Bust기준 딜러의 Stay를 받았을 때 패배 반환") + void testPlayerBlackjackVersusDealerStay() { + Card firstCard = Card.valueOf(Pattern.DIAMOND, Number.TWO); + Card secondCard = Card.valueOf(Pattern.DIAMOND, Number.TEN); + State dealerHit = Init.draw(firstCard, secondCard); + State dealerStay = dealerHit.stay(); + assertThat(this.bust.calculatePlayerResult(dealerStay)).isEqualTo(Result.LOSE); + } + + @Test + @DisplayName("플레이어 Bust기준 딜러의 Bust를 받았을 때 패배 반환") + void testPlayerBlackjackVersusDealerBust() { + Card firstCard = Card.valueOf(Pattern.DIAMOND, Number.KING); + Card secondCard = Card.valueOf(Pattern.DIAMOND, Number.TEN); + State dealerHit = Init.draw(firstCard, secondCard); + State dealerBust = dealerHit.draw(Card.valueOf(Pattern.HEART, Number.JACK)); + assertThat(this.bust.calculatePlayerResult(dealerBust)).isEqualTo(Result.LOSE); + } +} \ No newline at end of file diff --git a/src/test/java/blackjack/domain/participant/state/HandTest.java b/src/test/java/blackjack/domain/participant/state/HandTest.java new file mode 100644 index 0000000000..1a55e02a22 --- /dev/null +++ b/src/test/java/blackjack/domain/participant/state/HandTest.java @@ -0,0 +1,48 @@ +package blackjack.domain.participant.state; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.domain.carddeck.Card; +import blackjack.domain.carddeck.Number; +import blackjack.domain.carddeck.Pattern; +import java.util.Collections; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class HandTest { + + private Hand hand; + + @BeforeEach + void setUp() { + this.hand = new Hand( + Collections.singletonList(Card.valueOf(Pattern.DIAMOND, Number.THREE)) + ); + } + + @Test + @DisplayName("손패에 카드 추가 테스트") + void testAddCardInHand() { + this.hand.addCard(Card.valueOf(Pattern.DIAMOND, Number.TWO)); + assertThat(this.hand.getScoreToInt()).isEqualTo(5); + } + + @Test + @DisplayName("손패 점수 총합 테스트") + void testHandsTotalScore() { + this.hand.addCard(Card.valueOf(Pattern.CLOVER, Number.EIGHT)); + this.hand.addCard(Card.valueOf(Pattern.CLOVER, Number.NINE)); + this.hand.addCard(Card.valueOf(Pattern.CLOVER, Number.QUEEN)); + assertThat(this.hand.getScoreToInt()).isEqualTo(30); + } + + @Test + @DisplayName("SoftAce에서 HardAce로 자동변환 테스트") + void testAceAutoChange() { + this.hand.addCard(Card.valueOf(Pattern.DIAMOND, Number.ACE)); + this.hand.addCard(Card.valueOf(Pattern.CLOVER, Number.ACE)); + this.hand.addCard(Card.valueOf(Pattern.HEART, Number.ACE)); + assertThat(this.hand.getScoreToInt()).isEqualTo(16); + } +} diff --git a/src/test/java/blackjack/domain/participant/state/HitTest.java b/src/test/java/blackjack/domain/participant/state/HitTest.java new file mode 100644 index 0000000000..f34672fef8 --- /dev/null +++ b/src/test/java/blackjack/domain/participant/state/HitTest.java @@ -0,0 +1,62 @@ +package blackjack.domain.participant.state; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.domain.carddeck.Card; +import blackjack.domain.carddeck.Number; +import blackjack.domain.carddeck.Pattern; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class HitTest { + + private Card toBustCard; + private Card toHitCard; + private State hit; + + @BeforeEach + void setUp() { + Card firstCard = Card.valueOf(Pattern.HEART, Number.FIVE); + Card secondCard = Card.valueOf(Pattern.DIAMOND, Number.TEN); + this.hit = Init.draw(firstCard, secondCard); + this.toBustCard = Card.valueOf(Pattern.HEART, Number.KING); + this.toHitCard = Card.valueOf(Pattern.HEART, Number.TWO); + } + + @Test + @DisplayName("첫 2장을 받은 후 상태가 Hit인지 테스트") + void testFromInitDrawToHit() { + assertThat(this.hit).isInstanceOf(Hit.class); + } + + @Test + @DisplayName("Hit 에서 추가로 카드를 받았을 때 합이 21 이하인 경우 Hit이 되는지 테스트") + void testFromHitToHit() { + assertThat(this.hit.draw(this.toHitCard)).isInstanceOf(Hit.class); + } + + @Test + @DisplayName("Hit 에서 추가로 카드를 받았을 때 합이 21을 넘기는 경우 Bust가 되는지 테스트") + void testFromHitToBust() { + assertThat(this.hit.draw(this.toBustCard)).isInstanceOf(Bust.class); + } + + @Test + @DisplayName("Hit 에서 추가로 카드를 받고 싶지 않을 때 Stay가 되는지 테스트") + void testFromHitToStay() { + assertThat(this.hit.stay()).isInstanceOf(Stay.class); + } + + @Test + @DisplayName("Hit 에서 더 이상 뽑을 수 없는 상태인지 질문이 왔을 때 false 를 반환하는지 테스트") + void testIfAskedFinishedThenReplyNo() { + assertThat(this.hit.isFinished()).isFalse(); + } + + @Test + @DisplayName("Hit 에서 카드목록을 요구했을 시 가져갔던 카드개수가 맞는지 확인") + void testHitCards() { + assertThat(this.hit.cards()).hasSize(2); + } +} diff --git a/src/test/java/blackjack/domain/participant/state/InitTest.java b/src/test/java/blackjack/domain/participant/state/InitTest.java new file mode 100644 index 0000000000..67bdd6459e --- /dev/null +++ b/src/test/java/blackjack/domain/participant/state/InitTest.java @@ -0,0 +1,34 @@ +package blackjack.domain.participant.state; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.domain.carddeck.Card; +import blackjack.domain.carddeck.Number; +import blackjack.domain.carddeck.Pattern; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class InitTest { + + @Test + @DisplayName("처음 받은 2장의 카드를 받은 후 Blackjack인지 테스트") + void testInitDrawBlackjack() { + Card firstCard = Card.valueOf(Pattern.DIAMOND, Number.ACE); + Card secondCard = Card.valueOf(Pattern.DIAMOND, Number.TEN); + + State blackjack = Init.draw(firstCard, secondCard); + + assertThat(blackjack).isInstanceOf(Blackjack.class); + } + + @Test + @DisplayName("처음 받은 2장의 카드를 받은 후 Hit인지 테스트") + void testInitDrawHit() { + Card firstCard = Card.valueOf(Pattern.DIAMOND, Number.TWO); + Card secondCard = Card.valueOf(Pattern.DIAMOND, Number.TEN); + + State hit = Init.draw(firstCard, secondCard); + + assertThat(hit).isInstanceOf(Hit.class); + } +} \ No newline at end of file diff --git a/src/test/java/blackjack/domain/participant/state/ScoreTest.java b/src/test/java/blackjack/domain/participant/state/ScoreTest.java new file mode 100644 index 0000000000..98a63ddac4 --- /dev/null +++ b/src/test/java/blackjack/domain/participant/state/ScoreTest.java @@ -0,0 +1,58 @@ +package blackjack.domain.participant.state; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.domain.Result; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class ScoreTest { + + @Test + @DisplayName("점수 생성 테스트") + void testCreateScore() { + Score score = new Score(15); + assertThat(score.getValue()).isEqualTo(15); + } + + @Test + @DisplayName("점수 버스트 테스트") + void testScoreBust() { + Score notBustScore = new Score(21); + assertThat(notBustScore.isBust()).isFalse(); + + Score bustScore = new Score(22); + assertThat(bustScore.isBust()).isTrue(); + } + + @Test + @DisplayName("점수 블랙잭 테스트") + void testScoreBlackjack() { + Score notBlackjackScore = new Score(20); + assertThat(notBlackjackScore.isBlackjack()).isFalse(); + + Score blackjackScore = new Score(21); + assertThat(blackjackScore.isBlackjack()).isTrue(); + } + + @Test + @DisplayName("점수 버스트일 경우 줄이기 테스트") + void testReduceScoreIfBust() { + Score score = new Score(25); + assertThat(score.isBust()).isTrue(); + assertThat(score.reduceScoreIfBust().isBust()).isFalse(); + } + + @Test + @DisplayName("점수 비교 테스트") + void testCompareScore() { + Score compareScore = new Score(17); + Score firstScore = new Score(15); + Score secondScore = new Score(19); + Score thirdScore = new Score(17); + + assertThat(compareScore.compare(firstScore)).isEqualTo(Result.WIN); + assertThat(compareScore.compare(secondScore)).isEqualTo(Result.LOSE); + assertThat(compareScore.compare(thirdScore)).isEqualTo(Result.DRAW); + } +} \ No newline at end of file diff --git a/src/test/java/blackjack/domain/participant/state/StayTest.java b/src/test/java/blackjack/domain/participant/state/StayTest.java new file mode 100644 index 0000000000..95cfe74a3f --- /dev/null +++ b/src/test/java/blackjack/domain/participant/state/StayTest.java @@ -0,0 +1,92 @@ +package blackjack.domain.participant.state; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import blackjack.domain.Result; +import blackjack.domain.carddeck.Card; +import blackjack.domain.carddeck.Number; +import blackjack.domain.carddeck.Pattern; +import java.util.Collections; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class StayTest { + + private State stay; + private Card card; + + @BeforeEach + void setUp() { + this.card = Card.valueOf(Pattern.HEART, Number.FIVE); + this.stay = new Stay(new Hand(Collections.singletonList(this.card))); + } + + @Test + @DisplayName("Stay 에서 draw 요청시 에러처리") + void testDrawException() { + assertThatThrownBy(() -> this.stay.draw(this.card)) + .isInstanceOf(IllegalStateException.class); + } + + @Test + @DisplayName("Stay 에서 stay 요청시 에러처리") + void testStayException() { + assertThatThrownBy(() -> this.stay.stay()) + .isInstanceOf(IllegalStateException.class); + } + + @Test + @DisplayName("Stay 가 종료된 상태임을 확인") + void testIsFinishedTrue() { + assertThat(this.stay.isFinished()).isTrue(); + } + + @Test + @DisplayName("Stay 에서 카드목록을 요구했을 시 가져갔던 카드개수가 맞는지 확인") + void testHitCards() { + assertThat(this.stay.cards()).hasSize(1); + } + + @Test + @DisplayName("플레이어 Stay기준 딜러의 Blackjack을 받았을 때 패배 반환") + void testPlayerBlackjackVersusDealerBlackjack() { + Card firstCard = Card.valueOf(Pattern.DIAMOND, Number.ACE); + Card secondCard = Card.valueOf(Pattern.DIAMOND, Number.TEN); + State dealerBlackjack = Init.draw(firstCard, secondCard); + assertThat(this.stay.calculatePlayerResult(dealerBlackjack)).isEqualTo(Result.LOSE); + } + + @Test + @DisplayName("플레이어 Stay기준 딜러의 Bust를 받았을 때 승리 반환") + void testPlayerBlackjackVersusDealerBust() { + Card firstCard = Card.valueOf(Pattern.DIAMOND, Number.KING); + Card secondCard = Card.valueOf(Pattern.DIAMOND, Number.TEN); + State dealerHit = Init.draw(firstCard, secondCard); + State dealerBust = dealerHit.draw(Card.valueOf(Pattern.HEART, Number.JACK)); + assertThat(this.stay.calculatePlayerResult(dealerBust)).isEqualTo(Result.WIN); + } + + @Test + @DisplayName("플레이어 Stay기준 딜러의 Stay를 받았을 때 점수비교 결과 반환") + void testPlayerBlackjackVersusDealerStay() { + Card firstCard = Card.valueOf(Pattern.DIAMOND, Number.TWO); + Card secondCard = Card.valueOf(Pattern.DIAMOND, Number.TEN); + State dealerHit = Init.draw(firstCard, secondCard); + State dealerStay = dealerHit.stay(); + assertThat(this.stay.calculatePlayerResult(dealerStay)).isEqualTo(Result.LOSE); // 5 vs 12 + + firstCard = Card.valueOf(Pattern.DIAMOND, Number.TWO); + secondCard = Card.valueOf(Pattern.DIAMOND, Number.THREE); + dealerHit = Init.draw(firstCard, secondCard); + dealerStay = dealerHit.stay(); + assertThat(this.stay.calculatePlayerResult(dealerStay)).isEqualTo(Result.DRAW); // 5 vs 5 + + firstCard = Card.valueOf(Pattern.DIAMOND, Number.TWO); + secondCard = Card.valueOf(Pattern.HEART, Number.TWO); + dealerHit = Init.draw(firstCard, secondCard); + dealerStay = dealerHit.stay(); + assertThat(this.stay.calculatePlayerResult(dealerStay)).isEqualTo(Result.WIN); // 5 vs 4 + } +} \ No newline at end of file diff --git a/src/test/java/empty.txt b/src/test/java/empty.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/test/java/rentcar/abstractcar/AvanteTest.java b/src/test/java/rentcar/abstractcar/AvanteTest.java new file mode 100644 index 0000000000..2f695caccc --- /dev/null +++ b/src/test/java/rentcar/abstractcar/AvanteTest.java @@ -0,0 +1,41 @@ +package rentcar.abstractcar; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class AvanteTest { + + private Avante avante; + + @BeforeEach + private void setUp() { + avante = new Avante(150); + } + + @Test + @DisplayName("아반떼의 연비 반환 테스트") + void testDistancePerLiter() { + assertThat(avante.getDistancePerLiter()).isEqualTo(15); + } + + @Test + @DisplayName("아반뗴 생성할 때 이동할 거리 주입된다.") + void testTripDistance() { + assertThat(avante.getTripDistance()).isEqualTo(150); + } + + @Test + @DisplayName("아반떼에 필요한 주유량 테스트") + void testChargeQuantity() { + assertThat(avante.getChargeQuantity()).isEqualTo(10); + } + + @Test + @DisplayName("아반떼 이름 반환된다.") + void testName() { + assertThat(avante.getName()).isEqualTo("Avante"); + } +} diff --git a/src/test/java/rentcar/abstractcar/K5Test.java b/src/test/java/rentcar/abstractcar/K5Test.java new file mode 100644 index 0000000000..0327191d8a --- /dev/null +++ b/src/test/java/rentcar/abstractcar/K5Test.java @@ -0,0 +1,41 @@ +package rentcar.abstractcar; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class K5Test { + + private K5 k5; + + @BeforeEach + private void setUp() { + k5 = new K5(130); + } + + @Test + @DisplayName("K5의 연비 반환 테스트") + void testDistancePerLiter() { + assertThat(k5.getDistancePerLiter()).isEqualTo(13); + } + + @Test + @DisplayName("K5 생성할 때 이동할 거리 주입된다.") + void testTripDistance() { + assertThat(k5.getTripDistance()).isEqualTo(130); + } + + @Test + @DisplayName("K5에 필요한 주유량 테스트") + void testChargeQuantity() { + assertThat(k5.getChargeQuantity()).isEqualTo(10); + } + + @Test + @DisplayName("K5 이름 반환된다.") + void testName() { + assertThat(k5.getName()).isEqualTo("K5"); + } +} diff --git a/src/test/java/rentcar/abstractcar/RentCompanyTest.java b/src/test/java/rentcar/abstractcar/RentCompanyTest.java new file mode 100644 index 0000000000..1ca29b0d1e --- /dev/null +++ b/src/test/java/rentcar/abstractcar/RentCompanyTest.java @@ -0,0 +1,29 @@ +package rentcar.abstractcar; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +public class RentCompanyTest { + + private static final String NEWLINE = System.getProperty("line.separator"); + + @Test + public void report() throws Exception { + RentCompany company = RentCompany.create(); + company.addCar(new Sonata(150)); + company.addCar(new K5(260)); + company.addCar(new Sonata(120)); + company.addCar(new Avante(300)); + company.addCar(new K5(390)); + + String report = company.generateReport(); + assertThat(report).isEqualTo( + "Sonata : 15리터" + NEWLINE + + "K5 : 20리터" + NEWLINE + + "Sonata : 12리터" + NEWLINE + + "Avante : 20리터" + NEWLINE + + "K5 : 30리터" + NEWLINE + ); + } +} diff --git a/src/test/java/rentcar/abstractcar/SonataTest.java b/src/test/java/rentcar/abstractcar/SonataTest.java new file mode 100644 index 0000000000..5a4969a0f7 --- /dev/null +++ b/src/test/java/rentcar/abstractcar/SonataTest.java @@ -0,0 +1,41 @@ +package rentcar.abstractcar; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class SonataTest { + + private Sonata sonata; + + @BeforeEach + private void setUp() { + sonata = new Sonata(100); + } + + @Test + @DisplayName("소나타의 연비 반환 테스트") + void testDistancePerLiter() { + assertThat(sonata.getDistancePerLiter()).isEqualTo(10); + } + + @Test + @DisplayName("소나타 생성할 때 이동할 거리 주입된다.") + void testTripDistance() { + assertThat(sonata.getTripDistance()).isEqualTo(100); + } + + @Test + @DisplayName("소나타에 필요한 주유량 테스트") + void testChargeQuantity() { + assertThat(sonata.getChargeQuantity()).isEqualTo(10); + } + + @Test + @DisplayName("소나타 이름 반환된다.") + void testName() { + assertThat(sonata.getName()).isEqualTo("Sonata"); + } +} diff --git a/src/test/java/rentcar/interfacecar/AvanteTest.java b/src/test/java/rentcar/interfacecar/AvanteTest.java new file mode 100644 index 0000000000..6ac2388c9e --- /dev/null +++ b/src/test/java/rentcar/interfacecar/AvanteTest.java @@ -0,0 +1,41 @@ +package rentcar.interfacecar; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class AvanteTest { + + private Avante avante; + + @BeforeEach + private void setUp() { + avante = new Avante(150); + } + + @Test + @DisplayName("아반떼의 연비 반환 테스트") + void testDistancePerLiter() { + assertThat(avante.getDistancePerLiter()).isEqualTo(15); + } + + @Test + @DisplayName("아반뗴 생성할 때 이동할 거리 주입된다.") + void testTripDistance() { + assertThat(avante.getTripDistance()).isEqualTo(150); + } + + @Test + @DisplayName("아반떼에 필요한 주유량 테스트") + void testChargeQuantity() { + assertThat(avante.getChargeQuantity()).isEqualTo(10); + } + + @Test + @DisplayName("아반떼 이름 반환된다.") + void testName() { + assertThat(avante.getName()).isEqualTo("Avante"); + } +} diff --git a/src/test/java/rentcar/interfacecar/K5Test.java b/src/test/java/rentcar/interfacecar/K5Test.java new file mode 100644 index 0000000000..5ed3c4373c --- /dev/null +++ b/src/test/java/rentcar/interfacecar/K5Test.java @@ -0,0 +1,41 @@ +package rentcar.interfacecar; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class K5Test { + + private K5 k5; + + @BeforeEach + private void setUp() { + k5 = new K5(130); + } + + @Test + @DisplayName("K5의 연비 반환 테스트") + void testDistancePerLiter() { + assertThat(k5.getDistancePerLiter()).isEqualTo(13); + } + + @Test + @DisplayName("K5 생성할 때 이동할 거리 주입된다.") + void testTripDistance() { + assertThat(k5.getTripDistance()).isEqualTo(130); + } + + @Test + @DisplayName("K5에 필요한 주유량 테스트") + void testChargeQuantity() { + assertThat(k5.getChargeQuantity()).isEqualTo(10); + } + + @Test + @DisplayName("K5 이름 반환된다.") + void testName() { + assertThat(k5.getName()).isEqualTo("K5"); + } +} diff --git a/src/test/java/rentcar/interfacecar/RentCompanyTest.java b/src/test/java/rentcar/interfacecar/RentCompanyTest.java new file mode 100644 index 0000000000..6ef0ad82bb --- /dev/null +++ b/src/test/java/rentcar/interfacecar/RentCompanyTest.java @@ -0,0 +1,29 @@ +package rentcar.interfacecar; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +public class RentCompanyTest { + + private static final String NEWLINE = System.getProperty("line.separator"); + + @Test + public void report() throws Exception { + RentCompany company = RentCompany.create(); + company.addCar(new Sonata(150)); + company.addCar(new K5(260)); + company.addCar(new Sonata(120)); + company.addCar(new Avante(300)); + company.addCar(new K5(390)); + + String report = company.generateReport(); + assertThat(report).isEqualTo( + "Sonata : 15리터" + NEWLINE + + "K5 : 20리터" + NEWLINE + + "Sonata : 12리터" + NEWLINE + + "Avante : 20리터" + NEWLINE + + "K5 : 30리터" + NEWLINE + ); + } +} diff --git a/src/test/java/rentcar/interfacecar/SonataTest.java b/src/test/java/rentcar/interfacecar/SonataTest.java new file mode 100644 index 0000000000..b0ccf4056e --- /dev/null +++ b/src/test/java/rentcar/interfacecar/SonataTest.java @@ -0,0 +1,41 @@ +package rentcar.interfacecar; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class SonataTest { + + private Sonata sonata; + + @BeforeEach + private void setUp() { + sonata = new Sonata(100); + } + + @Test + @DisplayName("소나타의 연비 반환 테스트") + void testDistancePerLiter() { + assertThat(sonata.getDistancePerLiter()).isEqualTo(10); + } + + @Test + @DisplayName("소나타 생성할 때 이동할 거리 주입된다.") + void testTripDistance() { + assertThat(sonata.getTripDistance()).isEqualTo(100); + } + + @Test + @DisplayName("소나타에 필요한 주유량 테스트") + void testChargeQuantity() { + assertThat(sonata.getChargeQuantity()).isEqualTo(10); + } + + @Test + @DisplayName("소나타 이름 반환된다.") + void testName() { + assertThat(sonata.getName()).isEqualTo("Sonata"); + } +}