From 94c1e84a98f766bfbe84ef319053ad58c76306c9 Mon Sep 17 00:00:00 2001 From: JinJuMoon <40536197+JinJuMoon@users.noreply.github.com> Date: Mon, 4 May 2020 13:52:55 +0900 Subject: [PATCH] =?UTF-8?q?[=EB=AC=B4=EB=8A=AC]=20=EC=B2=B4=EC=8A=A4=20?= =?UTF-8?q?=EC=8A=A4=ED=94=84=EB=A7=81=203=EB=8B=A8=EA=B3=84=20=EB=AF=B8?= =?UTF-8?q?=EC=85=98=20=EC=A0=9C=EC=B6=9C=ED=95=A9=EB=8B=88=EB=8B=A4.=20(#?= =?UTF-8?q?143)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [스티치] 체스 스프링 실습 1단계 미션 제출입니다 (#37) * feat : 기존 Chess 코드 추가 * refactor : 기존 Chess 코드의 Application과 Controller 명명 수정 * refactor : JdbcTemplate 명명 수정 및 Spring Bean 등록 - 기존 JdbcTemplate 라이브러리와 충돌로 인한 명명 수정 - Dao, Service, ConnectionManager를 Spring Bean 등록 * feat : SpringChessController 추가 * feat : SpringChessController 구현 * refactor : controller 피드백 리팩토링 * refactor : database package 리팩토링 - ConnectionManager를 DataSource로 명명 수정. - CustomJdbcTemplate을 JdbcTemplate으로 명명 수정, 별칭 지정. - MySqlConnectionManager를 MySqlDataSource로 명명 수정, 별칭 지정. * refactor : 접근 지정자 수정 및 상수 추출 * refactor : BlackPawnStrategy와 WhitePawnStrategy를 PawnStrategy로 추상화 * [스티치] 체스 스프링 실습 2단계 미션 제출입니다 (#87) * feat : Spring Data JDBC 적용 - Spring Data JDBC 적용을 위한 GameRoomRepository 구현 - schema.sql 구현 * feat : GameHistory, GameRoom Entity 구현 * refactor : Spring Application에 불필요한 클래스 및 테스트 삭제 * refactor : 불필요한 util 패키지 및 클래스 삭제, GameHistory 클래스 내 CreatedTime 필드 삭제 Co-authored-by: Junyoung Lee --- .../chess/ConsoleChessApplication.java | 37 ----- .../wooteco/chess/SparkChessApplication.java | 36 ----- .../chess/controller/ChessController.java | 67 --------- .../controller/SparkChessController.java | 86 ----------- .../controller/SpringChessController.java | 52 ++++--- .../java/wooteco/chess/dao/ChessGameDao.java | 15 -- .../wooteco/chess/dao/ChessHistoryDao.java | 15 -- .../wooteco/chess/dao/MySqlChessGameDao.java | 62 -------- .../chess/dao/MySqlChessHistoryDao.java | 66 -------- .../wooteco/chess/database/DataSource.java | 10 -- .../chess/database/GameRoomRepository.java | 18 +++ .../wooteco/chess/database/JdbcTemplate.java | 66 -------- .../chess/database/MySqlDataSource.java | 46 ------ .../database/PreparedStatementSetter.java | 10 -- .../wooteco/chess/database/RowMapper.java | 10 -- .../java/wooteco/chess/entity/BaseEntity.java | 24 --- .../wooteco/chess/entity/ChessGameEntity.java | 34 ----- .../chess/entity/ChessHistoryEntity.java | 76 ---------- .../wooteco/chess/entity/GameHistory.java | 56 +++++++ .../java/wooteco/chess/entity/GameRoom.java | 58 +++++++ .../wooteco/chess/service/ChessService.java | 106 ++++++------- .../chess/service/dto/ChessGameDto.java | 16 +- .../chess/util/ChessBoardRenderer.java | 61 -------- .../java/wooteco/chess/util/StringUtil.java | 21 --- .../wooteco/chess/view/ConsoleInputView.java | 14 -- .../wooteco/chess/view/ConsoleOutputView.java | 40 ----- src/main/resources/application.properties | 12 +- src/main/resources/schema.sql | 15 ++ .../chess/dao/InMemoryChessGameDao.java | 45 ------ .../chess/dao/InMemoryChessHistoryDao.java | 43 ------ .../chess/dao/MySqlChessGameDaoTest.java | 133 ---------------- .../chess/dao/MySqlChessHistoryDaoTest.java | 131 ---------------- .../database/GameRoomRepositoryTest.java | 44 ++++++ .../wooteco/chess/entity/BaseEntityTest.java | 36 ----- .../chess/entity/ChessGameEntityTest.java | 41 ----- .../chess/entity/ChessHistoryEntityTest.java | 80 ---------- .../chess/service/ChessServiceTest.java | 142 ------------------ .../chess/service/dto/ChessGameDtoTest.java | 31 ---- .../chess/util/ChessBoardRendererTest.java | 43 ------ .../wooteco/chess/util/StringUtilTest.java | 30 ---- src/test/resources/application.properties | 11 ++ 41 files changed, 314 insertions(+), 1625 deletions(-) delete mode 100644 src/main/java/wooteco/chess/ConsoleChessApplication.java delete mode 100644 src/main/java/wooteco/chess/SparkChessApplication.java delete mode 100644 src/main/java/wooteco/chess/controller/ChessController.java delete mode 100644 src/main/java/wooteco/chess/controller/SparkChessController.java delete mode 100644 src/main/java/wooteco/chess/dao/ChessGameDao.java delete mode 100644 src/main/java/wooteco/chess/dao/ChessHistoryDao.java delete mode 100644 src/main/java/wooteco/chess/dao/MySqlChessGameDao.java delete mode 100644 src/main/java/wooteco/chess/dao/MySqlChessHistoryDao.java delete mode 100644 src/main/java/wooteco/chess/database/DataSource.java create mode 100644 src/main/java/wooteco/chess/database/GameRoomRepository.java delete mode 100644 src/main/java/wooteco/chess/database/JdbcTemplate.java delete mode 100644 src/main/java/wooteco/chess/database/MySqlDataSource.java delete mode 100644 src/main/java/wooteco/chess/database/PreparedStatementSetter.java delete mode 100644 src/main/java/wooteco/chess/database/RowMapper.java delete mode 100644 src/main/java/wooteco/chess/entity/BaseEntity.java delete mode 100644 src/main/java/wooteco/chess/entity/ChessGameEntity.java delete mode 100644 src/main/java/wooteco/chess/entity/ChessHistoryEntity.java create mode 100644 src/main/java/wooteco/chess/entity/GameHistory.java create mode 100644 src/main/java/wooteco/chess/entity/GameRoom.java delete mode 100644 src/main/java/wooteco/chess/util/ChessBoardRenderer.java delete mode 100644 src/main/java/wooteco/chess/util/StringUtil.java delete mode 100644 src/main/java/wooteco/chess/view/ConsoleInputView.java delete mode 100644 src/main/java/wooteco/chess/view/ConsoleOutputView.java create mode 100644 src/main/resources/schema.sql delete mode 100644 src/test/java/wooteco/chess/dao/InMemoryChessGameDao.java delete mode 100644 src/test/java/wooteco/chess/dao/InMemoryChessHistoryDao.java delete mode 100644 src/test/java/wooteco/chess/dao/MySqlChessGameDaoTest.java delete mode 100644 src/test/java/wooteco/chess/dao/MySqlChessHistoryDaoTest.java create mode 100644 src/test/java/wooteco/chess/database/GameRoomRepositoryTest.java delete mode 100644 src/test/java/wooteco/chess/entity/BaseEntityTest.java delete mode 100644 src/test/java/wooteco/chess/entity/ChessGameEntityTest.java delete mode 100644 src/test/java/wooteco/chess/entity/ChessHistoryEntityTest.java delete mode 100644 src/test/java/wooteco/chess/service/ChessServiceTest.java delete mode 100644 src/test/java/wooteco/chess/service/dto/ChessGameDtoTest.java delete mode 100644 src/test/java/wooteco/chess/util/ChessBoardRendererTest.java delete mode 100644 src/test/java/wooteco/chess/util/StringUtilTest.java create mode 100644 src/test/resources/application.properties diff --git a/src/main/java/wooteco/chess/ConsoleChessApplication.java b/src/main/java/wooteco/chess/ConsoleChessApplication.java deleted file mode 100644 index a7b4b09124..0000000000 --- a/src/main/java/wooteco/chess/ConsoleChessApplication.java +++ /dev/null @@ -1,37 +0,0 @@ -package wooteco.chess; - -import java.util.List; - -import wooteco.chess.controller.ChessController; -import wooteco.chess.domain.chessBoard.ChessBoard; -import wooteco.chess.domain.chessBoard.ChessBoardInitializer; -import wooteco.chess.domain.chessGame.ChessCommand; -import wooteco.chess.domain.chessGame.ChessGame; -import wooteco.chess.util.StringUtil; -import wooteco.chess.view.ConsoleInputView; -import wooteco.chess.view.ConsoleOutputView; - -public class ConsoleChessApplication { - - public static void main(String[] args) { - ChessBoard chessBoard = new ChessBoard(ChessBoardInitializer.create()); - ChessGame chessGame = ChessGame.from(chessBoard); - ChessController chessController = new ChessController(chessGame); - - ConsoleOutputView.printChessStart(); - if (isStartChessCommand()) { - chessController.run(); - } - ConsoleOutputView.printChessEnd(); - } - - private static boolean isStartChessCommand() { - List commandArguments = StringUtil.splitChessCommand(ConsoleInputView.inputChessCommand()); - - if (!ChessCommand.of(commandArguments).isStartChessCommand()) { - throw new IllegalArgumentException("게임을 시작해야 입력 가능한 명령어입니다."); - } - return true; - } - -} diff --git a/src/main/java/wooteco/chess/SparkChessApplication.java b/src/main/java/wooteco/chess/SparkChessApplication.java deleted file mode 100644 index ca1dd2c26b..0000000000 --- a/src/main/java/wooteco/chess/SparkChessApplication.java +++ /dev/null @@ -1,36 +0,0 @@ -package wooteco.chess; - -import static spark.Spark.*; - -import wooteco.chess.controller.SparkChessController; -import wooteco.chess.dao.ChessGameDao; -import wooteco.chess.dao.ChessHistoryDao; -import wooteco.chess.dao.MySqlChessGameDao; -import wooteco.chess.dao.MySqlChessHistoryDao; -import wooteco.chess.database.DataSource; -import wooteco.chess.database.JdbcTemplate; -import wooteco.chess.database.MySqlDataSource; -import wooteco.chess.service.ChessService; - -public class SparkChessApplication { - - public static void main(String[] args) { - port(8080); - staticFileLocation("/public"); - - SparkChessController sparkChessController = initWebController(); - sparkChessController.run(); - } - - private static SparkChessController initWebController() { - DataSource dataSource = MySqlDataSource.getInstance(); - JdbcTemplate template = new JdbcTemplate(dataSource); - - ChessGameDao chessGameDao = new MySqlChessGameDao(template); - ChessHistoryDao chessHistoryDao = new MySqlChessHistoryDao(template); - ChessService chessService = new ChessService(chessGameDao, chessHistoryDao); - - return new SparkChessController(chessService); - } - -} diff --git a/src/main/java/wooteco/chess/controller/ChessController.java b/src/main/java/wooteco/chess/controller/ChessController.java deleted file mode 100644 index d8d243518a..0000000000 --- a/src/main/java/wooteco/chess/controller/ChessController.java +++ /dev/null @@ -1,67 +0,0 @@ -package wooteco.chess.controller; - -import static wooteco.chess.util.StringUtil.*; -import static wooteco.chess.view.ConsoleInputView.*; -import static wooteco.chess.view.ConsoleOutputView.*; - -import java.util.Objects; - -import wooteco.chess.domain.chessGame.ChessCommand; -import wooteco.chess.domain.chessGame.ChessGame; -import wooteco.chess.util.ChessBoardRenderer; - -public class ChessController { - - private final ChessGame chessGame; - - public ChessController(ChessGame chessGame) { - Objects.requireNonNull(chessGame, "체스 게임이 null입니다."); - this.chessGame = chessGame; - } - - public void run() { - do { - printChessBoard(ChessBoardRenderer.render(chessGame.getChessBoard())); - - ChessCommand chessCommand = receiveChessCommand(); - playChessGameBy(chessCommand); - } while (!isEndState()); - } - - private ChessCommand receiveChessCommand() { - ChessCommand chessCommand = ChessCommand.of(splitChessCommand(inputChessCommand())); - - if (chessCommand.isStartChessCommand()) { - throw new IllegalArgumentException("start 명령어은 최초 시작 때만 사용 가능합니다."); - } - return chessCommand; - } - - private void playChessGameBy(ChessCommand chessCommand) { - if (chessCommand.isMoveChessCommand()) { - chessGame.move(chessCommand); - } - if (chessCommand.isStatusChessCommand()) { - double score = chessGame.status(chessCommand); - printStatus(chessCommand.getStatusPieceColor(), score); - } - if (chessCommand.isEndChessCommand()) { - chessGame.end(); - } - } - - private boolean isEndState() { - if (!chessGame.isEndState()) { - return false; - } - return checkKingCaught(); - } - - private boolean checkKingCaught() { - if (chessGame.isKingCaught()) { - printKingCaught(chessGame.getCurrentPieceColor()); - } - return true; - } - -} diff --git a/src/main/java/wooteco/chess/controller/SparkChessController.java b/src/main/java/wooteco/chess/controller/SparkChessController.java deleted file mode 100644 index 4923a1b31d..0000000000 --- a/src/main/java/wooteco/chess/controller/SparkChessController.java +++ /dev/null @@ -1,86 +0,0 @@ -package wooteco.chess.controller; - -import static spark.Spark.*; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -import spark.ModelAndView; -import spark.Request; -import spark.Response; -import spark.template.handlebars.HandlebarsTemplateEngine; -import wooteco.chess.service.ChessService; -import wooteco.chess.service.dto.ChessBoardDto; -import wooteco.chess.service.dto.ChessGameDto; -import wooteco.chess.service.dto.ChessStatusDtos; - -public class SparkChessController { - - private static final HandlebarsTemplateEngine HANDLEBARS_TEMPLATE_ENGINE = new HandlebarsTemplateEngine(); - - private final ChessService chessService; - - public SparkChessController(final ChessService chessService) { - Objects.requireNonNull(chessService, "체스 서비스가 null입니다."); - this.chessService = chessService; - } - - public void run() { - get("/", this::renderStartPage); - get("/chess", (request, response) -> renderGame(chessService.loadChessGame())); - - post("/chess_play", this::playChessGame); - post("/chess_new", this::newChessGame); - post("/chess_end", this::endChessGame); - } - - private String renderStartPage(final Request request, final Response response) { - return render(new HashMap<>(), "index.hbs"); - } - - private String playChessGame(final Request request, final Response response) { - final String sourcePosition = request.queryParams("sourcePosition").trim(); - final String targetPosition = request.queryParams("targetPosition").trim(); - final ChessGameDto chessGameDto = chessService.playChessGame(sourcePosition, targetPosition); - - if (chessGameDto.isEndState()) { - return renderResult(chessGameDto); - } - return renderGame(chessGameDto); - } - - private String newChessGame(final Request request, final Response response) { - return renderGame(chessService.createChessGame()); - } - - private String endChessGame(final Request request, final Response response) { - return renderResult(chessService.endChessGame()); - } - - private String renderGame(final ChessGameDto chessGameDto) { - final ChessBoardDto chessBoardDto = chessGameDto.getChessBoardDto(); - final ChessStatusDtos chessStatusDtos = chessGameDto.getChessStatusDtos(); - - final Map model = new HashMap<>(chessBoardDto.getChessBoard()); - model.put("piece_color", chessGameDto.getPieceColorDto()); - model.put("status", chessStatusDtos.getChessStatusDtos()); - return render(model, "chess.hbs"); - } - - private String renderResult(final ChessGameDto chessGameDto) { - final ChessBoardDto chessBoardDto = chessGameDto.getChessBoardDto(); - final ChessStatusDtos chessStatusDtos = chessGameDto.getChessStatusDtos(); - - final Map model = new HashMap<>(chessBoardDto.getChessBoard()); - model.put("is_king_caught", chessGameDto.isKingCaught()); - model.put("piece_color", chessGameDto.getPieceColorDto()); - model.put("status", chessStatusDtos.getChessStatusDtos()); - return render(model, "result.hbs"); - } - - private static String render(Map model, String templatePath) { - return HANDLEBARS_TEMPLATE_ENGINE.render(new ModelAndView(model, templatePath)); - } - -} diff --git a/src/main/java/wooteco/chess/controller/SpringChessController.java b/src/main/java/wooteco/chess/controller/SpringChessController.java index 5aa1c91747..2e32def772 100644 --- a/src/main/java/wooteco/chess/controller/SpringChessController.java +++ b/src/main/java/wooteco/chess/controller/SpringChessController.java @@ -2,15 +2,18 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; - import wooteco.chess.service.ChessService; import wooteco.chess.service.dto.ChessBoardDto; import wooteco.chess.service.dto.ChessGameDto; import wooteco.chess.service.dto.ChessStatusDtos; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + @Controller public class SpringChessController { @@ -21,36 +24,52 @@ public SpringChessController(final ChessService chessService) { } @GetMapping("/") - public String start() { + public String index(Model model) { + model.addAttribute("gameNames", chessService.showAllGames()); return "index"; } - @GetMapping("/chess") - public String loadChessGame(final Model model) { - final ChessGameDto chessGameDto = chessService.loadChessGame(); + @PostMapping("/game/new") + public String createGame(@RequestParam("name") final String name, final Model model, HttpServletResponse response) { + ChessGameDto chessGameDto = chessService.createChessGame(name); + Cookie cookie = new Cookie("gameId", String.valueOf(chessGameDto.getId())); + cookie.setPath("/"); + response.addCookie(cookie); return renderGame(chessGameDto, model); } - @PostMapping("/chess_play") - public String playChessGame(@RequestParam final String sourcePosition, @RequestParam final String targetPosition, - final Model model) { - final ChessGameDto chessGameDto = chessService.playChessGame(sourcePosition.trim(), targetPosition.trim()); + @PostMapping("/game") + public String showGame(@RequestParam("name") final String name, final Model model, HttpServletResponse response) { + ChessGameDto chessGameDto = chessService.loadChessGameByName(name); + Long gameId = chessGameDto.getId(); - if (chessGameDto.isEndState()) { + if (chessService.isEndGame(gameId)) { return renderResult(chessGameDto, model); } + + Cookie cookie = new Cookie("gameId", String.valueOf(gameId)); + cookie.setPath("/"); + response.addCookie(cookie); return renderGame(chessGameDto, model); } - @PostMapping("/chess_new") - public String newChessGame(final Model model) { - return renderGame(chessService.createChessGame(), model); + @PostMapping("/game/play") + public String playChessGame(@CookieValue("gameId") Cookie gameIdCookie, @RequestParam final String sourcePosition, + @RequestParam final String targetPosition, final Model model) { + final Long gameId = Long.parseLong(gameIdCookie.getValue()); + final ChessGameDto chessGameDto = chessService.playChessGame(gameId, sourcePosition.trim(), + targetPosition.trim()); + + if (chessGameDto.isEndState()) { + return renderResult(chessGameDto, model); + } + return renderGame(chessGameDto, model); } - @PostMapping("/chess_end") - public String endChessGame(final Model model) { - final ChessGameDto chessGameDto = chessService.endChessGame(); + @PostMapping("/game/end") + public String endChessGame(@CookieValue("gameId") Long gameId, final Model model) { + final ChessGameDto chessGameDto = chessService.endChessGame(gameId); return renderResult(chessGameDto, model); } @@ -74,5 +93,4 @@ private String renderResult(final ChessGameDto chessGameDto, final Model model) model.addAttribute("status", chessStatusDtos.getChessStatusDtos()); return "result"; } - } diff --git a/src/main/java/wooteco/chess/dao/ChessGameDao.java b/src/main/java/wooteco/chess/dao/ChessGameDao.java deleted file mode 100644 index 402b425a76..0000000000 --- a/src/main/java/wooteco/chess/dao/ChessGameDao.java +++ /dev/null @@ -1,15 +0,0 @@ -package wooteco.chess.dao; - -import wooteco.chess.entity.ChessGameEntity; - -public interface ChessGameDao { - - long add(final ChessGameEntity entity); - - long findMaxGameId(); - - boolean isEmpty(); - - void deleteAll(); - -} diff --git a/src/main/java/wooteco/chess/dao/ChessHistoryDao.java b/src/main/java/wooteco/chess/dao/ChessHistoryDao.java deleted file mode 100644 index 9fe17d0689..0000000000 --- a/src/main/java/wooteco/chess/dao/ChessHistoryDao.java +++ /dev/null @@ -1,15 +0,0 @@ -package wooteco.chess.dao; - -import java.util.List; - -import wooteco.chess.entity.ChessHistoryEntity; - -public interface ChessHistoryDao { - - List findAllByGameId(final long gameId); - - void add(final ChessHistoryEntity entity); - - void deleteAll(); - -} diff --git a/src/main/java/wooteco/chess/dao/MySqlChessGameDao.java b/src/main/java/wooteco/chess/dao/MySqlChessGameDao.java deleted file mode 100644 index ecdb88ee4b..0000000000 --- a/src/main/java/wooteco/chess/dao/MySqlChessGameDao.java +++ /dev/null @@ -1,62 +0,0 @@ -package wooteco.chess.dao; - -import java.sql.ResultSet; -import java.sql.Timestamp; -import java.util.Objects; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Repository; - -import wooteco.chess.database.JdbcTemplate; -import wooteco.chess.entity.ChessGameEntity; - -@Repository -public class MySqlChessGameDao implements ChessGameDao { - - public static final long EMPTY_CHESS_GAME = 0L; - private static final String CHESS_GAME_TABLE = "chess_games"; - - private final JdbcTemplate jdbcTemplate; - - public MySqlChessGameDao(@Qualifier("CustomJdbcTemplate") final JdbcTemplate jdbcTemplate) { - Objects.requireNonNull(jdbcTemplate, "JdbcTemplate이 null입니다."); - this.jdbcTemplate = jdbcTemplate; - } - - @Override - public long add(final ChessGameEntity entity) { - Objects.requireNonNull(entity, "엔티티가 null입니다."); - final String query = "INSERT INTO " + CHESS_GAME_TABLE + " (created_time) VALUES (?)"; - - return jdbcTemplate.executeUpdate(query, preparedStatement -> { - preparedStatement.setTimestamp(1, Timestamp.valueOf(entity.getCreatedTime())); - }); - } - - @Override - public long findMaxGameId() { - final String query = "SELECT MAX(game_id) AS max_id FROM " + CHESS_GAME_TABLE; - - return jdbcTemplate.executeQuery(query, resultSet -> { - if (resultSet.next()) { - return resultSet.getLong("max_id"); - } - return EMPTY_CHESS_GAME; - }); - } - - @Override - public boolean isEmpty() { - final String query = "SELECT * FROM " + CHESS_GAME_TABLE; - - return !jdbcTemplate.executeQuery(query, ResultSet::next); - } - - @Override - public void deleteAll() { - final String query = "DELETE FROM " + CHESS_GAME_TABLE; - - jdbcTemplate.executeUpdate(query); - } - -} diff --git a/src/main/java/wooteco/chess/dao/MySqlChessHistoryDao.java b/src/main/java/wooteco/chess/dao/MySqlChessHistoryDao.java deleted file mode 100644 index 356edf85f3..0000000000 --- a/src/main/java/wooteco/chess/dao/MySqlChessHistoryDao.java +++ /dev/null @@ -1,66 +0,0 @@ -package wooteco.chess.dao; - -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Repository; - -import wooteco.chess.database.JdbcTemplate; -import wooteco.chess.entity.ChessHistoryEntity; - -@Repository -public class MySqlChessHistoryDao implements ChessHistoryDao { - - private static final String CHESS_HISTORY_TABLE = "chess_histories"; - - private final JdbcTemplate jdbcTemplate; - - public MySqlChessHistoryDao(@Qualifier("CustomJdbcTemplate") final JdbcTemplate jdbcTemplate) { - Objects.requireNonNull(jdbcTemplate, "JdbcTemplate이 null입니다."); - this.jdbcTemplate = jdbcTemplate; - } - - @Override - public List findAllByGameId(final long gameId) { - final String query = "SELECT * FROM " + CHESS_HISTORY_TABLE + " WHERE game_id = ?"; - - return jdbcTemplate.executeQuery(query, resultSet -> { - final List entities = new ArrayList<>(); - - while (resultSet.next()) { - entities.add(ChessHistoryEntity.of( - resultSet.getLong("history_id"), - resultSet.getLong("game_id"), - resultSet.getString("start"), - resultSet.getString("end"), - resultSet.getTimestamp("created_time").toLocalDateTime())); - } - return entities; - }, preparedStatement -> preparedStatement.setLong(1, gameId)); - } - - @Override - public void add(final ChessHistoryEntity entity) { - Objects.requireNonNull(entity, "엔티티가 null입니다."); - final String query = - "INSERT INTO " + CHESS_HISTORY_TABLE + " (game_id, start, end, created_time) VALUES (?, ?, ?, ?)"; - - jdbcTemplate.executeUpdate(query, preparedStatement -> { - preparedStatement.setLong(1, entity.getGameId()); - preparedStatement.setString(2, entity.getStart()); - preparedStatement.setString(3, entity.getEnd()); - preparedStatement.setTimestamp(4, Timestamp.valueOf(entity.getCreatedTime())); - }); - } - - @Override - public void deleteAll() { - final String query = "DELETE FROM " + CHESS_HISTORY_TABLE; - - jdbcTemplate.executeUpdate(query); - } - -} diff --git a/src/main/java/wooteco/chess/database/DataSource.java b/src/main/java/wooteco/chess/database/DataSource.java deleted file mode 100644 index a2779f2a1a..0000000000 --- a/src/main/java/wooteco/chess/database/DataSource.java +++ /dev/null @@ -1,10 +0,0 @@ -package wooteco.chess.database; - -import java.sql.Connection; - -// TODO: 2020/04/25 명명 수정하기 -> DataSource -public interface DataSource { - - Connection getConnection(); - -} diff --git a/src/main/java/wooteco/chess/database/GameRoomRepository.java b/src/main/java/wooteco/chess/database/GameRoomRepository.java new file mode 100644 index 0000000000..cf06555096 --- /dev/null +++ b/src/main/java/wooteco/chess/database/GameRoomRepository.java @@ -0,0 +1,18 @@ +package wooteco.chess.database; + +import org.springframework.data.jdbc.repository.query.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; +import wooteco.chess.entity.GameRoom; + +import java.util.List; + +public interface GameRoomRepository extends CrudRepository { + + @Override + List findAll(); + + @Query("SELECT * FROM game_room WHERE name = :name") + GameRoom findByName(@Param("name") final String name); + +} \ No newline at end of file diff --git a/src/main/java/wooteco/chess/database/JdbcTemplate.java b/src/main/java/wooteco/chess/database/JdbcTemplate.java deleted file mode 100644 index 9abfb0c2aa..0000000000 --- a/src/main/java/wooteco/chess/database/JdbcTemplate.java +++ /dev/null @@ -1,66 +0,0 @@ -package wooteco.chess.database; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; - -@Component("CustomJdbcTemplate") -public class JdbcTemplate { - - private final DataSource dataSource; - - public JdbcTemplate(@Qualifier("CustomDataSource") final DataSource dataSource) { - this.dataSource = dataSource; - } - - public T executeQuery(String query, RowMapper rowMapper, PreparedStatementSetter preparedStatementSetter) { - try (Connection connection = dataSource.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement(query) - ) { - preparedStatementSetter.setArgument(preparedStatement); - return rowMapper.mapRow(preparedStatement.executeQuery()); - } catch (SQLException exception) { - System.err.println(exception.getMessage()); - } - return null; - } - - public T executeQuery(String query, RowMapper rowMapper) { - return executeQuery(query, rowMapper, preparedStatement -> { - }); - } - - public Long executeUpdate(String query, PreparedStatementSetter preparedStatementSetter) { - try (Connection connection = dataSource.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS) - ) { - preparedStatementSetter.setArgument(preparedStatement); - preparedStatement.executeUpdate(); - return generatedKey(preparedStatement); - } catch (SQLException e) { - throw new IllegalArgumentException(e.getMessage()); - } - } - - private Long generatedKey(final PreparedStatement preparedStatement) { - try (ResultSet resultSet = preparedStatement.getGeneratedKeys()) { - if (resultSet.next()) { - return resultSet.getLong(1); - } - return null; - } catch (SQLException e) { - throw new IllegalArgumentException(e.getMessage()); - } - } - - public Long executeUpdate(String query) { - return executeUpdate(query, preparedStatement -> { - }); - } - -} diff --git a/src/main/java/wooteco/chess/database/MySqlDataSource.java b/src/main/java/wooteco/chess/database/MySqlDataSource.java deleted file mode 100644 index 5199bccde1..0000000000 --- a/src/main/java/wooteco/chess/database/MySqlDataSource.java +++ /dev/null @@ -1,46 +0,0 @@ -package wooteco.chess.database; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; - -import org.springframework.stereotype.Component; - -@Component("CustomDataSource") -public class MySqlDataSource implements DataSource { - - private static final String server = "127.0.0.1:13306"; // MySQL 서버 주소 - private static final String database = "woowa_level_01_chess"; // MySQL DATABASE 이름 - private static final String option = "?useSSL=false&serverTimezone=UTC"; - private static final String userName = "root"; // MySQL 서버 아이디 - private static final String password = "root"; // MySQL 서버 비밀번호 - private static final String CONNECTION_FORMAT = "jdbc:mysql://%s/%s%s"; - - private MySqlDataSource() { - } - - public static MySqlDataSource getInstance() { - return LazyHolder.INSTANCE; - } - - @Override - public Connection getConnection() { - try { - Class.forName("com.mysql.cj.jdbc.Driver"); - return DriverManager.getConnection(String.format(CONNECTION_FORMAT, server, database, option), userName, - password); - } catch (ClassNotFoundException e) { - System.err.println("JDBC Driver load 오류: " + e.getMessage()); - e.printStackTrace(); - } catch (SQLException e) { - System.err.println("연결 오류:" + e.getMessage()); - e.printStackTrace(); - } - return null; - } - - private static class LazyHolder { - private static final MySqlDataSource INSTANCE = new MySqlDataSource(); - } - -} diff --git a/src/main/java/wooteco/chess/database/PreparedStatementSetter.java b/src/main/java/wooteco/chess/database/PreparedStatementSetter.java deleted file mode 100644 index 86042a15bb..0000000000 --- a/src/main/java/wooteco/chess/database/PreparedStatementSetter.java +++ /dev/null @@ -1,10 +0,0 @@ -package wooteco.chess.database; - -import java.sql.PreparedStatement; -import java.sql.SQLException; - -public interface PreparedStatementSetter { - - void setArgument(PreparedStatement preparedStatement) throws SQLException; - -} diff --git a/src/main/java/wooteco/chess/database/RowMapper.java b/src/main/java/wooteco/chess/database/RowMapper.java deleted file mode 100644 index 94c39cdf9d..0000000000 --- a/src/main/java/wooteco/chess/database/RowMapper.java +++ /dev/null @@ -1,10 +0,0 @@ -package wooteco.chess.database; - -import java.sql.ResultSet; -import java.sql.SQLException; - -public interface RowMapper { - - T mapRow(ResultSet resultSet) throws SQLException; - -} diff --git a/src/main/java/wooteco/chess/entity/BaseEntity.java b/src/main/java/wooteco/chess/entity/BaseEntity.java deleted file mode 100644 index 32d8ff50b5..0000000000 --- a/src/main/java/wooteco/chess/entity/BaseEntity.java +++ /dev/null @@ -1,24 +0,0 @@ -package wooteco.chess.entity; - -import java.time.LocalDateTime; -import java.util.Objects; - -public abstract class BaseEntity implements Comparable { - - protected final LocalDateTime createdTime; - - protected BaseEntity(final LocalDateTime createdTime) { - Objects.requireNonNull(createdTime, "생성 시간이 null입니다."); - this.createdTime = createdTime; - } - - public LocalDateTime getCreatedTime() { - return createdTime; - } - - @Override - public int compareTo(final BaseEntity that) { - return this.createdTime.compareTo(that.createdTime); - } - -} diff --git a/src/main/java/wooteco/chess/entity/ChessGameEntity.java b/src/main/java/wooteco/chess/entity/ChessGameEntity.java deleted file mode 100644 index a1d1a3e3f6..0000000000 --- a/src/main/java/wooteco/chess/entity/ChessGameEntity.java +++ /dev/null @@ -1,34 +0,0 @@ -package wooteco.chess.entity; - -import java.time.LocalDateTime; -import java.util.Objects; - -public class ChessGameEntity extends BaseEntity { - - private static final long DEFAULT_GAME_ID = 0L; - - private final long gameId; - - private ChessGameEntity(final long gameId, final LocalDateTime createdTime) { - super(createdTime); - this.gameId = gameId; - } - - public static ChessGameEntity of(final long gameId, final LocalDateTime createdTime) { - return new ChessGameEntity(gameId, createdTime); - } - - public static ChessGameEntity of(final long gameId, final ChessGameEntity entity) { - Objects.requireNonNull(entity, "엔티티가 null입니다."); - return new ChessGameEntity(gameId, entity.createdTime); - } - - public static ChessGameEntity of(final LocalDateTime createdTime) { - return new ChessGameEntity(DEFAULT_GAME_ID, createdTime); - } - - public long getGameId() { - return gameId; - } - -} diff --git a/src/main/java/wooteco/chess/entity/ChessHistoryEntity.java b/src/main/java/wooteco/chess/entity/ChessHistoryEntity.java deleted file mode 100644 index 5bd3ac8ea0..0000000000 --- a/src/main/java/wooteco/chess/entity/ChessHistoryEntity.java +++ /dev/null @@ -1,76 +0,0 @@ -package wooteco.chess.entity; - -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Arrays; -import java.util.Objects; - -import wooteco.chess.domain.chessGame.ChessCommand; - -public class ChessHistoryEntity extends BaseEntity { - - private static final long DEFAULT_HISTORY_ID = 0L; - private static final long DEFAULT_GAME_ID = 0L; - private static final String MOVE_COMMAND = "move"; - - private final long historyId; - private final long gameId; - private final String start; - private final String end; - - private ChessHistoryEntity(final long historyId, final long gameId, final String start, final String end, - final LocalDateTime createdTime) { - super(createdTime); - validate(start, end); - this.historyId = historyId; - this.gameId = gameId; - this.start = start; - this.end = end; - } - - public static ChessHistoryEntity of(final long historyId, final long gameId, final String start, final String end, - final LocalDateTime createdTime) { - return new ChessHistoryEntity(historyId, gameId, start, end, createdTime); - } - - public static ChessHistoryEntity of(final long gameId, final String start, final String end, - final LocalDateTime createdTime) { - return new ChessHistoryEntity(DEFAULT_HISTORY_ID, gameId, start, end, createdTime); - } - - public static ChessHistoryEntity of(final String start, final String end) { - return new ChessHistoryEntity(DEFAULT_HISTORY_ID, DEFAULT_GAME_ID, start, end, - LocalDateTime.now(ZoneId.of("Asia/Seoul"))); - } - - public static ChessHistoryEntity of(final long historyId, final ChessHistoryEntity entity) { - Objects.requireNonNull(entity, "엔티티가 null입니다."); - return new ChessHistoryEntity(historyId, entity.gameId, entity.start, entity.end, entity.createdTime); - } - - private void validate(final String start, final String end) { - Objects.requireNonNull(start, "출발 위치가 null입니다."); - Objects.requireNonNull(end, "도착 위치가 null입니다."); - } - - public ChessCommand generateMoveCommand() { - return ChessCommand.of(Arrays.asList(MOVE_COMMAND, start, end)); - } - - public long getHistoryId() { - return historyId; - } - - public long getGameId() { - return gameId; - } - - public String getStart() { - return start; - } - - public String getEnd() { - return end; - } - -} diff --git a/src/main/java/wooteco/chess/entity/GameHistory.java b/src/main/java/wooteco/chess/entity/GameHistory.java new file mode 100644 index 0000000000..186fdfe468 --- /dev/null +++ b/src/main/java/wooteco/chess/entity/GameHistory.java @@ -0,0 +1,56 @@ +package wooteco.chess.entity; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; +import wooteco.chess.domain.chessGame.ChessCommand; + +import java.util.Arrays; + +@Table("game_history") +public class GameHistory { + + private static final String MOVE_COMMAND = "move"; + + @Id + private Long id; + + @Column("source_position") + private String sourcePosition; + + @Column("target_position") + private String targetPosition; + + @Column("game_room") + private Long gameRoom; + + public GameHistory() { + } + + public GameHistory(final String sourcePosition, final String targetPosition, final Long gameRoom) { + this.sourcePosition = sourcePosition; + this.targetPosition = targetPosition; + this.gameRoom = gameRoom; + } + + public ChessCommand generateMoveCommand() { + return ChessCommand.of(Arrays.asList(MOVE_COMMAND, sourcePosition, targetPosition)); + } + + public Long getId() { + return id; + } + + public String getSourcePosition() { + return sourcePosition; + } + + public String getTargetPosition() { + return targetPosition; + } + + public Long getGameRoom() { + return gameRoom; + } + +} diff --git a/src/main/java/wooteco/chess/entity/GameRoom.java b/src/main/java/wooteco/chess/entity/GameRoom.java new file mode 100644 index 0000000000..e69e419f6e --- /dev/null +++ b/src/main/java/wooteco/chess/entity/GameRoom.java @@ -0,0 +1,58 @@ +package wooteco.chess.entity; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Table; + +import java.util.LinkedHashSet; +import java.util.Set; + +@Table("game_room") +public class GameRoom { + + @Id + private Long id; + private String name; + private Boolean state; + private Set gameHistories; + + public GameRoom() { + } + + public GameRoom(final String name) { + this.name = name; + this.state = false; + this.gameHistories = new LinkedHashSet<>(); + } + + public GameRoom(final GameRoom gameRoom, final boolean state) { + this.id = gameRoom.id; + this.name = gameRoom.name; + this.state = state; + this.gameHistories = gameRoom.gameHistories; + } + + public void addGameHistory(GameHistory gameHistory) { + gameHistories.add(gameHistory); + } + + public void removeGameHistory(GameHistory gameHistory) { + gameHistories.remove(gameHistory); + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public Boolean getState() { + return state; + } + + public Set getGameHistories() { + return gameHistories; + } + +} diff --git a/src/main/java/wooteco/chess/service/ChessService.java b/src/main/java/wooteco/chess/service/ChessService.java index c97fadbb04..98f8f16c0d 100644 --- a/src/main/java/wooteco/chess/service/ChessService.java +++ b/src/main/java/wooteco/chess/service/ChessService.java @@ -1,93 +1,97 @@ package wooteco.chess.service; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Arrays; -import java.util.Objects; - import org.springframework.stereotype.Service; - -import wooteco.chess.dao.ChessGameDao; -import wooteco.chess.dao.ChessHistoryDao; +import wooteco.chess.database.GameRoomRepository; import wooteco.chess.domain.chessBoard.ChessBoard; import wooteco.chess.domain.chessBoard.ChessBoardInitializer; import wooteco.chess.domain.chessGame.ChessCommand; import wooteco.chess.domain.chessGame.ChessGame; -import wooteco.chess.entity.ChessGameEntity; -import wooteco.chess.entity.ChessHistoryEntity; +import wooteco.chess.entity.GameHistory; +import wooteco.chess.entity.GameRoom; import wooteco.chess.service.dto.ChessGameDto; +import java.util.Arrays; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; + +import static java.util.stream.Collectors.toList; + @Service public class ChessService { private static final String MOVE_COMMAND = "move"; - private final ChessGameDao chessGameDao; - private final ChessHistoryDao chessHistoryDao; - - public ChessService(final ChessGameDao chessGameDao, final ChessHistoryDao chessHistoryDao) { - Objects.requireNonNull(chessGameDao, "ChessGameDao가 null입니다."); - Objects.requireNonNull(chessHistoryDao, "ChessHistoryDao가 null입니다."); - this.chessGameDao = chessGameDao; - this.chessHistoryDao = chessHistoryDao; - checkChessGameIsEmpty(chessGameDao); - } - - private void checkChessGameIsEmpty(final ChessGameDao chessGameDao) { - if (chessGameDao.isEmpty()) { - final ChessGameEntity entity = ChessGameEntity.of(LocalDateTime.now(ZoneId.of("Asia/Seoul"))); + private final GameRoomRepository gameRoomRepository; - chessGameDao.add(entity); - } + public ChessService(final GameRoomRepository gameRoomRepository) { + this.gameRoomRepository = gameRoomRepository; } - public ChessGameDto loadChessGame() { - final long gameId = chessGameDao.findMaxGameId(); - return ChessGameDto.of(initChessGameOf(gameId)); + public ChessGameDto loadChessGameByName(String name) { + GameRoom gameRoom = gameRoomRepository.findByName(name); + return ChessGameDto.of(gameRoom.getId(), initChessGameOf(gameRoom)); } - private ChessGame initChessGameOf(final long gameId) { + private ChessGame initChessGameOf(final GameRoom gameRoom) { final ChessBoard chessBoard = new ChessBoard(ChessBoardInitializer.create()); final ChessGame chessGame = ChessGame.from(chessBoard); - chessHistoryDao.findAllByGameId(gameId).stream() - .sorted(ChessHistoryEntity::compareTo) - .map(ChessHistoryEntity::generateMoveCommand) + gameRoom.getGameHistories().stream() + .map(GameHistory::generateMoveCommand) .forEach(chessGame::move); + return chessGame; } - public ChessGameDto playChessGame(final String sourcePosition, final String targetPosition) { + public ChessGameDto playChessGame(final Long gameId, final String sourcePosition, final String targetPosition) { Objects.requireNonNull(sourcePosition, "소스 위치가 null입니다."); Objects.requireNonNull(targetPosition, "타겟 위치가 null입니다."); - return moveChessPiece(sourcePosition, targetPosition); + return moveChessPiece(gameId, sourcePosition, targetPosition); } - private ChessGameDto moveChessPiece(final String sourcePosition, final String targetPosition) { - final long gameId = chessGameDao.findMaxGameId(); - final ChessGame chessGame = initChessGameOf(gameId); + private ChessGameDto moveChessPiece(final Long gameId, final String sourcePosition, final String targetPosition) { + GameRoom gameRoom = gameRoomRepository.findById(gameId) + .orElseThrow(() -> new NoSuchElementException("게임이 존재하지 않습니다.")); + + final ChessGame chessGame = initChessGameOf(gameRoom); final ChessCommand chessCommand = ChessCommand.of(Arrays.asList(MOVE_COMMAND, sourcePosition, targetPosition)); - final ChessHistoryEntity chessHistoryEntity = - ChessHistoryEntity.of(gameId, sourcePosition, targetPosition, LocalDateTime.now(ZoneId.of("Asia/Seoul"))); chessGame.move(chessCommand); - chessHistoryDao.add(chessHistoryEntity); - return ChessGameDto.of(chessGame); - } + gameRoom.addGameHistory(new GameHistory(sourcePosition, targetPosition, gameId)); - public ChessGameDto createChessGame() { - final ChessGameEntity entity = ChessGameEntity.of(LocalDateTime.now(ZoneId.of("Asia/Seoul"))); - final long gameId = chessGameDao.add(entity); + gameRoomRepository.save(gameRoom); + + return ChessGameDto.of(gameRoom.getId(), chessGame); + } - return ChessGameDto.of(initChessGameOf(gameId)); + public ChessGameDto createChessGame(final String name) { + GameRoom savedGameRoom = gameRoomRepository.save(new GameRoom(name)); + return ChessGameDto.of(savedGameRoom.getId(), initChessGameOf(savedGameRoom)); } - public ChessGameDto endChessGame() { - final long gameId = chessGameDao.findMaxGameId(); - final ChessGame chessGame = initChessGameOf(gameId); + public ChessGameDto endChessGame(final Long gameId) { + GameRoom gameRoom = gameRoomRepository.findById(gameId) + .orElseThrow(() -> new NoSuchElementException("게임이 존재하지 않습니다.")); + final ChessGame chessGame = initChessGameOf(gameRoom); chessGame.end(); - return ChessGameDto.of(chessGame); + gameRoomRepository.save(new GameRoom(gameRoom, true)); + return ChessGameDto.of(gameRoom.getId(), chessGame); + } + + public boolean isEndGame(final Long gameId) { + GameRoom gameRoom = gameRoomRepository.findById(gameId) + .orElseThrow(() -> new NoSuchElementException("게임이 존재하지 않습니다.")); + return gameRoom.getState(); + } + + public List showAllGames() { + List gameRooms = gameRoomRepository.findAll(); + + return gameRooms.stream() + .map(GameRoom::getName) + .collect(toList()); } } diff --git a/src/main/java/wooteco/chess/service/dto/ChessGameDto.java b/src/main/java/wooteco/chess/service/dto/ChessGameDto.java index e12f3a9b46..f0ea1f1124 100644 --- a/src/main/java/wooteco/chess/service/dto/ChessGameDto.java +++ b/src/main/java/wooteco/chess/service/dto/ChessGameDto.java @@ -1,19 +1,21 @@ package wooteco.chess.service.dto; -import java.util.Objects; - import wooteco.chess.domain.chessGame.ChessGame; +import java.util.Objects; + public class ChessGameDto { + private final Long id; private final ChessBoardDto chessBoardDto; private final PieceColorDto pieceColorDto; private final ChessStatusDtos chessStatusDtos; private final boolean isEndState; private final boolean isKingCaught; - private ChessGameDto(final ChessBoardDto chessBoardDto, final PieceColorDto pieceColorDto, + private ChessGameDto(final Long id, final ChessBoardDto chessBoardDto, final PieceColorDto pieceColorDto, final ChessStatusDtos chessStatusDtos, final boolean isEndState, final boolean isKingCaught) { + this.id = id; this.chessBoardDto = chessBoardDto; this.pieceColorDto = pieceColorDto; this.chessStatusDtos = chessStatusDtos; @@ -21,7 +23,7 @@ private ChessGameDto(final ChessBoardDto chessBoardDto, final PieceColorDto piec this.isKingCaught = isKingCaught; } - public static ChessGameDto of(final ChessGame chessGame) { + public static ChessGameDto of(final Long id, final ChessGame chessGame) { Objects.requireNonNull(chessGame, "체스 게임이 null입니다."); final ChessBoardDto chessBoardDto = ChessBoardDto.of(chessGame.getChessBoard()); @@ -30,7 +32,11 @@ public static ChessGameDto of(final ChessGame chessGame) { final boolean isEndStatus = chessGame.isEndState(); final boolean isKingCaught = chessGame.isKingCaught(); - return new ChessGameDto(chessBoardDto, pieceColorDto, chessStatusDtos, isEndStatus, isKingCaught); + return new ChessGameDto(id, chessBoardDto, pieceColorDto, chessStatusDtos, isEndStatus, isKingCaught); + } + + public Long getId() { + return id; } public ChessBoardDto getChessBoardDto() { diff --git a/src/main/java/wooteco/chess/util/ChessBoardRenderer.java b/src/main/java/wooteco/chess/util/ChessBoardRenderer.java deleted file mode 100644 index c8f5a035a7..0000000000 --- a/src/main/java/wooteco/chess/util/ChessBoardRenderer.java +++ /dev/null @@ -1,61 +0,0 @@ -package wooteco.chess.util; - -import static java.util.stream.Collectors.*; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -import wooteco.chess.domain.chessBoard.ChessBoard; -import wooteco.chess.domain.position.ChessFile; -import wooteco.chess.domain.position.ChessRank; -import wooteco.chess.domain.position.Position; - -public class ChessBoardRenderer { - - private static final String EMPTY_SPACE = ""; - private static final String DELIMITER = " "; - private static final String RANK_APPEND_FORMAT = "%s %s"; - private static final String EMPTY_POSITION = "."; - - public static List render(final ChessBoard chessBoard) { - Objects.requireNonNull(chessBoard, "체스 보드가 null입니다."); - final List renderedChessBoard = renderEachChessRankFrom(chessBoard); - - Collections.reverse(renderedChessBoard); - appendChessFileName(renderedChessBoard); - return renderedChessBoard; - } - - private static List renderEachChessRankFrom(final ChessBoard chessBoard) { - return Arrays.stream(ChessRank.values()) - .map(chessRank -> renderChessRankFrom(chessBoard, chessRank)) - .collect(toList()); - } - - private static String renderChessRankFrom(final ChessBoard chessBoard, final ChessRank chessRank) { - return Arrays.stream(ChessFile.values()) - .map(chessFile -> renderChessPieceFrom(chessBoard, chessRank, chessFile)) - .collect(collectingAndThen(joining(DELIMITER), - renderedRank -> String.format(RANK_APPEND_FORMAT, renderedRank, chessRank))); - } - - private static String renderChessPieceFrom(final ChessBoard chessBoard, final ChessRank chessRank, - final ChessFile chessFile) { - final Position renderingPosition = Position.of(chessFile, chessRank); - - if (chessBoard.isChessPieceOn(renderingPosition)) { - return chessBoard.getChessPieceNameOn(renderingPosition); - } - return EMPTY_POSITION; - } - - private static void appendChessFileName(final List renderedChessBoard) { - renderedChessBoard.add(EMPTY_SPACE); - renderedChessBoard.add(Arrays.stream(ChessFile.values()) - .map(ChessFile::toString) - .collect(joining(DELIMITER))); - } - -} diff --git a/src/main/java/wooteco/chess/util/StringUtil.java b/src/main/java/wooteco/chess/util/StringUtil.java deleted file mode 100644 index 242c74c80c..0000000000 --- a/src/main/java/wooteco/chess/util/StringUtil.java +++ /dev/null @@ -1,21 +0,0 @@ -package wooteco.chess.util; - -import static java.util.stream.Collectors.*; - -import java.util.Arrays; -import java.util.List; -import java.util.Objects; - -public class StringUtil { - - private static final String DELIMITER = " "; - - public static List splitChessCommand(final String chessCommand) { - Objects.requireNonNull(chessCommand, "분리할 명령어가 null입니다."); - - return Arrays.stream(chessCommand.split(DELIMITER)) - .map(String::trim) - .collect(toList()); - } - -} diff --git a/src/main/java/wooteco/chess/view/ConsoleInputView.java b/src/main/java/wooteco/chess/view/ConsoleInputView.java deleted file mode 100644 index 84b9a39d11..0000000000 --- a/src/main/java/wooteco/chess/view/ConsoleInputView.java +++ /dev/null @@ -1,14 +0,0 @@ -package wooteco.chess.view; - -import java.util.Scanner; - -public class ConsoleInputView { - - private static final Scanner SCANNER = new Scanner(System.in); - - public static String inputChessCommand() { - System.out.print(ConsoleOutputView.PROMPT); - return SCANNER.nextLine(); - } - -} diff --git a/src/main/java/wooteco/chess/view/ConsoleOutputView.java b/src/main/java/wooteco/chess/view/ConsoleOutputView.java deleted file mode 100644 index 9626f354f0..0000000000 --- a/src/main/java/wooteco/chess/view/ConsoleOutputView.java +++ /dev/null @@ -1,40 +0,0 @@ -package wooteco.chess.view; - -import java.util.List; - -import wooteco.chess.domain.chessPiece.pieceType.PieceColor; - -public class ConsoleOutputView { - - static final String PROMPT = "> "; - - private static void printNewLine() { - System.out.println(); - } - - public static void printChessStart() { - System.out.println(PROMPT + "체스 게임을 시작합니다."); - System.out.println(PROMPT + "게임 시작 : start"); - System.out.println(PROMPT + "게임 이동 : move source위치 target위치 - 예. move b2 b3"); - System.out.println(PROMPT + "게임 점수 : status 체스 색상 - 예. status white, status black"); - System.out.println(PROMPT + "게임 종료 : end"); - } - - public static void printChessBoard(List renderedChessBoard) { - printNewLine(); - renderedChessBoard.forEach(System.out::println); - } - - public static void printStatus(PieceColor statusPieceColor, double score) { - System.out.println(String.format("%s 점수 : %.1f", statusPieceColor.getColor(), score)); - } - - public static void printKingCaught(PieceColor catchingPieceColor) { - System.out.println(String.format("%s가 킹을 잡았습니다.", catchingPieceColor.getColor())); - } - - public static void printChessEnd() { - System.out.println(PROMPT + "게임 종료!"); - } - -} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 69b89983cb..8f3e0fb1a2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,11 @@ -spring.h2.console.enabled=true \ No newline at end of file +# H2 +#spring.h2.console.enabled=true +# MySql +spring.datasource.url=jdbc:mysql://localhost:13306/woowa_level_02_chess?useSSL=false&serverTimezone=UTC +spring.datasource.username=root +spring.datasource.password=root +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.datasource.initialization-mode=ALWAYS +# Logging +logging.level.org.springframework.web=DEBUG +logging.level.org.springframework.jdbc=TRACE \ No newline at end of file diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 0000000000..c4338a08fc --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,15 @@ +CREATE TABLE if not exists game_room +( + id bigint AUTO_INCREMENT primary key, + name varchar(255) NOT NULL unique, + state boolean NOT NULL +); + +CREATE TABLE if not exists game_history +( + id bigint AUTO_INCREMENT primary key, + game_room bigint NOT NULL, + source_position varchar(5) NOT NULL, + target_position varchar(5) NOT NULL, + created_time timestamp NOT NULL +); \ No newline at end of file diff --git a/src/test/java/wooteco/chess/dao/InMemoryChessGameDao.java b/src/test/java/wooteco/chess/dao/InMemoryChessGameDao.java deleted file mode 100644 index 8eed5866d2..0000000000 --- a/src/test/java/wooteco/chess/dao/InMemoryChessGameDao.java +++ /dev/null @@ -1,45 +0,0 @@ -package wooteco.chess.dao; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -import wooteco.chess.entity.ChessGameEntity; - -public class InMemoryChessGameDao implements ChessGameDao { - - private final Map chessGameRepository = new HashMap<>(); - private long autoIncrement; - - public InMemoryChessGameDao() { - this.autoIncrement = 0L; - } - - @Override - public long add(final ChessGameEntity entity) { - Objects.requireNonNull(entity, "엔티티가 null입니다."); - autoIncrement++; - - final ChessGameEntity chessGameEntity = ChessGameEntity.of(autoIncrement, entity); - - chessGameRepository.put(autoIncrement, chessGameEntity); - return autoIncrement; - } - - @Override - public long findMaxGameId() { - return autoIncrement; - } - - @Override - public boolean isEmpty() { - return chessGameRepository.isEmpty(); - } - - @Override - public void deleteAll() { - autoIncrement = 0L; - chessGameRepository.clear(); - } - -} diff --git a/src/test/java/wooteco/chess/dao/InMemoryChessHistoryDao.java b/src/test/java/wooteco/chess/dao/InMemoryChessHistoryDao.java deleted file mode 100644 index d67c80a634..0000000000 --- a/src/test/java/wooteco/chess/dao/InMemoryChessHistoryDao.java +++ /dev/null @@ -1,43 +0,0 @@ -package wooteco.chess.dao; - -import static java.util.stream.Collectors.*; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import wooteco.chess.entity.ChessHistoryEntity; - -public class InMemoryChessHistoryDao implements ChessHistoryDao { - - private final Map chessHistoryRepository = new HashMap<>(); - private long autoIncrement; - - public InMemoryChessHistoryDao() { - this.autoIncrement = 0L; - } - - @Override - public List findAllByGameId(final long gameId) { - return chessHistoryRepository.values().stream() - .filter(entity -> entity.getGameId() == gameId) - .collect(toList()); - } - - @Override - public void add(final ChessHistoryEntity entity) { - Objects.requireNonNull(entity, "엔티티가 null입니다."); - autoIncrement++; - - final ChessHistoryEntity chessHistoryEntity = ChessHistoryEntity.of(autoIncrement, entity); - - chessHistoryRepository.put(autoIncrement, chessHistoryEntity); - } - - @Override - public void deleteAll() { - chessHistoryRepository.clear(); - } - -} diff --git a/src/test/java/wooteco/chess/dao/MySqlChessGameDaoTest.java b/src/test/java/wooteco/chess/dao/MySqlChessGameDaoTest.java deleted file mode 100644 index b0eb5f40ad..0000000000 --- a/src/test/java/wooteco/chess/dao/MySqlChessGameDaoTest.java +++ /dev/null @@ -1,133 +0,0 @@ -package wooteco.chess.dao; - -import static org.assertj.core.api.Assertions.*; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullSource; - -import wooteco.chess.database.JdbcTemplate; -import wooteco.chess.database.MySqlDataSource; -import wooteco.chess.entity.ChessGameEntity; - -class MySqlChessGameDaoTest { - - private static final String CHESS_GAME_TABLE = "chess_games"; - private static final long INIT_AUTO_INCREMENT = 1L; - - private JdbcTemplate jdbcTemplate; - - @BeforeEach - void setUp() { - jdbcTemplate = new JdbcTemplate(MySqlDataSource.getInstance()); - - final String query1 = "DELETE FROM " + CHESS_GAME_TABLE; - jdbcTemplate.executeUpdate(query1); - - final String query2 = "ALTER TABLE " + CHESS_GAME_TABLE + " AUTO_INCREMENT = ?"; - jdbcTemplate.executeUpdate(query2, - preparedStatement -> preparedStatement.setLong(1, INIT_AUTO_INCREMENT)); - } - - @ParameterizedTest - @NullSource - void MySqlChessGameDao_NullJdbcTemplate_ExceptionThrown(final JdbcTemplate jdbcTemplate) { - assertThatThrownBy(() -> new MySqlChessGameDao(jdbcTemplate)) - .isInstanceOf(NullPointerException.class) - .hasMessage("JdbcTemplate이 null입니다."); - } - - @Test - void MySqlChessGameDao_JdbcTemplate_GenerateInstance() { - assertThat(new MySqlChessGameDao(jdbcTemplate)).isInstanceOf(MySqlChessGameDao.class); - } - - @ParameterizedTest - @NullSource - void add_NullChessGameEntity_ExceptionThrown(final ChessGameEntity entity) { - final MySqlChessGameDao mySqlChessGameDao = new MySqlChessGameDao(jdbcTemplate); - - assertThatThrownBy(() -> mySqlChessGameDao.add(entity)) - .isInstanceOf(NullPointerException.class) - .hasMessage("엔티티가 null입니다."); - } - - @Test - void add_ChessGameEntity_InsertChessGame() { - final MySqlChessGameDao mySqlChessGameDao = new MySqlChessGameDao(jdbcTemplate); - final ChessGameEntity entity = ChessGameEntity.of(LocalDateTime.now()); - - assertThat(mySqlChessGameDao.add(entity)).isEqualTo(INIT_AUTO_INCREMENT); - } - - @Test - void findMaxGameId_EmptyChessGame_ExceptionThrown() { - final MySqlChessGameDao mySqlChessGameDao = new MySqlChessGameDao(jdbcTemplate); - - assertThat(mySqlChessGameDao.findMaxGameId()).isEqualTo(MySqlChessGameDao.EMPTY_CHESS_GAME); - } - - @Test - void findMaxGameId_ReturnMaxGameId() { - final MySqlChessGameDao mySqlChessGameDao = new MySqlChessGameDao(jdbcTemplate); - final ChessGameEntity entity = ChessGameEntity.of(LocalDateTime.now()); - mySqlChessGameDao.add(entity); - - assertThat(mySqlChessGameDao.findMaxGameId()).isEqualTo(INIT_AUTO_INCREMENT); - } - - @Test - void isEmpty_EmptyChessGame_ReturnTrue() { - final MySqlChessGameDao mySqlChessGameDao = new MySqlChessGameDao(jdbcTemplate); - - assertThat(mySqlChessGameDao.isEmpty()).isTrue(); - } - - @Test - void isEmpty_NotEmptyChessGame_ReturnFalse() { - final MySqlChessGameDao mySqlChessGameDao = new MySqlChessGameDao(jdbcTemplate); - final ChessGameEntity entity = ChessGameEntity.of(LocalDateTime.now()); - mySqlChessGameDao.add(entity); - - assertThat(mySqlChessGameDao.isEmpty()).isFalse(); - } - - @Test - void deleteAll_ExistChessGame_DeleteAllFromChessGameTable() { - final MySqlChessGameDao mySqlChessGameDao = new MySqlChessGameDao(jdbcTemplate); - final ChessGameEntity entity = ChessGameEntity.of(LocalDateTime.now()); - mySqlChessGameDao.add(entity); - mySqlChessGameDao.deleteAll(); - - assertThat(findAll().isEmpty()).isTrue(); - } - - private List findAll() { - final String query = "SELECT * FROM " + CHESS_GAME_TABLE; - - return jdbcTemplate.executeQuery(query, resultSet -> { - final List entities = new ArrayList<>(); - - while (resultSet.next()) { - entities.add(ChessGameEntity.of( - resultSet.getLong("game_id"), - resultSet.getTimestamp("created_time").toLocalDateTime())); - } - return entities; - }); - } - - @AfterEach - void tearDown() { - final String query = "DELETE FROM " + CHESS_GAME_TABLE; - - jdbcTemplate.executeUpdate(query); - } - -} \ No newline at end of file diff --git a/src/test/java/wooteco/chess/dao/MySqlChessHistoryDaoTest.java b/src/test/java/wooteco/chess/dao/MySqlChessHistoryDaoTest.java deleted file mode 100644 index e779623f96..0000000000 --- a/src/test/java/wooteco/chess/dao/MySqlChessHistoryDaoTest.java +++ /dev/null @@ -1,131 +0,0 @@ -package wooteco.chess.dao; - -import static org.assertj.core.api.Assertions.*; - -import java.sql.ResultSet; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullSource; - -import wooteco.chess.database.JdbcTemplate; -import wooteco.chess.database.MySqlDataSource; -import wooteco.chess.entity.ChessHistoryEntity; - -class MySqlChessHistoryDaoTest { - - private static final String CHESS_HISTORY_TABLE = "chess_histories"; - private static final long INIT_AUTO_INCREMENT = 1L; - - private JdbcTemplate jdbcTemplate; - - @BeforeEach - void setUp() { - jdbcTemplate = new JdbcTemplate(MySqlDataSource.getInstance()); - - final String query1 = "DELETE FROM " + CHESS_HISTORY_TABLE; - jdbcTemplate.executeUpdate(query1); - - final String query2 = "ALTER TABLE " + CHESS_HISTORY_TABLE + " AUTO_INCREMENT = ?"; - jdbcTemplate.executeUpdate(query2, - preparedStatement -> preparedStatement.setLong(1, INIT_AUTO_INCREMENT)); - } - - @ParameterizedTest - @NullSource - void MySqlChessHistoryDao_NullJdbcTemplate_ExceptionThrown(final JdbcTemplate jdbcTemplate) { - assertThatThrownBy(() -> new MySqlChessHistoryDao(jdbcTemplate)) - .isInstanceOf(NullPointerException.class) - .hasMessage("JdbcTemplate이 null입니다."); - } - - @Test - void MySqlChessHistoryDao_JdbcTemplate_GenerateInstance() { - assertThat(new MySqlChessHistoryDao(jdbcTemplate)).isInstanceOf(MySqlChessHistoryDao.class); - } - - @Test - void findAllByGameId_GameId_ReturnChessHistoryEntities() { - final MySqlChessHistoryDao mySqlChessHistoryDao = new MySqlChessHistoryDao(jdbcTemplate); - final long gameId = 1; - final ChessHistoryEntity value = ChessHistoryEntity.of(gameId, "b2", "b4", LocalDateTime.now()); - mySqlChessHistoryDao.add(value); - - assertThat(isSame(mySqlChessHistoryDao.findAllByGameId(gameId), value)).isTrue(); - } - - private boolean isSame(final List actual, final ChessHistoryEntity expected) { - return actual.size() == 1 - && actual.get(0).getGameId() == expected.getGameId() - && actual.get(0).getStart().equals(expected.getStart()) - && actual.get(0).getEnd().equals(expected.getEnd()); - } - - @ParameterizedTest - @NullSource - void add_NullChessHistoryEntity_ExceptionThrown(final ChessHistoryEntity entity) { - final MySqlChessHistoryDao mySqlChessHistoryDao = new MySqlChessHistoryDao(jdbcTemplate); - - assertThatThrownBy(() -> mySqlChessHistoryDao.add(entity)) - .isInstanceOf(NullPointerException.class) - .hasMessage("엔티티가 null입니다."); - } - - @Test - void add_ChessHistoryEntity_InsertChessHistory() { - final MySqlChessHistoryDao mySqlChessHistoryDao = new MySqlChessHistoryDao(jdbcTemplate); - final long gameId = 1; - mySqlChessHistoryDao.add(ChessHistoryEntity.of(gameId, "b2", "b4", LocalDateTime.now())); - - assertThat(isChessHistoryExist("b2", "b4")).isTrue(); - } - - private boolean isChessHistoryExist(final String start, final String end) { - final String query = "SELECT * FROM " + CHESS_HISTORY_TABLE + " WHERE start = ? AND end = ?"; - - return jdbcTemplate.executeQuery(query, ResultSet::next, preparedStatement -> { - preparedStatement.setString(1, start); - preparedStatement.setString(2, end); - }); - } - - @Test - void deleteAll_DeleteAllChessHistoryFromChessHistoryTable() { - final MySqlChessHistoryDao mySqlChessHistoryDao = new MySqlChessHistoryDao(jdbcTemplate); - mySqlChessHistoryDao.add(ChessHistoryEntity.of("b2", "b4")); - mySqlChessHistoryDao.deleteAll(); - - assertThat(findAll().isEmpty()).isTrue(); - } - - private List findAll() { - final String query = "SELECT * FROM " + CHESS_HISTORY_TABLE; - - return jdbcTemplate.executeQuery(query, resultSet -> { - final List entities = new ArrayList<>(); - - while (resultSet.next()) { - entities.add(ChessHistoryEntity.of( - resultSet.getLong("history_id"), - resultSet.getLong("game_id"), - resultSet.getString("start"), - resultSet.getString("end"), - resultSet.getTimestamp("created_time").toLocalDateTime())); - } - return entities; - }); - } - - @AfterEach - void tearDown() { - final String query = "DELETE FROM " + CHESS_HISTORY_TABLE; - - jdbcTemplate.executeUpdate(query); - } - -} \ No newline at end of file diff --git a/src/test/java/wooteco/chess/database/GameRoomRepositoryTest.java b/src/test/java/wooteco/chess/database/GameRoomRepositoryTest.java new file mode 100644 index 0000000000..fc3ffcfeff --- /dev/null +++ b/src/test/java/wooteco/chess/database/GameRoomRepositoryTest.java @@ -0,0 +1,44 @@ +package wooteco.chess.database; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.data.jdbc.DataJdbcTest; +import org.springframework.data.relational.core.conversion.DbActionExecutionException; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.transaction.annotation.Transactional; +import wooteco.chess.entity.GameRoom; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@ExtendWith(SpringExtension.class) +@DataJdbcTest +@Transactional +class GameRoomRepositoryTest { + + @Autowired + GameRoomRepository gameRoomRepository; + + @DisplayName("이름으로 게임방을 검색하기") + @Test + void findByName() { + String gameRoomName = "test"; + GameRoom savedGameRoom = gameRoomRepository.save(new GameRoom(gameRoomName)); + + GameRoom expected = gameRoomRepository.findByName(gameRoomName); + assertThat(savedGameRoom.getName()).isEqualTo(expected.getName()); + } + + @DisplayName("중복된 이름의 게임방 생성시 오류 발생") + @Test + void save_duplicatedName_ExceptionThrown() { + String game = "test"; + + gameRoomRepository.save(new GameRoom(game)); + assertThatThrownBy(() -> gameRoomRepository.save(new GameRoom(game))) + .isInstanceOf(DbActionExecutionException.class); + } + +} \ No newline at end of file diff --git a/src/test/java/wooteco/chess/entity/BaseEntityTest.java b/src/test/java/wooteco/chess/entity/BaseEntityTest.java deleted file mode 100644 index edf11db089..0000000000 --- a/src/test/java/wooteco/chess/entity/BaseEntityTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package wooteco.chess.entity; - -import static org.assertj.core.api.Assertions.*; - -import java.time.LocalDateTime; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullSource; - -class BaseEntityTest { - - @ParameterizedTest - @NullSource - void BaseEntity_NullCreatedTime_ExceptionThrown(final LocalDateTime localDateTime) { - assertThatThrownBy(() -> ChessGameEntity.of(localDateTime)) - .isInstanceOf(NullPointerException.class) - .hasMessage("생성 시간이 null입니다."); - } - - @Test - void BaseEntity_CreatedTime_GenerateInstance() { - final BaseEntity baseEntity = ChessGameEntity.of(LocalDateTime.now()); - - assertThat(baseEntity).isInstanceOf(BaseEntity.class); - } - - @Test - void compareTo_CompareByCreatedTime_ReturnCompareToCreatedTime() { - final BaseEntity earlyChessGame = ChessGameEntity.of(LocalDateTime.MIN); - final BaseEntity lateChessGame = ChessGameEntity.of(LocalDateTime.MAX); - - assertThat(earlyChessGame.compareTo(lateChessGame)).isEqualTo(LocalDateTime.MIN.compareTo(LocalDateTime.MAX)); - } - -} \ No newline at end of file diff --git a/src/test/java/wooteco/chess/entity/ChessGameEntityTest.java b/src/test/java/wooteco/chess/entity/ChessGameEntityTest.java deleted file mode 100644 index b16bbce8cb..0000000000 --- a/src/test/java/wooteco/chess/entity/ChessGameEntityTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package wooteco.chess.entity; - -import static org.assertj.core.api.Assertions.*; - -import java.time.LocalDateTime; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullSource; - -class ChessGameEntityTest { - - private static final long DEFAULT_GAME_ID = 0L; - - @Test - void of_GameIdAndCreatedTime_GenerateInstance() { - assertThat(ChessGameEntity.of(1, LocalDateTime.now())).isInstanceOf(ChessGameEntity.class); - } - - @ParameterizedTest - @NullSource - void of_NullChessGameEntity_ExceptionThrown(final ChessGameEntity entity) { - assertThatThrownBy(() -> ChessGameEntity.of(1, entity)) - .isInstanceOf(NullPointerException.class) - .hasMessage("엔티티가 null입니다."); - } - - @Test - void of_GameIdAndChessGameEntity_GenerateInstance() { - final ChessGameEntity entity = ChessGameEntity.of(1, LocalDateTime.now()); - - assertThat(ChessGameEntity.of(1, entity)).isInstanceOf(ChessGameEntity.class); - } - - @Test - void of_CreatedTime_GenerateInstance() { - assertThat(ChessGameEntity.of(LocalDateTime.now())).isInstanceOf(ChessGameEntity.class) - .extracting("gameId").isEqualTo(DEFAULT_GAME_ID); - } - -} \ No newline at end of file diff --git a/src/test/java/wooteco/chess/entity/ChessHistoryEntityTest.java b/src/test/java/wooteco/chess/entity/ChessHistoryEntityTest.java deleted file mode 100644 index b24112b68a..0000000000 --- a/src/test/java/wooteco/chess/entity/ChessHistoryEntityTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package wooteco.chess.entity; - -import static org.assertj.core.api.Assertions.*; - -import java.time.LocalDateTime; -import java.util.Arrays; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullSource; - -import wooteco.chess.domain.chessGame.ChessCommand; - -class ChessHistoryEntityTest { - - private static final String MOVE_COMMAND = "move"; - - @ParameterizedTest - @NullSource - void validate_NullStart_ExceptionThrown(final String start) { - assertThatThrownBy(() -> ChessHistoryEntity.of(1, 1, start, "b2", LocalDateTime.now())) - .isInstanceOf(NullPointerException.class) - .hasMessage("출발 위치가 null입니다."); - } - - @ParameterizedTest - @NullSource - void validate_NullEnd_ExceptionThrown(final String end) { - assertThatThrownBy(() -> ChessHistoryEntity.of(1, 1, "b1", end, LocalDateTime.now())) - .isInstanceOf(NullPointerException.class) - .hasMessage("도착 위치가 null입니다."); - } - - @Test - void of_HistoryIdAndGameIdAndStartAndEndAndCreatedTime_GenerateInstance() { - assertThat(ChessHistoryEntity.of(1, 1, "b1", "b2", LocalDateTime.now())).isInstanceOf(ChessHistoryEntity.class); - } - - @Test - void of_GameIdAndStartAndEndAndCreatedTime_GenerateInstance() { - assertThat(ChessHistoryEntity.of(1, "b1", "b2", LocalDateTime.now())).isInstanceOf(ChessHistoryEntity.class); - } - - @Test - void of_StartAndEnd_GenerateInstance() { - assertThat(ChessHistoryEntity.of("b1", "b2")).isInstanceOf(ChessHistoryEntity.class); - } - - @ParameterizedTest - @NullSource - void of_NullChessHistoryEntity_ExceptionThrown(final ChessHistoryEntity entity) { - assertThatThrownBy(() -> ChessHistoryEntity.of(1, entity)) - .isInstanceOf(NullPointerException.class) - .hasMessage("엔티티가 null입니다."); - } - - @Test - void of_HistoryIdAndChessHistoryEntity_GenerateInstance() { - final ChessHistoryEntity entity = ChessHistoryEntity.of("b1", "b2"); - - assertThat(ChessHistoryEntity.of(1, entity)).isInstanceOf(ChessHistoryEntity.class); - } - - @Test - void of_ChessIdAndStartAndEnd_GenerateInstance() { - assertThat(ChessHistoryEntity.of("b1", "b2")).isInstanceOf(ChessHistoryEntity.class); - } - - @Test - void generateMoveCommand_MoveCommandFromStartToEnd_ReturnChessCommand() { - final String start = "b1"; - final String end = "b2"; - final ChessHistoryEntity chessHistoryEntity = ChessHistoryEntity.of(start, end); - - final ChessCommand expected = ChessCommand.of(Arrays.asList(MOVE_COMMAND, start, end)); - Assertions.assertThat(chessHistoryEntity.generateMoveCommand()).isEqualTo(expected); - } - -} \ No newline at end of file diff --git a/src/test/java/wooteco/chess/service/ChessServiceTest.java b/src/test/java/wooteco/chess/service/ChessServiceTest.java deleted file mode 100644 index 443249f615..0000000000 --- a/src/test/java/wooteco/chess/service/ChessServiceTest.java +++ /dev/null @@ -1,142 +0,0 @@ -package wooteco.chess.service; - -import static org.assertj.core.api.Assertions.*; - -import java.time.LocalDateTime; -import java.util.Arrays; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullSource; - -import wooteco.chess.dao.ChessGameDao; -import wooteco.chess.dao.ChessHistoryDao; -import wooteco.chess.dao.InMemoryChessGameDao; -import wooteco.chess.dao.InMemoryChessHistoryDao; -import wooteco.chess.domain.chessBoard.ChessBoard; -import wooteco.chess.domain.chessBoard.ChessBoardInitializer; -import wooteco.chess.domain.chessGame.ChessCommand; -import wooteco.chess.domain.chessGame.ChessGame; -import wooteco.chess.entity.ChessGameEntity; -import wooteco.chess.entity.ChessHistoryEntity; -import wooteco.chess.service.dto.ChessGameDto; - -class ChessServiceTest { - - private static final String MOVE_COMMAND = "move"; - - private ChessGameDao chessGameDao; - private ChessHistoryDao chessHistoryDao; - - @BeforeEach - void setUp() { - chessGameDao = new InMemoryChessGameDao(); - chessHistoryDao = new InMemoryChessHistoryDao(); - } - - @ParameterizedTest - @NullSource - void ChessService_NullChessGameDao_ExceptionThrown(final ChessGameDao chessGameDao) { - assertThatThrownBy(() -> new ChessService(chessGameDao, chessHistoryDao)) - .isInstanceOf(NullPointerException.class) - .hasMessage("ChessGameDao가 null입니다."); - } - - @ParameterizedTest - @NullSource - void ChessService_NullChessHistoryDao_ExceptionThrown(final ChessHistoryDao chessHistoryDao) { - assertThatThrownBy(() -> new ChessService(chessGameDao, chessHistoryDao)) - .isInstanceOf(NullPointerException.class) - .hasMessage("ChessHistoryDao가 null입니다."); - } - - @Test - void ChessService_ChessHistoryDao_GenerateInstance() { - assertThat(new ChessService(chessGameDao, chessHistoryDao)).isInstanceOf(ChessService.class); - } - - @Test - void checkChessGameIsEmpty_EmptyChessGame_AddChessGame() { - new ChessService(chessGameDao, chessHistoryDao); - - assertThat(chessGameDao.findMaxGameId()).isEqualTo(1); - } - - @Test - void checkChessGameIsEmpty_ExistChessGame_NotAddChessGame() { - chessGameDao.add(ChessGameEntity.of(LocalDateTime.now())); - chessGameDao.add(ChessGameEntity.of(LocalDateTime.now())); - new ChessService(chessGameDao, chessHistoryDao); - - assertThat(chessGameDao.findMaxGameId()).isEqualTo(2); - } - - @Test - void loadChessGame_RecentChessGame_ReturnChessGameDto() { - final ChessService chessService = new ChessService(chessGameDao, chessHistoryDao); - final long gameId = chessGameDao.findMaxGameId(); - final ChessGame chessGame = ChessGame.from(new ChessBoard(ChessBoardInitializer.create())); - chessHistoryDao.add(ChessHistoryEntity.of(gameId, "b2", "b4", LocalDateTime.now())); - chessHistoryDao.add(ChessHistoryEntity.of(gameId, "b7", "b5", LocalDateTime.now())); - chessGame.move(ChessCommand.of(Arrays.asList(MOVE_COMMAND, "b2", "b4"))); - chessGame.move(ChessCommand.of(Arrays.asList(MOVE_COMMAND, "b7", "b5"))); - - final ChessGameDto expected = ChessGameDto.of(chessGame); - assertThat(chessService.loadChessGame()).isEqualTo(expected); - } - - @ParameterizedTest - @NullSource - void playChessGame_NullSourcePosition_ExceptionThrown(final String sourcePosition) { - final String targetPosition = "b2"; - final ChessService chessService = new ChessService(chessGameDao, chessHistoryDao); - - assertThatThrownBy(() -> chessService.playChessGame(sourcePosition, targetPosition)) - .isInstanceOf(NullPointerException.class) - .hasMessage("소스 위치가 null입니다."); - } - - @ParameterizedTest - @NullSource - void playChessGame_NullTargetPosition_ExceptionThrown(final String targetPosition) { - final String sourcePosition = "b2"; - final ChessService chessService = new ChessService(chessGameDao, chessHistoryDao); - - assertThatThrownBy(() -> chessService.playChessGame(sourcePosition, targetPosition)) - .isInstanceOf(NullPointerException.class) - .hasMessage("타겟 위치가 null입니다."); - } - - @Test - void playChessGame_SourcePositionAndTargetPosition_ReturnChessGameDto() { - final ChessService chessService = new ChessService(chessGameDao, chessHistoryDao); - final ChessGame chessGame = ChessGame.from(new ChessBoard(ChessBoardInitializer.create())); - chessGame.move(ChessCommand.of(Arrays.asList(MOVE_COMMAND, "b2", "b4"))); - - final ChessGameDto expected = ChessGameDto.of(chessGame); - assertThat(chessService.playChessGame("b2", "b4")).isEqualTo(expected); - } - - @Test - void createChessGame_RemoveAllChessHistory_ReturnChessGameDto() { - final ChessService chessService = new ChessService(chessGameDao, chessHistoryDao); - chessHistoryDao.add(ChessHistoryEntity.of("b2", "b4")); - chessHistoryDao.add(ChessHistoryEntity.of("b7", "b5")); - - final ChessGame chessGame = ChessGame.from(new ChessBoard(ChessBoardInitializer.create())); - final ChessGameDto expected = ChessGameDto.of(chessGame); - assertThat(chessService.createChessGame()).isEqualTo(expected); - } - - @Test - void endChessGame_EndRecentChessGame() { - final ChessService chessService = new ChessService(chessGameDao, chessHistoryDao); - final ChessGame chessGame = ChessGame.from(new ChessBoard(ChessBoardInitializer.create())); - chessGame.end(); - - final ChessGameDto expected = ChessGameDto.of(chessGame); - assertThat(chessService.endChessGame()).isEqualTo(expected); - } - -} \ No newline at end of file diff --git a/src/test/java/wooteco/chess/service/dto/ChessGameDtoTest.java b/src/test/java/wooteco/chess/service/dto/ChessGameDtoTest.java deleted file mode 100644 index 11a30ad6f2..0000000000 --- a/src/test/java/wooteco/chess/service/dto/ChessGameDtoTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package wooteco.chess.service.dto; - -import static org.assertj.core.api.Assertions.*; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullSource; - -import wooteco.chess.domain.chessBoard.ChessBoard; -import wooteco.chess.domain.chessBoard.ChessBoardInitializer; -import wooteco.chess.domain.chessGame.ChessGame; - -class ChessGameDtoTest { - - @ParameterizedTest - @NullSource - void of_NullChessGame_ExceptionThrown(final ChessGame chessGame) { - assertThatThrownBy(() -> ChessGameDto.of(chessGame)) - .isInstanceOf(NullPointerException.class) - .hasMessage("체스 게임이 null입니다."); - } - - @Test - void of_ChessGame_GenerateInstance() { - final ChessBoard chessBoard = new ChessBoard(ChessBoardInitializer.create()); - final ChessGame chessGame = ChessGame.from(chessBoard); - - assertThat(ChessGameDto.of(chessGame)).isInstanceOf(ChessGameDto.class); - } - -} \ No newline at end of file diff --git a/src/test/java/wooteco/chess/util/ChessBoardRendererTest.java b/src/test/java/wooteco/chess/util/ChessBoardRendererTest.java deleted file mode 100644 index 92b1deacdb..0000000000 --- a/src/test/java/wooteco/chess/util/ChessBoardRendererTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package wooteco.chess.util; - -import static org.assertj.core.api.Assertions.*; - -import java.util.Arrays; -import java.util.List; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullSource; - -import wooteco.chess.domain.chessBoard.ChessBoard; -import wooteco.chess.domain.chessBoard.ChessBoardInitializer; - -class ChessBoardRendererTest { - - @ParameterizedTest - @NullSource - void render_NullChessBoard_ExceptionThrown(final ChessBoard chessBoard) { - assertThatThrownBy(() -> ChessBoardRenderer.render(chessBoard)) - .isInstanceOf(NullPointerException.class) - .hasMessage("체스 보드가 null입니다."); - } - - @Test - void render_ChessBoard_ReturnRenderedChessBoardByStringList() { - final ChessBoard chessBoard = new ChessBoard(ChessBoardInitializer.create()); - - final List expected = Arrays.asList( - "R N B Q K B N R 8", - "P P P P P P P P 7", - ". . . . . . . . 6", - ". . . . . . . . 5", - ". . . . . . . . 4", - ". . . . . . . . 3", - "p p p p p p p p 2", - "r n b q k b n r 1", - "", - "a b c d e f g h"); - assertThat(ChessBoardRenderer.render(chessBoard)).isEqualTo(expected); - } - -} \ No newline at end of file diff --git a/src/test/java/wooteco/chess/util/StringUtilTest.java b/src/test/java/wooteco/chess/util/StringUtilTest.java deleted file mode 100644 index d959bf3b98..0000000000 --- a/src/test/java/wooteco/chess/util/StringUtilTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package wooteco.chess.util; - -import static org.assertj.core.api.Assertions.*; - -import java.util.Arrays; -import java.util.List; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullSource; - -class StringUtilTest { - - @ParameterizedTest - @NullSource - void splitChessCommand_NullChessCommand_ExceptionThrown(final String chessCommand) { - assertThatThrownBy(() -> StringUtil.splitChessCommand(chessCommand)) - .isInstanceOf(NullPointerException.class) - .hasMessage("분리할 명령어가 null입니다."); - } - - @Test - void splitChessCommand_ChessCommand_ReturnListOfSpiltChessCommand() { - final String chessCommand = "move b1 b2"; - - final List expected = Arrays.asList("move", "b1", "b2"); - assertThat(StringUtil.splitChessCommand(chessCommand)).isEqualTo(expected); - } - -} \ No newline at end of file diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties new file mode 100644 index 0000000000..ecd2662b61 --- /dev/null +++ b/src/test/resources/application.properties @@ -0,0 +1,11 @@ +# H2 +spring.h2.console.enabled=true +# MySql +#spring.datasource.url=jdbc:mysql://localhost:13306/woowa_level_02_chess?useSSL=false&serverTimezone=UTC +#spring.datasource.username=root +#spring.datasource.password=root +#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +#spring.datasource.initialization-mode=ALWAYS +# Logging +logging.level.org.springframework.web=DEBUG +logging.level.org.springframework.jdbc=TRACE